Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vimscript: calling function inside inoremap throws "unknown function"

Tags:

neovim

I've been using Neovim with CoC for a while with no problems. Yesterday I upgraded my OS from Ubuntu 21.04 to 22.04. Without any change to my vim config files, an error pops up. I'll explain better with examples:

These are my config files (splitted in many files, fancy stuff): https://github.com/fr-mm/dot-files

Error comes from this file (CoC config file): https://github.com/fr-mm/dot-files/blob/bode/files/vim/plugins/coc.vim

In this file, I have this very common snippet used for trigger autocomplete:

inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

Triggering auto-complete with tab works fine, but when I try to use TAB in insert it throws

E117: Unknown function: <SNR>119_check_back_space

What does it mean: check_back_space function is not been recognized, despite been declared right below.

What I tried so far:

  • Declare function above use
  • Declare in init.vim (first file read by vim)
  • Declare another simpler function and use inside inoremap
  • Remove <SID> from function call

I'm using NVIM v0.6.1 (LuaJIT 2.1.0-beta3)

like image 872
Chico Moura Avatar asked Sep 03 '26 16:09

Chico Moura


1 Answers

There is new code in their GitHub repo for using tab to autocomplete: https://github.com/neoclide/coc.nvim

Replace these lines in your vimrc

" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

with these lines (from the new version of CoC):

" Use tab for trigger completion with characters ahead and navigate
" NOTE: There's always complete item selected by default, you may want to enable
" no select by `"suggest.noselect": true` in your configuration file
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config
inoremap <silent><expr> <TAB>
      \ coc#pum#visible() ? coc#pum#next(1) :
      \ CheckBackspace() ? "\<Tab>" :
      \ coc#refresh()
inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"

function! CheckBackspace() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

and if you want the same behaviour as before (pressing tab autocompletes the top option first, instead of the second option) then also enter the command :CocConfig to bring up your coc configuration file and add this entry to it

"suggest.noselect": true