一直听说vim,emacs两大神器,于是选了一直在用的vim来体验一下
先放个最后的效果图
最初目的是打算搞出来写django的,于是很多插件配置用的官方文档推荐的
https://code.djangoproject.com/wiki/UsingVimWithDjango
1、首先需要插件管理 Vundle
这个方式只修改当前用户的vim
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
编辑vimrc
vim ~/.vimrc
set nocompatible
filetype on
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
call vundle#end()
filetype plugin indent on
安装插件:进入vim,输入 :PluginInstall
或者直接命令行执行 vim +PluginInstall +qall
卸载插件:在vimrc中删除相应行后
进入vim ,输入 :PluginClean
其它用法github上看吧。。。
2、自动补全插件 Plugin ‘Valloric/YouCompleteMe’
https://github.com/Valloric/YouCompleteMe
先用vundle安装,PluginInstall会报错需要单独安装,执行下面步骤即可
PluginInstall过程很慢而且没有进度条显示,可以进入~/.vim/bundle/YouCompleteMe/目录查看大小是否在增长,我的有307M
sudo apt install build-essential cmake python3-dev
cd ~/.vim/bundle/YouCompleteMe
python3 install.py
clang之类的暂时用不到,参数就全都没加
3、目录树显示插件 Plugin ‘scrooloose/nerdtree’
vimrc中配置如下
Plugin 'scrooloose/nerdtree'
let g:NERDTreeChDirMode=2 #将当前目录设置为nerdtree根目录
map :NERDTreeToggle #设置快捷键,ctrl+n打开nerdtree
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | endif #这两行是打开目录是自动打开nerdtree,比如vim . 时
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif #只剩下nerdtree窗口时自动关闭vim
ctrl+w+w 切换窗口,vim和nerdtree之前切换
shift+c 将当前目录设为根节点
shift+r 刷新当前根目录
o / go将选中文件用buffer打开,不知道为什么help中这样介绍 o: open in prev window ,感觉像是用新窗口打开,但实际上是buffer的方式
直接使用nerdtree创建文件的方法,ctrl+n切到nerdtree,然后输入ma,即可在对应目录中创建新文件,创建目录只需要在输入的文件名后面加上/即可
4、状态栏,buffer显示等插件 Plugin ‘vim-airline/vim-airline’
使用vundle安装后需要安装对应字体
安装字体方法如下
# clone
git clone https://github.com/powerline/fonts.git --depth=1
# install
cd fonts
./install.sh
# clean-up a bit
cd ..
rm -rf fonts
然后vimrc中加入以下配置
vim中buffer,tab,window的区别介绍就不细说了。。。符合ide标签功能的查下来是buffer比较接近,我就只配置buffer切换的快捷键
Plugin 'vim-airline/vim-airline'
set hidden #能够使未保存的buffer进行切换
nnoremap bn :bnext #直接输入bn进行buffer切换快捷键
nnoremap bp :bprevious
nnoremap bd :bdelete #删除buffer快捷键,这里好像会把buffer全部删掉,使用 :bp|bd # 命令可以实现删除当前buffer功能,但是设置快捷键会报错,不知道怎么解决这点。。。
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show=1
let g:airline_powerline_fonts = 1 #安装字体后加入这个配置参数才能达到预期显示效果
set laststatus=2
set t_Co=256 #256色显示vim,不加这个airline显示颜色不正常
5、tmux插件 Plugin ‘christoomey/vim-tmux-navigator’
这个主要用于弄出vim下面的那个独立出来的终端效果,如果能够习惯tmux的分屏使用,其实这个插件不装也可以
首先安装tmux
apt-get install tmux
我使用的是github中作者推荐的另一种配置,详细链接如下
https://www.codeography.com/2013/06/19/navigating-vim-and-tmux-splits
~/.vimrc文件如下
Plugin 'christoomey/vim-tmux-navigator'
let g:tmux_navigator_no_mappings = 1
let g:tmux_navigator_save_on_switch = 2
if exists('$TMUX')
function! TmuxOrSplitSwitch(wincmd, tmuxdir)
let previous_winnr = winnr()
silent! execute "wincmd " . a:wincmd
if previous_winnr == winnr()
call system("tmux select-pane -" . a:tmuxdir)
redraw!
endif
endfunction
let previous_title = substitute(system("tmux display-message -p '#{pane_title}'"), '\n', '', '')
let &t_ti = "\]2;vim\\\" . &t_ti
let &t_te = "\]2;". previous_title . "\\\" . &t_te
nnoremap :call TmuxOrSplitSwitch('h', 'L')
nnoremap :call TmuxOrSplitSwitch('j', 'D')
nnoremap :call TmuxOrSplitSwitch('k', 'U')
nnoremap :call TmuxOrSplitSwitch('l', 'R')
else
map h
map j
map k
map l
endif
~/.tmux.conf配置如下
bind -n C-h run "(tmux display-message -p '#{pane_title}' | grep -iq vim && tmux send-keys C-h) || tmux select-pane -L"
bind -n C-j run "(tmux display-message -p '#{pane_title}' | grep -iq vim && tmux send-keys C-j) || tmux select-pane -D"
bind -n C-k run "(tmux display-message -p '#{pane_title}' | grep -iq vim && tmux send-keys C-k) || tmux select-pane -U"
bind -n C-l run "(tmux display-message -p '#{pane_title}' | grep -iq vim && tmux send-keys C-l) || tmux select-pane -R"
set -g default-terminal "screen-256color" #这个是为了让tmux256色显示,对应airline的配置,但是并没有生效!我还是在每次打开tmux加上 -2 参数,xshell中无法生效原因可能跟xshell登录终端后的系统环境参数有关,修改环境变量$TERM可以解决,或者alias tmux='tmux -2'
set -g mouse on #这个配置作用是能够使用鼠标调整分框的大小,加了这个后xshell进入tmux后无法使用选择复制
然后我们输入命令新建一个tmux会话
tmux new -s vim-test
输入ctrl+b,然后再输入 "
进行上下分屏,具体tmux使用方法不详细说了。。。
正常的tmux选择上下分屏需要输入ctrl+b,然后用方向键选着
如果我们上面的配置生效了,可直接使用ctrl+hjkl 进行上下左右分屏选择
然后我们在上面的分屏中打开vim就可以实现,上面vim,下面打开一个终端了,
ctrl+j/k 进行上下分屏选择
这里设置ctrl+h快捷键后可能会出现在tmux终端中敲命令行无法使用退格键的问题(在使用远程工具时会出现,比如使用xshell远程登录时)
原因是因为xshell默认发送的退格键字符也是ctrl+h(也可能是因为tmux中本来就只识别^?作为退格键,这里没有深入研究),设置快捷键后会无法识别,这里我们在属性设置中把退格键换成^?即可
补充一下tmux中alt键无法使用的办法,我发现使用ctrl+b,alt+方向键无法调整窗格大小,同样是上面那个图的页面,因为经常用左alt进行xshell标签页切换,就把右alt改了
别的插件如下
Plugin ‘SirVer/ultisnips’
Plugin ‘taglist.vim’
Plugin ‘ctrlpvim/ctrlp.vim’ #这个看github上airline插件作者说在airline里集成了,但是我只装了airline的情况下并不能成功调出来,原因未知,有知道的大佬求助。。。
这些没遇到什么坑,直接PluginInstall装上就能用,详细配置下面我放出来vimrc全部内容
我的~/.vimrc文件
set sw=4
set ts=4
set sts=4
set number
set nocompatible " be iMproved, required
filetype on " required
" 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 'VundleVim/Vundle.vim'
Plugin 'Valloric/YouCompleteMe'
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
Plugin 'scrooloose/nerdtree'
let g:NERDTreeChDirMode=2
map :NERDTreeToggle
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | endif
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" Track the engine.
Plugin 'SirVer/ultisnips'
" Snippets are separated from the engine. Add this if you want them:
Plugin 'honza/vim-snippets'
" 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
Plugin 'taglist.vim'
let Tlist_Use_Right_Window=1
let Tlist_GainFocus_On_ToggleOpen=1
Plugin 'vim-airline/vim-airline'
set hidden
nnoremap bn :bnext
nnoremap bp :bprevious
nnoremap bd :bdelete
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show=1
let g:airline_powerline_fonts = 1
set laststatus=2
set t_Co=256
Plugin 'ctrlpvim/ctrlp.vim'
Plugin 'christoomey/vim-tmux-navigator'
let g:tmux_navigator_no_mappings = 1
let g:tmux_navigator_save_on_switch = 2
if exists('$TMUX')
function! TmuxOrSplitSwitch(wincmd, tmuxdir)
let previous_winnr = winnr()
silent! execute "wincmd " . a:wincmd
if previous_winnr == winnr()
call system("tmux select-pane -" . a:tmuxdir)
redraw!
endif
endfunction
let previous_title = substitute(system("tmux display-message -p '#{pane_title}'"), '\n', '', '')
let &t_ti = "\]2;vim\\\" . &t_ti
let &t_te = "\]2;". previous_title . "\\\" . &t_te
nnoremap :call TmuxOrSplitSwitch('h', 'L')
nnoremap :call TmuxOrSplitSwitch('j', 'D')
nnoremap :call TmuxOrSplitSwitch('k', 'U')
nnoremap :call TmuxOrSplitSwitch('l', 'R')
else
map h
map j
map k
map l
endif
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required