12 KiB
Miscellaneous
Additional resources
Resource | Description |
---|---|
Seven habits of effective text editing | By Bram Moolenaar, the author of Vim. |
Seven habits of effective text editing 2.0 (PDF) | See above. |
IBM DeveloperWorks: Scripting the Vim editor | Five-part series on Vim scripting. |
Learn Vimscript the Hard Way | Develop a Vim plugin from scratch. |
Practical Vim (2nd Edition) | Hands down the best book about Vim. |
Vimcasts.org | Vim screencasts. |
Why, oh WHY, do those #?@! nutheads use vi? | Common misconceptions explained. |
Your problem with Vim is that you don't grok vi | Concise, informative and correct. A real gem. |
Vim distributions
Vim distributions are bundles of custom settings and plugins for Vim.
More advanced users know how to configure their editor anyway, so distributions are mostly targeted at beginners. If you think about that, it's quite paradoxical though: Making it easier by adding even more things to learn about?
I know that many people don't want to spend hours and hours on customizing an editor (and actually you never stop customizing your vimrc when you finally got hooked), but eventually you only get efficient in Vim when you take the time to learn it properly.
Repeat after me: "A programmer should know their tools."
Anyway, if you know what you're doing, you might draw some inspiration from looking at a few distributions:
Standard plugins
Surprising to many people, Vim comes with a handful of plugins on its own that
all get loaded by default. Check :scriptnames
after starting Vim to see all
sourced files.
Most of them will never get used, so disable them as you see fit. They will still be shown as sourced, but only the first lines actually get read before Vim bails out. No further code (mappings, commands, logic) will be processed.
Plugin | Disable it using.. | Help |
---|---|---|
2html | let g:loaded_2html_plugin = 1 |
:h 2html |
getscript | let g:loaded_getscriptPlugin = 1 |
:h pi_getscript |
gzip | let g:loaded_gzip = 1 |
:h pi_gzip |
logipat | let g:loaded_logipat = 1 |
:h pi_logipat |
matchparen | let g:loaded_matchparen = 1 |
:h pi_paren |
netrw | let g:loaded_netrwPlugin = 1 |
:h pi_netrw |
rrhelper | let g:loaded_rrhelper = 1 |
:e $VIMRUNTIME/plugin/rrhelper.vim |
spellfile | let g:loaded_spellfile_plugin = 1 |
:h spellfile.vim |
tar | let g:loaded_tarPlugin = 1 |
:h pi_tar |
vimball | let g:loaded_vimballPlugin = 1 |
:h pi_vimball |
zip | let g:loaded_zipPlugin = 1 |
:h pi_zip |
Map CapsLock to Control
CapsLock belongs to the most useless keys on your keyboard, but it's much easier to reach than the Control key, since it lies on your home row. Mapping CapsLock to Control is a great way to prevent or at least reduce RSI if you program a lot.
Attention: When you get used to it, you can't live without it anymore.
OSX:
System Preferences -> Keyboard -> Keyboard Tab -> Modifier Keys
. Change
"CapsLock" to "Control".
Linux:
To change the keys in X, put this in your ~/.xmodmap
:
remove Lock = Caps_Lock
keysym Caps_Lock = Control_L
add Control = Control_L
Afterwards source it via $ xmodmap ~/.xmodmap
.
An alternative would be using caps2esc or xcape.
Windows:
See superuser.com: Map Caps-Lock to Control in Windows 8.1.
Easter eggs
Command | Message |
---|---|
:Ni! |
Do you demand a shrubbery? |
:h 'sm' |
NOTE: Use of the short form is rated PG. |
:h 42 |
What is the meaning of life, the universe and everything? Douglas Adams, the only person who knew what this question really was about is now dead, unfortunately. So now you might wonder what the meaning of death is... |
:h UserGettingBored |
When the user presses the same key 42 times. Just kidding! :-) |
:h bar |
Ceci n'est pas une pipe. |
:h holy-grail |
You found it, Arthur! |
:h map-modes |
:nunmap can also be used outside of a monastery. |
:help! |
E478: Don't panic! (Glitch? When used in a help buffer (buftype=help ) this works like :h help.txt instead.) |
:smile |
Try it out yourself. ;-) Added in 7.4.1005. |
Why hjkl for navigation?
When Bill Joy created vi, a predecessor of Vim, he did it on a ADM-3A which had no extra cursor buttons but used, you might already guessed it, hjkl instead.
Keyboard layout: click
This also shows why ~
is used to denote the home directory on Unix systems.
Common problems
Editing small files is slow
There are two things which can have a huge impact on performance:
- Complex regular expressions. Particular the Ruby syntax file caused people to have slowdowns in the past. (Also see Debugging syntax files.)
- Screen redraws. Some features force all lines to redraw.
Typical culprit | Why? | Solution? |
---|---|---|
:set cursorline |
Causes all lines to redraw. | :set nocursorline |
:set cursorcolumn |
Causes all lines to redraw. | :set nocursorcolumn |
:set relativenumber |
Causes all lines to redraw. | :set norelativenumber |
:set foldmethod=syntax |
If the syntax file is slow already, this makes it even worse. | :set foldmethod=manual , :set foldmethod=marker or FastFold |
:set synmaxcol=3000 |
Due to internal representation, Vim has problems with long lines in general. Highlights columns till column 3000. | :set synmaxcol=200 |
matchparen.vim | Loaded by default. Uses regular expressions to find the accompanying parenthesis. | Disable plugin: :h matchparen |
NOTE: You only need to do this if you experience actual performance drawbacks. In most cases using the things mentioned above is absolutely fine.
Editing huge files is slow
The biggest issue with big files is, that Vim reads the whole file at once. This is done due to how buffers are represented internally. (Discussion on vim_dev@)
If you only want to read, tail hugefile | vim -
is a good workaround.
If you can live without syntax, settings and plugins for the moment:
$ vim -u NONE -N
This should make navigation quite a lot faster, especially since no expensive regular expressions for syntax highlighting are used. You should also tell Vim not to use swapfiles and viminfo files to avoid long delays on writing:
$ vim -n -u NONE -i NONE -N
Putting it in a nutshell, try to avoid using Vim when intending to write really huge files. :\
Bracketed paste (or why do I have to set 'paste' all the time?)
Bracketed paste mode allows terminal emulators to distinguish between typed text and pasted text.
Did you ever tried pasting code into Vim and afterwards everything seemed messed up?
This only happens if you paste via cmd+v
, shift-insert
, middle-click
etc.
because then you're just throwing text at the terminal emulator. Vim doesn't
know that you just pasted the text, it thinks you're an extremely fast typist.
Accordingly, it tries to indent the lines and fails.
Obviously this is not an issue, if you paste using Vim's registers, e.g. "+p
,
because then Vim knows that you're actually pasting.
To workaround this, you have to :set paste
, so it gets pasted as-is. See :h 'paste'
and :h 'pastetoggle'
.
If you're fed up with toggling 'paste'
all the time, have a look at this fine
plugin that does it for you:
bracketed-paste.
Additional read from the same author as the plugin: here.
Neovim: Neovim tries to make all of this much more seamless and sets bracketed paste mode automatically if the terminal emulator supports it.
Delays when using escape key in terminal
If you live in the command-line, you probably use a so-called terminal emulator like xterm, gnome-terminal, iTerm2, etc. (opposed to a real terminal).
Like their ancestors, terminal emulators use escape
sequences (or control
sequences) to control things like moving the cursor, changing text colors, etc.
They're simply strings of ASCII characters starting with an escape character
(displayed in caret notation as
^[
). When such a string arrives, the terminal emulator looks up the
accompanying action in the terminfo
database.
To make the problem clearer, I'll explain mapping timeouts first. They always happen when there's ambiguity between mappings:
:nnoremap ,a :echo 'foo'<cr>
:nnoremap ,ab :echo 'bar'<cr>
Both mappings work as expected, but when typing ,a
, there will be a delay of 1
second, because Vim waits whether the user keys in another b
or not.
Escape sequences pose the same problem:
<esc>
is used a lot for returning to normal mode or quitting an action.- Cursor keys are encoded using escape sequences.
- Vim expects Alt (also called Meta key) to send a proper 8-bit encoding with the high bit set, but many terminal emulators don't support it (or don't enable it by default) and send an escape sequence instead.
You can test the above like this: vim -u NONE -N
and type i<c-v><left>
and
you'll see a sequence inserted that starts with ^[
which denotes the escape
character.
Putting it in a nutshell, Vim has a hard time distinguishing between a typed
<esc>
character and a proper escape sequence.
By default, Vim uses :set timeout timeoutlen=1000
, so it delays on ambiguity
of mappings and key codes by 1 second. This is a sane value for mappings, but
you can define the key code timeout on its own which is the most common
workaround for this entire issue:
set timeout " for mappings
set timeoutlen=1000 " default value
set ttimeout " for key codes
set ttimeoutlen=10 " unnoticeable small value
Under :h ttimeout
you find a small table showing the relationship between
these options.
If you're using tmux between Vim and your terminal emulator, also put this in
your ~/.tmux.conf
:
set -sg escape-time 0
Function search undo
- A search pattern in a command (
/
,:substitute
, ...) changes the "last used search pattern". (It's saved in the/
register; print it with:echo @/
). - A simple text change can be redone with
.
. (It's saved in the.
register; print it with:echo @.
).
Both things are not the case, if you do them from a function, though! Thus you can't easily highlight words from a function or redo the text changes made by it.
Help: :h function-search-undo
Technical quirks
Newline used for NUL
NUL characters (\0
) in a file, are stored as newline (\n
) in memory and
displayed in a buffer as ^@
.
See man 7 ascii
and :h NL-used-for-Nul
for more information.