Reputation: 1219
I need to do the following:
temp
to some value (say 100).temp
for a range of lines.temp
to be +100.I started by setting the value 100 to temp using let temp=100
.
I then figure out the following ex command that I can apply to a line: :execute "normal! ". temp. "^A"
this will take temp and increase the number by temp
for the current line.
Unfortunately, this will not work when I visually select a range of lines and then hit :
to apply a command to all the lines selected.
How can I achieve the same but for a range of lines?
Here is an example:
1
2
3
4
5
Should become
101
102
103
104
105
Then I will update the temp to let temp=temp + 100
and repeat for the next block and so on.
Thanks!
Upvotes: 3
Views: 818
Reputation: 11
I think we can use global command to do the work, it accepts the range.
:'<,'>g/./execute "normal! ". temp. "^A"
Upvotes: 0
Reputation: 196556
To answer your question directly, :help :execute
is what is blocking you for two reasons:
:execute
doesn't accept a range,:execute
is not necessary to begin with.The following command does the job without :execute
:
:[range]normal! <C-r>=temp<CR><C-v><C-a><CR>
Breakdown:
[range]
would be '<,'>
after a visual selection.:help :normal
executes the given macro in normal mode.:help c_ctrl-r
inserts the content of the given register in the command line.:help "=
is the expression register, which returns an evaluated expression.temp
is the expression to evaluate, so <C-r>=temp<CR>
inserts the content of the variable temp
.<C-v><C-a>
inserts a literal ^A
.<CR>
executes the command.But that's a lot to type so a simple mapping seems more appropriate in this case:
xnoremap <expr> <key> temp . '<C-a>'
Breakdown:
:help :xnoremap
creates a visual mode mapping.:help <expr>
makes it an expression mapping, where the actual RHS is evaluated at runtime.<key>
is what key you want to press.temp . '<C-a>'
is your expression, which concatenates the current value of temp
with <C-a>
to obtain 100<C-a>
, 200<C-a>
, etc..Usage:
Set temp
to the desired value:
:let temp = 100
Select some lines:
v<motion>
Increment the first number of each line:
<key>
Change the value of temp
:
:let temp += 100
Move to next block and select some lines:
<motion>
v<motion>
Increment the first number of each line:
<key>
However, the manual way would go like this:
v<motion> " visually select the desired lines
100<C-a> " increment the first number on each line by 100
then:
<motion>
v<motion>
200<C-a> " increment the first number on each line by 200
and so on… so I'm not sure what's be the benefit of introducing variables, :normal
, etc., here.
Upvotes: 5
Reputation: 1219
I just found a workaround, if no one knows a better way.
I recorded a macro b
to run execute "normal! " . temp . "^A"
on the current line. Then recorded another macro a
that will go and visually select all the lines in the group interested and run :'<,'>norm @b
this will apply that operation on every line, then before ending the macro @a
, I also set let temp=temp+100
.
Upvotes: 2