VIM配置笔记
2019-08-01 / Luo Jinrong   

笔记

最近实验室要换新电脑,想到所有的环境都要重新配,其实是有点拒绝的。后来想想这些东西要是不会的话,以后又有点麻烦了,所以还是换个电脑重新练练手吧。

前期准备

  • 下载一个高版本的VIM,具体版本号忘记了,大概7.5以上的都是可以的,太低的话就用不了自动补全的插件了,这也是最重要的。
  • 自己旧的配置文件直接复制过来,放在用户主目录下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
".vimrc
let Tlist_Show_One_File=1
let Tlist_Exit_OnluWindow=1
let g:winManagerWindowLayout='FileExplorer|TagList'
nmap wm :WMToggle<cr>

set tabstop=4
set sw=4
" 你在此设置运行时路径
set rtp+=~/.vim/bundle/Vundle.vim

call vundle#begin()
Plugin 'winmanager'
Plugin 'taglist.vim'
" 在这里面输入安装的插件
" Vundle 本身就是一个插件
Plugin 'gmarik/Vundle.vim'
Plugin 'ucompleteme'

Bundle 'Valloric/YouCompleteMe'
"所有插件都应该在这一行之前
call vundle#end()

" filetype off
filetype plugin indent on

"在所有状态下都可以使用鼠标
set mouse-=a

"括号自动补全
inoremap ( ()<Esc>i
inoremap [ []<Esc>i
inoremap { {<CR>}<Esc>O
autocmd Syntax html,vim inoremap < <lt>><Esc>i| inoremap > <c-r>=ClosePair('>')<CR>
inoremap ) <c-r>=ClosePair(')')<CR>
inoremap ] <c-r>=ClosePair(']')<CR>
inoremap } <c-r>=CloseBracket()<CR>
inoremap " <c-r>=QuoteDelim('"')<CR>
inoremap ' <c-r>=QuoteDelim("'")<CR>

function ClosePair(char)
if getline('.')[col('.') - 1] == a:char
return "\<Right>"
else
return a:char
endif
endf

function CloseBracket()
if match(getline(line('.') + 1), '\s*}') < 0
return "\<CR>}"
else
return "\<Esc>j0f}a"
endif
endf

function QuoteDelim(char)
let line = getline('.')
let col = col('.')
if line[col - 2] == "\\"
return a:char
elseif line[col - 1] == a:char
return "\<Right>"
else
return a:char.a:char."\<Esc>i"
endif
endf

"YCM配置
let g:ycm_global_ycm_extra_conf ='~/.ycm_extra_conf.py'
let g:ycm_seed_identifiers_with_syntax = 1 "C/C++关键字自动补全
nnoremap gl :YcmCompleter GoToDeclaration
nnoremap gf :YcmCompleter GoToDefinition
nnoremap gg :YcmCompleter GoToDefinitionElseDeclaration
" for ycm
let g:ycm_error_symbol = '>>'
let g:ycm_warning_symbol = '>*'
nnoremap gl :YcmCompleter GoToDeclaration
nnoremap gf :YcmCompleter GoToDefinition
nnoremap gg :YcmCompleter GoToDefinitionElseDeclaration
"nmap :YcmDiags
let g:ycm_semantic_triggers = {
\ 'c' : ['->', '.' , 're!\w{2}'],
\ 'objc' : ['->', '.', 're!\[[_a-zA-Z]+\w*\s', 're!^\s*[^\W\d]\w*\s',
\ 're!\[.*\]\s'],
\ 'ocaml' : ['.', '#'],
\ 'cpp,objcpp' : ['->', '.', '::'],
\ 'perl' : ['->'],
\ 'php' : ['->', '::'],
\ 'cs,java,javascript,typescript,d,python,perl6,scala,vb,elixir,go' : ['.'],
\ 'ruby' : ['.', '::'],
\ 'lua' : ['.', ':'],
\ 'erlang' : [':'],
\ }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here's the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>

from distutils.sysconfig import get_python_inc
import platform
import os
import subprocess
import ycm_core

DIR_OF_THIS_SCRIPT = os.path.abspath( os.path.dirname( __file__ ) )
DIR_OF_THIRD_PARTY = os.path.join( DIR_OF_THIS_SCRIPT, '/home/ljr/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party' )
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]

# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
# You 100% do NOT need -DUSE_CLANG_COMPLETER and/or -DYCM_EXPORT in your flags;
# only the YCM source code needs it.
#'-DUSE_CLANG_COMPLETER',
#'-DYCM_EXPORT=',
# THIS IS IMPORTANT! Without the '-x' flag, Clang won't know which language to
# use when compiling headers. So it will guess. Badly. So C++ headers will be
# compiled as C headers. You don't want that so ALWAYS specify the '-x' flag.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-isystem',
'cpp/pybind11',
'-isystem',
'cpp/BoostParts',
'-isystem',
get_python_inc(),
'-isystem',
'cpp/llvm/include',
'-isystem',
'cpp/llvm/tools/clang/include',
'-I',
'cpp/ycm',
'-I',
'cpp/ycm/ClangCompleter',
'-isystem',
'cpp/ycm/tests/gmock/gtest',
'-isystem',
'cpp/ycm/tests/gmock/gtest/include',
'-isystem',
'cpp/ycm/tests/gmock',
'-isystem',
'cpp/ycm/tests/gmock/include',
'-isystem',
'cpp/ycm/benchmarks/benchmark/include',

'-isystem',
'/usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0',
'-isystem',
'/usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/backward',
'-isystem',
'/usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/x86_64-linux-gnu/c++/7.4.0',
'-isystem',
'/usr/local/include',
#'-isystem',
#'/usr/lib/clang/6.0/include',
'-isystem',
'/usr/include/x86_64-linux-gnu',
'-isystem',
'/usr/include'
]

# Clang automatically sets the '-std=' flag to 'c++14' for MSVC 2015 or later,
# which is required for compiling the standard library, and to 'c++11' for older
# versions.
if platform.system() != 'Windows':
flags.append( '-std=c++11' )


# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''

if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None


def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]


def FindCorrespondingSourceFile( filename ):
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
return replacement_file
return filename


def Settings( **kwargs ):
if kwargs[ 'language' ] == 'cfamily':
# If the file is a header, try to find the corresponding source file and
# retrieve its flags from the compilation database if using one. This is
# necessary since compilation databases don't have entries for header files.
# In addition, use this source file as the translation unit. This makes it
# possible to jump from a declaration in the header file to its definition
# in the corresponding source file.
filename = FindCorrespondingSourceFile( kwargs[ 'filename' ] )

if not database:
return {
'flags': flags,
'include_paths_relative_to_dir': DIR_OF_THIS_SCRIPT,
'override_filename': filename
}

compilation_info = database.GetCompilationInfoForFile( filename )
if not compilation_info.compiler_flags_:
return {}

# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object.
final_flags = list( compilation_info.compiler_flags_ )

# NOTE: This is just for YouCompleteMe; it's highly likely that your project
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
try:
final_flags.remove( '-stdlib=libc++' )
except ValueError:
pass

return {
'flags': final_flags,
'include_paths_relative_to_dir': compilation_info.compiler_working_dir_,
'override_filename': filename
}
return {}


def GetStandardLibraryIndexInSysPath( sys_path ):
for path in sys_path:
if os.path.isfile( os.path.join( path, 'os.py' ) ):
return sys_path.index( path )
raise RuntimeError( 'Could not find standard library path in Python path.' )


def PythonSysPath( **kwargs ):
sys_path = kwargs[ 'sys_path' ]
for folder in os.listdir( DIR_OF_THIRD_PARTY ):
if folder == 'python-future':
folder = os.path.join( folder, 'src' )
sys_path.insert( GetStandardLibraryIndexInSysPath( sys_path ) + 1,
os.path.realpath( os.path.join( DIR_OF_THIRD_PARTY,
folder ) ) )
continue

if folder == 'cregex':
interpreter_path = kwargs[ 'interpreter_path' ]
major_version = subprocess.check_output( [
interpreter_path, '-c', 'import sys; print( sys.version_info[ 0 ] )' ]
).rstrip().decode( 'utf8' )
folder = os.path.join( folder, 'regex_{}'.format( major_version ) )

sys_path.insert( 0, os.path.realpath( os.path.join( DIR_OF_THIRD_PARTY,
folder ) ) )
return sys_path
  • 在主目录下新建.vim/bundle,下载Vundle插件管理器到该目录下。
  • 进入vim,使用命令:PluginInstall安装.vimrc配置文件中列出来的插件,其中YouCompleteMe就是自动补全的插件,但是这里下载会比较慢,如果不愿意等的话(而且也不知道要等多久),可以使用git下载,不过如果不能翻墙的话,也不推荐从github下载,github下载速度太慢了。
  • 额外讲一下怎么快速下载github上面的仓库,
    • 首先在github上fork那个项目
    • 然后用github登录码云
    • 右上角+选择从github导入,选择自己刚刚fork的项目
    • 然后命令行git clone 码云上的该项目的ssh就可以快速下载该项目了
  • 下载完YCM之后如果直接运行下面的install.sh的话,会提示一些依赖项目还没有下载,可以使用git submodule update --init --recursive进行下载,如果嫌慢也可以用上述办法,不过一个一个找项目会非常的麻烦。
  • 网上说要build一下,我也不知道是不是必要的,不过还是先贴着吧cmake -G "Unix Makefiles" -DUSE_SYSTEM_LIBCLANG=ON . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
  • 注意运行install.sh要加参数--clang-completer,这样才可以补全头文件。
  • 大概就是这样子吧,打开vim看看,如果下面有报错的话,百度解决一下,下面的事情就不麻烦了。一般报错信息里面包含ycm的都是这个插件还没有配置好,不过只要运行install.sh没有报错就没什么问题了。
  • 相关下载:
    • apt下载:gcc,g++,python3-pip,ctags,cmake,clang
    • pip3下载:future

return 0;


本文链接:
https://luojinrong.github.io/2019/08/01/VIM配置笔记/