Copying from vim search term - vim

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.

Related

How to cut and then paste previous item in clipboard in vim?

In vim I copied the string ABCD to my clipboard. Now I want to replace certain words in a paragraph of text by doing c-e (this deletes and immediately puts me in insert mode). But when I paste it will paste the thing I just cut overriding my ABCD.
One solution I came up with is:
c-e
ctrl-o
"0P
But that just seems way too long. Is there a faster alternative to that?
While copying a string, place the cursor at the start of the string, then type
"ayw
where "a means the name of the register(its like a storage) and yw means copy(yank) the word into that register.
There are 26 registers, one for each letter of the alphabet.
When you want to paste the content, type
"ap
where p means to paste. Then use the vim repeat command . to repeat last action
You can store strings in different registers and paste them whenever u want.
to set contents of all registers type
:reg
For more information go to
Using Vim's named registers
Vim registers: The basics and beyond
Vim tips and tricks
You can use yankstack, which simplifies your use case.
This make it easy to cycle against your yank buffer when you paste.
I've personally remapped the keys to space (my leader key).
Here is an extract of my .vimrc:
if &runtimepath =~ 'vim-yankstack'
let g:yankstack_map_keys = 0
nmap <leader>p <Plug>yankstack_substitute_older_paste
nmap <leader>P <Plug>yankstack_substitute_newer_paste
endif
In your case, you just press space p right after having pasted your text. This will replace the word pasted with the last entry in your buffer. You can repeat pressingspace p if you need to go deeper in the history.
Use the "stamping" approach; this allows you to stay in normal mode and is just one keystroke. Add this mapping:
nnoremap S diw"0P
Then press S to "stamp" over any word your cursor is on with what you've yanked.
So, an example of the full routine:
1. ye
2. <move cursor over the word you wish to replace with the yank>
3. S
And, of course, if S is used, chose something else, e.g. ww.
This is a well known approach; see this documentation for variations and details: http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text.
The last thing you yanked is always available in register 0 so, in your case, you only have to do:
<C-e><C-r>0<Esc>
See :help i_ctrl-r.
But yeah, there's a much simpler way for one-off puts:
vep
or, if you need to do those changes several times:
ve"0p

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.

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

Omnicompletion search suggestions

Is there any way to configure Omnicompletion for / searches? So searching for /be would suggest other words in the text such as:
/be<tab>
Beatles
beer
Beethoven
personally, I think after typing / you can type a regex, auto-completion doesn't make much sense here... vim doesn't know what you want to have, how can it give suggestions? It is not like in Insert mode.
However there is way to achieve it.
you type /
you type Ctrl-F
you type i (go into insert mode)
you type beTAB
now you see the popup menu.
this works not only for /, but also for : (cmd mode)
Ctrl-F is handy when we write long commands
detail:
:h cedit
You can use the CmdlineComplete plugin.
It will be triggered with <C-n> / <C-p>, and won't show a completion menu (but you can cycle through candidates by repeating the trigger).
You can use a combination of 'incsearch' and command-line completion with CtrlR CtrlW (:h c_CTRL-R_CTRL-W) to achieve something quite close to what you want:
:set incsearch.
Start typing your search pattern, e.g. /Be. The cursor moves to the next potential match as you type.
As soon as the cursor lands on the word you want to complete, hit CtrlR CtrlW. This pulls the word down into your search prompt: it effectively "completes" your search pattern.
At stage 3 you could also use these variants instead:
CtrlR CtrlA (:h c_CTRL-R_CTRL-A) pulls down the WORD instead of the word.
CtrlL (:h c_CTRL-L) completes character by character.
I used the aforementioned CmdLineComplete plugin until I learned about
set incsearch

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

Resources