2017-03-27 14:09:41 +08:00

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:

  1. Complex regular expressions. Particular the Ruby syntax file caused people to have slowdowns in the past. (Also see Debugging syntax files.)
  2. 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.