How to search through vim keymaps? - vim

I often forget infrequently used keymappings, but i roughly remember the command name like make or PlugInstall.
When i open :nmap i have to scroll through a long list of mappings to find the one i look for.
As suggested in https://stackoverflow.com/a/2240892/4936725 i currently export the keybindings into a file and grep through that.
:redir >> ~/mymaps.txt
:map
:redir END
Is there a more convenient way to search or grep through the keymaps list?

Vim 8 has introduced the :help :filter command that allows you to directly grep the output of a :map command:
:filter /make/ nmap
This is good for a quick-and-dirty lookup. You still get annoying false positives like <Plug> mappings, though. For a robust solution, you'd probably still capture the output with :redir, then split() it into lines and filter() (via multiple passes) for matching output.

Related

Vim :Ag search and replace, globally and within a directory

I am using :Ag in vim to search for patterns, but I can't figure out how to search and replace through ALL files in my project, or within a directly that I specify. How is this done?
In Vim, project-wide search and replace is at best a two-step process unless you install a plugin that abstracts those two steps for you like EasyGrep.
In its most basic form, project-wide search/replace looks like this:
:args `grep -nl foo *.js`
:argdo %s/foo/bar/c
It won't help you much with :Ag, though, because Vim doesn't have a built-in command similar to the :*do family that works on the quickfix list.
Drew Neil has a couple of screencasts, here and there, that deal with project-wide search/replace. The :Qfdo command mentionned at the bottom of the second post is specifically geared toward :vimgrep/:Ack/:Ag users. With that command and :Ag, the two-step process becomes:
:Ag foo
:Qfdo s/foo/bar/c
-- EDIT --
Vim now has :cdo, :cfdo, :ldo, :lfdo.
In vim, there are multiple solutions, but you have to open all the files in order to be able to do this. You can open the files in different windows, buffers or tabs, and for all the options, you have a method to operate on all files:
:windo :Ag
or
:bufdo :Ag
or
:tabdo :Ag
See :help windows, :help buffers or :help tab-page-commands for more info.

Is it possible to grep the quickfix window in Vim?

Let’s say I use the ag.vim plugin to search for the string disabled through multiple files. It returns me some results in the quickfix window:
1 first_file.rb|1 col 1| disabled something something
2 second_file.rb|1 col 2| disabled another something
Is it possible to pick the quickfix results as an input, grep through them, and open results in new quickfix window? In other words, if I would enter :quickfix_grep first_file, new quickfix would pop up with only one entry:
1 first_file.rb|1 col 1| disabled something something
Update
A vim plugin has been written for this requirement: https://github.com/sk1418/QFGrep
Original Answer:
My understanding of your goal is:
Your grep result is somehow huge in your quickfix, you want to narrow
your view of it. by entering a command with regex, filter the grep
result. The filtered result should also be displayed in QuickFix
window, so that you could open/jump to the file.
If the above is what you want, check out the following:
source this function and the command line:
function! GrepQuickFix(pat)
let all = getqflist()
for d in all
if bufname(d['bufnr']) !~ a:pat && d['text'] !~ a:pat
call remove(all, index(all,d))
endif
endfor
call setqflist(all)
endfunction
command! -nargs=* GrepQF call GrepQuickFix(<q-args>)
then after your grep/ack/whatever show stuffs in your quickfix, you could type
:GrepQF <regex>
to do filtering in your quickfix.
Here I add an GIF animation. I am using Ack instead of grep, but it makes no difference. The given regex will match filename and the text showing in quickfix. I did filtering twice to show that.
hope it helps.
New official vim plugin cfilter
Since 21.8.2018 (patch: 8.1.0311) the plugin cfilter is distributed with vim in $VIMRUNTIME. It is documented under :h cfilter-plugin.
Load plugin cfilter when needed or load it always in your vimrc
:packadd cfilter
Filter quickfix list with
:Cfilter DPUST
My solution to this problem has always been to make the quickfix
buffer modifiable by default:
:autocmd BufReadPost quickfix set modifiable
(The above command is to be put in the .vimrc file.)
Doing this opens a whole range of possibilities for any appropriate
edits of the grepping results, such as removing unrelated entries
manually or by filtering using the :global and :vglobal commands
(which provide the functionality desired in the question for free);
grouping and reordering related entries; adding blank lines or
comments in free form; etc.
Here's a shorter & neater version of #Kent's answer:
function! GrepQuickFix(pat)
call setqflist(filter(getqflist(), "bufname(v:val['bufnr']) !~# a:pat"))
endfunction
command! -nargs=* GrepQF call GrepQuickFix(<q-args>)
It is the same code, just neater and shorter, I don't believe it deserves a separate plugin.

Does cscope support history list recording?

I use < C-\ >C to get the callers of one function, then I can press one number to jump to one caller. But if I want to jump to another caller, I had to press < C-T> to jump back, and press < C-\ >C again to get the caller list. Does cscope support history list recording ?
If you are using VIM, you can try quick fix
:se cscopequickfix=s-,c-,d-,i-,t-,e-
Navigate next or previous result with :cn :cp
Use :cw to display cscope search result.
For one thing, you can use
:se cscopetag
or
:lcscope ....
:lopen
With the latter you can even use :lolder and :lnewer to switch back and forth between previous cscope queries.
he cscopetag:
If 'cscopetag' set, the commands ":tag" and CTRL-] as well as "vim -t" will
always use |:cstag| instead of the default :tag behavior. Effectively, by
setting 'cst', you will always search your cscope databases as well as your
tag files. The default is off. Examples:
:set cst
:set nocst
That way you you just
:tnext
:tprev
like always.
Alternatively, you can use
I have no real experience with cscope but take a look at :help cscopequickfix: with this option set the <C-\>c results are supposed to appear in the quickfix window.

Find/Grep in all VI buffers

With many buffers open, I need a simple way to search all buffers for a regex and navigate the search result (quick list?)
I know I can :bufdo command, and it is easy to search and replace with %s, but I can't find a way to do just a simple search and then navigate the results.
I found plugins for that (e.g., buffergrep), but I'll be surprised if this simple task is not natively supported with a vim trick.. is it?
:grep & co. will populate the QuickFix buffer, which allows for fast navigation among results.
from :help grepadd
:grepa[dd][!] [arguments]
Just like ":grep", but instead of making a new list of
errors the matches are appended to the current list.
Example:
:call setqflist([])
:bufdo grepadd! something %
The first command makes a new error list which is
empty. The second command executes "grepadd" for each
listed buffer. Note the use of ! to avoid that
":grepadd" jumps to the first error, which is not
allowed with |:bufdo|.
An example that uses the argument list and avoids
errors for files without matches:
:silent argdo try
\ | grepadd! something %
\ | catch /E480:/
\ | endtry"
"I found plugins for that (e.g., buffergrep), but I'll be surprised if this simple task is not natively supported with a vim trick.. is it?"
Not that I know of. And existence of multiple plugins trying to offer this functionality tends to confirm that. . .
What plugins have you tried and what have they been lacking?
http://www.vim.org/scripts/script.php?script_id=2545
http://www.vim.org/scripts/script.php?script_id=2255
Also, just to make sure, you are aware of vimgrep, right? Vimgrep is an internal command that loads files into buffers and does greps on the buffers, with results in quickfix window. I haven't confirmed, but I assume if a searched file is already open in a buffer that Vimgrep doesn't reload it, at least not if it has 'nomodified' flag set. If so, one way to use Vimgrep for quick-and-easy buffer grepping would be to just create a file list for Vimgrep using the output from the :buffers command.

Hide all (not)matching lines in Vim

Is it possible to show/hide all matching lines in vi or Vim? Not highlight but just show only those lines.
For example I have a text with word the word ERROR. How do I make it show only lines containing ERROR and how to show only lines without ERROR?
Is there a solution without deleting all matching lines and then just undoing it?
Do you know about the :global command? Does this do what you want?
:g/ERROR
and for the opposite:
:g!/Error
or equivalently:
:v/Error
Another approach depending on your use case would be using vimgrep and its results in quickfix. You can do the following:
:vimgrep pattern % will search the current file and take you to the first search result. More importantly it also puts the results in the "quickfix list".
:copen will then open the quickfix list in a separate quickfix-window. So you will have a separate window with all lines from your last vimgrep. Inside the quickfix-window you can then hit Enter or double-click on a line to jump to the corresponding line in your original file.
:colder will let you go back to older quickfix lists (older vimgrep results). And :cnewer goes forward to newer search results.
Note that the quickfix list is also updated when running :make (which is why its called quickfix for fixing errors). Because of this there also is an alterative to the quickfix list called the "location list". To use it instead you use :lvimgrep, then use l-prefixed commands rather than c-prefixed commands - :lopen, :lolder, :lnewer.
There is, of course, a lot more you can do. See :help quickfix for more info.
PS, You said you didn't want an approach that deletes lines and then undoing them. But since you marked g/ERRORas the answer I thought I would point out a quick and dirty way is to do g!/ERROR/d. You can then easily undo it using u. Also FYI, you can do :set hlsearch to highlight patterns matched with :g commands.
You can use
:g/ERROR/
to print all the lines with ERROR
Also there is a Vim plugin which I saw many times but didn't use:
foldsearch : fold away lines that don't match a given pattern
The best way to do this is->
:vimgrep /something/g % | copen
This will open the list of matches for your keyword and also will show only the matched lines in quickfix window.
Replace % with path to file if not considering the current file.
:vimgrep /something/g % | copen works awesome. Also :g/<pattern>/d can be used to delete lines with the pattern
in case you happen to use fzf you could use:
:Lines in all open files
:BLines only in open buffer
:Rg [pattern] using ripgrep
You probably mean command in less vi vim
& /pattern/
which shows lines containing /pattern/ (like grep).
Some hackish dirty way to do this:
:w (save)
ggdG (deletes everything)
:.!grep something % (replace current line with grep output)

Resources