1

EDIT. Cause of problem has been found: the problem only appears when Tamas Kovacs' Paredit plugin is enabled.

I have a lisp file containing comments and strings written using Chinese chracters. The file is named chinese.scm:

;; 華文。
(display "一二三。")

I tried to delete a character using x in normal mode. Positioning my cursor on , I pressed x once, but this is what I see on the screen:

;; 華<96><87>。
(display "一二三。")

Vim appears to be deleting a byte instead of the entire Chinese character. The same problem appears when I try to delete a character within the string above. This problem only appears with lisp files (i.e. Scheme, Common Lisp, Clojure), and not with non-code files.

Surprisingly, deleting the Chinese character here works perfectly:

(印 "Dire bonjour à la dame.")  ; After deletion: ( "Dire bonjour à la dame.")

Questions are:

  1. Why does this happen?

  2. How can this problem be fixed? i.e. How can I delete one Chinese character in comments and strings using x?

  • I would guess that Vim's 'encoding' is set to something other than utf-8, so Vim is editing individual bytes instead of full Unicode characters. Usually that would result in garbage being shown, too. But somehow your terminal is able to correctly interpret the characters (as long as they're complete), maybe through a custom 'termencoding' setting. I couldn't reproduce this, though. – Ingo Karkat Nov 7 '18 at 7:39
  • @IngoKarkat That was what I suspected too, but the encoding I used is in fact utf-8. – Flux Nov 7 '18 at 8:13
  • @IngoKarkat I just discovered that this problem only appears when Tamas Kovacs' Paredit plugin is enabled. Thanks for looking into it. – Flux Nov 7 '18 at 8:20
  • could it be having the delcombine option set? – Christian Brabandt Nov 7 '18 at 8:33
  • @ChristianBrabandt No. set delcombine? shows nodelcombine. – Flux Nov 7 '18 at 8:40
2

You mentioned you are using the paredit plugin.

If you look into the plugin, you can see, that the DEL Key is mapped to the function PareditEraseFwd.

This function will later call s:EraseFw and if you look closely into the definition you see that in your case it will do this:

    elseif pos < len(line) && pos >= a:startcol
        " Erasing a non-special character
        let reg = reg . line[pos]
        let line = strpart( line, 0, pos ) . strpart( line, pos+1 )

Note, the strpart() function works with byte indices, so it will just remove a single byte instead of a single letter.

You should most likely contact the maintainer of the plugin mentioned at the top of the file to have this fixed (one could for example use a combination of split() and join() using the . to get character indices). When you talk to the maintainer, you should probably also mention that it would be desirable to let the user configure, whether or not he wants certain keys to be mapped (so you could prevent the plugin from mapping the DEL key at all, unfortunately, this is not possible currently).

(Unrelated, to that, it looks like the plugin should be rather distributed as filetype specific plugin instead of a general purpose plugin. So this is something else to be considered by the maintainer of the plugin).

However for a quick solution, you could create a file ~/.vim/after/ftplugin/scheme.vim (create non existing directories) and add

" prevent errors, in case of del being not mapped
" a nicer solution would just check if the key is being mapped
" using `mapcheck("<del>", 'n')
:sil! unmap <buffer> <del>

Or you could disable the whole plugin by setting :let g:paredit_mode=0 into your .vimrc file (which effectively disables the plugin completely. But then you could also just uninstall the plugin).

Also note, that the vim-scripts mirror on github is currently unmaintained and the latest version of the paredit plugin on vim.org is actually 0.9.13 while the github mirror only has the [0.9.12 version].

Update Actually, it looks like version 0.9.13 fixes your problem. Quoting from the changes of the vim.org page (emphasized by myself):

Always leave cursor to opening char's pos after wrapping selection.

Fix possible cursor move problem caused by &indentexpr when using the c operator.

Bugfix: 2 keymaps assumed g:paredit_leader is identical to ','.

Fix for paredit 'x' and 'X' when clipboard=unnamed.

Added support for hy.

Use instead of mapleader.

Enhanced detection of forms balanced state.

Unescaped square brackets in balance detection.

Bugfix: pressing (for completion) followed by ')'.

Remove invalid uses of call.

Fixed problem with 'x' and 'X' commands when erasing multi-byte unicode character.

Fix Paredit burfing (by moving parens left or right) when there are stings as elements.

Added paredit support for shen language.

Do not skip parens after \ when searching for pairs.

  • I actually have the commit that claims to fix the problem, but the problem appears regardless. The fix appears to work only for some multibyte characters (e.g. infinity ∞), but not Chinese characters. – Flux Nov 7 '18 at 9:38
  • then please contact the maintainer. It's his responsibility to fix it. Actually using norm! x instead of lines 1123-1130 should fix it. – Christian Brabandt Nov 7 '18 at 9:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.