How do I insert the current visual selection phrase into the command-line? - vim

When entering an argument on the command, I know I can type <C-R><C-W> to insert the word under the cursor and <C-R><C-A> to insert the WORD under the cursor.
Is there a way to insert the current visual-selection?
Thanks!

You can use the contents of any register on the ex or search command-lines with <C-R> followed by the register's name. By yanking your visual selection, it is put into the 0 register, so <C-R>0 will add your yanked selection to the current command-line.
That is the only way I know of, but I still use it on a daily basis.

There are a few ways your question can be construed. The easiest is if you mean you want to give the selected text as a range argument to an ex command. I doubt this is your question, since this happens automatically if you type : with a visual selection, but the ex syntax for this
:'<,'>
The second way I think your question could be construed is that you want to insert the visual selected text itself as an argument to an ex command; I don't think this can be done. If you read the vim manual section 40.2, where range arguments are described, the only things that a command is allowed to grab from a range argument is the number of the first line and the last line (using the tags <line1> and <line2>).
Finally, if you want to run the selected text on the shell command line, all you need to do is select it and type
:!sh
(The '<,'> part should get inserted for you between the : and the !. You can replace 'sh' with the command to start your favorite shell).

Yes, the register * contains the current visual selection...
You can type <C-R>* to get it from insert or command mode...
However, this is not very handy to use it in a command line, since you can't avoid the '<,'> when entering command mode from visual mode

Related

How to execute specific regex substitution on selected lines in visual mode in vim

I want to replicate the VS code feature of 'highlight and comment out code' (usually bound to keys SHIFT + /) in vim.
I can run :g//s/^/\/\/ / in normal mode to prepend // at the start of every line. I just want to put a constraint on this so it only applies the substitution to lines highlighted in visual mode.
Visually select all the lines (using V), then hit :.
This will give you :'<,'> which is the range of your visual selection.
Then you can add your vim command to it.
I would recommend the following method if you wish to not use plugins.
:'<,'>normal I//
Which is not a substitution.
If you want a really nice vim plugin that does this task in a vim manner, check out tpope's vim-commentary which is an essential in my opinion.
I can run :g//s/^/\/\/ / in normal mode to prepend // at the start of every line.
Well, that would be an unnecessarily complicated way to do it and your command wouldn't really work anyway.
:g// either matches nothing or it matches the previous search. What you want, here, is probably something like :g/^/ or :g/$/.
A simple substitution on the whole buffer would be much simpler and much faster:
:%s/^/\/\/ /
Using :help :global in this context provides no value (you want to operate on every line anyway) and is considerably slower (we are talking thousands of times slower)
You can use alternative separators to avoid all that backslashing:
:%s#^#// #
The last separator is not even needed:
:%s#^#// <-- there is a space, here
And the kicker: you can enter command-line mode from visual mode like you would do from normal mode, by pressing :. So you can simply make your visual selection, press :, and run your substitution:
v " enter visual mode
<motion> " expand the selection
: " press :
:'<,'> " Vim inserts the range covering the visual selection for you
:'<,'>s#^#// <CR> " perform your substitution

Duplicating line in Vim and appending few letters

I am editing a dictionary in a text file, containing Russian words - one word per line.
Some nouns are missing their derivatives, which are usually the same word appended by few more letters - in 6-7 variations as shown in this screenshot:
In Vim I would like to put the cursor in the first column and scroll down line by line. And when I recognize a noun, I'd like to press some (as few as possible!) keystrokes to take that word, copy it in separate lines and append the letters.
I can get rid of the duplicates by issuing %sort u later.
If I could run that command on the whole file it would be something like:
%s/\(.\+\)$/\1^M\1а^M\1ам^M\1ами^M\1ах^M\1е^M\1ном^M/
Do you please have an idea, how to create such a "macro" in Vim?
There are a couple of ways that you can handle this. You can create a macro or you can create a map. Either can be done while running VIM. Either can be placed in another file (your .vimrc, for example, or a file with bindings specific to this project) and sourced when needed.
I will also give you a bit more advice with regular expressions: if you are writing something particularly complex, you can greatly decrease the number of \s needed by starting the regular expression with \v (i.e., :s/\v([0-9a-f]+\s)/0x\1/g).
Creating a Macro in VIM
You can start a macro in VIM by pressing q in Normal mode, followed by the key that you wish to use for the macro. You can then invoke the macro by pressing # followed by the macro's letter. Press q again in Normal mode to stop recording.
You can therefore enter this macro as follows (using the q register):
qq:s/\(.\+\)$/\1\r\1а\r\1ам\r\1ами\r\1ах\r\1е\r\1ном\r/Enterq
Then, when you are on a line and you want to run this command, enter #q from Normal mode.
Storing a macro in a file and sourcing it
When you created a macro in the last step, what you were actually doing was setting the q register. You can check this by entering the registers in command mode. You can instead set this macro in your .vimrc file as follows and it will be available every time you start VIM.
Create the file you want to store this macro in (:new).
Add the following line to the file:
let #q=":s/\\(.\\+\\)$/\\1\\r\\1a\\r\\1b\\r\\1ам\\r\\1ами\\r\\1ах\\r\\1е\\r\\1ном\\r/^M"
(If you yank the line and paste it in VIM with Ctrl+R", there will be a proper ^M character at the end of the line. You'll need to do some manual editing to make sure that it's inside the quotes. Alternatively, you can enter Ctrl+VCtrl+M to enter the ^M character.)
Save the file (:w testmacro.vim).
Source it (:so % or :source %).
Test your macro by typing #q on one of the lines you'd like to do this to.
Later, you will be able to load this macro by running :so testmacro.vim.
Create a Mapping
You can instead create a mapping. The following mapping copies the last word in a given line, pastes it onto the following six lines, and then appends to each of the given lines.
nnoremap <c-j> yy6pAа<esc>jAам<esc>jAами<esc>jAах<esc>jAе<esc>jAном<esc>j
n at the beginning of "nnoremap" indicates that it only functions in Normal mode.
noremap means that this command won't engage in any recursive remapping (whereas with nmap, this could happen).
<c-j> maps to Ctrl+J
yy6p yanks the line and pastes it 6 times.
Aa<esc>j appends to the end of the current line, enters the text (in this case a), exits Insert mode, and moves down a line.
You can enter this command in VIM's command mode or you can store it in a file and load it with the :source command.
Combining Registers with Mappings
You can access a register in your mappings. This means that if you know that entering a given replacement regex will do what you want, you can save that in a register and then enter your command on the current line.
To do this, enter the following commands in a file and then source it:
nnoremap <c-i> :<c-r>f<cr>
let #f="s/\\(.\\+\\)$/\\1\\r\\1a\\r\\1b\\r\\1ам\\r\\1ами\\r\\1ах\\r\\1е\\r\\1ном\\r/^M"
Now you can enter Ctrl+I to run the replacement regex in register f on the current line.
Alternatively, dedicate a few registers to the purpose - let's say a-f.
nnoremap <c-l> yy6p$"apj"bpj"cpj"dpj"epj"fpj
let #a="a"
let #b="ам"
let #c="ами"
let #d="ax"
let #e="e"
let #f="ном
In this case, we're using the ability to press " and the name of a register before hitting a command that uses it, such as paste.
You can record macros by pressing q in the escape mode. For example,
position your cursor on the noun you want to edit.
press qa to start recording macro and store it in register a (other alphabet and digits may also be used for registers) .
do whatever general actions you want to do (copy line, paste, append letters, etc. as in you have tried to show in your search string).
once you are done with the changes, in escape mode press q again.
Your macro is now created in register a. Whenever, you want to repeat your key sequences, just press #a.
Note that you can do anything in recording mode, including any kinds of commands, insertions, cursor movements, and so on. For more information on macros and related options, check out Vim help :h complex-repeat.
Vim registers are shared as place holders for both macros and yanked test; this feature allows you to even save and edit your macros in a file. See this question for details.
Here is a map solution - which copies the line into a buffer and then pastes using p.
The A appends at the end of the line
map <F2> 0dwpo<esc>pAa<enter><esc>pAam<enter><esc>pAax ...etc
If your goal is, when your cursor on a special word, and press something, vim will append different "suffixes" (I hope I used the right word, but you knew what I mean). You could go macro (q). However since you have already written the :s command, you could create a mapping using that command do the same, and it would be shorter.
in command line, you can get the word under cursor by pressing <c-r><c-w>. so you could try:
nnoremap <leader>z :s/<c-r><c-w>/& & &..../<cr>
I didn't write the & & &... part, since I don't know (never tried, I don't have vim under windows. I don't even have windows) if the line break \n could be used here under windows. & means the whole matched part, which in this case is the word under your cursor.
So you just move your cursor to the word, type <leader>z, vim will do the job for you. (if the replacement part is correct :) ).

Keep vim always in command line mode with a ":"

Is there a way to make vim stuck in command mode with a : already typed in?
In that way, for instance:
I would type /fooEnter and the cursor would go to the beginning of the next line containing foo.
Next, I would be still on command line mode with a : already typed in for the next command.
Yes, start it in Ex mode, by invoking it either as ex or as vi -e.
You can also enter Ex mode from the normal visual mode by typing Q (must be upper case).
You can return from Ex mode to normal visual mode by using the vi command.
EDIT : This doesn't actually do what the OP is looking for. He wants to keep the visual display while keeping the cursor on the bottom command line. That may not be possible.
No, but you can map ; to : to put yourself "closer" to command mode.
I'll link to the Vim wiki instead of reposting identical information here.
http://vim.wikia.com/wiki/Map_semicolon_to_colon
You can build your own REPL, like this:
:while 1 | execute input(':') | redraw | endwhile
This is just a conceptual demo; you probably want to add a condition to quit this special mode. Also, commands like :append would need special handling to work properly.
As a last try, I could just initialize vim with -servername=FOO and then code a little script that would read from stdin and send remote-send to FOO whenever it detects(by parsing) a whole command was typed on stdin.
Then I would just use Vim and this other script side by side on different xterms/gnu screens.
EDIT
OK, I will use this one. This way I can even make :a command to enter vim's Insert mode and switch back to command mode when entering a line with a single .. This way I would also have syntax highlight on the fly when inserting text (you know, vim has a very pretty visual display of the text, I'm just too used with ed's interface). When I have so time I'll write this script and link it here.

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