I would like to map <c-h> to do an easy "replace" in the active buffer
For now I have something like this:
" <c-h> Replacement
noremap <c-h> :%s/<c-R><c-W>//g<left><left>
inoremap <c-h> <esc>:%s/<c-R><c-W>//g<left><left>
vnoremap <c-h> gv:%s/<c-R><c-W>//g<left><left>
The problems are:
The selection is not properly escaped
For the visual mode I do not paste the selection, juste the word below the cursor
Is there anyway to do something like:
inoremap <c-h> <esc>:%s/\=escapechars(<c-R><c-W>)}//g<left><left>
I have this function:
function! GetVisualSelection()
let old_reg = #v
normal! gv"vy
let raw_search = #v
let #v = old_reg
return substitute(escape(raw_search, '\/.*$^~[]'), "\n", '\\n', "g")
endfunction
which you could use like this:
xnoremap <c-h> :<C-u>%s/<C-r>=GetVisualSelection()<CR>//g<left><left>
The "escaping" part could be extracted into its own function:
function! Escape(stuff)
return substitute(escape(a:stuff, '\/.*$^~[]'), "\n", '\\n', "g")
endfunction
which you could use like this:
nnoremap <c-h> :<C-u>%s/<C-r>=Escape(expand('<cword>'))<CR>//g<left><left>
inoremap <c-h> <esc>:%s/<C-r>=Escape(expand('<cword>'))<CR>//g<left><left>
Related
why it raise error E523: Not allow here in the simple function?
function! CheckMode()
echom mode()
exec "normal \<Esc>"
" normal ^[
" call feedkeys('\<esc>')
endfunction
inoremap <expr> <Esc> CheckMode()
In fact, what I want to do is:
memory the "insert mode" and auto start insert after come back. For example:
function! LeaveBuffer(key)
let b:is_insert_mode = mode() == 'i'
if b:is_insert_mode
exec "normal! \<C-\\>\<C-n>"
endif
exec "normal! \<C-w>".a:key
endfunction
noremap <expr> <C-w>h LeaveBuffer("h")
noremap <expr> <C-w>j LeaveBuffer("j")
noremap <expr> <C-w>k LeaveBuffer("k")
noremap <expr> <C-w>l LeaveBuffer("l")
function! EnterBuffer()
if b:is_insert_mode
startinsert
endif
endfunction
autocmd BufEnter,TermOpen term://** call EnterBuffer()
Is there a way to have the search highlight text in vim under the cursor have a different color compared to the search text not under the cursor?
my .vimrc has this codes:
function! HiInterestingWord(n) " {{{2
" Save our location.
normal! mz
" Yank the current word into the z register.
normal! "zyiw
" Calculate an arbitrary match ID. Hopefully nothing else is using it.
let mid = 77750 + a:n
" Clear existing matches, but don't worry if they don't exist.
"silent! call matchdelete(mid)
try
call matchdelete(mid)
catch 'E803'
" Construct a literal pattern that has to match at boundaries.
let pat = '\V\<' . escape(#z, '\') . '\>'
" Actually match the words.
call matchadd("InterestingWord" . a:n, pat, 1, mid)
endtry
" Move back to our original location.
normal! `z
endfunction
"clear all highlighting
function! ClearAllHi()
for i in range(1,6)
let mid = 77750 + i
silent! call matchdelete(mid)
endfor
endfunction
nnoremap <silent> <leader>0 :call ClearAllHi()<cr>
nnoremap <silent> <leader>1 :call HiInterestingWord(1)<cr>
nnoremap <silent> <leader>2 :call HiInterestingWord(2)<cr>
nnoremap <silent> <leader>3 :call HiInterestingWord(3)<cr>
nnoremap <silent> <leader>4 :call HiInterestingWord(4)<cr>
nnoremap <silent> <leader>5 :call HiInterestingWord(5)<cr>
nnoremap <silent> <leader>6 :call HiInterestingWord(6)<cr>
hi def InterestingWord1 guifg=#000000 ctermfg=16 guibg=#ffa724 ctermbg=214
hi def InterestingWord2 guifg=#000000 ctermfg=16 guibg=#aeee00 ctermbg=154
hi def InterestingWord3 guifg=#000000 ctermfg=16 guibg=#8cffba ctermbg=121
hi def InterestingWord4 guifg=#000000 ctermfg=16 guibg=#b88853 ctermbg=137
hi def InterestingWord5 guifg=#000000 ctermfg=16 guibg=#ff9eb8 ctermbg=211
hi def InterestingWord6 guifg=#000000 ctermfg=16 guibg=#ff2c4b ctermbg=195
"}}}
This allows you to press <leader> + 1-6 to high light word under cursor in different colors; pressing it twice to clear the highlighting. (You can change the color in hi def...) commands. And <leader>+0 clear all highlights.
You can just put the codes in your vimrc to try.
It works like this:
People have used solution based on Damian Conway's talk
" Damian Conway's Die Blinkënmatchen: highlight matches
nnoremap <silent> n n:call HLNext(0.1)<cr>
nnoremap <silent> N N:call HLNext(0.1)<cr>
function! HLNext (blinktime)
let target_pat = '\c\%#'.#/
let ring = matchadd('ErrorMsg', target_pat, 101)
redraw
exec 'sleep ' . float2nr(a:blinktime * 1000) . 'm'
call matchdelete(ring)
redraw
endfunction
But personally, I prefer a simple one, though this highlight whole line
"cursorline and it's highlighting
set cursorline
hi CursorLine cterm=NONE ctermbg=NONE ctermfg=green
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>
Can you have Vim expand a fold automatically when the cursor touches it?
See the foldopen option. It controls which groups of commands will lead to
opening a fold if the cursor is moved into a closed fold.
Note that vertical movements do not open a closed fold, though. Moreover,
there is no setting in foldopen to enable this behavior. When hor item is
set in foldopen option, to open a fold one can use h, l or other
horizontal movement commands. In case if it is crucial to automatically open
a fold on any cursor movement that touches it, one can approach this problem
by remapping some subset of vertical movement commands like it is shown below.
nnoremap <silent> j :<c-u>call MoveUpDown('j', +1, 1)<cr>
nnoremap <silent> k :<c-u>call MoveUpDown('k', -1, 1)<cr>
nnoremap <silent> gj :<c-u>call MoveUpDown('gj', +1, 1)<cr>
nnoremap <silent> gk :<c-u>call MoveUpDown('gk', -1, 1)<cr>
nnoremap <silent> <c-d> :<c-u>call MoveUpDown("\<lt>c-d>", +1, '&l:scroll')<cr>
nnoremap <silent> <c-u> :<c-u>call MoveUpDown("\<lt>c-u>", -1, '&l:scroll')<cr>
nnoremap <silent> <c-f> :<c-u>call MoveUpDown("\<lt>c-f>", +1, 'winheight("%")')<cr>
nnoremap <silent> <c-b> :<c-u>call MoveUpDown("\<lt>c-b>", -1, 'winheight("%")')<cr>
function! MoveUpDown(cmd, dir, ndef)
let n = v:count == 0 ? eval(a:ndef) : v:count
let l = line('.') + a:dir * n
silent! execute l . 'foldopen!'
execute 'norm! ' . n . a:cmd
endfunction
An inferior, but a bit thriftier solution would be to open a fold on every
cursor movement.
autocmd CursorMoved,CursorMovedI * silent! foldopen
Unfortunately, this solution is not general one. After the fold under the
cursor is opened, the cursor is positioned on the first line of that fold. If
this behavior is undesirable, one can follow the vertical direction of
a movement, and place the cursor on the last line of the fold when the cursor
is moving bottom-up.
autocmd CursorMoved,CursorMovedI * call OnCursorMove()
function! OnCursorMove()
let l = line('.')
silent! foldopen
if exists('b:last_line') && l < b:last_line
norm! ]z
endif
let b:last_line = l
endfunction
However, a fold will not be opened if the movement jumps over the fold. For
example, 2j on the line just above a fold will put the cursor on the line
just after that fold, not the second line in it.
set foldopen=all
seems to do what you want. You may also make an autocommand for cursor movement:
au CursorMoved * call AutoOpen()
calling a function like:
function! AutoOpen()
if foldclosed(".") == line(".")
call feedkeys("zo")
endif
endfunction
If you want this to also work in insert mode, use:
au CursorMoved,CursorMovedI * call AutoOpen()
:help fdo and possibly :help fcl may help you. I have this line in my .vimrc:
set foldopen=block,hor,insert,jump,mark,percent,quickfix,search,tag,undo