unknown_document

We couldn't find that page... Were you looking for one of these?


Moving Lines
Reorganizing lines in a buffer is a very common task. While a yank and paste sequence could be used for each line, there is a better way. The following keymaps allow a line or group of lines to be easily moved up or down using a single keystroke: -- single-line vim . keymap . set ( "n" , "<A-j>" , ":move .+1<CR>==" ) vim . keymap . set ( "n" , "<A-k>" , ":move .-2<CR>==" ) -- multi-line vim . keymap . set ( "v" , "<A-j>" , ":move '>+1<CR>gv=gv" ) vim . keymap . set ( "v" , "<A-k>" , ":move '<-2<CR>gv=gv" ) To see how they work, consider the following buffer: Initial Conditions a = [ "one", "three", "two", "four", "five", ] NORMAL Top 1:1 Note that the words are out of order, and we would like to fix that. We start by moving the cursor to the line that we want to move (i.e. the "target" line): Move to Target Line 2j a = [ "one", "three", "two", "four", "five", ] NORMAL 38% 3:1 With this keymap, hitting A-J allows us to easily move the currently down one position, swapping its position with the line below it: Move Current Line <A-j> a = [ "one", "two", "three", "four", "five", ] NORMAL 50% 4:1 To get a better idea about what happened, consider the command that executed when we hit A-J : :move .+1<CR>== The :move command has a call signature: :m[ove] {address} and moves the current line (or selected lines) to the line below the specified address. In this case, the specified address is .+1 , which we learned in the ranges chapter means "the line below the current line". The carriage return causes the preceding command to execute, which is follows by == , which formats (indents) the line after it is moved. Let's see how this works with a visual selection . First, let's move the cursor so that the selection spans three lines: Select Multiple Lines v 2j a = [ "one", "two", "three", "four", "five", ] VISUAL 75% 6:1 Note that although the selection only touches the third line, the entire line is included in the block of lines to move. Now, move these lines up: Move Multiple Lines <A-k> a = [ "one", "three", "four", "five", "two", ] VISUAL 62% 5:1 3 lines indented The selected lines have each move up one line, and the line containing "two" (which has previously been above the selection) is now located below the selection.
Removing Duplicates
A common task when editing files is to remove duplicate lines. While this can be done manually, it is often easier to leverage Vim's command-line mode to leverage the uniq command. Suppose we have the following file in a buffer and want to remove duplicates: Initial Conditions b ananas apples apples oranges apples COMMAND Top 1:1 :%!uniq The command to execute is: :%!uniq 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, although this can be replaced with a range specifying a subset of lines, or a visual selection . 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: uniq with (initially) no arguments. By default uniq takes input from stdin , so there is no need to specify the input source. Executing this command produces the following output: Execute uniq b ananas apples oranges apples NORMAL Top 1:1 5 lines filtered which is not exactly what we were looking for. It turns out that by default uniq only detects adjacent repeating lines, so apple still appears twice in the output. If we take a look at the help page for uniq we see that the -u option can be used to print only unique lines, which is what we were looking for. Lets undo to get back to the original buffer, then try again using the -u argument: Execute uniq -u b ananas oranges apples NORMAL Top 1:1 5 lines filtered That is more like it. We should note that uniq also offers the -d option, which performs the opposite function and returns only the duplicate lines . Starting from the original buffer we can execute this command to see the result: Execute uniq -d a pples NORMAL Top 1:1 5 lines filtered
Formatting a Selection
Starting with the cursor in the middle of an un-formatted buffer : Initial Conditions <div> <p>line one</p> <p>line two</p> <p>line three</p> </div> NORMAL 50% 3:1 Enter visual mode : Enter Visual Mode <Esc> <div> <p>line one</p> <p>line two</p> <p>line three</p> </div> NORMAL 50% 3:1 Move down another row: Create the Selection v <div> <p>line one</p> <p>line two</p> <p>line three</p> </div> VISUAL 50% 3:1 and finally format the selected lines: Format Selection j <div> <p>line one</p> <p>line two</p> <p>line three</p> </div> VISUAL 67% 4:1 Note that Vim formatted only the lines contained within the selection (including lines containing the cursors), and didn't touch the other lines.
Navigating Markdown Headings
Neovim provides many ways to navigate within documents, and this tip creates a simple keymap that makes it quick and easy to jump between markdown headings, which can be a big speed boost in longer markdown documents. Create a markdown directory under ftplugin if it doesn't already exist, then add a file containing the following keymaps : vim . keymap . set ( "n" , "<A-j>" , "/^# \\ + <CR>" ) vim . keymap . set ( "n" , "<A-k>" , "?^# \\ + <CR>" ) These keymaps take advantage of the search operators / and ? to search forward and backward from the current cursor position, respectively. In each case, Neovim searches for the pattern ^#\\+ , which matches any line that starts with one or more # characters followed by a space. While this is a fairly naive pattern that may produce some false matches, it is very simple to implement and works quite well for most markdown documents. As a quick demo, let's take the following Markdown file. Starting from the top, in steps 1 and 2 we hit <A-j> to step forward through the headings, then finally in step 3 we use <A-k> to jump back up to the previous heading: Start 1 2 3 Before # Heading 1 Text ## Heading 2 Text ### Heading 3 NORMAL Top 1:1 Jump to Next Heading <A-j> # Heading 1 Text # # Heading 2 Text ### Heading 3 NORMAL 50% 5:1 Jump to Next Heading (Again) <A-j> # Heading 1 Text # # Heading 2 Text # ## Heading 3 NORMAL 90% 9:1 Jump to Previous Heading <A-k> # Heading 1 Text # # Heading 2 Text # ## Heading 3 NORMAL 50% 5:1 This keymap also supports counts , allowing you to navigate even faster by jumping multiple headings at a time. If you would like to see another way to implement the same function but using Treesitter, take a look at this tip.
Insert a REST API Response
Neovim registers and command-line mode can be combined to a pretty decent REST API client. This tip shows how. First, open a new buffer and add the API request: Initial Conditions h ttps://jsonplaceholder.typicode.com/todos/1 NORMAL Top 1:1 Now, yank the current line, which places the contents of the current line into register 0 : Yank the API Request String yy h ttps://jsonplaceholder.typicode.com/todos/1 NORMAL Top 1:1 Finally, lets build the command to call the API and insert the response. First, we learned previously that we can use the :read command to call a shell command and insert its output. The call signature is: :read !{cmd} [args] In this case we want to call a REST API, so lets use curl to call the API and receive the response. The command to achieve is: curl -s '{request}' where the -s option tells curl to operate in "silent mode". Finally, we could hard-code the request into the command, but we have already yanked it to register 0 . We can retrieve register contents in command-line mode using C-R followed by the register name, so our complete command is: :read !curl -s '<C-r>0' Executing this command produces: Insert the API response h ttps://jsonplaceholder.typicode.com/todos/1 { "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false } NORMAL 88% 7:1 6 more lines if you find yourself using this often, consider creating a macro to save yourself a few keystrokes.
Yank the Entire Buffer
When editing a document one often needs to yank the entire buffer content. As with most operations, Neovim provides several different ways to accomplish this task. For each of the examples below, we will start with the following buffer content and cursor position: Initial Conditions red,#f00 green,#0f0 blue,#00f y ellow,#ff0 cyan,#0ff magenta,#f0f NORMAL 57% 4:1 Common Method Perhaps the most common method to achieve this task is the following sequence: gg to move the cursor to the top of the buffer. v to enter visual mode . G to move the cursor to the bottom of the buffer. y to yank the selected content. Common Method gg V G y r ed,#f00 green,#0f0 blue,#00f y ellow,#ff0 cyan,#0ff magenta,#f0f NORMAL Top 1:1 6 lines yanked Let's check the unnamed register to confirm that the full buffer content was yanked: Common Method r ed,#f00 green,#0f0 blue,#00f yellow,#ff0 cyan,#0ff magenta,#f0f COMMAND Top 1:1 :reg " :reg " Type Name Content l  ""   red,#f00green,#0f0blue,#00fyellow,#ff0cyan,#0ffmagenta,#f0f line 0: sourcing "/tmp/.mount_nvimqnPRCt/usr/share/nvim/runtime/autoload/provider/clipboard.vim" finished sourcing /tmp/.mount_nvimqnPRCt/usr/share/nvim/runtime/autoload/provider/clipboard.vim continuing in nvim_exec2() Executing command: "'/usr/bin/wl-paste' '--no-newline' '--primary'" Executing command: "'/usr/bin/wl-paste' '--no-newline'" This method works well, and is probably so common because it is consistent with yanking smaller portions of the buffer. Besides requiring the most keystrokes, this method also has the disadvantage of moving the cursor to the top of the screen. Shorter Method A slightly shorter method leverages motions a bit more directly to save a keystroke: gg to move the cursor to the top of the buffer. y to yank the selected content. G to move the cursor to the bottom of the buffer. Shorter Method gg y G r ed,#f00 green,#0f0 blue,#00f y ellow,#ff0 cyan,#0ff magenta,#f0f NORMAL Top 1:1 6 lines yanked Let's check the unnamed register to confirm it worked: Shorter Method r ed,#f00 green,#0f0 blue,#00f yellow,#ff0 cyan,#0ff magenta,#f0f NORMAL Top 1:1 :reg " Type Name Content l  ""   red,#f00green,#0f0blue,#00fyellow,#ff0cyan,#0ffmagenta,#f0f line 0: sourcing "/tmp/.mount_nvimWwWNmU/usr/share/nvim/runtime/autoload/provider/clipboard.vim" finished sourcing /tmp/.mount_nvimWwWNmU/usr/share/nvim/runtime/autoload/provider/clipboard.vim continuing in nvim_exec2() Executing command: "'/usr/bin/wl-paste' '--no-newline' '--primary'" Executing command: "'/usr/bin/wl-paste' '--no-newline'" This method is slightly better than than the previous method, but also moves the cursor to the top of the screen. Shortest Method The third, and shortest, method of yanking all buffer content leverages the % range to yank the entire buffer with only 3 keystrokes: Upon hitting <CR> the entire buffer is yanked: Shortest Method red,#f00 green,#0f0 blue,#00f y ellow,#ff0 cyan,#0ff magenta,#f0f COMMAND 57% 4:1 :%y Not only is this the shortest method, it has the additional advantage of keeping the cursor in the same position. Shortest Method red,#f00 green,#0f0 blue,#00f y ellow,#ff0 cyan,#0ff magenta,#f0f NORMAL 57% 4:1 :reg " Type Name Content l  ""   red,#f00green,#0f0blue,#00fyellow,#ff0cyan,#0ffmagenta,#f0f line 0: sourcing "/tmp/.mount_nvimSM0vJf/usr/share/nvim/runtime/autoload/provider/clipboard.vim" finished sourcing /tmp/.mount_nvimSM0vJf/usr/share/nvim/runtime/autoload/provider/clipboard.vim continuing in nvim_exec2() Executing command: "'/usr/bin/wl-paste' '--no-newline' '--primary'" Executing command: "'/usr/bin/wl-paste' '--no-newline'"
Inserting Unicode Characters
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 substitution s ✕ 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
Replacing a Word in the Current Buffer
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 B eautiful 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 B eautiful 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. S parse 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: Title u B eautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. S parse is better than dense. Readability counts. NORMAL Top 1:1 6 changes; before #1 0 seconds ago
External Formatting
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.