Using Vim, how can I print the numbers, say, 1 through 100 on consecutive lines?
e.g.
1
2
3
.
.
100
Type:
1
Then record a macro:
qa (start recording a macro stored in register a)
yy (copies the line)
p (inserts that line below)
CTRL+A (increases number by one)
q (stops recording)
Next you can invoke that macro 99 times, by:
99#a
One way:
:call append( 0, range(1,100) )
First parameter is line number to begin the insert. Use line() function to choose another one.
Type 1 on the first line in insert mode. Leave insert mode.
Then enter in 'macro mode' with qa
type yyp then CTRLA
Leave macro mode by retyping q
Now type 98#a to invoke 98 times the macro creating the new line and increasing by one the count
You can use a simple for loop:
:for i in range(1, 100) | silent put = i | endfor
In insert mode: CTRL-R=join(range(1,100),"\n")Enter.
If you're not in insert mode it's tricky because you have to escape " and | :
:put =join(range(1,100),\"\n\")
Related
Let us assume that file 'file.txt' contains:
31
37
14
I would like to insert those lines into certain places of a Vim buffer (using perhaps visual block mode with Ctrl-v ??).
In other words, if file 'text.txt' contains
This is the beginning of a file with several lines
Age of Person A: ; Other info...
Age of Person B: ; Other info...
Age of person C: ; Other info...
This is the end of the file.
is it possible to insert the corresponding lines of 'file.txt' into the places before the ';' character at each selected line?
The desired result would be:
This is the beginning of a file with several lines
Age of Person A: 31; Other info...
Age of Person B: 37; Other info...
Age of person C: 14; Other info...
This is the end of the file.
Thanks.
Yes! Just highlight the numbers in visual block mode (C-v):
31
37
14
Yank them (y) and in normal mode place your cursor where I've put a |
symbol below:
This is the beginning of a file with several lines
Age of Person A:|; Other info...
Age of Person B: ; Other info...
Age of person C: ; Other info...
This is the end of the file.
and use the put command (p). You'll end up with:
This is the beginning of a file with several lines
Age of Person A: 31; Other info...
Age of Person B: 37; Other info...
Age of person C: 14; Other info...
This is the end of the file.
Assuming you are editing text.txt…
Edit file.txt:
:e file.txt<CR>
Select the lines in visual-block mode:
<C-v>Gl
Yank the block:
y
Switch back to text.txt:
<C-^> (or <C-6>, or :b#<CR>)
Move the cursor to where you want those numbers.
/;<CR>
Put the yanked text before the cursor:
P
Reference:
:help :edit
:help visual-block
:help G
:help l
:help ctrl-^
:help /
:help P
Just as an alternative answer, you may not have known (I didn't till now) that you can create Vim macros that work across files/splits.
For this problem, you can create a split to put the two files next to each other in the same Vim session:
Then on the destination file, move the cursor to the first line you want to modify, in this case Age of Person A. Now press q and any letter of your choosing to record the macro at that letter. Then once it's recording, I typed the following
^Whggdd^Wlpkf;d$jpkJ to go to the left window ^Wh (^W is ctrl+W), go to top line gg, cut line dd, move back to right window ^Wl, paste and rearrange the lines to get them in the right order pkf;d$jpkJ. Then I pressed q to stop the macro, and now you can apply the macro to every line you want with # and the letter you stored the macro in. In my case, I just did a visual block on the remaining lines and then typed :norm #a, since a was the letter I chose for my macro.
A little hackier, but the macros across files and splits might be useful feature to know.
For example, I want to select lines starting with B28, B29 and B30 using Shift + v in row B28 , then select row B29 and so on..., then press 'd' and then move to ROW 1 and press 'Shift-p' in the first row to paste all these rows there.
ROW 1
A26 51.00824
D26 35.94841
D27 35.94841
B28 7.07486
A28 35.95497
D28 179.99932
B29 4.15400
A29 90.00068
D29 179.99932
B30 7.07490
Visual mode(s) can only select contiguous regions (this applies to characterwise, linewise, and blockwise visual mode, regardless of the value of virtualedit). The only exception is ragged line-endings with, say, vip$.
But you can accomplish your goal other ways. For example:
:global/^B\d+/move /ROW 1/-
Should move all lines starting with B followed by digits to the line after ROW 1. (They will probably be reversed; in your case, a simple :sort n will probably be do, but generally :[range]!tac or :[range]global/./move <firstline> can reverse lines.)
Or, you could record a macro like so:
Mark insertion point: :/ROW 1/mark a
start a recursive macro in register q: qqqq (the first three clear the register)
go to next occurence to move /^B\d+
move it dd'ap
adjust mark ma
recursive invocation #q
fini q
Now hit #q and watch the magic.
If you needed to repeat the above many times for different things, I would write a series of commands to get it working once, then turn that into a function and generalize the things that are variable. Voilà, automation.
Another method, just for fun:
:g/^B/normal! dd1G}P
:g/^B/<cmd> executes <cmd> on every line starting with a B,
normal! <macro> executes normal mode macro <macro>,
dd cuts the line to the unnamed register,
1G moves the cursor to line 1,
} moves the cursor to the empty line after the current paragraph, this is key because it allows us to put the next line below the last one that was put and thus to respect order,
P puts the content of the unnamed register above the current line.
Reference:
:help :global
:help :normal
:help /^
:help dd
:help G
:help }
:help P
--- EDIT ---
There are plenty of ways to address your target, even if it is not on line 1.
With a line number:
:g/^B/normal! dd23G}P
With a mark:
ma
:g/^B/normal! dd'a}P
With a search:
:g/^B/normal! dd?ROW1^M}P " ^M is obtained with <C-v><CR>
Say I have the following code
aaa;
bbb;
ccc void () {
xxx;
yyy;
}
ddd;
eee;
Now suppose my cursor is at yyy. I'd like to highlight all code between the parenthesis { and } inclusive of the complete line the brackets are on. This means the highlight will look like
before select
after select
va} is not a solution as that produces this
Effectively it should be a linewise selection. But the corresponding "text-object" forces a charwise one (so there's no difference between va{ and Va{).
However, you can make a selection linewise anytime. So va{V achieves the desired result.
I'm not sure if any mapping is needed at all. But at least ab should not be touched as it normally stands for parentheses ("()-block").
vnoremap aB aBV
Now vaB will select {}-block linewise, while va{ will do "normal" {}-block selection.
nmap vab va{$o0
Breaking it down
vab
highlights within the brackets inclusive of the brackets. The cursor finishes at the end of the highlight.
$
moves the cursor to the end of the line
o
moves the cursor to the other end of the highlight block
0
moves the cursor to the start of the line
Let's say I want to initialize this tuple:
t = (
#(id, name)
(1, 'aasd'),
(2, 'bsfd'),
(3, 'asf'),
...
(21, 'aefae'),
)
I am sure I can do as follow with vim.
1/ Type this:
t = (
#(id, name)
(, 'aasd'),
(, 'bsfd'),
(, 'asf'),
...
(, 'aefae'),
)
2/ Visual select comma row, and type a tricky key sequence which would write successive number
Does anyone know what is the tricky key sequence I should type?
Instead of using VisIncr newer vims (starting with Version 8) support incrementing in visual mode. So I would go with:
Press Ctrl-V and mark the column with the commas
I1ESC to initialize each column to 1
Visually block select the second to last row (using e.g. gvj)
press gCtrl-A to have each row sequentially incremented.
This can be solved with a macro
Position the cursor on the first number: 3Gf1
Start recording: qq
Yank the number lyT, go one down j, paste P, increment ^A (Ctrl+ A), stop recording q.
Execute the macro for the remaining lines: 20#q
All together: 3Gf1lyT(jP^Aq20#q
To avoid the counting, and apply the increment until there are no more lines, you can also turn this into a recursive macro:
Position the cursor on the first number: 3Gf1
Clear macro register q and start recording: qqqqq
Yank the number lyT, go one down j, paste P, increment ^A (Ctrl+ A), re-invoke macro #q. All together: lyT(jP^A#q
Using the VisIncr plugin:
press Ctrl-v and mark the column with the commas (that is, where you want the numbers)
Shift-i1Esc - this should insert a column of 1s
gv - mark the column of 1s
:I - this should change the column of 1s into numbers 1 ... 21.
I'm so sure that this must exist, but if it doesn't maybe there is a macro for it...
One of my most favourite features of vim is the insert before when in visual mode (<C-v>, select the lines, <C-I>, type a little, then Esc).
My issue is that I want to paste the clipboard contents before, not 'insert'. I tried <C-P> but no love.
I have read cheat sheets, searched everywhere, looked through the questions on here and haven't found it, but I could definitely be searching for the wrong thing.
Generally, the P command (upper case, different from p) pastes the contents of the clipboard before the cursor position. Is that what you're looking for? (I'm not quite sure what you mean when you say you press Command+I, as my keyboard doesn't have a Command key.)
I assume you mean using I in visual block mode to insert the same text on multiple lines, where hitting p simply pastes on the current line rather than all the selected lines.
In insert mode, you can hit C-r followed by a register to insert the contents of that register, so if you wanted to paste the unnamed buffer, you'd enter
C-r"
Similarly, to paste from the clipboard
C-r*
By entering insert as you normally would, then using C-r, you'll get the text on all of the selected lines.
Take a look at :h registers to see what registers are available to you.
May seems late, but I faced the same problem.
e.g. A file having two lines:
foo
bar
Press v: visual mode
select foo in virtual mode
Press y: copy
Move the cursor to "b"ar
4-1.
Press p => bfooar
4-2.
Press P(Shift+P) => foobar
Which is what I expected.
TLDR: Upper case P (shift + p)
Based on Alligator solution, using maps.
E.g. to paste the string _s_ in 3 cases:
" |-- original --|-- pasted after C --|-- pasted before C --|-- pasted replacing C --|
" |--------------|------------------------------------------------------------------------|
" |-- --|-- select column C --|-- select column B --|-- select column C --| --> step 0 (after copying/yanking a string)
" |-- --|-- press <leader>py --|-- press <leader>py --|-- press p --| --> step 1 if yanked
" |-- --|-- press <leader>pc --|-- press <leader>pc --|-- press "+p --| --> step 1 if copied to clipboard
" ABCD ABC_s_D AB_s_CD AB_s_D
" ABCD ABC_s_D AB_s_CD AB_s_D
" ABCD ABC_s_D AB_s_CD AB_s_D
Where the mappings for each register (yanked or copied respectively) are:
xnoremap <leader>py A<C-r>*<Esc>
xnoremap <leader>pc A<C-r>+<Esc>
In previous examples I pasted after column (even pasting before column C, I workaround to paste after column B). If desired to paste before just change A to I in the 2 mappings.
Instead of "+p, one could use plain p if previously: copied + to * register (needed in last case of table):
nnoremap <leader>z :let #*='<C-r>+'<CR>