Type less and save time with Vim's global command!
Tags: vim, neovim, global, productivity
Published: 2019-12-21 16:21:07

---
title: Type less and save time with Vim's global command!
published: true
description: Procrastinators everywhere shall rejoice!
tags: vim, neovim, global, productivity
canonical_url: https://irian.to/blogs/type-less-and-save-time-with-vims-global-command
---

*If you're interested to learn more Vim, follow [@learnvim](https://twitter.com/learnvim) for tips/tricks!*

Vim's global (`:h :g` for more info) command is a useful tool to quickly perform Ex command within the file you're currently editing *(some common example of Ex commands are: `d` (delete), `t` (copy), `s` (substitute), `m` (move), etc)*. Used properly, it can save you a lot of time typing. 

`g` follows the syntax:

```
:[range]g[lobal]/{pattern}/[cmd]
```

Here I will cover *basic*, *slightly more advanced*, and *advanced* use cases. If this is your first time using `g`, you don't have to follow the advanced one yet, feel free to come back later after getting more experience with it. Learning Vim takes a lot of muscle memories. I am still learning new something new about Vim all the time! 🤓

# When to use it?

Anytime you find yourself *repeating* the same Ex command in one file, you should start thinking, "How can I do this in one stroke with `:g`?"

# Basic use cases

Let's start with basic use cases, going to more sophisticated ones.

Suppose you have a file with many "const" and you need to delete them all:

```
const hello = "world";
const foo = "bar";
const baz = "qux";
// and many more const...
```

Run `:g/const/d` and they are gone!

What just happened?

We gave `g` a pattern: `"const"` string. It found all *lines* (`g` is line-based) that matches the pattern. It performed `d` (deletion) to those matches.

`g` by default will perform `p` (print) if no command is passed. Try it: `:g/const/`.

It also accepts ranges. Let's say you want to get rid of all empty lines between lines 10 and 20. You can do this by:

```
:10,20g/^$/d
```

Note: `^$` is a regex pattern for blank lines.


# Slightly more advanced use cases

Let's move on to more fancy use cases.

Suppose you have the following and want to reverse the line order:

```
const one = 1;
const two = 2;
const three = 3;
const four = 4;
```

To do that with `:g`, you can do:

```
:global/^/m 0
```

We'd get:

```
const four = 4;
const three = 3;
const two = 2;
const one = 1;
```

Pretty cool, but how did it work?

`m 0` moves (see `:h :m` for details) a line into target line number (line 0). If you want to do it yourself manually, you can go to line 1, run `:m 0`, then go to next line, run `:m 0`, then next line, run `:m 0`, etc. You'll notice the lines are gradually being put on top of the latest one. The difference is, `g` does it for you in one move. (btw, `^` is a pattern for beginning of line; here it selects all lines in a file). 

Pretty cool! 😎


You can combine `g` with substitute (`s`):

```
good, bad, ugly
you're so good it's bad
nothing bad here
```

If we want to substitute all "bad"s into "nice", but only on the lines that contain "good", we can do:

```
:g/good/s/bad/nice/g
```

We'd get:

```
good, nice, ugly
you're so good it's nice
nothing bad here
```

# Advanced use cases

`g` can be used with macros. The syntax is :

```
:g/keyword/norm! @q
```

Let's say we have a the following:

```
import lib1
import lib2

const something = 'else';

import lib3
// ...and many more imports
```

Our tasks are:
1. wrap all libs with `{}`
2. capitalize the l in lib

We can create macro to do our tasks. But we don't want to execute our macro on lines *not* containing `import`. Does that mean we have to apply our macros individually on each line we want to do it on? 

Well, with `g`, we can select to apply our macros only to lines containing "import"! Imagine the time saving if you have to do it on 100+ lines!

Assuming we have [vim-surround](https://github.com/tpope/vim-surround) installed (for quick brackets wrap), here's how we can do it! 
- Record a macro to do tasks 1 and 2. With our cursor on "i" in `import lib1`, run: 

```
qq0w~ysiw{q
// qq = record macro in q register
// 0 = go to beginning of line
// w = jump one word
// ~ = capitalize letter under cursor
// ysiw{ = vim-surround: add {} around lib1
// q = exit recording
```

- Undo the changes so our line is  back to our original state: `import lib1`
- Now execute the macro on only lines containing "import" with `:g`!

```
:g/import/norm! @q
```

And there you have it:

```
import { Lib1 }
import { Lib2 }

const something = 'else';

import { Lib3 }
// and more...
```


`g` also accepts a different range. The syntax is:

```
:g/pattern1/, /pattern2/ {cmd}
```

This applies the `{cmd}` only to "blocks" between pattern1 and pattern2 (inclusive). 

A practical use case is, suppose we have the following:

```
const something = {
   c:  'x',
   b:  'x',
   a:  'x',
   d:  'x',
}

const else = {
   d: 'x',
   c: 'x',
   a: 'x',
   b: 'x',
}

const a = 'hello'
const b = 'foo'
const c = 'bar'

```

And we want to sort only the keys inside `something` and `else` and nothing else. 

If you do:

```
:g/\v\{/+1,/\v}/-1 sort
```

Everything inside your objects are now sorted and everything else remains unsorted:

```
const something = {
   a:  'x',
   b:  'x',
   c:  'x',
   d:  'x',
}

const else = {
   a: 'x',
   b: 'x',
   c: 'x',
   d: 'x',
}

const c = 'bar'
const a = 'hello'
const b = 'foo'

```
Which is exactly what we wanted.

Here's the breakdown:
`:g/\v\{/+1,/\v}/-1 sort`

- `\v` - activates vim's very magic
- `\{` - selects `{` (escape special character)
- `+1` - means apply the range 1 line after the match
- `-1` - apply the range 1 line before the match
- `sort` - vim's sorting method

And there you have it! Vim's global command. This is just the surface of what it can do. Have fun experimenting! 

What other useful cases do you think you can use it for?

*Thanks for reading. I started a twitter account to share daily vim tips. If you're interested, follow [@learnvim](https://twitter.com/learnvim)!* 😁