clearing selection after running substitute command - vim

is there a way to clear highlighted text after running a substitute command in vim? For example, when I run:
:'<,'>s/<\([^>].*\)>/<!--\1-->/
to comment out the current line in an html file, after the command runs all of the text in the doc is highlighted and I have to hit the spacebar to clear the selection.
Is there anything I can add immediately after or as part of the substitute command so any selection is cleared automatically after the command runs so I don't have to hit the spacebar to clear it?

Well, <Space> doesn't clear anything by default so you have it must have it mapped to something like :nohl<CR>. Therefore, you need to execute the command that you mapped to <Space> after your substitution.
This is done by "chaining" Ex commands with |:
:'<,'>s/<\([^>].*\)>/<!--\1-->/|nohl

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.

Vim :'<,'> When entering command mode

Sometimes in vim I appear to be entering a keymap unintentionally when attempting to enter command mode. For instance, when attempting to write :w I, sometimes, end up with this:
:'<,'>w
Which throws the error E481: No Range Allowed
It's mostly just a minor annoyance, and I'm more wanting to know what am I doing to initiate the command line in this way with the brackets.
:'<,'>w appears when you start a command line while being in visual mode. It allows to apply this command on a portion of your document, e.g. to sort some lines. In your case, you have accidentally hit v before entering your command.
Adding to Vincent's correct answer, if you happen to come upon a command that doesn't support a range and gives you the E481 error (though the given :write does support ranges), you can just remove the '<,'> prefilled content by pressing Ctrl + U, and then start typing the command. This is quicker than Esc and re-triggering command-line mode via :.

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 does :normal! /something<cr> relate to incsearch and the / operator?

A few micro-questions regarding normal!, incsearch and the / operator (search). I'm not solving any particular problem here, just trying to understand the relations between the mentioned, so I can put up some sort of analogy in my head.
If I have, set incsearch on, while in normal mode upon pressing /something Vim will jump to the first instance of something even before/without me pressing enter.
Okey, so normal! /something should do the same thing. Why doesn't it?
Similarly, normal! doesn't recognize special characters. So if I have a text file with this text in it,
something<cr>
(that's not a special character in there, but literally typed in text)
`normal! /something<cr>`
should put me up to that text. Why doesn't it?
I like it, but sometimes Vim's inconsistencies are, to put it mildly, most interesting :)
In :help :normal the relevant text is:
{commands} should be a complete command. If
{commands} does not finish a command, the last one
will be aborted as if <Esc> or <C-C> was typed.
The command string you give to normal has to be a complete command, or it aborts. However, normal! /something isn't complete; if you were typing it, Vim would be waiting for you to finish. You could press Esc or Ctrl-C to abort. Or you could complete it by pressing Enter. So the command isn't complete and it aborts, instead of jumping. To get it to complete, give it the Enter it wants (at the command line):
:normal! /something^M
You can get the ^M by typing Ctrl-V and then Enter. (If on Windows and Ctrl-V pastes, use Ctrl-Q.) Then you'll need to press Enter again to finish the whole command. If you were using execute you could do it with:
:execute "normal! /something\<cr>"
Be sure to use double-quotes so the \<cr> will be interpreted correctly.
I believe your second question is the same thing. The literally typed <cr> doesn't affect this situation, you just need to provide the carriage return that will complete the search command, or normal aborts it.
Since you've tagged this question with vimscript, I'm guessing that at least part of your interest is in using this in a script. Getting the literal carriage return into a script and having it work right is kind of a pain. In those cases, I would use execute as shown above, so you can use the double-quote interpretted string method of getting the carriage return.
As for incsearch, it won't have an effect because you can't be partially searching with normal, as we've seen. You can only submit the entire search. It will, however, update the most-recent-search register "/, so highlighting will still update correctly.

Resources