I am attempting to map a hotkey to do the following in Vim:
So, one example I have that uses CTAGS opens the declaration of a variable/function in a new tab like so:
map <C-\> :split<CR>:exec("tag ".expand("<cword>"))<CR>
When it hit CTRL-\, a new tab is opened with the declaration of the variable/function the cursor is on.
The command I am trying to map is shown below:
:lvim /\<\(text_i_want_to_find\)\>/gj *.c
:lw
When I run this command, a new tab is opened showing a list of all .c
files containing the text text_i_want_to_find
. I need to modify this to do two things different from what it does now:
.c
, .h
, .cpp
, .mk
, instead of just .c
, and also search files named "Makefile"text_i_want_to_find
Here is the code in my .vimrc
file for the mapping. I'm not entirely sure if CTRL-/ can be mapped at all, so there's one more problem for me to solve.
map <C-/> :split<CR>:lvim /\<\(.expand("<cword>")\)\>/gj *.c *.h *.cpp *.mk Makefile
Does anyone have any tips on fixing this Vim mapping?
EDIT:
After reviewing the answers provided to me, here's the final version of my code:
command! -nargs=1 SearchAll execute " grep -srnw --binary-files=without-match --exclude={*~,tags} --exclude-dir=.svn . -e " . expand("<args>") . " " <bar> cwindow
map <C-g> :SearchAll <cword><CR>
I mapped it to CTRL+g. I can also invoke it like so as a colon command:
:SearchAll my_text_to_search_for
Hope this helps others as well!
Of course, it does not work: you forgot :execute
, :lvimgrep
command on its own does not accept expressions, so you are searching for expand("<cword>")
that is not followed by a keyword character (\>
) and preceded by any character that does not follow keyword character (\<.
). \(
and \)
are useless here. Other notes:
map
: you need neither this mapping working in visual and operator-pending modes nor ability to use other mappings.*.[ch] *.cpp *.mk Makefile
or even *.{[ch],cpp,mk} Makefile
.<C-\>
can be mapped, but not <C-/>
(I hope only currently, but no real work on fixing it is done): \
is 0x5C and <C-\>
is 0x5C-0x40=0x1C. But /
is 0x2F and 0x2F-0x40<0. On my system pressing <C-/>
in terminal transforms into <C-_>
, so does <C-->
.:split
command does not open a new tab, it opens a new window. Prepend it with :tab
to do this.:lvimgrep
is not going to show you the results. It is not either going to jump to the first result unless you remove the j
flag.<CR>
as well as :lw<CR>
. I use :lopen
below, in this context they produce just the same result.<C-u>
after first :
or <C-\><C-n>
before: it is needed to discard count.:execute
in either of your mappings because there is <C-r>=expand("cword")<CR>
, or a default shortcut <C-r><C-w>
.:exec(str)
: it is confusing because :execute
is not a function and this syntax encourages others to think it is. Use :execute str
.Thus the final mapping is:
nnoremap <C-\> :<C-u>tab split \| lvimgrep /\V\<<C-r><C-w>\>/gj *.{[ch],cpp,mk} Makefile \| lopen<CR>
. Replace it with
nnoremap <C-\> :<C-u>lvimgrep /\V\<<C-r><C-w>\>/gj *.{[ch],cpp,mk} Makefile \| tab lopen<CR>
if you don’t want to see the current file in a newly opened tab.
Both mappings assume you have neither /
nor \
in 'iskeyword'
option, if you do replace <C-r><C-w>
with <C-r>=escape(expand('<cword>'), '/\')<CR>
.