Vim is a [[Vim License]] licensed modal text editor written in [[3. Reference/Software/Programming Languages/C|C]]. - [Website](https://www.vim.org/) - [Github](https://github.com/vim/vim) - [Wikipedia](<https://en.wikipedia.org/wiki/Vim_(text_editor)>) > Vim is a highly configurable text editor built to make creating and changing any kind of text very efficient. See also: [[NeoVim]], [[Vim Preconfigs]] # Notability One of the most ubiquitous editors in Unix-land for over 3 decades, leaving a huge mark on the way developers write code. I used Vim heavily starting in 2006 but moved to [[NeoVim]] soon after it was released. # Philosophy ## Slop The official Vim repo is likely being actively swamped with LLM code slop which has resulted in numerous bugs and regressions. The maintainers don't care and hide mentions of this.[^7] # OS Support > Vim runs under MS-Windows (7, 8, 10, 11), macOS, Haiku, VMS and almost all flavours of UNIX. Porting to other systems should not be very difficult. Older versions of Vim run on MS-DOS, MS-Windows 95/98/Me/NT/2000/XP/Vista, Amiga DOS, Atari MiNT, BeOS, RISC OS and OS/2. - [[Linux]] - [[Haiku]] - [[MacOS]] - [[Windows]] - [[DOS]] # Features - Modal text editing - Scriptable with [[Vimscript]] and [[Vim9script]] # History Vim was first released in 1991 and was for many years one of the most popular editors used for code and distributed with nearly every Linux distro in place of the traditional Unix editor `vi`. Due to growing dissatisfaction with the tech debt of the Vim codebase and the lack of real updates from the primary developer, a fork called [[NeoVim]] was created in 2014 which is slowly displacing the original. The release of NeoVim seemed to motivate Vim's developer and many new (NeoVim-incompatible) changes have been released since. - 2022 - [[Vim9script]] The original Vim developer Bram Moolenaar died in 2023 on August 3rd. Contributor [Christian Brabandt](https://github.com/chrisbra) took over as lead. # Tips ## Insert Single Character and Return to Normal Mode It is possible to *replace* a single character using the `r` normal command (like `rX` to replace the current character with `X`). But there is no built in way to do the same thing with insert. It feels like this should be a standard operation, but it isn't available. ### Static To insert a single, *predetermined* character from normal mode (such as underscore `_` when you press `ctrl-_`) you can create a new key mapping: ```vimscript noremap <C-_> i_<Esc>r ``` ### Dynamic If you want to grab just any *arbitrary* single character (typed afterwards), it is more of a challenge. Some register and expression abuse is necessary. ```vimscript nmap <silent> <C-i> "=nr2char(getchar())<cr>P ``` The downside of this approach is that the cursor disappears after you trigger it, so you might lose your place briefly. It will return after the insert. ## Open URL Under Cursor `gx` from normal mode. ## Run Selection If you *yank* the selection you can run it like this: ```viml :@" ``` ## Pipe Visual Selection to Shell Command ```viml :'<,'>:w !external_command ``` To replace the selected text with the output of the command, leave the `:w` out: ```viml :'<,'> !external_command ``` ## Close Buffer To delete a buffer: ```viml :bd ``` To completely wipe out a buffer, including undo history:[^1] ```viml :bw ``` ## Change Case To change the case[^2] of selected text press `u` for lowercase and `U` for uppercase. To change the case of text from the current cursor position to the end of a motion press `Gu
for lowercase or `GU
for uppercase where `
is the motion. To capitalize[^3] just the first letter of each word: ```viml s/\<./\u&/g ``` Prefix with `%` to affect the entire document, or remove the `/g` and prefix with `'<,'>` to affect a selection. In Vim's regex *replacement* dialect `\u` is uppercase next char and `\l` is lowercase next char, while `\U` is uppercase all following chars and `\L` is lowercase all following chars. These sequences may be prematurely terminated by each other or with the generic `\e` end syntax. Unfortunately this choice of end syntax means that `\e` is not available for the [[ASCII Table#ESC Escape Code|escape character]]. Similarly frustrating, `\n` inserts a `NUL` character rather than a newline, to get a newline you need to use `\r`.[^4] ## Inspect Character Under Cursor >[!FIXME] > Some of this info is provided by the plugin `tpopt/vim-characterize` To get detailed information[^5] about the character the cursor is on press `ga` or use the command `:as[cii]`. It will display the following information in the message area (two examples - top and bottom): ``` <\> 92, Hex 5c, Oct 134, Digr // ↑ ↑ ↑ ↑ ↑ │ │ └ hex └ octal └ digraph │ └ decimal ├─ character representation │ ┌ decimal │ │ ┌ octal │ │ │ ┌ codepoint │ │ │ │ ┌ name ┌ digraph ↓ ↓ ↓ ↓ ↓ ↓ <^[> 27, \033, U+001B ESCAPE, <C-K>EC ``` I don't know why the display is so inconsistent between characters, but this isn't the half of it. Sometimes it will also display "M codes" like `<M-^A>` and other fields not explained in the documentation. To see *just* the simple hex representation of the bytes under the cursor use `g8`. The hex values will display in the status area. Each pair of hex values represents a single byte. For [[ASCII]] characters there will only be a single pair, but for [[Unicode Standard|UTF-8]] characters it may display up to four pairs. For example, the down arrow (↓) used in the diagram above shows up as `e2 86 93` with `g8` and with `ga` shows: ``` <↓> 8595, U+2193 DOWNWARDS ARROW, <C-K>-v, &darr; &DownArrow; &downarrow; &ShortDownArrow; ``` This is has a couple of new fields, in addition to the control-k digraph, there are a list of HTML-entity-like names. ## Line Editing and Navigation | Command | | | ----------- | -------------------------------------------------- | | `d
or `D` | Delete (cut) from current character to end of line | | `y
or `Y` | Yank (copy) from current character to end of line | ## Quickly Edit Vim Config ```viml :edit $MYVIMRC ``` ## Evaluate Arbitrary Vim Script ```viml :source path/to/script.vim ``` Or directly from a command shell: ```sh vim +source path/to/script.vim ``` Or directly from a command shell without invoking any init scripts: ```sh vim -u NONE +source path/to/script.vim ``` ## Execute Command on Matching Lines The `:global` (or `:g`) command can be used to run any `ex` command on a match.[^6] ```viml :g/pattern/command ``` To run on lines that *don't* match, use `:g!` or `:v`. This is particularly useful to delete all matching/non-matching lines. For example to delete all empty lines: ``` :g/^$/d ``` ## Insert Multiline ```vim ctl-v (select lines) I ``` `I` insert before selection `A` insert after selection # Resources - Official [Vim scripts site](https://www.vim.org/scripts/) - GitHub [mirror](https://github.com/vim-scripts?tab=repositories) of most Vim scripts (ceased mirroring at the end of 2023) ## Cheat Sheets - https://vim.rtorr.com/ ## Color Schemes - https://alvinalexander.com/linux/vi-vim-editor-color-scheme-syntax/ - https://vimcolorschemes.com/i/trending/b.dark - https://github.com/morhetz/gruvbox - One of the big ones, with lots of support for different plugins - https://github.com/sainnhe/everforest/blob/master/colors/everforest.vim - Slightly nicer than a solarized but in the same vein ## Plugins - [[Vim Plugins]] Unsorted. - https://raw.githubusercontent.com/vimwiki/utils/master/vwtags.py ### Linters #### ALE - https://github.com/dense-analysis/ale To see what linters are currently active: `:ALEInfo` ### Pickers #### Ctrl-P - https://github.com/ctrlpvim/ctrlp.vim - https://github.com/tacahiroy/ctrlp-funky - https://github.com/fisadev/vim-ctrlp-cmdpalette - https://github.com/sgur/ctrlp-extensions.vim - https://github.com/suy/vim-ctrlp-commandline - https://github.com/pjkack/vim-ctrlp-tjump - https://github.com/mattn/ctrlp-matchfuzzy - https://github.com/JazzCore/ctrlp-cmatcher - https://github.com/endel/ctrlp-filetype.vim - https://github.com/xidiandaily/ctrlp.chiyl.vim/tree/master/autoload/ctrlp ### Fonts - https://github.com/ryanoasis/vim-devicons ### Tim Pope Pope has created and maintained a large number of extremely stable and useful plugins for many years. - https://github.com/tpope/vim-fugitive ### Git Integration mini.diff coc-git vim-gitgutter vim-signify - https://github.com/lewis6991/gitsigns.nvim - https://github.com/johntyree/time-lapse.vim - https://github.com/mwcz/fuhgit ### Code Navigation and Tags - https://github.com/preservim/tagbar a sidebar for tags ### Wiki - [[VimWiki]] - https://github.com/tbabej/taskwiki add-on for VimWiki, integrates with [[Taskwarrior]], requires Python setup ### Syntax #### Markdown - https://github.com/preservim/vim-markdown - https://github.com/gpanders/vim-medieval evaluate code blocks embedded in Markdown files - https://github.com/qadzek/link.vim converts inline Markdown links into reference-style links ### Other - https://github.com/mattn/calendar-vim ### Ctags Integrations Vim already supports ctags, but these plugins enhance it. - https://heptapod.host/cgtk/taghighlight - https://www.cgtk.co.uk/vim-scripts/taghighlight - https://vim.fandom.com/wiki/Generate_ctags_file_for_a_C/C%2B%2B_source_file_with_all_of_their_dependencies_(standard_headers,_etc) - https://www.vim.org/scripts/script.php?script_id=2646 ## Related - [[Taskwarrior]] - https://taskwarrior.org/ - Markdown Ctags - https://github.com/jszakmeister/markdown2ctags - find tags - https://github.com/matt-snider/vim-tagquery # References ## Single Character Insert - https://antifandom.com/vim/wiki/Insert_a_single_character - https://superuser.com/questions/581572/insert-single-character-in-vim - https://stackoverflow.com/questions/1557893/making-inserting-a-single-character-in-vim-an-atomic-operation - https://www.vim.org/scripts/script.php?script_id=2136 (Tim Pop's Repeat.vim) - https://github.com/tpope/vim-repeat (GitHub mirror) - https://www.vim.org/scripts/script.php?script_id=2810 (Peter Hodge's InsertChar.vim) - https://github.com/vim-scripts/InsertChar (GitHub mirror) - https://github.com/aur-archive/vim-insertchar (AUR PKGBUILD) ### Related https://stackoverflow.com/questions/36432919/how-can-i-map-underscore-in-vim - https://stackoverflow.com/questions/27882964/in-vim-remapping-how-do-i-capture-and-reuse-any-character [^1]: https://stackoverflow.com/questions/1269648/how-do-i-close-a-single-buffer-out-of-many-in-vim [^2]: https://stackoverflow.com/questions/2946051/changing-case-in-vim [^3]: https://stackoverflow.com/questions/17440659/capitalize-first-letter-of-each-word-in-a-selection-using-vim [^4]: https://stackoverflow.com/questions/71323/how-to-replace-a-character-by-a-newline-in-vim [^5]: https://vimtricks.com/p/inspect-character-under-cursor-in-vim/ [^6]: https://stackoverflow.com/a/706083 https://stackoverflow.com/questions/46781951/efficient-way-to-delete-line-containing-certain-text-in-vim-with-prompt#comment134971070_73580651 [^7]: https://github.com/vim/vim/issues/18800#issuecomment-3568417192 [^8]: https://github.com/neovim/neovim/issues/38186#issuecomment-4018682912