Welcome to tui.ninja!


expand_more
Sometimes it can be handy to get a quick diff of the changes that have been made to the current buffer since the previous save. This can be achieved with a simple command-line mode command. To demonstrate, let's start with the following buffer: Initial Conditions a = [ "one", "two", "three", "five", ] COMMAND Top 1:1 :%s/two/changed Now lets edit the buffer. To keep it simple we will make a single edit, changing "two" to "changed": Edit the Buffer a = [ "one", " changed", "three", "five", ] NORMAL 43% 3:5 Now, we can generate a simple diff with the command: :write !diff % - Let's review what this does. To start, this uses the :write command with the following call signature: :w[rite] !{cmd} Which passes the entire contents of the current buffer to the specified command via stdin . In this example we will use the diff shell command, which has the call signature: diff file1 file2 where our command defines file1 and file2 as: file1 = % , which contains the filename of the current file, and file2 = - , which tells diff to read stdin So, putting this all together, we pass the current buffer contents to the diff command, and generate the diff between the saved version of the current file ( % ) and the current buffer contents. Finally, the diff is passed back to Neovim: Generate the Diff a = [ "one", " changed ", "three", "five", ] NORMAL 43% 3:5 :write !diff % - 3c3 <     "two", --- >     "changed", shell returned 1 The output window shows that the line containing "two" has been changed to "changed". diff also returns a status code if 1 , meaning that the two files were different. This is definitely not the prettiest diff in the world, but is useful when a quick diff is required. Take a look at: diff --help to see what options are available to suit the output to your needs. For example, by leveraging diff 's options one can format the same output as a side-by-side diff: :write !diff -yt -W 60 % - Alternate Output a = [ "one", " changed ", "three", "five", ] NORMAL 43% 3:5 :write !diff -yt -W 60 % - a = [                           a = [ "one",                          "one", "two",                   |      "changed", "three",                        "three", "five",                         "five", ]                               ] shell returned 1
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 After Before Default Line o ne Line two Line three NORMAL Top 1:6 After Default J Line o ne 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 After Before Improved Line o ne Line two Line three NORMAL Top 1:6 After Improved <A-j> Line o ne 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 Mark mz Line o ne Line two Line three NORMAL Top 1:6 Now that we have set the mark , execute the join by executing J : Join Lines J Line o ne 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 o ne 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> .
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. NORMAL Top 1:1 Suppose one wants to change all occurrences of is better to is way better . The first step in the example if to move the cursor to the word we want to replace: w B eautiful i s 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:11 then press & to select all occurrences of the word under the cursor. In addition to selecting all occurrences of is , the cursor moves to the next occurrence. * Beautiful i s better than ugly. Explicit i s 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 25% 2:10 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}/ Not needed, since the words to replace are already selected. {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: Beautiful is way better than ugly. Explicit i s 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 .