I recently ran into a situation where I needed to reverse some lines in a visual selection and found a solution on stackoverflow. However, when I tried to add a keybinding for this, I ran into some trouble. When I ran
:'<,'>g/^/m <actual line number>
it worked. However, when I try to do this using
It does not include the top line in the selection. And when I use
:'<,'>g/^/m '<-1
It moves the top line to the bottom of the selection and nothing
more.
Here's an example:
Original Text:
1
2
3
4
Expected Result:
4
3
2
1
When I run :'<,'>g/^/m '<
1
4
3
2
When I run :'<,'>g/^/m '<-1
2
3
4
1
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
I think this is due (in the last example) to how mark '<
moves when you move the first line in the range, and (in the previous example) to the fact that "moving the first line to after itself" is a no-operation.
Try adding the following (untested) to your vimrc:
function SwitchLines() range
let whereto = a:firstline - 1
exe a:firstline . ',' . a:lastline . 'm' whereto
endfunction
(with no dot between 'm'
and whereto
); then when you're ready, use
:'<,'>call SwitchLines()
(the '<,'>
will, like before, be inserted when you hit :
in Visual mode, and the :exe
statement will construct an ex-command by evaluating the values of its arguments, then execute it — with the numbers of the concerned lines in it).
For more explanations about how this function works, see the first 50 lines of help starting at :help E124
. BTW, the lack of a :return
statement is not an error, the :endfunction
statement implies :return 0
.
Best regards,
Tony.
Thanks for the help! It didn't work initially, but when I changed
exe a:firstline . ',' . a:lastline . 'm' whereto
to exe a:firstline . ',' . a:lastline . 'g/^/m' whereto
It worked. But just to be clear, if moving marks to the line after themselves were not a nop inside the source code, my first solution would work?
It worked. But just to be clear, if moving marks to the line after themselves were not a nop inside the source code, my first solution would work?
No, Consider what is happening for :g/^/m '<
(lets ignore the initial address range for the :global
command).
Move line 1 below line 1, Buffer looks like this:
1
2
3
4
Move line 2 below line 1, Buffer looks like this:
1
2
3
4
Move line 3 below line 1, Buffer looks like this:
1
3
2
4
Move line 4 below line 1, Buffer looks like this:
1
4
3
2
Note, you can alternatively use the :lockmarks
command modifier, e.g. '<,'>g/^/lock m '<-
should have also worked.
Closing
Closed #2550.