These are features of Vim which I use but haven’t yet organised into sections or don’t use frequently enough to write about.
ctrl o = jumplist skip foward
ctrl i = jumplist skip backwards
`*` = next instace of word under cursor
`#` = prevous instance of word under cursor
:%y = yank whole file (works better than my old vGy technique)
ctrl g = filename
ctrl a = decrease number under cursor (works in visual selections too)
ctrl x = increase number under cursor (works in visual selections too)
:%s/foo/bar/g = Replace foo with bar on all lines
:s/foo/bar/g = Replace foo with bar on this line only
set clipboard=unnamedplus = sync system clipboard with yank register
set incsearch = jump to search word as you type
set linebreak = don't split long words across two lines
Although there are plenty of plugins available to help when finding files I like
to keep things stock so mostly use the :tabfind
command to find a file and have
it open in a new tab. Or if you want to have the file open in the current tab
use the :find
command instead.
:tabfind = Find file and open in a new tab
:find = Find file and open in current window
:fin = Shorthand for the :find command
By default Vim’s find
and tabfind
commands won’t scan for files recursively
so you’ll probably want to change this by adding a couple of asterisks to the
path
setting.
" Allows Vim's find and tabfind command to look in subfolders
set path=$PWD/**
Want to expand your find to look in the parent directory? Just pass in the path
into the find
command with a good old ../
. And if you need to look in
subdirectories too use a double asterisk.
"" Include the parent directory when finding files
:find ../footer
"" Include the parent directory and child folders when finding files
:find ../**/footer
Wildmenu is a built in Vim option which displays search results in a horizontal
bar which you can then tab through to find the result you want. You’ll probably
also want to use the wildignorecase
option to make the search case
insensitive.
"" Display find results in a horizontal menu format
set wildmenu
"" Ignore case when finding files
set wildignorecase
You’ll probably have some directories which you never want to look in such as
node_modules
or log
etc. You can easily ignore such paths with the
wildignore
setting.
"" Ignoring unwanted paths when finding files
set wildignore+=**/tmp/**
set wildignore+=**/node_modules/**
set wildignore+=**/_site/**
Finding a file in Vim and having it open in a new tab is such a common use case
for me that I have a keyboard shortcut set up for it in my vimrc
file. It lets
you hit ctrl+f
while in normal mode to start looking for a file.
"" Keyboard shortcut for finding files and opening in new tab
nnoremap <C-f> :tabfind<space>
First you’ll want to set the folding method. There are several options for this
but the one you’ll likely want to use is syntax
(note that the syntax setting
will have to be set for this folding method to work). Another potentially useful
folding method is indent
.
:set foldmethod=syntax
Now you can use the following commands in normal mode to control your folds:
### A = toggle
za = toggle fold at cursor
zA = toggle all folds in document (not very useful)
## O and C = Open and Close
zo = open fold at cursor
zc = close fold at cursor
zO = open fold at cursor (including child folds)
zC = close fold at cursor (including child folds - can't get this to work)
## R and M = Reduce and More (cursor position not relevant)
zr = open next level of folds in the document
zm = close next level of folds in document
zR = open all folds in the document
zM = close all folds in the document
" Use tabs for indentation (and convert existing indents to tabs)
:set noet \| retab! 2 \| :set ts=4 sw=4 <CR>
" Use tabs for indentation (but don't convert existing indents)
:set noet ts=4 sw=4 <CR>
" Use 2 spaces for indentation
:set et ts=2 sw=2 <CR>
" Use 2 spaces for indentation (and convert existing indents to spaces)
:set et ts=2 sw=2 \| retab <CR>
If you find yourself converting spaces into tabs often then you might like to
set up a remap in your vimrc
file. The following command will convert your
document from spaces into tabs and set Vim to use tabs from now on. To use these
remaps go into normal mode then type ,idt
to “indent tab” to start using tabs
for indentation, or type ,idtc
to “indent tab convert” to use tabs and convert
the existing indents to tabs. Same deal for spaces except use ,ids
and idsc
.
" Indentation shortcuts
"""""""""""""""""""""""
" Use tabs for indentation (but don't convert existing indents)
noremap ,idt :set noet ts=4 sw=4 <CR>
" Use tabs for indentation (and convert exsting indents to tabs)
noremap ,idtc :set noet \| retab! 2 \| :set ts=4 sw=4 <CR>
" Use 2 spaces for indentation (but don't convert existing indents)
noremap ,ids :set et ts=2 sw=2 <CR>
" Use 2 spaces for indentation (and convert existing indents to spaces)
noremap ,idsc :set et ts=2 sw=2 \| retab <CR>
I like all my new documents use tabs for indentation, for each tab to be 4
spaces wide, and to enable Vim’s auto and smart indentation features. The
following block added to my vimrc
file gets all that done.
" Indentation default settings
""""""""""""""""""""""""""""""
set ai " use autoindentation
set si " use smart indentation
set noet " use tabs instead of spaces
set ts=4 " tabs should be 4 spaces long
set sw=4 " autoindent width should be 4 spaces long
Vim has a whole bunch of options and commands relating to indentation which can be confusing at first because you often need to use a combination of these settings to make indentation work how you want it to. There might be more options available but these are the ones I used to get my indentation game figured out.
expandtab
and noexpandtab
- Boolean for setting what happens when you
press tab. When expandtab
or et
is set hitting the tab key will actually
insert a bunch of spaces (the number of which is set using the tabstop
setting). You can’t convert a document from spaces to tabs or vice versa with
this command, it just controls how the tab key behaves. The shorthand for
these commands are et
and noet
.
tabstop
- Sets the number of spaces each tab takes up. I prefer to use 4
spaces but certain formats such as markdown must be set to 2. Changing this
setting will update the whole document. The shorthand for this setting is
ts
.
shiftwidth
- Number of spaces to use for each step of autoindent
. You
don’t have to use this setting if you’re just converting the indentation of a
document but you’ll probably want to set it if you intend to do any editing.
Set it to the same as the tabstop
. The shorthand for this command is sw
.
autoindent
and noautoindent
- Copy indent from current line when starting
a new line. You can delete the indent by typing a single backspace followed by
the escape key. The shorthand for this command is ai
and noai
.
smartindent
- Enables smart auto indenting when starting a new line. Indents
will be automatically inserted after a line ending with ‘{‘ and before a line
starting with ‘}’. Normally autoindent
should also be on when working with
smartindent
. The shorthand for these commands are si
and nosi
.
retab
and retab!
- This is the command you use for converting a document
from spaces into tabs and vice versa, it works like a typical find and replace
and affects the entire document. You can pass in an optional tabstop number if
you like, or don’t to use whatever the current tabstop setting is. The !
makes vim also replace ‘normal’ strings of spaces with tabs where appropriate.
I’m not sure what makes a ‘normal’ string normal but I do know that you must
use the ! when converting spaces into tabs but not when converting tabs into
spaces.
Windows have advantages over tabs (at least, as far as I’ve read they do) but I’m yet to fully appreciate them and prefer to use tabs instead. In fact the only real time I have to use these Vim window commands is when I accidentally create a new window and need to close it.
"" split horizontal
ctrl+w s
"" split vertical
ctrl+w v
"" move around your splits
ctrl+w h,j,k,l
"" close split
ctrl+w c
One of the main reasons I choose Tmux over Vim windows is because I often want to ‘maximise’ the file I’m working on and as far as I know Vim windows aren’t really set up to do that. The only Vim command I can find to full screen a window also closes all the other windows which is something I rarely want to happen.
"" maximise window (but closes all other windows)
o
"" maximise vertical
_
"" maximise horizontal
|
"" equalize width or height of windows
=
The g
key does all sorts of useful things in Vim, here are some of the
commonly used ones. If you’re hungry for more you can see a list of all of them
use :help g
.
"" select whatever you had previously selected
gv
"" find definition of word under cursor
gd
"" open this file or folder
gf
"" move cursor up or down ignoring the text object
gj or gk
"" move cursor start or end ignoring the text object
g$ or g0
"" run last substition command on whole document
g&
Note that the g
is also used for capitalization and word wrap formatting which
have their own sections in this document.
There is a quick way of doing this using tilde and a more powerful way using g with either U (for capitalizing) or u (for lowercasing). The ‘g’ method works with the standard text objects such as word, paragraph, etc.
"" toggle caps under cursor (or on selected text)
~
"" current line toggle caps
g~~
To capitalize text in Vim use the U
key. It works with the standard text
objects:
"" current line uppercase
gUU
"" around word uppercase
gUaw
"" 4 words uppercase
gU4w
"" uppercase to '>'
gUt>
"" lowercase to end of document
gUG
Lowercasing in Vim works in the same way as capitalization except it uses a
lowercase u
:
"" current line lowercase
guu
"" around word lowercase
guaw
"" 4 words lowercase
gu4w
"" lower to '>'
gut>
"" lowercase to end of document
guG
You can set your files to be a maximum of 80 characters wide using Vim’s
textwidth
setting. This will put a carriage return in for you once you get to
the end of the line.
"" Auto wrap lines to 80 characters
set textwidth=80
"" Auto wrap lines to 80 characters (shorthand version)
set tw=80
This works fine when you’re typing but what if you paste in a long string of
text from your browser? Or what if you find some delinquent developer has used a
text width other than the one which we decided was best over 90 years
ago? Thankfully you can easily
reformat blocks of text using gq
command.
"" Reformat a long line of text to 80 characters wide
gqq
Note that typing the gq
command on its own is not enough, you need another
keystroke to tell Vim what object it should reformat. I tend to use q
because
it’s the most convenient but $
or j
would also work.
If you’re really serious about sticking to that 80 character limit then you
might like to try using the colorcolumn
setting to show a vertical bar showing
where the limit is.
"" Show vertical bar at 80 characters
set colorcolumn=80
"" Show vertical bar at 80 characters (short hand)
set cc=80
"" Remove vertical bar
set cc=0
"" Set color of the vertical bar
highlight ColorColumn ctermbg=blue
Vim has a built in spell checker which you can enable and disable with a simple
set spell
command.
"" Enable spelling
set spell
"" Disable spelling
set nospell
All the typos will now be highlighted and you can now jump back and forth
through them with [s
and ]s
.
"" Jump to next typo
[s
"" Jump to previous typo
]s
If Vim considers a word to be a typo but actually it’s correct (this usually
happens to me if I type brand names) then you can add the word under the cursor
to Vim’s dictionary with zg
or remove it with zw
.
"" Add word under cursor to the dictionary
zg
"" Remove word under cursor from dictionary
zw
Don’t know how to spell a particular word? Hit z=
and Vim will show you a
numbered list of suggestions. Find the one you want, type in the number, hit
enter and it’ll be corrected for you. If there aren’t any correct suggestions
then just hit enter.
"" Show list of suggestions
z=
To cut a section of text in Vim we use d
which is actually listed as the
‘delete’ command, but unlike the hitting the ‘delete’ key on your keyboard Vim
will store the given text in a clipboard ready to be pasted out.
"" Cut a whole line
dd
"" Cut around the current word
daw
"" Cut to end of the line
d$
Copy works pretty much the same as cut except it uses the y
key and is known
as ‘yank’ instead of copy.
"" Yank (aka copy) the whole line
yy
"" Yank (aka copy) around the current world
yaw
"" Yank (aka copy) to end of the line
y$
"" Yank (aka copy) around sentence
yas
"" Yank (aka copy) inside quote marks
yi"
Paste the contents of the clipboard with p
. You can also use P
to paste the
contents of the clipboard after the cursor.
"" Paste after cursor
p
"" Paste before cursor
P
One of the major differences between cut, copy, and paste in Vim compared to a
typical editor is that Vim has multiple clipboards so you can cut or copy
several different blocks of text and have them all available simultaneously.
There are 26 extra clipboards which can be assigned to letters a-z which you can
access using the "
key.
"" Yank (aka copy) line to clipboard a
"ayy
"" Paste from clipboard a
"ap
"" Cut word to clipboard b
"bdw
"" Paste from clipboard b
"bp
To find an occurrence of text in a file use /
for searching forwards or ?
for
searching backwards. This command is the equivalent of using the ‘Ctrl f’
feature in your browser or text editor.
"" Search forwards
/foo
"" Search backwards
?foo
Once you’ve performed your search you can cycle through each of the matches
using n
(for the next result) and N
(for the previous result).
"" Jump to next search result
n
"" Jump to previous search result
N
If you need to search for special characters you’ll have to escape them with a back slash.
"" Escape special characters with back slash
/class=\"foo
Lets you manipulate (or in the Vim world the correct word would be ‘operate’) in and around blocks of text.
Unlike the rest of the text operators here, you can use it without an inside/around option.
# can be used without inside/around
dw = delete word
yw = yank word
# used with inside/around
ciw = change inside word
yiw = yank inside word
Defined by a string of characters appended by a full stop, must be used with an inside/around option. This one only really works if the text on the previous line is also a setence. Try deleting the first sentence in this paragraph and it’ll delete the heading too as it is counted as part of the sentence.
Defined by a line break, even if the last sentence of the paragraph has no full stop.
Targets text within the given characters. Cursor must be on the same line and in front of the target.
Limited use when it comes to Ruby and React, but ideal for vanilla Javascript.
Same as above but targets contents of curly brackets.
Targets the contents of an XML tag.