In vim, how can I move text to certain columns?
Sophia Terry
I have text files of poems with line numbers on the right that look like this:
Bedded in store of rotten fig-leaves soft, 40
And corded up in a tight olive-frail,
Some lump, ah God, of lapis lazuli,
Big as a Jew’s head cut off at the nape,
Blue as a vein o’er the Madonna’s breast
Sons, all have I bequeathed you, villas, all, 45Where the spaces between the ends of the lines and the line numbers are not consistent. How can I move the numbers to a particular column, so that they line up?
3 Answers
A powerful method to solve problems with vim is to use macros and elementary commands, because those are simpler to remember then the vim scripting language.
In this case, I would place the cursor before number, which is the last word in the row (to do this: $b); insert a lot of spaces; remove the extraneous ones (if you want to use row 61, do: 061ldw); go to next line (to do this: j).
You first press qa to start recording macro "a", then press these keys above (and no others) and press q to finish recording. Now to use it, use @a for macro "a"; after that, keep pressing @@ (repeat last macro) until you get to the end of the text.
I wanted to achieve basically the same but for certain characters in software code. The characters can appear anywhere on the line but I wanted them (and anything to the right of them) to appear on a specific column. For example:
refclkp : in std_logic;
refclkn : in std_logic;
hdinp_ch0 : in std_logic;
hdinn_ch0 : in std_logic;
hdoutp_ch0 : out std_logic;I wanted it to look like this:
refclkp : in std_logic;
refclkn : in std_logic;
hdinp_ch0 : in std_logic;
hdinn_ch0 : in std_logic;
hdoutp_ch0 : out std_logic;I.e. with all the : on a specific column (column 30 in this case). The above didn't make sense to me (it may work but I don't use the visual stuff) but it did give me the clue to solving it:
:map H $?:<ctrl+Enter>Di <ctrl+Esc>029lP:s/\s*$//<ctrl+Enter>You do the <ctrl+Enter> and <ctrl+Esc> bits by holding Ctrl+Q and then hitting Enter or Esc. It appears in the command as ^M or ^[. The above essentially does this:
- Go to the end of the line (
$) - look backwards for the first ":" (
?:<ctrl+Enter>) - Delete everything from this point to the end of the line (
D) - Insert 30 spaces - this is so I know there is enough white space to allow me to jump to column 30 (
i <ctrl+Esc>) - Jump to Column 30 - not sure why I need to use '29' here, must be a 'feature' (
029l) - Paste the deleted text from step 3 (
P) - Clean up by deleting all the trailing white spaces created in step 4 (
:s/\s*$//<ctrl+Enter>)
I created this as a mapping so all I need to do now is hit H and the current line is modified!
1The another method for this kind of column alignment is like this :
let us take the above example,
before :
refclkp : in std_logic;
refclkn : in std_logic;
hdinp_ch0 : in std_logic;
hdinn_ch0 : in std_logic;
hdoutp_ch0 : out std_logic;after :
refclkp : in std_logic;
refclkn : in std_logic;
hdinp_ch0 : in std_logic;
hdinn_ch0 : in std_logic;
hdoutp_ch0 : out std_logic;Here I aligned the ":" character at the 15th column. for doing this follow the below steps:
Go to the first line (where we need to start the changes, here it is "refclkp : in std_logic;")
Then Press the
<Esc>key to go to the normal modePres these keys
qa0f:i (Press the space bar more than 20 times)<Esc>15|dw<DownArrow>qThen press
4@afor repeating the same for remaining 4 lines.
(Here the spaces more than 20 is for our safe side can change with respect your requirement)
1