# 将Vim打造成Python开发平台

## RHEL/CentOS vim安装

在RHEL/CentOS/Fedora发行版中，包含了以下软件包可以提高python开发效率

```
sudo yum install vim-enhanced vim-syntastic-python.noarch
```

> 安装vim增强包和语法扩展包之后，再使用`vim`编辑Python文件可以得到较好的语法高亮作用。

## 快速起步

> 本段落是快速完成Python Vim IDE设置的步骤，具体解释见本段落后的内容。本段落目标是尽快开始

* 安装[Vundle](https://github.com/VundleVim/Vundle.vim)扩展管理器

```
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
```

> [VIM and Python - a Match Made in Heaven](https://realpython.com/blog/python/vim-and-python-a-match-made-in-heaven/)这篇文章提供了非常详细的配置方法，并且提供了

* 使用[vimrc realpython](https://github.com/huataihuang/cloud-atlas-draft/tree/6f3204fffc11cf006abd394631e2598d98b415c3/img/vi/vimrc_realpython/README.md)或者直接从[VIM and Python - a Match Made in Heaven](https://realpython.com/blog/python/vim-and-python-a-match-made-in-heaven/)提供的[VIM config](https://github.com/j1z0/vim-config/blob/master/vimrc)保存成`~/.vimrc`
* 使用`vim`命令启动vim，然后执行如下命令安装插件：

```
:PluginInstall
```

> 如果vim版本过低或者vim编译时没有支持Python，则需要从源代码重新编译，过程比较繁杂。不成功的尝试见 [vim编译YouCompleteMe失败记录](https://github.com/huataihuang/cloud-atlas-draft/tree/6f3204fffc11cf006abd394631e2598d98b415c3/develop/vim/try_vim_compile_with_you_complete_me/README.md)。在fedora 27环境中，发行版提供的vim版本已经满足要求，可以省略这部分。
>
> 从源代码编译过程参考 [Building Vim from source](https://github.com/Valloric/YouCompleteMe/wiki/Building-Vim-from-source)

* 编译`ycm_core`（YouCompleteMe）

> `YoucompleteMe`插件安装后还需要编译一个`ycm_core`的库，这样可以快速语义分析补全或者函数变量快速转跳。编译需要`cmake`以及`python`开发的头文件

```
yum install cmake
yum install python2-devel python3-devel
```

```
cd ~/.vim/bundle/YouCompleteMe
./install.py --system-libclang --clang-completer --go-completer --js-completer
```

> 注意：我采用的是Fedora系统自带的libclang(`--system-libclang`)。完整的编译安装请参考[vim编译配置"YouCompleteMe"](https://github.com/huataihuang/cloud-atlas-draft/tree/6f3204fffc11cf006abd394631e2598d98b415c3/develop/vim/vim_ycm/README.md)

* 在`.vimrc`附加屏幕分割配置，这样就可以简化分割窗口的转跳，例如，原先使用`ctrl+w ctrl+j`才能调到下面的分割窗口，现在只需要简化成`ctrl+j`

```
set splitbelow
set splitright

"split navigations
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>
```

* 使用nerdtree功能（树状结构文件浏览）

```
:NERDTree
```

## 增加配置

> [vim进阶 | 使用插件打造实用vim工作环境](https://www.jianshu.com/p/56385f4f95f5)这篇文章是基于vundle的插件管理设置，推荐参考

* 取消备份

```
"disable backup
set nobackup
set noswapfile
```

* 默认文件编码utf-8

```
"file encode
set encoding=utf-8
```

* 设置查找

```
"search
set ic
set hls
set is
```

* 显示调整

突出显示当前行

```
"highlight current line
set cursorline
```

启动 vim 时关闭折叠代码

```
set nofoldenable
```

* 设置NERDTree
  * (未启用)默认启用`NERDTree`
  * 设置切换快捷键`ctrl-n`
  * 启用最小UI
  * 显示隐含文件（以`.`开头文件和目录）
  * (未启用)控制台启动时启动`NETDTree`
  * (未启用)启动`NERDTree`后将光标切换到文件

```
"autocmd vimenter * NERDTree
map <C-n> :NERDTreeToggle<CR>
let NERDTreeMinimalUI = 1
let NERDTreeShowHidden = 1

"let g:nerdtree_tabs_open_on_console_startup = 1
"let g:nerdtree_tabs_focus_on_files = 1
```

## 增加其他插件

> [VIM and Python - a Match Made in Heaven](https://realpython.com/blog/python/vim-and-python-a-match-made-in-heaven/)专注于Python，但是我也需要其他的插件来支持功能，所以在`call vundle#end()`行之前插入有关插件的配置

## 上述步骤已完成`vim ide for python`，以下步骤不需要执行，仅供参考

## vim环境检查

检查 `vim` 版本

```
vim --version
```

> `vim` 版本要求> 7.3，并且支持Python（可以看到上述输出有`+python`）

验证方法是在`vim`中运行命令`:python import sys; print(sys.version)`

可以看到输出

```
2.7.10 (default, Oct 23 2015, 18:05:06)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)]
```

## vim扩展

首先需要一个好的扩展管理器

> vim的扩展称为bundles或者plugins

### Vundle

vim有多种扩展管理器，最推荐的是[Vundle](https://github.com/gmarik/Vundle.vim)，就好像VIM的pip，安装方法如下

```
git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
```

然后在自己的用户目录添加一个文件

```
touch ~/.vimrc
```

然后在这个`.vimrc`文件开头添加

```
set nocompatible              " 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 'gmarik/Vundle.vim'

" Add all your plugins here (note older versions of Vundle used Bundle instead of Plugin)


" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required
```

然后开启`vim`程序，在命令中输入

```
:PluginInstall
```

可以看到Vundle自动下载安装插件

## 设置IDE

VIM不需要鼠标

### 分割页面

在`vim`中，使用命令 `:sv <filename>` 则垂直分隔页面，而使用`:vs <filename>`则水平分隔页面。

> 可以通过在`.vimrc`文件中设置屏幕的不同分隔区域

```
set splitbelow
set splitright
```

要在不同的split分区移动而不需要鼠标，则可以在`.vimrc`中添加以下配置

```
"split navigations
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>
```

这样就可以使用以下快捷键来移动

```
Ctrl-j move to the split below
Ctrl-k move to the split above
Ctrl-l move to the split to the right
Ctrl-h move to the split to the left
```

> `nnoremap`是nutshell中将一个键映射到另外一个键，例如上面的案例`nnoremap <C-J> <C-W><C-J>`表示将`<C-J`映射成`<C-W><C-j>`键。

### 缓存

缓存可以理解为最近打开的文件，vim提供了方便访问最近的缓存，只要输入`:b <buffer name or number>`用于切换到一个打开的缓存。可以使用`:ls`来列出所有缓存。

> 在`:ls`输出到最后，vim提示`Hit enter to continue`，你可以代之以`:b <buffer number>`来选择列表中的缓存。

### 代码目录

很多现代的IDE提供一个方便的折叠方式展示方法或者类，你可以在`.vimrc`中添加

```
" Enable folding
set foldmethod=indent
set foldlevel=99
```

但是这会是你必须使用`za`来进入目录，可以添加以下配置到`.vimrc`这样空格键就更好使用

```
" Enable folding with the spacebar
nnoremap <space> za
```

对于初始化命令，使用 `set foldmethod=indent`，创建行缩进的目录，这样可以更为方便。比较好的推荐插件是`SimpylFold`，可以在 `.vimrc` 中添加

```
Plugin 'tmhedberg/SimpylFold'
```

然后再次执行 `:PluginInstall` 就可以安装插件

然后在`.vimrc`中添加

```
let g:SimpylFold_docstring_preview=1
```

## Python缩排

对于Python，缩排是非常重要的，需要满足如下两点来完成缩进

* 缩进符合PEP8标准
* 自动处理缩进

在 `.vimrc` 中添加

```
au BufNewFile,BufRead *.py
    \ set tabstop=4
    \ set softtabstop=4
    \ set shiftwidth=4
    \ set textwidth=79
    \ set expandtab
    \ set autoindent
    \ set fileformat=unix
```

然后再添加以下内容

```
au BufNewFile,BufRead *.js, *.html, *.css
    \ set tabstop=2
    \ set softtabstop=2
    \ set shiftwidth=2
```

上述插件称为`ftype`，也就是让你可以针对不同的文件类型区分文件

* 自动缩排

自动缩排对于python不是总适用，所以我们为了解决这个问题，使用 `indentpython.vim`扩展

```
Plugin 'vim-scripts/indentpython.vim'
```

并且我们要避免不需要的空格，素以添加

```
au BufRead,BufNewFile *.py,*.pyw,*.c,*.h match BadWhitespace /\s\+$/
```

* UTF8支持

在`.vimrc`中添加

```
set encoding=utf-8
```

* 自动完成

一个非常好的自动完成插件 `Valloric/YouCompleteMe`，也就是添加

```
Bundle 'Valloric/YouCompleteMe'
```

不过，需要一些C库来避免插件自身的问题，文档介绍[installation instructions](https://github.com/Valloric/YouCompleteMe#mac-os-x-super-quick-installation)

```
let g:ycm_autoclose_preview_window_after_completion=1
map <leader>g  :YcmCompleter GoToDefinitionElseDeclaration<CR>
```

此外，如果提示错误：

```
ycm_client_support.[so|pyd|dll] and ycm_core.[so|pyd|dll] not detected; you need to compile YCM before using it. Read the docs!
```

这个报错是正常的，因为ycm需要手工编译出库文件

```
cd ~/.vim/bundle/YouCompleteMe
./install.py --clang-completer
```

## 支持Virtualenv

```
"python with virtualenv support
py << EOF
import os
import sys
if 'VIRTUAL_ENV' in os.environ:
  project_base_dir = os.environ['VIRTUAL_ENV']
  activate_this = os.path.join(project_base_dir, 'bin/activate_this.py')
  execfile(activate_this, dict(__file__=activate_this))
EOF
```

上述配置可以检查运行是否在virtualenv，并切换

## 语法检查和高亮

使用`syntastic`扩展

```
Plugin 'scrooloose/syntastic'
```

添加PEP8检查

```
Plugin 'nvie/vim-flake8'
```

然后再添加代码较好查看的方法

```
let python_highlight_all=1
syntax on
```

## 颜色

使用solarized用于GUI，以及Zenburn用于终端模式

```
Plugin 'jnurmine/Zenburn'
Plugin 'altercation/vim-colors-solarized'
```

以及检查环境来设置VIM模式

```
if has('gui_running')
  set background=dark
  colorscheme solarized
else
  colorscheme zenburn
endif
```

Solarized携带了两种theme，一种是dark，一种是light，切换非常方便，使用`F5`

```
call togglebg#map("<F5>")
```

## 文件浏览

```
Plugin 'scrooloose/nerdtree'
```

如果希望使用tabs，使用`vim-nerdtree-tabs`

如果需要隐藏`.pyc`文件，使用

## 超级搜索

```
Plugin 'kien/ctrlp.vim'
```

只要按下`Ctrl-P`就可以搜索

## 设置行号

```
set nu
```

## 集成Git

```
Plugin 'tpope/vim-fugitive'
```

## Powerline

```
Plugin 'Lokaltog/powerline', {'rtp': 'powerline/bindings/vim/'}
```

## 系统剪贴板

```
set clipboard=unnamed
```

## 在shell中使用vim

要激活，则在`~/.inputrc`添加

```
set editing-mode vi
```

一份完整清单[vimrc realpython](https://github.com/huataihuang/cloud-atlas-draft/tree/6f3204fffc11cf006abd394631e2598d98b415c3/img/vi/vimrc_realpython/README.md)

## 参考

* [VIM and Python - a Match Made in Heaven](https://realpython.com/blog/python/vim-and-python-a-match-made-in-heaven/)
* [vim安装YouCompleteMe 插件](http://www.cnblogs.com/junnyfeng/p/3633697.html)
* [vim进阶 | 使用插件打造实用vim工作环境](https://www.jianshu.com/p/56385f4f95f5)
