vim

How to replace nonbreakable spaces with regular spaces on input?


I'm having issues with text copied from e-books when pasted into source code with Vim, the "nonbreakable space" ends up with an error message from gcc at compile time.

Typical error message is:

filename.c:69:6: error: stray ‘\302’ in program
 69 | <U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0><U+00A0>return 1;

The simple solution I've used is to run :%s/\%ua0/ /g - making them regular spaces.

Is there a way to make this happen automatically on input in Vim (pasting from the terminal that is), for example a command or setting in .vimrc?


Solution

  • The idea behind copy and paste is that you insert the copied content verbatim. Once you decide to change it on the fly, you call for surprises.

    Your idea of pasting first and removing non-breaking spaces in a second pass already seems like a sensible idea. You can speed the process up with a key binding as described in Ciaran's answer.

    Having said that, you can use an autocommand to remove non-breaking spaces before saving your buffer to a file. It has the caveat that this will remove all non-breaking spaces, not just the ones you pasted. It will cause unwanted behavior e.g. when your source code contains Unicode strings containing non-breaking spaces.

    To enable this only for C files, add a buffer-local autocommand to your ~/.vim/after/ftplugin/c.vim like this:

    augroup remove_non_breaking_spaces
        autocmd!
        autocmd BufWritePre <buffer> %s/\%uA0/ /ge
    augroup END
    

    See :help :autocmd for general reference and :help BufWritePre for the specific event. Also see :help :augroup for an explanation of the augroup guard.

    (An earlier version of my answer triggered on the InsertLeave event but it's really enough to do this before writing the file.)

    To generalize your solution to other non-ASCII characters, also see How to get Vim to highlight non-ascii characters?