How to add text at the end of each line in Vim? - vim

In Vim, I have the following text:
key => value1
key => value2
key => value1111
key => value12
key => value1122222
I would like to add "," at the end of each line. The previous text will become the following:
key => value1,
key => value2,
key => value1111,
key => value12,
key => value1122222,
Does anyone know how to do this? Is it possible to use visual block mode to accomplish this?

This will do it to every line in the file:
:%s/$/,/
If you want to do a subset of lines instead of the whole file, you can specify them in place of the %.
One way is to do a visual select and then type the :. It will fill in :'<,'> for you, then you type the rest of it (Notice you only need to add s/$/,/)
:'<,'>s/$/,/

There is in fact a way to do this using Visual block mode. Simply pressing $A in Visual block mode appends to the end of all lines in the selection. The appended text will appear on all lines as soon as you press Esc.
So this is a possible solution:
vip<C-V>$A,<Esc>
That is, in Normal mode, Visual select a paragraph vip, switch to Visual block mode CTRLV, append to all lines $A a comma ,, then press Esc to confirm.
The documentation is at :h v_b_A. There is even an illustration of how it works in the examples section: :h v_b_A_example.

Another solution, using another great feature:
:'<,'>norm A,
See :help :normal.

ex mode is easiest:
:%s/$/,
: - enter command mode
% - for every line
s/ - substitute
$ - the end of the line
/ - and change it to
, - a comma

The substitute command can be applied to a visual selection. Make a visual block over the lines that you want to change, and type :, and notice that the command-line is initialized like this: :'<,'>. This means that the substitute command will operate on the visual selection, like so:
:'<,'>s/$/,/
And this is a substitution that should work for your example, assuming that you really want the comma at the end of each line as you've mentioned. If there are trailing spaces, then you may need to adjust the command accordingly:
:'<,'>s/\s*$/,/
This will replace any amount of whitespace preceding the end of the line with a comma, effectively removing trailing whitespace.
The same commands can operate on a range of lines, e.g. for the next 5 lines: :,+5s/$/,/, or for the entire buffer: :%s/$/,/.

:%s/$/,/g
$ matches end of line

If you want to add ',' at end of the lines starting with 'key', use:
:%s/key.*$/&,

I have <M-DOWN>(alt down arrow) mapped to <DOWN>. so that I can repeat the last command on a series of lines very quickly. with this mapping I can:
A,<ESC>
And then hold alt while pressing down repeatedly to append the comma to the end of each line.
This works well for me because it allows very good control over what lines do and do not get the change.
(I also have the other arrows mapped similarly to allow for easy repeating of .)
Here's the mapping line to paste into your vimrc:
map <M-DOWN> <DOWN>.

Following Macro can also be used to accomplish your task.
qqA,^[0jq4#q

Related

vim - surround text with function call

I want to wrap some code :
myObj.text;
with a function call where the code is passed as an argument.
console.log(myObj.text);
I've thought about using surround.vim to do that but didn't manage to do it.
Any idea if it's possible ? I
With Surround in normal mode:
ysiwfconsole.log<CR>
With Surround in visual mode:
Sfconsole.log<CR>
Without Surround in normal mode:
ciwconsole.log(<C-r>")<Esc>
Without Surround in visual mode:
cconsole.log(<C-r>")<Esc>
But that's not very scalable. A mapping would certainly be more useful since you will almost certainly need to do it often:
xnoremap <key> cconsole.log(<C-r>")<Esc>
nnoremap <key> ciwconsole.log(<C-r>")<Esc>
which brings us back to Surround, which already does that—and more—very elegantly.
I know and use two different ways to accomplish this:
Variant 1:
Select the text you want to wrap in visual mode (hit v followed by whatever movements are appropriate).
Replace that text by hitting c, then type your function call console.log(). (The old text is not gone, it's just moved into a register, from where it will be promptly retrieved in step 3.) Hit <esc> while you are behind the closing parenthese, that should leave you on the ) character.
Paste the replaced text into the parentheses by hitting P (this inserts before the character you are currently on, so right between the ( and the )).
The entire sequence is v<movement>c<functionName>()<esc>P.
Variant 2:
Alternatively to leaving insert mode and pasting from normal mode, you can just as well paste directly from insertion mode by hitting <ctrl>R followed by ".
The entire sequence is v<movement>c<functionName>(<ctrl>R")<esc>.
You can use substitution instruction combined with visual mode
To change bar to foo(bar):
press v and select text you want (plus one more character) to surround with function call (^v$ will select whole text on current line including the newline character at the end)
type :s/\%V.*\%V/foo\(&\)/<CR>
Explanation:
s/a/b/g means 'substitute first match of a with b on current line'
\%V.*\%V matches visual selection without last character
& means 'matched text' (bar in this case)
foo\(&\) gives 'matched text surrounded with foo(...) '
<CR> means 'press enter'
Notes
For this to work you have to visually select also next character after bar (^v$ selects also the newline character at the end, so it's fine)
might be some problems with multiline selections, haven't checked it yet
when I press : in visual mode, it puts '<,'> in command line, but that doesn't interfere with rest of the command (it even prevents substitution, when selected text appears also somewhere earlier on current line) - :'<,'>s/... still works

How to use Vim to do multiple line edit

I have text like this:
w ky,
wyz,
wyy,
wj,
w w,
and I want to change it to this:
"w ky",
"wyz",
"wyy",
"wj",
"w w",
I do it now using:
record a macro to insert double quota in one line, then go to next line qa0wi"$i"j
then just type 4#a
Yes, it works, but is there an easier way to do this?
There is an easier way. You can use the norm command. I would recommend this:
Visually select all of the lines
Type
:norm I"<C-v><esc>$i"<cr>
When you actually type this (before hitting enter), the text that should be shown in your command line is:
:'<,'>norm I"^[$i"
The norm command tells vim to simulate a set of normal mode keystrokes on certain lines. In this case, the command is:
:'<,'> " On every line in the visual selection:
norm " Do the following as if typed in normal mode:
I"<esc>$i" " Insert an '"', escape, then insert a '"' at the end (before the comma)
You can also do this without using a visual selection, by typing <n>:norm ..., and the command will apply the current n lines. (the current line and the next n-1 lines)
Doing a "very magic search \v" we can search...
\v(\w ?\w+),
\v ........... starts very magic search mode
( ........... starts group one
\w ........... any word
? ........... optional space
+ ........... one or more
) ........... ends group one
After testing the search we can pass into our command or
use the last search by placing two slashes on the search pattern
%s/\v(\w ?\w+),/"\1",/g
%s//"\1",/g
everything matched on group one can be referred by \1.
Do a basic multi-line edit at the front then do a string replace on , with ",.

Indent or comment several text lines with vi

can vim or vim be used to comment or indent at the same time a number of lines? For instance:
for item in Lista:
ind = int(floor(1.0*(item-lmin)/width))
if ind==nintervals:
ind=ind-1
print item,ind
comment it to:
#for item in Lista:
#ind = int(floor(1.0*(item-lmin)/width))
#if ind==nintervals:
#ind=ind-1
#print item,ind
or indent it to:
for item in Lista:
ind = int(floor(1.0*(item-lmin)/width))
if ind==nintervals:
ind=ind-1
print item,ind
P.D. Is relevant the difference between VI and VIM?
here is another way.
block lines with ctrl+v
Insert comment sign (//) with I
escape with ESC
the key typing is
ctrl+v → jjjj → I → // → ESC
To comment, press a capital V to enter VISUAL LINE mode, select all lines, then press : to enter command mode and use the command (note that VIM already include the '<,'>marks for you):
:'<,'>s/^/#/
If you prefer hash marks near the text, and not near the left margin, the command is:
:'<,'>s/^\(\s*\)/\1#/
To indent, select the block the same, then type > to indent, < to unindent.
type :set number. take note of the start and end line number of the block you want to comment. then do an address range substitution, eg
:12,17s/^/#
Lots of answers here, all with a theme. The best way to do it really depends on context (because context determines the easiest navigation method), so I'll make some assumptions about the context. If the section you want to indent or comment is a single paragraph (eg, you want to indent or comment everything from the cursor up to the next blank line), you can indent with:
>)
If the cursor is not on the start of the paragraph, but the section you want to indent is a single paragraph and the cursor is in the middle, use
>ip
Finally, suppose you want to indent a block of code delimited by {}, and the cursor is in the middle of that block. Use
>i{
To comment, in each case just replace the > with v and use the above commands to make a block selection, then do a text replace like s/^/#/.
The key is the navigation commands. I highly recommend
:help v_a
Similar to the accepted answer, but easier for blocks or paragraphs:
Block lines: Ctrl + V
Select paragraph: }
Insert mode: I (uppercase i)
Type character to insert: # (with space after char, no Enter!)
Press: ESC
This should auto complete the character in all the selected block.
Basically the diference with the accepted answer is that instead of using j to go down line by line you use } to select the whole paragraph (or you could use G for end of file, for ex.
Short version:
Ctrl + V + } + I + # + ESC
I know there are a zillion answers here already explaining how to use > and < for indentation, so I'm not going to bother with that. With respect to the commenting, though, while you can do it quick and dirty with a block insert or a substitution, you can do way better with the NERD Commenter plugin. It provides commands to comment and uncomment in various ways, it knows what comment symbol to insert based on the syntax, and it can do pretty multi-line comments if the language supports them.
Select the lines using visual mode.
To indent once type >> or << to indent right or left respectively. To indent n times type n>> or n<<.
To comment out do replace the beginning of the line with the comment:
:'<,'>s/^/#/
'<,'> means "from the beginning of the selection until the end.
s/^/#/ replaces the beginning of each line in the range with #, assuming # makes a line into a comment.
Put your cursor on the first line, count how many lines should be indented, in the above example it's 5, then for hash (#) type
:.,.+5%s/^\([ <tab>]*\)/#\1/<enter> or for a tab indentation,
:.,.+5%s/^\([ <tab>]*\)/<tab>\1/<enter>,
<tab> and <enter> are the tab and enter keys.
There are probably more elegant ways of doing this, but something like this is a quick-n-dirty thing.
For commenting you could use VISUAL BLOCK selection (Ctrl-V) and select the beginnings of the lines, then press Shift-I and write one #. After pressing Esc all the lines get the #.
My usual solution is:
<ESC>
<q><a> => start a macro and save it as macro a
<^> => to get to the start of the line
<i> => insert mode
<#> => Add the #
<ESC> => End insert mode
<down> => Move to the next line
<q> => End macro
Then once:
<[at]><a> => repeat macro a
Then just repeat <[at]><[at]> (repeat last executed macro) until all lines are commented. You can just hold <[at]> and let keyboard repeat do the rest.
BTW: How do you write an [at] sign here without stackoverflow turning it into "> blockquote"?
To indent:
[shift] + [v] => line select mode
[down] => until all lines to indent are selected
then:
[>] => indent once
or:
[2..x][>] => indent 2..x levels
If you are using Python (or other languages that use # as comment), a faster way to comment multiple lines would be:
Enter visual block mode (Ctrl+v) from the start of the line.
Go down as needed (j multiple times).
Replace space with # by pressing r then #.
To uncomment, do the same but for step three replace it with space.

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