Im trying to get vim to allow me to circle through the autocomplete popup list with the tab key. It works fine for tab but not for s-tab (shift-tab).
It seems like shift-tab somehow canceles the autocomplete menu before applying C-P
Anyone got any ideas?
function InsertTabWrapper(direction)
if pumvisible()
if "forward" == a:direction
return "\<C-N>"
else
return "\<C-P>"
endif
endif
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<tab>"
else
return "\<c-x>\<c-o>"
endif
endfunction
inoremap <tab> <c-r>=InsertTabWrapper("forward")<cr>
inoremap <s-tab> <c-r>InsertTabWrapper("backward")<cr>
You missed the equal sign "=" after <c-r> for the <s-tab> mapping.
However, I would suggest doing it like this:
function! InsertTabWrapper()
if pumvisible()
return "\<c-n>"
endif
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<tab>"
else
return "\<c-x>\<c-o>"
endif
endfunction
inoremap <expr><tab> InsertTabWrapper()
inoremap <expr><s-tab> pumvisible()?"\<c-p>":"\<c-d>"
Use <expr> mapping. It's nicer to see and clearer (many people don't know about <c-r>= things.
Mapping <s-tab> like this and you can do unindent in insertmode.
Related
I have the following snippet in my config for autocomplete navigation:
function! CheckBackspace() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
inoremap <silent><expr> <Tab>
\ coc#pum#visible() ? coc#pum#next(1) :
\ CheckBackspace() ? "\<Tab>" :
\ coc#refresh()
Now, when the popup menu opens I can press <CR> to complete the first entry or <Tab> to walk through all other entries. How can I make <Tab> start at the first entry (as in accept completion, not close the window and on more presses walk through the list)?
I would like to map <c-c> to copy with some improvements over the well known <c-c> shortcuts. If possible I would also like to use a generic mapping for it. I heard about v:count and I am wondering if a can use it here.
" Copy word under cursor
inoremap <silent> <c-c> <esc>m`viw"+y``a
nnoremap <silent> <c-c> m`viw"+y``
" Copy selection
vnoremap <c-c> "+y
" Copy word under cursor in register [count]
inoremap <silent> 1<c-c> <esc>m`viw"1y``a
inoremap <silent> 2<c-c> <esc>m`viw"2y``a
inoremap <silent> 3<c-c> <esc>m`viw"3y``a
[...]
inoremap <silent> 7<c-c> <esc>m`viw"7y``a
inoremap <silent> 8<c-c> <esc>m`viw"8y``a
inoremap <silent> 9<c-c> <esc>m`viw"9y``a
nnoremap <silent> 1<c-c> m`viw"1y``
nnoremap <silent> 2<c-c> m`viw"2y``
nnoremap <silent> 3<c-c> m`viw"3y``
[...]
nnoremap <silent> 8<c-c> m`viw"8y``
nnoremap <silent> 9<c-c> m`viw"9y``
The question is, can I use something like this and how can I do it ?
nnoremap <silent> <c-c> m`viw"{v:count}y``
Edit:
With your help, I made this but I still have some issues with it. For instance, when I do 3 it will paste the content of the 'e' register 3 times. How to avoid that ?
nnoremap <expr> <C-c> MyYank()
inoremap <expr> <C-c> MyYank()
vnoremap <expr> <C-c> MyYank()
nnoremap <expr> <C-v> MyPaste('n')
" Not using numbered registers because they get rotated due to quote_number
" Instead. A indexed string is used to map <count> to a letter
let s:mapping = 'qwertzuiop'
fu! MyYank(...)
" Get the register to yank in
let l:count = v:count > len(s:mapping) ? 0 : v:count
let l:regs = l:count ? s:mapping[l:count - 1] : '+'
" Action depends on the current mode
let l:currentmode = a:0 > 0 ? a:1 : mode()
if l:currentmode == 'n'
return 'm`viw"' . l:regs . 'y``'
elseif l:currentmode == 'i'
return "\e" . 'm`viw"' . l:regs . 'y``a'
elseif l:currentmode == 'v'
return '"' . l:regs . 'y'
endif
endfu
fu! MyPaste(...)
" Get the register to yank in
let l:count = v:count > len(l:mapping) ? 0 : v:count
let l:regs = l:count ? l:mapping[l:count - 1] : '+'
" Action depends on the current mode
let l:currentmode = a:0 > 0 ? a:1 : mode()
if l:currentmode == 'n'
return '"' . l:regs . 'P'
elseif l:currentmode == 'i'
return "\e" . 'm`viw"' . l:regs . 'y``a'
elseif l:currentmode == 'v'
return '"' . l:regs . 'y'
endif
endfu
You can do that with a :help :map-expr:
" Copy word under cursor in register [count]
nnoremap <expr> <silent> <c-c> 'm`viw"' . (v:count ? v:count : '"') . 'y``'
However, like #FDinoff, I'd ask you to reconsider your approach of yanking to the numbered registers. If you rework your original <C-c> mapping (using :map-expr and v:register), you can already yank into arbitrary registers (by prefixing with "{reg}) and still default to the clipboard. And those :imaps with the count will cause a noticeable delay when entering numbers.
I've found configure about autocompleting brackets,
inoremap ' ''<Left>
inoremap " ""<Left>
inoremap { {}<Left>
inoremap ( ()<Left>
but when I tried to delete the '(', the ')' stays, but in Sublime Text 2, that would disappear too. So how can I configure .vimrc ro make that?
// Update: got the vim-autoclose plugin, seems work now.
If you install surround.vim you can do this by using
inoremap ' ''<Left>
inoremap " ""<Left>
inoremap { {}<Left>
inoremap ( ()<Left>
imap <expr> <C-h> "\<C-\>\<C-n>x".((col('.')==col('$'))?(""):("h"))."a"
imap <BS> <C-h>
let s:pairsymbols={"'": "'",
\ '"': '"',
\ '{': '}',
\ '(': ')',}
function! s:DelPair()
let cnt=v:count1
if col('$')==1
let shiftline=(line('.')<line('$'))
normal! dd
if shiftline
normal! k
endif
normal! $
if cnt>1
execute 'normal '.(cnt-1).'x'
endif
return
endif
let curch=getline('.')[col('.')-1]
if has_key(s:pairsymbols, curch)
let oldchtick=b:changedtick
if getline('.')[col('.')] is# s:pairsymbols[curch]
normal! 2x
else
execute "normal \<Plug>Dsurround".s:pairsymbols[curch]
if b:changedtick==oldchtick
normal! x
endif
endif
else
normal! x
endif
if cnt>1
execute 'normal '.(cnt-1).'x'
endif
endfunction
nnoremap x :<C-u>call <SID>DelPair()<CR>
After a completion try, omnicppcomplete will display all the possible items in the pop up menu . To select an certain item in the menu, one should use <C-N> and <C-p> to switch back and forth between different items. I feel that it is very inconvient . It should be very cool if j and k can be used to to take place of <C-N> and <C-P> . so how should I do ?
function! OmniPopup(action)
if pumvisible()
if a:action == 'j'
return "\<C-N>"
elseif a:action == 'k'
return "\<C-P>"
endif
endif
return a:action
endfunction
inoremap <silent>j <C-R>=OmniPopup('j')<CR>
inoremap <silent>k <C-R>=OmniPopup('k')<CR>
I prefer using the tab key for completion (I am not sure where I got this from):
"tab complete
function! InsertTabWrapper(direction)
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<tab>"
elseif "backward" == a:direction
return "\<c-p>"
else
return "\<c-n>"
endif
endfunction
inoremap <tab> <c-r>=InsertTabWrapper ("forward")<cr>
inoremap <s-tab> <c-r>=InsertTabWrapper ("backward")<cr>
CTRL+J and CTRL+K instead: (so you can type j and k)
inoremap <expr><C-J> pumvisible() ? "\<C-n>" : "\<C-J>"
inoremap <expr><C-K> pumvisible() ? "\<C-p>" : "\<C-K>"
Bonus: <ENTER> to select the option
inoremap <expr><Cr> pumvisible() ? "\<C-y>" : "\<Cr>"
Omnicompletion works pressing <C-X><C-O> making a dropdown list appear.
I wanted to map it as <S-Tab> <C-X><C-O> but first I wanted to test it as: <C-F5> <C-X><C-O>.
It does complete the word but the dropdown list doesn't show up. (the same happens with the plugin SuperTab).
Any suggestions?
EDIT: it Works like this inoremap <S-F5> <C-X><C-O> but it doesn't work like this inoremap <Tab> <C-X><C-O> or <TAB> <C-X><C-O>
CODE:
" autocomplete using tab
imap <C-F5> <C-X><C-O>
One day, I found this (probably on vim.org):
fu! InsertTabWrapper(direction)
let char_before = col('.') - 1
if !char_before || getline('.')[char_before - 1] !~ '\k'
return "\<tab>"
elseif "backward" == a:direction
return "\<c-p>"
else
return "\<c-n>"
endif
endfu
inoremap <tab> <c-r>=InsertTabWrapper("forward")<cr>
inoremap <s-tab> <c-r>=InsertTabWrapper("backward")<cr>
And it works like a charm.