Jak ogarnąć edytor VIM

Konfiguracja oraz korzystanie z wieloplatformowego edytora VIM. W tym wpisie opiszę krok po kroku jak zacząć używać tego świetnego edytora. Oczywiście podam też rozwiązanie, które zwłaszcza młodym adeptom sprawia na tyle dużo trudności, że powstało wiele memów o tej tematyce.

Instalacja i konfiguracja VIMa

$ sudo apt-get install vim

Będziemy potrzebowali też GITa

$ sudo apt-get install git ctags cmake python-pip ack
$ sudo pip install git+git://github.com/Lokaltog/powerline

Pobieramy instalatora pluginów

$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

Przechodzimy do katalogu vima i wykonujemy polecenia

$ cd ~/.vim/bundle/
$ git clone https://github.com/Valloric/YouCompleteMe
$ cd YouCompleteMe
$ git submodule update --init --recursive
$ ./install.py --clang-completer

Wklejamy do pliku .vimrc w katalogu głównym


set ai
set ts=4
set sts=4
set et
set sw=4
set number                    " line numbers
" set relativenumber
set nocp                      " podpowiadanie polecen systemowych
set nocompatible              " be iMproved, required
set hls                       " highlighted searches
set wildmenu                  " podpowiadanie polecen
set laststatus=2
set encoding=utf-8
set backspace=2               " make backspace work like most other apps"

filetype off                  " required

let mapleader = ","

" vim as a man pager
runtime! ftplugin/man.vim

" shortcuts
nmap  :YRShow
set pastetoggle=
nmap  :noh
nmap  :tabnew
nmap  :PymodeRopeRegenerate
nmap  :GundoToggle
nmap  :NERDTreeToggle
nmap  :TagbarOpenAutoClose
nmap  :GoldenRatioToggle
nmap  :IndentGuidesToggle
nmap   (jsdoc)

" easier moving code of blocks
vnoremap < <gv " better indentation
vnoremap > >gv " better indentation

" substitute css/js links into django static
nnoremap mst :s/\(src\\|href\)=\
            \("\\|'\)
            \\(\#\\|http\\|\/\/\)\@!\([a-zA-Z0-9\-\/\.\_]\+\)\.\(\(\w\+\)\)
            \\("\\|'\)/
            \\1=\"{% static '\4.\5' %}"
            \:echo "static template tag added."

nnoremap mufs :s/\(src\\|href\)=\
            \("\\|'\)
            \\(\#\\|http\\|\/\/\)\@!\([a-zA-Z0-9\-\/\.\_]\+\)\.\(\(\w\+\)\)
            \\("\\|'\)/
            \\1=\"{{ url_for('static', filename='\4.\5') }}"
            \:echo "static template tag added."

" disable paste mode when leaving Insert Mode
au InsertLeave * set nopaste

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
Plugin 'Valloric/YouCompleteMe'
Plugin 'SirVer/ultisnips'
Plugin 'honza/vim-snippets'
Plugin 'majutsushi/tagbar'
Plugin 'tpope/vim-fugitive'
Plugin 'surround.vim'
Plugin 'tomasr/molokai'
Plugin 'flazz/vim-colorschemes'
Plugin 'scrooloose/syntastic'
Plugin 'taglist.vim'
Plugin 'jmcomets/vim-pony'
Plugin 'sukima/xmledit'
Plugin 'bling/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'Raimondi/delimitMate'
Plugin 'klen/python-mode'
Plugin 'The-NERD-tree'
Plugin 'The-NERD-Commenter'
Plugin 'Gundo' " cofanie zmian
Plugin 'shougo/vimproc'
Plugin 'shougo/vimshell'
Plugin 'nathanaelkane/vim-indent-guides'
Plugin 'mileszs/ack.vim' " wyszukiwanie tekstow
Plugin 'roman/golden-ratio' " dopasowanie wysokosci/szerokosci okna
Plugin 'ludovicchabant/vim-lawrencium' " mercurial
Plugin 'easymotion/vim-easymotion'
Plugin 'mattn/emmet-vim'
Plugin 'YankRing.vim'
Plugin 'ctrlpvim/ctrlp.vim'
Plugin 'jelera/vim-javascript-syntax'
Plugin 'MattesGroeger/vim-bookmarks'
Plugin 'mru.vim'  " ostatnio uzywane pliki :Mru
Plugin 'tmhedberg/SimpylFold'  " zwijanie
Plugin 'vimlatex'
Plugin 'VST'
Plugin 'fs111/pydoc.vim'
Plugin 'tacahiroy/ctrlp-funky'
Plugin 'thethirduniverse/delphi'
Plugin 'mhinz/vim-startify'
Plugin 'will133/vim-dirdiff'
Plugin 'rkulla/pydiction'  " Pydiction allows you to Tab-complete Python code in Vim such as keywords, built-ins, standard library, and third-party modules
Plugin 'compilerpython.vim'
Plugin 'hienvd/vim-stackoverflow' 
Plugin 'vim-scripts/py-coverage'  " Pokrycie kodu testami

" All of your Plugins must be added before the following line
call vundle#end()            " required
syntax on
filetype on
filetype plugin indent on    " required

let g:tex_flavor='latex'
let python_highlight_all=1

" UltiSnips
" " Trigger configuration. Do not use  if you use
" https://github.com/Valloric/YouCompleteMe.
let g:UltiSnipsExpandTrigger       = ""
let g:UltiSnipsJumpForwardTrigger=""
let g:UltiSnipsJumpBackwardTrigger=""
let g:UltiSnipsListSnippets        = "" "List possible snippets based on current file
let g:UltiSnipsEditSplit="vertical"
let g:ultisnips_python_style = 'sphinx'

function! g:UltiSnips_Complete()
    call UltiSnips#ExpandSnippet()
    if g:ulti_expand_res == 0
        if pumvisible()
            return "\"
        else
            call UltiSnips#JumpForwards()
            if g:ulti_jump_forwards_res == 0
               return "\"
            endif
        endif
    endif
    return ""
endfunction

au BufEnter * exec "inoremap  " . g:UltiSnipsExpandTrigger . " =g:UltiSnips_Complete()"
inoremap   pumvisible() ? "\" : "\u\"

au BufEnter,BufRead *.html,*.htm UltiSnipsAddFiletypes html.htmldjango
au BufEnter,BufRead *.rst UltiSnipsAddFiletypes rst.rst
au BufEnter,BufRead *.py UltiSnipsAddFiletypes python.python rst.rst
au BufEnter,BufRead *.js UltiSnipsAddFiletypes javascript.javascript
" Docker snippets
au BufEnter,BufRead docker-compose.yml UltiSnipsAddFiletypes docker.docker
au BufEnter,BufRead Dockerfile UltiSnipsAddFiletypes docker.docker
au BufReadPost *.snippets set filetype=snippets
au BufEnter,BufRead *.snippets UltiSnipsAddFiletypes snippets.snippets
au BufReadPost *.snippets set filetype=snippets
au BufNewFile,BufRead *.html set filetype=htmldjango


let g:ycm_collect_identifiers_from_tags_files = 1 " Let YCM read tags from Ctags file
let g:ycm_use_ultisnips_completer = 1 " Default 1, just ensure
let g:ycm_seed_identifiers_with_syntax = 1 " Completion for programming language's keyword
let g:ycm_complete_in_comments = 1 " Completion in comments
let g:ycm_complete_in_strings = 1 " Completion in string
let g:snips_author = 'Piotr Bagiński'
let g:snips_email = 'pbaginski@grupazpr.pl'
let g:snips_github = 'https://github.com/nestation'

" Ack search
let g:ackhighlight = 1
let g:ackpreview = 1
let g:ack_autoclose = 1
let g:ack_default_options =
              \ " -s -H --nogroup --column --smart-case --follow --ignore-directory=htmlcov/ --ignore-dir=migrations/"

" Syntastic
let g:syntastic_always_populate_loc_list = 1 " automatyczne dopisywanie bledow skladni
let g:syntastic_aggregate_errors = 1 " wyswietlanie wszystkich bledow w pliku
let g:last_relative_dir = ''

nnoremap \1 :call RelatedFile ("models.py")
nnoremap \2 :call RelatedFile ("views.py")
nnoremap \3 :call RelatedFile ("urls.py")
nnoremap \4 :call RelatedFile ("admin.py")
nnoremap \5 :call RelatedFile ("managers.py")
nnoremap \6 :call RelatedFile ("templates/")
nnoremap \7 :call RelatedFile ("templatetags/")
nnoremap \8 :call RelatedFile ("management/")
nnoremap \0 :e settings.py
nnoremap \9 :e urls.py

fun! RelatedFile(file)
    " This is to check that the directory looks djangoish
    if filereadable(expand("%:h"). '/models.py') || isdirectory(expand("%:h") . "/templatetags/")
        exec "edit %:h/" . a:file
        let g:last_relative_dir = expand("%:h") . '/'
        return ''
    endif
    if g:last_relative_dir != ''
        exec "edit " . g:last_relative_dir . a:file
        return ''
    endif
        echo "Cant determine where relative file is : " . a:file
        return ''
endfun

fun SetAppDir()
    if filereadable(expand("%:h"). '/models.py') || isdirectory(expand("%:h") . "/templatetags/")
        let g:last_relative_dir = expand("%:h") . '/'
        return ''
    endif
endfun
autocmd BufEnter *.py call SetAppDir()

" Project
let Tlist_Auto_Highlight_Tag = 0
let Tlist_Auto_Open = 0
let Tlist_Use_Right_Window = 1

" Airline
let g:airline_powerline_fonts = 1
let g:airline_theme='kolor'
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#show_buffers = 0

" Gundo
let g:gundo_width = 60
let g:gundo_preview_height = 40
let g:gundo_right = 1

" pymode
let g:pymode_rope_completion = 0
let g:pymode_rope_complete_on_dot = 0
let g:pymode_rope_regenerate_on_write = 0
let g:pymode_rope_autoimport = 1
let g:pymode_rope_autoimport_import_after_complete = 0
let g:pymode_rope_autoimport_modules = ['os', 'shutil', 'datetime', 'django']
let g:pymode_rope_completion_bind = ''
let g:pymode_doc = 1
let g:pymode_lint = 1
let g:pymode_folding = 0
set foldlevelstart=99  " domyslnie wszystkie foldy otwarte
let g:pymode_lint_cwindow = 1
let g:pymode_lint_options_mccabe = { 'complexity': 8 }
let g:pymode_lint_on_write = 1
let g:pymode_lint_message = 1
let g:pymode_lint_checkers = ['pyflakes', 'mccabe', 'pep257', 'pep8', 'pylint']
let g:pymode_lint_ignore = "D100, D102, C0111,too-few-public-methods, old-style-class"

" Golden ratio
let g:golden_ratio_autocommand = 0
let g:golden_ratio_exclude_nonmodifiable = 1

au FileType python set omnifunc=pythoncomplete#Complete
au FileType html,xhtml setl ofu=htmlcomplete#CompleteTags
au FileType css setl ofu=csscomplete#CompleteCSS
let g:SuperTabDefaultCompletionType = "context"
set completeopt=menuone,longest,preview

" lawrencium
let g:lawrencium_auto_close_buffers = 1

" jshint2
let jshint2_read = 1
let jshint2_save = 1

" Delphi playground
" let g:use_delphi = 1

" make the 81st column stand out
" highlight ColorColumn ctermbg=red
" call matchadd('ColorColumn', '\%81v', 100)

" Highlights matches when jumping to next
" This rewires n and N to do the highlighing...
nnoremap  n   n:call HLNext(0.4)
nnoremap  N   N:call HLNext(0.4)

" EITHER blink the line containing the match...
function! HLNext (blinktime)
    highlight RedOnRed ctermfg=red ctermbg=red
    let [bufnum, lnum, col, off] = getpos('.')
    let matchlen = strlen(matchstr(strpart(getline('.'),col-1),@/))
    echo matchlen
    let ring_pat = (lnum > 1 ? '\%'.(lnum-1).'l\%>'.max([col-4,1]) .'v\%<'.(col+matchlen+3).'v.\|' : '')
            \ . '\%'.lnum.'l\%>'.max([col-4,1]) .'v\%<'.col.'v.'
            \ . '\|'
            \ . '\%'.lnum.'l\%>'.max([col+matchlen-1,1]) .'v\%<'.(col+matchlen+3).'v.'
            \ . '\|'
            \ . '\%'.(lnum+1).'l\%>'.max([col-4,1]) .'v\%<'.(col+matchlen+3).'v.'
    let ring = matchadd('RedOnRed', ring_pat, 101)
    redraw
    exec 'sleep ' . float2nr(a:blinktime * 1000) . 'm'
    call matchdelete(ring)
    redraw
endfunction

" different colorschema when using vimdiff
if &diff
    colorscheme BlackSea
endif

" kolory
:hi TabLineFill ctermfg=Black ctermbg=1
:hi TabLineSel ctermfg=7 ctermbg=166 " aktywna zakładka
:hi TabLine ctermfg=7 ctermbg=56 " nieaktywna załadka
:hi Pmenu ctermfg=7 ctermbg=56 " rozwijane menu
:hi PmenuSel ctermfg=7 ctermbg=166 " select w menu
:hi WildMenu ctermfg=7 ctermbg=56 " podpowiadanie cmd
:hi VertSplit ctermfg=0
:hi MatchParen ctermbg=white ctermfg=red " podswietlanie tagów
:hi DiffText ctermbg=26
:hi DiffChange ctermbg=12

" Underline the current line with dashes in normal mode
nnoremap  yyp$r-

" Underline the current line with dashes in insert mode
inoremap  yyp$r-A

let g:startify_enable_special         = 0
let g:startify_files_number           = 10
let g:startify_relative_path          = 1
let g:startify_change_to_dir          = 1
let g:startify_session_autoload       = 1
let g:startify_session_persistence    = 1
let g:startify_session_delete_buffers = 1

let g:startify_skiplist = [
            \ 'COMMIT_EDITMSG',
            \ ]

let g:startify_custom_header =
      \ map(split(system('fortune | cowsay -f daemon'), '\n'), '"   ". v:val') + ['']

let g:startify_bookmarks = [
            \ { 'w': '/home/pbaginski/Projekty/' },
            \ { 'h': '/home/pbaginski/' },
            \ { 's': 'settings.py' },
            \ { 'ls': 'local_settings.py' },
            \ { 'mv': '~/.vimrc' },
            \ ]

hi StartifyBracket ctermfg=240
hi StartifyFile    ctermfg=99
hi StartifyFooter  ctermfg=240
hi StartifyHeader  ctermfg=114
hi StartifyNumber  ctermfg=215
hi StartifyPath    ctermfg=246
hi StartifySlash   ctermfg=240
hi StartifySpecial ctermfg=240

" JSDoc
let g:jsdoc_allow_input_prompt = 1
let g:jsdoc_input_description = 1
let g:jsdoc_additional_descriptions = 1

" YAML
" You can trigger reindent by typing CTRL-F in INSERT mode
filetype plugin indent on
autocmd FileType yaml setl indentkeys-=

" Pydiction
let g:pydiction_location = '~/.vim/bundle/pydiction/complete-dict'

if has('gui_running')
    set background=light
    colorscheme solarized
    set guioptions-=m  "remove menu bar
    set guioptions-=T  "remove toolbar
    set guioptions-=r  "remove right-hand scroll bar
    set guioptions-=L  "remove left-hand scroll bar
endif
nnoremap soll :set background=light:colorscheme solarized:AirlineTheme solarized
nnoremap sold :set background=dark:colorscheme solarized

" let hour = strftime("%H")
" if 12 <= hour && hour < 20
"   set background=light
"   colorscheme solarized
" endif

let &path = getcwd() . '/templates'

hi SpellBad ctermfg=232 ctermbg=160 guifg=#000000 guibg=#990000

:hi PyCoverageMissed term=reverse ctermfg=white ctermbg=darkred

nnoremap \ne :lnext
nnoremap \pe :lprev
colorscheme basic-dark

Uruchamiamy edytor VIM

$ vim

Wydajemy polecenie aktualizacji pluginów

:PluginInstall

Przydatne polecenia


" zamknięcie pojedynczego okna
:q
" zamknięcie wszystkich okien
:qa
" zamknięcie wszystkich okien ignorując niezapisane zmiany
:qa!
" zapisanie zmian w aktywnym oknie
:w
" otwarcie pliku ze wskazanej ścieżki w bieżącym oknie
:e ścieżka/do/pliku
" sprawdzenie ścieżki do aktualnie otwartego pliku
:echo @%
" otwarcie pliku w nowej zakładce
:tabnew ścieżka/do/pliku
" split pionowy
:vsplit ścieżka/do/pliku
" split poziomy
:split ścieżka/do/pliku 
" szukanie frazy w otwartym pliku
/fraza
" szukamy frazy w bieżącym folderze
:Ack fraza
" szukamy frazy w określonym folderze
:Ack fraza folder/
" przechodzenie między oknami
ctrl w
" zaznaczanie wybranego tekstu
v

Komentarze