Vim
Internals
vimtutor
To follow navigation in vim :help you can use <c-]>
quick reference card
We will use vims keynames :help keycode but lowercase (anywas it is case
insensitive), for example <c-d> is control Ctrl and d, in help it can be
written as ^d or <ctrl-d> but we will stick with <c-d>
<esc>is escape key (when recording macro it is^[<80>y)<space>space<cr>sometimes it is<Enter><bs>backspace<left>left arrow<s-left>shift left<c-left>control left^Iis when we insert<tab><nl>new line. If you useechom "a\nb"you will seea^@b(CTRL-vandCTRL-j)<tab>tab
If you press <c-s> ctrl-s ^s than terminal will freeze all output and looks
like vim hangs and stop working, but you need to run <c-q> ctrl-q ^q to exit
from that.
special variables
<leader>by default is\but I use<space>. To check current value use::echo mapleader, to set use:let mapleader=" "<localleader><non-keyword-character>maps all non keyword chars::set iskeyword?returnsiskeyword=@,48-57,_,192-255,-ie alphabetic ascii, digits 0-9, _ , and some special chars<nop>no operation, usefull when you want to disable some keys
Run vim without any plugins or settings with
vim --clean
# start vim without plugin , no plugins
vim --noplugin
# vanila vim without vimrc
vim -u NONE
Reload vimrc. Note that old config is not automatically reseted (you need to exit vim and start again)
:source $MYVMRC<cr>
My Vimrc
Good starting poing for .vimrc is http://vim.wikia.com/wiki/Example_vimrc
Also nice default vimrc :r $VIMRUNTIME/defaults.vim
You can find my
.vimrc
Main settings
" do not need to be backward compatible
set nocompatible
Note that control key can be written as caret ^ so instead Ctrl-n it can
be written as ^n.
Use vim help, with:
:help:help user-manualhelp on some topic:helpgrep windowssearch all help pages (also plugins) for topic:help ctrl-iwhat Ctrl-i do in normal mode (normal is by default searched) we could also write:help ^i:help i_^iwhat ctrl-i do in insert mode:help v_^iwhat ctrl-i do in visual mode:help c_^iwhat ctrl-i do in command line editing mode:help :swhat s do in ex-command mode:help -thelp with command line options (run:optionsto see all options):help 'listhelp on some option:help myfunc()add brackets to search only functions:help hl-WarningMsghighlighting groups start withhl-:help /\+regexp items start with/:help quote:registers start withquote:help >contdebugging commands
Other help commands can be found :help 0.8.
Follow link with ctrl-] and jump back with ctrl-o
Use Ctrl-o to run normal mode command from insert Mode
<ctrl-o>take to normal mode for just ONE command, so if you want to go up while in insert mode<ctrl-o> k, or to reformat paragraph<ctrl-o> gqip, clear whole line but not new line<ctrl-o><s-o>(similiar to<ctrl-u>
Other usefull commands in insert mode:
<ctrl-t><ctrl-d>indent deindent in insert mode<ctrl-o> ddelete everything to the right of cursor<ctrl-u>delete everything to the left<ctrl-w>delete word to the left of cursor<ctrl-h>backspace<ctrl-j>return<ctrl-a>insert the text you typed last time you were in Insert mode<ctrl-p>complete words under the cursor. If there is no word, it look previous word,<ctrl-p>again look previous…<ctrl-r> ain insert mode will yarn register a (usefull when there are a lot of similar words and completion does not help much)<ctrl-v> {digit}insert character with special meaning like for<esc>it is^[.<ctrl-v> {key}insert char with key number like<ctrl-v> 110isn.<ctrl-k> Coinsert special digraph char from the list:digraphsbut instead using key you use two chars
Operators
- to change case you can select and press
~ gqtext formatting (gwformating without cursor movement) to 80 chartextwidthlines and proper code indent. Visually select the range or use motion likegqapformat a paragraf,gggqGwhole file.cchange,yyank,ddelete<shift left>shift right,==indent current line,gg=Gindent whole file
Motions and selections
- shortcuts
x(dldelete char),C(c$change to end of line) ciwchange inner word,cawincluding spaces that follows the wordca]change all inside brackets including both [ ]Schange whole line (delete and go to insert mode)
dawremoves the inner worddtdelete until the space,dfdelete until the space including spacedap}pswitch two paragraphdEremoves to the End of the stringvitinner orvatouter visual select (including html tag):h tag-blocks- repeat
atto select wraped tag - jump to closing (Oposite) html tag with
oin visual mode. more on:help visual-operators:help v_it vapselect paragraph (until next empty line, including that empty line) other text objects areaw(a word),a((a block of any of the paranthesis quotes). Note the differences between using object and movement command,dwwill delete from current position to the end of word,dawwill delete whole word regardless of cursor positiondstdelete surround tag with vim surround plugin.cilchange inner line with line text object pluginviiselect same indent level with indent text object
- repeat
va'visually select all inside ‘ including ‘cgnchange visually selected text using previous search- recording macro to q with
qq, exit withq, run with@q. To repeat last macro registar you can use@@. You can edit macro by simply pasting"qpand edit the line and yank back to the same register"qyil. To add new commands to register use uppercase, for example adding search toqregisterqQ/word<enter>q(this appending also works for yanking) To cancel recording the macro you can copy existing (before you exit recording, existing is still available) to new register and than back to original https://superuser.com/questions/666377/how-to-cancel-recording-a-macro-in-vim#comment1558163_666428# recording qa but I wanted to execute @a :let @t=@a q :let @a=@t - paste commands in insert mode with
^Rq ^Tindent^Ddedent in insert mode. Shift can be also done in visual mode (also in blockwise selection) with>. In normal mode you can select and indent with=To indent whole file you can jump to begging and indent to last linegg=G.- Sort selection with
:sort :set scrollbindin two buffers will make them scroll simultaneously. toggle scrolling with:set scb!
Motion in visual mode
'<to the first line of last selected visual area. Note that you need to exit current visual area and than jump to first or last line/chargvto reselect previous selected visual area
Normal mode
- Repeat last colon command
@:, repeat last command@@ Kin normal mode opens documentation for that keyword in any language, for exampleErrorin ruby file will openri Error.:set keywordprgis program used for documentation (default is:helporman):set backupwill createmyname.txt~(or:set backupext=.bak) inside:set backupdir. To keep original file:set patchmode=.orig.
Command line mode
Command line mode :help usr_20.txt is when using : or search /,?.
- You can press
<Enter>anywhere inside line - Navigation with cursors
<Left>,<S-Left>(one word left) andCTRL-B/CTRL-Ebegin/end of line. Difference with bash is that^bis begin of line (char left in bash),^eis the same, and^f(char right in bash) enters Replace mode in comand line window so you can usel - Delete with
<BS>(or^h) andCTRL-Wdelete whole word,CTRL-Udelete all before text.ctrl-dis not as in bash, it is completion in vim. - tab completion works and you can see all matches with
CTRL-D(match is when command starts or short name starts with that). So^dto show all completion and<tab>to iterate over completions ,^pto iterate in reverse direction (^nin forward direction). Note if you are not yet in completion mode^pwill just show previos command (not previous completion). To get a value use tab two times::set isk<TAB>=<TAB> - command line history can be used when you type start of command and
:se<UP>CTRL-Pwill go to previous command no matter what you have types so farctrl+pandctrl+nwill go up and down,ctrl+ywill accept currentctrl+ewill cancel suggestions - Command line window
q:orCTRL-Fis used to edit long commands.<CR>to execute comand and exit. Exit with:qorCTRL-C. Search previos with? - You can join multiple commands with
|or<NR>(more help withcmdline-lines) :set viminfo=<TAB>will show what is saved when you exit vim. To jump back to last file use mark'0when you start vim.'100how many files for which vim save marksf1if 0 global marks are not stored. If missing or 1 global marks are stored<100how many lines per register is stored, 0 nothing. By default all lines are storeds10max size in KBytehdisable ‘hlsearch’ highlighting when starting
:mksession! a.vimwill createa.vimfile and save all windows, files … Restore withvim -S a.vim.viminfostores marks, registers, history and you can also write:wviminfo ~/.vim/myapp.viminfoand thanrviminfo.- You can instruct vim how to view the file using first or last 5 lines
commands are between
:colons/* vim: set shiftwidth=4 : */
Command line options
- Edit multiple files
vim one.txt two.txtit will open
one.txt. You need to save and:nextor:wnextto write and go to next file. You can see all arguments with:args. Going back is:previous, also works:first,:last,:2next. - You can open in split windows
vim one.txt two.txt -o # or -O for vertical split :args app/*/*to add all files to arg list- open file on specific line
vi +10 README - open readonly mode
vim -R filebut it can be overwritten with:write!. To really keep read only usevim -M file(but this also can be turned of with:set modifiable). vimdiff a bwill show differences. Inside vim:e aand:vertical diffsplit b. If you are in left window you can usedpto copy change to the right (diff put), ordo(diff obtain) to pull from other right window.- read commands from file
change.vimexamplefor file in *.txt; do vim -e -s $file < change.vim lpr -r tempfile done - read file from stdin
ls | vim -
Exploring
:edit .(short:e.) opens (:vsp) splits netrw of folder,cd ~to change directory to home folder for all windows. If you usegfin Gemfile, it will not change directory (you can check that:pwdis showing same folder). To manually change current folder directory to file path you can use:lcd %:p:h.%is the current file name,%:pfile full path,%:p:hgive its directory. Or you can typecdwhen cursor is on the line where is the path:%<expands filename without trailing extension:help filename-modifiers- beside window local directory
:lcd, you can set tab local directory so to work with other gem you can usetabe Gemfile,gfand:tcd %:p:h gfusespath(which stores all apsolute paths, run:set path=<tab>to see them).- instead of
:w otherand:e otheryou can use:saveas other. Similar is using:file other(which will be ‘Not edited’ ie not saved yet).
Windows buffers and tabs
:splitwill create new window of the same file,:newwill create new window for new file.:3split filewill open 3 lines height window, you can increate withctrl-w +:tabe fileopen file in new tab,gtswitch between tabs- move between windows is with
ctrl-w w :help Ctrl-W_Tmove current buffer in new tab (similar to:tabe %), Disable default Terminal -> Preferences -> Shortcutsgxopen link under cursor withgnome-open. Issue #1386:vsp #1vertically split window with file #1:on(:only) orCtrl-W ocloses all windows except current:buffers,:b1open first,:buncloses the buffer,:sbuffer 2uunlisted%current#alternate (jump to it with^^)aloaded and displayed,hloaded and hidden=read only-not modifiable+has been modifiedCTRL-^(shift+6) jump to previous buffer:retabthis will actually reformat all sourcectrl-w fis the same asgfbut opens in new vertical split window:b substring_of_filenameopen buffer that matches substring (press tab in case of multiple mathces)- Status Line
:set statusline=%f\ -\ FileType:\ %ywill change status line%fpath to the file%Ffull path to the file%yfiletype of the file%Ltotal lines
- set file type in magic comment
# vi: ft=conf
Movements and Navigation
wbnext (prev) begging of word. UseWandBto include'iskeyword'option characters like"|-. Useeandgefor end of word.gjgkfor long lines that are wrapped to multiple lines, it will go up and down$end of line,0start of line (or^), use_to select end of line before new line character+and-move line up or down on the first letter{ {and}}move on start or end of paragraph (empty line), single brace is default but I changed to double^B(^U,^Y) or^F(^D,^E) scroll next page up (half page, one line) or down (half page, one line). But for one line it is easier to useLjjjHMLjump to the top/middle/bottom of what you see- move screen one line
CTRL+yup (down is remapedctrl+e) mAthen'Ajump there (downcase letteracan jump only on current file buffer, useabacktick to jump to specific column instead of beggining of the line),:marksgives the jump location, two ‘''is jump back,'.jump to last change^oand^iwill jump to previos and next location.^]to jump to section under cursor - hyperlink - ctags%jump closing brackets or other matching brace5Gor:5goes to the line 5gggoes top,Ggoes bottomg,andg;jump to next/prev change on current bufferg ^gprint column, line, word, character. Used for word count- show line numbers
:set numberor relative numbers:set relativenumber(or shorter:set rnu. To disable you can:set norelativenumber - show approx position in text
^G gfgo to file, follow that link path
Quickfix and location list
QuiCkfix window is just a preview window. You can open with :copen or :cw
(open only if there are errors, close if there are no errors).
Location list is similar to quickfix but for current window replacing c with
l like :lopen, :lmake. There is Location in status bar and is
independed from quickfix list.
:cnextjump to next error,:clastto jump to last (with plugin:help unimpaired-nextyou can use]qgo next[qprev error). For ALE rubocop use list]l:ccto show full error message in status bar for this line:clistto list all errors
to get quickfix title (usually it is command that generates the list)
:echo getqflist({'title' : 1})
Error format efm is using scanf tags :help error-file-format
%ffile name%lline number%terror type%merror message%rrest of a single line file message%O/P/Q
:set efm=
Using unimpaired
[c]cgo to prev next change in diffsplit[l]lALE rubobop errors. To close error window you need to:lcl]bbuffers]owto enable wrap, toggle withyow, more:help unimpaired-toggling
Copy paste
- select which register to use with (use character not number) for example:
yank link to register
ais"addand paste:"ap". When deleting or changing it will override default register, so you need to select some other register, like black hole register"_if you want to paste same stuff multiple times, for example"_dor"_cwill keep default register untouched. %y+copy all lines to clipboard"+ycopy visual selection to system clipboard, ubuntu should runsudo apt-get install vim-gtk. orvim-gnome- to move a line to buffer on the left you can record macro (something like
yy ^wh p ^wl) - to paste with proper indend use vim-unimpaired
]p, also from plugin:help unimpaired - insert text from external command is with
:read !date - undo
uredoctrl-r.:help 32. If you know the change number you can jump to it using:undo 2. Useg+(:later) andg-(:earlier) to jump back and see change number so you can jump to it. See change numbers with:undolistor use time in:earlier 10s. Try plugin:UndotreeShowhttps://github.com/mbbill/undotree remaped to F5
Search and replace
Seach files
:grep subject -R * --exclude-dir={log,spec,public,features,tmp,vendor,assets,db} -I
Instead of :grep I use :Ack (which uses ag)
https://github.com/ggreer/the_silver_searcher. It will ignore all from
.gitignore so no need to exclude dir. Invoke with double search //
Here are some ack.vim helpers:
?quick summary of keys,hopen in horizontal split-
ag pattern -G showwill search only filenames likeshow.html.erb(-Gis short for--file-search-regex patter),-iignore case,-lshow only filenames.--ignore-dir=libwill ignore specific folders (regex not supported). Filter only specific file typeag --list-file-types| lessyou can useag MyClass --ruby.:Ackcan be used to find in files. In vim it usesaginstead ofgreporAck. To search specific types use option-Gand regexp like::Ack montserrat -G 'css$'For two line search you can use::Ack 'destroy\n.*authorize' app/controllers/For multiline (does not matter how many lines are in between):Ack 'destroy(\n.*)*flash.now..notice' app/controllers/ vimgrep my_string **/*.md | copensearch only md files for my_string and show results
Search text in a file
:help usr_27.txtand:help pattern/for searching, to search in oposite direction?(nandNfor next and previous result). If search string is all lowercased than it will search ignore case (when:set ignorecaseoption is set), but if you have at least on uppercased letter than case is important (when you have:set smartcase)- use
*search forward (#backward) of the word nearest to the cursor (middle fingeers are clicking the*and#). Useg*to match words that include the string (no boundary constrains) - offset is used to position cursor on prev line
/default/-1or character/default/e+1(1 char from end of search word)/default/b+1(one char from beginning of match) - use
:match Error /asd/to highlight asd in buffer - instead of zero or more
.*, you can use.\+to match one or more times (.\*means any char and star,.+means any char and plus) - use very magic regexp (like in other languages) if you start with
\vfor example those two are equivalent searches:help magic(very magic does not need to escape + | ( ) { })/for .\+ in .\+: /\vfor .+ in .+: :help pattern-overview- search with end of the word
/usan\>help with:h /\> - beggining and end of line marks like
/^asdand/asd$works fine (not in the middle/asd^qwe) - For multiline search you can use:
\nnew line\_sspace, tab or newline,\_.any char including new line\_^(\_$) match new line or beggining (end) of line
- instead of
*which will stop at last occurrence till the end of line, you can use minimum matcher\{-}to stop as soon as possible. Use\{2,4}to match 2, 3 or 4 times. For example/asd\_.\{-}qwefind asd followed with any character (including new line) and stop at qwe (match as few as possible)/asd\(.*\n\)\{2,3}.*qwefindqweif it is afterasdin 2 or 3 lines- You can use S and S! snippet
- or operator is
\|for example/one\|two. If you use inside other match you need to put\(and\), for examplet\(wo\|hree\). If it is chars than use character ranges for example:/[a-z]or/[abcdef]will match any of the chars included in list./[^xyz]matches char which is not in the list- special characters:
\ttab\eesc,
- predefined ranges
\dis[0-9]digit,\Dnon digit[^0-9],\swhite space or tab,\a,\land\uany, lower and upper case alphabetic character. Note that predefined ranges can not be used inside range, use or operator instead - you can use character classes like
\f(any char than can be a file name, depends on the OS). - character classes and ranges can be modified to include new line like
\_aor even for inverse ranges/"\_[^"]*"strings that may split up in several lines :set nowrapscanis usefull when you want to stop search when you hit bottom of a file. Withggyou can jump to begging.:set wrapscanwhen you want to back to wrapped search-
clear highlights until next search
:noh, to clear completely:set nohlsearch q:shows history of commandsq/shows history of searches
Replace text
Replace command synax is :[range]substitute/from/to/[flags] also add % so it
applies to whole file. Use + instead of / if you need to escape a lot, for
example :%s+http://+https://+g
:%s/old/new/gcg means global (each occurence in a line) c confirm:%s/old/new/gee means not to return error ifoldis not found, usefull in macros, so it does not stop the macro- replace tabs with two spaces in whole file(you can use % also)
:1,$s/\t/ /grange from current line to the end is:.,$s/yes/no/. To split the line by space into multiple lines use::.,.s/ /\r/gThis is example to replace grey with gray only in current chapter (each chapter starts with Chapter) search backward from current position use?:?^Chapter?,/^Chapter/s=grey=gray=gThis will also include a lines with Chapter. To exclude them use offset like
:.+3,$-$s/a/b/gFrom current position till the exact number of lines you can write
5:which will expand to:.,.+4Instead of writing the rage you can set marksmtandmband use them:'t,'bs/a/b/gIn visual mode it marks with angle brackets
:'<,'> - remove all non acii charaters
:%s/[^[:print:]]//gfor example<200b>^F - match replace first group with second group,for example Doe, John -> John Doe
:s/\([^,]*\), \(.*\)/\2 \1/ :argdo %s/foo/bar/ge | updatereplace (substitute) in all arg.
Global command to find a match and execute command there
Syntax is [range]global/{pattern}/{command} . command can be s (substitute),
m (move the line). Default range is whole file. For normal commands use
:normal.
- search for comment and inside that line replace foo with bar
:g=//=s/foo/bar/g - reverse all lines
# It matches every line and move to the top :g/^/m 0 # also works with marks, for example reverse from mark t to current line :'t+1,.g/^/m 't
Insert Completions
^nor^pin insert mode to autocomplete strings and get next/previous item^x^oto autocomplete using omni completion (intellisense) inteligent way of completion for example complete only methods that exists on that object:help compl-omni-filetype- in html you can auto close last opened tag if after </ you click
^x^o(similar with ragtag plugin that completes using<Ctrl-x>/) - in css
:set omnifunc=csscomplete#CompleteCSS - in ruby
let g:rubycomplete_buffer_loading = 1 let g:rubycomplete_classes_in_global = 1 let g:rubycomplete_rails = 1
- in html you can auto close last opened tag if after </ you click
^x^nonly strings from current file^x^lcomplete whole lines^x^fto complete filename (keep^x^fwhen you navigate subfolders)^x^]for tags find other shortcuts with:help ins-completion^aand^xto increment and decrement numbers speeddating if you want to increment dates
Installing
Update to vim 8 use
sudo add-apt-repository ppa:jonathonf/vim
sudo apt-get update
sudo apt-get install vim
On ubuntu 18 that package is outdated so I need to compile from source https://stackoverflow.com/questions/37079424/ubuntu-16-04-lts-cant-enable-xterm-clipboard-in-vim/37079474#37079474 Add gtk so we can copy to clipboard
sudo apt-get build-dep vim
git clone https://github.com/vim/vim.git vim_source
cd vim_source/
./configure \
--enable-perlinterp=dynamic \
--enable-pythoninterp=dynamic \
--enable-rubyinterp=dynamic \
--enable-cscope \
--enable-gui=auto \
--enable-gtk2-check \
--enable-gnome-check \
--with-features=normal \
--with-x \
--with-compiledby="DevNull <darkstar@/dev/null>" \
--with-python-config-dir=/usr/lib/python2.7/config-$(uname -m)-linux-gnu
make -j8
sudo checkinstall
Plugins
Pathogen is no longer needed since you can install packages to the pack folder
.vim/pack/my-package. Start using :packadd! my-package.
Plugins are installed in ~/.vim/plugin/. You can add subfolders for better
organizations ~/.vim/plugin/rails/*.vim
For specific file type (based on extension .c, or first line #!/bin/bash)
only specific plugins from ~/.vim/ftplugin are loaded ~/.vim/ftplugin/c.vim.
Help doc files are added to ~/.vim/doc like ~/.vim/doc/my_plug.vim, than run
:helptags ~/.vim/doc so that doc is added to local help. List of all added
files is :help local-additions
Instead of installing pathogen and
mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
cd ~/.vim/bundle
git clone git://github.com/tpope/vim-rails.git # example: Rview
you can use vim builtin way
:help packages
You can find my list of plugins
- rails-vim is nice
- if you want to use rspec instead of minitest, you need to remove
testsfolder so:Especworks - run
<leader>sto run nearest spec (alsot,l,afor file, last and all specs) - there are mappings for minitests:
Efunctionaltestare controller tests,Eunittestare model tests,Eintegrationtestare integration between controllers. Do not know how to jump system tests. - use projections to add custom commands, for example
app/services
let g:rails_projections = { \ "app/services/*.rb": { \ "command": "service", \ "template": \ ["class {camelcase|capitalize|colons}", "end"], \ "test": [ \ "test/services/{}_test.rb", \ "spec/models/{}_spec.rb" \ ], \ }} - if you want to use rspec instead of minitest, you need to remove
-
vim-commentary comment line, visual select and press
gc - ctrlp ctrl+p
- to seach already opened buffers, hit
<ctrl-p>and than<ctrl-f> - to open in horizontal sprit use
<ctrl-p>and<ctrl-x> - to open in current buffer, instead of patching
autoload/ctrlp.vim:1309to uselet md = 'r'instead oflet md = argmapsyou can configure different prompt mappings for<ctrl-o>to immediatelly replace buffer.
" make ctrl-o immediatelly replace buffer so we don't need to answer OpenMulti prompt " Open Selected: [t]ab/[v]ertical/[h]orizontal/[r]eplace/h[i]dden? let g:ctrlp_prompt_mappings = { \ 'PrtSelectMove("j")': ['<down>'], \ 'AcceptSelection("r")': ['<c-j>'], \ } - to seach already opened buffers, hit
- splitjoin for inline ruby
blocks
{ }to convert do multilinedo\n end.
Some not used anymore
-
You complete me: its too much visualisation
# http://vimawesome.com/plugin/vim-rspec-sad-beautiful-tragic # :RunSpec git clone [email protected]:Valloric/YouCompleteMe.git && cd YouCompleteMe && ./install.sh && cd - -
vim-markdown: issue with syntax highlight for * inside code block
-
vim-autoclose: annoying O char waiting next input
- ragtag plugin in insert mode:
<ctrl-x>/close last html tag<ctrl-x>=append<%= %>, use<ctrl-x>+to wrap around last line<ctrl-x>-append<% %>, use<ctrl-x>_to wrap around last line<ctrl-x>@insert stylesheet or<ctrl-x>$javascript tags
- multicursors mode change several strings at the same time https://github.com/mg979/vim-visual-multi
Running ruby in vim and show in separate window
link
Press F7 to run selected or all code. Shift + F7 close the window.
"save code, run ruby, show output in preview window
function! Ruby_eval_vsplit() range
let src = tempname()
let dst = tempname()
execute ": " . a:firstline . "," . a:lastline . "w " . src
execute ":silent ! ruby " . src . " > " . dst . " 2>&1 "
execute ":pclose!"
execute ":redraw!"
execute ":vsplit"
execute "normal \<C-W>l"
execute ":e! " . dst
execute ":set pvw"
execute "normal \<C-W>h"
endfunction
vmap <silent> <F7> :call Ruby_eval_vsplit()<CR>
nmap <silent> <F7> mzggVG<F7>`z
imap <silent> <F7> <Esc><F7>a
map <silent> <S-F7> <C-W>l:bw<CR>
imap <silent> <S-F7> <Esc><S-F7>a
Seeing is believing
Show ruby return values on each line in vim.
Install seeing_is_believing
with gem install seeing_is_believing --version 3.0.0.beta.7 and add plugin cd
~/.vim/bundle && git clone https://github.com/hwartig/vim-seeing-is-believing
and add mappins: F4 mark, F5 run (not in visual) and enter mark and run
(not in insert mode)
" .vimrc Enable seeing-is-believing mappings only for Ruby
augroup seeingIsBelievingSettings
autocmd!
autocmd FileType ruby nmap <buffer> <Enter> <Plug>(seeing-is-believing-mark-and-run)
autocmd FileType ruby xmap <buffer> <Enter> <Plug>(seeing-is-believing-mark-and-run)
autocmd FileType ruby nmap <buffer> <F4> <Plug>(seeing-is-believing-mark)
autocmd FileType ruby xmap <buffer> <F4> <Plug>(seeing-is-believing-mark)
autocmd FileType ruby imap <buffer> <F4> <Plug>(seeing-is-believing-mark)
autocmd FileType ruby nmap <buffer> <F5> <Plug>(seeing-is-believing-run)
autocmd FileType ruby imap <buffer> <F5> <Plug>(seeing-is-believing-run)
augroup END
Indent
HTML indent works fine but note when to avoid erb tags. It detects %> as
closed tag except when line starts with <%. Do not use comment in the middle
of erb since that line somehow is not indented. Better is to add another comment
tag inline <%# if condition? %>
Instead
<div>
text node <%= name %>
</div>
Use
<div>
text node
<%= name %>
</div>
For if else anotation use separated tag
<% if b %>
<% else %><%# if b %>
<% end %><%# if b %>
For multiline ruby there is a problems so use single line erb
<% one %>
<% two %>
For case switch there is a problem since it is not recognized as valid ruby
<fieldset>
<% case searchable %>
<% when Book %>
<legend>Book</legend>
<%= searchable.title %>
<% when User %>
<% end %>
only solution is to merge two line into one
<fieldset>
<% case searchable when Book %>
<legend>Book</legend>
<%= searchable.title %>
<% when User %>
<% end %>
Netrw
netrw.vim is
native exprorer.
:Explore(short :E) :Vex of current editing file
To change current folder just press c on folder line help :netrw-c.
That’s better than cd ../path which change in all tabs. It will not affect
already opened windows, so it should be done on the first window in the tab.
Inside netrw:
%create new file, more info:help netrw-%dcreate new directoryRrename file/directory under cursorDdelete file/directory under cursor
NERD tree
- to change current directory to selected folder, type in normal mode
cd. It will change directory only in current buffer. - refresh with
r(selected dir) orR(all) - to preview file you have to open
:NERDTreeToggleinstead of:e .and that you can usegoto preview or<cr>to jump to file. To remap<cr>for preview and to cursor stay you can add" https://github.com/preservim/nerdtree/issues/1123#issuecomment-628737990 let NERDTreeCustomOpenArgs = {'file':{'where':'p','keepopen':1,'stay':1}} let g:NERDTreeMapPreview = "<CR>"
CTAGS
You need to generate tags file with ctags -R .. You can use default params.
# ~/.ctags
--recurse=yes
--exclude=.git
--exclude=log
--languages=ruby
Some vim keys:
^]ctrl-] : jump to tag under cursor^tjump back in tags stack, stack is when you jump with ^], see all with:tags. You can open in split window<ctrl-w> ]^x^]autocomplete tagsg]list all ambiguous tags: same method could be defined in multiple classes:ts my_metselect tags for my_met.:tfirst:tnextto jump next- To search for all tags that contains met use
:tag /metand pressTo open a window (preview window) and stays at current position you can use `:ptag met` (close preview window with `:pclose`). ctrp tags
To generate tags for all gems install https://github.com/tpope/gem-ctags
gem install gem-ctags
gem ctags
Create template to git hook http://tbaggery.com/2011/08/08/effortless-ctags-with-git.html
Also use CtrlPTag so you can navigate to tag
Syntastic checker
Instead of synstastic I use ALE https://github.com/w0rp/ale
Results are put in location list so you can navigate with ] l.
" config/vim/ale.vim
" change message
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
" disable linter on change
let g:ale_lint_on_text_changed = 'never'
" use only erubylint
let g:ale_linters = {'eruby': ['erubylint']}
" enable airline
let g:airline#extensions#ale#enabled = 1
" use less invansive color for warnings
highlight ALEWarning ctermbg=DarkMagenta
" disable ale for all subrepositories under real-world-rails
let g:ale_pattern_options = {
\ '.*real-world-rails.*': { 'ale_enabled': 0},
\}
You can disable ALE with ALEToggle. You can see error message ALEDetail. Yo
see all configuration options ALEInfo.
There was issue with erb https://github.com/w0rp/ale/issues/580 but this
erubylint was recently removed from ale linters.
On Ruby 3.2.0 there is a warning
Passing trim_mode with the 3rd argument of erb.new is deprecated.
https://github.com/dense-analysis/ale/issues/4167 so maybe the solution could be to define it’s own linter like https://github.com/dense-analysis/ale/issues/580#issuecomment-337676607
Syntastic (deprecated, use ALE instead)
syntastic vim plugin is great to
write your code. Just need to install external syntac checkers and they will be
eabled. SyntasticInfo can give you current checkers and help
syntastic-checkers will show you all available checkers.
To check if some checker is installed you can try with system command (here we show current path):
:echo syntastic#util#system('echo "$PATH"')
You need to activate checkers for specific filetype and you can customise speific checker
let g:syntastic_<filetype>_checkers = ['<checker-name>']
let g:syntastic_<filetype>_<checker>_args = "--my --args --here"
Here is my configuration for syntastic and vim https://github.com/duleorlovic/config/blob/master/vim/syntastic.vim You need to install this tools:
- Markdown
gem install mdl -
Ruby, Rails
gem install rubocop. You can automatically fix some errors withrubocop --auto-correct Gemfile. Configuration is in .rubocop.yml in $HOME or project root. You can can generate TODO config file withrubocop --auto-gen-configMy preferred configuration is https://github.com/duleorlovic/config/blob/master/.rubocop.yml
- inline in comment
# rubocop:disable Metrics/AbcSize, Metrics/MethodLengthto disable whole file you can put at first line# rubocop:todo all - gem ‘rubocop-rspec’ is nice linter for rspec.
You can run manually with
-Dparam to see cop names.
- inline in comment
To disable some errors define quiet messages in syntastic.vim (:help
syntastic_quiet_messages)
g:syntastic_eruby_ruby_quiet_message
-
fix
possibly useless use of a constant in void contextin erb is with<%= CONST.to_s %>, when is problem with + than fix with assign<%= total = a + b; total %> - for js I use
jshintwith es6 and disabled semicolons - semicolons also disabled in
eslint(which extends from airbnb-base) inline comments# disable one line }(function( $, window, document, undefined ) { // eslint-disable-line - for styles I use
stylelintand local.stylelintrcsince version 9.10 does not pick my home configuration - Javascript
npm install -g jscs jscs-angularand create files [.jscs]( -
json
npm install -g jsonlintlink to issue" .vimrc au BufRead,BufNewFile *.json set filetype=json let g:syntastic_json_checkers=['jsonlint'] - coffeescript
npm install -g coffeelint
Vimium chrome extension
https://github.com/philc/vimium
Normal mode:
jandkdown and up on a pageffollow linksFfollow in new tabHandLback and forward in historyJandKprev and next tabosearch and open history linksTsearch open tabsrreload the pageggtop orGbottom of the pagegigo to first input element
Additional navigation commands:
yycopy current url to clipboardgugo up one level in URL pathgUgo to root of domain
Find mode, enter with /:
nandNnext and prev search match
Insert mode, enter with i. So if you notice that x closes tab even you are
inside input, jump into insert mode first…
Since gmail has own j k prev and next email, I added rule to ignore all
(*) keys
Do not know https://stackoverflow.com/questions/53918093/why-is-class-demo-button-so-special-in-vimium?noredirect=1#comment94679088_53918093
Vimum VimFx
Vimium-FF
VimFx does not support
firefox 57+
source is vimium for
firefox. f for navigation and clicks, / for search (n N), x X for close
and reopen tab, J K switch, space shift+space page down up.
Hints
mode:
fanything clicableFopens in new tab (or press Ctrl)ewnew window- by default lowercase letter will filter hint strings, but you can use uppercase letter to filter by text (you can see what is entered in lower right corner)
yfcopy text and links
Rails vim
Some todos:
Pluralize
- When I type
:Rcontroller customerit should go to:Rcontroller customersinstead of error:No such controller customer. This usually happens when I have a lot of modelscustomer_invoices,customer_paymentsandcustomers.
Localize
- When I’m in
index.html.erband I type:Rcontrollerthan I jump to controller, but if I’m onindex.in.html.erbthan there is an errorArgument required. Also problem with:Eview another_
Jump to system tests
Create scripts for vim
help usr_41.txt is Write a vim script in user manual.
https://en.wikibooks.org/wiki/Learning_the_vi_Editor/Vim/VimL_Script_language
Detect if some features are enabled, for example only on macOS :help
feature-list:
" copy to clipboard on macOS need to use pbcopy
if has('macunix')
vnoremap "+y :w !pbcopy<cr><cr>
endif
Vim scripts in ruby:
https://subvisual.co/blog/posts/139-how-to-program-vim-using-ruby/
Vim ruby support
:help ruby
Some integrated stuff in vim
https://github.com/vim-ruby/vim-ruby/blob/master/doc/vim-ruby.txt
https://github.com/vim-ruby/vim-ruby/wiki/VimRubySupport
WHEREAMI my plugin to show dedented lines above
When looking at large files in small window (I have 4 vim windows in my single terminal window) than I want to see to which block current line belongs. In schema.rb, current line in which table ?
ActiveRecord::Schema.define(version: 20170124131420) do
create_table "projects", force: :cascade do |t|
... long ...
t.integer title
In ability.rb, current ability to which user ?
When I’m in long spec file, I want to see setup block for current example and all outer example groups (maybe to group all descriptions in one sentence).
RSpec.describe Project do
let(:project) { Project.new }
before
... long ...
describe "create task" do
... long ...
it "order by date" do
project
Also in view, I want to be able where current element belongs, so list all wrapped elements. And when I’m in scss I want to see all parent selector, classes and media queries.
Solution is to use similar row as in https://github.com/chrisbra/csv.vim
:Header
similar but does not work for rspec
http://vim-taglist.sourceforge.net/installation.html :TlistToggle
Nice example of opening sidewindow is undotree plugin Also similar showing info per each line is vim-fugitive plugin
usage:
- in rspec you can see all previous describe blocks
- in db/schema.rb when you search for column_name, you can see in which table this column under cursor belongs to
My solution is using search https://github.com/duleorlovic/config/blob/master/bin/whereami.rb which I mapped to leader w
" whereami
set errorformat+=%f%l%m
set grepprg=~/config/bin/whereami.rb
" move to function and use silent
" three <cr> one for execute, one for grep and one for copen to jump back to line
nnoremap <leader>w :execute ":grep %:p " . line('.') . "\|clast\|copen"<cr><cr><cr>
TODO: try to follow the cursor
RubocopFix vim plugin rubocop
Fix current rubocop errors and comment uncorrectable
rubocop --auto-correct --disable-uncorrectable
but this is applying to whole file
TODO: write vim code that takes only the patch which is on current line
Graph visualization in markdown
https://markvis-editor.js.org/
Debug profile startup time
- if vim does not show properly, blank or empty screen, try
:redraw!
https://github.com/bchretien/vim-profiler
Vim test
https://8thlight.com/blog/chris-jordan/2016/06/13/running-tests-in-vim.html
" run single rspec test example for current line
nnoremap <leader>rs :execute "!rspec %:" . line(".")<cr>
" set compiler
:compiler rspec
:make %
Place language specific (file type) plugins inside ~/.vim/ftplugin/ruby.vim so
they are automatically loaded when you open ruby file.
Use https://github.com/janko-m/vim-test
<leader>ttest nearest spec to the line (if not inside example, whole file will be run):TestNearest<leader>Ttest whole file:TestFile<leader>atest whole suite:TestSuite<leader>ltest last, usefull if you navigate to the code and see if test pass:TestLast<leader>gvisit test, jump back to the test to write more tests:TestVisit
I use strategy let test#strategy = "dispatch". Asyncrun will not correctly
parse errors:
# instead of one error
# AsyncRun show two
expected `#<User id: 1061, email: "[email protected]", created_at: "2017-09-23 09|19| 48", updated_at: "2017-09-23 09:19:48">.confirmed?` to return true, got false
spec/features/user_confirmation_spec.rb|25| in `block (2 levels) in <top (required)>'
I prefer to use xdotool and send command to actual window
" config/vim/ftplugin/ruby.vim
function! EchoStrategy(cmd)
let current_window = system('xdotool getactivewindow | tr -d "\n"')
let target_window = system('xdotool search --classname vp_3_class_slash | tr -d "\n"')
execute 'Dispatch! xdotool windowactivate --sync '.target_window.' type "'.a:cmd.'"; xdotool key --delay 50 space Return windowactivate '.current_window
endfunction
let g:test#custom_strategies = {'echo': function('EchoStrategy')}
let g:test#strategy = 'echo'
Vim plugin
https://github.com/junegunn/vim-plug vim plugin manager is installed with one
command curl -fLo ~/.vim/autoload/plug.vim --create-dirs
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim and setup
in .vimrc
call plug#begin('~/.vim/plugged')
" Make sure you use single quotes
" Shorthand notation; fetches https://github.com/junegunn/vim-easy-align
Plug 'junegunn/vim-easy-align'
call plug#end()
And install with PlugInstall
Vim Color Scheme
https://github.com/nightsense/vimspectr is installed using vim-plug
Plug 'nightsense/vimspectr'
colorscheme vimspectr60flat-dark
but I prefer to tweek one by one color
highlight Comment cterm=underline ctermbg=Blue ctermfg=White
You can find example color scheme :e $VIMRUNTIME/colors
term defines attribute in black and white terminal, cterm in color terminal.
cterm accepts bold underline reverse italic but no colors.
ctermfg and ctermbg accepts colors, list of all on :help cterm-color
Highlight groups can be found on
highlight-groups
To see where the color is defined use verbose, for example
verbose hi Comment
Using ALE I see :help g:ale_set_highlights that groups are ALEError,
ALEWarning … so I use less invasive color:
hi ALEWarning m
If color is not properly set and wrong wile scrolling bottom to top, that could
be since vim does not read whole file. You can refresh with ctrl-l
Folding
In visual mode you can select and run :fold to collapse. Also as operator in
normal mode you can use zfap a paragraf. zo is to open, zc it to close
again (if fold already created on that line previously), zr to reduce (open)
and zm to minimize (close) all folds in buffer. Use zM and zR to
recursivelly close and open all nested folds. zn disable zN brings back the
folding.
To see all lines that can be folded you can :set foldcolumnd=2.
To automatically open and close folds when you navigate over it use :set
foldopen=all and :set foldclose=all
Save all fold positions with :mkview and load with :loadview
Automatically create folds based on indent :set foldmethod=indent
You can hide copy right sections of other comments.
" .vimrc
" https://stackoverflow.com/questions/2250011/can-i-have-vim-ignore-a-license-block-at-the-top-of-a-file
function! FoldCopyright()
if !exists( "b:foldedCopyright" )
let b:foldedCopyright = 1
silent! 1,/# Copyright/;/USA\.$/fold
endif
endfunction
autocmd BufNewFile,BufRead *.rb call FoldCopyright()
If you use autocmd FileType vim setlocal foldmethod=marker marker method than
any lines that starts and ends with { { { …. }}} can be toggled with za
Database
Use https://github.com/tpope/vim-db and access with
:DB mysql://username:password@localhost/my_db_test
Tmux
Not using for now
- strange characters instead of single quote I see
<91>and<92>in vim. https://superuser.com/questions/199799/vim-shows-strange-characters-91-92 run:%s/[\x91\x92]/'/gto replace them
https://handbook.infinum.co/books/rails/Editors/Vim https://emily.st/2018/11/13/vim-in-the-future/ https://onivim.io/ https://neovim.io/doc/ https://github.com/neoclide/coc.nvim Visual studio plugins running on vim
# you need to install coc using yarn
cd ~/.vim/bundle/coc.nvim/
yarn
and you can install plugins
:CocInfo
:CocInstall coc-yaml
:CocConfig
# to edit `~/.vim/coc-settings.json`