What does pipe character do in vim command mode? (for example, :vimgrep /pattern/ file | another_cmd)
| is used to execute more than one command at a time.
In your example:
:vimgrep /pattern/ file | copen
This finds for the pattern in the specified file and then opens a window to show current list of occurrence of pattern.
The second command (and subsequent commands) are only executed if the prior command succeeds.
vim - navigating characters in command mode
For small edits, Backspace and light use of the cursor keys should be fine. For anything larger, I would advise to use the command-line window:
In the command-line window the command line can be edited just like editing
text in any window.
So, there's no need to mentally switch to readline key mappings; just use the full editing power (including any custom mappings) of Vim!
You can switch via <C-F>
from the command-line, or directly enter it (from normal mode) by pressing q:
instead of :
. All the details can be found at :help cmdline-window
.
VIM - Hotkey for VIMGREP on Visual Selection in current buffer
A low-level solution
Try [I
and the :ilist
command:
[I " lists every occurrence of the word under the cursor
" in the current buffer (and includes)
:ilist /foo<CR> " lists every occurrence of foo in the current buffer
" (and includes)
Press :
followed by a line number and <CR>
to jump to that line.
You can use them on the visual selection with a simple mapping:
xnoremap <key> "vy:<C-u>ilist /<C-r>v<CR>:
You'll probably need to sanitize the register upon insertion, though.
See :help :ilist
.
Another even lower-level solution
Since we are at it, let's dig even deeper and find the amazingly simple and elegant:
:g/foo/#
that you could use in the same way as :ilist
above:
xnoremap <key> "vy:<C-u>g/<C-r>v/#<CR>:
Limitations
The solutions above don't use the quickfix window, obviously, but they allow you to:
- see their result as a list,
- use line numbers to actually get to where you want.
They have limitations, though:
- the list is not cached so you must perform the search again if you want to get to a different occurrence,
- the list is not transient like the quickfix list so you can't use navigation commands like
:cnext
or:clast
to move around the result.
A higher-level solution
If those limitations are a showstopper, the function below, adapted from justinmk's answer in this /r/vim thread, gives you an almost complete solution:
- press
[I
in normal mode to search for the word under the cursor in the whole buffer, - press
]I
in normal mode to search for the word under the cursor after the current line, - press
[I
in visual mode to search for the selected text in the whole buffer, - press
]I
in visual mode to search for the selected text after the current line.
The function below uses the quickfix list/window when the buffer is associated to a file and falls back to the regular behavior of [I
and ]I
otherwise. It could probably be modified to be used as part of an :Ilist
command.
" Show ]I and [I results in the quickfix window.
" See :help include-search.
function! Ilist_qf(selection, start_at_cursor)
" there's a file associated with this buffer
if len(expand('%')) > 0
" we are working with visually selected text
if a:selection
" we build a clean search pattern from the visual selection
let old_reg = @v
normal! gv"vy
let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g')
let @v = old_reg
" and we redirect the output of our command for later use
redir => output
silent! execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern
redir END
" we are working with the word under the cursor
else
" we redirect the output of our command for later use
redir => output
silent! execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
redir END
endif
let lines = split(output, '\n')
" better safe than sorry
if lines[0] =~ '^Error detected'
echomsg 'Could not find "' . (a:selection ? search_pattern : expand("<cword>")) . '".'
return
endif
" we retrieve the filename
let [filename, line_info] = [lines[0], lines[1:-1]]
" we turn the :ilist output into a quickfix dictionary
let qf_entries = map(line_info, "{
\ 'filename': filename,
\ 'lnum': split(v:val)[1],
\ 'text': getline(split(v:val)[1])
\ }")
call setqflist(qf_entries)
" and we finally open the quickfix window if there's something to show
cwindow
" there's no file associated with this buffer
else
" we are working with visually selected text
if a:selection
" we build a clean search pattern from the visual selection
let old_reg = @v
normal! gv"vy
let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g')
let @v = old_reg
" and we try to perform the search
try
execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern . '<CR>:'
catch
echomsg 'Could not find "' . search_pattern . '".'
return
endtry
" we are working with the word under the cursor
else
" we try to perform the search
try
execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
catch
echomsg 'Could not find "' . expand("<cword>") . '".'
return
endtry
endif
endif
endfunction
nnoremap <silent> [I :call Ilist_qf(0, 0)<CR>
nnoremap <silent> ]I :call Ilist_qf(0, 1)<CR>
xnoremap <silent> [I :<C-u>call Ilist_qf(1, 0)<CR>
xnoremap <silent> ]I :<C-u>call Ilist_qf(1, 1)<CR>
NB: <C-r><C-w>
inserts the word under the cursor, not the visual selection for which there's unfortunately no such shortcut. We have no choice but to yank.
How to use regex in vim to replace with an incrementing number variable
Mind that you can use an expression as the replacement string in the substitute command (:s
). When the replacement string starts with \=
it is evaluated as an expression.
Here, one possible solution is
:let i=1 | g/^x'\d\+'/s//\=i/ | let i=i+1
It finds all occurrences (one per line) of the ^x'\d\+'
pattern and replaces it with the value if i
that is incremented each time the match is found. As has been noted in comments, the |
is a part of the g
replacing "code", as "|
is used to execute more than one command at a time".
Another solution is using the line()
command (taking into account that your file has a header top line, so you should actually subtract 1
from the value returned with line()
):
%s/^x'\d\+'/\=line('.')-1/
The ^x'\d\+'
regex matches
^
- start of a linex'
-x'
string\d\+
- 1+ digits'
- a'
char.
There are other interesting "increment number in regex" examples at the Using an expression in substitute command page:
- Number all the lines in a file (insert line number followed by a tab):
:%s/^/\=line('.')."\t"/- Number a range of lines (from line 10 to line 20):
:10,20s/^/\=line('.')."\t"/- Number a range of lines sequentially starting from 1:
:let counter=0|10,20g//let counter=counter+1|s/^/\=counter."\t"- Number all the paragraphs in range starting from 1 (assuming the paragraphs are separated by one or more blank lines):
:let counter=0|1,20g/^$\n^\s*[^\s]/let counter=counter+1|+1s/^/\=counter."\t"
Note: The above command does not work for the first paragraph in the file if there is no blank line above it.
Vim Regex Capture Groups [bau - byau : ceu - cyeu]
One way to fix this is by ensuring the pattern is enclosed by escaped parentheses:
:%s/\(\w\)\(\w\w\)/\1y\2/g
Slightly shorter (and more magic-al) is to use \v
, meaning that in the pattern after it all ASCII characters except '0'-'9'
, 'a'-'z'
, 'A'-'Z'
and '_'
have a special meaning:
:%s/\v(\w)(\w\w)/\1y\2/g
See:
:help \(
:help \v
How to replace a character by a newline in Vim
Use \r
instead of \n
.
Substituting by \n
inserts a null character into the text. To get a newline, use \r
. When searching for a newline, you’d still use \n
, however. This asymmetry is due to the fact that \n
and \r
do slightly different things:
\n
matches an end of line (newline), whereas \r
matches a carriage return. On the other hand, in substitutions \n
inserts a null character whereas \r
inserts a newline (more precisely, it’s treated as the input CR). Here’s a small, non-interactive example to illustrate this, using the Vim command line feature (in other words, you can copy and paste the following into a terminal to run it). xxd
shows a hexdump of the resulting file.
echo bar > test
(echo 'Before:'; xxd test) > output.txt
vim test '+s/b/\n/' '+s/a/\r/' +wq
(echo 'After:'; xxd test) >> output.txt
more output.txt
Before:
0000000: 6261 720a bar.
After:
0000000: 000a 720a ..r.
In other words, \n
has inserted the byte 0x00 into the text; \r
has inserted the byte 0x0a.
How can I search a word in whole project/folder recursively?
:vimgrep /JFactory/ **/*.java
You can replace the pattern /JFactory/
with /\<JFactory\>/
if you want full word match. :vim
is shorthand for :vimgrep
.
If JFactory
or \<JFactory\>
is your current search pattern (for example you have hit *
on one occurrence) you can use an empty search pattern: :vimgrep // **/*.java
, it will use last search pattern instead. Handy!
Warning: :vimgrep
will trigger autocmds if enabled. This can slow down the search. If you don't want that you can do:
:noautocmd vimgrep /\<JFactory\>/ **/*.java
which will be quicker. But: it won't trigger syntax highlighting or open gz
files ungzipped, etc.
Note that if you want an external program to grep your pattern you can do something like the following:
:set grepprg=ack
:grep --java JFactory
Ack
is a Perl-written alternative to grep. Note that then, you will have to switch to Perl regexes.
Once the command of your choice returned, you can browse the search results with those commands described in the Vim documentation at :help quickfix
. Lookup :cfirst
, :cnext
, :cprevious
, :cnfile
, etc.
2014 update: there are now new ways to do that with the_silver_searcher
or the_platinum_searcher
and either ag.vim
or unite.vim
plugins.
Vim regular expression to match string with prefix and suffix
The command below should work unless "any character" means something different for you than for Vim:
:g/abc.*xyz
.
means "any character except an EOL".*
means "any number (including 0) of the previous atom".1,$
could be shortened to%
.:global
works on the whole buffer by default so you don't even need the%
.- The closing
/
is not needed if you don't follow:g/pattern
by a command as in:g/foo/d
.
Related Topics
Efficiently Read The Average Color of The Screen Content Rendered by Xbmc
Tomcat Server Creating Directories in Tmp
Alternative for Netcat Utility
Selecting a Part of a File and Copying That into New File in Linux
Is Anyone Using Netlink for Ipc
Source Line Numbers in Perf Call Graph
Where Does Top Gets Real-Time Data
How to Determine The Available Physical Memory in Linux
Bash: Getting Percentage from a Frequency Table
Cannot Run 32-Bit Apps on 64-Bit Linux
Windows Command Line Equivalent to "Time" in Linux
How to Run a Cron Job with Arguments and Pass Results to a Log
Why Glibc Binary Is Called Libc.So.6 Not a Libc.So.1 or Libc.So.4