I was reading a blog post for Settings up a C# Development Environment with Vim on Debian and I got most of this going except I have an issue with the <C-x><C-o> inoremap'ing. I am running both Vim 8.2 and NeoVim 0.4.3 on WSL on Windows 10. OmniSharp-Vim seems to have installed and started OmniSharp-roslyn as when I do ps aux I see the /home/user01/.cache/omnisharp-vim/omnisharp-roslyn/bin/mono /home/user01/.cache/omnisharp-vim/omnisharp-roslyn/omnisharp/OmniSharp.exe command running.

The original line is:

inoremap <expr> <Tab> pumvisible() ? '<C-n>' :                                                                                                                    
\ getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? '<C-x><C-o>' : '<Tab>'

and I thought to wrap it in an augroup with an autocmd so its not always running.

augroup phil_omnisharp_settings
  autocmd FileType cs inoremap <expr> <Tab> pumvisible() ? '<C-n>' : \ getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? '<C-x><C-o>' : '<Tab>'

  "autocmd FileType cs remap <C-o><C-u> :OmniSharpFindUsages<CR>
  autocmd FileType cs nnoremap <C-o><C-d> :OmniSharpGotoDefinition<CR>
  autocmd FileType cs nnoremap <C-o><C-d><C-p> :OmniSharpPreviewDefinition<CR>
  autocmd FileType cs nnoremap <C-o><C-r> :!dotnet run
augroup END

This will start as expected, but when I get to a System.Console.<Tab> I get the following error:

E15: Invalid expression: \ getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? '^X^O' : '^I'

or System.Console.<C-x><C-o> sequence I get the following error:

-- Omni completion (^O^N^P) Pattern not found

I would just run Vim/NeoVim on Windows, but I ran into issues with neither having +python or +python3 support enabled. Vim 8.2 had something called +python/dyn enabled, which OmniSharp didn't seem to like either if I used the HTTP method, and the socket method didn't work either.

GitHub Gist: https://gist.github.com/predatorian3/01525f9d82b71972f16882de789e6569

2 Answers 2


If you want to generate key sequences as strings, you need to use double-quoted strings and quote the < with a backslash. Such as "\<C-x>\<C-o>".

See :help expr-quote for more details (single quote strings are under :help literal-string).

Putting it all together:

inoremap <expr> <Tab> pumvisible() ? "\<C-n>" :
\ getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? "\<C-x>\<C-o>" : "\<Tab>"
  • I am still getting the ^O^N^P error when I manually type in <C-x><C-o> and when I press tab in INSERT mode, I get the following still. E15: Invalid expression: \ getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? "\^X\^O" : "\^I". I copied the line you used because I thought I had an error when I typed it in.
    – FilBot3
    Mar 10, 2020 at 18:04
  • @Pred Looks like you typed the literal characters, escaping them with CTRL-V. Type the \<C-X> as 6 separate characters, backslash, <, uppercase C, dash, X, >.
    – filbranden
    Mar 10, 2020 at 18:16
  • I typed the whole thing in by hand this time, but I am still getting the same error. I'll include a GitHub Gist of the vimrc snippet and error. gist.github.com/predatorian3/01525f9d82b71972f16882de789e6569
    – FilBot3
    Mar 10, 2020 at 19:00
  • 1
    Ah, that does make sense. The \ character is when a statement is split over multiple lines. I removed that. So, this all seems to only work in WSL with Vim/NeoVim rather than the Windows version of Vim and NeoVim. When I press <Tab> in the WIndows version, it just inserts a \t character. In WSL, the menus actually pop up. I also think the Windows version is using the .NET Framework rather than the .NET Core installation to do its linting.
    – FilBot3
    Mar 10, 2020 at 19:40
  • 1
    @Pred Not sure what to say about the Windows non-WSL issue... If you can create a minimal reproducer for that and you can reproduce that under vim -u NONE -N or vim --clean etc., then I suggest you open a separate question about that issue. Cheers!
    – filbranden
    Mar 10, 2020 at 20:05

In an <expr> mapping there is actually nothing wrong with using single quotes. An <expr> mapping expects a string which it interprets as the mapping RHS when it is invoked. So the original mapping is perfectly correct.

Your error comes in because the original mapping is split over 2 lines, which requires a line continuation character \. When you have joined it into a single line, you must remove the backslash. So to use that line in an autocmd, it should become:

" Original version, for comparison:
" autocmd FileType cs inoremap <expr> <Tab> pumvisible() ? '<C-n>' : \ getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? '<C-x><C-o>' : '<Tab>'
"                                                        remove this ^
  autocmd FileType cs inoremap <expr> <Tab> pumvisible() ? '<C-n>' : getline('.')[col('.')-2] =~# '[[:alnum:].-_#$]' ? '<C-x><C-o>' : '<Tab>'

Edit: I see you eventually worked that out in the comments, but I'll still post this answer to make it clear what the actual fix for your error was.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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