Difference between append and insert mode in Vim - vim

I noticed this accidentally when playing around in vimtutor. What's the difference between append and insert mode in Vim? When I type a in normal mode (not A) I can insert text. When should I use one and not the other?

The append command will put the cursor after the current position, while the insert command will put the cursor before it.
Using the append command is like moving the cursor one character to the right, and using the insert command.
Using the insert command is like moving the cursor one character to the left, and using the append command.
You choose which depending on where you want to start typing.

Note that vimtutor doesn't initially make the case of the command obvious:
SHIFT+A (capital A, as opposed to a) the cursor moves to the end of the current line.
SHIFT+I (capital I, as opposed to i)moves to the start of the current line.

Another important aspect on Append is that if the position after the current position is a empty space followed by a word. After you are done writing it will concatenate both words.
E.g. A file with the following text:
Hi there.
With the cursor on i. After pressing the a button and then ESC you would have:
Hithere.

Related

How to delete, including the current character?

Let's say I've typed "abcdefg", with the cursor at the end. I want to delete back to the c, so that I only have "abc" left.
Is there a command like d that includes the current character? I know I could do dTcx, but the x feels like a work-around and I suppose there's a better solution.
No. Backward motions always start on the left of the current character for c, y and d which is somehow logical but also unnerving.
The only "clean" solutions I could think of either imply moving to the char after c first and then do a forward delete:
Tcde
or using visual mode:
vTcd
v3hd
But, given your sample and assuming you are entering normal mode just for that correction, the whole thing sounds extremely wasteful to me.
What about staying in insert mode and simply doing ←←←←?
try this:
TcD
this will leave abc for your example... well if the abcdefg is the last word of the line.
if it is not the last word in that line, you may do:
ldTc
or golfing, do it within 3 key-stroke:
3Xx or l4X
See this answer to a similar question : there is a setting to be allowed to go beyond the end of the line
From the doc :
Virtual editing means that the cursor can be positioned where there is
no actual character. This can be halfway into a tab or beyond the end
of the line. Useful for selecting a rectangle in Visual mode and
editing a table.
"onemore" is not the same, it will only allow moving the cursor just
after the last character of the line. This makes some commands more
consistent. Previously the cursor was always past the end of the line
if the line was empty. But it is far from Vi compatible. It may also
break some plugins or Vim scripts. For example because |l| can move
the cursor after the last character. Use with care!
Using the $ command will move to the last character in the line, not
past it. This may actually move the cursor to the left!
The g$ command will move to the end of the screen line.
It doesn't make sense to combine "all" with "onemore", but you will
not get a warning for it.
In short, you could try :set virtualedit=onemore, and see if your environment is stable or not with it.
Use d?c
That will start d mode, search back to 'c' and then delete up to your cursor position.
Edit: nope, that does not include current position...
I may be misunderstanding your request, but does 3hd$ do it?
I would use vFdd in this example. I think it's nicer than the other solutions since the command explicitly shows what to delete. It includes the current character and the specified character when deleting.
v: enter visual mode (mark text)
F: find/goto character backwards
d: the character "d" that will be included for removal.
d: delete command
Since it is visual mode, the cursor can also be moved before executing the actual removal d. This makes the command powerful even for deleting up to a non unique character by first marking a special character close to the character and then adjusting the position.

Can vim markers work with the repeat key?

I regularly use the . key to repeat my last vim command. I'm wondering if there's a way to use it with commands performed using markers. Here's a simple example:
Mark a line of text using m'a
Move down a few lines, e.g. 5j
Indent the lines using >'a -- indents 6 lines
Press . to repeat above command on the same 6 lines -- will only affect 1st line
Is there a way to get vim to apply the same marker range of the previous command when using the . command?
ps. I know the above example would have been easier with 6>>, which works with the ., I'm just using it as an example. I often use markers for more complex/longer commands.
The problem is that the command you're repeating is >'a, but because of the rule "After applying the operator the cursor is mostly left at the start of the text that was operated upon" (from :help operator), >'a leaves the cursor at mark a if that was above your starting position. Then when you repeat >'a you end up with a linewise motion from that line to itself, which only re-indents one line.
Since you're left at the beginning of the block of text, to affect the same block of text again you can use the '] (linewise) or `] (charwise) motions, which move to the end of the block of text just affected. So you can use >'] to indent the same block again, and since your cursor starts and ends at the same position this time, you can repeat it additional times with ..
A simpler choice, though, would be to just use V5j> instead of ma5j>'a. V starts visual mode (linewise) at your current position, 5j moves down 5 lines, and then > indents. And when you repeat using ., the same visual selection still pertains, so you get the desired result whether you moved up or down.

Vim: insert text from a file at current cursor position

To insert text from a file in the current Vim buffer I use :r filename to insert the text below the cursor or :0r filename to insert in the first line.
How do you insert the contents of a file where [Cursor] is located?
Actual line with some coding [Cursor] // TODO for later version
Line below actual line ...
This inserts the contents of the file whose path is at the cursor position:
:r <cfile>
Insert a line break, read the file, and then take out the line break...
I propose Ctrl-R Ctrl-O = join(readfile('filename','b'), "\n")
Other solution:
Possibly open the other file in another window, use :%yh (h is a register name) and in your original file, in normal mode use "hp or "hP or in insert mode, Ctrl-R Ctrl-O h
To expand on the accepted answer with actual code, since I tried the suggestion and it worked nicely;
Here is an example of it working to insert a little php snippet:
`nnoremap <leader>php a<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
In general the syntax is
`nnoremap [KEY SEQUENCE] a<CR><ESC>:.-1read [FILE PATH]<CR>I<BS><ESC>j0i<BS><ESC>l`
Just to break it down:
nnoremap : I'm about to define a new key mapping for normal mode
<leader>php : I would like to trigger the command sequence when this key combination is pressed. In my case <leader> is , so I type ,php to trigger the command.
Now for the command, bit by bit:
a<CR><ESC> : go into insert mode (after the cursor), insert a line break, go back into normal mode.
:.-1read <file><CR> : this enters the desired file on the line above the current line.
I<BS><ESC> : jump to the start of the line, delete line break, return to normal mode.
j0i<BS><ESC>l : Go down one line (to the remainder of the line that you were initially on), jump to the start, enter insert mode, delete the line break, return to normal mode.
l : position the cursor to the right of the pasted file (this just made the command work more like how you expect it to).
note
You have a choice of whether to paste before or after the cursor. I have chosen in this example to paste after the cursor because that is how the p command usually works to paste yanked text. Alternately, to paste before the cursor you should change the a at the start of the command to an i. You could use one of these exclusively, or you could bind them both to different but related key sequences. For example:
`nnoremap <leader>php i<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
Could paste text before the cursor,
and :
`nnoremap <leader><leader>php a<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
could paste text after the cursor. Or vice versa. I have made 'before the cursor' easier to trigger because I use it more often when pasting in-line.
other note
This solution is mainly useful if you're reading from a file that you expect to use often enough that it's worthwhile setting up a key mapping for it (ie reading a snippet from a file). This doesn't really help if you just want to read in a random files whenever since you won't have the key mapping ready.
Since it is very formulaic, I'm sure it would be possible to define a function that would take the file name as an argument and do the same thing though. I've never written a function in vimscript though so if someone who knows more feels like editing this answer to contain that solution - I urge them to do so!
" put this in your ~/.vimrc
" in insert mode press ,n
"
imap ,n <c-r>=expand("%:p")<cr>
Read more in wikia.

How can I insert text in the middle of the line to multiple lines in Vim?

Say I have ten lines and I want to prepend text to some word that occurs in those lines? It does not have to be at the beginning of the line.
From:
sdfsd foo sdfsd
sfsd foo fsdf
sdfsdf foo sdfsdf
to:
sdfsd bar(foo sdfsd
sfsd bar(foo fsdf
sdfsdf bar(foo sdfsdf
Is it also possible to not only prepend the bar( but actually surround foo with bar(foo)?
I would also like a quick way to append // comments to multiple lines (C-style comments).
I use Vim/GVim 7.2.
Go to the first foo, press Ctrl-v to enter visual block mode and press down until all the lines with foo are marked. Then press Shift-i to insert at the beginning (of the block). When you are finished and press Esc, the inserted characters will be added to each line at the left of the marked block.
To insert at the end, press again Ctrl-v, move up/down to mark all affected lines and then press End or $ to extend the selection until the end of the lines. Now you can press Shift-a to append at the end of all the lines, just like previously with Shift-i.
The visual selection can also be done with normal movement commands. So to comment a whole block in C you could move to the opening brace and type Ctrl-v % Shift-i // Esc.
To answer your first question, the below
:%s/foo/bar(&)/g
will look for foo, and surround the matched pattern with bar(). The /g will do this multiple times in one line.
Since you're just matching foo, you could do a simple :s/foo/bar(foo)/g. The above will work, however, if you decide to match on a regular expression rather than a simple word (e.g. f[a-z][a-z]). The '&' in the above represents what you've matched.
To prefix a set of lines I use one of two different approaches:
One approach is the block select (mentioned by sth). In general, you can select a rectangular region with ctrl-V followed by cursor-movement. Once you've highlighted a rectangle, pressing shift-I will insert characters on the left side of the rectangle, or shift-A will append them on the right side of the rectangle. So you can use this technique to make a rectangle that includes the left-most column of the lines you want to prefix, hit shift-I, type the prefix, and then hit escape.
The other approach is to use a substitution (as mentioned by Brian Agnew). Brian's substitution will affect the entire file (the % in the command means "all lines"). To affect just a few lines the easiest approach is to hit shift-V (which enables visual-line mode) while on the first/last line, and then move to the last/first line. Then type:
:s/^/YOUR PREFIX/
The ^ is a regex (in this case, the beginning of the line). By typing this in visual line mode you'll see '<,'> inserted before the s automatically. This means the range of the substitution will be the visual selection.
Extra tip: if your prefix contains slashes, you can either escape them with backslash, or you can use a different punctuation character as the separator in the command. For example, to add C++ line comments, I usually write:
:s:^:// :
For adding a suffix the substitution approach is generally easier unless all of your lines are exactly the same length. Just use $ for the pattern instead of ^ and your string will be appended instead of pre-pended.
If you want to add a prefix and a suffix simultaneously, you can do something like this:
:s/.*/PREFIX & SUFFIX/
The .* matches the whole line. The & in the replacement puts the matched text (the whole line) back, but now it'll have your prefix and suffix added.
BTW: when commenting out code you'll probably want to uncomment it later. You can use visual-block (ctrl-V) to select the slashes and then hit d to delete them, or you can use a substitution (probably with a visual line selection, made with shift-V) to remove the leading slashes like this:
:s:// ::
:normal to the rescue!
:%norm Wibar(
:%norm WEa)
:norm(al) replays the commands as if you had typed them:
W - goes to the next word
i - starts insertion mode
bar( - types the sequence 'bar('
Or in one line:
:%norm Wibar(ctrlvESCEa)
If you're running Windows then type ctrlq instead of ctrlv.
Yet another possibility (probably not-so-useful in your test case, but handy in other situations) is to cordon off the area you want to change with marks.
Put the cursor anywhere in the top line and press 'a
Put the cursor anywhere in the last line and press 'b
Issue the command :'a,'b s/foo/bar(&)/
I usually like visual block mode if everything is visible on the screen, and I usually prefer marks if the start and stop are separated by many screens.
Another simple regular expression is:
%s/^/<text you want to prepend>/
For the C-style comments, use the regexp answer by Brian, and match on line ending $, and insert away.

In Vim, what is the best way to select, delete, or comment out large portions of multi-screen text?

Selecting a large amount of text that extends over many screens in an IDE like Eclipse is fairly easy since you can use the mouse, but what is the best way to e.g. select and delete multiscreen blocks of text or write e.g. three large methods out to another file and then delete them for testing purposes in Vim when using it via putty/ssh where you cannot use the mouse?
I can easily yank-to-the-end-of-line or yank-to-the-end-of-code-block but if the text extends over many screens, or has lots of blank lines in it, I feel like my hands are tied in Vim. Any solutions?
And a related question: is there a way to somehow select 40 lines, and then comment them all out (with "#" or "//"), as is common in most IDEs?
Well, first of all, you can set vim to work with the mouse, which would allow you to select text just like you would in Eclipse.
You can also use the Visual selection - v, by default. Once selected, you can yank, cut, etc.
As far as commenting out the block, I usually select it with VISUAL, then do
:'<,'>s/^/# /
Replacing the beginning of each line with a #. (The '< and '> markers are the beginning and and of the visual selection.
Use markers.
Go to the top of the text block you want to delete and enter
ma
anywhere on that line. No need for the colon.
Then go to the end of the block and enter the following:
:'a,.d
Entering ma has set marker a for the character under the cursor.
The command you have entered after moving to the bottom of the text block says "from the line containing the character described by marker a ('a) to the current line (.) delete."
This sort of thing can be used for other things as well.
:'a,.ya b - yank from 'a to current line and put in buffer 'b'
:'a,.ya B - yank from 'a to current line and append to buffer 'b'
:'a,.s/^/#/ - from 'a to current line, substitute '#' for line begin
(i.e. comment out in Perl)
:'s,.s#^#//# - from 'a to current line, substitute '//' for line begin
(i.e. comment out in C++)
N.B. 'a (apostrophe-a) refers to the line containing the character marked by a. ``a(backtick-a) refers to the character marked bya`.
To insert comments select the beginning characters of the lines using CTRL-v (blockwise-visual, not 'v' character wise-visual or 'V' linewise-visual). Then go to insert-mode using 'I', enter your comment-character(s) on the first line (for example '#') and finally escape to normal mode using 'Esc'. Voila!
To remove the comments use blockwise-visual to select the comments and just delete them using 'x'.
Use the visual block command v (or V for whole lines and C-V for rectangular blocks). While in visual block mode, you can use any motion commands including search; I use } frequently to skip to the next blank line. Once the block is marked, you can :w it to a file, delete, yank, or whatever. If you execute a command and the visual block goes away, re-select the same block with gv. See :help visual-change for more.
I think there are language-specific scripts that come with vim that do things like comment out blocks of code in a way that fits your language of choice.
Press V (uppercase V) and then press 40j to select 40 lines and then press d to delete them. Or as #zigdon replied, you can comment them out.
The visual mode is the solution for your main problem. As to commenting out sections of code, there are many plugins for that on vim.org, I am using tComment.vim at the moment.
There is also a neat way to comment out a block without a plugin. Lets say you work in python and # is the comment character. Make a visual block selection of the column you want the hash sign to be in, and type I#ESCAPE. To enter a visual block mode press C-q on windows or C-v on linux.
My block comment technique:
Ctrl+V to start blockwise visual mode.
Make your selection.
With the selection still active, Shift+I. This put you into column insert mode.
Type you comment characters '#' or '//' or whatever.
ESC.
Or you may want to give this script a try...
http://www.vim.org/scripts/script.php?script_id=23
For commenting out lines, I would suggest one of these plugins:
EnhancedCommentify
NERD Commenter
I find myself using NERD more these days, but I've used EnhancedCommentify for years.
If you want to perform an action on a range of lines, and you know the line numbers, you can put the range on the command line. For instance, to delete lines 20 through 200 you can do:
:20,200d
To move lines 20 through 200 to where line 300 is you can use:
:20,200m300
And so on.
Use Shift+V to go in visual mode, then you can select lines and delete / change them.
My usual method for commenting out 40 lines would be to put the cursor on the first line and enter the command:
:.,+40s/^/# /
(For here thru 40 lines forward, substitute start-of-line with hash, space)
Seems a bit longer than some other methods suggested, but I like to do things with the keyboard instead of the mouse.
First answer is currently not quite right?
To comment out selection press ':' and type command
:'<,'>s/^/# /g
('<, '> - will be there automatically)
You should be aware of the normal mode command [count]CTRL-D.
It optionally changes the 'scroll' option from 10 to [count], and then scrolls down that many lines. Pressing CTRL-D again will scroll down that same lines again.
So try entering
V "visual line selection mode
30 "optionally set scroll value to 30
CTRL-D "jump down a screen, repeated as necessary
y " yank your selection
CTRL-U works the same way but scrolls up.
v enters visual block mode, where you can select as if with shift in most common editors, later you can do anything you can normally do with normal commands (substitution :'<,'>s/^/#/ to prepend with a comment, for instance) where '<,'> means the selected visual block instead of all the text.
marks would be the simplest mb where u want to begin and me where u want to end once this is done you can do pretty much anything you want
:'b,'ed
deletes from marker b to marker e
commenting out 40 lines you can do in the visual mode
V40j:s/^/#/
will comment out 40 lines from where u start the sequence

Resources