what is the "count" in vim? - vim

Seeing the help of vim I have problem to understand what refers the word count I see it many times while reading the manual:
i Insert text before the cursor [count] times
It would be awesome if you give an example for it.

Vim's "Count" allows you to repeat an operator or command several times. For example, if you are on the first cursor of this line:
Hello world, how are you?
And you type dw you will have
world, how are you?
Rather than typing dwdwdwdw, you may simply type 4dw or d4w and you will have
are you?
More specific to your example, you may type something like 5ihello<esc> and this will insert
hellohellohellohellohello
Like Kevin said in a comment, you can read up more in the help docs with :h count, which says:
*count* *[count]*
[count] An optional number that may precede the command to multiply
or iterate the command. If no number is given, a count of one
is used, unless otherwise noted. Note that in this manual the
[count] is not mentioned in the description of the command,
but only in the explanation. This was done to make the
commands easier to look up. If the 'showcmd' option is on,
the (partially) entered count is shown at the bottom of the
window. You can use <Del> to erase the last digit (|N<Del>|).

Just in case somebody is wondering how count plus insert works, you have to type a number before pressing i, then it will enter in insert mode, where you can type what you want, after you press esc to go back to normal mode, it will repeat count times what you typed.

Can you provide a link to the place in the documentation where you are confused? I would have posted this as a comment instead of an answer, but my reputation is not high enough. In attempting to answer your question without clarification:
Usually [count] can be substituted with a number.
For example; consider the delete command d. If you position your cursor in the middle of a text line and type :d[count] (ex: :d4) then press an arrow key (left or right arrow); you will end up deleting [count] (e.g. 4 characters) in the corresponding direction of the arrow key.
In the case of insert I am not sure to what the argumentcount is referring.
EDIT: I forgot to mention that you must hit the enter key after :d4. Then press the left arrow key. Of course, in order for VIM to realize that you are entering a command you must exit insert mode by pressing the esc key prior to entering the command :d4.

Related

How to go back to previous when doing find replace confirm in vi?

Frequently when I am doing a find and replace in vi I will do it like this:
:%s/find/replace/gc
This gives you the option to skip by pressing n, or replace by pressing y. But, sometimes I will accidentally skip over one in a large file by pressing n when I meant to press y.
How do I go backwards to the previous one and give me a second change?
Essentially, how to I find (search) the other direction temporarily? thanks.
I'm not sure if you would like to interrupt current find-replace operation and resume it again. But if that is acceptable, here is my suggestion:
Start your find-replace the way you mentioned:
:%s/find/replace/gc
After you accidentally skip over a substitution by pressing n, interrupt the search by pressing <ctrl-C>
Press <shift-N> to go back to the previous occurrence of your find term
Run find-replace a little differently while you are at this word: :.,$s/find/replace/gc
Continue the operation
All this functionality works with vim native capabilities without having to install any addon.
Note: The .,$ range specifier indicates to perform :s (substitute) operation over a range of lines that start with current line (indicated by .) and until last line (indicated by $).
Note2: It might be known to you, but reiterating for anyone else who stumbles upon this post searching for something similar - The % range specifier indicates to perform :s (substitute) operation over all lines of currently active buffer.
This is not answer to the question, but a very good alternative. I recently discovered the CtrlSF plugin and it improves the search /replace process dramatically.
Basically, you have the search results in a buffer and you can do all the replacements in this single buffer.
In your scenario, you first do :CtrlSF find, get a buffer with all the matches in all files and then you do /find and move with n over your targets and change them (of course, you can actually change only the first one and then repeat the replacement with .).
If you miss some target, you just hit N to go back to the previous result and replace it.
Seems like you can't back to previous match using this pattern. Appeared bar propose following commands y/n/a/q/l/^E/^Y but no one of them will return backward to previous match.
But you can use little different pattern described bellow:
Type this /pattern replacing pattern with interested word;
Your cursor is navigated to first occurrence, if you don't need to change it press n it will navigates you to the next occurrence;
Since you understand you need to replace a word, do this by typing cw, this command cuts the forward word and turns you to insertion mode;
Type in desired text on the released place and press ESC to switch back to command mode;
Now again press n until desired occurrence;
Since you realize that you need to change an occurrence, just press on . it will repeat previously mentioned actions;
If you want to go back just use N.

c, i and s commands combined in VIM

I've been using VIM for a while and it surprises me each time. Under "Building Sentences" section in this tutorial, I saw the combination of commands cis and yip. I have used Vim quite a while and I am familiar with most commands in Normal Mode. I also know combining the commands in a meaningful way to produce combined actions.
However, the examples I showed above (cis and yip) totally broke my understanding of VIM command system in normal mode. "c" stands for change, "i" stands for insert and "s" stands for substitute but combined action is different than I would expect. I also went through VIM help files but never saw an example illustrating given usage.
Could someone clarify what's going on ?
cis
In vim help it is described as follows
:help c
"Delete {motion} text [into register x] and start insert …"
The next part of the command cis refer to the "motion" part. These commands are for text object selection. An explanation on the different types of text object selections can you get here:
:help text-objects
e.g. for
is – "inner sentence", select [count] sentences …
Analog to the explanation above its the same with yip
:help y
"Yank {motion} text [into register x] … "
And the text selection part yip
ip – "inner paragraph", select [count] paragraphs (see paragraph) …
In this case i does not stand for Insert and s not for substitute.
cis = change inner sentence.
This is completly logic once you understand the basic principle. Each command is like a sentence, it needs an Verb(Action) and an Noun(Object) and there are modifiers.
So the first button is your action C (Change). Now the following keystrokes will not be actions, until the c action ended (Until an Object is provided, or an invalid sequence is inserted). I (inner) is a modifier here and S the Object (Sentence).
I find this especially usefull for Changing words. if you only press cw on a word, you have to have the cursor on the beginning of the word.
With ciw you can change the whole word regardless of the cursor position (Note if you have / or some other seperators in the word, you maybe need ciW)
same letter can have different meanings. E.g. (/{ move to sentences/paragraph back, but ci( or ci{ means change in (...)/{...}.
Same as your s case, s in normal mode alone, does delete & start insert, however in cis, das means sentence.
p case: in normal mode alone, means paste, however in cip, yap ... means paragraph.
:h text-objects
will show you the concept of text-objects. It is a must skill for vim user. ;-)

How do I get fine-grained undo in Vim

I find Vim's undo to be a bit too coarse. E.g. if I type something like this:
a // to go into edit mode
to be or not to ve
<esc> // to exit insert mode
Oops! I made a typo. I want to start undoing so I press u, but then it clears the whole line. Is there a way to undo word-by-word or character-by-character?
You can break undos via :help i_ctrl-g_u. You can map this if you want for every character, but that might a little bit complicated. Mapping this to space button is a way.
:inoremap <Space> <Space><C-g>u
After that every word can be undo via u
So as you see from the others what you are asking for doesn't exist in Vi (AFAIK).
Undo undoes what your last action was. If your last action was to enter insert mode and then add a line and then exit insert mode. That will be undone, however if from the default mode you hit the "x" key then you will delete 1 character or if in visual mode with text selected the text will be deleted. If you hit undo then you will restore that one character or the text that was selected.
...You should think of this as an action, and actions can be atomically undone or restored
As mentioned previously if you wish to delete the previous word then you should be able to hit Ctrl + w and delete the previous word while remaining in insert mode.
If you exit insert mode you can navigate (motion) back a word with "b" forward a word with "w" to the end of a word with "e", and can cut (which leaves you in insert mode) with "c" or delete with "d". Both actions cut and delete can accept a motion following them so you can delete the current word / up to the next word with "dw" or cut the previous word with "cb"
This concept becomes more useful when you remember to use the "." command (in normal mode). This command is to repeat the last action. I have used this many times to find and replace a small group of words in a file (It is especially useful if you are paranoid about changing too much). The scenario would be the following:
File:
This is my post
really it is a test
this is the middle
This is the end
if I wanted to replace "is" with "was" I could write:
%s/\<is\>/was/g
however if I wanted to change the first line and the third line "is" to "was" (and I didn't know their line numbers, and I wanted to see if there were any other places I wanted to change is to was I could type
"/is"
hit "n" until I reach the place I want substituted, and then hit "cw" and type "was"
I can now hit "n" until I reach another place I want substituted and hit ".", and that will replace "is" with "was" (Note: my search string didn't limit to the word "is", just the two characters "is" so "This" & "this" will match in this case)
No, it is not possible and is actually not necessary either. Vim has a million ways of dealing with that. Try cb for example. Or bC. Or brb. Or Tspace to jump back instead of b. Or ciw.
You can, of course use most of these solutions in insert mode (by pressing CTRLo first), or bind one to your favorite key combination (:help map and :help imap).
On Linux, using control-w while in input mode deletes the last 'word'.

Is there some pattern behind the many VIM commands?

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"

How to repeat a command with substitution in Vim?

In Unix the ^ allows you to repeat a command with some text substituted for new text. For example:
csh% grep "stuff" file1 >> Results
grep "stuff" file1
csh% ^file1^file2^
grep "stuff" file2
csh%
Is there a Vim equivalent? There are a lot of times I find myself editing minor things on the command line over and over again.
Specifically for subsitutions: use & to repeat your last substitution on the current line from normal mode.
To repeat for all lines, type :%&
q: to enter the command-line window (:help cmdwin).
You can edit and reuse previously entered ex-style commands in this window.
Once you hit :, you can type a couple characters and up-arrow, and it will character-match what you typed. e.g. type :set and it will climb back through your "sets". This also works for search - just type / and up-arrow. And /abc up-arrow will feed you matching search strings counterchronologically.
There are 2 ways.
You simply hit the . key to perform an exact replay of the very last command (other than movement). For example, I type cw then hello to change a word to "hello". After moving my cursor to a different word, I hit . to do it again.
For more advanced commands like a replace, after you have performed the substition, simply hit the : key then the ↑ up arrow key, and it fills your command line with the same command.
To repeat the previous substition on all lines with all of the same flags you can use the mapping g&.
If you have made a substitution in either normal mode :s/A/B/g (the current line) or visual mode :'<,>'s/A/B/g (lines included in the current selection) and you want to repeat that last substitution, you can:
Move to another line (normal mode) and simply press &, or if you like, :-&-<CR> (looks like :&), to affect the current line without highlighting, or
Highlight a range (visual mode) and press :-&-<CR> (looks like :'<,'>&) to affect the range of lines in the selection.
With my limited knowledge of Vim, this solves several problems. For one, the last visual substitution :'<,'>s/A/B/g is available as the last command (:-<UP>) from both normal and visual mode, but always produces an error from normal mode. (It still refers to the last selection from visual mode - not to the empty selection at the cursor like I assumed - and my example substitution exhausts every match in one pass.) Meanwhile, the last normal mode substitution starts with :s, not :'<,'>s, so you would need to modify it to use in visual mode. Finally, & is available directly from normal mode and so it accepts repetitions and other alternatives to selections, like 2& for the next two lines, and as user ruohola said, g& for the entire file.
In both versions, pressing : then & works as if you had pressed : and then retyped s/A/B/, so the mode you were in last time is irrelevant and only the current cursor line or selection determines the line(s) to be affected. (Note that the trailing flags like g are cleared too, but come next in this syntax too, as in :&g/: '<,'>&g. This is a mixed blessing in my opinion, as you can/must re-specify flags here, and standalone & doesn't seem to take flags at all. I must be missing something.)
I welcome suggestions and corrections. Most of this comes from experimentation just now so I'm sure there's a lot more to it, but hopefully it helps anyway.
Take a look at this: http://vim.wikia.com/wiki/Using_command-line_history for explanation.

Resources