分享我的 Vim 設定檔 (vimrc)
October 18, 2019
平常有用 Vim 在寫 Go, Python, PHP, JavaScript, HTML, Markdown…等,以不用滑鼠的寫作習慣這樣還算可以應付。從零想要快速進入一個「仿 IDE」的使用環境的話可以直接試試我的配置(我是用 vim-plug 作 Vim plugin manager),但 Vim 的配置就跟自己的親生小孩一樣,畢竟是自己的致愛,是很需要花時間自己養成的!自己才知道自己需要什麼~ 每個人習慣的「手路」都不一樣。也可以參考網路上大大的討論來發現新玩意兒,我比較常看的 Telegram 討論群組有 Vim 中文 和 Vim 正體中文社群。
Vim 螢幕截圖
.vimrc
| " curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ | |
| " https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim | |
| " Specify a directory for plugins | |
| " - For Neovim: ~/.local/share/nvim/plugged | |
| " - Avoid using standard Vim directory names like 'plugin' | |
| call plug#begin('~/.vim/plugged') | |
| Plug 'mhinz/vim-startify' | |
| Plug 'tpope/vim-obsession' | |
| Plug 'joshdick/onedark.vim' | |
| Plug 'dracula/vim', { 'as': 'dracula' } | |
| Plug 'tpope/vim-fugitive' | |
| Plug 'ryanoasis/vim-devicons' | |
| Plug 'majutsushi/tagbar' | |
| nmap <F8> :TagbarToggle<CR> | |
| let g:tagbar_type_go = { | |
| \ 'ctagstype' : 'go', | |
| \ 'kinds' : [ | |
| \ 'p:package', | |
| \ 'i:imports:1', | |
| \ 'c:constants', | |
| \ 'v:variables', | |
| \ 't:types', | |
| \ 'n:interfaces', | |
| \ 'w:fields', | |
| \ 'e:embedded', | |
| \ 'm:methods', | |
| \ 'r:constructor', | |
| \ 'f:functions' | |
| \ ], | |
| \ 'sro' : '.', | |
| \ 'kind2scope' : { | |
| \ 't' : 'ctype', | |
| \ 'n' : 'ntype' | |
| \ }, | |
| \ 'scope2kind' : { | |
| \ 'ctype' : 't', | |
| \ 'ntype' : 'n' | |
| \ }, | |
| \ 'ctagsbin' : 'gotags', | |
| \ 'ctagsargs' : '-sort -silent' | |
| \ } | |
| Plug 'ludovicchabant/vim-gutentags' | |
| Plug 'skywind3000/gutentags_plus' | |
| Plug 'multilobyte/gtags-cscope' | |
| let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project'] | |
| let g:gutentags_ctags_tagfile = '.tags' | |
| let g:gutentags_modules = [] | |
| if executable('ctags') | |
| let g:gutentags_modules += ['ctags'] | |
| endif | |
| if executable('gtags-cscope') && executable('gtags') | |
| let g:gutentags_modules += ['gtags_cscope'] | |
| endif | |
| let g:gutentags_cache_dir = expand('~/.cache/tags') | |
| let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extras=+q'] | |
| let g:gutentags_ctags_extra_args += ['--c++-kinds=+px'] | |
| let g:gutentags_ctags_extra_args += ['--c-kinds=+px'] | |
| let g:gutentags_ctags_extra_args += ['--PHP-kinds=+cf'] | |
| let g:gutentags_ctags_extra_args += ['--Go-kinds=+cf'] | |
| let g:gutentags_ctags_extra_args += ['--output-format=e-ctags'] | |
| let g:gutentags_auto_add_gtags_cscope = 0 | |
| let g:gutentags_define_advanced_commands = 1 | |
| let g:gutentags_ctags_exclude = ['*.css', '*.html', '*.json', '*.xml', | |
| \ '*.phar', '*.ini', '*.rst', '*.md', '*.bin', | |
| \ '*storage/*', '*vendor/*', '*node_modules/*', '*public/*'] | |
| let g:gutentags_plus_switch = 1 | |
| Plug 'tpope/vim-repeat' | |
| Plug 'airblade/vim-gitgutter' | |
| let g:gitgutter_highlight_lines = 0 | |
| nmap ]h <Plug>GitGutterNextHunk | |
| nmap [h <Plug>GitGutterPrevHunk | |
| " Plug 'nsf/gocode' | |
| Plug 'dgryski/vim-godef' | |
| Plug 'fatih/vim-go' | |
| let g:go_highlight_functions = 1 | |
| let g:go_highlight_methods = 1 | |
| let g:go_highlight_structs = 1 | |
| let g:go_highlight_operators = 1 | |
| let g:go_highlight_build_constraints = 1 | |
| let g:go_fmt_command = "goimports" | |
| let g:go_def_mode = "godef" | |
| let g:go_def_mapping_enabled = 0 | |
| let g:go_def_use_buffer = 1 | |
| let g:go_fmt_autosave = 1 | |
| Plug 'sheerun/vim-polyglot' | |
| Plug 'empanda/vim-varnish' | |
| Plug 'yukpiz/vim-volt-syntax' | |
| Plug 'dag/vim-fish' | |
| Plug 'pearofducks/ansible-vim', { 'do': 'cd ./UltiSnips; ./generate.py' } | |
| au BufRead,BufNewFile */playbooks/*.yml set filetype=yaml.ansible | |
| augroup ansible_vim_fthosts | |
| autocmd! | |
| autocmd BufNewFile,BufRead hosts setfiletype yaml.ansible | |
| augroup END | |
| Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } | |
| map <F1> :NERDTreeToggle<CR> | |
| Plug 'scrooloose/nerdcommenter' | |
| let g:NERDSpaceDelims = 1 | |
| let g:NERDCompactSexyComs = 1 | |
| let g:NERDDefaultAlign = 'left' | |
| let g:NERDAltDelims_java = 1 | |
| let g:NERDCustomDelimiters = { 'c': { 'left': '/**','right': '*/' } } | |
| let g:NERDCommentEmptyLines = 1 | |
| let g:NERDTrimTrailingWhitespace = 1 | |
| Plug 'Xuyuanp/nerdtree-git-plugin' | |
| Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --bin' } | |
| Plug 'junegunn/fzf.vim' | |
| let g:fzf_command_prefix = 'Fzf' | |
| nnoremap <C-b> :FzfBuffers<CR> | |
| nnoremap <C-p> :FzfFiles<CR> | |
| nnoremap <C-a> :FzfAg<CR> | |
| " nnoremap <C-c> :FzfCommands<CR> | |
| " nnoremap <leader><leader> :FzfCommands<CR> | |
| nnoremap <C-g> :call FzfOmniFiles()<CR> | |
| fun! FzfOmniFiles() | |
| let is_git = system('git status') | |
| if v:shell_error | |
| :FzfFiles | |
| else | |
| :FzfGitFiles | |
| endif | |
| endfun | |
| " This is the default extra key bindings | |
| let g:fzf_action = { | |
| \ 'ctrl-t': 'tab split', | |
| \ 'ctrl-x': 'split', | |
| \ 'ctrl-v': 'vsplit' } | |
| " Default fzf layout | |
| " - down / up / left / right | |
| let g:fzf_layout = { 'down': '~40%' } | |
| " Customize fzf colors to match your color scheme | |
| let g:fzf_colors = | |
| \ { 'fg': ['fg', 'Normal'], | |
| \ 'bg': ['bg', 'Normal'], | |
| \ 'hl': ['fg', 'Comment'], | |
| \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], | |
| \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], | |
| \ 'hl+': ['fg', 'Statement'], | |
| \ 'info': ['fg', 'PreProc'], | |
| \ 'border': ['fg', 'Ignore'], | |
| \ 'prompt': ['fg', 'Conditional'], | |
| \ 'pointer': ['fg', 'Exception'], | |
| \ 'marker': ['fg', 'Keyword'], | |
| \ 'spinner': ['fg', 'Label'], | |
| \ 'header': ['fg', 'Comment'] } | |
| " Enable per-command history. | |
| " CTRL-N and CTRL-P will be automatically bound to next-history and | |
| " previous-history instead of down and up. If you don't like the change, | |
| " explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS. | |
| let g:fzf_history_dir = '~/.local/share/fzf-history' | |
| Plug 'tpope/vim-unimpaired' | |
| Plug 'jiangmiao/auto-pairs' | |
| Plug 'terryma/vim-multiple-cursors' | |
| Plug 'neoclide/coc.nvim', {'do': './install.sh nightly'} | |
| command! -nargs=0 Prettier :CocCommand prettier.formatFile | |
| set hidden | |
| set nobackup | |
| set nowritebackup | |
| set updatetime=300 | |
| set shortmess+=c | |
| set signcolumn=yes | |
| " use <tab> for trigger completion and navigate to the next complete item | |
| function! s:check_back_space() abort | |
| let col = col('.') - 1 | |
| return !col || getline('.')[col - 1] =~ '\s' | |
| endfunction | |
| inoremap <silent><expr> <Tab> | |
| \ pumvisible() ? "\<C-n>" : | |
| \ <SID>check_back_space() ? "\<Tab>" : | |
| \ coc#refresh() | |
| inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>" | |
| inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>" | |
| inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>" | |
| inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm() : "\<C-g>u\<CR>" | |
| autocmd! CompleteDone * if pumvisible() == 0 | pclose | endif | |
| inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>" | |
| nmap <silent> [c <Plug>(coc-diagnostic-prev) | |
| nmap <silent> ]c <Plug>(coc-diagnostic-next) | |
| nmap <silent> gd <Plug>(coc-definition) | |
| nmap <silent> gy <Plug>(coc-type-definition) | |
| nmap <silent> gi <Plug>(coc-implementation) | |
| nmap <silent> gr <Plug>(coc-references) | |
| nnoremap <silent> K :call <SID>show_documentation()<CR> | |
| function! s:show_documentation() | |
| if (index(['vim','help'], &filetype) >= 0) | |
| execute 'h '.expand('<cword>') | |
| else | |
| call CocAction('doHover') | |
| endif | |
| endfunction | |
| autocmd CursorHold * silent call CocActionAsync('highlight') | |
| nmap <leader>rn <Plug>(coc-rename) | |
| xmap <leader>f <Plug>(coc-format-selected) | |
| nmap <leader>f <Plug>(coc-format-selected) | |
| augroup mygroup | |
| autocmd! | |
| autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') | |
| autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') | |
| augroup end | |
| xmap <leader>a <Plug>(coc-codeaction-selected) | |
| nmap <leader>a <Plug>(coc-codeaction-selected) | |
| nmap <leader>ac <Plug>(coc-codeaction) | |
| nmap <leader>qf <Plug>(coc-fix-current) | |
| command! -nargs=0 Format :call CocAction('format') | |
| command! -nargs=? Fold :call CocAction('fold', <f-args>) | |
| command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport') | |
| noremap <F3> :Format<CR> | |
| let g:airline#extensions#coc#enabled = 1 | |
| let airline#extensions#coc#stl_format_err = '%E{[%e(#%fe)]}' | |
| let airline#extensions#coc#stl_format_warn = '%W{[%w(#%fw)]}' | |
| Plug 'ap/vim-buftabline' | |
| Plug 'itchyny/lightline.vim' | |
| set laststatus=2 | |
| let g:lightline = { | |
| \ 'colorscheme': 'Tomorrow_Night_Eighties', | |
| \ 'active': { | |
| \ 'left': [ [ 'mode', 'paste' ], | |
| \ [ 'gitbranch', 'cocstatus', 'readonly', 'filename', 'modified' ] ] | |
| \ }, | |
| \ 'component_function': { | |
| \ 'cocstatus': 'coc#status', | |
| \ 'gitbranch': 'fugitive#head' | |
| \ }, | |
| \ 'separator': { | |
| \ 'left': '', | |
| \ 'right': '' | |
| \ }, | |
| \ 'subseparator': { | |
| \ 'left': '', | |
| \ 'right': '' | |
| \ } | |
| \ } | |
| nnoremap <silent> <space>a :<C-u>CocList diagnostics<cr> | |
| nnoremap <silent> <space>e :<C-u>CocList extensions<cr> | |
| nnoremap <silent> <space>c :<C-u>CocList commands<cr> | |
| nnoremap <silent> <space>o :<C-u>CocList outline<cr> | |
| nnoremap <silent> <space>s :<C-u>CocList -I symbols<cr> | |
| nnoremap <silent> <space>j :<C-u>CocNext<CR> | |
| nnoremap <silent> <space>k :<C-u>CocPrev<CR> | |
| nnoremap <silent> <space>p :<C-u>CocListResume<CR> | |
| Plug 'valloric/MatchTagAlways' | |
| let g:mta_set_default_matchtag_color = 0 | |
| let g:mta_use_matchparen_group = 0 | |
| nnoremap <leader>% :MtaJumpToOtherTag<cr> | |
| Plug 'easymotion/vim-easymotion' | |
| Plug 'christoomey/vim-tmux-navigator' | |
| " Initialize plugin system | |
| call plug#end() | |
| syntax on | |
| set tabstop=4 | |
| set shiftwidth=4 | |
| set expandtab | |
| " set background=dark | |
| set t_Co=256 | |
| " set termguicolors | |
| set hlsearch | |
| set relativenumber | |
| set nu | |
| " set cursorline | |
| set re=1 | |
| set ttyfast | |
| set lazyredraw | |
| " set synmaxcol=128 | |
| " syntax sync minlines=256 | |
| set backspace=2 | |
| set backspace=indent,eol,start | |
| set encoding=UTF-8 | |
| colorscheme onedark | |
| " colorscheme dracula | |
| highlight Normal ctermfg=grey ctermbg=black | |
| highlight MatchTag ctermfg=black ctermbg=Yellow guifg=black guibg=Yellow | |
| filetype plugin on | |
| autocmd FileType javascript setlocal shiftwidth=2 tabstop=2 | |
| autocmd FileType html setlocal shiftwidth=2 tabstop=2 | |
| if !has('nvim') | |
| set viminfo='100,n$HOME/.vim/files/info/viminfo' | |
| endif | |
| vmap <C-c> :w !xclip -selection clipboard<CR><CR> | |
| noremap <F2> :set hlsearch! hlsearch?<CR> | |
| nnoremap <CR> :nohlsearch<CR><CR> | |
| function InlineCommand() | |
| let l:cmd = input('Command: ') | |
| let l:output = system(l:cmd) | |
| let l:output = substitute(l:output, '[\r\n]*$', '', '') | |
| execute 'normal i' . l:output | |
| endfunction | |
| nmap <silent> \e :call InlineCommand()<CR> | |
| nnoremap <C-W>O :call MaximizeToggle()<CR> | |
| nnoremap <C-W>o :call MaximizeToggle()<CR> | |
| nnoremap <C-W><C-O> :call MaximizeToggle()<CR> | |
| function! MaximizeToggle() | |
| if exists("s:maximize_session") | |
| exec "source " . s:maximize_session | |
| call delete(s:maximize_session) | |
| unlet s:maximize_session | |
| let &hidden=s:maximize_hidden_save | |
| unlet s:maximize_hidden_save | |
| else | |
| let s:maximize_hidden_save = &hidden | |
| let s:maximize_session = tempname() | |
| set hidden | |
| exec "mksession! " . s:maximize_session | |
| only | |
| endif | |
| endfunction | |
| execute "set t_8f=\e[38;2;%lu;%lu;%lum" | |
| execute "set t_8b=\e[48;2;%lu;%lu;%lum" |