I know how to repeat the last command in Vim. I use ..
But how can I repeat the last macro? It's a little non-comfortable to press #q everytime I want to repeat it.
I tried with . but it just repeats the last command from the macro.
Is there a shorter way of doing that?
Yes, you can use ## to replay the last used macro.
As a bonus, use #: to replay the last ex command. (And then that becomes the "last used macro" that can be repeated with ##.)
I find ## a bit hard to type and as I don't use , much - and it's close enough to .:
:map , ##
Related
If I do a substitution, for example:
:s/ov/xx/g
To substitute "ov" with "xx". However, if I press the . command on another line, it seems like it isn't repeating that find-and-replace operation. Instead it seems to insert a space when I try it again on the next line.
Why not? Is there a way to re-do that command?
You can repeat the last command made in command-line-mode (those made at the : prompt) with #: and then use ## to repeat the same change thereafter. Using . will repeat the last change that was made in normal-mode.
The builtins are & and :&&
I started recording by typing qw.
Then, I pressed #w to replay the search,movement and replacement.
A couple of seconds after, I saw my replay in an infinite loop.
How can I only repaly my recording only once ?
Is this possible ? Should I use another vim command ?
Thanks in advance !
Usually search and replace is done with :s. For example, to replace all foo with bar
:%s/foo/bar/g
See :help :s for more info.
To end a macro, type q in normal mode. So, a macro to move right, delete the next three characters, and move down would be typed as follows
qql3xjq
Then to replay the macro, #q or 3#q to execute it three times (:help q). Adding #q to the macro would make it recursive.
Doing . repeats the last change. Doing 2. repeats the last change two times.
But imagine I want to repeat the change before the last one. How do I do it in Vim?
Don't think you can, see :help . However, what you can do is to record a macro for your edits, you have a lot of registers to choose from {0-9a-zA-Z"} (uppercase to append).
Then use e.g. #u for edit 1, #t for edit 2 and so on.
Great tips about recording from Best of VIM Tips
" Recording (BEST TIP of ALL)
qq # record to q
your complex series of commands
q # end recording
#q to execute
## to Repeat
5## to Repeat 5 times
qQ#qq : Make an existing recording q recursive *N*
" editing a register/recording
"qp :display contents of register q (normal mode)
<ctrl-R>q :display contents of register q (insert mode)
" you can now see recording contents, edit as required
"qdd :put changed contacts back into q
#q :execute recording/register q
Have a look at these for more hints for repeating:
:& last substitute
:%& last substitute every line
:%&gic last substitute every line confirm
g% normal mode repeat last substitute
g& last substitute on all lines
## last recording
#: last command-mode command
:!! last :! command
:~ last substitute
:help repeating
I wrote the RepeatLast.vim plugin to address this exact requirement. It provides a 5\. key binding to repeat the last 5 changes (including movements) and 2\D to drop/forget the last 2 actions.
It works by enabling macro recording all the time, which may not be desirable for everyone. But if you can live with that, it works in 99% of use cases.
Latest version: https://github.com/joeytwiddle/RepeatLast.vim (Please feedback!)
Caveats:
Please :set ch=2 so that the first line of output won't be hidden by the "recording" message.
The 1% of times it fails to work as intended are usually due to:
Difficulties triggering the CursorHold event slowly without losing
fast-repeated keystrokes
Undesirable recording of [Space] and
[Enter] keys when the user is responding to a prompt.
Training your q muscle to pre-emptively record macros might be a better approach in the long term. ;-)
Based on Fredrick Phil's answer, here is an example:
Recording your macro
The following shows how to record a macro to delete everything in and including a quoted string and store in register d. The command to delete a string is da". So to store this command in macro register d we can simply do this:
qdda"q
Notice it starts and ends with a q. The second character is the register, in this case d for delete. But we could have given it any letter or number. The remaining characters da" is our command.
Using our macro
Now that our macro is recorded we can invoke it by using the # symbol followed by the register:
#d
Repeating the last macro command
To use the most recently invoked macro command again:
##
Unrelated info:
In this example, we used da" which stands for delete a quoted string. (If you instead wanted to delete everything inside the quoted string, but not the quotation marks themselves you can instead use di" instead.).
Record Your "Edits"
yes! you can do this in vim! 😎
One of Vim's most useful features is its ability to record what you type for later playback. This is most useful for repeated jobs that cannot easily be done with .
To start recording
press q in normal mode followed by a letter (a to z)
That starts recording keystrokes to the specified register. Vim displays recording in the status line
Type any normal mode commands, or enter insert mode and type text
To stop recording
ending in normal mode, come to normal mode if you are not, and press q
ending in insert mode, press Ctrl+O, this will temporarily get you into normal mode, and then press q
To playback your keystrokes/recording
press # followed by the letter previously chosen
Typing ## repeats the last playback
References
Vim Fandom: Recording keys for repeated jobs
Vim Fandom: Macros
Quora - How do you stop recording a Vim macro when in insert mode?
In Vim, is there any way to repeat the last command regardless of whether it was an edit or not, and without having the foresight to first record a macro?
E.g. say I type :bn, and want to do it again (it was the wrong file). Pressing . obviously doesn't do it. Or maybe I'm doing gE and want to repeat that (with one keystroke since clearly gE is kinda painful to type).
Perhaps there are some plugins? Similar to this question.
(Even cooler would be to retroactively bind a number of commands to a macro, so one could type 5qa#a or something to repeat the last 5 commands...)
To repeat a command-line command, try #:, To repeat a normal/insert-mode command, try .,
Add below mapping to your .vimrc if you want to shortcut the same:-
:noremap <C-P> #:<CR> - This will map Ctrl+P to previous command-line command. You can map any other combo.
:help repeating will provide the typical repeat commands (like ., #:, etc.). You could try repeat.vim. That may get you closer to what you are looking for.
For motion commands there is no mechanism built into Vim. The Find and To commands (f/F/t/T) have ; and , to repeat and reverse. There are a couple of plugins which extend those bindings to repeat other motion commands:
http://www.vim.org/scripts/script.php?script_id=2174
http://www.vim.org/scripts/script.php?script_id=3665
The later should support repeating gE using ;
You can just use "."
Example:
You have "abc" at 10 places in your file and you want to replace it with "def" at 5 places of it.
Step 1: Find first occurance of abc by typing command "/abc"
Step 2: Once cursor is on "abc", Replace abc by command "cw" to take out word "abc"
Step 3: Type in "def" as replacement and press enter to go to command mode
Step 4: To repeat this action just type command "n" to go to next occurrence of abc and type command "." . The command remembers that you replaced "abc" with "def" last time and will perform the same here.
You can map #: to some key for more convenience:
:map <F2> #:
and then it's easier to use it with repeats.
Say I have the following style of lines in a text file:
"12" "34" "some text "
"56" "78" "some more text"
.
.
.
etc.
I want to be able to remove the quotes surrounding the first two columns. What is the best way to do this with Vim (I'm currently using gVim)?
I figured out how to at least delete the beginning quote of each line by using visual mode and then enter the command '<,'>s!^"!!
I'm wondering if there is a way to select an entire column of text (one character going straight down the file... or more than 1, but in this case I would only want one). If it is possible, then would you be able to apply the x command (delete the character) to the entire column.
There could be better ways to do it. I'm looking for any suggestions.
Update
Just and FYI, I combined a couple of the suggestions. My _vimrc file now has the following line in it:
let #q=':%s/"\([0-9]*\)"/\1/g^M'
(Note: THE ^M is CTRLQ + Enter to emulate pressing the Enter key after running the command)
Now I can use a macro via #q to remove all of the quotes from both number columns in the file.
use visual block commands:
start mode with Ctrl-v
specify a motion, e.g. G (to the end of the file),
or use up / down keys
for the selected block specify an action, e.g. 'd' for delete
For more see
:h visual-mode
Control-V is used for block select. That would let you select things in the same character column.
It seems like you want to remove the quotes around the numbers. For that use,
:%s/"\([0-9]*\)"/\1/g
Here is a list of what patterns you can do with vim.
There is one more (sort of ugly) form that will restrict to 4 replacements per line.
:%s/^\( *\)"\([ 0-9]*\)"\([ 0-9]*\)"\([ 0-9]*\)"/\1\2\3\4/g
And, if you have sed handy, you can try these from the shell too.
head -4 filename.txt | sed 's/pattern/replacement/g'
that will try your command on the first 4 lines of the file.
Say if you want to delete all columns but the first one, the simple and easy way is to input this in Vim:
:%!awk '{print $1}'
Or you want all columns but the first one, you can also do this:
:%!awk '{$1="";$0=$0;$1=$1;print}'
Indeed it requires external tool to accomplish the quest, but awk is installed in Linux and Mac by default, and I think folks with no UNIX-like system experience rarely use Vim in Windows, otherwise you probably known how to get a Windows version of awk.
Although this case was pretty simple to fix with a regex, if you want to do something even a bit more advanced I also recommend recording a macro like Bryan Ward. Also macros come easier to me than remembering which characters need to be escaped in vim's regexes. And macros are nice because you can see your changes take place immediately and work on your line transformation in smaller bits at a time.
So in your case you would have pressed qw to start recording a macro in register w (you can of course use any letter you want). I usually start my macros with a ^ to move to the start of the line so the macro doesn't rely on the location of the cursor. Then you could do a f" to jump to the first ", x to delete it, f" to jump to the next " and x to delete that too. Then q to finish recording.
Instead of making your macro end on the next line I actually as late as today figured out you can just V (visually line select) all lines you want to apply your macro to and execute :normal #w which applies your macro in register w to each visually selected line.
See column editing in vim. It describes column insert, but basically it should work in the same way for removing.
You could also create a macro (q) that deletes the quotes and then drops down to the next line. Then you can run it a bunch of times by telling vi how many times to execute it. So if you store the macro to say the letter m, then you can run 100#m and it will delete the quotes for 100 lines. For some more information on macros:
http://vim.wikia.com/wiki/Macros
The other solutions are good. You can also try...
:1,$s/^"\(\w\+\)"/\1/gc
For more Vim regex help also see http://vim.wikia.com/wiki/Search_patterns.
Start visual-block by Ctrl+v.
Jump at the end and select first two columns by pressing: G, EE.
Type: :s/\%V"//g which would result in the following command:
:'<,'>s/\%V"//g
Press Enter and this will remove all " occurrences in the selected block.
See: Applying substitutes to a visual block at Vim Wikia