I'm learning vim with vimtutor. I was wondering if there is a difference between command motion number and number command motion.
For example:
2dw seems to me to work exactly like d2w, similarly 2dd does the same as d2d.
The two numbers are both called [count], in your example, indeed, they do same job. But the two counts come from different concept.
[count]command
this will do the command [count] times, 2dd does dd twice; 2dw does dw twice.
The second is from the {motion}, 2w, 2j etc.
If you want to see some differences, here are two I can think of:
Some commands don't support {motion}. For example, the X, you press 2X, will remove 2 characters before the cursor. However, you cannot do X{motion}. other commands that don't support {motion} p (paste), s etc. You can do 2p, 2s, but you cannot do p2w s3w
You get same result from 2dw and d2w, but the two 2 have different meaning, understanding what the number does is ok. you can combine the count and motion, like 2d3w.
The number command motion can use on all command, but number motion only in a few.
The most important is that repeat-action(.) redo the previous action.
Example:
2dd->. = 2dd->dd
d2d->. = d2d->d2d
Usually, I suggest use the first command. Because it is easier to be repeated.
Related
Is there a command to delete the current and previous line at the same time in vi? I have tried :-1,d but it won't work.
In normal mode, press d for delete. Then, press k for upward motion. This is a shorthand for d1k. You can increase the count to delete more than the current and previous line. For example, to delete the current line and the previous two lines, type d2k.
In general, most commands take motion and count modifiers. See the following Vim documentation for details:
The motion commands can be used after an operator command, to have the command
operate on the text that was moved over. That is the text between the cursor
position before and after the motion. Operators are generally used to delete
or change text. The following operators are available:
...
If the motion includes a count and the operator also had a count before it,
the two counts are multiplied. For example: "2d3w" deletes six words.
Motions and operators
-2dd
should achieve what you require. This will move up one line and then perform dd on 2 lines.
if you want it as a : command then
.,-1d
works for me
I would like to copy n more number of lines in a file. At the moment, I am doing this indirectly: From current line x, I use V<x+n>ggy where <x+n> is substituted with the actual sum.
Is there a way to copy directly n more lines from current line?
You don't need to go into visual mode (the V) for that. The normal mode yy command already takes a [count], but that includes the current line. So for n more lines, you need to pass a [count] of n + 1. Example: Yank current and 2 more lines (total 3): 3yy.
If you don't want to do the arithmetic, you can also use the :yank Ex command. The range there is specified as you want: current (.) until current plus n (.+n). Example: :.,.+2yank
Based on your preference to visual mode, and using gg instead of G to move to a line, it appears as if you're still new to Vim. Learn how to look up commands and navigate the built-in :help; it is comprehensive and offers many tips. You won't learn Vim as fast as other editors, but if you commit to continuous learning, it'll prove a very powerful and efficient editor.
Okay, I found the solution myself while playing around. n more lines can be simply copied by using: Vn+y
Imagine you need to change a few last letters in a word.
From
.. visualizing a graph?_
(_ denotes where the cursor is, mode:normal)
you need to arrive at
.. visualize| a graph?
(| denotes the cursor, mode:insert)
How would you do this?
(please suggest how would you really do this, not the "super-doper" way nobody uses)
I am asking, because I do this insanely inefficiently:
type b until reach _visualizing a graph?,
followed by e (visualizinG a graph?),
followed by x to remove g under cursor,
followed by few Shift+x to remove what is before the cursor,
and, finally, i switch into the insert mode and type e.
With given example, I would do:
Tzcwe
If there are just a few words between the cursor and where I want to go, I will use CTRL+left as many times as needed plus CTRL+right once and <bs> 3 times. I may also use the mouse. It's not that different from what you use, except I don't leave the insert mode for simple moves. Note this is exactly what I use when I type messages in my browser (I've never been conquered by vimperator & co).
I'm aware of <esc>gegege...3<left>cwe<esc>. But that's definitively not my first choice.
I may use T and F on symbols with few occurrences, but I seldom use them on letters as I'll spend more time detecting the best character to use than using CTRL+cursor as many times as needed. Beside, when I'm correcting what I've typed, it's likely that my mind is in "reread+correct/refactor sentences" mode, speed typing is not my priority.
I'm dealing with a fixed-width file format and I need to increase all of the numbers in some columns. I have a simple macro that adds a value to a number, moves to the next line and repeats (like 2aj) However, these numbers start from 1 and usually end above 10000, so the column widths get messed up, e.g. (underscores as spaces, this example only covering the jump from 9 to 10)
FOO_7_BAR
FOO_8_BAR
FOO_9_BAR
becomes
FOO_9BAR
FOO_10_BAR
FOO_11_BAR
(note the new column of text that will break my program)
when I need
FOO_9_BAR
FOO10_BAR
FOO11_BAR
I have been manual going through and deleting a space from the first 9 columns, then 90, then 900, but I am looking for a more robust way to handle this without dealing with the first 10, 100, 1000, etc. with different macros or any manual input.
Thanks.
I come up with this way, I think the animation explains itself:
The final result is:
FOO 3 BAR
FOO 4 BAR
FOO 5 BAR
FOO 6 BAR
FOO 7 BAR
FOO 8 BAR
FOO 9 BAR
FOO10 BAR
FOO11 BAR
This requires a bit of manual hackery, but it's still better than manually deleting spaces.
You could also probably write a function that does this automagically, via Vimscript, though!
First, find the length of the shortest line. You can do this via ex. :echo col("$") on the shortest line.
Then, run the following command:
:g/.\{NUM\}/exec "norm! /[0-9]\<cr>X"
Replace NUM in the above command with the original number you got in the previous step.
Here's an explanation of how it works:
:g/.\{NUM\}/ Find lines that are too long
exec "norm! A common idiom: build a string to execute in normal mode
/[0-9]<cr> Find the first number on the line
X Delete the space before it (equivalent to "hx")
Then simply repeatedly run the same command (you can do this by pressing :UpReturn) until all the lines are the same length—it will result in an error once this is the case (since it won't find any matching lines).
Here's a short animation of the entire process:
This can be done with :s and a sub-replace expression.
:%s/\v([^0-9]*)(\d+)/\=strpart(submatch(1), 0, 5 - len(submatch(2))).submatch(2)
The idea is we capture the portion before the digits and the digits themselves. The replacement execute an vim expression via \= which put the two capture groups back together. However slice the first capture group via strpart() to a fixed width (5 in this example) minus the length of our second capture group, len(submatch(2)).
For more help see:
:h sub-replace-expression
:h strpart()
:h len()
I have to add a VIM personality to an IDE. I never used VIM for more than the most basic edits and i'm now overwhelmed by the complexity of the command structure.
Is there any overall structure for the combination of counts moves and insert/delete commands?
I just can't see the wood for the trees.
Well, there is obviously a finger position pattern behind h, j, k, l.
The fact that ^ goes to the beginning of a line and $ goes to the end is patterned on common regular expression syntax.
Ctrl-F and Ctrl-B page forward and back, and that's fairly intuitive.
i inserts (before) and a appends (after the cursor). Similarly,
I inserts at the beginning of the line, and A appends at the very end.
> and < indent and outdent, respectively. That's also kind of intuitive.
But on the whole, many of the other commands are on whatever keys were left – it's hard to find an intuitive mapping between the letters of the alphabet and an editor's commands.
Repeat counts are always entered before a command, and mostly repeat the command that many times, but in some cases do something clever but analogous.
I think the secret to not going crazy over vi is to start out with only a small handful of commands. I have a lot of colleagues who don't know to do anything other than
move the cursor around using the arrow keys (you don't have to use h, j, k, l);
insert with i, delete with Del (you don't have to use x);
delete a line with dd
get out of input mode with Esc
get out of vi with :x (exit) or q! (quit, and throw away my changes!)
Because I'm much smarter, the additional commands I know and use are:
go to the top of the file with gg, the bottom with G.
I can go to a specified line number with (line-number)G.
copy a line with y (yank), paste it with p
change a word with cw, the rest of the line with C
delete a word with dw, the rest of the line with D
I sometimes use . to repeat the last command, or u (undo) if I messed up.
When you have occasion to use other commands, you can teach them to yourself one by one as needed.
This is a good article for explaining the VIM philosophy.
I think the characteristic that better defines VIM in respect to other editors is its wide array of motion commands. The first thing to learn to fully use VIM is hitting the arrow keys as little as possible, and think at the text in terms of "blocks" like "a sentence" "a tag" "a word" "a group of brackets".
Say you have function foo($bar, $fooz) you can change the parameters by simply positioning your cursor anywhere inside the brackets and pressing ci) (mnemonic: change inner bracket). The same pattern applies to other commands: yank (y), delete (d) and so on.
I know this doesn't explain the whole "VIM philosophy" but combining normal mode commands with the vast amount of motion modifiers is what really made me see the light.
There are plenty of nice and interesting tutorials. One example is
http://blog.interlinked.org/tutorials/vim_tutorial.html
But the broad structure that most of them would give you is
There are two main modes for editing - Command mode and insert mode. You can move from insert mode to command mode using the key.
You can execute commands in the command mode by typing a single key or a sequence of keys.
Commands can help you achieve a wide variety of things
deletion of lines - dd
yanking (copying of lines ) - yy
pasting lines below the current line - p
pasting lines above the current line - P ( and so on)
Most commands in the command mode can be pre-fixed by a "count" to indicate the number of times the command has to be executed. For example, 3dd would delete three lines.
One set of commands in the command mode lets you move to the insert mode. That is explained below.
There are different ways of entering the insert mode from the command mode. Prominent among them are (i-insert at cursor, I-insert at beginning of line, o-insert a line below, O-insert a line above, a-append, A-append at end of line.
The quick reference at
http://www.andy-roberts.net/misc/vim/vim.pdf
Will help you understand the relevance of "count"