Vim Tips #1

Sharing some of the vim tips, which I use regularly but came across very late in my use of vim.

Increment a bullet list

Many times, while editing my markdown file, I have a bullet list of which I want to convert to a numbered list. For example, from the following:

- item one
- item two
- item three
- item four

I want to convert to following:

1. item one
2. item two
3. item three
4. item four
  • 0 to jump to the start of the line.

  • Go to the first dash, by either pressing k till you reach the first dash or gg to jump to the very first line.

  • Ctrl + v to visual select the block. This will select the first dash. Ctrl + v does visual selection by selecting blocks, it will allow you to move and select below - without selecting the entire line. Select all the dashes

  • Press r to replace the - with 0.

  • Press gv to select the previous visual selection.

  • Press g + Ctrl + a to add a sequence. This will increment the first number from 0 to 1 and then create sequence of incremented numbers below it. Giving the required results.

  • For the missing dots (.). Select the previous visual selection with gv, then press a, this will take you into insert mode, then press . and then escape. This will add . to all the selected lines.

Search and Replace

I am sure you are familiar with s command used for search and replace. For example if you want to replace all the instances of word like hello with world you can do %s/hello/world/g (of-course, this command is to be run after entering into command mode). But things get a little trickier if you want to replace a word like world with worlds. Of-course you can still do %s/world/worlds/g but here we are typing the world twice, and going by DRY, I don’t like to repeat myself.
A much better way is to use capture groups in the s command i.e. %s/\(world\)/\1s/g. Using (and escaping) () we capture the selection in a group and then reuse it in replace with \1. The number increments as the number of capture groups increase.

Delete all lines matching a pattern

Suppose you are in the middle of the page, from here you want to delete all the lines matching a certain pattern. For example, in a file, you have many # TODOs and it was a very productive day for you and you finished all the todos, now you want to remove them.
You can use this to delete all the comment lines in the file using: :g/^#/d . (Here the pattern is to select all lines that start with #)

The general purpose command is: :g/pattern/command.

Insert at the end of multiple lines

Suppose you have the following text, you want to insert comma at the end of all the props, but the issue is that the lines are of unequal length:

const props = {
  name: "Hello world"
  profession: "Singer"
  city: "atlanta"
  age: 25
}

There are three ways, I can think of doing this:

  • Go into visual block selection, with <Ctrl+v>, then press j to select all the prop lines. Note, press Ctrl+v when you are on the first prop. Then press A, this will take you in insert mode and at the end of current line, then press , and then escape. This will insert comma, automatically to the end of each line.

  • Using the command :g/^\s\+[^}].*$/s/$/,/.

    • This is the same as :g/pattern/command

    • pattern is: ^\s\+[^}].*$, i.e. select all line which starts with one or more space, don’t select any line ending with } braces and select the whole line.

    • command is substitution command: s/$/,/ replace the end character with comma

    • But the drawback is it will select all lines with spaces including the ones which already have comma

  • Visually select these lines and then enter command mode and then use the same substitution command as above i.e. :'<,'>s/$/,/.

Reply

or to participate.