日期 | 作者 | 版本 | 备注 |
---|---|---|---|
2021-03-24 | dingbin | V1.0 | |
C++程序员日常开发中不可避免地遇到变更电脑,变更服务器等事情时重建搭建C++开发环境实在过于繁重,需要耗费很多不必要的宝贵时间。vim 的YouCompleteMe(简称YCM) 插件可以实现较好的C/C++语言自动补全跳转功能,是利用vim进行C /C++代码编辑的必备神器之一。然后实际中YCM的安装及其复杂,不仅依赖python动态链接库,还依赖特定高版本的gcc和clang或clangd和cmake等。准备这些前置组件也很费时费力。有鉴于此,本文介绍一种新的玩法,并给出实际操作细节和直接可用的docker镜像成果,即:构建基于Vim的C++补全跳转插件YouCompleteMe的Docker镜像,一键完成任意机器上C++开发环境搭建。具体操作方法介绍如下。
环境准备
时间: 2021-03-24
机器配置:CentOS Linux release 7.5.1804 (Core),8核 12G
创建基础的docker镜像
考虑安装当前时间下最新版本的vim和YoucompleteMe插件。参考YouCompleteMe官网介绍的安装方法要求vim/gcc/clang/clangd/cmake/python都在比较高的版本下才能安装成功。而我们为了制作docker 镜像,因此不可能选很旧的基础os。参考YCM官网的建议,我们基础OS选择ubuntu 20.04 LTS。hub.docker.com上直接现成的镜像文件。配置文件需要准备好如下3个配置文件,本文直接贴出原文内容如下:
vim配置文件.vimrc
set nocompatible " be iMproved, required
filetype off " required
set encoding=utf-8
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'flazz/vim-colorschemes'
Plugin 'godlygeek/csapprox'
Plugin 'Valloric/YouCompleteMe'
call vundle#end() " required
filetype plugin indent on " required
set cst
set csto=1
set nocsverb
set csverb
"set smd "set showmode
"set sc "set showcmd
set aw "set autowrite
set awa "set autowriteall
set title
"使打开文件时使光标自动定位到上一次文件被关闭时的准确行
if has("autocmd")
autocmd BufRead *.txt set tw=78
au BufReadPost * exe "normal! g`\""
endif
"设置高亮关键字显示
syntax enable
syntax on "等同于syn on
"禁止在搜索到文件两端时重新搜索
"set nows "set nowrapscan
set ws
"设置搜索式的匹配字符串高亮显示
set hls "set hlsearch
"设置搜索式的匹配字符串不高亮显示
"set nohls "set nohlsearch
"高亮光标所在的当前行set cursorline
set cul "相反的设置是set nocul
"set nocul
"搜索时在未完全输入完毕要检索的文本时就开始检索
set is "set incsearch
"搜索时在未完全输入完毕要检索的文本时不开始检索
"set nois "set noincsearch
"设置以backspace删除自动缩进的,行末回车,行首的字符,很有用
set backspace=indent,eol,start
set ic "相反是 set noic
"set scs "相反是 set noscs
"增强模式中的命令行自动完成操作,非常有用
set wildmenu
"设置代码折叠为按语法折叠
"set foldmethod=syntax
"设定折叠方式为手动
set foldmethod=manual
"设置启动vim时不要自动折叠代码
set foldlevel=100
set fdc=1 "set foldcolumn=1
"设置帮助的语言为中文
set helplang=cn
"set helplang=en
"实现C程序的缩进(indent)
set cin
"设置行号
set nu
"set nonu
"设置256色彩
set t_Co=256
"设置配色方案
"colorscheme 简写成colo
"colo colorful
"colo white2
colo desert
"colo night
"colo navajo
"colo lucius
"colo blackdust
"colo freya
"colo darkslategray
"colo torte
"colo fruidle
"colo colorful
"设置编辑模式下状态栏标尺显示
set ru "set ruler
"设置编辑模式下状态栏标尺不显示
"set noru "set noruler
"记录历史的行数
set history=1000
"检测文件类型
"filetype on
filetype plugin on
" 开启文件类型检测 的插件和缩进开
filetype plugin indent on
"设置可以至上一行和下一行的字符按键
set ww=b,s,<,>,[,] ",h,l
"Alt组合键不映射到菜单上
set winaltkeys=no
"同时支持GBK和UTF-8编码
set fileencodings=utf-8,ucs-bom,gbk,cp936
set fileencoding=utf-8
set encoding=utf-8
"如果在终端环境下使用Vim,需要设置termencoding和终端所使用的编码一致。例如:
set termencoding=utf-8
"设置更新ctags文件的快捷键
"map : ! ${HOME}/tools/gen_tags_by_dingbin.bash "%:p:h" z6tags
"map : ! ${HOME}/tools/gen_tags_by_dingbin.bash "%:p:h" oatags
"map : ! ${HOME}/tools/gen_tags_by_dingbin.bash "%:p:h" qttags
"====================================================================================================================
"map : cs show : let @i = &tags :let @j = $CSCOPE_TAGS : !genvimtags -vimCtags i -vimCscope j :so ${VIM_SCRIPT_HOME}/configure/vimSourceFile
"map : cs show : let @i = &tags :let @j = $CSCOPE_TAGS : !genvimtags -g -vimCtags i -vimCscope j :so ${VIM_SCRIPT_HOME}/configure/vimSourceFile
"====================================================================================================================
"设置grep插件的快捷键
"nnoremap :Grep
"-----------------------------------------------------
"自动缩进的时候, 缩进尺寸为 4 个空格。
"即shiftWidth,自动缩进的空格数,用于<<,>>,cindent
set shiftwidth=4
"softtabstop,sts,默认是0,
"执行编辑操作,如插入 或者使用 时,把 算作空格的数目
set softtabstop=4 "set sts=4
"编辑时将所有 Tab 替换为空格。
"该选项只在编辑时将 Tab 替换为空格, 如果打开一个已经存在的文件, 并不会将已有的Tab 替换为空格。
"设置了该选项后,如果想输入tab制表符,先输入CTRL-V或CTRL-Q,再输入tab制表符
set et "相反的设置是set noet
"Tab 宽度为 4 个字符。
set ts=4 "即set tabstop=4
"Tab操作快捷方式!
"nnoremap :tabnext:TlistClose:TlistToggle
"nnoremap :tabprev:TlistClose:TlistToggle
"nnoremap :tabnext:TlistClose
"nnoremap :tabprev:TlistClose
""关于tab的快捷键
"map tn :tabnext
"map tp :tabprevious
"map td :tabnew .
"map te :tabedit
"map tc :tabclose
""map tf :tabnew %:p:TlistClose:TlistToggle
"map tf :tabnew %:p:TlistClose
"覆盖文件时不备份
set nobackup
"成功保存文件之前备份
set wb "set writebackup
"set nowb "set nowritebackup
"插入括号时,短暂地跳转到匹配的对应括号
set sm "set showmatch
"短暂跳转到匹配括号的时间
set matchtime=2
"设置魔术
set magic
"允许在有未保存的修改时切换缓冲区,此时的修改由 vim 负责保存
set hidden
"开启新行时使用智能自动缩进
set smartindent
set autoindent
"打开普通文件类型的自动缩进。 该自动缩进不如 cindent 智能, 但它可以为你编辑非 C/C++ 文件提供一定帮助。
set ai
"选中状态下 Ctrl+c 复制
"vmap "+y
"注意使用的过程中可以通过e和b键盘以word为单位前进或后退以选择文本
"set keymodel= "不使用此功能
set keymodel=startsel,stopsel "使用此功能
"visual 模式下标签查找(*,#)可用
vnoremap * y/"
vnoremap # y?"
nnoremap g[ :tag =expand("")
vnoremap g[ :tag *
:inoremap ( ()i
:inoremap [ []i
:inoremap ;; A;
"插入模式下使Ctrl+ h,j,k,l四个键效果等同于移动上、下、左、右方向键
inoremap
inoremap
inoremap
inoremap
"插入模式下使ctrl+ w,b两个键效果等同于普通模式下ctrl+w(前进一个单词),ctrl+b(
"后退一个单词)
inoremap b
inoremap w
"插入模式下使ctrl+ f(front),Ctrl+e(end)两个键效果等同于普通模式下,键
inoremap
inoremap
"插入模式下ctrl + d,等效于普通模式下backspace键,
"插入模式下ctrl + x,等效于普通模式下delete键,
inoremap
inoremap
"指定在选择文本时,光标所在位置也属于被选中的范围
set selection=inclusive
"-----------------------------------------------------
"-----------------------------------------------------
"指定不折行。 如果一行太长, 超过屏幕宽度, 则向右边延伸到屏幕外面。如果使用图形界面的话, 指定不折行视觉效果会好得多。
set nowrap
"set wrap
"设置显示时一行的文本宽宽
set tw=80 "set textwidth=80
"添加水平滚动条。 如果你指定了不折行, 那为窗口添加一个水平滚动条就非常有必要了。
set guioptions-=b
"去除vim的GUI版本的toolbar
set guioptions+=T
"去除vim的GUI版本的menubar
set guioptions+=m
"设置断行,当一行的文字太长时,为自动智能在一个单词的中间
"空白处断开到下一行显示,注意:这里的断行只用显示,并不在行末加
set lbr "set linebreak
"打开断行模块对亚洲语言支持。 m 表示允许在两个汉字之间断行, 即使汉字之间没有出现空格。
"B 表示将两行合并为一行的时候, 汉字与汉字之间不要补空格。 该命令支持的更多的选项请参看用户手册。
set fo+=mB
"配置字体
"set fileencoding=gbk
"set guifont=Courier\ 11
"set guifont=Inconsolata\ Medium\ 9 "史上最好看的vim字体
"set guifont=Bitstream_Vera_Sans_Mono:h10:cANSI
"set gfw=幼圆:h10.5:cGB2312
set guifont=Bitstream\ Vera\ Sans\ Mono\ 13
"当右键单击窗口的时候, 弹出快捷菜单
set mousemodel=popup
"不使用选择模式
set selectmode=
"设置屏幕滚动的ctrl+d,ctrl+u的行数,默认是窗口的一半,即半屏
set scr=4
"-----------------------------------------------------
"""""""""""""""""""""""""""""""
""Taglist plugin settings
"""""""""""""""""""""""""""""""
"let Tlist_Auto_Highlight_Tag = 1
"let Tlist_Hightlight_Tag_On_BufEnter = 1
"let Tlist_GainFocus_On_ToggleOpen = 0 "if 0 focus at code window, if 1 focus at tag window
"
""启动vim自动打开taglist
"let Tlist_Auto_Open = 0
"
"" 不同时显示多个文件的 tag ,只显示当前文件的
"let Tlist_Show_One_File = 1
"
"" 如果 taglist 窗口是最后一个窗口,则退出 vim
"let Tlist_Exit_OnlyWindow = 1
"
""让当前不被编辑的文件的方法列表自动折叠起来
"let Tlist_File_Fold_Auto_Close = 0
"
""把taglist窗口放在屏幕的右侧,缺省在左侧
"let Tlist_Use_Right_Window=1
"
""显示taglist菜单
"let Tlist_Show_Menu = 1
"
""taglist window width
"let Tlist_WinWidth = 40
"
"let Tlist_Process_File_Always = 1
"
"" 是否允许打开taglist窗口时自动加宽窗口, 默认为允许.
"let Tlist_Inc_Winwidth = 1
"" 精简模式, 不同的tag类别之间没有空行, 默认为有空行
"let Tlist_Compact_Format = 1
"" tag是以何种顺序排序, 以"order"还是"name", 默认是order, 可以用s切换,
"let Tlist_Sort_Type = "order"
"
""用 + 数字切换Tab窗口
""用过Gnome-terminal的人都知道, 在一个Terminal里打开多个TAB窗口, 用ALT+数字就可以
""切换到相应的窗口. 很喜欢这个功能, 映射如下:
"
"noremap 1gt
"noremap 2gt
"noremap 3gt
"noremap 4gt
"noremap 5gt
"noremap 6gt
"noremap 7gt
"noremap 8gt
"noremap 9gt
"noremap 10gt
"
"
"""""""""""""""""""""""""""""""
""Winmanager plugin settings
"""""""""""""""""""""""""""""""
""设置界面分割
"let g:winManagerWindowLayout='FileExplorer|TagList'
""let g:winManagerWindowLayout = BufExplorer,FileExplorer|TagList"
""let g:winManagerWindowLayout = TagList|FileExplorer,BufExplorer"
"
""设置winmanager的宽度,默认为25
""let g:winManagerWidth = 30
"
""定义打开关闭winmanager按键
"nmap wm :WMToggle
""nmap :WMToggle
"nmap :TlistToggle
"
""1)将插件显示在右侧
""打开winmanager.vim,在function! StartWindowsManager()函数中修改:
""将:wincmd H 修改为wincmd L:
"" for now assume that the explorer windows always stay on the left.
"" TODO: make this optional later
"" make the explorers window always stay on the right ---by chenyong
"" wincmd H
""wincmd L
"
""2)进入vim自动打开winmanager
""在进入vim时自动打开winmanager
"let g:AutoOpenWinManager = 0
""相应的在winmanager.vim中修改:
""set auto open Winmanager
""if g:AutoOpenWinManager
""autocmd VimEnter * nested call s:StartWindowsManager()|1wincmd w
""endif
"
""3)退出缓冲区时,自动退出vim
""这个功能是参考了taglist的自动退出功能,在taglist.vim中修改的。
""函数:function! s:Tlist_Window_Exit_Only_Window()中的winbunr(2)改为winbunr(3),
""即只剩2个窗口时关闭,考虑到2个窗口肯定是同时存在,所以这样还是可行的:
""同时在vimrc中需要设置:
""let Tlist_Exit_OnlyWindow=1
"
"
"""""""""""""""""""""""""""""""
""QuickFix plugin settings
"""""""""""""""""""""""""""""""
"nmap :cw:cn
"nmap :cw:cp
"nmap :cclose
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""
""设定是否使用 quickfix 窗口来显示 cscope 结果
"""""""""""""""""""""""""""""""""""""""""""""""""""""
":set cscopequickfix=s-,g-,c-,d-,i-,t-,e-,f-
"
"
""cscope find"的用法:
""cs find c|d|e|f|g|i|s|t name
""0 或 s 查找本 C 符号(可以跳过注释)
""1 或 g 查找本定义
""2 或 d 查找本函数调用的函数
""3 或 c 查找调用本函数的函数
""4 或 t 查找本字符串
""6 或 e 查找本 egrep 模式
""7 或 f 查找本文件
""8 或 i 查找包含本文件的文件
"nmap s :cs find s =expand("")
"nmap g :cs find g =expand("")
"nmap c :cs find c =expand("")
"nmap t :cs find t =expand("")
"nmap e :cs find e =expand("")
"nmap f :cs find f =expand("")
"nmap i :cs find i ^=expand("")$
"nmap d :cs find d =expand("")
"
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""
""头文件与源文件相互切换a.vim settings
"""""""""""""""""""""""""""""""""""""""""""""""""""""
""nnoremap :A
""A 在新Buffer中切换到c\h文件
""AS 横向分割窗口并打开c\h文件
""AV 纵向分割窗口并打开c\h文件
""AT 新建一个标签页并打开c\h文件
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""
"" F11 : set csto=1, F12 : set csto=0
"""""""""""""""""""""""""""""""""""""""""""""""""""""
"nnoremap :set csto=1
"nnoremap :set csto=0
"
"
"" set cs hotkey
"nmap s :cs find s =expand("")
"nmap g :cs find g =expand("")
"nmap c :cs find c =expand("")
"nmap t :cs find t =expand("")
"nmap e :cs find e =expand("")
"nmap f :cs find f =expand("")
"nmap i :cs find i ^=expand("")$
"nmap d :cs find d =expand("")
"
"" Using 'CTRL-spacebar' then a search type makes the vim window
"" split horizontally, with search result displayed in
"" the new window.
"
"nmap s :scs find s =expand("")
"nmap g :scs find g =expand("")
"nmap c :scs find c =expand("")
"nmap t :scs find t =expand("")