owned this note
owned this note
Published
Linked with GitHub
---
tags: 程式設計
---
# Use Vim as IDE
## 安裝插件
### 安裝插件管理器
```$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim```
### 安裝插件
- 編輯```~/.vimrc```
```=
" vundle 環境設置
filetype off
set rtp+=~/.vim/bundle/Vundle.vim
" vundle 管理的插件列表必须位於 vundle#begin() 和 vundle#end() 之间
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'Lokaltog/vim-powerline'
Plugin 'octol/vim-cpp-enhanced-highlight'
Plugin 'nathanaelkane/vim-indent-guides'
Plugin 'SirVer/ultisnips'
Plugin 'Chiel92/vim-autoformat'
Plugin 'Valloric/YouCompleteMe'
Plugin 'scrooloose/nerdcommenter'
Plugin 'scrooloose/nerdtree'
Plugin 'Raimondi/delimitMate'
call vundle#end()
filetype plugin indent on
```
- 編輯完後
```=
$ vim
:PluginInstall
```
### 卸載插件
- 刪除```~/.vimrc```中的配置後
```=
$ vim
:PluginClean
```
### 更新插件
```=
$ vim
:PluginUpdate
```
## 界面美化
### 主題風格
在```~/.vimrc```中選用某個主題:
```=
"開啟真彩色支持
set termguicolors
"開啟256色支持
set t_Co=256
" 配色方案
set background=dark
"colorscheme NeoSolarized
```
### 添加輔助訊息
```=
" 總是顯示狀態欄
set laststatus=2
" 顯示光標當前位置
set ruler
" 開啟行號顯示
set number
" 高亮顯示當前行/列
set cursorline
set cursorcolumn
hi LineNr gui=bold guifg=DarkGrey guibg=NONE
hi Cursorline cterm=none gui=none guibg=darkblue
" 高亮顯示搜索结果
set hlsearch
" map Ctrl-L to be nohl, clear search highlight
nnoremap <c-l> :nohl<cr>
```
### 其他美化
```=
" 禁止折行
set nowrap
" 用滑鼠選取
set mouse=a
```
- 複製到系統剪貼簿 ```"+y```
## 代碼分析
### 語法高亮
```=
" 開啟語法高亮功能
syntax enable
" 允許用指定語法高亮配色方案替換默認方案
syntax on
```
### 代碼縮進
```=
" 適應不同語言的智能縮進
filetype indent on
" 將制表符擴展為空格
set expandtab
" 設置編輯時制表符占用空格數
set tabstop=4
" 設置格式化時制表符占用空格數
set shiftwidth=4
" 讓 vim 把連續數量的空格視為一個制表符
set softtabstop=4
```
可視化的將相同縮進的代碼關聯起来
```=
" 随 vim 啟動
let g:indent_guides_enable_on_vim_startup=1
" 從第二層開始可視化顯示縮進
let g:indent_guides_start_level=2
" 色塊寬度
let g:indent_guides_guide_size=1
" 快捷键 i 開/關 縮進可視化
:nmap <silent> <Leader>i <Plug>IndentGuidesToggle
```
### 代碼折疊
vim 自身支持多種折疊:
- 手動建立折疊:manual
- 基於縮進進行折疊:indent
- 基於語法進行折疊:syntax
- 未更改文本構成折疊:diff
- 其中,indent、syntax 比較適合編程,按需選用
```=
" 基於缩進或語法進行代碼折疊
"set foldmethod=indent
set foldmethod=syntax
" 啟動 vim 時關閉摺疊代碼
set nofoldenable
```
- 操作:
- za,打開或關閉當前摺疊
- zm,關閉所有摺疊
- zr,打開所有摺疊
## 代碼開發
### 快速開關註釋
- ```<leader>cc```->註釋
- ```<leader>cu```->取消
### 模板補全
- 使用方法:輸入完,按space再按tab,即可自動補全
- 安裝:
```=
$ cd ~/.vim/bundle/ultisnips
$ mkdir mysnippets
$ cd mysnippets
$ vim cgeneral.snippets
$ vim c.snippets
$ vim cpp.snippets
```
- 完整 cgeneral.snippets 内容如下:
```=
# #include <...>
snippet inc
#include <${1}>${2}
endsnippet
# if
snippet if
if(${1}){
${2}
}
endsnippet
# else if
snippet ei
else if(${1}){
${2}
}
endsnippet
# else
snippet el
else{
${1}
}
endsnippet
# return
snippet re
return ${1};
endsnippet
# Do While Loop
snippet do
do{
${2}
}while(${1});
endsnippet
# While Loop
snippet wh
while(${1}){
${2}
}
endsnippet
# switch
snippet sw
switch(${1}){
${2}
}
endsnippet
# for
snippet for
for(${1}){
${2}
}
endsnippet
```
- c.snippets 及 cpp.snippets 內容如下
```=
extends cgeneral
```
新增以下至 ```~/.vimrc```
```=
let mapleader = "\<Space>"
let g:UltiSnipsSnippetDirectories=["mysnippets"]
" UltiSnips 的 tab 键与 YCM 冲突,重新设定
let g:UltiSnipsExpandTrigger="<leader><tab>"
let g:UltiSnipsJumpForwardTrigger="<leader><tab>"
let g:UltiSnipsJumpBackwardTrigger="<leader><s-tab>"
```
## 安裝YCM
### 安裝
ycm 這插件並不只單純 Plugin 就完成了,還需以下設定
```=
$ sudo apt install build-essential cmake
$ sudo apt install python3-dev
$ cd ~/.vim/bundle/YouCompleteMe
$ ./install.py --clang-completer
```
在 ```~/.vimrc``` 中加入
```=
let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/.ycm_extra_conf.py'
"默認使用"
let g:ycm_confirm_extra_conf = 0
```
- 若沒有支援c++的智能補充,檢查 ```.ycm_extra_conf.py``` 中的 flags 是否有
```=
'-isystem',
'/usr/include/c++/[版本]'
```
### 美化
#### 改變提視窗框顏色
```=
highlight PMenu ctermfg=0 ctermbg=242 guifg=black guibg=darkgrey
highlight PMenuSel ctermfg=242 ctermbg=8 guifg=darkgrey guibg=black
```
#### 自動提示
因為預設內容的提示框,要文章之前有輸入過才會顯示,因此得手動在 ```~/.vimrc```中加入:
```=
let g:ycm_semantic_triggers = {
\ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'],
\ 'cs,lua,javascript': ['re!\w{2}'],
\ }
```
最後建議設置一下: ```g:ycm_filetype_whitelist``` 這個白名單,避免編輯白名單的文件時YCM也在那分析半天。
```=
let g:ycm_filetype_whitelist = {
\ "c":1,
\ "cpp":1,
\ "python":1,
\ "objc":1,
\ "sh":1,
\ "zsh":1,
\ "zimbu":1,
\ }
```
### 關閉自動提示函式原型預覽視窗
```=
set completeopt=menu,menuone
let g:ycm_add_preview_to_completeopt = 0
```
## 項目樹
```=
" 使用 NERDTree 插件查看工程文件。设置快捷键,速记:file list
noremap <F1> :NERDTreeToggle<CR>
" 设置NERDTree子窗口宽度
let NERDTreeWinSize=32
" 设置NERDTree子窗口位置
let NERDTreeWinPos="left"
" 不显示隐藏文件
let NERDTreeShowHidden=0
" NERDTree 子窗口中不显示冗余帮助信息
let NERDTreeMinimalUI=1
" 删除文件时自动删除文件对应 buffer
let NERDTreeAutoDeleteBuffer=1
"當副檔名為這些時自動開啟
autocmd vimenter * if (&filetype == 'c' || &filetype == 'cpp' || &filetype == 'java') | NERDTree | endif
" 当所有文件关闭时关闭项目树窗格
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" 不显示这些文件
let NERDTreeIgnore=['\.pyc$', '\~$', 'node_modules'] "ignore files in NERDTree
"資料夾開關圖示
let NERDTreeDirArrows = 1
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'
```
## 一鍵編譯
  每次都要儲存退出再編譯執行,太過麻煩,因此以下可將以下程式碼加入 ```~/.vimrc``` (預設F5)
```=
map <F5> :call CompileRunGcc() <CR><CR><CR>
func! CompileRunGcc()
exec "w"
exec '!clear'
if &filetype == 'c'
exec '!gcc % -o %< -lm'
exec '! ./%<'
elseif &filetype == 'cpp'
exec '!g++ % -o %<'
exec '! ./%<'
elseif &filetype == 'python'
exec '! python %'
endif
endfunc
```
## 自動格式化(排版)
```=
sudo apt-get install astyle
sudo apt-get install python3-autopep8
```
- ```~/.vimrc```
```=
let g:formatdef_harttle = '"astyle --style=google --pad-oper --break-closing-braces --indent-switches"'
let g:formatdef_autopep8 = '"autopep8"'
let g:formatters_c = ['harttle']
let g:formatters_cpp = ['harttle']
let g:formatters_java = ['harttle']
let g:formatters_python = ['autopep8']
noremap <F3> :Autoformat<CR>
```
- [astyle 格式代碼](http://astyle.sourceforge.net/astyle.html)
## 完整 .vimrc
```.vimrc=
filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'Lokaltog/vim-powerline'
Plugin 'octol/vim-cpp-enhanced-highlight'
Plugin 'nathanaelkane/vim-indent-guides'
Plugin 'SirVer/ultisnips'
Plugin 'Chiel92/vim-autoformat'
Plugin 'Valloric/YouCompleteMe'
Plugin 'scrooloose/nerdcommenter'
Plugin 'scrooloose/nerdtree'
Plugin 'Raimondi/delimitMate'
call vundle#end()
filetype plugin indent on
set termguicolors
set t_Co=256
set background=dark
set laststatus=2
set ruler
set number
set cursorline
hi LineNr gui=bold guifg=DarkGrey guibg=NONE
hi Cursorline cterm=none gui=none guibg=darkblue
set hlsearch
nnoremap <c-l> :nohl<cr>
set nowrap
set mouse=a
set backspace=2
syntax enable
syntax on
filetype indent on
set expandtab
set tabstop=4
set shiftwidth=4
set softtabstop=4
set foldmethod=syntax
set nofoldenable
let g:indent_guides_enable_on_vim_startup=1
let g:indent_guides_start_level=2
let g:indent_guides_guide_size=1
let mapleader = "\<Space>"
:nmap <silent> <Leader>i <Plug>IndentGuidesToggle
let g:UltiSnipsSnippetDirectories=["mysnippets"]
let g:UltiSnipsExpandTrigger="<leader><tab>"
let g:UltiSnipsJumpForwardTrigger="<leader><tab>"
let g:UltiSnipsJumpBackwardTrigger="<leader><s-tab>"
let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/.ycm_extra_conf.py'
let g:ycm_confirm_extra_conf = 0
let g:ycm_semantic_triggers = {
\ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'],
\ 'cs,lua,javascript': ['re!\w{2}'],
\ }
let g:ycm_filetype_whitelist = {
\ "c":1,
\ "cpp":1,
\ "python":1,
\ "objc":1,
\ "sh":1,
\ "zsh":1,
\ "zimbu":1,
\ }
highlight PMenu ctermfg=0 ctermbg=242 guifg=black guibg=darkgrey
highlight PMenuSel ctermfg=242 ctermbg=8 guifg=darkgrey guibg=black
set completeopt=menu,menuone
let g:ycm_add_preview_to_completeopt = 0
noremap <F1> :NERDTreeToggle<CR>
let NERDTreeWinSize=25
let NERDTreeWinPos="left"
let NERDTreeShowHidden=0
let NERDTreeMinimalUI=1
let NERDTreeAutoDeleteBuffer=1
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
let NERDTreeIgnore=['\.pyc$', '\~$', 'node_modules'] "ignore files in NERDTree
let NERDTreeDirArrows = 1
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'
let g:formatdef_harttle = '"astyle --style=google --pad-oper --break-closing-braces --indent-switches"'
let g:formatdef_autopep8 ='"autopep8"'
let g:formatters_c = ['harttle']
let g:formatters_cpp = ['harttle']
let g:formatters_java = ['harttle']
let g:formatters_python = ['autopep8']
noremap <F3> :Autoformat<CR>
map <F5> :call CompileRunGcc() <CR><CR><CR>
func! CompileRunGcc()
exec "w"
exec '!clear'
if &filetype == 'c'
exec '!gcc % -o %< -lm'
exec '! ./%<'
elseif &filetype == 'cpp'
exec '!g++ % -o %<'
exec '! ./%<'
elseif &filetype == 'python'
exec '!python %'
endif
endfunc
map <F6> ggvG"+y
map <F7> ggvGddd
map <F8> :call OpenExam() <CR> ggdd :9 <CR>
func! OpenExam()
if &filetype == 'c'
exec "r exam.c"
elseif &filetype == 'cpp'
exec "r exam.cpp"
endif
endfunc
```
## WSL 系統剪貼簿
- 使用WSL的人,需要修改一下```.vimrc```中```map <F6>```那一小段,即可在vim中以```<C-y>```、```<C-x>```來複製、剪下了
```=
func! GetSelectedText()
normal gv"xy
let result = getreg("x")
return result
endfunc
noremap <silent><C-y> :call system('/mnt/c/Windows/System32/clip.exe', GetSelectedText())<CR>
noremap <silent><C-x> :call system('/mnt/c/Windows/System32/clip.exe', GetSelectedText())<CR>gvx
map <F6> ggvG<C-y>
```