vim按鍵說明
除了上面簡易范例的 i, o,a,Esc, :wq 之外放接,其實(shí) vim 還有非常多的按鍵可以使用
這些基本命令需要我們在使用過程中不斷的總結(jié),這樣才會(huì)融會(huì)貫通疫赎。附上一張vim的鍵盤圖约炎,哈哈。
vim插件之Vundle
先安裝vunble(如果沒有g(shù)it的先安裝git)
git clone http://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
安裝完成后如圖會(huì)有一個(gè)vundle文件
二涧卵、打開.vimrc文件在家目錄下(如果沒有新建一個(gè))
sudo vim ~/.vimrc
將以下內(nèi)容復(fù)制到.vimrc , 保存退出
"語法高亮
syntax on
"顯示行號(hào)
set number
"顯示光標(biāo)所在位置的行號(hào)和列號(hào)
set ruler
set wrap "自動(dòng)折行
set shiftwidth=4
set tabstop=4
set softtabstop=4
set expandtab "將tab替換為相應(yīng)數(shù)量空格
set smartindent
set backspace=2
"設(shè)置取消備份 禁止臨時(shí)文件生成
set nobackup
set noswapfile
"設(shè)置匹配模式 類似當(dāng)輸入一個(gè)左括號(hào)時(shí)會(huì)匹配相應(yīng)的那個(gè)右括號(hào)
set showmatch
"set laststatus=2 "命令行為兩行
"set fenc=utf-8 "文件編碼
"set mouse=a "啟用鼠標(biāo)
"set ignorecase "忽略大小寫
"set cursorline "突出顯示當(dāng)前行
"set cursorcolumn "突出顯示當(dāng)前列
set fdm=marker
"jj退出insert模式
"inoremap <C-j> <ESC>
inoremap jk <ESC>
"nmap ,v "+p
"vmap ,c "+y
"nmap ,c "+y
vmap ,c :w !pbcopy<CR><CR>
nmap ,c :w !pbcopy<CR><CR>
nmap ,v :r !pbpaste<CR><CR>
"設(shè)置vundle
set nocompatible " be iMproved
filetype off " required!
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
filetype plugin indent on " required!
"vundle設(shè)置完畢
"Bundle 'taglist.vim'
"let Tlist_Ctags_Cmd='ctags'
"let Tlist_Show_One_File=1 "不同時(shí)顯示多個(gè)文件的tag勤家,只顯示當(dāng)前文件的
"let Tlist_WinWidt =28 "設(shè)置taglist的寬度
"let Tlist_Exit_OnlyWindow=1 "如果taglist窗口是最后一個(gè)窗口,則退出vim
"let Tlist_Use_Right_Window=1 "在右側(cè)窗口中顯示taglist窗口
"let Tlist_Use_Left_Windo =1 "在左側(cè)窗口中顯示taglist窗口
Bundle 'majutsushi/tagbar'
"nmap <Leader>tb :TagbarToggle<CR> "快捷鍵設(shè)置
let g:tagbar_ctags_bin='ctags' "ctags程序的路徑
let g:tagbar_width=20 "窗口寬度的設(shè)置
map <F3> :Tagbar<CR>
map <C-t> :Tagbar<CR>
"autocmd BufReadPost *.cpp,*.c,*.h,*.hpp,*.cc,*.cxx call tagbar#autoopen() "如果是c語言的程序的話柳恐,tagbar自動(dòng)開啟
Bundle 'scrooloose/nerdtree'
let NERDTreeWinPos='left'
let NERDTreeWinSize=25
let g:NERDTreeNodeDelimiter = "\u00a0"
"let g:NERDTreeNodeDelimiter = ''
"map <F2> :NERDTreeToggle<CR>
map <C-n> :NERDTreeToggle<CR>
"打開NERDTree
"autocmd vimenter * NERDTree
"光標(biāo)默認(rèn)在主窗口
"wincmd w
"autocmd VimEnter * wincmd w
"vim 退出時(shí)直接關(guān)閉NERDTree
"autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
Bundle 'bling/vim-airline'
set laststatus=2
Bundle 'scrooloose/nerdcommenter'
let mapleader = ','
nnoremap <C-l> gt
nnoremap <C-h> gT
nnoremap <leader>t : tabe<CR>
"vim-multiple-cursors 多光標(biāo)選中
"Bundle 'terryma/vim-multiple-cursors'
"let g:multi_cursor_use_default_mapping=0
"let g:multi_cursor_start_key='<C-m>'
"let g:multi_cursor_start_word_key='g<C-m>'
"let g:multi_cursor_next_key='<C-m>'
"let g:multi_cursor_prev_key='<C-p>'
"let g:multi_cursor_skip_key='<C-x>'
"let g:multi_cursor_quit_key='<C-j>'
"MatchTagAlways
Bundle 'Valloric/MatchTagAlways'
"Markdown語法高亮
Bundle 'godlygeek/tabular'
"Bundle 'plasticboy/vim-markdown'
"markdown實(shí)時(shí)顯示
Bundle 'suan/vim-instant-markdown'
"indentLine 代碼縮進(jìn)線標(biāo)志線
Plugin 'Yggdroot/indentLine'
let g:indentLine_char = '┆'
let g:indentLine_color_term = 239
let g:indentLine_enabled = 1
"映射到ctrl+I鍵
"map <C-i> :IndentLinesToggle<CR>
"delimitMate 自動(dòng)補(bǔ)全引號(hào)(單引號(hào)/雙引號(hào)/反引號(hào)), 括號(hào)(()[]{})
Bundle 'Raimondi/delimitMate'
:w保存 , 然后進(jìn)入命令行模式
三伐脖、輸入一下命令回車 , 等待下載插件完成
: BundleInstall
四热幔、然后讓.vimrc文件生效即可
source ~/.vimrc
如果這一步出錯(cuò)可以忽略
打開高亮渲染
在 ~/.vimrc 中配置
set nonu
syntax on
修復(fù) mac 下 vim 無法使用delete刪除文本的問題
在 ~/.vimrc 中配置
" fix mac vim delete error, so as set backspace=indent,eol,start
set backspace=2
安裝 Vundle
它的使用方法很簡單,安裝一個(gè)插件只需要在.vimrc按照規(guī)則中添加 Plugin 的名稱讼庇,某些需要添加路徑绎巨,之后在 Vim 中使用:PluginInstall既可以自動(dòng)化安裝。
git 克隆 Vundle 工程到本地
git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
修改.vimrc配置 Plugins蠕啄。在.vimrc文件中添加如下內(nèi)容
set nocompatible " be iMproved, required
filetype off " 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'
" The following are examples of different formats supported.
" Keep Plugin commands between vundle#begin/end.
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList - lists configured plugins
" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line
保存后進(jìn)入 vim 運(yùn)行命令
:PluginInstall
vundle 命令
# 安裝插件
:BundleInstall
# 更新插件
:BundleUpdate
# 清除不需要的插件
:BundleClean
# 列出當(dāng)前的插件
:BundleList
# 搜索插件
:BundleSearch
注意
插件配置不要在 call vundle#end() 之前场勤,不然插件無法生效
如果配置錯(cuò)誤,需要重新配置后歼跟,在vim中運(yùn)行 :PluginInstall
安裝 YouCompleteMe
使用 Vundle 安裝 YouCompleteMe
在.vimrc中添加如下內(nèi)容 位置在call vundle#begin()和call vundle#end()之間
Bundle 'Valloric/YouCompleteMe'
在vim中運(yùn)行命令
:BundleInstall
編譯 YouCompleteMe
編譯過程需要CMake
brew install CMake
帶 C-family languages 語義支持的版本
cd ~/.vim/bundle/YouCompleteMe
./install.sh --clang-completer
不帶 C-family languages 語義支持的版本
cd ~/.vim/bundle/YouCompleteMe
./install.sh
帶 C# 語義支持的版本
cd ~/.vim/bundle/YouCompleteMe
./install.sh --omnisharp-completer
帶 Go 語言語義支持的版本
cd ~/.vim/bundle/YouCompleteMe
./install.sh --gocode-completer
配置 YCM
在.vimrc中添加配置
" 自動(dòng)補(bǔ)全配置
set completeopt=longest,menu "讓Vim的補(bǔ)全菜單行為與一般IDE一致(參考VimTip1228)
autocmd InsertLeave * if pumvisible() == 0|pclose|endif "離開插入模式后自動(dòng)關(guān)閉預(yù)覽窗口
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>" "回車即選中當(dāng)前項(xiàng)
"上下左右鍵的行為 會(huì)顯示其他信息
inoremap <expr> <Down> pumvisible() ? "\<C-n>" : "\<Down>"
inoremap <expr> <Up> pumvisible() ? "\<C-p>" : "\<Up>"
inoremap <expr> <PageDown> pumvisible() ? "\<PageDown>\<C-p>\<C-n>" : "\<PageDown>"
inoremap <expr> <PageUp> pumvisible() ? "\<PageUp>\<C-p>\<C-n>" : "\<PageUp>"
"youcompleteme 默認(rèn)tab s-tab 和自動(dòng)補(bǔ)全沖突
"let g:ycm_key_list_select_completion=['<c-n>']
let g:ycm_key_list_select_completion = ['<Down>']
"let g:ycm_key_list_previous_completion=['<c-p>']
let g:ycm_key_list_previous_completion = ['<Up>']
let g:ycm_confirm_extra_conf=0 "關(guān)閉加載.ycm_extra_conf.py提示
let g:ycm_collect_identifiers_from_tags_files=1 " 開啟 YCM 基于標(biāo)簽引擎
let g:ycm_min_num_of_chars_for_completion=2 " 從第2個(gè)鍵入字符就開始羅列匹配項(xiàng)
let g:ycm_cache_omnifunc=0 " 禁止緩存匹配項(xiàng),每次都重新生成匹配項(xiàng)
let g:ycm_seed_identifiers_with_syntax=1 " 語法關(guān)鍵字補(bǔ)全
nnoremap <F5> :YcmForceCompileAndDiagnostics<CR> "force recomile with syntastic
"nnoremap <leader>lo :lopen<CR> "open locationlist
"nnoremap <leader>lc :lclose<CR> "close locationlist
inoremap <leader><leader> <C-x><C-o>
"在注釋輸入中也能補(bǔ)全
let g:ycm_complete_in_comments = 1
"在字符串輸入中也能補(bǔ)全
let g:ycm_complete_in_strings = 1
"注釋和字符串中的文字也會(huì)被收入補(bǔ)全
let g:ycm_collect_identifiers_from_comments_and_strings = 0
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR> " 跳轉(zhuǎn)到定義處
YCM 安裝錯(cuò)誤
首先插件需要安裝一些dependencies和媳。包括build-essential,cmake哈街,python-dev留瞳, python3-dev。在MacOS底下xcode-select --install
取代 Linux底下的‘sudo apt install build-essential’骚秦。python 和python 3之前安裝vim和macvim的時(shí)候其實(shí)已經(jīng)裝完了她倘,缺少的只有cmake這個(gè)插件。
brew install cmake
然后在 /.vimrc
文件中加入
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py'}
帶特定語言支持的安裝方式骤竹,上面語句改為
C-family languages
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --clang-completer'}
C# supportbrew install Mono
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --cs-completer'}
Go support
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --go-completer'}
Rust support: support brew install rust
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --rust-completer'}
Java support: support brew cask install java8
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --java-completer'}
全部安裝
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --all'}
打開vim帝牡,輸入
:PlugInstall
自動(dòng)安裝所有。
/.vimrc
文件中 YouCompleteMe的常用設(shè)置, 配置來源 http://howiefh.github.io/2015/05/22/vim-install-youcompleteme-plugin/
set completeopt=longest,menu "讓Vim的補(bǔ)全菜單行為與一般IDE一致(參考VimTip1228)
autocmd InsertLeave * if pumvisible() == 0|pclose|endif "離開插入模式后自動(dòng)關(guān)閉預(yù)覽窗口
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>" "回車即選中當(dāng)前項(xiàng)
"上下左右鍵的行為 會(huì)顯示其他信息
inoremap <expr> <Down> pumvisible() ? "\<C-n>" : "\<Down>"
inoremap <expr> <Up> pumvisible() ? "\<C-p>" : "\<Up>"
inoremap <expr> <PageDown> pumvisible() ? "\<PageDown>\<C-p>\<C-n>" : "\<PageDown>"
inoremap <expr> <PageUp> pumvisible() ? "\<PageUp>\<C-p>\<C-n>" : "\<PageUp>"
" 跳轉(zhuǎn)到定義處
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
nnoremap <F6> :YcmForceCompileAndDiagnostics<CR> "force recomile with syntastic
" nnoremap <leader>lo :lopen<CR> "open locationlist
" nnoremap <leader>lc :lclose<CR> "close locationlist
inoremap <leader><leader> <C-x><C-o>
let g:ycm_global_ycm_extra_conf = '~/.vim/.ycm_extra_conf.py'
" 不顯示開啟vim時(shí)檢查ycm_extra_conf文件的信息
let g:ycm_confirm_extra_conf=0
" 開啟基于tag的補(bǔ)全蒙揣,可以在這之后添加需要的標(biāo)簽路徑
let g:ycm_collect_identifiers_from_tags_files=1
"注釋和字符串中的文字也會(huì)被收入補(bǔ)全
let g:ycm_collect_identifiers_from_comments_and_strings = 0
" 輸入第2個(gè)字符開始補(bǔ)全
let g:ycm_min_num_of_chars_for_completion=2
" 禁止緩存匹配項(xiàng),每次都重新生成匹配項(xiàng)
let g:ycm_cache_omnifunc=0
" 開啟語義補(bǔ)全
let g:ycm_seed_identifiers_with_syntax=1
"在注釋輸入中也能補(bǔ)全
let g:ycm_complete_in_comments = 1
"在字符串輸入中也能補(bǔ)全
let g:ycm_complete_in_strings = 1
" 設(shè)置在下面幾種格式的文件上屏蔽ycm
let g:ycm_filetype_blacklist = {
\ 'tagbar' : 1,
\ 'nerdtree' : 1,
\}
"youcompleteme 默認(rèn)tab s-tab 和 ultisnips 沖突
let g:ycm_key_list_select_completion = ['<Down>']
let g:ycm_key_list_previous_completion = ['<Up>']
" 修改對(duì)C函數(shù)的補(bǔ)全快捷鍵靶溜,默認(rèn)是CTRL + space,修改為ALT + ;
let g:ycm_key_invoke_completion = '<M-;>'
" SirVer/ultisnips 代碼片斷
" Trigger configuration. Do not use <tab> if you use https://github.com/Valloric/YouCompleteMe.
let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
let g:UltiSnipsListSnippets="<c-e>"
"定義存放代碼片段的文件夾懒震,使用自定義和默認(rèn)的罩息,將會(huì)的到全局,有沖突的會(huì)提示
let g:UltiSnipsSnippetDirectories=["plugged/vim-snippets/UltiSnips"]
" 參考https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-62941322
" 解決ultisnips和ycm tab沖突个扰,如果不使用下面的辦法解決可以參考
" https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-63205056的配置
" begin
" let g:ycm_key_list_select_completion=['<C-n>', '<Down>']
" let g:ycm_key_list_previous_completion=['<C-p>', '<Up>']
" let g:UltiSnipsExpandTrigger="<Tab>"
" let g:UltiSnipsJumpForwardTrigger="<Tab>"
" let g:UltiSnipsJumpBackwardTrigger="<S-Tab>"
" end
" UltiSnips completion function that tries to expand a snippet. If there's no
" snippet for expanding, it checks for completion window and if it's
" shown, selects first element. If there's no completion window it tries to
" jump to next placeholder. If there's no placeholder it just returns TAB key
function! g:UltiSnips_Complete()
call UltiSnips#ExpandSnippet()
if g:ulti_expand_res == 0
if pumvisible()
return "\<C-n>"
else
call UltiSnips#JumpForwards()
if g:ulti_jump_forwards_res == 0
return "\<TAB>"
endif
endif
endif
return ""
endfunction
au BufEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=g:UltiSnips_Complete()<cr>"
" Expand snippet or return
let g:ulti_expand_res = 1
function! Ulti_ExpandOrEnter()
call UltiSnips#ExpandSnippet()
if g:ulti_expand_res
return ''
else
return "\<return>"
endfunction
" Set <space> as primary trigger
inoremap <return> <C-R>=Ulti_ExpandOrEnter()<CR>
~/.vim/.ycm_extra_conf.py文件示范
import os
import os.path
import fnmatch
import logging
import ycm_core
import re
BASE_FLAGS = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-ferror-limit=10000',
'-DNDEBUG',
'-std=c++11',
'-xc++',
'-I/usr/lib/',
'-I/usr/include/'
]
SOURCE_EXTENSIONS = [
'.cpp',
'.cxx',
'.cc',
'.c',
'.m',
'.mm'
]
SOURCE_DIRECTORIES = [
'src',
'lib'
]
HEADER_EXTENSIONS = [
'.h',
'.hxx',
'.hpp',
'.hh'
]
HEADER_DIRECTORIES = [
'include'
]
def IsHeaderFile(filename):
extension = os.path.splitext(filename)[1]
return extension in HEADER_EXTENSIONS
def GetCompilationInfoForFile(database, filename):
if IsHeaderFile(filename):
basename = os.path.splitext(filename)[0]
for extension in SOURCE_EXTENSIONS:
# Get info from the source files by replacing the extension.
replacement_file = basename + extension
if os.path.exists(replacement_file):
compilation_info = database.GetCompilationInfoForFile(replacement_file)
if compilation_info.compiler_flags_:
return compilation_info
# If that wasn't successful, try replacing possible header directory with possible source directories.
for header_dir in HEADER_DIRECTORIES:
for source_dir in SOURCE_DIRECTORIES:
src_file = replacement_file.replace(header_dir, source_dir)
if os.path.exists(src_file):
compilation_info = database.GetCompilationInfoForFile(src_file)
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile(filename)
def FindNearest(path, target, build_folder):
candidate = os.path.join(path, target)
if(os.path.isfile(candidate) or os.path.isdir(candidate)):
logging.info("Found nearest " + target + " at " + candidate)
return candidate;
parent = os.path.dirname(os.path.abspath(path));
if(parent == path):
raise RuntimeError("Could not find " + target);
if(build_folder):
candidate = os.path.join(parent, build_folder, target)
if(os.path.isfile(candidate) or os.path.isdir(candidate)):
logging.info("Found nearest " + target + " in build folder at " + candidate)
return candidate;
return FindNearest(parent, target, build_folder)
def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
if not working_directory:
return list(flags)
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith('/'):
new_flag = os.path.join(working_directory, flag)
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith(path_flag):
path = flag[ len(path_flag): ]
new_flag = path_flag + os.path.join(working_directory, path)
break
if new_flag:
new_flags.append(new_flag)
return new_flags
def FlagsForClangComplete(root):
try:
clang_complete_path = FindNearest(root, '.clang_complete')
clang_complete_flags = open(clang_complete_path, 'r').read().splitlines()
return clang_complete_flags
except:
return None
def FlagsForInclude(root):
try:
include_path = FindNearest(root, 'include')
flags = []
for dirroot, dirnames, filenames in os.walk(include_path):
for dir_path in dirnames:
real_path = os.path.join(dirroot, dir_path)
flags = flags + ["-I" + real_path]
return flags
except:
return None
def FlagsForCompilationDatabase(root, filename):
try:
# Last argument of next function is the name of the build folder for
# out of source projects
compilation_db_path = FindNearest(root, 'compile_commands.json', 'build')
compilation_db_dir = os.path.dirname(compilation_db_path)
logging.info("Set compilation database directory to " + compilation_db_dir)
compilation_db = ycm_core.CompilationDatabase(compilation_db_dir)
if not compilation_db:
logging.info("Compilation database file found but unable to load")
return None
compilation_info = GetCompilationInfoForFile(compilation_db, filename)
if not compilation_info:
logging.info("No compilation info for " + filename + " in compilation database")
return None
return MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_)
except:
return None
def FlagsForFile(filename):
root = os.path.realpath(filename);
compilation_db_flags = FlagsForCompilationDatabase(root, filename)
if compilation_db_flags:
final_flags = compilation_db_flags
else:
final_flags = BASE_FLAGS
clang_flags = FlagsForClangComplete(root)
if clang_flags:
final_flags = final_flags + clang_flags
include_flags = FlagsForInclude(root)
if include_flags:
final_flags = final_flags + include_flags
return {
'flags': final_flags,
'do_cache': True
}