近期对VIM进行设置,增加了一键编译/运行/调试等功能,配置部分快捷键如下:
Zz 同ZZ,在正常模式下快速保存退出
Zq 同Zq,正常模式下快速不保存退出
\\ 取消本次当前高亮显示
\/ 尝试从自定义的.vimcfg配置文件中读取PATH和PATH+值并设置文件查找路径path
\. 将工作目录转为当前文件目录
\hh 在命令行中输入替换命令模板s///gc
\hc 在命令行中输入替换命令模板s/当前光标下的词/当前光标下的词/gc
\hv 在命令行中输入替换命令模板s/最近一次复制或删除的词/最近一次复制或删除的词/gc
\y Visual模式下复制到系统剪切板(需要+clipboard属性)
\v Normal模式下从系统剪切板粘贴(需要+clipboard属性)
F2 在右侧分割窗口打开文件浏览界面
\F2 在新标签页(Tab)打开文件浏览界面
F3 快速保存当前文件
\F3 快速保存全部文件
F4 去掉每行尾部的空白字符
\F4 去掉全部空白行
F5 对可编译的文件进行编译
Ctrl-F5 运行ctags生成tags文件
F6 执行编译好的文件(通过cmake、configure、make等编译时无法自动找到可执行文件)
F7 启动调试(通过cmake、configure、make等编译时需要用file命令手动加载可执行文件)
F8 打开文件浏览窗口
Ctrl-F8 打开或关闭QuickFix窗口
将以下代码复制到~/.vimrc文件即可生效(注意备份原.vimrc文件)。
"-----------------------------------------------------------------------
autocmd BufWritePost $MYVIMRC source $MYVIMRC
autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exec "normal! g`\"" | endif
filetype on
syntax enable
syntax on
set nocompatible
set noautochdir
set showcmd
set showmode
set showtabline=2
set laststatus=2
set mouse=a
set tags=./tags;,tags
set hlsearch
set incsearch
set noignorecase
set selection=inclusive
set virtualedit=onemore
set whichwrap+=h,l,<,>,[,]
set wildmenu
set wildmode=longest,list
set completeopt=preview,menu,longest
set expandtab
set smarttab
set autoindent
set cindent
set tabstop=4
set softtabstop=4
set shiftwidth=4
set scrolloff=8
set ruler
set number
set cursorline
highlight LineNr cterm=none ctermfg=darkgray
highlight CursorLineNr cterm=bold ctermfg=gray ctermbg=darkgray
autocmd InsertEnter * highlight CursorLineNr cterm=bold ctermbg=darkblue
autocmd InsertLeave * highlight CursorLineNr cterm=bold ctermbg=darkgray
highlight CursorLine cterm=none ctermbg=darkgray
autocmd InsertEnter * highlight CursorLine cterm=bold ctermbg=darkblue
autocmd InsertLeave * highlight CursorLine cterm=none ctermbg=darkgray
highlight TablineSel ctermfg=black ctermbg=white
highlight Tabline ctermbg=gray
highlight TablineFill ctermfg=black
highlight StatusLine ctermfg=gray
highlight StatusLineNC ctermfg=gray
highlight VertSplit ctermfg=gray
"-----------------------------------------------------------------------
let g:mapleader='\'
nnoremap <Del> i<Del>
nnoremap q ^
nnoremap Q $
nnoremap Zz ZZ
nnoremap Zq ZQ
"nnoremap j k
"nnoremap k j
"nnoremap b <PageUp>
"nnoremap n <PageDown>
"nnoremap <Leader>i [<C-i>
"nnoremap <Leader>d [<C-d>
"inoremap <C-h> <Left>
"inoremap <C-l> <Right>
"inoremap <C-j> <Up>
"inoremap <C-k> <Down>
"inoremap <C-b> <PageUp>
"inoremap <C-n> <PageDown>
"vnoremap <C-t> :w !cat<CR>
nnoremap <Leader><CR> i
nnoremap <Leader><Leader> :nohl<CR>
nnoremap <Leader>hh :%s///gc<Left><Left><Left><Left>
vnoremap <Leader>hh :s///gc<Left><Left><Left><Left>
nnoremap <Leader>hc :%s/\<<C-R><C-W>\>/<C-R><C-W>/gc<Left><Left><Left><Left>
vnoremap <Leader>hc :s/\<<C-R><C-W>\>/<C-R><C-W>/gc<Left><Left><Left><Left>
nnoremap <Leader>hv :%s/<C-R>"/<C-R>"/gc<Left><Left><Left><Left>
vnoremap <Leader>hv :s/<C-R>"/<C-R>"/gc<Left><Left><Left><Left>
vnoremap <Leader>y "+y
nnoremap <Leader>v "+p
noremap <silent><C-w> <Esc><C-w>
noremap! <silent><C-w> <Esc><C-w>
noremap <F2> <Esc>:botright vsp .<CR>
noremap! <F2> <Esc>:botright vsp .<CR>
nnoremap <Leader><F2> :tabnew .<CR>
noremap <F3> <Esc>:w<CR>
noremap! <F3> <Esc>:w<CR>
nnoremap <Leader><F3> :wa<CR>
noremap <F4> <Esc>:%s/\s\+$//g<CR>
noremap! <F4> <Esc>:%s/\s\+$//g<CR>
nnoremap <Leader><F4> :g/^\s*$/d<CR>
"-----------------------------------------------------------------------
function! GetCfg(file, key)
if filereadable(a:file)
for line in readfile(a:file)
if line =~? '^'.a:key.'='
return substitute(line, '\c'.a:key.'=', '', '')
endif
endfor
endif
return ''
endfunction
function! SetPath()
let path=GetCfg(expand('%:p').'.vimcfg', 'PATH')
if path == ''
let path=GetCfg('./.vimcfg', 'PATH')
endif
if path != ''
let &path=path
endif
let path=GetCfg(expand('%:p').'.vimcfg', 'PATH+')
if path == ''
let path=GetCfg('./.vimcfg', 'PATH+')
endif
if path != '' && stridx(','.&path.',', ','.path.',') < 0
if &path =~ ',$'
let &path=&path.path
else
let &path=&path.','.path
endif
endif
endfunction
"call SetPath()
"autocmd BufReadPost * call SetPath()
nnoremap <Leader>/ :call SetPath()\|set path<CR>
nnoremap <Leader>. :cd %:p:h\|pwd<CR>
"-----------------------------------------------------------------------
function! GenMakeCmd()
" filetype on
" &filetype ==? expand('%:e')
let ext=expand('%:e')
if ext ==? 'c' || ext ==? 'cpp' || ext ==? 'cxx' || ext ==? 'cc'
if filereadable(expand('%:p:h').'/CMakeLists.txt')
if executable('/usr/bin/cmake')
if !isdirectory(expand('%:p:h').'/build')
call mkdir(expand('%:p:h').'/build')
endif
return 'cd "%:p:h/build" && cmake .. && make -j8'
else
echoerr 'Can not find "cmake"!'
endif
elseif executable(expand('%:p:h').'/configure')
return 'cd "%:p:h" && ./configure && make -j8'
elseif filereadable(expand('%:p:h').'/Makefile')
\ || filereadable(expand('%:p:h').'/makefile')
return 'cd "%:p:h" && make -j8'
elseif filereadable('CMakeLists.txt')
if executable('/usr/bin/cmake')
if !isdirectory('build')
call mkdir('build')
endif
return 'cd build && cmake .. && make -j8'
else
echoerr 'Can not find "cmake"!'
endif
elseif executable('./configure')
return './configure && make -j8'
elseif filereadable('Makefile') || filereadable('makefile')
return 'make -j8'
else
if ext ==? 'c'
return 'gcc --verbose -g3 -O0 -Wall -o "%<" "%"'
else
return 'g++ --verbose -g3 -O0 -Wall -o "%<" "%"'
endif
endif
elseif ext ==? 'java'
return 'javac -verbose -g "%"'
elseif ext == ''
echoerr 'Unknown file type: "'.@%.'"!'
else
echoerr 'Operation "make" on "*.'.ext.'" is not defined!'
endif
return ''
endfunction
let g:MAKE_CMD=''
function! GetMakeCmd()
if exists('g:MAKE_CMD') && g:MAKE_CMD != ''
return g:MAKE_CMD
endif
let make_cmd=GetCfg(expand('%:p').'.vimcfg', 'MAKE_CMD')
if make_cmd != ''
return make_cmd
endif
let make_cmd=GetCfg('./.vimcfg', 'MAKE_CMD')
if make_cmd != ''
return make_cmd
endif
return GenMakeCmd()
endfunction
function! Make()
exec 'update'
redraw!
let make_cmd=GetMakeCmd()
if make_cmd != ''
exec 'cclose'
let &makeprg=make_cmd
make!
exec 'botright cwindow'
return
endif
echoerr 'MAKE_CMD is not defined!'
endfunction
noremap <silent><F5> <Esc>:call Make()<CR>
noremap! <silent><F5> <Esc>:call Make()<CR>
"-----------------------------------------------------------------------
function! Ctags()
exec 'update'
redraw!
if executable('/usr/bin/ctags')
exec '!ctags -R --c-kinds=+px --c++-kinds=+px --fields=+iaS --extra=+q
\ && echo "CTags completed successfully."'
else
echoerr 'Can not find "ctags"!'
endif
endfunction
noremap <silent><C-F5> <Esc>:call Ctags()<CR>
noremap! <silent><C-F5> <Esc>:call Ctags()<CR>
"-----------------------------------------------------------------------
function! GenRunCmd()
" filetype on
" &filetype ==? expand('%:e')
let ext=expand('%:e')
if ext ==? 'c' || ext ==? 'cpp' || ext ==? 'cxx' || ext ==? 'cc'
if filereadable(expand('%:p:h').'/CMakeLists.txt')
echoerr '"CMakeLists.txt" has been found in directory "'.expand('%:p:h').'".'
elseif executable(expand('%:p:h').'/configure')
echoerr '"configure*" has been found in directory "'.expand('%:p:h').'".'
elseif filereadable(expand('%:p:h').'/Makefile')
\ || filereadable(expand('%:p:h').'/makefile')
echoerr '"Makefile" has been found in directory "'.expand('%:p:h').'".'
elseif filereadable('CMakeLists.txt')
echoerr '"CMakeLists.txt" has been found in working directory "'.getcwd().'".'
elseif executable('./configure')
echoerr '"configure*" has been found in working directory "'.getcwd().'".'
elseif filereadable('Makefile') || filereadable('makefile')
echoerr '"Makefile" has been found in working directory "'.getcwd().'".'
else
if stridx(expand('%<'), '/') < 0
let exe_file='./'.expand('%<')
else
let exe_file=expand('%<')
endif
if executable(exe_file)
return '"'.exe_file.'"'
else
echoerr 'Can not find executable file!'
endif
endif
elseif ext ==? 'java'
"return 'cd "'.expand('%:p:h').'" && java '.expand('%:t:r')
return 'cd "%:p:h" && java %:t:r'
elseif ext ==? 'py'
return 'python "%"'
elseif ext ==? 'sh'
return 'bash "%"'
elseif ext ==? 'html'
return 'firefox "%" &'
elseif ext == ''
echoerr 'Unknown file type: "'.@%.'"!'
else
echoerr 'Operation "run" on "*.'.ext.'" is not defined!'
endif
return ''
endfunction
let g:RUN_CMD=''
function! GetRunCmd()
if exists('g:RUN_CMD') && g:RUN_CMD != ''
return g:RUN_CMD
endif
let run_cmd=GetCfg(expand('%:p').'.vimcfg', 'RUN_CMD')
if run_cmd != ''
return run_cmd
endif
let run_cmd=GetCfg('./.vimcfg', 'RUN_CMD')
if run_cmd != ''
return run_cmd
endif
return GenRunCmd()
endfunction
function! Run()
exec 'update'
redraw!
let run_cmd=GetRunCmd()
if run_cmd != ''
exec 'cclose'
exec '!'.run_cmd
return
endif
echoerr 'RUN_CMD is not defined!'
endfunction
noremap <silent><F6> <Esc>:call Run()<CR>
noremap! <silent><F6> <Esc>:call Run()<CR>
"-----------------------------------------------------------------------
function! GenDebugCmd()
" filetype on
" &filetype ==? expand('%:e')
let ext=expand('%:e')
if ext ==? 'c' || ext ==? 'cpp' || ext ==? 'cxx' || ext ==? 'cc'
if exists(':ConqueGdb')
let debug_cmd='ConqueGdb'
else
let debug_cmd='gdb -tui'
endif
if filereadable(expand('%:p:h').'/CMakeLists.txt')
return debug_cmd
elseif executable(expand('%:p:h').'/configure')
return debug_cmd
elseif filereadable(expand('%:p:h').'/Makefile')
\ || filereadable(expand('%:p:h').'/makefile')
return debug_cmd
elseif filereadable('CMakeLists.txt')
return debug_cmd
elseif executable('./configure')
return debug_cmd
elseif filereadable('Makefile') || filereadable('makefile')
return debug_cmd
else
"if stridx(expand('%<'), '/') < 0
" let exe_file='./'.expand('%<')
"else
" let exe_file=expand('%<')
"endif
"if executable(exe_file)
" return debug_cmd.' "'.exe_file.'"'
"else
" return debug_cmd
"endif
return debug_cmd.' "'.expand('%<').'"'
endif
elseif ext ==? 'java'
"return 'cd "'.expand('%:p:h').'" && jdb '.expand('%:t:r')
return 'cd "%:p:h" && jdb %:t:r'
elseif ext ==? 'py'
return 'python -m pdb "%"'
elseif ext ==? 'sh'
"return 'bashdb "%"'
return 'bash -x "%"'
elseif ext == ''
echoerr 'Unknown file type: "'.@%.'"!'
else
echoerr 'Operation "debug" on "*.'.ext.'" is not defined!'
endif
return ''
endfunction
let g:DEBUG_CMD=''
function! GetDebugCmd()
if exists('g:DEBUG_CMD') && g:DEBUG_CMD != ''
return g:DEBUG_CMD
endif
let debug_cmd=GetCfg(expand('%:p').'.vimcfg', 'DEBUG_CMD')
if debug_cmd != ''
return debug_cmd
endif
let debug_cmd=GetCfg('./.vimcfg', 'DEBUG_CMD')
if debug_cmd != ''
return debug_cmd
endif
return GenDebugCmd()
endfunction
function! Debug()
exec 'update'
redraw!
let debug_cmd=GetDebugCmd()
if debug_cmd != ''
exec 'cclose'
if debug_cmd =~ '^ConqueGdb'
exec debug_cmd
else
exec '!'.debug_cmd
endif
return
endif
echoerr 'DEBUG_CMD is not defined!'
endfunction
noremap <silent><F7> <Esc>:call Debug()<CR>
noremap! <silent><F7> <Esc>:call Debug()<CR>
"-----------------------------------------------------------------------
function! ExpToggle()
if exists(':WMToggle')
if exists(':Tlist')
let g:winManagerWindowLayout='FileExplorer|TagList'
else
let g:winManagerWindowLayout='FileExplorer'
endif
WMToggle
else
let g:netrw_banner=0
let g:netrw_winsize=12
let g:netrw_liststyle=3
Lex
endif
endfunction
let g:ConqueTerm_ToggleKey='<F12>'
noremap <silent><F8> <Esc>:call ExpToggle()<CR>
noremap! <silent><F8> <Esc>:call ExpToggle()<CR>
"-----------------------------------------------------------------------
autocmd QuickFixCmdPost * botright cwindow
autocmd BufReadPost quickfix let t:qfix_win=bufnr('$')
autocmd BufWinEnter quickfix let t:qfix_win=bufnr('$')
autocmd BufWinLeave * if exists('t:qfix_win') && expand('<abuf>') == t:qfix_win | unlet! t:qfix_win | endif
function! QFixToggle()
if exists('t:qfix_win')
cclose
else
botright copen
endif
endfunction
noremap <silent><C-F8> <Esc>:call QFixToggle()<CR>
noremap! <silent><C-F8> <Esc>:call QFixToggle()<CR>
"-----------------------------------------------------------------------
编译、运行和调试三个命令的命令行按优先顺序如下设置:
1、设置g:MAKE_CMD/g:RUN_CMD/g:DEBUG_CMD三个变量,如let g:RUN_CMD='build/exec_file'。如果在命令行模式下输入则只对本次窗口有效,下次重启需要重新输入;如果在.vimrc文件中写入虽然不用每次重新输入,但是需要对不同的文件经常修改.vimrc文件。
2、在要编辑的文件filename.ext同目录下创建filename.ext.vimcfg配置文件,文件中配置MAKE_CMD/RUN_CMD/DEBUG_CMD,如make_cmd=pwd && make,这种方式适合对单独文件进行分别配置。
3、在工作目录下创建.vimcfg文件,文件中配置MAKE_CMD/RUN_CMD/DEBUG_CMD,这种方式适合按照项目组织的多个文件统一编译、运行和调试。
4、尝试根据filename.ext文件类型和CMakeLists.txt等文件自动生成MAKE_CMD/RUN_CMD/DEBUG_CMD:如果在文件目录或工作目录存在CMakeLists.txt、configure、makefile等配置文件,则利用其进行编译,但无法获得输出文件名,因为其可能输出多个文件,需要手工指定,否则默认可执行文件名为filename。
“\/”快捷键尝试从自定义的配置文件中读取PATH和PATH+值并设置文件查找路径path,这在利用gf命令打开包含(include)文件时很有用。具体设置是在.vimcfg或filename.ext.vimcfg文件中设置path=和path+=的值,“+”代表追加的意思,多个路径间用“,”分割,如path+=include,src。
最后,一个完整的.vimcfg文件设置示例如图所示:

一天一点进步

浙公网安备 33010602011771号