Home Writing

til / sort lines in vim

Occasionally, you find cases where you want to sort something. Either alphabetically or numerically. In Vim, we can use the built-in :sort command to help us out.

Alphabetically #

Standard sort #

Let’s say we have the following JavaScript object and that we would like to sort it by its keys.

const sort = {
  beta: 'beta',
  charlie: 'charlie',
  alpha: 'alpha',
}

With our cursor anywhere inside the object, we type vi{:sort<CR>. Let’s break that down:

  • vi{ – Visually select (v) everything inside (i) curly brackets ({). After running this part, we’ll probably see that the rows inside the object have been highlighted. We can also use viB which does the same thing.
  • :sort – Once we type :, we’ll see :'<,'> on the command line. This might look weird, but it means that whatever command we type afterward, sort in our case, will only be applied to the lines we have selected.
  • <CR> – Shorthand for “Carriage return”, which basically means press enter.

After we’ve run the command, our object will be sorted.

// vi{:sort<CR>
const sort = {
  alpha: 'alpha',
  beta: 'beta',
  charlie: 'charlie',
}

Tip: Use dangling commas, commas on all lines, otherwise we would have to add a comma after alpha. This also comes into play when we want to remove duplicates.

Reverse sort #

To reverse the order, we scream sort by adding a ! at the end, i.e., vi{:sort!<CR>.

// vi{:sort!<CR>
const sortReverse = {
  charlie: 'charlie',
  beta: 'beta',
  alpha: 'alpha'
}

Case insensitive #

What if we have mixed casings in the object keys?

const sortMixedCases = {
  beta: 'beta',
  Charlie: 'charlie',
  Alpha: 'alpha'
}

If we try using :sort, we would get the uppercase keys before the lowercase keys.

// vi{:sort<CR>
const sortMixedCases = {
  Alpha: 'alpha',
  Charlie: 'charlie',
  beta: 'beta',
}

This might be what we want in some cases, but if we aren’t concerned about the casing, we can use :sort i, where i makes it case-insensitive.

// vi{:sort i<CR>
const sortMixedCases = {
  Alpha: 'alpha',
  beta: 'beta',
  Charlie: 'charlie',
}

Remove duplicates #

Let’s say we have an object that we want to sort which contains a duplicate charlie key.

const sortAndRemoveDuplicates = {
  charlie: 'charlie',
  beta: 'beta',
  charlie: 'charlie',
  alpha: 'alpha',
}

To sort and remove duplicates, we use :sort u, where u stands for unique.

// vi{:sort u<CR>
const sortAndRemoveDuplicates = {
  alpha: 'alpha',
  beta: 'beta',
  charlie: 'charlie',
}

This only removes exact duplicates. If the values had been different for the charlie keys, then sort would’ve kept both lines. This is also a case where dangling commas are useful because if one of the lines is missing it, it wouldn’t be interpreted as a duplicate.

Multiple sorts #

We can combine multiple sorts to do more things at once. For instance, we can use :sort ui to remove duplicates and ignore casing.

// Before
const sortAndRemoveDuplicates = {
  charlie: 'charlie',
  alpha: 'alpha',
  Alpha: 'alpha',
  beta: 'beta',
  Charlie: 'charlie',
  alpha: 'alpha',
}

// After
// vi{:sort ui<CR>
const sortAndRemoveDuplicates = {
  alpha: 'alpha',
  beta: 'beta',
  charlie: 'charlie',
}

Numerically #

The :sort command has multiple options for sorting numbers. For this example, we’ll use a numbered list. We’ll use vip to visually select (v) inside (i) of the paragraph (p). Inside in this case means “select content without adjacent whitespace”.

20. Delta
10. Beta
100. Charlie
1. Alpha

If we use :sort, the list would be sorted 1, 10, 100, 20. Not quite what we want. But, if we use :sort n we instead sort by the first decimal number in the line. So, the command becomes vip:sort n<CR>.

1. Alpha
10. Beta
20. Delta
100. Charlie

Since it uses the first decimal number, we would get the same sort order even if the lines looked like this.

1. Alpha
Beta 10.
De 20. lta
100. Charlie

We can exchange n with any of the following to sort other number types.

  • b – Binary numbers
  • f – Floating-point numbers
  • o – Octal numbers
  • x – Hexadecimal numbers

  • Loading next post...
  • Loading previous post...