How to delete lines in Vim / Vi

How to delete lines in Vim / Vi

[#short-answer]The Short Answer[#short-answer]

  • [.inline-code]dd[.inline-code] deletes the whole line under the cursor.
  • [.inline-code]5dd[.inline-code] deletes multiple (5) lines, starting at the cursor.
  • [.inline-code]d$[.inline-code] deletes to the end of the line, starting at the cursor.
  • [.inline-code]dG[.inline-code] deletes all lines starting from the line under the cursor

However, those only work in normal mode. Ex mode has some more capable and interesting ways to remove lines!

[#review-of-vim-modes]Review of Vim Modes[#review-of-vim-modes]

Our tools make us superhuman. For programmers, that’s our editor. Vim’s main distinctive feature is that it’s a “modal editor,” which means it has distinct modes with different purposes and controls. Learning to use these modes is like having several knives for slicing different foods. You can use a chef’s knife for everything, but no chef would recommend that! You’ll prep much faster with a full set of knives.

When asking how to delete a line in Vim, the best answer depends on which mode you use. The best mode for the task will depend on what you’re deleting. Are you deleting the line the cursor is on? Are you deleting the first line to match a certain pattern? Some deletion tasks are a lot of work in normal mode but a piece of cake in ex mode. Let’s define the modes we’ll discuss here, i.e. the “knives in our set”.

  1. Insert mode - This is the mode most similar to other text editors. It’s very literal. You press the “f” key and the letter “f” appears in the text.
  2. Visual mode - This mode selects ranges of text. This is kind of like when you click and drag to select text in other programs.
  3. Normal mode - This mode is all about using commands to do things based on where the cursor is. Each key no longer inserts the letter it represents, but represents a distinct command.
  4. Ex mode - This mode doesn’t deal with the cursor too much anymore, but the file as a whole. It treats the file as a stream of text lines that you can transform with commands.

[#deleting-lines-in-insert-mode]Deleting Lines in Insert Mode[#deleting-lines-in-insert-mode]

Press: [.inline-code]Backspace[.inline-code] or [.inline-code]Delete[.inline-code] (a lot)

There are no surprises here. Deleting a line in insert mode is the same as deleting any other piece of text: mash the backspace/delete key until that line is gone!

[#deleting-lines-in-visual-mode]Deleting Lines in Visual Mode[#deleting-lines-in-visual-mode]

Press: [.inline-code]Vd[.inline-code]

Select the line, then press delete.” That’s what most people will think to delete a line. They might grab the mouse and drag it over the line to select it. Vim also has the idea of selection, though it can do it faster than other editors which use the mouse.

Vim does this with “visual mode”. The idea is that you enter visual mode from normal mode by pressing [.inline-code]v[.inline-code] and then selecting a section of text by moving the cursor over that text. Subsequent commands will apply to the selected text. The command to delete is [.inline-code]d[.inline-code]. So, you can move to the beginning of the line, press [.inline-code]v, move to the end of the line, and press d[.inline-code]. Altogether that might look like [.inline-code]0v$d[.inline-code]. However, Vim provides a shortcut to select the line under the cursor: (capital letter) [.inline-code]V[.inline-code]! So, to delete the line under the cursor, you can press [.inline-code]Vd[.inline-code].

For example, when the cursor is on line 5 and you press [.inline-code]V[.inline-code] to select it:

Pressing [.inline-code]d[.inline-code] deletes the selected line:

[#deleting-lines-in-normal-mode]Deleting Lines in Normal Mode[#deleting-lines-in-normal-mode]

Press: [.inline-code]dd[.inline-code]

You’ll spend most of your time in normal mode. It involves movement of the cursor as well as actions based on where the cursor is. Each key is a command rather than the literal insertion of a letter as in insert mode. [.inline-code]d[.inline-code] is delete. However, you would never just press [.inline-code]d[.inline-code]. Pressing [.inline-code]d[.inline-code] means delete something, but delete what? You need more keypresses to specify what to delete. This is the power of normal mode. You don’t just delete the character behind the cursor or the stuff that’s selected. You combine commands like [.inline-code]d[.inline-code] with movement for more powerful deletion. But what sort of things can we press after [.inline-code]d?[.inline-code] You can use any of Vim’s commands for movement:

Word navigation [.inline-code]wWeEbB[.inline-code], e.g. [.inline-code]dw[.inline-code] to delete a word.

Character searching [.inline-code]fFtT[.inline-code], e.g. [.inline-code]df([.inline-code] to delete between the cursor and the next [.inline-code]([.inline-code] character.

Text object navigation [.inline-code]}])[.inline-code]

Line navigation [.inline-code]0^$[.inline-code]

Buffer navigation [.inline-code]gG[.inline-code]

Alternatively, pressing [.inline-code]d[.inline-code] again ([.inline-code]dd[.inline-code] altogether) will tell Vim to delete the line under the cursor.

So, [.inline-code]dd[.inline-code] deletes the line under the cursor. There is more! In general, normal mode commands are repeatable by entering an integer before the command. For example, [.inline-code]j[.inline-code] moves down a line, but [.inline-code]10j[.inline-code] moves down 10 lines. This flexibility applies to [.inline-code]dd[.inline-code] too. You can press [.inline-code]5dd[.inline-code] to delete 5 lines, the first line being the one under the cursor.

For more sophisticated movement, you can rely on the other movement commands using [.inline-code]d + movement[.inline-code]. For example, to delete the line under the cursor plus 4 lines above you can press [.inline-code]d4k[.inline-code]. Or, to delete all lines from where the cursor is until the end of the file press [.inline-code]dG[.inline-code]. In this file, to delete the function [.inline-code]pythagorean_theorem[.inline-code] we can jump to line 7 with [.inline-code]7G[.inline-code] and then press [.inline-code]dG[.inline-code].

Note: For all these commands, you can replace [.inline-code]d[.inline-code] with [.inline-code]c[.inline-code] to enter insert mode after the deletion. How is this different from using [.inline-code]d[.inline-code] followed by pressing [.inline-code]i[.inline-code]? It makes the subsequently inserted text part of the same action as the delete, which allows both to be repeated by a dot repeat [.inline-code].[.inline-code].

[#deleting-lines-in-ex-mode]Deleting Lines in Ex Mode[#deleting-lines-in-ex-mode]

This mode is the most powerful and mysterious. It rarely deals with the cursor (though it can at times). You enter ex mode by pressing [.inline-code]:[.inline-code] from normal or visual mode. What follows is a range and a command. The range specifies which lines to apply the command to. Again, the [.inline-code]d[.inline-code] command means delete here. The simplest range is a line number. [.inline-code]:15d[.inline-code] means delete line 15. You can make it an inclusive range with a comma, so :[.inline-code]15,18d[.inline-code] means delete lines 15, 16, 17, and 18. Going back to the previous example. You can delete the [.inline-code]pythegorean_theorem[.inline-code] function with [.inline-code]:8,10d[.inline-code] without needing to move the cursor!

There are some special characters for certain lines. [.inline-code]$[.inline-code] represents the last line in the file. . is the line under the cursor. [.inline-code]'<[.inline-code] and [.inline-code]'>[.inline-code] represent the first and last lines of the selected range if you entered ex mode from visual mode. So, [.inline-code]:.,$d[.inline-code] means delete the line under the cursor up to the end of the file, similar to [.inline-code]dG[.inline-code] in normal mode.

[#using-deletion-as-a-means-of-searching]Using Deletion as a Means of Searching 🔍[#using-deletion-as-a-means-of-searching]

How do these tools fit into the bigger picture of engineering?

If I was asked to find a needle in a haystack, I would light the haystack on fire. The hay would burn and the needle wouldn’t. The search becomes much easier when only the needle is left. However, I wouldn’t’ve thought of this approach unless I’d started a few fires before

Deletion is like burning something you aren’t looking for. Suppose you’re administrating a Linux server that uses Fluentd to collect database logs. The daemon is sending its logs to [.inline-code]syslog[.inline-code] among many other daemons on the server. You can view the logs in Vim with [.inline-code]vim /var/log/syslog[.inline-code].

Suppose you don’t need to read any messages from [.inline-code]cron[.inline-code] or [.inline-code]systemd[.inline-code]. Sifting through the logs becomes much easier if you delete the log messages from those sources. An ex mode delete command can be the best solution! Rather than using line numbers to specify a range, you can specify a regexp pattern on which to apply the delete command. Do this with [.inline-code]:g/pattern/d[.inline-code]. So, since the relevant log messages include the process name, you can do [.inline-code]:g/CRON\\|systemd/d[.inline-code] to delete them!

Suppose we want to get even more specific, and only want to see log messages from our log-collecting service, [.inline-code]fluent-bit[.inline-code]. We want to delete all log messages that don’t match “fluent-bit”. You can negate a pattern with [.inline-code]:v/pattern/d[.inline-code]. So, by doing [.inline-code]:v/fluent-bit/d[.inline-code] we get a nicely filtered result.

[#going-beyond-deletion]Going Beyond Deletion[#going-beyond-deletion]

You’ll encounter many tasks that are made simpler with “smart deletion”. For example, maybe during development you added a bunch of print statements for debugging, and you need to remove them all before committing and pushing. Something like [.inline-code]:g/console.log/d[.inline-code] can make that very easy. The more you master your delete tools, the more opportunities you’ll find them useful.

Vim’s modes each give us unique ways to delete stuff ranging from simple to super stylish. The more ways you know to delete lines, the more creatively you can use these to do all kinds of things. The next time you find yourself using visual mode to delete a section of text, ask yourself if there is a better way to do it in normal mode or ex mode!