When searching string with notepad++, new window opens and shows find
results. I want to use this feature in vim. After googling I found out some suggestions:
vimgrep /<pattern>/ %
copen
It is possible to create mapping which do those two commands. Pattern should be the current word: may be cword keyword in vim?
The requirement is actually easy. but to get user inputted pattern, you need a function.
function! FindAll()
call inputsave()
let p = input('Enter pattern:')
call inputrestore()
execute 'vimgrep "'.p.'" % |copen'
endfunction
if you want to have a mapping, add this line:
nnoremap <F8> :call FindAll()<cr>
but as I commented under your question. % may not work for unamed buffer.
I suggest lvimgrep (so you can use quickfix for :make)
:nnoremap <F6> :lvimgrep /\M\<<C-R><C-W>\m\>/ **/*.[ch]pp **/Makefile | lopen<CR>
Also, if you just wanted to find in the current file:
:g/<pattern>/
will invoke 'print' (default command) on each matching line.
:v// " non-matching lines
:g//-1 " lines preceding the matching line
:g//-1,+1 " lines around the matching line
etc.
:global is far more useful:
:g/foo/ join " join all lines containing foo
etc.
Those two commands can be shortened and chained: :vim foo %|co. You can pull the word under the cursor like this: :vim <C-r><C-w> %|co.
Here is a quick normal mode mapping that you can use to list all the occurrences of the word under your cursor in the quickfix window:
nnoremap <F6> :vimgrep /<C-r><C-w>/j % <bar> cwindow<cr>
You can also use :il[ist] foo to display a list of all the occurrences of foo or [I to display the same list for the word under your cursor.
When the list is displayed, use :{line number} to jump to the corresponding line.
Related
I currently use the following mapping to substitute the result of the last search pattern with a new word in the entire buffer:
nnoremap <Leader>sa :%s///g<left><left>
What I would like is to put the result of the last search pattern where the new word goes.
Example:
suppose my cursor is standing on the word "hello"
Then I press *
Then I invoke the mapping with <Leader>sa
At this point, my command line is filled with :%s///g. What I would like to have is :%s//hello/g.
I tried the mapping below, but it adds the whole word delimeters (\< and \>) which I don't want.
nnoremap <Leader>sa :%s///g<left><left><C-r>/
--- EDIT ---
After some much needed clarification, I think that the simplest approach is to use :help s/\& in the replacement part of your substitution:
nnoremap <key> :%s//&/g<left><left>
If you really need a more visually explicit method, you can trim the \< and the \>, like this:
nnoremap <key> :%s//<C-r>=substitute(#/,'\\<\\|\\>','','g')<CR>/g<left><left>
which should get you something like this:
:%s//hello/g
with the cursor after hello, ready for further editing.
--- ENDEDIT ---
In command-line mode, :help c_ctrl-r_ctrl-w inserts the word under the cursor:
nnoremap <key> :%s///g<left><left><C-r><C-w>
<cword> gets the word under the cursor, but you have to call expand and send a carriage return
nnoremap <Leader>sa :%s///g<left><left><C-r>=expand("<cword>")<CR>
One way to support visual selections and multiple words is to yank the text you want to replace then search for it with <C-r>"
nnoremap <Leader>sa :%s///g<left><left><C-r>"
You would make a visual selection, press y, then <leader>sa to replace, or /<C-r>" to search.
Edit
After reading the clarifications above, here is a different way to do (almost) the same thing:
Make a visual selection
Press *
Type cgn<C-r>"2 (e.g. change "ThisIsAVeryLongVariable" to "ThisIsAVeryLongVariable2")
Each press of . will repeat the substitution
I have this script to search for the word under cursor in the current project:
nnoremap <leader>K :grep! "\b<C-R><C-W>\b"<CR>:cw<CR>
It works just fine except when the word starts with b.
This is due to <C-R><C-W> only completing the remaining of the word. For example, if I'm searching for "branch", my pattern gets something like this:
\branch\b
Which is equivalent to search for the work "ranch".
Any thoughts on how to figure this out?
Try this: nnoremap <leader>K :execute 'grep! "\b"'.expand("<cword>").'"\b"'<CR>:cw<CR>.
<cword> will expand to the current word under the cursor, as :help :<cword> explains, along with others:
<cword> is replaced with the word under the cursor (like |star|)
<cWORD> is replaced with the WORD under the cursor (see |WORD|)
<cfile> is replaced with the path name under the cursor (like what|gf| uses)
Check the help for more info.
I've enjoyed using # to highlight and search for a word (variable) but I would love if I could hit a single command that would simply tell me how many occurrences are in the current file. I've found the following
:%s/dns_name_change_flag/&/gn
But that's too much typing. Is there anyway to maybe map the above one-liner to use the word under cursor?
I don't know how to do this without execute. The following maps F5 to count occurrences of the word under the cursor using <cword> and word boundary patterns (\\< and \\>):
:map <f5> :execute ":%s#\\<" . expand("<cword>") . "\\>\#&#gn"<CR>
:map <F2> "zyiw:exe "%s/".#z."//gn"<CR>
add this line (without the ":") to your .vimrc and F2 will be mapped every time you start vim.
It yanks the 'inner word' to the z register and then performs a search in the whole buffer outputting the number of appearances.
This approach differs to the one given by Thor in that way, that it also counts appearances of the word that are not a word themselves, but only part of a word. For example: looking for 'an' will also count 'and'.
This might be helpful too:
"A quick way to list all occurrences of the word under the cursor it to type [I (which displays each line containing the current keyword, in this file and in included files when using a language such as C)."
source: http://vim.wikia.com/wiki/Word_count
Map Execute to Grep
You can map a sequence to an external grep command. For example:
:nmap fg :execute '!fgrep --count <cword> %'<CR>
This maps a normal-mode command to fg. The command will run fgrep on the current file in an external process, counting the instances of the word under the cursor.
Minor Caveat
This operates on the current file, not the current buffer. You need to make sure the file is written to disk (e.g. :write) before the word count will be accurate.
I have written a plugin for that: SearchPosition; it provides mappings for the current search pattern and current word / selection, and also lists where the matches occur:
1 match after cursor in this line, 8 following, 2 in previous lines;
total 10 for /\<SearchPosition\>/
:nmap <Leader>* *<C-o>:%s///gn<CR><C-o>
I have a function that does not change search register #/
fun! CountWordFunction()
try
let l:win_view = winsaveview()
exec "%s/" . expand("<cword>") . "//gn"
finally
call winrestview(l:win_view)
endtry
endfun
command! -nargs=0 CountWord :call CountWordFunction()
nnoremap <F3> :CountWord<CR>
If you alredy have searched for the word you can just type
:%~n
I already know that gg=G can indent the entire file on Vim. But this will make me go to the beginning of the file after indent. How can I indent the entire file and maintain the cursor at the same position?
See :h ''
This will get you back to the first char on the line you start on:
gg=G''
and this will get you back to the starting line and the starting column:
gg=G``
I assume the second version, with the backtick, is the one you want. In practice I usually just use the double apostrophe version, since the backtick is hard to access on my keyboard.
Add this to your .vimrc
function! Preserve(command)
" Preparation: save last search, and cursor position.
let _s=#/
let l = line(".")
let c = col(".")
" Do the business:
execute a:command
" Clean up: restore previous search history, and cursor position
let #/=_s
call cursor(l, c)
endfunction
nmap <leader>> :call Preserve("normal gg>G")<CR>
You can also use this on any other command you want, just change the argument to the preserve function. Idea taken from here: http://vimcasts.org/episodes/tidying-whitespace/
You can set a bookmark for the current position with the m command followed by a letter. Then after you run the indent command, you can go back to that bookmark with the ` (backtick) command followed by the same letter.
In a similar spirit to Alex's answer I use the following mapping in vimrc.
nnoremap g= :let b:PlugView=winsaveview()<CR>gg=G:call winrestview(b:PlugView) <CR>:echo "file indented"<CR>
by pressing g= in normal mode the whole buffer is indented, and the scroll/cursor position is retained.
Following on top of Herbert's solution, the reader can also use <C-o>
In vim script
exe "norm! gg=G\<C-o>"
Or mapping
:nnoremap <F10> gg=G\<C-o>
I have log file of multi threaded application. Each line has a well know format (e.g. 3rd field is thread id). while one of fields is thread id. I hope that I'm not trying to reinvent the wheel :)
Any way, to easy reading of the file, I thought of two options that could help:
Highlight all lines with the same thread id as current line.
If some keystroke is pressed, all lines with other thread id are folded, pressing again the keystroke unfold the lines.
A skeleton for both items is welcomed.
Highlighting by pattern
Here is a function to highlight (and another to clear) all lines that contain a given pattern, with an accent highlight on the pattern itself. The "last search" register #/ is also set to the requested pattern so n/N, in normal mode, jumps forwards/backwards through matching lines. <Leader>l (equivalent to \l on most installs) is a shortcut to highlight lines that contain the WORD under your cursor.
highlight def link xHiLine Special
highlight def link xHiPatt String
function! ClearHighlight()
syn clear xHiLine
syn clear xHiPatt
let #/ = ''
endfunction
function! HighlightPattern(patt)
call ClearHighlight()
if a:patt != ''
echo "Highlighting pattern: ".a:patt
exec "syn match xHiPatt \"".a:patt."\" contained"
exec "syn match xHiLine \".*".a:patt.".*\" contains=xHiPatt"
let #/ = a:patt
endif
endfunction
map <Leader>l :call HighlightPattern(expand("<cWORD>"))<CR>
map <Leader>c :call ClearHighlight()<CR>
Folding by pattern
For an example of folding based on patterns, check out the Show-Hide Vim plug-in. It provides two commands, SHOW and HIDE, and a few shortcut maps. For example, :SHOW thread=1234 will fold all lines except those that contain thread=1234, while zs in normal mode will show lines containing the word under your cursor. [You may want to create an alternate map, such as zS, to use <cWORD> instead of <cword>.]
Building patterns
If neither <cword> nor <cWORD> extract a sufficiently unique filter pattern (or to avoid moving the cursor to the proper field), create another function like the one below and call it from a map.
function! GetField(num)
let toks = split(getline('.'))
if len(toks) >= a:num
return toks[a:num-1]
endif
return ''
endfunction
map <Leader>hl :call HighlightPattern(GetField(3))<CR>
map <Leader>fl :exec "SHOW ".GetField(3)<CR>
What you are basically looking for is an external mechanisem to be built on top of your log file.
Chainsaw is doing exactly that for log4j based logs:
http://logging.apache.org/chainsaw/index.html
Not sure what is your logging application, but you should probbaly look at that direction.