How can you count the number of matches in Vim?
For instance, for the text
<?
:%s/<?//ng
See :h count-items.
Count-items describes what you are after.
:%s/<?/whatever/ng
This is the substitution command, but the n flag avoids the actual substitution.
:help count-items
In VIM 6.3, here's how you'd do it:
:set report=0
:%s/<?/&/g # returns the count without substitution
In VIM 7.2, here's how you'd do it:
:%s/<?/&/gn # returns the count without substitution
Related
Here you can found the following Vim command:
:%!markdown
I know there's a 'similar' command to find/replace
:%s/OLD/NEW
But I suspect that they have nothing to do
Can someone explain the first command?
:%!markdown
%: is another form of 1,$ it is the range of all lines of the file
!: this exclamation point is for executing an external command
markdown: this command is for changing the text to html form
So that command is nothing than a filter that transform your text to html form. You can use a vim command that generate that by typing :%TOhtml
For more see :help filter, :help :!, :help range, :help TOhtml
Say I wanna see what directory I am in, I type
:echo .
and get the error message:
E15:Invalid expression .
How can I echo out those special characters like %, ., <cfile>?
There is a dedicated command to print the current directory path:
:pwd
(See :help :pwd and the whole “The current directory” section in the
help: :help current-directory.)
To quickly find out what paths Vim command-line specials are expanded
to, use
:echo expand('%:p:h')
or, shorter,
:!echo %:p:h
The former command is based on the expand() function that expands
wildcards and special keywords in a given argument (see :help expand).
The latter command takes advantage of the fact that wildcards are
expanded before running an external command (see :help cmdline-special).
You need to use expand()
For example
:echo expand("%:h")
prints the actual directory (of the currenct buffer).
See also :help expand
If you want to inquire about the current-directory (which is buffer independant), you should just du a :pwd. (See :help current-directory)
(Edit: changed from :cd to :pwd as per comment of ib).
Since my google-fu is failing me, can anyone give me a simple example on how to use --remote-expr or any other command line trick to insert text to current buffer, or to set a cfile. (Any : -command would be good.)
All I manage to get with --remote-expr is E449: Invalid expression received for anything.
:help E449 leads you to a basic example. Unfortunately it is a bit too basic:
remote_expr({server}, {string} [, {idvar}])
Examples:
:echo remote_expr("gvim", "2+2")
:echo remote_expr("gvim1", "b:current_syntax")
In command line, that turns into
$ vim --servername "gvim" --remote-expr "2+2"
4
To get an idea what you can do with expressions, see :help expr.
Ordering Vim to insert text from Command line
You are better off with --remote-send that sends key sequences in similar manner as you'd do with maps or abbrs:
$ vim --servername Foo --remote-send "GoHello world! <ESC>"
will append a new line at the end of the active window's buffer.
If you want to execute a command, let's say :ls, to get a list of buffers, you can do
vim --servername GVIM --remote-expr "execute(\"ls\")"
This will print the list of all buffers in GVIM server. Note the escaped quotes.
I've been trying to find something that will let me run multiple commands on the same line in Vim, akin to using semicolons to separate commands in *nix systems or & in Windows. Is there a way to do this?
A bar | will allow you to do this. From :help :bar
'|' can be used to separate commands, so you can give multiple commands in one
line. If you want to use '|' in an argument, precede it with '\'.
Example:
:echo "hello" | echo "goodbye"
Output:
hello
goodbye
NB: You may find that your ~/.vimrc doesn't support mapping |, or \|. In these cases, try using <bar> instead.
Put <CR> (Carriage Return/Enter) between and after commands. For example:
map <F5> :w<CR>:!make && ./run<CR>
Don't use | because:
Some commands have problems if you use | after them
| does not work consistently in configuration files, see :help map_bar
You could define a function that executes your commands.
function Func()
:command
:command2
endfunction
And place this in, for example, your vimrc. Run the function with
exec Func()
The command seperator in vim is |.
Thought this might help someone trying to do substitutions in a chain and one fails
from a comment
%s/word/newword/ge | %s/word2/newword2/ge
You can use the e flag to ignore the error when the string is not found.
I've always used ^J to separate multiple commands by pressing Ctrl+v, Ctrl+j.
You can create a new file, and write your commands on it. Then :so %, which means source current file.
My problem is simple. I search a specific pattern in a file (let's say label in a Tex file)
:g/label/#
but there are lots of occurrences. So I'd like to redirect this output to another file to be able to work easily with it.
Do you have a trick or a command that I don't know?
it's not clear from the original post what you mean by "work easily with it" but it's often useful to see and quickly jump between all of the matches in a buffer without "extracting" the matches to a separate buffer.
vim has an internal grep built in. your example would be something like this (in vim, % denotes the current file)
:vimgrep /label/ %
This will take you to the first occurrence and report how many matches there were. What's cool is that you can look at all of the matches listed by opening up the quickfix error list using
:cope
Now you can just scroll around and press enter on a line to jump to the exact position of the match.
The quickfix error list is exactly the same buffer you use if you run make from inside vim and your compiler throws errors: it gives you a list of what and where the errors are.
After you've jumped to one location pointed by quickfix, you can go to forwards and backwards in the list via :cn and :cp. :ccl closes the error list.
You can also expand your "error" list via :vimgrepa /newpattern/ % or :vimgrepadd
The (documented) caveat is that vim's internal grep is slower than most native grep implementations (but you do get it "for free" in windows, for example). If you do have a grep installed, you can use :grep instead of :vimgrep for similar results.
quoting :help grep
Vim has two ways to find matches for a
pattern: Internal and external. The
advantage of the internal grep is that
it works on all systems and uses the
powerful Vim search patterns. An
external grep program can be used when
the Vim grep does not do what you
want.
The internal method will be slower,
because files are read into memory.
The advantages are:
- Line separators and encoding are automatically recognized, as if a file
is being edited.
- Uses Vim search patterns. Multi-line patterns can be used.
- When plugins are enabled: compressed and remote files can be searched.
You can also use the location list if you're already using the error list for dealing with compilation errors. just add l (for location) to the beginning of the grep command (:lvimgrep,:lvimgrepa :lgrep, :lgrepa) and use :lopen :ln :lp :lcl instead of the :c* ones.
For more commands consult
:help grep
:help quickfix-window
:help quickfix
:help quickfix-error-lists
:redir > matches.txt|execute 'g/foo/#'|redir END
See :h :redir, you can also redirect to registers, variables, the clipboard etc.
What you're doing is essentially 'grep -n label file' from command line. So you can run that command and > it into a file easily enough.
The derivation of 'grep' is even from basically the same source.
I've gotten this of the net at some point:
function GoToLine(mainbuffer)
let linenumber = expand("<cword>")
silent bd!
silent execute "buffer" a:mainbuffer
silent execute ":"linenumber
silent nunmap <Enter>
endfunction
command -nargs=1 GoToLine :call GoToLine(<f-args>)
function GrepToBuffer(pattern)
let mainbuffer = bufnr("%")
silent %yank g
enew
silent put! g
execute "%!egrep -n" a:pattern "| cut -b1-80 | sed 's/:/ /'"
silent 1s/^/\="# Press Enter on a line to view it\n"/
silent :2
silent execute "nmap <Enter> 0:silent GoToLine" mainbuffer "<Enter>"
" silent nmap <C-G> <C-O>:bd!<Enter>
endfunction
command -nargs=+ Grep :call GrepToBuffer(<q-args>)
Put it in your .vimrc, then :Grep Foo
Requires external grep program to work properly.
(Just an idea -- untested.)
You can delete all the lines with your pattern in it, write to another file, and undo the delete.
:g/label/d
:w matches
u