This chapter compiles many of the best tips and tricks that the Neovim community has developed over the years to turbo-charge your Neovim workflow.
Filed In:editing
Vim's built-in J command can be used to join the current line with the next line, which can be a very handy tool for keeping text "clean" when editing. Let's take a quick look at the default behavior. Starting from the following buffer , execute J : Before Before Default Line one Line two Line three NORMAL Top 1:6 After After DefaultJ Line one Line two Line three NORMAL Top 1:9 Note that the second line has merged with the first, but the cursor jumped after joining the lines, which is a bit disorienting. We would prefer to join lines without having the cursor move, so in this tip we will develop a simple keymap that achieved this. For comparison, here is a quick demo of the buffer before and after the improved keymap: Before Before Improved Line one Line two Line three NORMAL Top 1:6 After After Improved<A-j> Line one Line two Line three NORMAL Top 1:6 Let's set this up, step by step. Since the default J moves the cursor, our goal is to have the cursor return to the original location, which we can achieve by setting a mark to record the cursor position before we execute J . We can use any lower-case letter, let's use z: Set Markmz Line one Line two Line three NORMAL Top 1:6 Now that we have set the mark , execute the join by executing J : Join LinesJ Line one Line two Line three NORMAL Top 1:9 As we saw before, the cursor jumped. Now, we simply jump back to the mark we previously set using `z : Jump to Mark`z Line one Line two Line three NORMAL Top 1:6 Now that we have compiled the steps required to get the behavior we want, let's combine the steps into the following keymap: vim.keymap.set("n","<A-j>","mzJ`z") Note that for demonstration purposes this mapping sets the alternate keymap to A-J. If you prefer this functionality over the default, then you can also override the default keymap directly by using J instead of <A-J>.
Filed In:editing
Inserting unicode characters into a document can be cumbersome, and for many the default process is to do a quick web search to find the desired character, then copy and paste it into the document. While Neovim can't make it easier to remember all of the code points, it does make the process of inserting it into a document slightly easier. Suppose we are shopping with a simple shopping list, and just bought coffee so we want to update the shopping list. Let's move the cursor into position then check that line off: Initial Conditions ✕ milk ✕ coffee ✕ eggs NORMAL 50% 2:1 The first step is to type s (substitute), to delete the current character and enter insert mode . Start a substitutions ✕ milk coffee ✕ eggs INSERT 50% 2:1 Next, we hit C-V , followed by u and the Unicode code point we want to insert. Insert the Unicode<C-v>u2713 ✕ milk ✓ coffee ✕ eggs INSERT 50% 2:2 Finally, hit Esc to return to normal mode : Final Result<Esc> ✕ milk ✓ coffee ✕ eggs NORMAL 50% 2:1
Filed In:editing
It is a common task to search and replace all occurrences of a word within the current buffer. For example, given the following buffer : Initial Conditions Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. COMMAND Top 1:1 :%s/is/is way/ Suppose one wants to change all occurrences of is better to is way better. The general template for searching and replacing is: :[range]s/{pattern}/{replacement}/[flags] where Template Value Description : Puts Vim into Command Mode [range] % Applies this command to the entire file s/ Indicates that this is a search and replace operation {pattern}/ is Specifies the pattern to search for {replacement}/ is way Specifies the text to replace the search pattern with. [flags] No flags are specified. Putting this all together and executing the command: Title Beautiful is way better than ugly. Explicit is way better than implicit. Simple is way better than complex. Complex is way better than complicated. Flat is way better than nested. Sparse is way better than dense. Readability counts. NORMAL 75% 6:1 6 substitutions on 6 lines As expected, each occurrence of is has been replaced with is way. Writing patterns can sometimes require a bit of trial and error, if the final text is not as expected, simply hit u to return to the original: Titleu Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. NORMAL Top 1:1 6 changes; before #1 0 seconds ago
Filed In:editing
Vim's internal formatting features work great in many cases, but sometimes it can be helpful to send a buffer's content to an external program to perform the formatting, then replace the buffer contents with the result. For example, suppose we have the following JSON file in a buffer and want to sort the keys. Initial Conditions { "bananas": 12, "strawberries": 15, "apples": 34, "oranges": 24, "grapes": 33 } COMMAND Top 1:1 :%!jq -S . % We will demonstrate how to achieve this using a command-line mode command that calls jq , a popular command-line JSON processor. Obviously jq needs to be installed on a system for this to work. The command to execute is: :%!jq -S . % Let's break this down to review what is happening: To start, this follows the pattern: :[range]!{cmd} {args} where :% specifies the range as the entire file. Next, !{cmd} indicates that an external command is to be called with the specified range and arguments. In this case the external command to be called is: jq -S . % The details of this command are (mostly) outside the scope of Vim itself, but can be found by executing jq --help which indicates that the jq command is called with the format: jq [options] <jq filter> [file] where: [options] = -S (sort object keys) <jq filter> = . (pass all lines back to stdout) [file] = % (Vim inserts the current filename) Now, when we execute this command we get the following result: After External Formatting { "apples": 34, "bananas": 12, "grapes": 33, "oranges": 24, "strawberries": 15 } NORMAL Top 1:1 7 lines filtered which contains our sorted JSON object.