Vi: Difference between revisions
(493 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
This page is about the editor '''Vim''' itself. The other related pages are<br/> |
|||
== Links == |
|||
* '''[[Vimrc]]''', dedicated to ''vim configuration settings'' and to the file {{file|~/.vimrc}}. |
|||
* '''[[Vim plugins]]''', dedicated to Vim ''plugins''. |
|||
* '''[[Neovim]]''', dedicated to ''NeoVim'', a new port of Vim. |
|||
== References == |
|||
* General |
|||
** My links on vi on [http://delicious.com/m1p/vi del.icio.us]. |
|||
** Official '''vim''' [http://www.vim.org/ homepage]. |
|||
* Fun |
|||
** Vi would not be vi without a bit of [http://www.dina.kvl.dk/~abraham/religion/index.html fun]... |
|||
* Guides & Cheat sheets |
|||
** Very good post explaining why vi is superior and defeating common misconception (with examples) [http://www.viemu.com/a-why-vi-vim.html]. |
|||
** Very good graphical [http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html cheatsheet] |
|||
*** Direct links: [http://www.viemu.com/vi-vim-cheat-sheet.gif overview] and [http://www.viemu.com/vi-vim-tutorial-svg.zip per-lesson]. |
|||
== |
=== Things to look at === |
||
* Use {{kb|Ctrl-C}} or {{kb|Alt-L}} as ESC replacement. |
|||
* NeoVim fast setup: |
|||
:* [https://www.lazyvim.org/ LazyVim] A Neovim setup powered by lazy.nvim. |
|||
:* [https://github.com/NvChad/NvChad NvChad] |
|||
:* [https://github.com/AstroNvim/AstroNvim AstroNvim] |
|||
:* [https://www.lunarvim.org/ LunarVim] Another IDE-like setup for Neovim. |
|||
* [https://github.com/kovidgoyal/kitty kitty] Cross-platform, fast, feature-rich, GPU based terminal, with support for hyperlinks, image viewer. |
|||
<font color="red">''! If keys HJKLM have been remapped to MHJKL, shortcut below must be changed accordingly'' !</font> |
|||
* [https://github.com/tree-sitter/tree-sitter tree-sitter] An incremental parsing system for programming tools |
|||
:* Goes along with [https://github.com/nvim-treesitter/nvim-treesitter nvim-treesitter] |
|||
* [https://github.com/dense-analysis/ale ale] — Check syntax in Vim asynchornously and fix files, with Language Server Protocol (LSP) support. |
|||
* [https://github.com/jose-elias-alvarez/null-ls.nvim null-ls] Use Neovim as a language server |
|||
* [https://github.com/neovim/nvim-lspconfig nvim-lspconfig] Quickstarts configs for Nvim LSP, suggested by Neovim project. |
|||
* [https://github.com/neoclide/coc.nvim coc.nvim] — Conquer of Completion (maybe older tech, but still maintained). |
|||
* [https://github.com/nvim-lua/kickstart.nvim kickstart.nvim] — A launch point for personal nvim configuration. |
|||
* [https://github.com/williamboman/mason.nvim Mason A portable package manager (LSP, DAP...)] |
|||
* Comments on [https://news.ycombinator.com/item?id=36753225 HN] |
|||
=== External links === |
|||
; General |
|||
* '''Official vim [http://www.vim.org/ homepage]''' |
|||
* '''[http://vim.wikia.com/wiki/Vim_Tips_Wiki Vim Tips Wiki]''' |
|||
* [http://vimdoc.sourceforge.net/htmldoc/map.html Vim documentation: map] |
|||
* My links on '''vim''' on [http://delicious.com/m1p/vi del.icio.us] |
|||
* List of all commands for each mode: <code>:help index</code> |
|||
; Vi clones or inspired |
|||
* '''[https://neovim.io/ Neovim]''' |
|||
* [[Kakoune]], a vim-like but using ''noun-verb'' syntax. |
|||
; General - Vim Help |
|||
* '''[http://vimdoc.sourceforge.net/htmldoc/help.html Vim documentation: help]''' |
|||
* Built-in help: |
|||
<source lang=vim> |
|||
" Get help on a command |
|||
:h map |
|||
" Get help on a mapping, NORMAL or INSERT mode |
|||
:h CTRL-R |
|||
:h i_CTRL-R |
|||
</source> |
|||
; Other General |
|||
* [http://thomer.com//vi/vi.html Vi Lovers home page] |
|||
* [http://www.viemu.com/a-why-vi-vim.html Why, oh WHY, do those #?@! nutheads use vi?] — explains why vi is superior and defeats common misconceptions (with examples). |
|||
* Vi would not be vi without a bit of [http://www.dina.kvl.dk/~abraham/religion/index.html fun]... |
|||
* [https://groups.google.com/forum/?fromgroups#!forum/vimsf vimsf discussion forum] |
|||
; Cheat sheets |
|||
* [http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html Very good graphical keyboard cheatsheet ] |
|||
** [[Media:Visio-Vim graphic cheatsheet-AZERTY-MIP.pdf|My custom cheatsheet (AZERTY)]] |
|||
* [http://tnerual.eriogerg.free.fr/vim.html Another compact & complete cheatsheet (as folded reference card)]. |
|||
* [http://mysite.verizon.net/astronaut/vim/vimcmd.txt.gz Real Short Vim Normal-Mode List of Commands (from Dr Chip's)] |
|||
; Productivity & Setup Guides |
|||
Get the best Vim configuration |
|||
* '''{{red|NEW}}''' — [http://www.bestofvim.com/plugin/ best of Vim] |
|||
* '''{{red|NEW}}''' — [http://www.colbycheeze.com/blog/2015/02/level-up-your-workflow-with-vim-and-tmux.html Level up your workflow with Vim and Tmux] |
|||
* '''{{red|NEW}}''' — [https://castel.dev/post/lecture-notes-1/ How I'm able to take notes in mathematics lectures using LaTeX and Vim — Gilles Castel] |
|||
:Similar post on [https://www.quora.com/Can-people-actually-keep-up-with-note-taking-in-Mathematics-lectures-with-LaTeX/answer/Gilles-Castel-1 Quora], video on [https://www.youtube.com/watch?time_continue=70&v=a7gpx0h-BuU YouTube], [https://castel.dev/tex-e0c2e8b64036f77db00411d562750c12.snippets snippets]. |
|||
Tuned for Neovim |
|||
* '''{{red|NEW}}''' — [http://nerditya.com/code/guide-to-neovim/ A guide to neovim] |
|||
; Guides & Cheat sheets |
|||
* [http://vim.wikia.com/wiki/New_to_Vim New To Vim] |
|||
* [http://vim.wikia.com/wiki/Quick_tips Quick Tips] |
|||
* [http://vim.wikia.com/wiki/Avoid_the_escape_key Avoiding the ESC key] |
|||
* [http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_1) Vim map tutorial] |
|||
* [http://www.drchip.org/astronaut/vim/ Dr Chip's Vim Page] — A tremendous amount of Vim treasures from an expert user |
|||
* [http://jmcpherson.org/editing.html Efficient editing with vim] (link dead, [http://web.archive.org/web/20080509163159/http://jmcpherson.org/editing.html wayback machine], [http://robertames.com/files/vim-editing.html mirror]) |
|||
* [http://tldp.org/HOWTO/C-editing-with-VIM-HOWTO/index.html C editing with VIM HOWTO] |
|||
* [http://vim.wikia.com/wiki/Using_vim_as_an_IDE_all_in_one Using vim as an IDE all in one] |
|||
* [http://vim.wikia.com/wiki/Browsing_programs_with_tags Browsing programs with tags] |
|||
* [http://vim.wikia.com/wiki/Using_bash_completion_with_ctags_and_Vim Using Bash completion with ctags and Vim] |
|||
* [http://vim.wikia.com/wiki/Alternative_tab_navigation Alternative tab navigation] |
|||
* [http://www.moolenaar.net/habits.html Seven habits of effective text editing] (from author of Vim) |
|||
* [http://www.ibm.com/developerworks/linux/library/l-vim-script-1/index.html Scripting the Vim editor, Part 1: Variables, values, and expressions] (a great introduction to Vim scripting) |
|||
* '''{{red|NEW}}''' — [https://www.youtube.com/watch?v=YD9aFIvlQYs Turn Vim & Tmux into an IDE like environment] |
|||
:* Uses {{kbkey|^h}} {{kbkey|^j}} {{kbkey|^k}} {{kbkey|^l}} to navigate between pane (also in Tmux apparently) |
|||
:* Tips: Use CapsLock as ESC, Copy Paste, Tab movements, '''Relative numbering''' |
|||
:* Plugins: NERDTree, Ctrl-P, Surround.vim, Comments, '''Snippets''', '''Vim Wiki''' |
|||
:* [https://github.com/colbycheeze/dotfiles ColbyCheeze dot files] |
|||
* '''{{red|NEW}}''' — [http://vim.wikia.com/wiki/Vim_as_XML_Editor Vim as XML Editor] |
|||
; Vim in Windows/Cygwin |
|||
* [http://vim.wikia.com/wiki/Use_cygwin_shell Use cygwin shell] |
|||
* [http://vim.wikia.com/wiki/Running_the_win32-version_of_Vim_from_cygwin Running the Win32 version of Vim from Cygwin] |
|||
* '''[http://www.viemu.com/ viEmu]''' — vim for Word, Outlook, Visual Studio... |
|||
* [http://hermitte.free.fr/cygwin/ cyg-wrapper.sh] |
|||
* [http://vimdoc.sourceforge.net/htmldoc/vimfaq.html#33.6 FAQ / 33.6 What are the recommended settings for using Vim with cygwin?] |
|||
* [http://theletterpsi.blogspot.com/2010/08/using-cygwin-bash-as-your-win32-vim.html Using Cygwin Bash as your Win32-Vim shell] |
|||
* A patch to use Win32 clipboard under Cygwin ([http://groups.google.com/group/vim_dev/browse_thread/thread/5293258c705aefbc], [http://vim.1045645.n5.nabble.com/Subject-Re-vim-on-cygwin-using-win32-clipboard-td1201641.html]) |
|||
; Tips |
|||
* [http://vim.wikia.com/wiki/VimTip459 Use Ctrl-O instead of Esc in insert mode mappings] |
|||
* [http://stackoverflow.com/questions/235839/how-do-i-indent-multiple-lines-quickly-in-vi How do I indent multiple lines quickly in vi?] |
|||
* [http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text Replace a word with yanked text]<br/>''Here we learn that Deleting, Changing and Yanking text copies the affected text to unnamed buffer (<tt>""</tt>).<br/>But Yanking text also copies the text to buffer 0 (<tt>"0</tt>)'' |
|||
* [http://vim.wikia.com/wiki/Search_and_replace_the_word_under_the_cursor Search and replace the word under the cursor] |
|||
* [http://vim.wikia.com/wiki/Find_in_files_within_Vim Find in files within Vim]<br/>About commands <code>:grep</code>, <code>:lgrep</code>, <code>:vimgrep</code>, <code>:lvimgrep</code> |
|||
* [http://vim.wikia.com/wiki/Power_of_g Power of g]<br/>Examples on how to use the command <code>:''{{green|r}}''g/''{{green|pattern}}''/''{{green|cmd}}''</code> |
|||
* [http://vim.wikia.com/wiki/Keystroke_Saving_Substituting_and_Searching Keystroke Saving Substituting and Searching] |
|||
* [http://vim.wikia.com/wiki/Quickly_adding_and_deleting_empty_lines Quickly adding and deleting empty lines] |
|||
* [http://vim.wikia.com/wiki/Very_basic_session_persistence Very basic session persistence]<br/>Using <tt>mksession!</tt> and <tt>:au VimLeave</tt>... |
|||
* [http://vim.wikia.com/wiki/Automatically_fitting_a_quickfix_window_height Automatically fitting a quickfix window height] |
|||
* [http://vim.wikia.com/wiki/Highlight_unwanted_spaces Highlight unwanted spaces] |
|||
* [http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers Using Vim's tabs like buffers] |
|||
:<code>:set hidden</code> to have vim behave like any other multi-file editors. |
|||
:Use <code>:bn</code>, <code>:bp</code>, <code>:b #</code>, <code>:b name</code>, {{kb|^6}} and {{kb|#^6}} to switch between buffers. '''{{kb|^6}} are very useful to switch to previously used buffer''' (or {{kb|#^6}} to switch to buffer <code>#</code>). |
|||
:Use <code>:ls</code> to list buffers. |
|||
; Vimrc examples |
|||
* https://github.com/mitechie/pyvim (author of the [http://lococast.net/archives/185 screencast] on [http://www.vim.org/scripts/script.php?script_id=2050 LustyJuggler]) |
|||
* https://github.com/colbycheeze/dotfiles |
|||
: Use vim-plug to manage plugins. |
|||
=== Vim help === |
|||
;Help on mappings |
|||
* For mapping like {{kb|<C-U>}} (ie. {{kb|<Ctrl-U>}}): <code>:h CTRL-U</code> |
|||
* For mapping like {{kb|<C-G>u}}: <code>:h CTRL-G_u</code> (not the same as <code>:h CTRL-G_U</code>). |
|||
* For mapping like {{kb|<C-G>u}} in ''insert mode'': <code>:h i_CTRL-G_u</code> |
|||
== Related projects == |
|||
=== [https://ctags.io/ Universal ctags] === |
|||
A maintained version of ''exuberant ctags''. |
|||
First uninstall ''exuberant-ctags'' if installed: |
|||
<source lang=bash> |
|||
sudo apt-get remove exuberant-ctags |
|||
</source> |
|||
To build (see {{file|docs/autotools.rst}}): |
|||
<source lang=bash> |
|||
git clone https://github.com/universal-ctags/ctags.git |
|||
cd ctags |
|||
./autogen.sh |
|||
./configure |
|||
make |
|||
sudo make install |
|||
</source> |
|||
== Install == |
|||
=== Building from Sources === |
|||
See |
|||
* [[Cygwin#Vim|Build Vim on Cygwin]] |
|||
* [http://aufather.wordpress.com/2010/08/15/building-gvim/ Building Gvim from source] (linux) |
|||
== Invocation == |
|||
<source lang="bash"> |
|||
vi -p file1.txt file2.txt # Open each file in a different tab |
|||
vi -t tagname # Open file and move cursor at specified tag (requires ctags) |
|||
view file.txt # View file in vim, with syntax highlighting... (read-only) |
|||
vimdiff file1.txt file2.txt # View differences in vim |
|||
</source> |
|||
The following is a description of the start up sequence as I understood by experience. It's certainly far from complete. For more information: |
|||
<source lang=vim> |
|||
:version |
|||
:echo $HOME |
|||
:echo $VIM |
|||
:set runtimepath? |
|||
:help vimrc |
|||
:help gvimrc |
|||
:help runtimepath |
|||
</source> |
|||
<ol> |
|||
<li> First, load the system config files:</li> |
|||
{| class="wikitable" |
{| class="wikitable" |
||
!File!!description!!OS!!Location |
|||
!Shortcut |
|||
!Description |
|||
!Custom |
|||
|- |
|- |
||
|vimrc||System config file for ''vim'' and ''gvim''||Unix & Win||<tt>$VIM/vimrc</tt> |
|||
|'''Ctrl+<tt>[</tt>''' |
|||
|- |
|||
|Same effect as '''Esc''', but a bit faster/easier to type. Also works on ''AZERTY'' keyboard (but apparently not for AndLinux, snif!) |
|||
|gvimrc||System config file for ''gvim'' only||Unix & Win||<tt>$VIM/gvimrc</tt> |
|||
|} |
|||
<li> Second, load the user config files:</li> |
|||
{| class="wikitable" |
|||
!File!!description!!OS!!Location |
|||
|- |
|||
|rowspan=2|vimrc||rowspan=2|User config file for ''vim'' and ''gvim''||Unix||<tt>$HOME/.vimrc</tt> |
|||
|- |
|||
|Win||<tt>$HOME/_vimrc</tt> |
|||
|- |
|||
|rowspan=2|gvimrc||rowspan=2|User config file for ''gvim'' only||Unix||<tt>$HOME/.vimrc</tt> |
|||
|- |
|||
|Win||<tt>$HOME/_vimrc</tt> |
|||
|} |
|||
<li>Search for runtime files in path {{green|'runtimepath'}}. Basically vim looks for directories in that path for further runtime files to execute (see <code>:help runtimepath</code> for more information) |
|||
</ol> |
|||
=== Using vimdiff === |
|||
Invoke <tt>vimdiff</tt> with |
|||
<source lang=bash> |
|||
vimdiff file1.txt file2.txt |
|||
</source> |
|||
One can tell vim to ignore case or whitespaces with: |
|||
<source lang=vim> |
|||
" Ignore case differences |
|||
:set diffopt+=icase |
|||
" Ignore white space differences |
|||
:set diffopt+=iwhite |
|||
" Tell vim to redo comparison (in case file was edited) |
|||
:diffupdate |
|||
</source> |
|||
== Plugins == |
|||
See [[Vim plugins]]. |
|||
== Vim on Windows == |
|||
* '''Tab Edit with &Vim''' — The following registry setting add a context menu item in explorer to open a file in a new tab in a running instance of ''gvim'' (see [http://vim.wikia.com/wiki/Add_open-in-tabs_context_menu_for_Windows]): |
|||
<source lang=reg> |
|||
REGEDIT4 |
|||
[HKEY_CLASSES_ROOT\*\Shell\Tab Edit with &Vim\command] |
|||
@="\"C:\\Program Files\\vim\\vim71\\gvim.exe\" -p --remote-tab-silent \"%1\" \"%*\"" |
|||
</source> |
|||
:Best solution however is to use the '''gvim explorer menu extension''', which offers much more functionality (see [[Configuration NXP Dell Latitude E5430|NXL67170]]). |
|||
* '''Share config with Cygwin''' |
|||
: To have win32 ''gvim'' and cygwin ''vim'', use the same config files. Simply define the env. var '''HOME''' to point to user home in cygwin: |
|||
<source lang=text> |
|||
HOME=c:\cygwin\home\username |
|||
</source> |
|||
:Create the file <tt>C:\Program Files\Vim\vimrc</tt> (system vimrc file for windows) |
|||
<source lang=vim> |
|||
set runtimepath-=~/vimfiles |
|||
let tmp=&runtimepath |
|||
let &runtimepath="~/.vim,".tmp |
|||
</source> |
|||
Win32 ''gvim'' will read the standard configuration files <tt>.vimrc</tt> and <tt>.gvimrc</tt> (although this is not reported by <code>:version</code>). It will also fetch the plugins from cygwin home directory. |
|||
* '''Detect windows in vimrc script''' |
|||
: Use <code>has('win32')</code> or alike: |
|||
<source lang="vim"> |
|||
if has('win32') |
|||
echo "Windows (32 or 64 bits)" |
|||
endif |
|||
if has('win32unix') |
|||
echo "Cygwin" |
|||
endif |
|||
if has('unix') |
|||
echo "linux" |
|||
endif |
|||
if has('macunix') |
|||
echo "Mac" |
|||
endif |
|||
</source> |
|||
* '''Enable Ruby support''' |
|||
: There is a bug in Vim7.3_46 that crashes vim when ruby is loaded. This is fixed in a later release [1]. Install: |
|||
* Latest Vim from [http://cream.sourceforge.net/home.html Cream] (currently Vim 7.3.260) |
|||
* This version of Vim requires '''Ruby 1.8.x''' (and not Ruby 1.9.1 as indicated in <tt>:help ruby</tt>).<br/>Download <tt>ruby-1.8.7-p330-i386-mswin32.zip</tt> from [http://www.garbagecollect.jp/ruby/mswin32/en/download/release.html here], and install it in <tt>C:\RUBY</tt>.<br/>Add <tt>C:\RUBY\bin</tt> to system path (before cygwin!) |
|||
* '''Save .vimrc in utf-8 format *with* BOM''' |
|||
: Vim Windows will default to Iso8859 encoding on windows. By adding the BOM to .vimrc file, it'll ensure that both Vim Linux and Vim Windows will use the same encoding to read the configuration file (relevant in case you have special character in .vimrc) |
|||
* '''Use Caps Lock as Escape key''' |
|||
:Import the following in the registry then logout/logon: |
|||
<source lang=reg> |
|||
REGEDIT4 |
|||
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] |
|||
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,46,00,01,00,3a,00,00,00,00,00 |
|||
</source> |
|||
:To restore old behavior: |
|||
<source lang=reg> |
|||
REGEDIT4 |
|||
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] |
|||
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,46,00,01,00,3a,00,00,00,00,00 |
|||
</source> |
|||
Check also potential goodies [[Vi#Vim_in_Windows.2FCygwin above]]. |
|||
== Configuration == |
|||
=== Color schemes === |
|||
* '''[http://ethanschoonover.com/solarized Solarized]''' (truecolor) — [https://github.com/altercation/vim-colors-solarized Git plugin], [https://github.com/xeyownt/vim-colors-solarized my fork]. |
|||
:My current favorite scheme, cheerful colors. But I would like to increase the contrast for the main text. |
|||
* '''[https://github.com/morhetz/gruvbox Gruvbox]''' (truecolor) |
|||
:A truecolor color scheme. |
|||
=== Tabs and indent === |
|||
<source lang=vim> |
|||
"#### Indentation ######################################## |
|||
set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab |
|||
set autoindent " Indent is based on the previous line |
|||
" set smartindent " Same as above but also recognize some C syntax |
|||
" set cindent " Even clever C indent mode |
|||
" set cinkeys=0{,0},:,0#,!,!^F " For cindent - specifies which keys trigger reindenting |
|||
</source> |
|||
Or shorter: |
|||
<source lang=vim> |
|||
set ts=4 sts=4 sw=4 noet |
|||
</source> |
|||
=== Cursor shape and mode === |
|||
By default, the cursor shape depends on the UI: |
|||
* In TUI, cursor is always has a block shape. |
|||
* In GUI (<code>gvim</code>), cursor is either a blinking block (normal mode), or a blinking caret (insert mode). |
|||
In TUI, we can configure the cursor for terminals that support it: |
|||
* Under tmux, using escape sequences [http://blog.terriblelabs.com/blog/2013/02/09/stupid-vim-tricks-how-to-change-insert-mode-cursor-shape-with-tmux/]. Add to {{file|.vimrc}}: |
|||
<source lang=bash> |
|||
" set the cursor to a vertical line in insert mode and a solid block |
|||
" in command mode |
|||
let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\" |
|||
let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\" |
|||
" upon hitting escape to change modes, send successive move-left and move-right |
|||
" commands to immediately redraw the cursor |
|||
inoremap <special> <Esc> <Esc>hl |
|||
" don't blink the cursor |
|||
set guicursor+=i:blinkwait0 |
|||
</source> |
|||
:Finally, in {{file|tmux.conf}}: |
|||
<source lang=bash> |
|||
# don't wait for an escape sequence after hitting |
|||
# Esc. fixes insert mode exit lag in vim |
|||
set -sg escape-time 0 |
|||
</source> |
|||
== Managing Options == |
|||
See <code>:help options</code> for more details |
|||
<source lang="vim"> |
|||
"Show all options that differ from default |
|||
:set |
|||
"Show value of {option} |
|||
:set {option}? |
|||
"Set {option} to value |
|||
:set {option}={value} |
|||
"Add value to {option} |
|||
:set {option}+={value} |
|||
</source> |
|||
== Scripting == |
|||
=== Variables, environment variables and options === |
|||
Some basic stuff on Vim scripts: |
|||
<source lang=vim> |
|||
" Use LET for VARIABLES |
|||
let myvar="Hello" |
|||
echo myvar |
|||
let myvar=call func(param1,param2) |
|||
" Use SET for OPTIONS |
|||
set runtimepath=~/.vim " SET option" |
|||
set runtimepath? " GET option" |
|||
" We can use LET with &{OPTIONS} |
|||
let myvar='batch' |
|||
let &filetype=myvar " &{option} returns option value in an expression" |
|||
echo &filetype |
|||
if &filetype == 'java' |
|||
... |
|||
endif |
|||
" But these does not give the same: |
|||
set runtimepath? " No expansion within runtimepath (eg. replace ~ with /home/...)" |
|||
echo &runtimepath " Expansion occurs with runtimepath" |
|||
" Another example, use variable to prepend a path to runtimepath: |
|||
set runtimepath-=~/vimfiles |
|||
let tmp=&runtimepath |
|||
let &runtimepath="~/.vim,".tmp |
|||
</source> |
|||
Use <code>let</code> to edit '''environment variables''': |
|||
<source lang="vim"> |
|||
let $MAKEFLAGS="-j1" " Set env. var MAKEFLAGS - force sequential build |
|||
</source> |
|||
=== Expressions === |
|||
See <code>:h expression-syntax</code> for more. |
|||
<source lang=text> |
|||
|expr1| expr2 ? expr1 : expr1 if-then-else |
|||
|expr2| expr3 || expr3 .. logical OR |
|||
|expr3| expr4 && expr4 .. logical AND |
|||
|expr4| expr5 == expr5 equal |
|||
expr5 != expr5 not equal |
|||
expr5 > expr5 greater than |
|||
expr5 >= expr5 greater than or equal |
|||
expr5 < expr5 smaller than |
|||
expr5 <= expr5 smaller than or equal |
|||
expr5 =~ expr5 regexp matches |
|||
expr5 !~ expr5 regexp doesn't match |
|||
expr5 ==? expr5 equal, ignoring case |
|||
expr5 ==# expr5 equal, match case |
|||
etc. As above, append ? for ignoring case, # for |
|||
matching case |
|||
expr5 is expr5 same |List| instance |
|||
expr5 isnot expr5 different |List| instance |
|||
|expr5| expr6 + expr6 .. number addition or list concatenation |
|||
expr6 - expr6 .. number subtraction |
|||
expr6 . expr6 .. string concatenation |
|||
|expr6| expr7 * expr7 .. number multiplication |
|||
expr7 / expr7 .. number division |
|||
expr7 % expr7 .. number modulo |
|||
|expr7| ! expr7 logical NOT |
|||
- expr7 unary minus |
|||
+ expr7 unary plus |
|||
|expr8| expr8[expr1] byte of a String or item of a |List| |
|||
expr8[expr1 : expr1] substring of a String or sublist of a |List| |
|||
expr8.name entry in a |Dictionary| |
|||
expr8(expr1, ...) function call with |Funcref| variable |
|||
|expr9| number number constant |
|||
"string" string constant, backslash is special |
|||
'string' string constant, ' is doubled |
|||
[expr1, ...] |List| |
|||
{expr1: expr1, ...} |Dictionary| |
|||
&option option value |
|||
(expr1) nested expression |
|||
variable internal variable |
|||
va{ria}ble internal variable with curly braces |
|||
$VAR environment variable |
|||
@r contents of register 'r' |
|||
function(expr1, ...) function call |
|||
func{ti}on(expr1, ...) function call with curly braces |
|||
</source> |
|||
=== Process control === |
|||
<source lang=vim> |
|||
if filereadable("foo.cfg") " Boolean" |
|||
" ... |
|||
endif |
|||
while lnum <= line("$") " Number - other tests are =, !=, <=, >=" |
|||
call FixLine(lnum) |
|||
let lnum = lnum + 1 |
|||
endwhile |
|||
if $ENV_VAR != "" " String" |
|||
echo $ENV_VAR |
|||
endif |
|||
" FOR with LISTS |
|||
for item in ["foo", "bar"] |
|||
echo item |
|||
unlet item " E706 without this" |
|||
endfor |
|||
for item in ["foo", ["bar"]] |
|||
echo item |
|||
unlet item " E706 without this because different item types |
|||
endfor |
|||
for [lnum, col] in [[1, 3], [2, 5], [3, 8]] |
|||
echo getline(lnum)[col] |
|||
endfor |
|||
</source> |
|||
=== Handy functions === |
|||
(see <code>:h functions</code> for complete list) |
|||
<source lang=vim> |
|||
glob("/foo/bar") " String, extension file wildcard (here as file existence test)" |
|||
filereadable("foo.cfg") " Number, TRUE if file readable" |
|||
</source> |
|||
=== Testing version, options and features === |
|||
Some examples for testing Vim version, and option/feature availability [http://stackoverflow.com/questions/11774904/vim-scripting-if-vim-version-is-7-3]: |
|||
<source lang="vim"> |
|||
if v:version < 703 " Exit if Vim version 7.3 or less |
|||
finish |
|||
endif |
|||
" Plugin goes here. |
|||
</source> |
|||
<source lang="vim"> |
|||
" Avoid installing twice or when in unsupported Vim version. |
|||
if exists('g:loaded_pluginname') || (v:version < 700) |
|||
finish |
|||
endif |
|||
let g:loaded_pluginname = 1 |
|||
</source> |
|||
To test whether an option/feature is available |
|||
<source lang="vim"> |
|||
exists('+relativenumber') " Is option relativenumber available? |
|||
has('python') " Is feature python supported? |
|||
</source> |
|||
=== How-to === |
|||
;Test for quickfix buffer |
|||
<source lang=vim> |
|||
&filetype == 'qf' " Test filetype |
|||
&buftype ==# 'quickfix' " Test buftype |
|||
</source> |
|||
=== Frequent caveats === |
|||
* Don't confuse ''variables'' and ''options''. |
|||
: Variables are initialized with '''let''', options with '''set'''. Options can be read/written like a variable with prefix '''&''', like '''&filetype'''. |
|||
* Don't confuse ''functions'' (like <code>max</code>, <code>strlen</code>), with editor ''commands'' (like let, set, call). |
|||
: Functions can be called directly in expression, but must be called with command '''call''' where commands are expected. |
|||
<source lang="vim"> |
|||
add(list,10) " WRONG! add is not an editor command |
|||
list2=add(list,10) " CORRECT |
|||
call add(list,10) " CORRECT |
|||
</source> |
|||
* Give regular expression patterns in ''single-quotes''! |
|||
<source lang="vim"> |
|||
echo match("binary(blob)","b\|(",0) " WRONG! |
|||
echo match("binary(blob)",'b\|(',0) " CORRECT |
|||
</source> |
|||
== Mappings == |
|||
* Mouse mappings requires <code>:set mouse=a</code>. |
|||
=== View mappings === |
|||
List mappings: |
|||
<source lang="vim"> |
|||
:map |
|||
:map! |
|||
</source> |
|||
List mappings, with origin: |
|||
<source lang="bash"> |
|||
:verbose map |
|||
:verbose map! |
|||
</source> |
|||
=== Define new mapping === |
|||
* Note that not all combinations are possible (see [http://vim.1045645.n5.nabble.com/How-to-map-say-Ctrl-Shift-B-td1183582.html] and <code>help :keycodes</code>) |
|||
** {{kb|S-b}} and {{kb|S-B}} are the same |
|||
** {{kb|C-b}} and {{kb|C-b}} (both mean 0x02) |
|||
** {{kb|A-b}} and {{kb|A-B}} are different, but are represented by vim by setting the high bit (0x80), so {{kb|A-b}} is same as 'â', and {{kb|A-B}} is same as 'Â' |
|||
* Note that GUI Vim some Alt key shortcuts select the menu. To disable that: |
|||
<source lang="vim"> |
|||
set guioptions-=m |
|||
</source> |
|||
== Cheatsheets == |
|||
Custom mappings are <u>underlined</u>. |
|||
=== Custom Cheatsheets === |
|||
* [[Media:Visio-Vim graphic cheatsheet-AZERTY-MIP.pdf|Custom graphical keyboard cheatsheet (AZERTY)]] |
|||
* [[Media:Vim quick reference card.pdf|Vim quick reference card (PDF)]] |
|||
** [[Media:MIP Vim quick reference card.pdf|Custom version (PDF)]] |
|||
=== Mappings === |
|||
<div style="column-width:36em;"> |
|||
{| class="wikitable" width="100%" |
|||
|+ Window management |
|||
|- |
|||
|width="120px"| |
|||
{{kbctrl|W}}_ {{kbctrl|W}}<nowiki>|</nowiki> {{kbctrl|W}}=<br/> |
|||
{{kbctrl|W}}h {{kbctrl|W}}l<br/> |
|||
{{kbctrl|W}}j {{kbctrl|W}}k<br/> |
|||
{{kbctrl|W}}p<br/> |
|||
{{kbctrl|W}}o<br/> |
|||
{{kbctrl|W}}t |
|||
| |
| |
||
Max. h/w current window or tile<br/> |
|||
Move to left, right window<br/> |
|||
Move to down, up window<br/> |
|||
Move to previous window<br/> |
|||
Show current window only<br/> |
|||
Promote window to tab |
|||
|} |
|||
{| class="wikitable" width="100%" |
|||
|+ Mouse |
|||
|- |
|- |
||
|width="120px"| |
|||
|'''<tt>*</tt>''' |
|||
{{kbname|MouseL}}<br/> |
|||
|Search next occurence of word under cursor (Here [http://vim.wikia.com/wiki/VimTip1 more] like this...) |
|||
g{{kbname|MouseR}} {{kbctrl|{{kbname|MouseR}}}} |
|||
| |
| |
||
Jump to tag<br/> |
|||
Return from tag |
|||
|} |
|||
{| class="wikitable" width="100%" |
|||
|+ Command-line Mode (<code>:</code>) |
|||
|- |
|||
|width="120px"| |
|||
{{kbctrl|U}}<br/> |
|||
{{kbctrl|R}}<br/> |
|||
{{kbctrl|1=R=}}<br/> |
|||
{{kbctrl|W}} |
|||
|Remove auto-range (<code>:help omap-info</code>)<br/> |
|||
Insert register / object (<code>:help c_CTRL-R</code>)<br/> |
|||
Insert expression (eg.<code>&gfn</code>)<br/> |
|||
Delete previous word |
|||
|} |
|||
{| class="wikitable" width="100%" |
|||
|+ Insert Mode |
|||
|- |
|- |
||
|width="120px"| |
|||
|'''<tt>#</tt>''' |
|||
{{kbctrl|{{kbname|Space}}}}<br/> |
|||
|Search previous occurence of word under cursor |
|||
{{kbctrl|O}} |
|||
| |
| |
||
Same as {{kbname|Esc}}, but easier (see [http://vim.wikia.com/wiki/Avoid_the_escape_key])<br/> |
|||
Execute one command, back to insert mode |
|||
|} |
|||
{| class="wikitable" width="100%" |
|||
|+ Normal Mode |
|||
|- |
|- |
||
|width="120px"| |
|||
|'''<tt>gd</tt>''' |
|||
{{green|''n''}}{{kbctrl|O}}<br/> |
|||
|Search first occurence of current search |
|||
{{green|''n''}}{{kbctrl|I}}<br/> |
|||
<code>:ju[mps]</code><br/> |
|||
{{kbctrl|R}}<br/> |
|||
{{kb|&}}<br/> |
|||
<code>:%&</code> |
|||
| |
| |
||
Go to {{green|''n''}} older pos. in jump list<br/> |
|||
Go to {{green|''n''}} newer pos. in jump list<br/> |
|||
Print jump list<br/> |
|||
Redo<br/> |
|||
Repeat last substitution<br/> |
|||
Repeat for all lines (add <code>c</code> for confirmation) |
|||
|} |
|} |
||
== Some Stuff to Add in <tt>~/vimrc</tt> file == |
|||
''(remarks: command in <tt>~/vimrc</tt> file must not be prefixed with a colon :)'' |
|||
* To enable syntax highlighting + numbering: |
|||
syntax enable |
|||
set bg=light ''" Use set bg=dark if console background color is dark'' |
|||
set number |
|||
* To remap movement key bindings to JKLM (instead of HJKL, so that they are right under right hand fingers on ''AZERTY'' keyboards). Commands on key 'M' are now on key 'H'. |
|||
nnoremap j h |
|||
nnoremap k j |
|||
nnoremap l k |
|||
nnoremap m l |
|||
nnoremap h m |
|||
vnoremap j h |
|||
vnoremap k j |
|||
vnoremap l k |
|||
vnoremap m l |
|||
vnoremap h m |
|||
{| class="wikitable" width="100%" |
|||
== Miscellaneous Tips and Tricks == |
|||
|+Registers |
|||
* Inserting only a single character (http://vim.wikia.com/wiki/Insert_a_single_character). |
|||
|- |
|||
|width="120px"| |
|||
{{kbkey|"ay}} |
|||
| |
|||
YANK to / paste frmo register {{green|''a''}}. |
|||
|- |
|||
|width="120px"| |
|||
{{kbkey|"Ay}} |
|||
| |
|||
APPEND to register {{green|''a''}}. |
|||
|} |
|||
{| class="wikitable" width="100%" |
|||
|+Miscellaneous |
|||
|- |
|||
|width="120px"| |
|||
{{kbctrl|^}} ''or'' {{kbctrl|6}} (azerty) |
|||
| |
|||
Edit alternate buffer (#) |
|||
|} |
|||
</div> |
|||
=== Operators & motions === |
|||
''Operators'' in Vim acts |
|||
* on ''the current selection'' (visual mode like {{kbkey|v}}, {{kbkey|V}} or {{kbctrl|v}}) when there is such a selection, |
|||
* or must be followed by a ''motion'' indicating which part of the text must be modified. |
|||
<table> |
|||
<tr valign="top"> |
|||
<td> |
|||
'''Operators''' |
|||
{| class="wikitable" width="100%" |
|||
|- |
|||
| |
|||
c<br/> |
|||
d<br/> |
|||
y<br/> |
|||
~<br/> |
|||
g~<br/> |
|||
gu<br/> |
|||
gU<br/> |
|||
<nowiki>!</nowiki><br/> |
|||
=<br/> |
|||
gq<br/> |
|||
g?<br/> |
|||
><br/> |
|||
<<br/> |
|||
zf<br/> |
|||
g@ |
|||
| |
|||
change<br/> |
|||
delete<br/> |
|||
yank into register (does not change the text)<br/> |
|||
swap case (only if 'tildeop' is set)<br/> |
|||
swap case<br/> |
|||
make lowercase<br/> |
|||
make uppercase<br/> |
|||
filter through an external program<br/> |
|||
filter through 'equalprg' or C-indenting if empty<br/> |
|||
text formatting<br/> |
|||
ROT13 encoding<br/> |
|||
shift right<br/> |
|||
shift left<br/> |
|||
define a fold<br/> |
|||
call function set with the 'operatorfunc' option |
|||
|} |
|||
</td> |
|||
</tr> |
|||
</table> |
|||
The ''motion'' is either one of the ''motion key'' (like {{kbkey|>%}} for ''shift right until match'') or an ''operator motion'' (like {{kbkey|diB}} for ''delete inner {} block''). See <tt>[http://vimdoc.sourceforge.net/htmldoc/motion.html#operator :help operator]</tt>. |
|||
'''Frequently-used operator motion''' |
|||
{| class="wikitable" |
|||
|- valign="top" |
|||
|<tt>'''iw'''</tt><br/> |
|||
<tt>'''iW'''</tt><br/> |
|||
<tt>'''is'''</tt><br/> |
|||
<tt>'''ip'''</tt> |
|||
|inner word<br/> |
|||
inner WORD<br/> |
|||
inner sentence<br/> |
|||
inner paragraph |
|||
|<tt>'''aw'''</tt><br/> |
|||
<tt>'''aW'''</tt><br/> |
|||
<tt>'''as'''</tt><br/> |
|||
<tt>'''ap'''</tt> |
|||
|a word<br/> |
|||
a WORD<br/> |
|||
a sentence<br/> |
|||
a paragraph |
|||
|<tt>'''i['''</tt><br/> |
|||
<tt>'''ib'''</tt> <tt>'''i('''</tt><br/> |
|||
<tt>'''i<'''</tt><br/> |
|||
<tt>'''it'''</tt><br/> |
|||
<tt>'''iB'''</tt> <tt>'''i{'''</tt> |
|||
|inner [] block<br/> |
|||
inner () block<br/> |
|||
inner <> block<br/> |
|||
inner tag block<br/> |
|||
inner {} block |
|||
|<tt>'''a['''</tt><br/> |
|||
<tt>'''ab'''</tt> <tt>'''a('''</tt><br/> |
|||
<tt>'''a<'''</tt><br/> |
|||
<tt>'''at'''</tt><br/> |
|||
<tt>'''aB'''</tt> <tt>'''a{'''</tt> |
|||
|a [] block<br/> |
|||
a () block<br/> |
|||
a <> block<br/> |
|||
a tag block<br/> |
|||
a {} block |
|||
|<tt>'''i"'''</tt><br/> |
|||
<tt>'''i<nowiki>'</nowiki>'''</tt><br/> |
|||
<tt>'''i`'''</tt> |
|||
|inner "" string<br/> |
|||
inner <nowiki>''</nowiki> string<br/> |
|||
inner `` string |
|||
|<tt>'''a"'''</tt><br/> |
|||
<tt>'''a<nowiki>'</nowiki>'''</tt><br/> |
|||
<tt>'''a`'''</tt> |
|||
|a "" string<br/> |
|||
a <nowiki>''</nowiki> string<br/> |
|||
a `` string |
|||
|} |
|||
=== Commands === |
|||
<source lang="vim"> |
|||
" Search & replace - current line |
|||
:s/search/replace/g |
|||
" Search & replace - global scope |
|||
:%s/search/replace/g |
|||
" Set Vim option (here textwidth) |
|||
:set {option}=70 |
|||
" Show value of {option} |
|||
:echo &{option} |
|||
:set {option}? |
|||
" Search / replace in all opened buffers |
|||
:bufdo %s/pattern/substitution/ge | update |
|||
" Replace current line with register content |
|||
VP |
|||
</source> |
|||
== General tips == |
|||
=== Practical Vim — Part I: Modes === |
|||
<ul> |
|||
<li>'''Tip 4: Act, Repeat, Reverse''' —</li> |
|||
{|class=wikitable |
|||
|- |
|||
|Make a change||{edit}||{{kbkey|.}}||{{kbkey|u}} |
|||
|- |
|||
|Scan line for next character||{{kbkey|f}}{{kbname|{char} }}/ {{kbkey|t}}{{kbname|{char} }}||rowspan=2|{{kbkey|;}}||rowspan=2|{{kbkey|,}} |
|||
|- |
|||
|Scan line for previous character||{{kbkey|F}}{{kbname|{char} }}/ {{kbkey|T}}{{kbname|{char} }} |
|||
|- |
|||
|Scan document for next match||/pattern{{kb|CR}}||rowspan=2|{{kbkey|n}}||rowspan=2|{{kbkey|N}} |
|||
|- |
|||
|Scan document for previous match||/pattern{{kb|CR}} |
|||
|- |
|||
|Perform substitution||:s/target/replacement||{{kbkey|&}}||{{kbkey|u}} |
|||
|- |
|||
|Execute a sequence of changes||{{kbkey|qx{{kbname| {changes} }}q}}||{{kbkey|@x}}<br/>{{kbkey|éx}}||{{kbkey|u}} |
|||
|} |
|||
<li>'''Tip 6: Meet the Dot Formula''' —One keystroke to move, one keystroke to execute (like <code>{{kbkey|A}}.{{kb|ESC}}</code> then <code>{{kbkey|j.j.j.}}</code>, <code>{{kbkey|f}}+{{kbkey|s}}_+_</code> then <code>{{kbkey|;.;.;.}}</code>, <code>{{kbkey|*cw}}copy{{kb|ESC}}</code> then <code>{{kbkey|n.n.n.}}</code>)</li> |
|||
<li>'''Tip 9: Compose Repeatable Changes''' — e.g. favor {{kbkey|daw}} instead of {{kbkey|dbx}} or {{kbkey|bdw}} to delete a word, because the former is a single operation, and hence invests the most power into the dot command.</li> |
|||
<li>'''Tip 13: Make Corrections Instantly from Insert Mode''' — e.g. use {{kbctrl|h}} for ''backspace'', {{kbctrl|w}} for ''delete word'', {{kbctrl|u}} for ''delete line''.</li> |
|||
<li>'''Tip 14: Go Back to Normal Mode''' — use {{kbctrl|[}} for ''Switch to Normal mode'', and {{kbctrl|o}} for ''Insert Normal mode'' (e.g. {{kbctrl|o}}{{kbkey|zz}}).</li> |
|||
<li>'''Tip 15: Paste from a Register Without Leaving Insert Mode'''</li> |
|||
* use {{kbctrl|r}} for ''putting character-wise register'', and {{kbctrl|r}}{{kbctrl|o}} for inserting characters litteraly and without auto-indent |
|||
* remap {{kb|{{kbname|CAPS LOCK}}}} (capslock) to something else ''at system level'', either {{kb|ESC}} (escape) or {{kb|CTRL}} (see Tips section). |
|||
<li>'''Tip 16: Do Back-of-the-Envelope Calculations in Place''' — Example {{kbkey|a ^r}}= 6*35 {{kb|CR}}</li> |
|||
<li>'''Tip 17: Insert Unusual Characters by Character Code''' — {{kbkey|^v123}} inserts by decimal code, {{kbkey|^vu1234}} inserts by hexadecimal code, {{kbkey|^v {{kbname|non-digit}}}} inserts literally, {{kbkey|ga}} returns character code.</li> |
|||
<li>'''Tip 18: Insert Unusual Characters by Digraph''' — {{kbkey|^k {{kbname|char1 char2}}}} inserts digraph. See <code>:h digraphs-default</code> (convention), <code>:h digraphs</code> (all digraphs), <code>:h digraph-table</code> (more usable list). There's also plugin [https://gist.github.com/panozzaj/8346388 betterdigraphs.vim] from Damian Conway.</li> |
|||
<li>'''Tip 19: Overwrite Existing Text with Replace Mode''' — {{kbkey|r}}, {{kbkey|R}} to replace, {{kbname|Insert}} to switch mode, {{kbkey|gr}},{{kbkey|gR}} to replace visually.</li> |
|||
<li>'''Tip 21: Define a Visual Selection''' — {{kbkey|gv}} reselect the last visual selection, {{kbkey|o}} go to other end of highlighted text.</li> |
|||
<li>'''Tip 27: Command-Line Mode''' — {{kbctrl|v}} or {{kbctrl|k}} to insert special character, {{kbctrl|r}}{{kbname|{register}}} to insert content of any register.</li> |
|||
<li>'''Tip 28: Execute a Command on One or More Consecutive Lines''' — Example of ranges <code>:1p</code>, <code>:$p</code>, <code>:2,5p</code>, <code>:.,$p</code>, <code>:%p</code>, <code>:'<,'>p</code>, <code>/<html>/,/<\/html>/p</code>, <code>/<html>/+1,/<\/html>/-1p</code>, <code>:.,.+3p</code> (there is also <code>0</code> for virtual line before first line).</li> |
|||
<li>'''Tip 29: Duplicate or Move Lines Using ':t' and ':m' Commands''' — <code>:[range]copy {address}</code> or <code>:[range]t {address}</code> for copy, <code>:[range]move {address}</code> or <code>:[range]m {address}</code> for move.</li> |
|||
<li>'''Tip 30: Run Normal Mode Commands Accross a Range''' — Use <code>:[range]normal {command}</code> or <code>:[range]norm {command}</code>. Eg. <code>:%norm .</code>, <code>:%norm A;</code>, <code>:%norm i//</code>.</li> |
|||
<li>'''Tip 31: Repeat the Last Ex Command''' — Use <code>{{kbkey|@:}}</code> and <code>{{kbkey|@@}}</code> afterwards (last command always stored in <code>:</code> register).</li> |
|||
<li>'''Tip 32: Tab-Complete Your Ex Commands''' — Use {{kbctrl|d}} to view auto-complete list, {{kbkey|Tab}} and {{kbkey|S-Tab}} to cycle through it.</li> |
|||
<li>'''Tip 33: Insert the Current Word at the Command Prompt''' — Use {{kbctrl|r}}{{kbctrl|w}} to insert current word, {{kbctrl|r}}{{kbctrl|a}} for current WORD.</li> |
|||
<li>'''Tip 34: Recall Commands from History''' — Use {{kbname|Up}}/{{kbname|Down}} or or {{kbctrl|p}}/{{kbctrl|n}} to recall command with filtering. Use {{kbkey|:q}} for Command-Line Window ({{kbname|Enter}} to execute, {{kb|:q}} to leave). Use {{kbctrl|f}} to switch to Command-line window, even while typing a command. Use following mapping to have filtering enabled for {{kbctrl|p}}/{{kbctrl|n}}:</li> |
|||
<source lang=vim> |
|||
cnoremap <C-p> <Up> |
|||
cnoremap <C-n> <Down> |
|||
</source> |
|||
<li>'''Tip 35: Run Commands in the Shell''' — Use <code>%</code> as shorthand for current file name, like <code>:!ruby %</code> (see <tt>:h cmdline-special</tt>) |
|||
* <code>:shell</code> runs a shell (in a terminal better use {{kbctrl|z}} to suspend vim), |
|||
* <code>:!{cmd}</code> executes a command with the shell, |
|||
* <code>:read !{cmd}</code> inserts command output at the cursor, |
|||
* <code>:[range]write !{cmd}</code> executes command with selected text as input, |
|||
* <code>:[range]!{filter}</code> filters selected text through command.</li> |
|||
</ul> |
|||
=== Practical Vim — Part II: Files === |
|||
<ul> |
|||
<li>'''Tip 36: Track Open Files with the Buffer List''' — <code>:ls</code> to list buffers; <code>:<u>b</u>uffer N</code> or <code>:<u>b</u>uffer {bufname}</code> to jump directly; <code>:bprevious</code>, <code>:bnext</code>, <code>:bfirst</code> and <code>:blast</code> to navigate through buffers; <code>:<u>bd</u>elete</code> to delete buffers; and <code>:bufdo</code> to execute command on all buffers. <code>:write</code>, <code>:update</code> and <code>:saveas</code> to write buffer to disk. </li> |
|||
</ul> |
|||
=== Efficient Editing === |
|||
<ul> |
|||
<li>'''Dot command''' — See [http://www.viemu.com/a-why-vi-vim.html] for example.</li> |
|||
<li>'''Use * to search word under cursor (and # backward)''' &mdash see also [http://www.viemu.com/a-why-vi-vim.html] for example. |
|||
<li>'''Substitute current line''' — Use {{kbkey|S}} ( or {{kbkey|cc}}) to replace the current line, while keeping current indentation (instead of {{kbkey|ddO}} to delete current line and open new one)</li> |
|||
<source lang="vim"> |
|||
" F3 (an improved UltraEdit F3 ;-) ) search for next occurrence of replaced word (actually register -) - handy for refactorizing code |
|||
" Also mapped to ù (AZERTY power!) |
|||
nnoremap <F3> /\<<C-R>-\><CR> |
|||
nnoremap ù /\<<C-R>-\><CR> |
|||
</source> |
|||
Using this mapping, one can: |
|||
# Rename a variable with {{kbkey|ciw}} for instance, and type the new variable name (use {{kbctrl|R}}{{kbkey|-}} to start from old name) |
|||
# Look for next occurent of the replaced variable with {{kb|F3}} (or {{kbkey|ù}}) |
|||
# Repeat replacement with {{kbkey|.}} ({{kbname|dot}} key) |
|||
# Repeat from step 2 (or use {{kbkey|n}}), or {{kbkey|N}} for previous occurrence. |
|||
This tip works better than using <code>{{green|range}}:s/{{green|pattern}}</code>, because you don't have to type the name of replaced variable, nor use the word delimiter <code>\<</code>...<code>\></code>, and you don't have to specify a range in advance. |
|||
<li>'''Quick buffer edit''' — Use <code>:b {bufname}</code> to quickly jumped to buffer referenced by its number (see <code>:ls</code>) or by its name. Buffer name can be ''incomplete'' as long as it is ''unique'' (this is very handy!!!). |
|||
<li>use '''(''' and ''')''' to move between sentences, ''']p''' paste indented, '''`.''' move to last edit (source [http://robertames.com/files/vim-editing.html Efficient editing with vim])</li> |
|||
<li>'''Smart ranges and clipboards''' — (source [http://www.viemu.com/a-why-vi-vim.html])</li> |
|||
<source lang=c> |
|||
if (!entry.used && |equivalent(entry.key(), qk.key) && (curcontext & entry.contexts)) |
|||
</source> |
|||
:Starting from cursor position above , type '''c%''' and '''equiv{{kb|{{kbname|ESC}}}}''', and then '''Obool equiv = {{kb|C-R}}";{{kb|{{kbname|ESC}}}}''' to get the result below. |
|||
<source lang=c> |
|||
bool equiv = equivalent(entry.key(), qk.key); |
|||
if (!entry.used && equiv && (curcontext & entry.contexts)) |
|||
</source> |
|||
<li>'''Syntax folding''' — Enable automatic folding for javascrip, PHP, XML, ... [http://stackoverflow.com/questions/4789605/how-do-i-enable-automatic-folds-in-vim]</li>. Add to {{file|.vimrc}}: |
|||
<source lang=vim> |
|||
set foldmethod=syntax |
|||
set foldlevelstart=1 |
|||
let javaScript_fold=1 " JavaScript |
|||
let perl_fold=1 " Perl |
|||
let php_folding=1 " PHP |
|||
let r_syntax_folding=1 " R |
|||
let ruby_fold=1 " Ruby |
|||
let sh_fold_enabled=1 " sh |
|||
let vimsyn_folding='af' " Vim script |
|||
let xml_syntax_folding=1 " XML |
|||
# https://stackoverflow.com/questions/32154285/folding-expanding-and-colapsing-xml-tags-in-vim-xml-parsing |
|||
au FileType xml setlocal foldmethod=syntax |
|||
au FileType xslt setlocal foldmethod=syntax |
|||
</source> |
|||
<li>Use '''Caps Lock''' as another '''Escape (ESC)''' key.</li> |
|||
On '''Linux''', see [[X#Configuring_Layout_Options]]. Basically we update gnome settings for current user: |
|||
<source lang=bash> |
|||
gsettings get org.gnome.desktop.input-sources xkb-options |
|||
gsettings set org.gnome.desktop.input-sources xkb-options "@as ['caps:escape']" |
|||
</source> |
|||
On '''Windows''', see [http://vim.wikia.com/wiki/Map_caps_lock_to_escape_in_Windows Map caps lock to escape in Windows]. Import the registry file (Win7/Win8): |
|||
<source lang=reg> |
|||
Windows Registry Editor Version 5.00 |
|||
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] |
|||
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,46,00,01,00,3a,00,00,00,00,00 |
|||
</source> |
|||
</ul> |
|||
=== Modeline === |
|||
Use '''modeline''' to embed vim format settings in the document itself. This requires the following line in <tt>~/.vimrc</tt>:</li> |
|||
<source lang=vim> |
|||
set modeline |
|||
</source> |
|||
The format of the modeline is (see <code>help modeline</code> for more variants): |
|||
<u>[text] vim:</u>{options} |
|||
<u>[text] vim: set </u>{options}<u>:</u> |
|||
Now you can for instance for automatic word wrapping in a text document by adding the following line to the document (for instance as the last line or within a comment block): |
|||
/* vim: set ai fo=tcroq tw=105: */ |
|||
Alternatively, use the following to disable automatic line break, but still wrap words at word boundaries: |
|||
/* vim: set ai fo=tcroq tw=0 wrap linebreak nolist: */ |
|||
Add <code>spell</code> to enable background spell checker (e.g. LaTeX document): |
|||
/* vim: set ai fo=tcroq tw=105 spell: */ |
|||
/* vim: set ai fo=tcroq tw=0 wrap linebreak nolist spell: */ |
|||
;Markdown |
|||
Use the following line [https://stackoverflow.com/questions/4823468/comments-in-markdown]: |
|||
[//]: # ( vim: set tw=105: ) |
|||
=== Miscellaneous === |
|||
<ul> |
|||
<li>Inserting only a single character (http://vim.wikia.com/wiki/Insert_a_single_character):</li> |
|||
<source lang="vim"> |
|||
:nnoremap <space> :exec "normal i".nr2char(getchar())."\e"<CR> |
|||
</source> |
|||
<li>Macro</li> |
|||
* <tt>qq</tt> to start recording a macro '''q'''. End macro with <tt>q</tt> again. |
|||
* <tt>@q</tt> to replay macro, followed by <tt>.</tt> to replay it again. |
|||
<li>Visual Block</li> |
|||
* <tt>Ctrl-v</tt> to start ''VISUAL BLOCK'' mode. |
|||
* <tt>Shift-I</tt> to insert some text at the start of each line of selected block. |
|||
<li>wrap-around</li> |
|||
* Set option '''[http://www.vim.org/htmldoc/options.html#'whichwrap' whichwrap]''' or '''ww''' that allows specified keys that move the cursor left/right to move to the previous/next line when the cursor is on the first/last character in the line. |
|||
* In ''Vim'', '''<space>''' and '''<backspace>''' are set to wrap-around by default. |
|||
<li>Read-only viewer (with syntax highlighting):</li> |
|||
<source lang="bash"> |
|||
$ vi -R sensitive_file |
|||
$ view sensitive_file |
|||
</source> |
|||
<li> Retab</li> |
|||
To convert tabs in current file to current tab settings, use command '''<code>:retab</code>''' [http://vim.wikia.com/wiki/Converting_tabs_to_spaces]. For instance to '''convert tabs into space''' |
|||
<source lang="vim"> |
|||
:set expandtab |
|||
:retab |
|||
</source> |
|||
<li>View differences in vim</li> |
|||
<source lang="bash"> |
|||
vimdiff file1.txt file2.txt |
|||
</source> |
|||
<li>Interaction with X Clipboard</li> |
|||
'''vim''' can use the X clipboard if it has been compiled with the <tt>clipboard</tt> feature (run <code>vim --version</code> and see if you have <tt>+clipboard</tt> in the output). In that case, yanking to the '''<code>+</code>''' register, or simply selecting with the mouse, will actually copy in the X clipboard, hence allowing other applications, or even other instances of '''vim''' to exchange text snippets. Also, it will ease the copy-paste of indented text, since in that case, '''vim''' will first disable ''autoindentation'' before pasting the text (see option <code>paste</code>). |
|||
On system like ''Ubuntu'', you need to install an instance of '''gvim''' (like package '''vim-gnome''' or '''vim-gtk''') to have feature <code>+clipboard</code> turned on (i.e. installing package '''vim''' is not enough). |
|||
When <code>set mouse=a</code>, use '''shift-mouse''' to still use the xterm copy/paste (see ''mouse-using''). |
|||
<source lang="vim"> |
|||
:set paste " Enable paste mode, i.e. disable autoindent, mapping... " |
|||
:set nopaste " Disable paste mode (back to normal...) " |
|||
</source> |
|||
<li><code>set incsearch</code>, moves cursor as search pattern is typed. <tt>Ctrl-L</tt> to type letter under cursor, <tt>Ctrl-R Ctrl-W</tt> to type current word.</li> |
|||
<li>References:</li> |
|||
http://vim.wikia.com/wiki/Best_Vim_Tips |
|||
<li> type <code>:help ctrl<font color="blue"><C-D></font></code>, to get a list of all ctrl sequence. Type <font color="blue"><C-D></font> in command line for auto-completion.</li> |
|||
<li> Support '''256 colors''' in ''gnome-terminal'': add <code>set t_Co=256</code> in <tt>~/.vimrc</tt> ([http://djcraven5.blogspot.com/2006/10/gnome-terminal-vim-with-256-colors.html])</li> |
|||
<li> Use <code>:make</code> and <code>:grep</code> instead of <code>:!make</code> or <code>:!grep</code>. Then use <code>:cwin</code> or <code>:copen</code> to view the results of either make or grep in a coloured list (from [http://vim.wikia.com/wiki/New_to_Vim]).</li> |
|||
<li> (from [http://vim.wikia.com/wiki/Quick_tips]), The <code>:g</code> command is useful to apply a command to all lines matching a search.</li> |
|||
<source lang="vim"> |
|||
" delete all lines matching pattern |
|||
:g/pattern/d |
|||
" --> example: delete empty lines |
|||
:g/^$/d |
|||
" --> example: delete lines with only whitespaces |
|||
:g/^\s*$/d |
|||
" delete all lines *NOT* matching pattern (:v same as :g!) |
|||
:g!/pattern/d |
|||
:v/pattern/d |
|||
</source> |
|||
<li> '''[https://github.com/justinmk/vim-syntax-extra vim-syntax-extra]''' — C syntax extension, to also highlight C delimiters. Copy as file {{file|~/.vim/after/syntax/c.vim}} (and {{file|~/.vim/after/syntax/cpp.vim}}).</li> |
|||
The previous solution was to use the settings below, but these break code folding with <code>foldmethod=syntax</code>. |
|||
<source lang="vim"> |
|||
" OBSOLETE - THESE BREAK FOLDMETHOD=SYNTAX |
|||
syn match cDelimiter "[&\.!^,;:<>=|+%*-]" |
|||
syn match cParenDelimiter "[][(){}]" |
|||
hi def link cDelimiter Delimiter |
|||
hi def link cParenDelimiter Delimiter |
|||
</source> |
|||
<li>Replace a word with yanked text (see tip [http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text])</li> |
|||
<source lang="vim"> |
|||
yiw " Yank word under cursor " |
|||
... " Move to next word " |
|||
viwp " Replace current word with yanked text. " |
|||
... |
|||
viwp |
|||
... |
|||
</source> |
|||
<li>Quickly switch between opened buffers. The commands <code>:b</code> and <code>:sb</code> accepts partial buffer name when specifying which buffer to edit:</li> |
|||
<source lang="vim"> |
|||
:ls " List buffer list, say you have a file verylongfilename_spec.c and anotherverylong_code.c" |
|||
:b spec " Will switch to buffer verylongfilename_spec.c" |
|||
:sb code " Will split the window and switch to buffer anotherverylong_code.c" |
|||
</source> |
|||
<li>Various command to interact with the shell:</li> |
|||
{| |
|||
|- |
|||
|<tt>[http://vimdoc.sourceforge.net/htmldoc/various.html#:! :!{cmd}]</tt> |
|||
|Execute {cmd} with the shell. |
|||
|- |
|||
|<tt>[http://vimdoc.sourceforge.net/htmldoc/various.html#:!! :!!]</tt> |
|||
|Repeat last ":!{cmd}". |
|||
|- |
|||
|<tt>[http://vimdoc.sourceforge.net/htmldoc/insert.html#:r! <nowiki>:[range]r[ead] !{cmd}</nowiki>]</tt> |
|||
|Execute {cmd} and insert its standard output below the cursor or the specified line. |
|||
|- |
|||
|<tt>[http://vimdoc.sourceforge.net/htmldoc/editing.html#:w_c <nowiki>:[range]w[rite] [++opt] !{cmd}</nowiki>]</tt> |
|||
|Execute {cmd} with [range] lines as standard input. |
|||
|} |
|||
<li>Save a file you edited without the needed permissions (source [http://www.commandlinefu.com/commands/view/1204/save-a-file-you-edited-in-vim-without-the-needed-permissions])</li> |
|||
<source lang="vim"> |
|||
:w !sudo tee % |
|||
</source> |
|||
<li>Delete all trailing spaces ([http://vim.wikia.com/wiki/Remove_unwanted_spaces]):</li> |
|||
<source lang="bash"> |
|||
:%s/\s\+$// " Remove all trailing spaces |
|||
:%s/\s\+$ " We can omit substitution text if blank |
|||
</source> |
|||
Add this to <tt>.vimrc</tt> to have vim remove automatically trailing spaces before saving |
|||
<source lang="vim"> |
|||
autocmd BufWritePre * :%s/\s\+$//e |
|||
</source> |
|||
More elaborate version: |
|||
<source lang="vim"> |
|||
" Trim trailing spaces on save |
|||
if !exists("autocmd_BufWritePre_trimspace_tab") |
|||
let autocmd_BufWritePre_trimspace_tab = 1 |
|||
autocmd FileType c,cpp,java,php,vim autocmd BufWritePre <buffer> :call setline(1,map(getline(1,"$"),'substitute(v:val,"\\s\\+$","","")')) |
|||
" autocmd BufWritePre * :set expandtab<CR>:retab |
|||
endif |
|||
</source> |
|||
Or better yet, create a custom mapping [http://vi.stackexchange.com/questions/454/whats-the-simplest-way-to-strip-trailing-whitespace-from-all-lines-in-a-file]: |
|||
<source lang="vim"> |
|||
" F10 - Remove all trailing whitespace |
|||
nnoremap <F10> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR> |
|||
</source> |
|||
<li>Promote window to tab (see [http://vim.1045645.n5.nabble.com/Promote-window-to-tab-td1198017.html])</li> |
|||
<source lang="vim"> |
|||
:noremap <C-W>t :tabedit <C-R>%<CR>gT<C-W>qgt |
|||
</source> |
|||
<li>[http://vim.wikia.com/wiki/Find_in_files_within_Vim Find in files within Vim] (commands <code>:grep</code>, <code>:lgrep</code>, <code>:vimgrep</code>, <code>:lvimgrep</code>)</li> |
|||
Define this custom command to quickly look for current word, and displays the quicklist window: |
|||
<source lang="vim"> |
|||
" We must embed :grep in :execute or otherwise vim will append /dev/null |
|||
" to :cw command and will complain of E488: trailing characters |
|||
command! GREP :execute "grep -R <cword> ./src"|:cw |
|||
</source> |
|||
<li>Use <code>:E[xplore]</code> for explore directory of current file (from netrw)</li> |
|||
<li>Formatting code with '''column''' shell filter. Say you have a code like the one on the left. To align this text, select the 3 lines, then <code>!column -t</code>. This will give: </li> |
|||
{| |
|||
|- |
|||
| |
|||
<source lang="c"> |
|||
int myint = 1; |
|||
double a = 2.0; |
|||
float verylongf = 1234.50; |
|||
</source> |
|||
| → |
|||
| |
|||
<source lang="c"> |
|||
int myint = 1; |
|||
double a = 2.0; |
|||
float verylongf = 1234.50; |
|||
</source> |
|||
|} |
|||
<li>Only english dictionary is available by default. But Vim will automatically download and install the '''french''' dictionary with</li> |
|||
<source lang=vim> |
|||
set spelllang=fr |
|||
</source> |
|||
<li>Use <code>set fileencoding=utf-8</code> to convert a file to unicode UTF-8 format. Vim can also add the BOM (Byte Order Mark) with <code>setlocal bomb</code></li> |
|||
<source lang=vim> |
|||
" Convert into utf-8 |
|||
set fileencoding=utf-8 |
|||
" Add the BOM |
|||
setlocal bomb |
|||
" Remove the BOM |
|||
setlocal nobomb |
|||
</source> |
|||
<li>Justify text. For instance justifying left-right, with 74-char line (require package {{deb|par}}:</li> |
|||
<source lang=vim> |
|||
!par -jw74 |
|||
</source> |
|||
<li>Copy current buffer filename into clipboard:</li> |
|||
<source lang=vim> |
|||
:let @+=expand("%")<CR> " Copy basename |
|||
:let @+=expand("%:p")<CR> " Copy fullpath |
|||
</source> |
|||
<li>'''Create a new file / directory''' — Easy with plugin ''NERDTree''. Open NERDTree, then navigate to folder where to create the new file, then press {{kb|m}}{{kb|a}}. This will create a new file / directory in given node. |
|||
</ul> |
|||
=== Spell checker === |
|||
;French |
|||
Vim will automatically download and install FR dictionary with |
|||
<source lang=vim> |
|||
:set spelllang=fr |
|||
</source> |
|||
To install manually, download FR dictionaries with |
|||
<source lang=bash> |
|||
cd ~/.vim/spell/ |
|||
wget http://ftp.vim.org/vim/runtime/spell/fr.latin1.spl |
|||
wget http://ftp.vim.org/vim/runtime/spell/fr.latin1.sug |
|||
wget http://ftp.vim.org/vim/runtime/spell/fr.utf-8.spl |
|||
wget http://ftp.vim.org/vim/runtime/spell/fr.utf-8.sug |
|||
</source> |
|||
Alternatively, copy them into {{file|/usr/share/vim/vim7X/spell/}} to have them available globally. |
|||
=== Command-line mode Tips === |
|||
<ul> |
|||
<li>'''Ex special characters''' — These are special character that can be used in ''executed command line'' (<code>:! ...</code>) or when ''ex'' is expecting a filename (see also <code>:help <cword></code>):</li> |
|||
<source lang="text"> |
|||
<cword> replaced with word under cursor |
|||
<CWORD> replaced with WORD under cursor |
|||
<cfile> replaced with pathname under cursor |
|||
... |
|||
</source> |
|||
<li>'''Insert register / object <C-R>''' — these can be used to insert some register content or text from context (see also <code>:help c_CTRL-R</code>):</li> |
|||
<source lang="text"> |
|||
<C-R>* insert X11 clipboard content |
|||
<C-R>+ insert clipboard content |
|||
<C-R>= expression register. You are prompted to enter an expression |
|||
<C-R><C-W> insert word under cursor |
|||
<C-R><C-A> insert WORD under cursor |
|||
</source> |
|||
Example of expressions: |
|||
<source lang="vim"> |
|||
nmap <C-@><C-@> :cs find s <C-R>=expand("<cword>")<CR><CR> |
|||
</source> |
|||
<li>'''Insert an environment variable $VAR in command map''' — Use <code><C-R>=$VAR<CR></code> to have a command map use the value of an environment variable</li> |
|||
<source lang=vim> |
|||
nmap <silent> <F12> :wa<CR>:b <C-R>=$VPMAINDOC<CR><CR>\ll |
|||
</source> |
|||
<li>'''New user-defined command in lowercase''' — </li> One cannot define a user-defined in lower case with <code>newcommand</code> because Vim forces the command to start with an uppercase. But we can circumvent this requirement with an ''abbreviation'' [http://vim.wikia.com/wiki/Replace_a_builtin_command_using_cabbrev]: |
|||
<source lang=vim> |
|||
cboreabbrev ag <c-r>=(getcmdtype()=':' && getcmdpos()==1 ? 'Ag' : 'ag')<CR> |
|||
</source> |
|||
</ul> |
|||
=== Clipboard support === |
|||
* On Linux, install ''gvim'' to get full clipboard support |
|||
** On Terminator, use also shortcuts {{kbctrl|S-c}} and {{kbctrl|S-V}} to copy & paste. |
|||
* On Cygwin, install ''gvim'' and a X server. |
|||
** ''vim'' will not have clipboard support. But similar result can be obtained by using <code>:set paste</code>, then <code>i</code>, followed by {{kb|S-''Insert''}} (under ''mintty'') |
|||
** ''gvim'' under Cygwin/X will have clipboard support. |
|||
** There is also some plugin (e.g. [http://www.vim.org/scripts/script.php?script_id=2098]) |
|||
* Alternatively, install Win32 gvim (but this versions is not correctly integrated in cygwin, or requires use of wrapper) |
|||
=== Whitespaces === |
|||
* A nice tip about [http://vim.wikia.com/wiki/Highlight_unwanted_spaces highlighting unwanted spaces] |
|||
* Use <code>set list</code> and <code>set listchars</code> to show trailing space, tags, extending spaces as another character...<br/>Some examples: |
|||
<source lang="vim"> |
|||
:set list listchars=tab:>-,trail:.,extends:>,precedes:< |
|||
" Enter the middle-dot by pressing Ctrl-k then .M |
|||
:set list listchars=tab:\|_,trail:· |
|||
" Enter the right-angle-quote by pressing Ctrl-k then >> |
|||
:set list listchars=tab:»·,trail:· |
|||
" Enter the Pilcrow mark by pressing Ctrl-k then PI |
|||
:set list listchars=tab:>-,eol:¶ |
|||
" The command :dig displays other digraphs you can use. |
|||
</source> |
|||
:To hide tabs even when using ''listchars'': |
|||
<source lang="vim"> |
|||
:set list listchars=tab:\ \ ,trail:·,extends:>,precedes:< |
|||
</source> |
|||
:This is also subject to highlighting ("NonText" is used for "eol", "extends" and "precedes" / "SpecialKey" for "nbsp", "tab" and "trail") |
|||
=== Advanced source highlighting === |
|||
* See file '''$VIMRUNTIME/syntax/c.vim''' for more advanced highlighting options for C files, like |
|||
** Highlighting of space errors |
|||
** Highlighting of curly, parens errors... |
|||
* Highlight column: |
|||
<source lang=vim> |
|||
:set colorcolumn=+1 " highlight column after 'textwidth' |
|||
:set colorcolumn=+1,+2,+3 " highlight three columns after 'textwidth' |
|||
:set colorcolumn=80 " highlight column 80 |
|||
:highlight ColorColumn ctermbg=lightgrey guibg=lightgrey |
|||
</source> |
|||
=== Digraphs === |
|||
''Digraph'' is an easy way to enter special character in Vim, much easier than using {{kbctrl|V}}. See <code>:help dig</code> for more details. |
|||
{| class="wikitable" |
|||
|- |
|||
!code!!result |
|||
|- |
|||
|{{kbctrl|k}}.M||· |
|||
|- |
|||
|{{kbctrl|k}}>>||» |
|||
|- |
|||
|{{kbctrl|k}}PI||¶ (Pilcrow mark) |
|||
|- |
|||
|{{kbctrl|k}}00||∞ (infinity) |
|||
|- |
|||
|{{kbctrl|k}}(-||∈ (in) |
|||
|- |
|||
|{{kbctrl|k}}In||∫ (integral) |
|||
|} |
|||
=== viEmu === |
|||
Tips for better use of viEmu. |
|||
* Applying format in Word via keyboard. To apply format like '''bold''' or ''italic'', you can't use the regular key binding {{kb|C-b}} or {{kb|C-i}} since it is intercepted by viEmu. Some work-arounds: |
|||
** (best) Use the new Ribbon shortcuts. For instance, {{kb|A-h 1}} for '''bold''', {{kb|A-h 2}} for ''italic'', {{kb|{{kbname|Alt}} 3}} for '''redo'''... |
|||
** (heavy) Temporarily disable viEmu with {{kb|C-S-A-v}}. Say {{kb|C-S-A-v}} {{kb|C-b}} {{kb|C-S-A-v}} for '''bold'''. |
|||
** (worsts) In the viEmu menu, tell viEmu not to intercept {{kb|C-b}} and to pass it to Word. |
|||
* In viEmu, don't let {{kb|C-c}} to be passed to office app. This allows using {{kb|C-C}} to leave insert mode. |
|||
* In viEmu, don't ''Emulate vi/vim block caret''. This allows formatting a single word w/o selecting it first, as usual in office. |
|||
* In viEmu, don't ''Update display during long commands''. Unchecking this box seems to fix the display glitch with viEmu status bar when scrolling down. |
|||
=== Editing HTML, XML, LaTeX === |
|||
(for LaTeX, see also the ''vim-latex'' plugin) |
|||
* [http://stackoverflow.com/questions/130734/how-can-one-close-html-tags-in-vim-quickly Stackoverflow post] |
|||
:* Use [http://vim.sourceforge.net/scripts/script.php?script_id=13 closetag] |
|||
:* Use {{kb|C-X C-O}} (omnicomplete) or define macro: |
|||
<source lang=vim> |
|||
imap ,/ </<C-X><C-O> |
|||
</source> |
|||
:* Use [http://www.vim.org/scripts/script.php?script_id=1896 ragtag] from Tim Pope (author of surround.vim) |
|||
:* Use [https://github.com/rstacruz/sparkup sparkup] (very efficient) |
|||
* Define ''abbreviations'' (see [http://vim.wikia.com/wiki/Auto_closing_an_HTML_tag]) |
|||
* Surround plugin in insert mode (use {{kbkey|^stli<enter>}} to insert a <code><li></code> tag for instance) |
|||
* LaTex + surround plugin, use {{kbkey|ys''m''\}} to insert <code>\begin{...} \end{...}</code> environment. |
|||
* To '''format''' LaTeX, see also plugin ''Latex Text Formatter''. |
|||
=== Omni-Completion === |
|||
Vim omni-completion {{kb|C-X C-O}} is quite powerful. Example: |
|||
* To insert HTML closing tags, type <code></{{kb|C-X C-O}}</code> |
|||
<sometag> |
|||
some text |
|||
some text |
|||
</{{kb|C-X C-O}} |
|||
* To complete a LaTeX tag. For instance to close a <code>\begin</code> environment, type {{kb|C-X C-O}} {{kb|C-O}} {{kb|C-X C-O}}: |
|||
\begin{theorem} |
|||
some text |
|||
some text |
|||
{{kb|C-X C-O}} {{kb|C-O}} {{kb|C-X C-O}} |
|||
A customization I used, but now disabled: |
|||
<source lang=vim> |
|||
" C-N: Auto-completion menu |
|||
" # DISABLED - Don't like the extra window opened, and strange completion. |
|||
" # To try: CTRL-N, or CTRL-X CTRL-N, CTRL-X CTRL-O, CTRL-X CTRL-P... |
|||
inoremap <expr> <C-N> pumvisible() \|\| &omnifunc == '' ? |
|||
\ "\<lt>C-n>" : |
|||
\ "\<lt>C-x>\<lt>C-o><c-r>=pumvisible() ?" . |
|||
\ "\"\\<lt>c-n>\\<lt>c-p>\\<lt>c-n>\" :" . |
|||
\ "\" \\<lt>bs>\\<lt>C-n>\"\<CR>" |
|||
</source> |
|||
=== Use Vim as Hexadecimal Editor === |
|||
* From [http://www.kevssite.com/2009/04/21/using-vi-as-a-hex-editor/] |
|||
<source lang=vim> |
|||
" To convert current buffer to hex |
|||
:%xxd |
|||
" To convert current buffer from hex |
|||
:%xxd -r |
|||
</source> |
|||
* Use plugin [http://www.vim.org/scripts/script.php?script_id=666 hexman.vim]. This still require to open vim in '''binary mode''' to prevent '''insertion of newlines''' (see [http://stackoverflow.com/questions/1050640/vim-disable-automatic-newline-at-end-of-file]): |
|||
<source lang=bash> |
|||
vim -b file # Might still require ":set noeol" |
|||
vim ++bin file |
|||
vim file # Then ':set binary' and ':set noeol' |
|||
</source> |
|||
=== Avoid the ESC key === |
|||
* '''{{red|BEST}}''' — Configure CapsLock as another ESC key. |
|||
** [[Windows_7#Use_Caps_Lock_as_another_Escape_key|On Windows]] |
|||
** On Linux: <code>gsettings set org.gnome.desktop.input-sources xkb-options "@as ['caps:escape']"</code> |
|||
* Use <code>{{kb|jj}}</code>: |
|||
<source lang=vim> |
|||
"--- jj ----------- |
|||
" jj : ... same as ESC (let's try) ... |
|||
inoremap jj <Esc>`^ |
|||
</source> |
|||
* Use <code>{{kb|Ctrl-C}}</code>. Here with a fix to prevent the cursor to move one character on the left |
|||
<source lang=vim> |
|||
"--- C-C ---------- |
|||
" C-C : Same as ESC, with an additional fix to prevent cursor move -- Note that ESC does move the cursor |
|||
inoremap <C-C> <Esc>`^ |
|||
</source> |
|||
* (No longer used) — Use <code>{{kb|Ctrl-Space}}</code>. |
|||
<source lang=vim> |
|||
"--- C-Space ------ ###DISABLED###. C-Space used for snippet completion instead. |
|||
" C-Space: NORMAL --> ESC any prefix keys |
|||
" C-Space: VISUAL --> ESC any selection (gV is required to prevent automatic reselection) |
|||
" C-Space: OPERATOR --> ESC any operator pending commands (like y) |
|||
" C-Space: INSERT --> ESC insert mode and `^ restore cursor position (cursor does not move left) |
|||
" (S-Space only works in GUI, see http://vim.wikia.com/wiki/Avoid_the_escape_key) |
|||
" nnoremap <nul> <Esc> (disabled, conflicts with cscope shortcuts) |
|||
" vnoremap <nul> <Esc>gV |
|||
" onoremap <nul> <Esc> |
|||
" inoremap <nul> <Esc>`^ |
|||
</source> |
|||
* Use {{kb|Alt-L}}, or any other Alt combination w/o side effect, since on most terminal Alt-key are sent as ESC-key. |
|||
=== Navigate <code>#ifdef</code> === |
|||
* Possibly install some plugins. None good found so far. |
|||
* Use the standard map {{kb|[#}} and {{kb|]#}} to navigate between <code>#ifdef</code>, and also {{kb|%}} to cycle through them [http://stackoverflow.com/questions/8601280/in-vim-how-to-check-the-ifdef-macro-i-am-currently-inside]. |
|||
=== Using filetype (detection, plugins...) === |
|||
Reference: |
|||
* <code>help filetype</code> |
|||
Some commands: |
|||
<source lang=vim> |
|||
:filetype " Print file type status |
|||
:filetype detect " Detect file type again |
|||
:echo &ft " Print current file type |
|||
</source> |
|||
;Detection |
|||
See <code>help new-filetype</code>. There are 4 methods: |
|||
# Create a new <code>autocommand</code> and write this in a new file (e.g. {{file|~/.vim/ftdetect/mine.vim}}. This will overrule default file type checks. |
|||
# Same as above, but use <code>setfiletype</code> to set the file type. This will set the filetype only if no file type was detected yet. |
|||
# If type can be detected from file name, create a new <code>autocommand</code> (in a <code>augroup</code>), and save it in file {{file|~/.vim/filetype.vim}}. This will be sourced before default file type detection. |
|||
# If type can only be detected by inspecting file content, create a vim script named {{file|~/.vim/scripts.vim}}. This will be sourced before {{file|$VIMRUNTIME/scripts.vim}}. |
|||
;Plugins |
|||
See <code>help filetype-plugins</code>. |
|||
When filetype was detected, vim will look for available filetype plugins to set options and mappings local to the current buffer. There are 3 ways to create or update an existing filetype plugin: |
|||
# Add a few settings before the default plugin. For this create a file in {{file|~/.vim/ftplugin}} (for instance {{file|~/.vim/ftplugin/fortran.vim}}). |
|||
# Copy existing plugin. This will prevent default plugin to load. |
|||
# Overrule the default plugin. For this create a file in {{file|~/.vim/after/ftplugin}} (for instance {{file|~/.vim/after/ftplugin/fortran.vim}}) |
|||
Note that vim looks for all plugins in <code>runtimepath</code> that match the filetype name, '''with an optional underscore and suffix''' (e.g. {{file|fortran.vim}}, {{file|fortran_custom.vim}}). |
|||
;Debug |
|||
Start vim with <code>vim -V2</code>. Look for strings like <code>Searching for "plugin/**/*.vim" in ~</code>. |
|||
=== Compare files in Vim === |
|||
References: [http://unix.stackexchange.com/questions/1386/comparing-two-files-in-vim stackexchange.com], [http://vimcasts.org/episodes/comparing-buffers-with-vimdiff/ vimcast.org]. |
|||
<source lang="vim"> |
|||
:edit file1 |
|||
:vsplit file2 |
|||
:windo diffthis " Start diff between both v-splits |
|||
:windo diffoff " Stop diff |
|||
</source> |
|||
=== Indenting === |
|||
To use an indent program that is configurable via environment variable <code>INDENT</code>: |
|||
<source lang=vim> |
|||
if exists('$INDENT') |
|||
nnoremap <silent><leader>= :call IndentBuffer()<CR> |
|||
endif |
|||
function! IndentBuffer() |
|||
let cursor_position = getpos('.') " Save the current cursor position |
|||
silent exe "%!$INDENT 2>/dev/null" |
|||
if v:shell_error |
|||
undo |
|||
endif |
|||
call setpos('.',cursor_position) " Restore the previous cursor position. |
|||
endfunction |
|||
</source> |
|||
Otherwise, use <code>equalprg</code>. By using a filetype auto-command, we can specify the file language to indent program [https://vi.stackexchange.com/questions/616/how-can-i-specify-a-command-line-command-with-options-as-an-equalprg]: |
|||
<source lang=vim> |
|||
set equalprg=~/etc/indent.sh |
|||
autocmd FileType cpp setlocal equalprg=~/etc/indent.sh\ -l\ CPP |
|||
nnoremap <silent><leader>= mzgg=G`z |
|||
</source> |
|||
=== Determine the highlight group under the cursor === |
|||
<source lang=vim> |
|||
" --- :HL -------------------------------------------------------------------------------------{{{ |
|||
" Determining the highlight group that the word under the cursor belongs to ([http://mysite.verizon.net/astronaut/vim/index.html#Tags]) |
|||
command! -bar -nargs=0 HL echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">" |
|||
</source> |
|||
=== Print to PDF === |
|||
;Linux |
|||
On Linux, print to file to generate a PS file: |
|||
<source lang="bash"> |
|||
:hardcopy > myfile.ps " or :ha > myfile.ps |
|||
</source> |
|||
Then in bash: |
|||
<source lang="bash"> |
|||
ps2pdf myfile.ps |
|||
</source> |
|||
;Windows |
|||
On windows, simply call <code>:hardcopy</code>: |
|||
<source lang="vim"> |
|||
:hardcopy |
|||
</source> |
|||
This will trigger the printer dialog. |
|||
On Windows, one call also change the printer font: |
|||
<source lang="vim"> |
|||
set pfn=Fantasque_Sans_Mono:h10:cANSI |
|||
</source> |
|||
=== Set <code>path</code> for <code>gf</code> (goto-file) === |
|||
{{kb|gf}} in vim opens the file whose name is under the cursor. By default vim looks into the current directory, but we can specify a list of directories to look into: |
|||
<source lang="vim"> |
|||
let &path.="src/include,/usr/include/AL," |
|||
</source> |
|||
One can also give an expression to transform any string into filename. For instance, for java [http://www.alexeyshmalko.com/2014/using-vim-as-c-cpp-ide/]: |
|||
<source lang="vim"> |
|||
set includeexpr=substitute(v:fname,'\\.','/','g') |
|||
</source> |
|||
=== Capture output of an ex command === |
|||
<source lang="vim"> |
|||
:redir @a |
|||
:map " The captured command |
|||
:redir END |
|||
</source> |
|||
Now content of command <code>:map</code> is in register <code>"a</code>. |
|||
=== Diff two files === |
|||
See also Vimdiff section above. |
|||
Open both files, in separate windows. Then: |
|||
<source lang="vim"> |
|||
:diffthis " In first window |
|||
:diffthis " In second window |
|||
</source> |
|||
Alternatively, run: <code>:windo diffthis</code>. |
|||
This should trigger diff mode, folding of unchanged section, and synchronize scrolling of both windows |
|||
To stop diff: |
|||
<source lang="vim"> |
|||
:diffoff! " Stop diff mode |
|||
</source> |
|||
To ignore whitespaces: |
|||
<source lang="vim"> |
|||
set diffopt+=iwhite |
|||
</source> |
|||
=== Processing Input - Insert output of external command === |
|||
* Reference: http://vim.wikia.com/wiki/Use_filter_commands_to_process_text. |
|||
<source lang="vim"> |
|||
:r !ls " read output from running ls, after current line |
|||
:0r !ls " after line 0 (before first line) |
|||
:-r !ls " before current line ("-" is ".-1") |
|||
:r !dir " use 'dir' on Windows |
|||
</source> |
|||
=== Processing Input - Filter (pipe) buffer to external command === |
|||
We use <code>!pgm</code> to call an external program. To pipe the current buffer to that program, just prefix the command with <code>%</code>: |
|||
<source lang="vim"> |
|||
:%!sort -u " Sort current buffer and remove duplicates |
|||
</source> |
|||
Prefix with a dot <code>.</code> to only filter the current line: |
|||
<source lang="vim"> |
|||
:.!sed 's/0/-/' " Replace all zeroes with - on current line |
|||
</source> |
|||
Pressing {{kb|!}} when in ''visual'' mode, apply the filter on the current selection. This is the same as: |
|||
<source lang="vim"> |
|||
:'<,'>!sed 's/0/-/' " Replace all zeroes with - on current selection |
|||
</source> |
|||
As a rule {{kb|!}} works as an operator, and hence works with motion as well: |
|||
<source lang="vim"> |
|||
!}sort " sort from cursor to end of paragraph |
|||
3!}sort " same, 3 paragraphs |
|||
3!!sort " sort 3 lines |
|||
</source> |
|||
=== Save and restore a mapping === |
|||
See [https://vi.stackexchange.com/questions/7734/how-to-save-and-restore-a-mapping/7735 stackexchange]: |
|||
<source lang=vim> |
|||
let map_save = maparg('<C-c>', 'n', 0, 1) |
|||
" do some stuff which changes the mapping |
|||
exe (map_save.noremap ? 'nnoremap' : 'nmap') . |
|||
\ join(map(['buffer', 'expr', 'nowait', 'silent'], 'map_save[v:val] ? "<" . v:val . ">": ""')) . |
|||
\ map_save.lhs . ' ' . |
|||
\ substitute(map_save.rhs, '<SID>', '<SNR>' . map_save.sid . '_', 'g') |
|||
</source> |
|||
=== Edit a macro === |
|||
Two methods [https://robots.thoughtbot.com/how-to-edit-an-existing-vim-macro]: |
|||
;Editing the macro register in a buffer: |
|||
* {{kbkey|"qp}} paste the contents of the register to the current cursor position |
|||
* Edit the macro as necessary |
|||
* {{kbkey|"qy$}} (and '''NOT''' {{kb|"qyy"}} which adds an extra newline) to yank the modified macro back into the q register |
|||
* {{kbkey|dd}} delete the pasted register from the file your editing |
|||
;Editing the macro register in the command line: |
|||
* <code>:let @q='</code> open the q register |
|||
* {{kbkey|<C-r><C-r>q}} paste the contents of the q register into the buffer |
|||
* Edit the macro as necessary |
|||
* <code>'</code> add a closing quote, and {{kb|Enter}} to finish editing the macro. |
|||
=== Fix spelling errors automatically === |
|||
The following mapping will fix the last spelling error automatically [https://castel.dev/post/lecture-notes-1/]: |
|||
<source lang="vim"> |
|||
" C-l : Auto-correct last mispelled word (https://castel.dev/post/lecture-notes-1/) |
|||
inoremap <C-l> <c-g>u<Esc>[s1z=`]a<c-g>u |
|||
</source> |
|||
The change can be undone with {{kb|u}} as necessary. |
|||
This requires to enable and configure the spellcheck: |
|||
<source lang="vim"> |
|||
setlocal spell |
|||
set spelllang=nl,en_gb |
|||
</source> |
|||
=== Persistent session === |
|||
Using <code>:mksession</code> one can save the current session state for later: |
|||
<source lang="vim"> |
|||
" Save session in Session.vim |
|||
:mksession |
|||
" Save session in lastsession.vim |
|||
:mksession lastsession.vim |
|||
</source> |
|||
For ease add the following lines at the end of our <tt>project.vim</tt>: |
|||
<source lang="vim"> |
|||
set sessionoptions+=blank,buffers,curdir,folds,help,options,resize,tabpages,winpos,winsize |
|||
source ./Session.vim |
|||
</source> |
|||
Now start editing with: |
|||
<source lang="bash"> |
|||
gvim -S project.vim |
|||
</source> |
|||
And before quiting Vim, do: |
|||
<source lang="vim"> |
|||
" Overwrite! Session.vim and quit |
|||
:mksession! |
|||
:wqa |
|||
</source> |
|||
This can be done automatically (see [http://vim.wikia.com/wiki/Very_basic_session_persistence]). Add to your configuration file either of these autocmd: |
|||
<source lang="vim"> |
|||
" Update the session file only if one already exists |
|||
au VimLeave * if v:this_session != "" | exe "mksession! " . v:this_session | endif |
|||
" Or always save the session file |
|||
au VimLeave * mksession! |
|||
</source> |
|||
=== Edit powershell scripts with Vim === |
|||
See [https://robindouglas.uk/powershell/vim/2018/04/05/PowerShell-with-Vim.html this blog post]. |
|||
== Language tips == |
|||
=== C/C++ (IDE) === |
|||
Principle: |
|||
* Use plugin '''TagList''' to get list of identifiers. |
|||
* Use plugin '''mcf-make-target''' (to build any target from within Vim). |
|||
* Use tip on ''persistent session''. |
|||
Thanks to plugin ''TagList'', it is possible to turn Vim into a simple yet efficient development IDE. The basic idea is to use the ''TagList'' window as a simple file explorer. We use a ''session file'' to add all files in the project to the ''TagList'' window. For C/C++ projects, we add our common settings/mapping defined in our <tt>cpp.vim</tt>. |
|||
Here an example session file <tt>project.vim</tt>: |
|||
<source lang="vim"> |
|||
" Project specific settings |
|||
set tags=./tags |
|||
TlistAddFiles src/*.cpp |
|||
TlistAddFiles src/*.h |
|||
" Source our custom cpp script |
|||
source ~/.vim/cpp.vim |
|||
" Session Persistence |
|||
au VimLeave * mksession! |
|||
set sessionoptions+=blank,buffers,curdir,folds,help,options,resize,tabpages,winpos,winsize |
|||
" Find in files |
|||
command! GREP :execute "grep -R <cword> ./src"|:cw |
|||
source Session.vim |
|||
</source> |
|||
Create the tag and cscope files: |
|||
<source lang="bash"> |
|||
ctags -R . |
|||
cscope -Rb |
|||
</source> |
|||
Then start the IDE session with: |
|||
<source lang="bash"> |
|||
gvim -S project.vim |
|||
</source> |
|||
Alternatively, one can use the filename <tt>Session.vim</tt>, and use the shorter command <code>gvim -S</code>. |
|||
Use the mappings {{kb|A-Up}} / {{kb|A-Down}} to switch the current window to the next/previous file. These mappings simply move and center the cursor in the ''TagList'' window to the previous/next file, open the file and put the cursor to its last position. |
|||
To build the project (assuming you have a valid <tt>Makefile</tt> in the project directory), just issue the command |
|||
<source lang="vim"> |
|||
:make |
|||
</source> |
|||
Optionally, we can set <code>MAKEFLAGS</code>: |
|||
<source lang="vim"> |
|||
let $MAKEFLAGS="-j" " Enable parallel build |
|||
</source> |
|||
To easily navigate between the compilation errors, open the ''quickfix window'': |
|||
<source lang="vim"> |
|||
" Open the window when there are compilation errors: |
|||
:cw |
|||
" Or open it always: |
|||
:cope |
|||
</source> |
|||
Finally you can run the program directly from Vim with: |
|||
<source lang="vim"> |
|||
:!./bin/myprogram |
|||
"To repeat the last :!{cmd}, do: |
|||
:!! |
|||
</source> |
|||
=== LaTeX (vimtex) === |
|||
See [[vim-tex]]. |
|||
=== LaTeX (vim-latex) - OLD === |
|||
{| class=wikitable width="100%" |
|||
|- |
|||
|'''{{red|Obsolete}}''' |
|||
|We don't use this setup anymore. |
|||
|} |
|||
Before using ''vimtex'', we were using plugin [[Vim-latex]]. |
|||
== To Do == |
|||
* '''Done''' Find a way to prevent vim to mess up with my register when deleting text. |
|||
* Auto-complete, use cursor keys instead of up/down to search in the drop down list. |
|||
* Look at '''Virtual-edit''' (see http://vim.wikia.com/wiki/Add_trailing_blanks_to_lines_for_easy_visual_blocks) |
|||
* Other links: |
|||
: http://www.faqs.org/docs/Linux-HOWTO/C-editing-with-VIM-HOWTO.html |
|||
: http://www.ibiblio.org/pub/linux/docs/howto/translations/nl/onehtml/Vim-HOWTO-NL.html |
|||
* '''{{red|NEW}}''' — Install '''[https://neovim.io/ neovim]'''. |
|||
* '''{{red|NEW}}''' — Install '''[https://ctags.io/ universal ctags]'''. |
|||
* '''{{red|NEW}}''' — Consider installing LSP (language-server protocol) for code completion as in VSCode (see Plugin page). |
|||
* '''{{red|NEW}}''' — <code>set clipboard+=unnamedplus; inoremap <C-V> <C-R>+; vnoremap <C-C> y; cnoremap <C-V> <C-R>+;</code> as alternative for my clipboard mappings. Or apparently, <code>set clipboard^=unnamedplus</code>, which prepends the setting, is more recommended [https://vim.fandom.com/wiki/Accessing_the_system_clipboard]. |
|||
* Look at https://kite.com as autocomplete alternative. |
|||
== Troubleshooting == |
|||
Here several methods to troubleshoot issues. See also the list of known issues for possible fix. |
|||
=== Startup time === |
|||
Use this command to measure Vim startup time [http://stackoverflow.com/questions/1687799/profiling-vim-startup-time], [http://vimzone.pixelblaster.ro/content/fast-fast-fast-with-vim-terminal-256-color-mode]: |
|||
<source lang=bash> |
|||
# Start VIM and exit immediately |
|||
rm -f vim.log && time vi --startuptime vim.log -c 'qa!' && tail vim.log |
|||
# ... or edit a file |
|||
rm -f vim.log && vim --startuptime vim.log SOMEFILE |
|||
</source> |
|||
=== Profiling === |
|||
We run the vim profiler [https://stackoverflow.com/questions/12213597/how-to-see-which-plugins-are-making-vim-slow]: |
|||
<source lang="vim"> |
|||
:profile start profile.log |
|||
:profile func * |
|||
:profile file * |
|||
" At this point do slow actions |
|||
:profile pause |
|||
:noautocmd qall! |
|||
</source> |
|||
=== Key mapping === |
|||
Get the list of mappings, and where they were defined, for instance for the {{kb|tab}} key: |
|||
<source lang="vim"> |
|||
:verbose imap <tab> |
|||
</source> |
|||
== Known issues == |
|||
=== Mapping portability === |
|||
* {{kb|C-,}} only available to win32 gvim, not to cygwinX gvim. |
|||
=== Memory leaks === |
|||
* Command <code>syn match</code> may create memory leaks which slowly impact performance. Do the following as temporary fix (from [http://vim.wikia.com/wiki/Highlight_unwanted_spaces]): |
|||
<source lang="vim"> |
|||
autocmd BufWinLeave * call clearmatches() |
|||
</source> |
|||
=== Slow cursor move (vertical / horizontal) === |
|||
* references: [http://en.reddit.com/r/vim/comments/fdwax/just_a_reminder_cursorline_and_relativenumber/], |
|||
* Can be due to ''cursorline''. Try <code>set nocursorline</code>. Also remove any occurence of <code>highlight CursorLine ...</code> |
|||
* Can be due to ''cursorcolumn''. Try <code> set nocursorcolumn</code>. Also remove any occurence of <code>highlight CursorColumn ...</code> |
|||
* Can be due to slow ''matchparen''. Add to <tt>.vimrc</tt>: |
|||
<source lang="vim"> |
|||
let loaded_matchparen = 1 |
|||
set noshowmatch |
|||
</source> |
|||
* Can be improved with <code>set lazyredraw</code> |
|||
=== Meta - characters <M-x> (aka <Alt-x>) not working in console === |
|||
* Add the following to {{file|.vimrc}}, where <code>^[x</code> is obtained with {{kb|C-v}}{{kb|C-x}} (from [http://tex.stackexchange.com/questions/53692/m-i-mapping-not-working-in-vim-latexsuite-on-linux] and [http://vim.wikia.com/wiki/Get_Alt_key_to_work_in_terminal]): |
|||
set <M-x>=^[x |
|||
:Note, this may also require the following in the shell console: |
|||
set convert-meta on |
|||
:Although my current settings below also work it seems: |
|||
set meta-flag on |
|||
set convert-meta off |
|||
set input-meta on |
|||
set output-meta on |
|||
:Another solution is to set the terminal in 8-bit mode as suggested in the link. This is however not possible with ''Gnome-terminal''. A more advanced solution use a timeout to allow distinguishing between {{kb|M-x}} and {{kb|Esc}}{{x}} [http://stackoverflow.com/questions/6778961/alt-key-shortcuts-not-working-on-gnome-terminal-with-vim]: |
|||
<source lang=vim> |
|||
let c='a' |
|||
while c <= 'z' |
|||
exec "set <A-".c.">=\e".c |
|||
exec "imap \e".c." <A-".c.">" |
|||
let c = nr2char(1+char2nr(c)) |
|||
endw |
|||
set timeout ttimeoutlen=50 |
|||
</source> |
|||
Or use the following to have timeout only for keycodes and not other mappings: |
|||
<source lang=vim> |
|||
set ttimeout ttimeoutlen=50 |
|||
</source> |
|||
=== Terminal issues === |
|||
* [https://sunaku.github.io/vim-256color-bce.htm Fixing Vim's Background Color Erase for 256-color tmux and GNU screen] |
|||
=== Cannot unmap a mapping (no such mapping) === |
|||
<code>:map A</code> gives |
|||
A *@g$a |
|||
Trying to remove with <code>:unmap A</code>, we get the error |
|||
E31: No such mapping: |
|||
In fact the mapping is buffer local (see <code>:h E1</code>), and we need to remove it with |
|||
<source lang="vim"> |
|||
:unmap <buffer> A |
|||
</source> |
|||
=== Bugs === |
|||
* [2010-07-22] - (to bugs@vim.org) 'winfixheight' not honored when botright split is closed. |
|||
{{hiddenSourceFile| ./|wfh-bug.vim|content=<source lang="vim" class="wfh-bug.vim"> |
|||
30 vnew |
|||
wincmd l |
|||
insert |
|||
We will open an horizontal split below, with wfh option set |
|||
Then we open a botright split, and close it immediately |
|||
Normally this window should recover its initial height, but if there is a vertical |
|||
split on the left, this window will be smaller |
|||
. |
|||
go |
|||
belowright 5 new |
|||
set wfh |
|||
insert |
|||
This window should only be 5 lines in height. |
|||
But it will be taller after closing the botright split if there is a vertical split |
|||
on the left |
|||
. |
|||
go |
|||
wincmd k |
|||
botright 10 split |
|||
q |
|||
</source>}} |
|||
* [2011-07-27] - infinite loop when using :bn after a :edit dir/ (breaks plugin minibufexpl.vim) |
Latest revision as of 10:00, 17 July 2023
This page is about the editor Vim itself. The other related pages are
- Vimrc, dedicated to vim configuration settings and to the file ~/.vimrc.
- Vim plugins, dedicated to Vim plugins.
- Neovim, dedicated to NeoVim, a new port of Vim.
References
Things to look at
- Use Ctrl-C or Alt-L as ESC replacement.
- NeoVim fast setup:
- kitty Cross-platform, fast, feature-rich, GPU based terminal, with support for hyperlinks, image viewer.
- tree-sitter An incremental parsing system for programming tools
- Goes along with nvim-treesitter
- ale — Check syntax in Vim asynchornously and fix files, with Language Server Protocol (LSP) support.
- null-ls Use Neovim as a language server
- nvim-lspconfig Quickstarts configs for Nvim LSP, suggested by Neovim project.
- coc.nvim — Conquer of Completion (maybe older tech, but still maintained).
- kickstart.nvim — A launch point for personal nvim configuration.
- Mason A portable package manager (LSP, DAP...)
- Comments on HN
External links
- General
- Official vim homepage
- Vim Tips Wiki
- Vim documentation: map
- My links on vim on del.icio.us
- List of all commands for each mode:
:help index
- Vi clones or inspired
- General - Vim Help
- Vim documentation: help
- Built-in help:
" Get help on a command
:h map
" Get help on a mapping, NORMAL or INSERT mode
:h CTRL-R
:h i_CTRL-R
- Other General
- Vi Lovers home page
- Why, oh WHY, do those #?@! nutheads use vi? — explains why vi is superior and defeats common misconceptions (with examples).
- Vi would not be vi without a bit of fun...
- vimsf discussion forum
- Cheat sheets
- Very good graphical keyboard cheatsheet
- Another compact & complete cheatsheet (as folded reference card).
- Real Short Vim Normal-Mode List of Commands (from Dr Chip's)
- Productivity & Setup Guides
Get the best Vim configuration
- NEW — best of Vim
- NEW — Level up your workflow with Vim and Tmux
- NEW — How I'm able to take notes in mathematics lectures using LaTeX and Vim — Gilles Castel
Tuned for Neovim
- NEW — A guide to neovim
- Guides & Cheat sheets
- New To Vim
- Quick Tips
- Avoiding the ESC key
- Vim map tutorial
- Dr Chip's Vim Page — A tremendous amount of Vim treasures from an expert user
- Efficient editing with vim (link dead, wayback machine, mirror)
- C editing with VIM HOWTO
- Using vim as an IDE all in one
- Browsing programs with tags
- Using Bash completion with ctags and Vim
- Alternative tab navigation
- Seven habits of effective text editing (from author of Vim)
- Scripting the Vim editor, Part 1: Variables, values, and expressions (a great introduction to Vim scripting)
- NEW — Turn Vim & Tmux into an IDE like environment
- Uses ^h ^j ^k ^l to navigate between pane (also in Tmux apparently)
- Tips: Use CapsLock as ESC, Copy Paste, Tab movements, Relative numbering
- Plugins: NERDTree, Ctrl-P, Surround.vim, Comments, Snippets, Vim Wiki
- ColbyCheeze dot files
- NEW — Vim as XML Editor
- Vim in Windows/Cygwin
- Use cygwin shell
- Running the Win32 version of Vim from Cygwin
- viEmu — vim for Word, Outlook, Visual Studio...
- cyg-wrapper.sh
- FAQ / 33.6 What are the recommended settings for using Vim with cygwin?
- Using Cygwin Bash as your Win32-Vim shell
- A patch to use Win32 clipboard under Cygwin ([1], [2])
- Tips
- Use Ctrl-O instead of Esc in insert mode mappings
- How do I indent multiple lines quickly in vi?
- Replace a word with yanked text
Here we learn that Deleting, Changing and Yanking text copies the affected text to unnamed buffer ("").
But Yanking text also copies the text to buffer 0 ("0) - Search and replace the word under the cursor
- Find in files within Vim
About commands:grep
,:lgrep
,:vimgrep
,:lvimgrep
- Power of g
Examples on how to use the command:rg/pattern/cmd
- Keystroke Saving Substituting and Searching
- Quickly adding and deleting empty lines
- Very basic session persistence
Using mksession! and :au VimLeave... - Automatically fitting a quickfix window height
- Highlight unwanted spaces
- Using Vim's tabs like buffers
:set hidden
to have vim behave like any other multi-file editors.- Use
:bn
,:bp
,:b #
,:b name
, ^6 and #^6 to switch between buffers. ^6 are very useful to switch to previously used buffer (or #^6 to switch to buffer#
). - Use
:ls
to list buffers.
- Vimrc examples
- https://github.com/mitechie/pyvim (author of the screencast on LustyJuggler)
- https://github.com/colbycheeze/dotfiles
- Use vim-plug to manage plugins.
Vim help
- Help on mappings
- For mapping like <C-U> (ie. <Ctrl-U>):
:h CTRL-U
- For mapping like <C-G>u:
:h CTRL-G_u
(not the same as:h CTRL-G_U
). - For mapping like <C-G>u in insert mode:
:h i_CTRL-G_u
Related projects
Universal ctags
A maintained version of exuberant ctags.
First uninstall exuberant-ctags if installed:
sudo apt-get remove exuberant-ctags
To build (see docs/autotools.rst):
git clone https://github.com/universal-ctags/ctags.git
cd ctags
./autogen.sh
./configure
make
sudo make install
Install
Building from Sources
See
Invocation
vi -p file1.txt file2.txt # Open each file in a different tab
vi -t tagname # Open file and move cursor at specified tag (requires ctags)
view file.txt # View file in vim, with syntax highlighting... (read-only)
vimdiff file1.txt file2.txt # View differences in vim
The following is a description of the start up sequence as I understood by experience. It's certainly far from complete. For more information:
:version
:echo $HOME
:echo $VIM
:set runtimepath?
:help vimrc
:help gvimrc
:help runtimepath
- First, load the system config files:
- Second, load the user config files:
- Search for runtime files in path 'runtimepath'. Basically vim looks for directories in that path for further runtime files to execute (see
:help runtimepath
for more information)
File | description | OS | Location |
---|---|---|---|
vimrc | System config file for vim and gvim | Unix & Win | $VIM/vimrc |
gvimrc | System config file for gvim only | Unix & Win | $VIM/gvimrc |
File | description | OS | Location |
---|---|---|---|
vimrc | User config file for vim and gvim | Unix | $HOME/.vimrc |
Win | $HOME/_vimrc | ||
gvimrc | User config file for gvim only | Unix | $HOME/.vimrc |
Win | $HOME/_vimrc |
Using vimdiff
Invoke vimdiff with
vimdiff file1.txt file2.txt
One can tell vim to ignore case or whitespaces with:
" Ignore case differences
:set diffopt+=icase
" Ignore white space differences
:set diffopt+=iwhite
" Tell vim to redo comparison (in case file was edited)
:diffupdate
Plugins
See Vim plugins.
Vim on Windows
- Tab Edit with &Vim — The following registry setting add a context menu item in explorer to open a file in a new tab in a running instance of gvim (see [3]):
REGEDIT4
[HKEY_CLASSES_ROOT\*\Shell\Tab Edit with &Vim\command]
@="\"C:\\Program Files\\vim\\vim71\\gvim.exe\" -p --remote-tab-silent \"%1\" \"%*\""
- Best solution however is to use the gvim explorer menu extension, which offers much more functionality (see NXL67170).
- Share config with Cygwin
- To have win32 gvim and cygwin vim, use the same config files. Simply define the env. var HOME to point to user home in cygwin:
HOME=c:\cygwin\home\username
- Create the file C:\Program Files\Vim\vimrc (system vimrc file for windows)
set runtimepath-=~/vimfiles
let tmp=&runtimepath
let &runtimepath="~/.vim,".tmp
Win32 gvim will read the standard configuration files .vimrc and .gvimrc (although this is not reported by :version
). It will also fetch the plugins from cygwin home directory.
- Detect windows in vimrc script
- Use
has('win32')
or alike:
if has('win32')
echo "Windows (32 or 64 bits)"
endif
if has('win32unix')
echo "Cygwin"
endif
if has('unix')
echo "linux"
endif
if has('macunix')
echo "Mac"
endif
- Enable Ruby support
- There is a bug in Vim7.3_46 that crashes vim when ruby is loaded. This is fixed in a later release [1]. Install:
- Latest Vim from Cream (currently Vim 7.3.260)
- This version of Vim requires Ruby 1.8.x (and not Ruby 1.9.1 as indicated in :help ruby).
Download ruby-1.8.7-p330-i386-mswin32.zip from here, and install it in C:\RUBY.
Add C:\RUBY\bin to system path (before cygwin!)
- Save .vimrc in utf-8 format *with* BOM
- Vim Windows will default to Iso8859 encoding on windows. By adding the BOM to .vimrc file, it'll ensure that both Vim Linux and Vim Windows will use the same encoding to read the configuration file (relevant in case you have special character in .vimrc)
- Use Caps Lock as Escape key
- Import the following in the registry then logout/logon:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,46,00,01,00,3a,00,00,00,00,00
- To restore old behavior:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,46,00,01,00,3a,00,00,00,00,00
Check also potential goodies Vi#Vim_in_Windows.2FCygwin above.
Configuration
Color schemes
- Solarized (truecolor) — Git plugin, my fork.
- My current favorite scheme, cheerful colors. But I would like to increase the contrast for the main text.
- Gruvbox (truecolor)
- A truecolor color scheme.
Tabs and indent
"#### Indentation ########################################
set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab
set autoindent " Indent is based on the previous line
" set smartindent " Same as above but also recognize some C syntax
" set cindent " Even clever C indent mode
" set cinkeys=0{,0},:,0#,!,!^F " For cindent - specifies which keys trigger reindenting
Or shorter:
set ts=4 sts=4 sw=4 noet
Cursor shape and mode
By default, the cursor shape depends on the UI:
- In TUI, cursor is always has a block shape.
- In GUI (
gvim
), cursor is either a blinking block (normal mode), or a blinking caret (insert mode).
In TUI, we can configure the cursor for terminals that support it:
- Under tmux, using escape sequences [4]. Add to .vimrc:
" set the cursor to a vertical line in insert mode and a solid block
" in command mode
let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\"
" upon hitting escape to change modes, send successive move-left and move-right
" commands to immediately redraw the cursor
inoremap <special> <Esc> <Esc>hl
" don't blink the cursor
set guicursor+=i:blinkwait0
- Finally, in tmux.conf:
# don't wait for an escape sequence after hitting
# Esc. fixes insert mode exit lag in vim
set -sg escape-time 0
Managing Options
See :help options
for more details
"Show all options that differ from default
:set
"Show value of {option}
:set {option}?
"Set {option} to value
:set {option}={value}
"Add value to {option}
:set {option}+={value}
Scripting
Variables, environment variables and options
Some basic stuff on Vim scripts:
" Use LET for VARIABLES
let myvar="Hello"
echo myvar
let myvar=call func(param1,param2)
" Use SET for OPTIONS
set runtimepath=~/.vim " SET option"
set runtimepath? " GET option"
" We can use LET with &{OPTIONS}
let myvar='batch'
let &filetype=myvar " &{option} returns option value in an expression"
echo &filetype
if &filetype == 'java'
...
endif
" But these does not give the same:
set runtimepath? " No expansion within runtimepath (eg. replace ~ with /home/...)"
echo &runtimepath " Expansion occurs with runtimepath"
" Another example, use variable to prepend a path to runtimepath:
set runtimepath-=~/vimfiles
let tmp=&runtimepath
let &runtimepath="~/.vim,".tmp
Use let
to edit environment variables:
let $MAKEFLAGS="-j1" " Set env. var MAKEFLAGS - force sequential build
Expressions
See :h expression-syntax
for more.
|expr1| expr2 ? expr1 : expr1 if-then-else
|expr2| expr3 || expr3 .. logical OR
|expr3| expr4 && expr4 .. logical AND
|expr4| expr5 == expr5 equal
expr5 != expr5 not equal
expr5 > expr5 greater than
expr5 >= expr5 greater than or equal
expr5 < expr5 smaller than
expr5 <= expr5 smaller than or equal
expr5 =~ expr5 regexp matches
expr5 !~ expr5 regexp doesn't match
expr5 ==? expr5 equal, ignoring case
expr5 ==# expr5 equal, match case
etc. As above, append ? for ignoring case, # for
matching case
expr5 is expr5 same |List| instance
expr5 isnot expr5 different |List| instance
|expr5| expr6 + expr6 .. number addition or list concatenation
expr6 - expr6 .. number subtraction
expr6 . expr6 .. string concatenation
|expr6| expr7 * expr7 .. number multiplication
expr7 / expr7 .. number division
expr7 % expr7 .. number modulo
|expr7| ! expr7 logical NOT
- expr7 unary minus
+ expr7 unary plus
|expr8| expr8[expr1] byte of a String or item of a |List|
expr8[expr1 : expr1] substring of a String or sublist of a |List|
expr8.name entry in a |Dictionary|
expr8(expr1, ...) function call with |Funcref| variable
|expr9| number number constant
"string" string constant, backslash is special
'string' string constant, ' is doubled
[expr1, ...] |List|
{expr1: expr1, ...} |Dictionary|
&option option value
(expr1) nested expression
variable internal variable
va{ria}ble internal variable with curly braces
$VAR environment variable
@r contents of register 'r'
function(expr1, ...) function call
func{ti}on(expr1, ...) function call with curly braces
Process control
if filereadable("foo.cfg") " Boolean"
" ...
endif
while lnum <= line("$") " Number - other tests are =, !=, <=, >="
call FixLine(lnum)
let lnum = lnum + 1
endwhile
if $ENV_VAR != "" " String"
echo $ENV_VAR
endif
" FOR with LISTS
for item in ["foo", "bar"]
echo item
unlet item " E706 without this"
endfor
for item in ["foo", ["bar"]]
echo item
unlet item " E706 without this because different item types
endfor
for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
echo getline(lnum)[col]
endfor
Handy functions
(see :h functions
for complete list)
glob("/foo/bar") " String, extension file wildcard (here as file existence test)"
filereadable("foo.cfg") " Number, TRUE if file readable"
Testing version, options and features
Some examples for testing Vim version, and option/feature availability [5]:
if v:version < 703 " Exit if Vim version 7.3 or less
finish
endif
" Plugin goes here.
" Avoid installing twice or when in unsupported Vim version.
if exists('g:loaded_pluginname') || (v:version < 700)
finish
endif
let g:loaded_pluginname = 1
To test whether an option/feature is available
exists('+relativenumber') " Is option relativenumber available?
has('python') " Is feature python supported?
How-to
- Test for quickfix buffer
&filetype == 'qf' " Test filetype
&buftype ==# 'quickfix' " Test buftype
Frequent caveats
- Don't confuse variables and options.
- Variables are initialized with let, options with set. Options can be read/written like a variable with prefix &, like &filetype.
- Don't confuse functions (like
max
,strlen
), with editor commands (like let, set, call).
- Functions can be called directly in expression, but must be called with command call where commands are expected.
add(list,10) " WRONG! add is not an editor command
list2=add(list,10) " CORRECT
call add(list,10) " CORRECT
- Give regular expression patterns in single-quotes!
echo match("binary(blob)","b\|(",0) " WRONG!
echo match("binary(blob)",'b\|(',0) " CORRECT
Mappings
- Mouse mappings requires
:set mouse=a
.
View mappings
List mappings:
:map
:map!
List mappings, with origin:
:verbose map
:verbose map!
Define new mapping
- Note that not all combinations are possible (see [6] and
help :keycodes
)- S-b and S-B are the same
- C-b and C-b (both mean 0x02)
- A-b and A-B are different, but are represented by vim by setting the high bit (0x80), so A-b is same as 'â', and A-B is same as 'Â'
- Note that GUI Vim some Alt key shortcuts select the menu. To disable that:
set guioptions-=m
Cheatsheets
Custom mappings are underlined.
Custom Cheatsheets
Mappings
^W_ ^W| ^W= |
Max. h/w current window or tile |
MouseL |
Jump to tag |
^U |
Remove auto-range (:help omap-info )Insert register / object ( |
^Space |
Same as Esc, but easier (see [7]) |
n^O |
Go to n older pos. in jump list |
"ay |
YANK to / paste frmo register a. |
"Ay |
APPEND to register a. |
^^ or ^6 (azerty) |
Edit alternate buffer (#) |
Operators & motions
Operators in Vim acts
- on the current selection (visual mode like v, V or ^v) when there is such a selection,
- or must be followed by a motion indicating which part of the text must be modified.
Operators
|
The motion is either one of the motion key (like >% for shift right until match) or an operator motion (like diB for delete inner {} block). See :help operator.
Frequently-used operator motion
iw iW |
inner word inner WORD |
aw aW |
a word a WORD |
i[ ib i( |
inner [] block inner () block |
a[ ab a( |
a [] block a () block |
i" i' |
inner "" string inner '' string |
a" a' |
a "" string a '' string |
Commands
" Search & replace - current line
:s/search/replace/g
" Search & replace - global scope
:%s/search/replace/g
" Set Vim option (here textwidth)
:set {option}=70
" Show value of {option}
:echo &{option}
:set {option}?
" Search / replace in all opened buffers
:bufdo %s/pattern/substitution/ge | update
" Replace current line with register content
VP
General tips
Practical Vim — Part I: Modes
- Tip 4: Act, Repeat, Reverse —
- Tip 6: Meet the Dot Formula —One keystroke to move, one keystroke to execute (like
A.ESC
thenj.j.j.
,f+s_+_
then;.;.;.
,*cwcopyESC
thenn.n.n.
) - Tip 9: Compose Repeatable Changes — e.g. favor daw instead of dbx or bdw to delete a word, because the former is a single operation, and hence invests the most power into the dot command.
- Tip 13: Make Corrections Instantly from Insert Mode — e.g. use ^h for backspace, ^w for delete word, ^u for delete line.
- Tip 14: Go Back to Normal Mode — use ^[ for Switch to Normal mode, and ^o for Insert Normal mode (e.g. ^ozz).
- Tip 15: Paste from a Register Without Leaving Insert Mode
- use ^r for putting character-wise register, and ^r^o for inserting characters litteraly and without auto-indent
- remap CAPS LOCK (capslock) to something else at system level, either ESC (escape) or CTRL (see Tips section).
- Tip 16: Do Back-of-the-Envelope Calculations in Place — Example a ^r= 6*35 CR
- Tip 17: Insert Unusual Characters by Character Code — ^v123 inserts by decimal code, ^vu1234 inserts by hexadecimal code, ^v non-digit inserts literally, ga returns character code.
- Tip 18: Insert Unusual Characters by Digraph — ^k char1 char2 inserts digraph. See
:h digraphs-default
(convention),:h digraphs
(all digraphs),:h digraph-table
(more usable list). There's also plugin betterdigraphs.vim from Damian Conway. - Tip 19: Overwrite Existing Text with Replace Mode — r, R to replace, Insert to switch mode, gr,gR to replace visually.
- Tip 21: Define a Visual Selection — gv reselect the last visual selection, o go to other end of highlighted text.
- Tip 27: Command-Line Mode — ^v or ^k to insert special character, ^r{register} to insert content of any register.
- Tip 28: Execute a Command on One or More Consecutive Lines — Example of ranges
:1p
,:$p
,:2,5p
,:.,$p
,:%p
,:'<,'>p
,/<html>/,/<\/html>/p
,/<html>/+1,/<\/html>/-1p
,:.,.+3p
(there is also0
for virtual line before first line). - Tip 29: Duplicate or Move Lines Using ':t' and ':m' Commands —
:[range]copy {address}
or:[range]t {address}
for copy,:[range]move {address}
or:[range]m {address}
for move. - Tip 30: Run Normal Mode Commands Accross a Range — Use
:[range]normal {command}
or:[range]norm {command}
. Eg.:%norm .
,:%norm A;
,:%norm i//
. - Tip 31: Repeat the Last Ex Command — Use
@:
and@@
afterwards (last command always stored in:
register). - Tip 32: Tab-Complete Your Ex Commands — Use ^d to view auto-complete list, Tab and S-Tab to cycle through it.
- Tip 33: Insert the Current Word at the Command Prompt — Use ^r^w to insert current word, ^r^a for current WORD.
- Tip 34: Recall Commands from History — Use Up/Down or or ^p/^n to recall command with filtering. Use :q for Command-Line Window (Enter to execute, :q to leave). Use ^f to switch to Command-line window, even while typing a command. Use following mapping to have filtering enabled for ^p/^n:
- Tip 35: Run Commands in the Shell — Use
%
as shorthand for current file name, like:!ruby %
(see :h cmdline-special):shell
runs a shell (in a terminal better use ^z to suspend vim),:!{cmd}
executes a command with the shell,:read !{cmd}
inserts command output at the cursor,:[range]write !{cmd}
executes command with selected text as input,:[range]!{filter}
filters selected text through command.
Make a change | {edit} | . | u |
Scan line for next character | f{char} / t{char} | ; | , |
Scan line for previous character | F{char} / T{char} | ||
Scan document for next match | /patternCR | n | N |
Scan document for previous match | /patternCR | ||
Perform substitution | :s/target/replacement | & | u |
Execute a sequence of changes | qx {changes} q | @x éx |
u |
cnoremap <C-p> <Up>
cnoremap <C-n> <Down>
Practical Vim — Part II: Files
- Tip 36: Track Open Files with the Buffer List —
:ls
to list buffers;:buffer N
or:buffer {bufname}
to jump directly;:bprevious
,:bnext
,:bfirst
and:blast
to navigate through buffers;:bdelete
to delete buffers; and:bufdo
to execute command on all buffers.:write
,:update
and:saveas
to write buffer to disk.
Efficient Editing
- Dot command — See [8] for example.
- Use * to search word under cursor (and # backward) &mdash see also [9] for example.
- Substitute current line — Use S ( or cc) to replace the current line, while keeping current indentation (instead of ddO to delete current line and open new one)
- Rename a variable with ciw for instance, and type the new variable name (use ^R- to start from old name)
- Look for next occurent of the replaced variable with F3 (or ù)
- Repeat replacement with . (dot key)
- Repeat from step 2 (or use n), or N for previous occurrence.
- Quick buffer edit — Use
:b {bufname}
to quickly jumped to buffer referenced by its number (see:ls
) or by its name. Buffer name can be incomplete as long as it is unique (this is very handy!!!). - use ( and ) to move between sentences, ]p paste indented, `. move to last edit (source Efficient editing with vim)
- Smart ranges and clipboards — (source [10])
- Starting from cursor position above , type c% and equivESC, and then Obool equiv = C-R";ESC to get the result below.
- Syntax folding — Enable automatic folding for javascrip, PHP, XML, ... [11] . Add to .vimrc:
- Use Caps Lock as another Escape (ESC) key. On Linux, see X#Configuring_Layout_Options. Basically we update gnome settings for current user:
" F3 (an improved UltraEdit F3 ;-) ) search for next occurrence of replaced word (actually register -) - handy for refactorizing code
" Also mapped to ù (AZERTY power!)
nnoremap <F3> /\<<C-R>-\><CR>
nnoremap ù /\<<C-R>-\><CR>
Using this mapping, one can:
This tip works better than using range:s/pattern
, because you don't have to type the name of replaced variable, nor use the word delimiter \<
...\>
, and you don't have to specify a range in advance.
if (!entry.used && |equivalent(entry.key(), qk.key) && (curcontext & entry.contexts))
bool equiv = equivalent(entry.key(), qk.key);
if (!entry.used && equiv && (curcontext & entry.contexts))
set foldmethod=syntax
set foldlevelstart=1
let javaScript_fold=1 " JavaScript
let perl_fold=1 " Perl
let php_folding=1 " PHP
let r_syntax_folding=1 " R
let ruby_fold=1 " Ruby
let sh_fold_enabled=1 " sh
let vimsyn_folding='af' " Vim script
let xml_syntax_folding=1 " XML
# https://stackoverflow.com/questions/32154285/folding-expanding-and-colapsing-xml-tags-in-vim-xml-parsing
au FileType xml setlocal foldmethod=syntax
au FileType xslt setlocal foldmethod=syntax
gsettings get org.gnome.desktop.input-sources xkb-options
gsettings set org.gnome.desktop.input-sources xkb-options "@as ['caps:escape']"
On Windows, see Map caps lock to escape in Windows. Import the registry file (Win7/Win8):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,46,00,01,00,3a,00,00,00,00,00
Modeline
Use modeline to embed vim format settings in the document itself. This requires the following line in ~/.vimrc:
set modeline
The format of the modeline is (see help modeline
for more variants):
[text] vim:{options}
[text] vim: set {options}:
Now you can for instance for automatic word wrapping in a text document by adding the following line to the document (for instance as the last line or within a comment block):
/* vim: set ai fo=tcroq tw=105: */
Alternatively, use the following to disable automatic line break, but still wrap words at word boundaries:
/* vim: set ai fo=tcroq tw=0 wrap linebreak nolist: */
Add spell
to enable background spell checker (e.g. LaTeX document):
/* vim: set ai fo=tcroq tw=105 spell: */ /* vim: set ai fo=tcroq tw=0 wrap linebreak nolist spell: */
- Markdown
Use the following line [12]:
[//]: # ( vim: set tw=105: )
Miscellaneous
- Inserting only a single character (http://vim.wikia.com/wiki/Insert_a_single_character):
- Macro
- qq to start recording a macro q. End macro with q again.
- @q to replay macro, followed by . to replay it again.
- Visual Block
- Ctrl-v to start VISUAL BLOCK mode.
- Shift-I to insert some text at the start of each line of selected block.
- wrap-around
- Set option whichwrap or ww that allows specified keys that move the cursor left/right to move to the previous/next line when the cursor is on the first/last character in the line.
- In Vim, <space> and <backspace> are set to wrap-around by default.
- Read-only viewer (with syntax highlighting):
- Retab To convert tabs in current file to current tab settings, use command
- View differences in vim
- Interaction with X Clipboard vim can use the X clipboard if it has been compiled with the clipboard feature (run
set incsearch
, moves cursor as search pattern is typed. Ctrl-L to type letter under cursor, Ctrl-R Ctrl-W to type current word.- References: http://vim.wikia.com/wiki/Best_Vim_Tips
- type
:help ctrl<C-D>
, to get a list of all ctrl sequence. Type <C-D> in command line for auto-completion. - Support 256 colors in gnome-terminal: add
set t_Co=256
in ~/.vimrc ([14]) - Use
:make
and:grep
instead of:!make
or:!grep
. Then use:cwin
or:copen
to view the results of either make or grep in a coloured list (from [15]). - (from [16]), The
:g
command is useful to apply a command to all lines matching a search. - vim-syntax-extra — C syntax extension, to also highlight C delimiters. Copy as file ~/.vim/after/syntax/c.vim (and ~/.vim/after/syntax/cpp.vim). The previous solution was to use the settings below, but these break code folding with
- Replace a word with yanked text (see tip [17])
- Quickly switch between opened buffers. The commands
:b
and:sb
accepts partial buffer name when specifying which buffer to edit: - Various command to interact with the shell:
- Save a file you edited without the needed permissions (source [18])
- Delete all trailing spaces ([19]):
- Promote window to tab (see [21])
- Find in files within Vim (commands
:grep
,:lgrep
,:vimgrep
,:lvimgrep
)
Define this custom command to quickly look for current word, and displays the quicklist window:
- Use
:E[xplore]
for explore directory of current file (from netrw) - Formatting code with column shell filter. Say you have a code like the one on the left. To align this text, select the 3 lines, then
!column -t
. This will give: - Only english dictionary is available by default. But Vim will automatically download and install the french dictionary with
- Use
set fileencoding=utf-8
to convert a file to unicode UTF-8 format. Vim can also add the BOM (Byte Order Mark) withsetlocal bomb
- Justify text. For instance justifying left-right, with 74-char line (require package par:
- Copy current buffer filename into clipboard:
- Create a new file / directory — Easy with plugin NERDTree. Open NERDTree, then navigate to folder where to create the new file, then press ma. This will create a new file / directory in given node.
:nnoremap <space> :exec "normal i".nr2char(getchar())."\e"<CR>
$ vi -R sensitive_file
$ view sensitive_file
:retab
[13]. For instance to convert tabs into space
:set expandtab
:retab
vimdiff file1.txt file2.txt
vim --version
and see if you have +clipboard in the output). In that case, yanking to the +
register, or simply selecting with the mouse, will actually copy in the X clipboard, hence allowing other applications, or even other instances of vim to exchange text snippets. Also, it will ease the copy-paste of indented text, since in that case, vim will first disable autoindentation before pasting the text (see option paste
).
On system like Ubuntu, you need to install an instance of gvim (like package vim-gnome or vim-gtk) to have feature +clipboard
turned on (i.e. installing package vim is not enough).
When set mouse=a
, use shift-mouse to still use the xterm copy/paste (see mouse-using).
:set paste " Enable paste mode, i.e. disable autoindent, mapping... "
:set nopaste " Disable paste mode (back to normal...) "
" delete all lines matching pattern
:g/pattern/d
" --> example: delete empty lines
:g/^$/d
" --> example: delete lines with only whitespaces
:g/^\s*$/d
" delete all lines *NOT* matching pattern (:v same as :g!)
:g!/pattern/d
:v/pattern/d
foldmethod=syntax
.
" OBSOLETE - THESE BREAK FOLDMETHOD=SYNTAX
syn match cDelimiter "[&\.!^,;:<>=|+%*-]"
syn match cParenDelimiter "[][(){}]"
hi def link cDelimiter Delimiter
hi def link cParenDelimiter Delimiter
yiw " Yank word under cursor "
... " Move to next word "
viwp " Replace current word with yanked text. "
...
viwp
...
:ls " List buffer list, say you have a file verylongfilename_spec.c and anotherverylong_code.c"
:b spec " Will switch to buffer verylongfilename_spec.c"
:sb code " Will split the window and switch to buffer anotherverylong_code.c"
:!{cmd} | Execute {cmd} with the shell. |
:!! | Repeat last ":!{cmd}". |
:[range]r[ead] !{cmd} | Execute {cmd} and insert its standard output below the cursor or the specified line. |
:[range]w[rite] [++opt] !{cmd} | Execute {cmd} with [range] lines as standard input. |
:w !sudo tee %
:%s/\s\+$// " Remove all trailing spaces
:%s/\s\+$ " We can omit substitution text if blank
Add this to .vimrc to have vim remove automatically trailing spaces before saving
autocmd BufWritePre * :%s/\s\+$//e
More elaborate version:
" Trim trailing spaces on save
if !exists("autocmd_BufWritePre_trimspace_tab")
let autocmd_BufWritePre_trimspace_tab = 1
autocmd FileType c,cpp,java,php,vim autocmd BufWritePre <buffer> :call setline(1,map(getline(1,"$"),'substitute(v:val,"\\s\\+$","","")'))
" autocmd BufWritePre * :set expandtab<CR>:retab
endif
Or better yet, create a custom mapping [20]:
" F10 - Remove all trailing whitespace
nnoremap <F10> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR>
:noremap <C-W>t :tabedit <C-R>%<CR>gT<C-W>qgt
" We must embed :grep in :execute or otherwise vim will append /dev/null
" to :cw command and will complain of E488: trailing characters
command! GREP :execute "grep -R <cword> ./src"|:cw
int myint = 1;
double a = 2.0;
float verylongf = 1234.50;
|
→ |
int myint = 1;
double a = 2.0;
float verylongf = 1234.50;
|
set spelllang=fr
" Convert into utf-8
set fileencoding=utf-8
" Add the BOM
setlocal bomb
" Remove the BOM
setlocal nobomb
!par -jw74
:let @+=expand("%")<CR> " Copy basename
:let @+=expand("%:p")<CR> " Copy fullpath
Spell checker
- French
Vim will automatically download and install FR dictionary with
:set spelllang=fr
To install manually, download FR dictionaries with
cd ~/.vim/spell/
wget http://ftp.vim.org/vim/runtime/spell/fr.latin1.spl
wget http://ftp.vim.org/vim/runtime/spell/fr.latin1.sug
wget http://ftp.vim.org/vim/runtime/spell/fr.utf-8.spl
wget http://ftp.vim.org/vim/runtime/spell/fr.utf-8.sug
Alternatively, copy them into /usr/share/vim/vim7X/spell/ to have them available globally.
Command-line mode Tips
- Ex special characters — These are special character that can be used in executed command line (
:! ...
) or when ex is expecting a filename (see also:help <cword>
): - Insert register / object <C-R> — these can be used to insert some register content or text from context (see also
:help c_CTRL-R
): - Insert an environment variable $VAR in command map — Use
<C-R>=$VAR<CR>
to have a command map use the value of an environment variable - New user-defined command in lowercase — One cannot define a user-defined in lower case with
<cword> replaced with word under cursor
<CWORD> replaced with WORD under cursor
<cfile> replaced with pathname under cursor
...
<C-R>* insert X11 clipboard content
<C-R>+ insert clipboard content
<C-R>= expression register. You are prompted to enter an expression
<C-R><C-W> insert word under cursor
<C-R><C-A> insert WORD under cursor
Example of expressions:
nmap <C-@><C-@> :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <silent> <F12> :wa<CR>:b <C-R>=$VPMAINDOC<CR><CR>\ll
newcommand
because Vim forces the command to start with an uppercase. But we can circumvent this requirement with an abbreviation [22]:
cboreabbrev ag <c-r>=(getcmdtype()=':' && getcmdpos()==1 ? 'Ag' : 'ag')<CR>
Clipboard support
- On Linux, install gvim to get full clipboard support
- On Terminator, use also shortcuts ^S-c and ^S-V to copy & paste.
- On Cygwin, install gvim and a X server.
- vim will not have clipboard support. But similar result can be obtained by using
:set paste
, theni
, followed by S-Insert (under mintty) - gvim under Cygwin/X will have clipboard support.
- There is also some plugin (e.g. [23])
- vim will not have clipboard support. But similar result can be obtained by using
- Alternatively, install Win32 gvim (but this versions is not correctly integrated in cygwin, or requires use of wrapper)
Whitespaces
- A nice tip about highlighting unwanted spaces
- Use
set list
andset listchars
to show trailing space, tags, extending spaces as another character...
Some examples:
:set list listchars=tab:>-,trail:.,extends:>,precedes:<
" Enter the middle-dot by pressing Ctrl-k then .M
:set list listchars=tab:\|_,trail:·
" Enter the right-angle-quote by pressing Ctrl-k then >>
:set list listchars=tab:»·,trail:·
" Enter the Pilcrow mark by pressing Ctrl-k then PI
:set list listchars=tab:>-,eol:¶
" The command :dig displays other digraphs you can use.
- To hide tabs even when using listchars:
:set list listchars=tab:\ \ ,trail:·,extends:>,precedes:<
- This is also subject to highlighting ("NonText" is used for "eol", "extends" and "precedes" / "SpecialKey" for "nbsp", "tab" and "trail")
Advanced source highlighting
- See file $VIMRUNTIME/syntax/c.vim for more advanced highlighting options for C files, like
- Highlighting of space errors
- Highlighting of curly, parens errors...
- Highlight column:
:set colorcolumn=+1 " highlight column after 'textwidth'
:set colorcolumn=+1,+2,+3 " highlight three columns after 'textwidth'
:set colorcolumn=80 " highlight column 80
:highlight ColorColumn ctermbg=lightgrey guibg=lightgrey
Digraphs
Digraph is an easy way to enter special character in Vim, much easier than using ^V. See :help dig
for more details.
code | result |
---|---|
^k.M | · |
^k>> | » |
^kPI | ¶ (Pilcrow mark) |
^k00 | ∞ (infinity) |
^k(- | ∈ (in) |
^kIn | ∫ (integral) |
viEmu
Tips for better use of viEmu.
- Applying format in Word via keyboard. To apply format like bold or italic, you can't use the regular key binding C-b or C-i since it is intercepted by viEmu. Some work-arounds:
- (best) Use the new Ribbon shortcuts. For instance, A-h 1 for bold, A-h 2 for italic, Alt 3 for redo...
- (heavy) Temporarily disable viEmu with C-S-A-v. Say C-S-A-v C-b C-S-A-v for bold.
- (worsts) In the viEmu menu, tell viEmu not to intercept C-b and to pass it to Word.
- In viEmu, don't let C-c to be passed to office app. This allows using C-C to leave insert mode.
- In viEmu, don't Emulate vi/vim block caret. This allows formatting a single word w/o selecting it first, as usual in office.
- In viEmu, don't Update display during long commands. Unchecking this box seems to fix the display glitch with viEmu status bar when scrolling down.
Editing HTML, XML, LaTeX
(for LaTeX, see also the vim-latex plugin)
- Use closetag
- Use C-X C-O (omnicomplete) or define macro:
imap ,/ </<C-X><C-O>
- Define abbreviations (see [24])
- Surround plugin in insert mode (use ^stli<enter> to insert a
<li>
tag for instance) - LaTex + surround plugin, use ysm\ to insert
\begin{...} \end{...}
environment. - To format LaTeX, see also plugin Latex Text Formatter.
Omni-Completion
Vim omni-completion C-X C-O is quite powerful. Example:
- To insert HTML closing tags, type
</C-X C-O
<sometag>
some text
some text
</C-X C-O
- To complete a LaTeX tag. For instance to close a
\begin
environment, type C-X C-O C-O C-X C-O:
\begin{theorem} some text some text C-X C-O C-O C-X C-O
A customization I used, but now disabled:
" C-N: Auto-completion menu
" # DISABLED - Don't like the extra window opened, and strange completion.
" # To try: CTRL-N, or CTRL-X CTRL-N, CTRL-X CTRL-O, CTRL-X CTRL-P...
inoremap <expr> <C-N> pumvisible() \|\| &omnifunc == '' ?
\ "\<lt>C-n>" :
\ "\<lt>C-x>\<lt>C-o><c-r>=pumvisible() ?" .
\ "\"\\<lt>c-n>\\<lt>c-p>\\<lt>c-n>\" :" .
\ "\" \\<lt>bs>\\<lt>C-n>\"\<CR>"
Use Vim as Hexadecimal Editor
- From [25]
" To convert current buffer to hex
:%xxd
" To convert current buffer from hex
:%xxd -r
- Use plugin hexman.vim. This still require to open vim in binary mode to prevent insertion of newlines (see [26]):
vim -b file # Might still require ":set noeol"
vim ++bin file
vim file # Then ':set binary' and ':set noeol'
Avoid the ESC key
- BEST — Configure CapsLock as another ESC key.
- On Windows
- On Linux:
gsettings set org.gnome.desktop.input-sources xkb-options "@as ['caps:escape']"
- Use
jj
:
"--- jj -----------
" jj : ... same as ESC (let's try) ...
inoremap jj <Esc>`^
- Use
Ctrl-C
. Here with a fix to prevent the cursor to move one character on the left
"--- C-C ----------
" C-C : Same as ESC, with an additional fix to prevent cursor move -- Note that ESC does move the cursor
inoremap <C-C> <Esc>`^
- (No longer used) — Use
Ctrl-Space
.
"--- C-Space ------ ###DISABLED###. C-Space used for snippet completion instead.
" C-Space: NORMAL --> ESC any prefix keys
" C-Space: VISUAL --> ESC any selection (gV is required to prevent automatic reselection)
" C-Space: OPERATOR --> ESC any operator pending commands (like y)
" C-Space: INSERT --> ESC insert mode and `^ restore cursor position (cursor does not move left)
" (S-Space only works in GUI, see http://vim.wikia.com/wiki/Avoid_the_escape_key)
" nnoremap <nul> <Esc> (disabled, conflicts with cscope shortcuts)
" vnoremap <nul> <Esc>gV
" onoremap <nul> <Esc>
" inoremap <nul> <Esc>`^
- Use Alt-L, or any other Alt combination w/o side effect, since on most terminal Alt-key are sent as ESC-key.
- Possibly install some plugins. None good found so far.
- Use the standard map [# and ]# to navigate between
#ifdef
, and also % to cycle through them [27].
Using filetype (detection, plugins...)
Reference:
help filetype
Some commands:
:filetype " Print file type status
:filetype detect " Detect file type again
:echo &ft " Print current file type
- Detection
See help new-filetype
. There are 4 methods:
- Create a new
autocommand
and write this in a new file (e.g. ~/.vim/ftdetect/mine.vim. This will overrule default file type checks. - Same as above, but use
setfiletype
to set the file type. This will set the filetype only if no file type was detected yet. - If type can be detected from file name, create a new
autocommand
(in aaugroup
), and save it in file ~/.vim/filetype.vim. This will be sourced before default file type detection. - If type can only be detected by inspecting file content, create a vim script named ~/.vim/scripts.vim. This will be sourced before $VIMRUNTIME/scripts.vim.
- Plugins
See help filetype-plugins
.
When filetype was detected, vim will look for available filetype plugins to set options and mappings local to the current buffer. There are 3 ways to create or update an existing filetype plugin:
- Add a few settings before the default plugin. For this create a file in ~/.vim/ftplugin (for instance ~/.vim/ftplugin/fortran.vim).
- Copy existing plugin. This will prevent default plugin to load.
- Overrule the default plugin. For this create a file in ~/.vim/after/ftplugin (for instance ~/.vim/after/ftplugin/fortran.vim)
Note that vim looks for all plugins in runtimepath
that match the filetype name, with an optional underscore and suffix (e.g. fortran.vim, fortran_custom.vim).
- Debug
Start vim with vim -V2
. Look for strings like Searching for "plugin/**/*.vim" in ~
.
Compare files in Vim
References: stackexchange.com, vimcast.org.
:edit file1
:vsplit file2
:windo diffthis " Start diff between both v-splits
:windo diffoff " Stop diff
Indenting
To use an indent program that is configurable via environment variable INDENT
:
if exists('$INDENT')
nnoremap <silent><leader>= :call IndentBuffer()<CR>
endif
function! IndentBuffer()
let cursor_position = getpos('.') " Save the current cursor position
silent exe "%!$INDENT 2>/dev/null"
if v:shell_error
undo
endif
call setpos('.',cursor_position) " Restore the previous cursor position.
endfunction
Otherwise, use equalprg
. By using a filetype auto-command, we can specify the file language to indent program [28]:
set equalprg=~/etc/indent.sh
autocmd FileType cpp setlocal equalprg=~/etc/indent.sh\ -l\ CPP
nnoremap <silent><leader>= mzgg=G`z
Determine the highlight group under the cursor
" --- :HL -------------------------------------------------------------------------------------{{{
" Determining the highlight group that the word under the cursor belongs to ([http://mysite.verizon.net/astronaut/vim/index.html#Tags])
command! -bar -nargs=0 HL echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">"
Print to PDF
- Linux
On Linux, print to file to generate a PS file:
:hardcopy > myfile.ps " or :ha > myfile.ps
Then in bash:
ps2pdf myfile.ps
- Windows
On windows, simply call :hardcopy
:
:hardcopy
This will trigger the printer dialog. On Windows, one call also change the printer font:
set pfn=Fantasque_Sans_Mono:h10:cANSI
Set path
for gf
(goto-file)
gf in vim opens the file whose name is under the cursor. By default vim looks into the current directory, but we can specify a list of directories to look into:
let &path.="src/include,/usr/include/AL,"
One can also give an expression to transform any string into filename. For instance, for java [29]:
set includeexpr=substitute(v:fname,'\\.','/','g')
Capture output of an ex command
:redir @a
:map " The captured command
:redir END
Now content of command :map
is in register "a
.
Diff two files
See also Vimdiff section above.
Open both files, in separate windows. Then:
:diffthis " In first window
:diffthis " In second window
Alternatively, run: :windo diffthis
.
This should trigger diff mode, folding of unchanged section, and synchronize scrolling of both windows
To stop diff:
:diffoff! " Stop diff mode
To ignore whitespaces:
set diffopt+=iwhite
Processing Input - Insert output of external command
:r !ls " read output from running ls, after current line
:0r !ls " after line 0 (before first line)
:-r !ls " before current line ("-" is ".-1")
:r !dir " use 'dir' on Windows
Processing Input - Filter (pipe) buffer to external command
We use !pgm
to call an external program. To pipe the current buffer to that program, just prefix the command with %
:
:%!sort -u " Sort current buffer and remove duplicates
Prefix with a dot .
to only filter the current line:
:.!sed 's/0/-/' " Replace all zeroes with - on current line
Pressing ! when in visual mode, apply the filter on the current selection. This is the same as:
:'<,'>!sed 's/0/-/' " Replace all zeroes with - on current selection
As a rule ! works as an operator, and hence works with motion as well:
!}sort " sort from cursor to end of paragraph
3!}sort " same, 3 paragraphs
3!!sort " sort 3 lines
Save and restore a mapping
See stackexchange:
let map_save = maparg('<C-c>', 'n', 0, 1)
" do some stuff which changes the mapping
exe (map_save.noremap ? 'nnoremap' : 'nmap') .
\ join(map(['buffer', 'expr', 'nowait', 'silent'], 'map_save[v:val] ? "<" . v:val . ">": ""')) .
\ map_save.lhs . ' ' .
\ substitute(map_save.rhs, '<SID>', '<SNR>' . map_save.sid . '_', 'g')
Edit a macro
Two methods [30]:
- Editing the macro register in a buffer
- "qp paste the contents of the register to the current cursor position
- Edit the macro as necessary
- "qy$ (and NOT "qyy" which adds an extra newline) to yank the modified macro back into the q register
- dd delete the pasted register from the file your editing
- Editing the macro register in the command line
:let @q='
open the q register- <C-r><C-r>q paste the contents of the q register into the buffer
- Edit the macro as necessary
'
add a closing quote, and Enter to finish editing the macro.
Fix spelling errors automatically
The following mapping will fix the last spelling error automatically [31]:
" C-l : Auto-correct last mispelled word (https://castel.dev/post/lecture-notes-1/)
inoremap <C-l> <c-g>u<Esc>[s1z=`]a<c-g>u
The change can be undone with u as necessary.
This requires to enable and configure the spellcheck:
setlocal spell
set spelllang=nl,en_gb
Persistent session
Using :mksession
one can save the current session state for later:
" Save session in Session.vim
:mksession
" Save session in lastsession.vim
:mksession lastsession.vim
For ease add the following lines at the end of our project.vim:
set sessionoptions+=blank,buffers,curdir,folds,help,options,resize,tabpages,winpos,winsize
source ./Session.vim
Now start editing with:
gvim -S project.vim
And before quiting Vim, do:
" Overwrite! Session.vim and quit
:mksession!
:wqa
This can be done automatically (see [32]). Add to your configuration file either of these autocmd:
" Update the session file only if one already exists
au VimLeave * if v:this_session != "" | exe "mksession! " . v:this_session | endif
" Or always save the session file
au VimLeave * mksession!
Edit powershell scripts with Vim
See this blog post.
Language tips
C/C++ (IDE)
Principle:
- Use plugin TagList to get list of identifiers.
- Use plugin mcf-make-target (to build any target from within Vim).
- Use tip on persistent session.
Thanks to plugin TagList, it is possible to turn Vim into a simple yet efficient development IDE. The basic idea is to use the TagList window as a simple file explorer. We use a session file to add all files in the project to the TagList window. For C/C++ projects, we add our common settings/mapping defined in our cpp.vim.
Here an example session file project.vim:
" Project specific settings
set tags=./tags
TlistAddFiles src/*.cpp
TlistAddFiles src/*.h
" Source our custom cpp script
source ~/.vim/cpp.vim
" Session Persistence
au VimLeave * mksession!
set sessionoptions+=blank,buffers,curdir,folds,help,options,resize,tabpages,winpos,winsize
" Find in files
command! GREP :execute "grep -R <cword> ./src"|:cw
source Session.vim
Create the tag and cscope files:
ctags -R .
cscope -Rb
Then start the IDE session with:
gvim -S project.vim
Alternatively, one can use the filename Session.vim, and use the shorter command gvim -S
.
Use the mappings A-Up / A-Down to switch the current window to the next/previous file. These mappings simply move and center the cursor in the TagList window to the previous/next file, open the file and put the cursor to its last position.
To build the project (assuming you have a valid Makefile in the project directory), just issue the command
:make
Optionally, we can set MAKEFLAGS
:
let $MAKEFLAGS="-j" " Enable parallel build
To easily navigate between the compilation errors, open the quickfix window:
" Open the window when there are compilation errors:
:cw
" Or open it always:
:cope
Finally you can run the program directly from Vim with:
:!./bin/myprogram
"To repeat the last :!{cmd}, do:
:!!
LaTeX (vimtex)
See vim-tex.
LaTeX (vim-latex) - OLD
Obsolete | We don't use this setup anymore. |
Before using vimtex, we were using plugin Vim-latex.
To Do
- Done Find a way to prevent vim to mess up with my register when deleting text.
- Auto-complete, use cursor keys instead of up/down to search in the drop down list.
- Look at Virtual-edit (see http://vim.wikia.com/wiki/Add_trailing_blanks_to_lines_for_easy_visual_blocks)
- Other links:
- http://www.faqs.org/docs/Linux-HOWTO/C-editing-with-VIM-HOWTO.html
- http://www.ibiblio.org/pub/linux/docs/howto/translations/nl/onehtml/Vim-HOWTO-NL.html
- NEW — Install neovim.
- NEW — Install universal ctags.
- NEW — Consider installing LSP (language-server protocol) for code completion as in VSCode (see Plugin page).
- NEW —
set clipboard+=unnamedplus; inoremap <C-V> <C-R>+; vnoremap <C-C> y; cnoremap <C-V> <C-R>+;
as alternative for my clipboard mappings. Or apparently,set clipboard^=unnamedplus
, which prepends the setting, is more recommended [33]. - Look at https://kite.com as autocomplete alternative.
Troubleshooting
Here several methods to troubleshoot issues. See also the list of known issues for possible fix.
Startup time
Use this command to measure Vim startup time [34], [35]:
# Start VIM and exit immediately
rm -f vim.log && time vi --startuptime vim.log -c 'qa!' && tail vim.log
# ... or edit a file
rm -f vim.log && vim --startuptime vim.log SOMEFILE
Profiling
We run the vim profiler [36]:
:profile start profile.log
:profile func *
:profile file *
" At this point do slow actions
:profile pause
:noautocmd qall!
Key mapping
Get the list of mappings, and where they were defined, for instance for the tab key:
:verbose imap <tab>
Known issues
Mapping portability
- C-, only available to win32 gvim, not to cygwinX gvim.
Memory leaks
- Command
syn match
may create memory leaks which slowly impact performance. Do the following as temporary fix (from [37]):
autocmd BufWinLeave * call clearmatches()
Slow cursor move (vertical / horizontal)
- references: [38],
- Can be due to cursorline. Try
set nocursorline
. Also remove any occurence ofhighlight CursorLine ...
- Can be due to cursorcolumn. Try
set nocursorcolumn
. Also remove any occurence ofhighlight CursorColumn ...
- Can be due to slow matchparen. Add to .vimrc:
let loaded_matchparen = 1
set noshowmatch
- Can be improved with
set lazyredraw
Meta - characters <M-x> (aka <Alt-x>) not working in console
set <M-x>=^[x
- Note, this may also require the following in the shell console:
set convert-meta on
- Although my current settings below also work it seems:
set meta-flag on set convert-meta off set input-meta on set output-meta on
- Another solution is to set the terminal in 8-bit mode as suggested in the link. This is however not possible with Gnome-terminal. A more advanced solution use a timeout to allow distinguishing between M-x and EscTemplate:X [41]:
let c='a'
while c <= 'z'
exec "set <A-".c.">=\e".c
exec "imap \e".c." <A-".c.">"
let c = nr2char(1+char2nr(c))
endw
set timeout ttimeoutlen=50
Or use the following to have timeout only for keycodes and not other mappings:
set ttimeout ttimeoutlen=50
Terminal issues
Cannot unmap a mapping (no such mapping)
:map A
gives
A *@g$a
Trying to remove with :unmap A
, we get the error
E31: No such mapping:
In fact the mapping is buffer local (see :h E1
), and we need to remove it with
:unmap <buffer> A
Bugs
- [2010-07-22] - (to bugs@vim.org) 'winfixheight' not honored when botright split is closed.
30 vnew
wincmd l
insert
We will open an horizontal split below, with wfh option set
Then we open a botright split, and close it immediately
Normally this window should recover its initial height, but if there is a vertical
split on the left, this window will be smaller
.
go
belowright 5 new
set wfh
insert
This window should only be 5 lines in height.
But it will be taller after closing the botright split if there is a vertical split
on the left
.
go
wincmd k
botright 10 split
q
- [2011-07-27] - infinite loop when using :bn after a :edit dir/ (breaks plugin minibufexpl.vim)