Center cursor position after search in Vim - vim

I would like Vim to place my cursor in the middle of screen after search. I have achieved for *, #, n and N commands with the following lines in .vimrc
nmap * *zz
nmap # #zz
nmap n nzz
nmap N Nzz
My question is: how to map / and ? the same way? I.e. I would like to position cursor after some text has been found using
/some-text-to-find-forward
?some-text-to-find-backward

Edit: Threw away my initial answer as it was too much of a kludge. Here's a much better solution.
function! CenterSearch()
let cmdtype = getcmdtype()
if cmdtype == '/' || cmdtype == '?'
return "\<enter>zz"
endif
return "\<enter>"
endfunction
cnoremap <silent> <expr> <enter> CenterSearch()
The way this works is to remap Enter in command-line-mode to a custom expression.
The function performs the current search followed by zz if the command-line is currently in a search. Otherwise it just executes whatever command was being done.

It's not very pretty, but
:nnoremap / :execute "normal! /\<lt>cr>zz"<c-left><right>
will get the job done. (Puts an :execute "normal! /" command on the commandline, then adds a <cr>zz to the end to it so that you automatically zz when you issue the command. The final <c-left><right> just steps into the search pattern at the right spot

Solution from Randy Morris but as a oneliner:
cnoremap <silent><expr> <enter> index(['/', '?'], getcmdtype()) >= 0 ? '<enter>zz' : '<enter>'

Related

Calling hjkl keys from vim's command line

Whenever I am browsing folded code in vim and press the l key I want it to open that fold recursively. For that I did the following: nmap l lzO. Which worked ok, apart from the fact of getting a E490: No fold found whenever I would press l not in a fold. I used that an excuse to learn about Vimscript and write a function for that and avoid the error.
Now, I am missing the part of how can I call a vim command like l or lzO from inside a function?
function! OpenFoldOrNot()
if foldclosed(line(".")) == -1
echo "just l"
l # TODO
else
echo "open fold"
lzO # TODO
endif
endfunction
nmap l :call OpenFoldOrNot()<CR>
Try the normal command. For this case you will need normal! to avoid recursive execution of your function.
You could try the following, using the normal command (my vimscript is very rusty):
function! OpenFoldOrNot()
if foldclosed(line(".")) == -1
normal! l
else
normal! lzO
endif
endfunction
nmap l :call OpenFoldOrNot()<CR>
Alternatively you can use a map-expression to make this kind of job easier.
nnoremap <expr> l foldclosed(line(".")) == -1 ? 'l' : 'lzO'
In a map expression the right hand side, {rhs}, of the mapping is a VimScript expression. This is evaluated to obtain what to execute. In your case it is used to determine if the mapping calls l or lz0.
For more help see:
:h :map-expression

Gvim, Usage of registers in command

I want to use registers value in command line and in function in GVIM.
More specificaly my goal is to ease the on-the-fly highlithing of my log file. I want to be able to hightlight by a simple command the selected string like the * touch do.
Currently I have these line in my vimrc
hi Hi1 guifg=#FFD000
hi Hi2 guifg=#FA0020
hi Hi3 guifg=#A5BB00
To highlith I write in the command line:
:syntax match Hi1 /MON_STRING/
and I obtain what I want. I would like to have a command like
noremap ,H1 :syntax math Hi1 "0
to do the same more easyly but I haven't find the right way to write "0
Any idea?
EDIT =>
Thanks to the answer I create the function that I was looking for:
let g:hicounter = 0
function TT(incr)
if a:incr == 1
let g:hicounter = g:hicounter + 1
let g:hicounter = g:hicounter % 18
endif
:exec 'syntax match Hi' . g:hicounter .' /'.#/.'/'
:echo "falue de incr a:incr " . a:incr . " :let g:hicounter ="
endfunction
noremap <F3> *#:call TT(1)<CR>
noremap <s-F3> *#:call TT(0)<CR>
use execute
:exec 'your command'.#x
x is the reg
. concatenating the cmd strings
Your approach uses :syntax match; that can interfere with the existing syntax (so sometimes, your highlighting won't match on existing syntax, or it prevents the existing syntax to properly highlight the file). For a more robust highlighting, :match / matchadd() is better (but more complex to manage).
If you're willing to install a plugin, my Mark plugin provides this functionality. (The plugin page has links to alternative plugins.)

Vim: corresponding colon command to "a" in normal mode

As we know that you can't enter insert mode by
:exec "normal [iIaAs]"
The only way I know to enter the insert mode from colon command is
:startinsert[!]
While the :startinsert performs like 'i' and :startinsert! like 'A'. But how can I get 'a'?
You can't use
:exec "normal l"
:startinsert
because it doesn't work at the end of line.
does feedkeys function help ?
e.g.
:call feedkeys('a','n')
This snippet:
function! Append()
startinsert
normal! l
endfunction
nmap <F6> :call Append()<CR>
makes <F6> work like a.
Outside of a script, you must do:
:startinsert
<C-o>
:normal l
Note that execute is necessary only if you do some interpolation or concatenation in the command you want to execute.
execute "normal a"
is pointless but
execute "normal a" . my_variable
is correct.

vim: visual star search not working as expected

I copied this function to visually search with * and #:
function! s:VSetSearch(cmdtype)
let temp = #s
norm! gv"sy
let #/ = '\V' . substitute(escape(#s, a:cmdtype.'\'), '\n', '\\n', 'g')
let #s = temp
endfunction
xnoremap * :<C-u>call <SID>VSetSearch('/')<CR>/<C-R>=#/<CR><CR>
xnoremap # :<C-u>call <SID>VSetSearch('?')<CR>?<C-R>=#/<CR><CR>
The # mapping works fine but the * mapping doesn't exit visual selection (it extends the range of the visual selection until the next searched word). I don't understand why this is happening. Is there a solution?
EDIT: To reproduce the problem save the code snippet, download the MS Installer, open cmd.exe and start vim vim -u NONE, then do :set nocp and finally source the saved code. In fact, the following simple mapping doesn't work either:
nnoremap * *<C-o>
EDIT 2: Can someone else reproduce this issue? Should it be reported?
EDIT 3: I believe that the problem (bug?) is that the * (star) key cannot be remapped: if I start vim with vim -N -u NONE (Vim 7.4 with patches 1-274) and run the command :noremap * :echo "star"<CR> and press *, vim tries to perform a search. I also reported this to the vim dev group.
The following is what I use :
function! s:Vword()
return getline('.')[col("'<")-1:col("'>")-1]
endfunction
xnoremap <silent> * <Esc>/\v<<C-R>=<SID>Vword()<CR>><CR>
xnoremap <silent> g* <Esc>/\v<C-R>=<SID>Vword()<CR><CR>
xnoremap <silent> # o<Esc>?\v<<C-R>=<SID>Vword()<CR>><CR>
xnoremap <silent> g# o<Esc>?\v<C-R>=<SID>Vword()<CR><CR>
nnoremap <silent> g// :grep -w <cword> <C-R>=getcwd()<CR><CR>
nnoremap <silent> g/* :grep <cword> <C-R>=getcwd()<CR><CR>
xnoremap <silent> g// :<C-U>grep -w <C-R>=<SID>Vword()<CR> <C-R>=getcwd()<CR><CR>
xnoremap <silent> g/* :<C-U>grep <C-R>=<SID>Vword()<CR> <C-R>=getcwd()<CR><CR>
I have also additionally added nice mappings for g* & similarly g# and also a bunch of mappings for invoking grep that I find very useful.
Edit: minor fixes to code.
Mapping <kMultiply> instead of * solved the problem. Really strange since I do not use the keypad multiply key.

vim : <silent> nmap

In vim I have this nmap
nmap <silent> ,mu : marks ABCDEFGHIJKLMNOPQRSTUVWXYZ<CR>
If I donĀ“t have Upper marks and try ,mu I get
E283: No marks matching "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
why don't show the Error output ?
Try
nnoremap <silent> ,mu :execute "try\nmarks ABCDEFGHIJKLMNOPQRSTUVWXYZ\ncatch /\\V\\^Vim(marks):E283:/\nendtry"<CR>
By the way, is there a reason for writing :nmap instead of :nnoremap? You should not do this if you don't have a reason unless you want to run in the situation where you can't predict what will be the result of adding another mapping (directly to vimrc or by installing a plugin).
Edit (sehe)
To make things more readable, I'd suggest using a snippet like this in your $MYVIMRC:
function! ShowGlobalMarks()
try
marks ABCDEFGHIJKLMNOPQRSTUVWXYZ
catch /E283:/
endtry
endfu
nnoremap <silent> ,mu :call ShowGlobalMarks()<CR>

Resources