Vim Hints is back!
Oops! Where did half of 2015, all of 2016 and the first half of 2017 go?
Well, life got in the way, plus motivation dwindled somewhat. This series is very demanding - the sed series was a walk in the park compared to tackling the continental-scale landscape of Vim!
Still, the original goal was to try and introduce the really useful features of Vim and to make it manageable for everyday use. The hope was, and still is, that the series could get people started on their own journeys through its marvels.
Also, with the currently circulating StackOverflow article on “How to exit the Vim editor?”, it’s worth pointing out that we dealt with that subject in episode 1, and this issue is revealed as the ridiculous meme that it really is!
To recap, the last episode of this planned series was in March 2015. Here’s a list of links to all of the episodes so far:
- Vim Hints 001 (show 1714 2015-02-26)
- Vim Hints 002 (show 1724 2015-03-12)
- Vim Hints 003 (show 1734 2015-03-26)
- Vim Hints 004 (show 1776 2015-05-25)
Let’s briefly describe what was covered in these episodes to set the context.
So far we have looked at very basic editing in episode 1, where we mentioned modes Normal, Insert and Command modes.
In episode 2 we looked at Vim’s backup mechanism, undoing and redoing changes, and file recovery in the event of a problem. We started using the
.vimrc configuration file.
We began looking at movement commands in Normal mode in episode 3, and beefed up the configuration file somewhat.
More movement commands were covered in episode 4 as well as searching. We began looking at commands that make changes, adding, inserting, deleting and changing text in various ways. The concept of doing these things with various movements was covered. Again, a number of useful options for the configuration file were introduced.
Copying and pasting
So far we have inserted, changed and deleted text, all in Normal mode. Now we want to look at how to copy existing text and how to paste text. See the Vim Help (type :help change.txt) or the online documentation here for the full details.
The yy command in Normal mode yanks or copies lines. Just like dd (which we saw in episode 4), if preceded by a count it will yank more than the default one line.
Note that the Y command is a synonym for yy. It doesn’t do the equivalent of what C and D do, yank from the current position to the end of the line.
The y command yanks or copies characters. Like c (change) and d (delete) (seen in episode 4) it needs a movement command to follow. The table below shows some examples of the operator+movement combinations:
|yw||Yank from the cursor to before the start of the next word|
|ye||Yank from the cursor to the end of the next word|
|y$||Yank from the cursor to the end of the line (same as yy)|
|y0||Yank from before the cursor to the beginning of the line|
|y)||Yank from the cursor to the end of the sentence|
Having copied text (or having deleted or changed it) it’s then possible to paste it (or put it as the Vim documentation defines it). The various delete commands save the last text that was deleted, and the change commands save the last text as it was before it was changed.
The p command in Normal mode puts (pastes) text after the cursor. The P command puts (pastes) text before the cursor. In both cases the cursor is left on the last character of the pasted text. Both commands can be preceded by a count, resulting in the text being pasted multiple times.
A number of Vim commands can be preceded by g which makes changes to their effects. We will visit these as we introduce new features.
In the case of these paste commands the effects are:
|gp||Just like p but leave the cursor after the pasted text|
|gP||Just like P but leave the cursor after the pasted text|
Deleted, changed and copied text is stored in a register. It’s a default register if not specified, but a number of other registers exist in Vim and can be chosen as the source and destination of commands.
This is a large topic, and this information is just a forward reference to the subject which we’ll look at in more detail in a forthcoming show in the series.
Examples of cutting, copying and pasting
- A simple use of cut and paste is the sequence xp. This swaps the character under the cursor with the one after it. It’s really useful if, like me, your fingers keep typing teh instead of the, for example.
- The sequence dwwP is useful for swapping words. Remember that dw deletes the current word (assuming the cursor is on the first character), then the next w moves forward one word and P pastes the deleted word in front of it. This is not the most robust and reliable way of doing this, but hopefully it makes the point.
- The sequence ywP yanks the current word (again assuming the cursor is on the first character) and pastes it in front of the cursor, thereby duplicating the word.
Text objects again
We saw in episode 4 that Vim has the concept of text objects, and we looked at sentences and paragraphs, and at movements and actions relating to them. There are more than these, and in this episode we’ll look at them in the context of commands. We’ll just touch the surface of this subject for now, and will come back for a deeper look in a later episode. See the Vim Help (type :help motion.txt) or the online documentation here for the full details.
Defining an inner object
We have seen commands like dw and yw which have an effect relating to a word. The command yw means “yank from the cursor position to before the beginning of the next word”. However, yiw, means “yank inner word” and has the effect of yanking from the start of the current word to the end of that word. That is, it doesn’t matter where in the word the cursor is positioned.
Similarly diw deletes the entire word the cursor is positioned on. The “inner word” means that it does not include any non-word character after the word. In fact, the same applies to leading non-word characters too.
There are many objects that can be used with this “inner” text selection mechanism, including sentences and paragraphs. We will not look at all of them in this episode, but will revisit the subject again later.
Defining an object
This terminology is a little confusing, but it exists because the effect is achieved by using an a (“an object”) rather than the i for “inner object”. (I like to think of the a as signifying all as a way to remember it.)
Here yaw includes all trailing white space (if there is any) and leading white space if there was no trailing space. Again the effect works regardless of where the cursor is positioned in the word.
There are many objects that can be used with this type of text selection mechanism, including sentences and paragraphs. We will not look at all of them in this episode, but will revisit the subject again later.
The following example shows two rows of numbers which represent the column number in the line of text which follows. We will use these lines to show the result of actions at certain cursor positions:
1 2 3 4 5 6 123456789012345678901234567890123456789012345678901234567890 Hacker Public Radio is dedicated to sharing knowledge.
- Cursor at column 10 (on the b of Public). Typing diw here results in the deletion of “Public” leaving the leading and trailing spaces.
Hacker Radio is dedicated to sharing knowledge.
- Cursor at column 10. Typing daw here results in the deletion of “Public” including the trailing space.
Hacker Radio is dedicated to sharing knowledge.
- Cursor at column 48 (on the w of knowledge). Typing diw here results in the deletion of knowledge but leaves the leading space and the terminating full stop.
Hacker Public Radio is dedicated to sharing .
- Cursor at column 48. Typing daw here results in the deletion of knowledge and the leading space, thereby terminating the sentence.
Hacker Public Radio is dedicated to sharing.
A few other objects
|yis||Yank inner sentence (start to ending punctuation)|
|yas||Yank a sentence (including trailing white spaces)|
|yip||Yank inner paragraph (start to before terminating blank line)|
|yap||Yank a paragraph (including trailing blank line)|
There are times when two lines adjacent to one another might need to be joined together. This can be achieved with the J command (remember that j is a cursor movement command). The J command can be preceded by a count to join multiple lines.
The J command places a space between the joined lines. It is removing the <EOL> (end of line) characters between lines and replacing them with spaces. More spaces may be inserted here if certain options are enabled which add double spaces after the end of a sentence.
The gJ command (remember g is often used for variants of certain commands) joins lines like J does but without adding spaces.
Given the following three lines, we will demonstrate the results of the two commands:
Hacker Public Radio
Positioning the cursor on the first line and typing 3J results in:
Hacker Public Radio
Whereas the same with 3gJ results in:
The configuration file we have built so far (see episode 4) has grown moderately long, and it will get longer in this episode. I order to simplify matters this is now included as a separate file: example_vimrc_5.
Full information on the options available in Vim can be found in the Vim Help (type :h options.txt) or online here.
This turns on Vim’s syntax highlighting features. We haven’t really looked at these in detail, but it’s useful to have some colouring and highlighting wherever it’s available.
If you have indented a line while typing, and start a new line then Vim will automatically indent that line the same as the original. This is very useful when writing a program or when preparing text.
This feature is turned on with the command:
The abbreviation for the command is is se ai and the effect can be reversed with set noautoindent or se noai.
As you are typing in Insert mode Vim can wrap automatically to the next line (by automatically adding the necessary line break). It does this when the defined line width has been reached and the current word is completed. It does not split words.
Note that if you add to an existing line and make it exceed the text width, Vim will not wrap the line.
The maximum width of text which triggers wrapping can be defined with the command:
The abbreviation for the command is is se tw=NNN and the text width feature can be turned off with set textwidth=0 or se tw=0. The text width feature is turned off by default.
Tabs or spaces
In Insert mode, pressing the TAB key inserts a TAB character and moves the cursor to the appropriate tab stop.
The subject of whether to use TAB characters or spaces to indent programs can generate much discussion. We will look at this matter in more depth later in the series, but for now I suggest we make Vim replace TAB characters with spaces by default and make indenting to be in increments of 4 columns.
This can be achieved with two configuration options: expandtab and shiftwidth.
The expandtab option forces all TAB characters to be replaced by the appropriate number of spaces in Insert mode. This is a Boolean option, to to turn it on you need:
To turn it off use:
The command can be abbreviated to se et or se noet.
Note that if the file you are editing already contains TAB characters this setting will not affect them. There is a command mode command :retab which can be used to replace all TAB characters but we’ll look at that later.
The shiftwidth option controls the number of spaces to use for autoindenting. It takes an argument - the number of spaces:
This sets the autoindent step to 4 spaces.
The option can be abbreviated to se sw=4.
As already mentioned, this is not the whole story, but we’ll leave this subject to be developed in an upcoming episode. (Hint: we’ll be looking at tabstop and softtabstop later).
We will also look at the use of CTRL+D (<C-D>) and CTRL+T (<C-T>) to delete and add indents to the automatically created ones.
Turning off the search highlight
It was mentioned in episode 4 that when searching for text with incsearch and hlsearch on all of the matches would be highlighted. These strings remain highlighted until another search is executed or the :nohl command is issued.
One way to simplify the cancellation of the highlight is shown in this episode’s example configuration file. It uses a feature we have not seen yet, the mapping of a key to a command. We will look at this in detail in a later episode. Suffice it to say that if you add the following to your
.vimrc you will be able to turn off the highlighting by typing CTRL-L, which will also refresh (redraw) the window:
nnoremap <C-L> :nohl<CR><C-L>
- yy or Y to copy a line
- ymotion to copy text up to a movement target
- p puts (pastes) after the cursor
- P puts (pastes) before the cursor
- gp and gP like p and P but leave the cursor after the pasted text
- Text objects with i and a
- i means the inner object
- a means all of the object
- Joining lines
- J joins with spaces
- gJ joins without spaces
" Previous stuff omitted for now, see 'example_vimrc_5' " Enable syntax highlighting syntax on " Indent automatically set autoindent " Wrap at 78 characters set textwidth=78 " In Insert mode use numbers of spaces instead of tabs set expandtab " Define number of spaces to use for indenting set shiftwidth=4 " Highlight searches (use <C-L> to temporarily turn off " highlighting; see the mapping of <C-L> below) set hlsearch " Map <C-L> (redraw screen) to also turn off search highlighting " until the next search nnoremap <C-L> :nohl<CR><C-L>