├── .vimrc ├── README.md └── plugin └── netrwPlugin.vim /.vimrc: -------------------------------------------------------------------------------- 1 | " vim:set expandtab shiftwidth=2 tabstop=8 textwidth=72: 2 | 3 | if exists('$VIM_TERMINAL') 4 | echoerr 'Do not run Vim inside a Vim terminal' 5 | quit 6 | endif 7 | 8 | if has('autocmd') 9 | " 为了可以重新执行 vimrc,开头先清除当前组的自动命令 10 | au! 11 | endif 12 | 13 | if has('gui_running') 14 | " 下面两行仅为占位使用;请填入你自己的字体 15 | set guifont= 16 | set guifontwide= 17 | 18 | " 不延迟加载菜单(需要放在下面的 source 语句之前) 19 | let do_syntax_sel_menu = 1 20 | let do_no_lazyload_menus = 1 21 | endif 22 | 23 | set enc=utf-8 24 | source $VIMRUNTIME/vimrc_example.vim 25 | 26 | " 启用 man 插件 27 | source $VIMRUNTIME/ftplugin/man.vim 28 | 29 | set fileencodings=ucs-bom,utf-8,gb18030,latin1 30 | set formatoptions+=mM 31 | set keywordprg=:Man 32 | set scrolloff=1 33 | set spelllang+=cjk 34 | set tags=./tags;,tags,/usr/local/etc/systags 35 | set nobackup 36 | 37 | if has('persistent_undo') 38 | set undofile 39 | set undodir=~/.vim/undodir 40 | if !isdirectory(&undodir) 41 | call mkdir(&undodir, 'p', 0700) 42 | endif 43 | endif 44 | 45 | if has('mouse') 46 | if has('gui_running') || (&term =~ 'xterm' && !has('mac')) 47 | set mouse=a 48 | else 49 | set mouse=nvi 50 | endif 51 | endif 52 | 53 | if !has('gui_running') 54 | " 设置文本菜单 55 | if has('wildmenu') 56 | set wildmenu 57 | set cpoptions-=< 58 | set wildcharm= 59 | nnoremap :emenu 60 | inoremap :emenu 61 | endif 62 | 63 | " 识别终端的真彩支持 64 | if has('termguicolors') && 65 | \($COLORTERM == 'truecolor' || $COLORTERM == '24bit') 66 | set termguicolors 67 | endif 68 | endif 69 | 70 | if exists('g:loaded_minpac') 71 | " Minpac is loaded. 72 | call minpac#init() 73 | call minpac#add('k-takata/minpac', {'type': 'opt'}) 74 | 75 | " Other plugins 76 | call minpac#add('adah1972/vim-copy-as-rtf') 77 | call minpac#add('airblade/vim-gitgutter') 78 | call minpac#add('junegunn/fzf', {'do': {-> fzf#install()}}) 79 | call minpac#add('junegunn/fzf.vim') 80 | call minpac#add('majutsushi/tagbar') 81 | call minpac#add('mbbill/undotree') 82 | call minpac#add('mg979/vim-visual-multi') 83 | call minpac#add('preservim/nerdcommenter') 84 | call minpac#add('preservim/nerdtree') 85 | call minpac#add('skywind3000/asyncrun.vim') 86 | call minpac#add('tpope/vim-eunuch') 87 | call minpac#add('tpope/vim-fugitive') 88 | call minpac#add('tpope/vim-repeat') 89 | call minpac#add('tpope/vim-surround') 90 | call minpac#add('vim-airline/vim-airline') 91 | call minpac#add('vim-scripts/SyntaxAttr.vim') 92 | call minpac#add('yegappan/mru') 93 | endif 94 | 95 | if has('eval') 96 | " Minpac commands 97 | command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update() 98 | command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean() 99 | command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status() 100 | 101 | " 和 asyncrun 一起用的异步 make 命令 102 | command! -bang -nargs=* -complete=file Make AsyncRun -program=make @ 103 | endif 104 | 105 | if v:version >= 800 106 | packadd! editexisting 107 | endif 108 | 109 | " 修改光标上下键一次移动一个屏幕行 110 | nnoremap gk 111 | inoremap gk 112 | nnoremap gj 113 | inoremap gj 114 | 115 | " 切换窗口的键映射 116 | nnoremap w 117 | inoremap w 118 | nnoremap W 119 | inoremap W 120 | 121 | " 检查光标下字符的语法属性的键映射 122 | nnoremap a :call SyntaxAttr() 123 | 124 | " 替换光标下单词的键映射 125 | nnoremap v viw"0p 126 | vnoremap v "0p 127 | 128 | " 停止搜索高亮的键映射 129 | nnoremap :nohlsearch 130 | inoremap :nohlsearch 131 | 132 | " 映射按键来快速启停构建 133 | nnoremap :if g:asyncrun_status != 'running' 134 | \if &modifiable 135 | \update 136 | \endif 137 | \exec 'Make' 138 | \else 139 | \AsyncStop 140 | \endif 141 | 142 | " 开关撤销树的键映射 143 | nnoremap :UndotreeToggle 144 | inoremap :UndotreeToggle 145 | 146 | " 开关 Tagbar 插件的键映射 147 | nnoremap :TagbarToggle 148 | inoremap :TagbarToggle 149 | 150 | " 用于 quickfix、标签和文件跳转的键映射 151 | if !has('mac') 152 | nnoremap :cn 153 | nnoremap :cp 154 | else 155 | nnoremap :cn 156 | nnoremap :cp 157 | endif 158 | nnoremap :copen 159 | nnoremap :cclose 160 | nnoremap :tn 161 | nnoremap :tp 162 | nnoremap :n 163 | nnoremap :prev 164 | 165 | if has('unix') && !has('gui_running') 166 | " Unix 终端下使用两下 Esc 来离开终端作业模式 167 | tnoremap 168 | else 169 | " 其他环境则使用 Esc 来离开终端作业模式 170 | tnoremap 171 | tnoremap 172 | endif 173 | 174 | if has('autocmd') 175 | function! GnuIndent() 176 | setlocal cinoptions=>4,n-2,{2,^-2,:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1 177 | setlocal shiftwidth=2 178 | setlocal tabstop=8 179 | endfunction 180 | 181 | " 异步运行命令时打开 quickfix 窗口,高度为 10 行 182 | let g:asyncrun_open = 10 183 | 184 | " 用于 Airline 的设定 185 | let g:airline_powerline_fonts = 1 " 如没有安装合适的字体,则应置成 0 186 | let g:airline#extensions#tabline#enabled = 1 187 | let g:airline#extensions#tabline#buffer_nr_show = 1 188 | let g:airline#extensions#tabline#overflow_marker = '…' 189 | let g:airline#extensions#tabline#show_tab_nr = 0 190 | 191 | " 非图形环境不使用 NERD Commenter 菜单 192 | if !has('gui_running') 193 | let g:NERDMenuMode = 0 194 | endif 195 | 196 | " 用于 YouCompleteMe 的设定 197 | let g:ycm_auto_hover = '' 198 | let g:ycm_complete_in_comments = 1 199 | let g:ycm_filetype_whitelist = { 200 | \ 'c': 1, 201 | \ 'cpp': 1, 202 | \ 'java': 1, 203 | \ 'python': 1, 204 | \ 'vim': 1, 205 | \ 'sh': 1, 206 | \ 'zsh': 1, 207 | \ } 208 | let g:ycm_goto_buffer_command = 'split-or-existing-window' 209 | let g:ycm_key_invoke_completion = '' 210 | let g:ycm_use_clangd = 1 211 | nnoremap fi :YcmCompleter FixIt 212 | nnoremap gt :YcmCompleter GoTo 213 | nnoremap gd :YcmCompleter GoToDefinition 214 | nnoremap gh :YcmCompleter GoToDeclaration 215 | nnoremap gr :YcmCompleter GoToReferences 216 | 217 | au FileType c,cpp,objc setlocal expandtab shiftwidth=4 softtabstop=4 tabstop=4 cinoptions=:0,g0,(0,w1 218 | au FileType json setlocal expandtab shiftwidth=2 softtabstop=2 219 | au FileType vim setlocal expandtab shiftwidth=2 softtabstop=2 220 | 221 | au FileType help nnoremap q c 222 | 223 | au BufRead /usr/include/* call GnuIndent() 224 | endif 225 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vim 实用技巧必知必会示例配置 2 | 3 | 这里是 [Vim 实用技巧必知必会](https://time.geekbang.org/column/324)的示例配置。 4 | -------------------------------------------------------------------------------- /plugin/netrwPlugin.vim: -------------------------------------------------------------------------------- 1 | " netrwPlugin.vim: Handles file transfer and remote directory listing across a network 2 | " PLUGIN SECTION 3 | " Date: Feb 08, 2016 4 | " Maintainer: Charles E Campbell 5 | " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim 6 | " Copyright: Copyright (C) 1999-2013 Charles E. Campbell {{{1 7 | " Permission is hereby granted to use and distribute this code, 8 | " with or without modifications, provided that this copyright 9 | " notice is copied with it. Like anything else that's free, 10 | " netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided 11 | " *as is* and comes with no warranty of any kind, either 12 | " expressed or implied. By using this plugin, you agree that 13 | " in no event will the copyright holder be liable for any damages 14 | " resulting from the use of this software. 15 | " 16 | " But be doers of the Word, and not only hearers, deluding your own selves {{{1 17 | " (James 1:22 RSV) 18 | " =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 19 | " Load Once: {{{1 20 | if &cp || exists("g:loaded_netrwPlugin") 21 | finish 22 | endif 23 | let g:loaded_netrwPlugin = "v156" 24 | let s:keepcpo = &cpo 25 | set cpo&vim 26 | "DechoRemOn 27 | 28 | " --------------------------------------------------------------------- 29 | " Public Interface: {{{1 30 | 31 | " Local Browsing Autocmds: {{{2 32 | augroup FileExplorer 33 | au! 34 | au BufLeave * if &ft != "netrw"|let w:netrw_prvfile= expand("%:p")|endif 35 | au BufEnter * sil call s:LocalBrowse(expand("")) 36 | au VimEnter * sil call s:VimEnter(expand("")) 37 | if has("win32") || has("win95") || has("win64") || has("win16") 38 | au BufEnter .* sil call s:LocalBrowse(expand("")) 39 | endif 40 | augroup END 41 | 42 | " Network Browsing Reading Writing: {{{2 43 | augroup Network 44 | au! 45 | au BufReadCmd file://* call netrw#FileUrlRead(expand("")) 46 | au BufReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufReadPre ".fnameescape(expand(""))|call netrw#Nread(2,expand(""))|exe "sil doau BufReadPost ".fnameescape(expand("")) 47 | au FileReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileReadPre ".fnameescape(expand(""))|call netrw#Nread(1,expand(""))|exe "sil doau FileReadPost ".fnameescape(expand("")) 48 | au BufWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufWritePre ".fnameescape(expand(""))|exe 'Nwrite '.fnameescape(expand(""))|exe "sil doau BufWritePost ".fnameescape(expand("")) 49 | au FileWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand(""))|exe "'[,']".'Nwrite '.fnameescape(expand(""))|exe "sil doau FileWritePost ".fnameescape(expand("")) 50 | try 51 | au SourceCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("")) 52 | catch /^Vim\%((\a\+)\)\=:E216/ 53 | au SourcePre ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("")) 54 | endtry 55 | augroup END 56 | 57 | " Commands: :Nread, :Nwrite, :NetUserPass {{{2 58 | com! -count=1 -nargs=* Nread let s:svpos= winsaveview()call netrw#NetRead(,)call winrestview(s:svpos) 59 | com! -range=% -nargs=* Nwrite let s:svpos= winsaveview(),call netrw#NetWrite()call winrestview(s:svpos) 60 | com! -nargs=* NetUserPass call NetUserPass() 61 | com! -nargs=* Nsource let s:svpos= winsaveview()call netrw#NetSource()call winrestview(s:svpos) 62 | com! -nargs=? Ntree call netrw#SetTreetop() 63 | 64 | " Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2 65 | com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(,0,0+0,) 66 | com! -nargs=* -bar -bang -count=0 -complete=dir Sexplore call netrw#Explore(,1,0+0,) 67 | com! -nargs=* -bar -bang -count=0 -complete=dir Hexplore call netrw#Explore(,1,2+0,) 68 | com! -nargs=* -bar -bang -count=0 -complete=dir Vexplore call netrw#Explore(,1,4+0,) 69 | com! -nargs=* -bar -count=0 -complete=dir Texplore call netrw#Explore(,0,6 ,) 70 | com! -nargs=* -bar -bang Nexplore call netrw#Explore(-1,0,0,) 71 | com! -nargs=* -bar -bang Pexplore call netrw#Explore(-2,0,0,) 72 | com! -nargs=* -bar -bang -count=0 -complete=dir Lexplore call netrw#Lexplore(,0,) 73 | 74 | " Commands: NetrwSettings {{{2 75 | com! -nargs=0 NetrwSettings call netrwSettings#NetrwSettings() 76 | com! -bang NetrwClean call netrw#Clean(0) 77 | 78 | " Maps: 79 | if !exists("g:netrw_nogx") 80 | if maparg('gx','n') == "" 81 | if !hasmapto('NetrwBrowseX') 82 | nmap gx NetrwBrowseX 83 | endif 84 | nno NetrwBrowseX :call netrw#BrowseX(expand((exists("g:netrw_gx")? g:netrw_gx : '')),netrw#CheckIfRemote()) 85 | endif 86 | if maparg('gx','v') == "" 87 | if !hasmapto('NetrwBrowseXVis') 88 | vmap gx NetrwBrowseXVis 89 | endif 90 | vno NetrwBrowseXVis :call netrw#BrowseXVis() 91 | endif 92 | endif 93 | if exists("g:netrw_usetab") && g:netrw_usetab 94 | if maparg('','n') == "" 95 | nmap NetrwShrink 96 | endif 97 | nno NetrwShrink :call netrw#Shrink() 98 | endif 99 | 100 | " --------------------------------------------------------------------- 101 | " LocalBrowse: invokes netrw#LocalBrowseCheck() on directory buffers {{{2 102 | fun! s:LocalBrowse(dirname) 103 | " Unfortunate interaction -- only DechoMsg debugging calls can be safely used here. 104 | " Otherwise, the BufEnter event gets triggered when attempts to write to 105 | " the DBG buffer are made. 106 | 107 | if !exists("s:vimentered") 108 | " If s:vimentered doesn't exist, then the VimEnter event hasn't fired. It will, 109 | " and so s:VimEnter() will then be calling this routine, but this time with s:vimentered defined. 110 | " call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered doesn't exist)") 111 | " call Dret("s:LocalBrowse") 112 | return 113 | endif 114 | 115 | " call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered=".s:vimentered.")") 116 | 117 | if has("amiga") 118 | " The check against '' is made for the Amiga, where the empty 119 | " string is the current directory and not checking would break 120 | " things such as the help command. 121 | " call Decho("(LocalBrowse) dirname<".a:dirname."> (isdirectory, amiga)") 122 | if a:dirname != '' && isdirectory(a:dirname) 123 | sil! call netrw#LocalBrowseCheck(a:dirname) 124 | if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt 125 | exe w:netrw_bannercnt 126 | endif 127 | endif 128 | 129 | elseif isdirectory(a:dirname) 130 | " call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)") 131 | " call Dredir("LocalBrowse ft last set: ","verbose set ft") 132 | " call Decho("(s:LocalBrowse) COMBAK#23: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) 133 | sil! call netrw#LocalBrowseCheck(a:dirname) 134 | " call Decho("(s:LocalBrowse) COMBAK#24: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) 135 | if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt 136 | exe w:netrw_bannercnt 137 | " call Decho("(s:LocalBrowse) COMBAK#25: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) 138 | endif 139 | 140 | else 141 | " not a directory, ignore it 142 | " call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...") 143 | endif 144 | " call Decho("(s:LocalBrowse) COMBAK#26: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col(".")) 145 | 146 | " call Dret("s:LocalBrowse") 147 | endfun 148 | 149 | " --------------------------------------------------------------------- 150 | " s:VimEnter: after all vim startup stuff is done, this function is called. {{{2 151 | " Its purpose: to look over all windows and run s:LocalBrowse() on 152 | " them, which checks if they're directories and will create a directory 153 | " listing when appropriate. 154 | " It also sets s:vimentered, letting s:LocalBrowse() know that s:VimEnter() 155 | " has already been called. 156 | fun! s:VimEnter(dirname) 157 | " call Dfunc("s:VimEnter(dirname<".a:dirname.">) expand(%)<".expand("%").">") 158 | let curwin = winnr() 159 | let s:vimentered = 1 160 | windo call s:LocalBrowse(expand("%:p")) 161 | exe curwin."wincmd w" 162 | " call Dret("s:VimEnter") 163 | endfun 164 | 165 | " --------------------------------------------------------------------- 166 | " NetrwStatusLine: {{{1 167 | fun! NetrwStatusLine() 168 | " let g:stlmsg= "Xbufnr=".w:netrw_explore_bufnr." bufnr=".bufnr("%")." Xline#".w:netrw_explore_line." line#".line(".") 169 | if !exists("w:netrw_explore_bufnr") || w:netrw_explore_bufnr != bufnr("%") || !exists("w:netrw_explore_line") || w:netrw_explore_line != line(".") || !exists("w:netrw_explore_list") 170 | let &stl= s:netrw_explore_stl 171 | if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif 172 | if exists("w:netrw_explore_line")|unlet w:netrw_explore_line|endif 173 | return "" 174 | else 175 | return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen 176 | endif 177 | endfun 178 | 179 | " ------------------------------------------------------------------------ 180 | " NetUserPass: set username and password for subsequent ftp transfer {{{1 181 | " Usage: :call NetUserPass() -- will prompt for userid and password 182 | " :call NetUserPass("uid") -- will prompt for password 183 | " :call NetUserPass("uid","password") -- sets global userid and password 184 | fun! NetUserPass(...) 185 | 186 | " get/set userid 187 | if a:0 == 0 188 | " call Dfunc("NetUserPass(a:0<".a:0.">)") 189 | if !exists("g:netrw_uid") || g:netrw_uid == "" 190 | " via prompt 191 | let g:netrw_uid= input('Enter username: ') 192 | endif 193 | else " from command line 194 | " call Dfunc("NetUserPass(a:1<".a:1.">) {") 195 | let g:netrw_uid= a:1 196 | endif 197 | 198 | " get password 199 | if a:0 <= 1 " via prompt 200 | " call Decho("a:0=".a:0." case <=1:") 201 | let g:netrw_passwd= inputsecret("Enter Password: ") 202 | else " from command line 203 | " call Decho("a:0=".a:0." case >1: a:2<".a:2.">") 204 | let g:netrw_passwd=a:2 205 | endif 206 | " call Dret("NetUserPass") 207 | endfun 208 | 209 | " ------------------------------------------------------------------------ 210 | " Modelines And Restoration: {{{1 211 | let &cpo= s:keepcpo 212 | unlet s:keepcpo 213 | " vim:ts=8 fdm=marker 214 | --------------------------------------------------------------------------------