Editable vimgrep string in command line - vim

I use vimgrep a lot to navigate in files and usually use the last search from the history to modify the search pattern and run it again.
Is there a way to display in the command line an editable string like the one below, with the cursor already positioned between the two search pattern slashes (and the pattern being empty)?
:vimgrep // **/*[ch]|copen
I don't want to use a constant mapping (like the one at this vim tip) since I want to be able to add/change options (\c etc.).

I'd recommend using the command-line window for this (q: opens it from normal mode), since you
can edit the command with the regular normal mode keystrokes (and you get syntax highlighting too).
You can also move around in your history just like in a normal buffer. So ?vimgrep<Enter>nnn... will search for and move you to all your old vimgrep commands.
Just hit <Enter> as normal when you are done editing, or :q<Enter> to abort the command and quit the window like you would any other.
Finally, here's a mapping to quickly bring up your empty vimgrep template in the command-line window.
:nnoremap \v q:ivimgrep<Space>//<Space>**/*[ch]<Bar>copen<Esc>F/;i
Reference: :help cmdline-window

Related

Moving around the vim command line

I've been a vim user for a while now and I know how to move around the files, but is there anyway to do so on the editor command line itself (is there a name for that?).
e.g. I typed :vimgerp /sometext/ files/*.js and I realized I spelled :vimgrep incorrectly and I want to just jump to the beginning of that line and fix it. Any other sort of small tips here (jump between words -- neither w,e nor alt+left/right seem to work) also appreciated.
http://vimdoc.sourceforge.net/htmldoc/usr_20.html
<Left> one character left
<Right> one character right
<S-Left> or <C-Left> one word left
<S-Right> or <C-Right> one word right
CTRL-B or <Home> to begin of command line
CTRL-E or <End> to end of command line
The easiest method would be to use CTRL-F. This opens your command in the command-line window where you can edit your misspelled command like any other plain text.
from vimhelp
OPEN c_CTRL-F q: q/ q?
There are two ways to open the command-line window:
From Command-line mode, use the key specified with the 'cedit' option. The default is CTRL-F when 'compatible' is not set.
From Normal mode, use the "q:", "q/" or "q?" command. This starts editing an Ex command-line ("q:") or search string ("q/" or
"q?"). Note that this is not possible while recording is in progress
(the "q" stops recording then).
It's not the fastest and therefore probably only worth it for long commands, but you could just hit enter on the incorrect command as is, undo any incorrect changes if necessary, then open up your command history with q:, where you can edit it as you like. Enter then runs the command if you have your cursor over it in the command history buffer.
Also, shift+arrow left/right jumps between words in command mode, and you can use home/end to go to the beginning and end.

Using Ack.vim on visual selection

Currently I have this mapping in my ~/.vimrc
noremap <Leader>a :Ack <cword><cr>
which enables me to search for a word under the cursor.
I would like to search for a current visual selection instead, because sometimes words are not enough.
Is there a way I can send visual selection to ack.vim?
You can write a visual-mode map that yanks the highlighted text and then pastes it verbatim (properly escaped) onto the vim command-line:
vnoremap <Leader>a y:Ack <C-r>=fnameescape(#")<CR><CR>
This solution uses the <C-r>= trick that allows you to enter a kind of second-level command-line, which allows you to enter any vimscript expression, which is then evaluated, and the result is stringified and pasted onto the (original, first-level) command-line where the cursor is.
A slight disadvantage of this approach is that it commandeers the unnamed register, which you may not want.
While bgoldst's answer should work just fine, you could also consider my fork of ack.vim: https://github.com/AndrewRadev/ack.vim
It comes with a working :Ack command in visual mode, and a few other extras that I've summarized at the top of the README.
At the time of this writing this is the default behaviour of Ack.
Just do the following:
move your cursor on any word in normal mode (for instance, hit Esc button to enter in normal mode, you know...)
type :Ack with no argument
it will search for the word under the cursor
Usually I select text during a search in a file (for instance put cursor inside word and type * repeateadly) the type :Ack to look for that word in other files of the project.

gvim - jumplist to functions within a file

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:

How do I repeatedly search & replace a long string of text in vim?

I'm aware of the vim replace command, which is of the form, eg:
:%s/old/new/gc
But what if either of these strings is long? How can I use something like visual selection mode, the clipboard or vim registers instead of having to type the old/new text in?
You can use q: to bring up a command-line window. This lets you use all the vim editing commands to edit the vim command line, including p to paste. So, you could copy the text into a register, paste it into the command line window, and execute it that way.
I recently discovered this feature via vimcasts.
According to the manual, you can use Ctrl+R to insert the contents of a register into the current position in the command line. The manual also claims that Ctrl+Y inserts the text highlighted with the mouse into the command line. Remember that in X11 and some other systems, you can also paste text into a program from the system clipboard using the middle mouse button or a menu command in your terminal emulator.
I think to avoid have your command line be huge you can use this to solve your issue
:%s/foo/\=#a/g
That replaces "foo" with whatever is in register a.
If you're trying to do a substitute with a long complicated search pattern, here's a good way of going about it:
Try out the search pattern using some test cases and refine it until you have the pattern you want. I find incsearch really helps, especially with complicated regular expressions.
You can then use :%s//new to replace all instances of the last searched for pattern.
If you've entered a pattern and want to copy it out of the search history, you can use q/ to bring up a command line window containing recent search patterns very similar to the q: one that contains recent command history.
On the other hand, if you're asking about how to copy and paste text into the substitute command:
I'd write the pattern out in insert mode and yank the search and replacement into two distinct registers using, say, "ay and "by and then use :%s/<C-R>a/<C-R>b/gc to do the substitute. There are lots of variations of the yank command, but this one should also work automatically when using a visual selection.
If you're copying in text from the clipboard, you can use <C-R>* to paste it's contents in insert mode.
I have the following mapping in my .vimrc
vnoremap <leader>r "ry:%s/^Rr/
So I visually select the thing I want to replace, and hit ,r, type the replacement and hit return. If I want to paste the replacement, I yank it before selecting the text to replace, and then use <C-r>" to paste it as the replacement before hitting return.
Note: to insert ^R in your .vimrc, you actually type <C-v><C-r>.

Copying from vim search term

I'm trying to copy text from my vim search term. I spend a fair bit of time building regular expressions for sed search&replace. Since my regex is often quite complicated, I like to build it up in a search before executing :%s/regex/new text/g
In a terminal vim, I can copy my new regex from the search line using the mouse. I'd like to use gvim as much as possible, but it doesn't let right mouse clicks through for me to copy.
Any ideas how to get the search term into a buffer?
Thanks,
Andrew
In command mode (where you are when you hit : in normal mode), you can do ctrl-R /, which will expand to your last search term (other ctrl-R favorites are " for your yank buffer, or % for the full path of the current window)
You actually don't need to do that though. If you leave out the search term for :s, it will assume you want to use the last thing you searched for. so you can /searchregex, and then right after do :%s//replaceregex/ and it will use search regex to do the replace.
Use q: to open an editable window containing your commandline history. From there you can use all your usual Vim toolset to copy/paste/etc.
For the equivalent feature regarding search history, type q/.
q/ shows the search history. For the reverse action of copying a string from your normal buffer into command buffer or search buffer, which doesn't allow the normal use of p, use Ctrl-R 1 to paste.
You can copy text between registers using :let, e.g. copy last search term into register b:
:let #b=#/
Then use ctrl-R b to insert it as in Matt Briggs' answer. Of course that isn't necessary when you can insert it directly using ctrl-R / (in insert or ex mode) or "/p (in normal mode), but with this mapping:
nnoremap <silent> y/ :let #"=#/<CR>
you can type y/ to copy the last search term to the unnamed register for easy pasting. You could use the * register instead to copy to the system clipboard and have the text available to other apps:
nnoremap <silent> y/ :let #*=#/<CR>
See
:help 'clipboard'
:help registers
for more info about Vim registers and using the system clipboard.

Resources