mac定制开发环境记录
前言
以前一直使用windows系统工作,因此很自然就使用了visual studio作为开发工具。编写代码使用visual studio,写完后上传到服务器上使用g++编译。最近切换到mac os系统下做开发,考虑到以前也使用过vim,很多快捷键都用熟悉了,因此决定使用vim来做主要的开发编辑器。
vim本身作为编辑器和visual studio比起来很多功能都很弱甚至根本没有,但是通过丰富的vim插件基本可以做到和visual stiduo相同的体验,甚至抛开了鼠标使敲代码更加快意。因此我把自己使用visual studio时常用的一些功能做了罗列,再去寻找相应的vim插件:
- 自动补全
- 跳转声明、定义
- 跳转头文件
- 代码错误提示
- 多文件切换
- 快速注释、取消注释
- 目录树浏览
- 文件快速查找
安装
根据以上内功能,我查找资料后找到了以下插件,通过他们基本可以实现上述功能:
- YouCompleteMe
- NERDTree
- NERDCommenter
- ctrlp
- vim-airline
vim插件可以通过Vundle插件管理工具简便的安装,因此先安装Vundle插件。
Vundle
首先在~/目录下新建.vim目录,然后使用以下命令从Vundle的github拉取插件:
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
然后将以下配置添加到.vimrc文件的顶部:
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.
" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
" plugin from http://vim-scripts.org/vim/scripts.html
" Plugin 'L9'
" Git plugin not hosted on GitHub
Plugin 'git://git.wincent.com/command-t.git'
" git repos on your local machine (i.e. when working on your own plugin)
Plugin 'file:///home/gmarik/path/to/plugin'
" The sparkup vim script is in a subdirectory of this repo called vim.
" Pass the path to set the runtimepath properly.
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
" Install L9 and avoid a Naming conflict if you've already installed a
" different version somewhere else.
" Plugin 'ascenator/L9', {'name': 'newL9'}
" 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
在上述配置中,需要手动添加需要安装的插件,配置命令为Plugin '<PluginName>'
;然后启动vim,输入命令:PluginInstall
,Vundle将会根据配置文件里面的配置依次安装插件,注意添加的配置命令需要放在call vundle#begin()
和call vundle#end()
之间。我自己的配置命令如下:
Plugin 'VundleVim/Vundle.vim'
Plugin 'ctrlp.vim'
Plugin 'taglist.vim'
Plugin 'The-NERD-Commenter'
Plugin 'The-NERD-tree'
Plugin 'winmanager'
Plugin 'molokai'
Plugin 'Valloric/YouCompleteMe'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
YouCompleteMe
安装YoucompleteMe时,若需要支持C系语言,需要使用clang,因此需要手动编译。使用Vundle自动安装YouCompleteMe完成后,在.vim/bundle/
目录下会产生一个YouCompleteMe
目录,进入其中执行./install.py --clang-completer
命令,这个python脚本将会自动编译安装插件的所需要的动态库。
编译安装完成之后,需要将~/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py
文件拷贝到工程的根目录下;每次启动vim后,插件都将在依次在当前目录以及父目录下寻找该文件;该文件定义了clang的编译选项以及一些配置,用于生成补全需要的数据;在~目录下默认放一个该文件即可,也可以根据需要拷贝到工程目录下定制修改,插件会优先使用最先找到的.ycm_extra_conf.py
文件。在该配置文件中可以指定项目使用的头文件路径,这样插件在补全的时候会根据配置的头文件路径去分析查找补全字段,配置方式如下:
# 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 in your flags; only the YCM
# source code needs it.
'-DUSE_CLANG_COMPLETER',
# THIS IS IMPORTANT! Without a "-std=<something>" 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
# a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++11',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-isystem',
'../BoostParts',
'-isystem',
# This path will only work on OS X, but extra paths that don't exist are not
# harmful
'/System/Library/Frameworks/Python.framework/Headers',
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I',
'.',
'-I',
'/Users/joee33/include',
'-I',
'./ClangCompleter',
'-isystem',
'./tests/gmock/gtest',
'-isystem',
'./tests/gmock/gtest/include',
'-isystem',
'./tests/gmock',
'-isystem',
'./tests/gmock/include',
]
在flag
标签下的值中按照规则添加即可,如上述配置中我的配置为:
'-I',
'/Users/joee33/include',
其他插件
其他几个插件Vundle会自动安装,无需其他的操作
使用方法
自动补全
示例代码:
using namespace std;
using std::map;
using std::list;
class A {
public:
A() {
}
A(int a_, int b_): _a(a_), _b(b_) { }
int a() { return _a; }
int b() { return _b; }
void a(int v) { _a = v; }
void b(int v) { _b = v; }
int max() { return _a > _b? _a: _b; }
int add() { return _a + _b; }
void hello() { cout << "hello,world" << endl; }
void print() { cout << "print test" <<endl; }
private:
int _a;
int _b;
};
map<int, int> m;
list<int> l;
int main(int argc, char* argv[]) {
}
插件安装成功后,启动vim打开C/C++文件,在输入代码时,就可以看到自动补全的候选列表,效果如下图:
跳转声明、定义 && 跳转头文件 && 查看变量类型
YouCompleteMe插件提供自动补全功能的同时,也提供了跳转声明和定义的功能,但是前提是声明或定义文件能被插件找到。
跳转声明的命令::YcmCompleter GoToDeclaration
跳转定义的命令::YcmCompleter GoToDefinition
跳转申明或定义::YcmCompleter GoToDefinitionElseDeclaration
跳转头文件::YcmCompleter GoToInclude
查看变量类型::YcmCompleter GetType
以上命令都比较长,因此可以在~/.vimrc
文件使用快捷键做映射,方便使用,这也是使用vim的好处之一。~/.vimrc
文件中配置如下:
let mapleader = ','
nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR> "跳转到申明
nnoremap <leader>gf :YcmCompleter GoToDefinition<CR> "跳转到定义
nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR> "跳转到定义或申明
nnoremap <leader>gi :YcmCompleter GoToInclude<CR> "跳转到头文件
nnoremap <leader>gt :YcmCompleter GetType<CR> "获取类型
let g:ycm_confirm_extra_conf=0 "启动是默认加载.ycm_extra_conf.py文件
配置好之后,将光标移动到要查看的方法或者变量上,在vim Normal模式下使用以下快捷按键,其中逗号为<leader>
符号:
跳转声明:,gl
跳转定义:,gf
跳转声明或定义:,gg
跳转头文件:,gi
跳转变量类型:,gt
代码错误提示
YouCompleteMe插件也提供代码错误提示功能。如忘记分号、括号、关键字拼写错误、变量未定义等错误,都可以在编写时被发现。效果如下:
当光标移动到错误行时,状态栏会给出错误提示信息。
多文件切换
在编写代码时,会经常同时打开并编辑多个文件,vim-airline插件扩展了vim本身的buffer功能,让多文件切换更加直观。效果图如下:
在vim窗口顶部会排列现实buffer中的文件,使用命令可以方便的各个buffer中切换。
打开第几个buffer:b<n> \*n为buffer编号*\
打开下一个buffer:bn
打开上一个buffer:bp
也可以根据个人喜好在~./vimrc
中配置快捷按键,我的配置如下:
" 打开tabline功能,方便查看Buffer和切换,省去了minibufexpl插件
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show = 1
" 设置切换Buffer快捷键
nnoremap <C-t> :bn<CR>
nnoremap <C-s-t> :bp<CR>
使用ctrl+t
切换到下一个buffer, ctrl + s + t
切换到上一个buffer。
快速注释、取消注释
在编写代码时,经常会用到注释和取消注释功能。NERDCommenter插件提供了丰富的注释快捷键。
,cc
:注释当前行
,cu
:取消注释
,cs
:添加注释说明 /*/
,cy
:复制并注释当前行
,c$
:从当前位置注释到行尾
,cA
:跳转到行尾添加注释并进入编辑模式
,ca
:切换注释方式
目录树浏览
NERDTree插件提供了浏览文件目录的功能。安装插件后,使用:NERDTreeToggle
命令唤出窗口,插件将显示以当前路径为根目录的目录树,效果如下:
在.vimrc
文件中配置F2为快捷键唤出窗口:
map <F2> :silent! NERDTreeToggle<CR> "设置F2快捷键
NERDTree提供了书签功能,可以将常用的目录以书签的形式保存起来,下次启动直接打开书签即可打开相应目录。在NERDTree窗口中将光标移动到要标记为书签的目录上,使用命令Bookmark <name>
即可添加书签,ClearBookMarks <name list>
删除书签。
NERDTree也提供了一些命令方便操作,在NERDTree的窗口直接执行即可:
q
:推出
o
:打开文件目录或文件或书签
O
:打开目录下的所有子目录
x
:关闭当前目录
X
:关闭所有子目录
i
:水平打开文件
s
:垂直打开文件
ctrl + w + r
:切换NERDTree窗口位置(左侧或右侧)
文件快速查找
在编写代码过程中需要快速查找文件,ctrlp插件提供了该功能。插件安装完成后,使用快捷键ctrl + p
即可唤出查找窗口,输入文件名的同时,插件将列出符合条件的候选文件。
ctrlp的文件名匹配模式有2 * 2 = 4种,分别为
- 全路径匹配(提示符:
>>>
) - 文件名匹配(提示符:
>d>
)
和
- 字符串匹配(提示符:
r>>
) - 正则表达式匹配(提示符:
>>>
)
之间的组合。
唤出搜索栏后按ctrl + d
在全路径匹配和文件名匹配间切换;ctrl + r
在正则表达式匹配和字符串匹配之间切换。
效果如下图:
后记
以上为我根据自己的需要配置的vim开发环境。下面附上我的整个~\.vimrc
文件。
set nocompatible " be iMproved, required
filetype off " required
syntax on
set number
set ts=4
set noexpandtab
%retab!
" 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 'ctrlp.vim'
Plugin 'taglist.vim'
Plugin 'The-NERD-Commenter'
Plugin 'The-NERD-tree'
Plugin 'winmanager'
Plugin 'molokai'
Plugin 'Valloric/YouCompleteMe'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'vim-sync'
" The following are examples of different formats supported.
" Keep Plugin commands between vundle#begin/end.
" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
" plugin from http://vim-scripts.org/vim/scripts.html
" Plugin 'L9'
" Git plugin not hosted on GitHub
" Plugin 'git://git.wincent.com/command-t.git'
" git repos on your local machine (i.e. when working on your own plugin)
Plugin 'file:///home/gmarik/path/to/plugin'
" The sparkup vim script is in a subdirectory of this repo called vim.
" Pass the path to set the runtimepath properly.
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
" Install L9 and avoid a Naming conflict if you've already installed a
" different version somewhere else.
" Plugin 'ascenator/L9', {'name': 'newL9'}
" 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
" 设置主题配色
let g:molokai_original = 1
let g:rehash256 = 1
colorscheme molokai
" NERDTree Settings{
let NERDTreeShowBookmarks=1 "当打开NERDTree窗口时,自动显示Bookmarks
map <F2> :silent! NERDTreeToggle<CR> "设置F2快捷键
" }
" YouCompleteMe{
let mapleader = ','
let g:ycm_error_symbol = 'e>'
let g:ycm_warning_symbol = 'w>'
nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR> "跳转到申明
nnoremap <leader>gf :YcmCompleter GoToDefinition<CR> "跳转到定义
nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR> "跳转到定义或申明
nnoremap <leader>gi :YcmCompleter GoToInclude<CR> "跳转到头文件
nnoremap <leader>gt :YcmCompleter GetType<CR> "获取类型
let g:ycm_confirm_extra_conf=0 "启动是默认加载.ycm_extra_conf.py文件
" }
" 打开tabline功能,方便查看Buffer和切换,省去了minibufexpl插件
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show = 1
" 设置切换Buffer快捷键
nnoremap <C-t> :bn<CR>
nnoremap <C-s-t> :bp<CR>