In jEdit, you can do what is called a hyper search, which lists all of the search results in one pane, and allows you to click on them to jump to that place in the text.
Does vim have a similar functionality, using a plugin or otherwise?
That would be the quickfix list or the location list.
To search for foo in the current buffer and display a list of all the occurrences, do:
:vim foo % | copen <-- use the quickfix list
:lvim foo % | lopen <-- use the location list
To search for foo in the current buffer's directory and display a list of all the occurrences, do:
:vim foo .* | copen
See :h quickfix.
Related
I'm using VIM to work with Powershell files. How do I make gvim:
show full list of strings that match some regex? (either in new buffer or in command window)
go to a line selected in the found list?
The following command will get you all the matching lines into the command window.
:vimgrep /INSERT_EXPRESSION_HERE/ % | cw
You can then use normal vim navigation to find the line inside the command window, and hit Enter to jump to that line in the file. To return to the list again, you can use the normal vim Window movement commands C-w,j in normal mode.
For a non-persistent list of search results, you can use the built-in :ilist command to list and :ijump to jump. My FindOccurrence plugin has extended mappings ([/ to query for a pattern, list all occurrences, and query for a number to jump to, and [N which uses the current search pattern). Here's a little demo:
To persist the list of search results, :vimgrep with the quickfix list can be used (as shown in #merlin2011's answer). My GrepHere plugin makes this even easier. Again, a short demo:
I'm using Ctrl-] in Vim to navigate using Ctags.
How do I navigate to alternate file if there are multiple matches?
Ex. something.publish in a codebase containing multiple occurrences of publish:
class Foo
def publish
end
end
class Bar
def publish
end
end
Use g] instead of C-] to get the list of all matches.
You might want to read :help g]
:tn[ext] goes to the next tag, :tp[revious] goes to the previous one. :ts[elect] gives you a list to choose from.
:help tag-matchlist for more fun and exciting things to try!
Adding the answer I was ultimately looking for in case it helps others:
g<C-]> will jump to the tag if there's only one match and will present a list if there are multiple matches.
I've added this mapping to my .vimrc to make it do what I want by default:
nnoremap <C-]> g<C-]>
ltag
ltag the_tag_name
lopen
opens a location window with the tag matches.
This is specially powerful with regular expression tag searches:
ltag /tag_na
lopen
which will list all tags that contain the string tag_na (thus including the_tag_name).
You can then further search inside the location list, before hitting enter to jump to the tag.
To use it for the word under the cursor, you might want to define the map:
nnoremap <leader>l exec("ltag ".expand("<cword>"))<CR>
Then, if you are a tab maniac like me:
command! -nargs=1 Ltag silent ltag <args> | execute "normal \<C-o>" | tab lopen
will open a new tab with the location list and all the matches, instead of jumping to the tab directly:
:Ltag /my_struct
Is there a way to search for some text in a folder and to display search results in a separate buffer in Vim? (Like Sublime Text Ctrl + Shift + F results)
No, you don't need any plugin. The default :vimgrep (or :vim) is all you need.
Search for foo in every file in the current directory:
:vim foo * | cw
Search for foo in every JavaScript file in the current directory:
:vim foo *.js | cw
Search for foo in every JavaScript file in the current directory recursively:
:vim foo **/*.js | cw
Search for the current word in every file in the current directory:
:vim <C-r><C-w> * | cw
:vim <cword> * | cw
(edit: use :cw[indow] instead of :copen)
Sounds like you need ack.vim:
This plugin is a front for the Perl module App::Ack. Ack can be used as a replacement for 99% of the uses of grep. This plugin will allow you to run ack from vim, and shows the results in a split window.
Usage:
:Ack [options] {pattern} [{directory}]
Search recursively in {directory} (which defaults to the current directory) for the {pattern}.
Files containing the search term will be listed in the split window, along with the line number of the occurrence, once for each occurrence. [Enter] on a line in this window will open the file, and place the cursor on the matching line.
The :grep Vim command delegates the searching to the external grep tool (or a compatible alternative like ack, set via 'grepprg'). Alternatively, you can use :vimgrep, which performs the searching inside Vim. This allows use to use the same Vim-style regular expressions and glob patterns (like **/), but it usually is slower because each file is read into a Vim buffer.
Both commands display the results in the quickfix window, from which you can navigate to the matches.
You don't need any plugins for this, though there are several available that try to make the handling simpler or support different search commands (e.g. the already mentioned ack.vim).
I am new to vim, and still exploring some features of it. I have a problem with vimgrep. I can search for a pattern like this vimgrep /define/ ** so that it finds and opens next file that contains a define. But I couldn't yet find out how to go to the next file/line that matches my pattern. Any pointers?
Useful commands for the quickfix list (brackets around omittable part of the commands):
:cn[ext] and :cp[revious] jump to next and previous entry
:cnf[ile] and :cpf[ile] jump to next and previous file (if the quickfix list is not sorted by file you could write a function that getqflist(), performs a sort and then setqflist()
:cr[ewind] and :cla[st] go to beginning or end of the quickfix list
:col[der] and :cnew[er] will iterate through historical quickfix lists.
Needless to say there are plenty of other commands and you can discover them at :help quickfix.
Personally I have the following maps :
| ΓΈ | SHIFT | CTRL
------+--------+---------+---------
<F11> | :cprev | :cpfile | :colder
<F12> | :cnext | :cnfile | :cnewer
Of course if you use the location list instead of the quickfix list (:lvimgrep) the same commands exist, just replace the initial c with an l and that's it.
Vim 8 Additions:
:cdo : perform a command on all entries of quickfix list. For example
:vim /foo/ *.cpp *.h *.hpp can be followed by
:cdo s/pattern/replacement/g
:cfdo: perform a command an all files in quickfix list. For example,
:vim /foo/ *.cpp *.h *.hpp can be followed by
:cfdo %s/2ndpattern/2ndreplacement/g
To jump to the next occurrence of the patter you can use :cnext. You can go in reverse with :cNext.
I'm not sure of a way to skip all occurrences until the next file automatically, but you could open the quickfix window with :cwindow to see a list of matches and navigate to those matches by hitting Enter on the entry in the list.
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)