# Unleashing VIM

## 1. Multi-lines actions

In VIM, it is quite useful to utilise the visual mode and multi-line actions when you are commenting out multiple lines for troubleshooting or documentation.

Here is how to comment out multi-lines.

1. Ensure that we are in *normal mode*.
2. Move the cursor to the first line you want to comment out and press `Ctrl + v` to put the editor into *visual block mode*.
3. Select the lines you want to comment out with VIM's key `j` or arrow down key.
4. After that, press `Shift + i` to put the editor into *insert mode* inside *visual mode* and then press `#` which will add a hash to the first line.
5. Then press `Esc` to insert `#` character at all other selected lines.

Note that it can be any other characters instead of `#` for multi-lines insert. To append something at the end of multi-lines, it's the same workflow up to **Step 3** then `Shift + 4` (`$` symbol) to move the highlight to the end of each line, and `Shift + a` (`A` symbol) to append any character. After that, `Esc` to append the character(s) at the rest of selected lines in *visual block mode*.

Here is how to remove comment from multi-lines.

1. Ensure that you are in *normal mode*.
2. Move the cursor to the first line you want to comment out and press `Ctrl + v` to put the editor into *visual mode*.
3. Select the lines you want to comment out with VIM's key `j` or arrow down key.
4. Then press `x` to delete `#` character on all lines.

The same workflow can be used to perform any other multi-lines actions in VIM as well.

## 2. Macros

It can be quite powerful to use macros in VIM for the same repetitive task in your editor. For instance, a specific set of motions and actions you are about to perform at multiple places can be recorded as a macro.

Here is how to record a macro in VIM.

1. Ensure that you are in normal mode.
2. Press `q + w` to register `w` as macro.
3. Perform the commands/actions while it shows `recording @w`.
4. If it is in the insert mode, press `Esc` to get out of it.
5. Then press `q` to end the recording which stores the commands/actions in `@w`.

To reuse the recorded macro, move the cursor to where you want to perform the same commands/actions in VIM, and press `@w` to recall the macro.

## 3. .vimrc

As someone who writes Ansible playbooks and manages infrastructure almost entirely in YAML, having Vim configured *just right* makes a massive difference to my day-to-day flow. Here’s a breakdown of my simple but practical `.vimrc`, focused on keeping spacing consistent, catching bad characters, and visualising whitespace — all of which are critical when working with indentation-sensitive formats like YAML.

```bash
set ai et ts=2 sw=2 sts=0
highlight NonAscii ctermbg=red guibg=red
syntax match NonAscii "[^\x00-\x7F]"
highlight SpecialKey ctermfg=1
set list
set listchars=tab:T→,trail:␣
```

### Consistent, YAML-friendly indentation

```bash
set ai et ts=2 sw=2 sts=0
```

* `ai` automatically indents new lines to match the previous one, saving you repetitive indenting.
* `et` converts all tabs to **spaces**, which is essential for YAML.
* `ts=2 sw=2` enforce **2-space indentation**, which is considered best practice for YAML and Ansible.
* `sts=0` makes pressing `<Tab>` insert exactly `shiftwidth` worth of spaces rather than mixing spacing.

### Catch non-ASCII characters instantly

```bash
highlight NonAscii ctermbg=red guibg=red
syntax match NonAscii "[^\x00-\x7F]"
```

These two lines work together to highlight any sneaky non-ASCII characters (like smart quotes or hidden Unicode) with a **bright red background**. This is incredibly helpful when copying from websites or PDF documents, where curly quotes and odd whitespace can silently break YAML parsing.

### Draw attention to whitespace characters

```bash
highlight SpecialKey ctermfg=1
set list
set listchars=tab:T→,trail:␣
```

Whitespace errors are one of the most common causes of YAML headaches — so I make them visible:

* `set list` tells Vim to actually display invisible whitespace characters.
* `listchars` defines what to show:
  * Tabs become `T→` so I can spot them immediately.
  * Trailing spaces render as a visible `␣` symbol.
* The `SpecialKey` highlight tweaks colouring so these markers stand out in the terminal.

This mini `.vimrc` is intentionally focused: keep indentation perfect, highlight bad characters, and make invisible whitespace obvious. It’s not flashy — but it saves me from subtle bugs daily when I’m writing Ansible playbooks and YAML configuration files.

## 4. Quickly Re-indent a Whole YAML File

If someone sends you a badly-formatted YAML file (mixed tabs/spaces, messy nesting, etc.), you can re-indent the **entire file** cleanly using one command inside Vim:

`gg=G`

What it does:

* `gg` jumps to the very top of the file.
* `=` is Vim’s built-in auto-indent command.
* `G` tells it to apply until the *end* of the file.

Together, `gg=G` says: *“Re-indent everything from top to bottom.”* This uses whatever indentation settings you already have (e.g. `et ts=2 sw=2`), so after running it, your YAML file instantly snaps into neat, consistent two-space indentation.

## 5. Run a Command on Every Line - Efficient Batch Editing with `:g` and `normal`

Suppose you want to **comment out all lines containing a certain word** (like `debug:`) or you want to **add indentation to every line that matches a pattern** — Vim’s powerful `:g` command combined with `normal` mode commands lets you do this in seconds.

**Example**: Comment out every line containing `debug:` in your YAML file

`:g/debug:/normal I#`

**How it works:**

* `:g/debug:/` — Finds every line containing `debug:`.
* `normal I#` — Runs normal mode command `I#` on those lines, which inserts `#` at the start of the line, effectively commenting it out.

**Another example**: Increase indentation by 2 spaces on lines with `when:`

```
:g/when:/normal 2>>
```

* `2>>` indents the line twice (2× your shiftwidth, usually 2 spaces each).

This saves you from repetitive manual edits and supercharges bulk modifications without leaving Vim or writing scripts.

## 6. Supercharging Your Vim Workflow with Relative Line Numbers

If you’ve been using Vim for a while, you probably already know about `:set number` - absolute line numbers. They’re great for orientation, but when it comes to actual **navigation and editing**, relative line numbers (`:set relativenumber`) can make a *huge* difference.

Instead of showing the exact line numbers, Vim shows the distance from your cursor line. This makes moving, deleting, or copying code faster and more intuitive.

Let’s look at why - using an Ansible playbook as our example.

### Editing YAML the Smart Way

Here’s a small Ansible playbook:

```yaml
- name: Configure web server
  hosts: web
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present

    - name: Start nginx service
      service:
        name: nginx
        state: started
        enabled: true

    - name: Deploy index.html
      copy:
        src: files/index.html
        dest: /var/www/html/index.html
```

Now let’s say you’re on the `apt` task line (installing nginx). With relative numbers turned on, Vim might look something like this:

```yaml
  5   - name: Install nginx
  4     apt:
  3       name: nginx
  2       state: present
  1
  0     - name: Start nginx service
  1       service:
  2         name: nginx
  3         state: started
  4         enabled: true
```

Notice how the numbers show **distance from the cursor**, not absolute positions.

### Why It Is Useful

#### Fast Navigation

If you want to jump to the `service:` line (1 below), you don’t have to count - it literally tells you.

`1j`

Want to get to the `copy:` task that’s **7 lines down**?

`7j`

No more guesswork.

#### Smarter Editing

Say you want to **delete the nginx task entirely** (4 lines). With relative numbers, you instantly see it’s 4 lines long.

`d4j`

Or maybe you want to **yank** the whole `service` task (5 lines). Just:

`y5j`

This beats visually selecting and counting every time.

#### Visual Mode with Precision

Want to indent the next two tasks?

`V10j>`

Relative numbers make bulk actions super predictable.

#### Hybrid Mode (Best of Both Worlds)

Most people (me included) use:

`set number` `set relativenumber`

This way, the current line shows its **absolute number** (helpful when debugging YAML errors that say “line 23”), while all other lines stay **relative** for editing speed.

```yaml
  8 - name: Configure web server
  7   hosts: web
  6   tasks:
  5     - name: Install nginx
  4       apt:
  3         name: nginx
  2         state: present
  1 
9       - name: Start nginx service
  1       service:
  2         name: nginx
  3         state: started
  4         enabled: true
  5 
  6     - name: Deploy index.html
  7       copy:
  8         src: files/index.html
  9         dest: /var/www/html/index.html
```

Relative line numbers might feel odd at first, but once you get used to them, you’ll never go back. They turn Vim into a precision editing machine - especially for structured files like YAML, JSON, or code blocks where you constantly jump, copy, or delete in chunks.

Next time you’re editing an Ansible playbook, flip on relative numbers and watch your speed go up.

## 7. Changing Case in Vim Like a Pro

Vim has powerful built-in commands for **changing case** (upper ↔ lower). You don’t need external plugins or search-replace tricks - just a few keystrokes.

### The Basics

#### Toggle case (`~`)

* In **Normal mode**, place the cursor on a character and press `~`.
* It flips that single character: `a` → `A`, `X` → `x`.
* Works in **Visual mode** too: select text, hit `~`, and everything toggles case.

Example:

`hello World`

Select `World` in Visual mode and press `~` →

`hello wORLD`

#### Force to lowercase (`gu`)

* `gu` + motion makes text lowercase.
* Examples:
  * `guu` → lowercase the whole line
  * `gUw` → uppercase the current word
  * `gu$` → lowercase from cursor to end of line

Example:

`HELLO WORLD`

On the first line, type `guu` →

`hello world`

#### Force to uppercase (`gU`)

* `gU` + motion makes text uppercase.
* Examples:
  * `gUU` → uppercase the whole line
  * `gUw` → uppercase the current word
  * `gU}` → uppercase until the end of paragraph

Example:

`hello world`

On the first line, type `gUU` →

`HELLO WORLD`

### Practical Use Cases

#### Fixing Constants in Code

`api_key = "abcd1234"`

Cursor on `api_key`, type `gUw` →

`API_key = "abcd1234"`

#### Normalising Config Files

Editing YAML in Ansible? Need `true`/`false` lowercase?

`enabled: TRUE`

Cursor on `TRUE`, type `guw` →

`enabled: true`

#### Quick Title Casing

Got this in Markdown:

`# my awesome blog POST`

Cursor on line, `gUaw` (uppercase a word) on `my`, then `aw` again on others.\
Result:

`# MY AWESOME BLOG POST`

### Visual Mode + Motions

You don’t have to memorise motions if you prefer **Visual mode**:

* Select text with `v` or `V`
* Press `u` → lowercase selection
* Press `U` → uppercase selection

It’s intuitive and fast for larger chunks.

### Hybrid Trick

Want **all lowercase, but just the first letter uppercase** (title case)? Combine commands:

1. `guw` → lowercase word
2. `gU~` → uppercase just the first character

So `"HELLO"` becomes `"Hello"`.

Changing case in Vim is a tiny feature with a big productivity payoff. Between `~`, `gu`, and `gU`, you can transform text however you like without leaving Normal mode. Try them on your next config file, YAML playbook, or Markdown doc - and you’ll see how much smoother editing becomes.

## 8. Mastering Vim’s Visual Line Mode: Editing Multiple Lines with Ease

One of the most underrated Vim superpowers is **Visual Line Mode** (`Shift+V`). It lets you select entire lines of text and then apply commands to all of them at once - from indentation to inserting text at the beginning of each line.

If you’ve ever found yourself manually repeating the same command across multiple lines, Visual Line Mode combined with `:` and `normal` is the trick you’ve been missing.

### What Is Visual Line Mode?

Vim has three visual modes:

* **Character-wise** (`v`) → Selects characters
* **Line-wise** (`V` or `Shift+V`) → Selects entire lines
* **Block-wise** (`Ctrl+v`) → Selects columns

Visual Line Mode is perfect when you want to work with *whole lines of text*, like YAML tasks, Python code, or Markdown lists.

### Basic Usage

1. Move the cursor to a line
2. Press `Shift+V` → entire line is selected
3. Move up or down (`j`/`k`) to extend selection

For example:

```yaml
- name: Install nginx
  apt:
    name: nginx
    state: present
- name: Start service
  service:
    name: nginx
    state: started
```

With `Shift+Vj`, you select both tasks.

### Power Move: Using `:` After Selection

Here’s the magic: once you’ve selected lines in Visual Line Mode, press `:` (that’s `Shift+;`).

* Vim will automatically expand the range for you, like: `:'<,'>`
* Now you can apply any **Ex command** or even run **Normal mode commands** on all those lines.

#### Indenting Multiple Lines

1. Select lines with `Shift+Vj`
2. Press `:` → prompt shows `:'<,'>`
3. Type: `normal >>`

All selected lines are indented one level.

#### Insert Text at the Beginning of Each Line

Say you want to comment out multiple lines with `#`:

1. Select lines in Visual Line Mode
2. Press `:`
3. Run: `normal I#`

Every selected line now has a `#` at the start.

#### Append Text at the End of Each Line

1. Select lines
2. `:`
3. Run: `normal A;`

Adds a `;` at the end of each selected line. Perfect for quickly editing languages where statements need semicolons.

### Why This Is So Powerful

* No need to record macros
* Works with *any* Normal mode command
* Faster than manual repetition
* Perfect for code, config files, and structured text like YAML or JSON

Once you get the hang of `:'<,'> normal …`, you’ll feel like you’ve unlocked a hidden “batch-edit” mode in Vim.

Visual Line Mode with `:` and `normal` bridges the gap between **precise motions** and **bulk editing**. Whether you’re commenting out a YAML playbook, adding semicolons to JavaScript, or indenting Python code, this workflow saves time and reduces errors.

Next time you need to make the same change across multiple lines, try this:

`Shift+V → select → : → normal command`

You’ll wonder how you ever worked without it.

## 9. Doing Arithmetic in Vim: Increment, Decrement, and Beyond

When you think of Vim, you probably imagine blazing-fast navigation, text objects, and macros. But did you know Vim can also do **arithmetic operations** directly inside your text?

Yes - without leaving your editor, you can increment, decrement, or even perform calculations on numbers. This makes Vim surprisingly powerful for editing configs, version numbers, lists, or anything with numeric data.

### The Basics: `<C-a>` and `<C-x>`

* **`<C-a>` (Ctrl+a)** → Increment the number under (or after) the cursor
* **`<C-x>` (Ctrl+x)** → Decrement the number under (or after) the cursor

Example:

`version: 1`

Put the cursor on `1`, press `<C-a>` →

`version: 2`

Press `<C-x>` →

`version: 1`

### Repeating Counts

You can pass a **count** before the command:

* `5<C-a>` → Increase the number by 5
* `3<C-x>` → Decrease the number by 3

Example:

`retries: 10`

With the cursor on `10`, press `5<C-a>` →

`retries: 15`

### Incrementing Across Multiple Lines

One of Vim’s hidden gems is **Visual mode + `<C-a>`**.

1. Select multiple lines in **Visual Block mode** (`Ctrl+v`)
2. Move cursor down to highlight a column of numbers
3. Press `g<C-a>` → increments all numbers at once

Example before:

```
item1 
item2 
item3
```

Select the `1`, `2`, `3` in block mode and press `g<C-a>` →

```
item2 
item3 
item4
```

Add a count: `10g<C-a>` →

```
item11 
item12 
item13
```

### Arithmetic in the Command Line

You can also use Vim’s command line for calculations:

`:echo 5*7`

→ `35`

Or set a register/variable:

`:let x = 42 | echo x + 8`

→ `50`

This is especially useful in mappings or small Vimscript snippets.

### Practical Use Cases

* **Config files:** Tuning retry counts, port numbers, or version IDs
* **Code editing:** Updating array indices or enum values
* **Markdown lists:** Renumbering ordered lists on the fly
* **Bulk updates:** Generating sequential IDs or test data

Vim isn’t just a text editor - it’s a toolbox. Knowing that you can perform **arithmetic operations directly in your buffer** means fewer context switches and faster editing. Next time you need to bump a version number, increment test IDs, or adjust numeric values, remember:

* `<C-a>` increments
* `<C-x>` decrements
* `g<C-a>` batch-increments in block mode

Small trick, big productivity boost.
