How to access the last expression used in search in Vim? - vim

When doing more complicated search & replace operation in Vim I often try it out in search and only if it finds what I expect I use search & replace.
Is there a way how to access the last value from search and put it into search & replace or alternatively, to put this last value into a register?

From the VIM wiki page:
:%s//<c-r>//g
Replace each match of the last search pattern with the / register (the last search pattern).
After pressing Ctrl-R then / to insert the last search pattern (and before pressing Enter to perform the command), you could edit the text to make any required change.

If you don't need to edit the search regex you can omit it and vim will use the last search for the pattern.
:%s//<replacement>/
From :h :s | /If the {pattern}
If the {pattern} for the substitute command is empty, the command uses the
pattern from the last substitute or `:global` command. If there is none, but
there is a previous search pattern, that one is used. With the [r] flag, the
command uses the pattern from the last substitute, `:global`, or search
command.

You can edit your search history by pressing q/.
Your search history will open in a separate file, spit vertically.
You can navigate and edit each line like a normal Vim session.
To execute a search, hit ENTER on any line.
To cancel, hit :q to close the search history window.
You can copy and paste things to and from this window.
You can also edit your command history by pressing q:.

Related

how to edit highlight text in vim after searching

I like to use "*" to search text in vim. after hight light the target text, I want to edit all of them, is there any way I can do it in vim? for example, after highlight text, I just need to press ctrl+i then the highlight text can be edited simultaneously
Simultaneous editing (like seen in other editors) is not built into Vim (but there are plugins). You don't need them, though. After *, the text is stored in the last search pattern register, and you can just :substitute// without repeating what you're searching for:
:%s//replacement/g
The % is a range and applies this to the whole buffer; the /g is a flag that replaces all (globally) instances, not just the first in each line. Read :help :s for details.
You can check out the vim-multiple-cursors plugin.
Personally, I like #Ingo's solution. The less plugins the better.
As a nice alternative. You can use gn and the . command.
Set your search pattern i.e. * or /foo
Change your highlighted pattern via c operator over the gn motion
cgnbar<esc> will change the highlighted area to bar.
Now you can use . too repeat this change. You can also use n to skip places.
Note: This requires at least 7.4
For more help see:
:h gn
:h .
If you wish to edit the word with another you can use the substitute command. (e.g. :%s/hi/hello/g)
This will change all occurrences of hi to hello in the file.

Editable vimgrep string in command line

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

How to copy text from commandline mode in Vim while searching

There is already a question regarding how to copy text in commandline in Vim. There are two alternative answers:
":p, and
Ctrl+F, followed by finding the previous command.
But these methods don't work when the previous command is a search. That is if I enter into command mode with / or ?, then the search term used cannot be accessed with these methods.
Is there a way to copy text for search text as well?
I believe you are looking for the / register. You can use "/p to paste the last search. While on the command-line you can use <c-r> followed by a register to insert the contents of the given register. example: <c-r>/ will paste the last search.
You may also wish to use q/ to do more extensive editing of your previous searches.
:h registers
:h q/
:h c_CTRL-R
Taking the approach similar to the one proposed in the accepted
answer to the question “How to copy text from commandline mode
in Vim”, one can use the / register to paste the most recent
search pattern:
"/p
The whole history of searches can be explored using the command-line
window (see :help cmdwin). To open it for editing of search strings
from Normal mode, use the q/ or q? commands. To do the same when
entering a search pattern for the / or ? commands, press the key
combination specified by the cedit option (Ctrl+F,
by default).

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>.

vim search pattern for a piece of text line yanked in visual mode

I am trying search a part of some line which is yanked under visual mode.
What's the quickest way to do it in VIM? For exmaple,
Hello, #{1} world.
I press v enter visual mode and select llo, #{1} wor at the line 1. Then I yanked the selected text by pressing y, and then, I am trying to search for the selected text by pressing /. That leads to the following questions:
A: How to past a yanked text when I am in search mode?
B: How to avoid the work of escaping characters for a search pattern?
A:
Ctrl-r 0.
B:
In addition to the Ctrl-r 0 trick, there's also Ctrl-r =, which lets you type in an expression to be evaluated and expands to the result.
/ (now the prompt looks like /)
Ctrl-R = (now the prompt looks like =)
escape(#0, '\^$*.~[') Enter (now the prompt looks like /llo, #{1} wor)
Enter
Note that #reg means "the contents of register reg", and register 0 is the the last yank or delete. I think that escapes all the characters which are special in vi regexps… in any case, you would probably prefer to make a mapping than to type that all in.
When you yank some text (and specify no register to yank it into), it goes to register 0. So, if you want to search for that yanked text, press ESC to get into normal mode and then
/CTRL-r0
(i.e. press /, then CTRL+r, then 0) to pull the content of register 0 into the search pattern.
Some notes:
To search for other patterns stored in other registers, you could type :reg and watch the register contents before deciding which register content to use for your search.
To yank into a different register than 0 (e.g. 2), you could type "2y (:he v_y).
To search for the selected text directly, you could use the mapping described here which enables you to simply press X (uppercase character X) while in visual mode to search for that text.
For searching in general, this vimcast gives you an introduction to the very powerful command line window with the history of searches (discovered it two weeks ago and absolutely love it!).
I've overriden the star command for the visual mode (NB: it requires one file from lh-vim-lib). It answers your need:
select in visual mode
press */#
continue searching with n/N

Resources