I have the following Ruby code:
if some_cond && another
foo_bar
end
and I want to change it to:
foo_bar if some_cond && another
What are the most idiomatic ways to do tha开发者_StackOverflow社区t in Vim?
Assuming that the cursor is located at the if
-line prior to
refactoring (not necessarily at the beginning of that line),
I would use the following sequence of Normal-mode commands:
ddjVpkJ<<
or this chain of Ex commands:
:m+|-j|<|+d
Here the if
-line is first moved down one line by the :move +
command.
The :move
command cuts a given range of lines (the current line, if
not specified) and pastes it below the line addressed by the argument.
The +
address is a shorthand for .+1
referring to the next line
(see :help {address}
).
Second, the line containing the body of the conditional statement is
joined with the just moved if
-line. The :join
command concatenates
a given range of lines into a single line. The -
range is a shortened
form of the .-1
address referring to the line just above the cursor
(see :help {address}
).
Third, the newly joined line is unindented by one shiftwidth
using
the :<
command.
Finally, the remaining end
-line, which can now be addressed as +
,
is removed by the :delete
command.
I see few (probably non-optimal) solutions:
cursor in first character in first line:
- D - remove
if
condition but leave cursor in same position (don't delete line) - J - join next line to current
- A <Space> <ESC> - append space and exit to Normal mode
- p - paste
if
condition - and then remove remaining end with jdd
- D - remove
cursor in first character in first line, as previously:
- j - move to next line
- dd - remove this line
- k - move back to
if
condition - P - paste removed line before actual line, cursor should be placed to pasted line
- J - join next line to current
- == or << - unindent current line
- and then remove remaining end with jdd
another solution:
- j - move to second line
- JD - join line with next, remove what was joined
- dd - remove current line
- k - step to previous line
- PJ<< - paste, join and unshift
It's probably not optimal, but I do it without thinking, because most of this commands are in my muscle memory (you don't think how to move around you, how to yank/delete and paste most of the time, and joining line is also helpful to remember).
If you have virtualedit
enabled in config, instead of A <Space> <Esc> you can $ <Space>, but I find $ harder to use than A followed by Ctrl-[ (it's simmilar to ESC).
As an advice: if you use some upper letter commands, try to chain them if it's possible, so you only need to keep Shift pressed and then execute some commands, instead of mixing upper and lower letter commands and pressing two keys at a time (upper letter is 2 key press, one is Shift). Once I found combo helpful for restarting server in console Ctrl+cpj, which sends Ctrl+c, Ctrl+p (previous command) and Ctrl+j (Enter key) with single Ctrl press. Since then I try to find simmilar time-saving combination in Vim too mostly with Shift, as Ctrl is not much used in Vim.
Yet another way:
ddpkJjdd
- ddp swap the two lines
- kJ move up and join the lines
- == re-indent the line
- jdd move down and delete the last line
There are probably 30 ways to do this.
Here is one, assuming you are starting from the end of the word end
in normal mode:
dd (delete last line)
"aD (delete and copy foo_bar
to buffer a
)
dd (delete now-empty line 2)
"aP (paste from buffer a
before caret)
aSpaceEsc (insert space and return to normal mode)
Again, "properly" rarely applies in Vim because there are so many ways to accomplish something. This is so small a change that even re-typing foo_bar
could be justifiable.
精彩评论