Vim + Python – bộ đôi hoàn hảo

Vim + Python – bộ đôi hoàn hảo
Photo by Patrik Houštecký from Pixabay

Vài ngày trước, tôi đã viết bài hướng dẫn cấu hình Emacs, trong bài viết này tôi sẽ giới thiệu một môi trường phát triển phát triển Python nữa. Đó chính là Vim. Vim rất phổ biến, nhanh, nhẹ và không bao giờ bị crash. Và nó có thể làm được mọi thứ.

Có thể việc cấu hình Vim với người bắt đầu khá khó khăn, tuy nhiên, bạn đừng lo. Trong bài viết này, tôi sẽ chỉ cho bạn cách cấu hình Vim để biến nó trở thành một môi trường đầy sức mạnh cho việc phát triển Python.

vim ide

Trong bài viết này, tôi mặc định bạn đã biết cách sử dụng Vim về cơ bản. Nếu chưa, bạn thể tham khảo những hướng dẫn ở đây hay ở đây. Hãy tìm hiểu một chút về cách sử dụng Vim và một số lệnh của nó trước khi chúng ta bắt đầu.

Cài đặt

Bởi vì Vim được cài sẵn ở rất nhiều hệ điều hành *nix, nên trước hết, hãy kiểm tra xem nó đã được cài đặt chưa.

$ vim --version

Nếu Vim đã được cài rồi thì lệnh trên sẽ cho kết quả như dưới đây.

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Jan  2 2014 19:39:47)
Included patches: 1-52
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@
Huge version with GTK2-GNOME GUI.  Features included (+) or not (-):
+acl             +farsi           +mouse_netterm   +syntax
+arabic          +file_in_path    +mouse_sgr       +tag_binary
+autocmd         +find_in_path    -mouse_sysmouse  +tag_old_static
+balloon_eval    +float           +mouse_urxvt     -tag_any_white
+browse          +folding         +mouse_xterm     +tcl
++builtin_terms  -footer          +multi_byte      +terminfo
+byte_offset     +fork()          +multi_lang      +termresponse
+cindent         +gettext         -mzscheme        +textobjects
+clientserver    -hangul_input    +netbeans_intg   +title
+clipboard       +iconv           +path_extra      +toolbar
+cmdline_compl   +insert_expand   +perl            +user_commands
+cmdline_hist    +jumplist        +persistent_undo +vertsplit
+cmdline_info    +keymap          +postscript      +virtualedit
+comments        +langmap         +printer         +visual
+conceal         +libcall         +profile         +visualextra
+cryptv          +linebreak       +python          +viminfo
+cscope          +lispindent      -python3         +vreplace
+cursorbind      +listcmds        +quickfix        +wildignore
+cursorshape     +localmap        +reltime         +wildmenu
+dialog_con_gui  +lua             +rightleft       +windows
+diff            +menu            +ruby            +writebackup
+digraphs        +mksession       +scrollbind      +X11
+dnd             +modify_fname    +signs           -xfontset
-ebcdic          +mouse           +smartindent     +xim
+emacs_tags      +mouseshape      -sniff           +xsmp_interact
+eval            +mouse_dec       +startuptime     +xterm_clipboard
+ex_extra        +mouse_gpm       +statusline      -xterm_save
+extra_search    -mouse_jsbterm   -sun_workshop    +xpm
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  system gvimrc file: "$VIM/gvimrc"
    user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
    system menu file: "$VIMRUNTIME/menu.vim"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK  -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/libpng12 -I/usr/include/harfbuzz   -pthread -DORBIT2=1 -D_REENTRANT -I/usr/include/libgnomeui-2.0 -I/usr/include/libart-2.0 -I/usr/include/gconf/2 -I/usr/include/gnome-keyring-1 -I/usr/include/libgnome-2.0 -I/usr/include/libbonoboui-2.0 -I/usr/include/libgnomecanvas-2.0 -I/usr/include/gtk-2.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gnome-vfs-2.0 -I/usr/lib/x86_64-linux-gnu/gnome-vfs-2.0/include -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/orbit-2.0 -I/usr/include/libbonobo-2.0 -I/usr/include/bonobo-activation-2.0 -I/usr/include/libxml2 -I/usr/include/pango-1.0 -I/usr/include/gail-1.0 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/cairo -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/libpng12     -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1     -I/usr/include/tcl8.6  -D_REENTRANT=1  -D_THREAD_SAFE=1  -D_LARGEFILE64_SOURCE=1
Linking: gcc   -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -rdynamic -Wl,-export-dynamic -Wl,-E  -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed -o vim   -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfontconfig -lgobject-2.0 -lglib-2.0 -lfreetype     -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2 -lgnome-2 -lpopt -lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfontconfig -lfreetype -lgconf-2 -lgthread-2.0 -lgmodule-2.0 -lgobject-2.0 -lglib-2.0   -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE  -lm -ltinfo -lnsl  -lselinux  -lacl -lattr -lgpm -ldl  -L/usr/lib -llua5.2 -Wl,-E  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl/5.18/CORE -lperl -ldl -lm -lpthread -lcrypt -L/usr/lib/python2.7/config-x86_64-linux-gnu -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions  -L/usr/lib/x86_64-linux-gnu -ltcl8.6 -ldl -lz -lpthread -lieee -lm -lruby-1.9.1 -lpthread -lrt -ldl -lcrypt -lm  -L/usr/lib

Bạn cần kiểm tra 2 điểm:

  1. Phiên bản Vim, nó nên là bản 7.3 trở nên.
  2. Vim có hỗ trợ Python. Trong danh sách được đưa ra, hãy kiểm tra nếu có dòng +python là Vim đã hỗ trợ Python rồi.

Nếu hệ thống của bạn thỏa mãn cả 2 điểm trên, thì bạn đã sẵn sàng để cấu hình Vim. Bạn có thể bỏ qua phần install/upgrade này.

OS X

Một cách cài khá đơn giản trên OS X là sử dụng Homebrew.

$ brew update
$ brew install vim

*NIX

Với hệ điều hành Debian hay Ubuntu, bạn có thể cài đặt Vim bằng lệnh:

$ sudo apt-get remove vim-tiny
$ apt-get update
$ apt-get install vim

Với những bản phân phối khác của Linux, bạn có thể tham khảo tài liệu này để biết cách cài đặt Vim trên hệ thống của mình.

Windows

Có rất nhiều cách để cài Vim trên Windows, cách dễ dàng nhất là bạn hãy đọc và làm theo tài liệu của Vim.

Kiểm tra việc cài đặt

Bạn hãy chắc chắn rằng mình đã cài đặt Vim từ phiên bản 7.3 trở nên, và nó có hỗ trợ Python. Bạn có thể chạy lệnh vim --version để kiểm tra thêm lần nữa. Nếu bạn muốn kiểm tra phiên bản Python được Vim sử dụng, bạn có thể chạy lệnh :python import sys; print(sys.version) trong Vim.

2.7.6 (default, Jun 22 2015, 18:01:27)
[GCC 4.8.2]

Lệnh trên sẽ đưa ra phiên bản hiện tại của Python trên hệ thống của bạn. Nếu có lỗi xảy ra, nghĩa là Vim của bạn chưa hỗ trợ Python, bạn sẽ cần cài đặt lại nó.

Với Vim đã được cài đặt xong, phần tiếp theo, tôi sẽ trình bày cách tùy biến Vim để biến nó thành môi trường phát triển Python.

Update

Nếu bạn muốn phát triển bằng Python 3 thì Vim của bạn nên hỗ trợ Python 3 (+python3). Những cách cài đặt ở trên sẽ cài đặt phiên bản Vim hỗ trợ Python 2 (+python) mà không hỗ trợ Python 3 (-python3). Vì vậy, bạn sẽ cần cài đặt Vim từ mã nguồn của nó để có thể làm việc với Python 3 một cách tốt nhất.

Cách cài đặt của tôi như sau (Với hệ điều hành Ubuntu):

  • Cài đặt các gói cần thiết để build Vim từ mã nguồn.
$ sudo apt-get build-dep vim
  • Lấy mã nguồn Vim từ Github:
$ git clone https://github.com/vim/vim.git && cd vim
  • Config để Vim hỗ trợ Python 3
$ ./configure --with-features=huge --enable-multibyte \
  --enable-python3interp --enable-gui=gtk-2
  • Make và cài đặt
$ make && make install

Config trên sẽ giúp bạn cài đặt một phiên bản Vim khá đầy đủ tính năng, hỗ trợ Python 3, clipboard và một phiên bản Vim đồ họa (gvim). Phiên bản Vim này sẽ được cài vào thư mục /usr/local/ nên bạn hoàn toàn có thể dùng nó song song với các phiên bản Vim khác được cài đặt thông qua các trình quản lý package. Bạn có thể alias như sau để sử dụng 2 phiên bản Vim một cách nhanh chóng:

alias vimm='/usr/bin/vim'

Với alias trên, hệ thống của bạn sẽ có lệnh vim để làm việc với Python 3 và vimm để làm việc với Python 2.

Vim Extension

Vim có thể làm rất nhiều việc mà một developer cần. Tuy nhiên, Vim cũng có khả năng mở rộng rất linh hoạt, và cũng nó nhiều extension cho Vim để biến nó trở thành một IDE hiện đại. Nhưng trước tiên, bạn cần một trình quản lý extension tốt.

Extension của Vim thường được gọi là bundle hoặc plugin.

Vundle

Vim có rất nhiều trình quản lý extension khác nhau, nhưng tôi recommend bạn nên sử dụng Vundle. Vundle của Vim cũng giống như là pip của Python. Nó khiến việc cài đặt và cập nhật các extension trở nên rất đơn giản.

Để cài đặt Vundle, bạn dùng lệnh sau:

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

Lệnh trên sẽ download Vundle và lưu nó vào thư mục chứa plugin của Vim. Sau khi cài đặt Vundle, bạn có thể quản lý các extension từ trong file config.vimrc

Thêm file .vimrc vào thư mục HOME của bạn.

$ touch ~/.vimrc

Bây giờ, bạn cần cấu hình Vundle trong file .vimrc bằng cách thêm vào đó các nội dung sau.

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

Trên đây, bạn đã cấu hình để Vim sử dụng Vundle. Từ bây giờ, mỗi lần thêm plugin, nếu bạn muốn cài đặt, bạn chỉ cần mở Vim và chạy lệnh:

:PluginInstall

Lệnh trên sẽ chỉ dẫn Vundle làm công việc của một trình quản lý extension – download các plugin và cài đặt/update chúng cho bạn.

vim plugin install

Với người dùng Windows, bạn có thể tham khảo Windows Installation Instructions.

Biến Vim thành một IDE

Chúng ta khó có thể liệt kê tất cả các tính năng của Vim. Ở trong nội dung bài viết này, chúng ta sẽ kể ra một số tính năng quan trọng với những người phát triển Python.

Không sử dụng chuột

Một tính năng quan trọng nhất của Vim là nó không cần đến chuột (trừ một vài biến thể có giao diện đồ họa như gvim hay macvim). Khi mới bắt đầu, việc này có vẻ khó chịu, nhưng sau khi làm quen rồi bạn sẽ thấy hữu ích. Không sử dụng chuột khiến bạn không bị nhảy nhầm con trỏ ra vị trí khác nếu vô tình bạn chạm tay vào touch pad. Hãy nghiên cứu một số tổ hợp phím bạn sẽ thấy dùng Vim cũng rất thú vị.

Phân chia màn hình

Mở một file với lệnh :sv <filename> bạn sẽ chia màn hình Vim theo chiều thẳng đứng (nghĩa là file mới sẽ được mở bên trên file cũ). Hoặc dùng lệnh ngược lại :vs <filename> bạn sẽ chia màn hình theo chiều ngang (nghĩa là file mới được mở bên trái file cũ).

vim split layouts

Bạn có thể chia các màn hình lồng nhau, chia màn hình ngang bên trong màn hình đã được chia dọc, tùy theo bạn muốn. Bởi vì thường các developer vẫn cần đọc nhiều file một lúc, nên tính năng thực sự rất hữu ích.

Pro Tip: Bạn có thể dùng phím Tab để Vim đưa ra các gợi ý cho file sau khi gõ lệnh :sv.

Pro Tip: Bạn cũng có thể chỉ định các vùng màn hình khác nhau để chia bằng cách thêm các cấu hình sau vào file .vimrc:

set splitbelow
set splitright

Pro Tip: Nếu bạn muốn di chuyển giữa các màn hình đã được chia mà không có chuột. Rất đơn giản, bạn có thể thêm các cấu hình sau vào file .vimrc và bạn có thể di chuyển qua lại các cửa sổ chỉ bằng 1 tổ hợp phím.

"split navigations
nnoremap <C-J> <C-W>j
nnoremap <C-K> <C-W>k
nnoremap <C-L> <C-W>l
nnoremap <C-H> <C-W>h

Cấu hình trên cho bạn các tổ hợp phím sau:

  • Ctrl-j chuyển đến cửa sổ bên dưới
  • Ctrl-k chuyển lên cửa sổ bên trên
  • Ctrl-l chuyển sang cửa sổ bên phải
  • Ctrl-h chuyển sang cửa sổ bên trái

Nói ngắn gọn lại, bạn có thể sử dụng phím Ctrl và các phím di chuyển của Vim để di chuyển qua lại các cửa sổ.

nnoremap là gì? Có thể hiểu đơn giản rằng, nnoremap làm nhiệm vụ gán các tổ hợp phím thành các tổ hợp phím mới (remap). noremap có nghĩa là bạn remap các phím trong “normal mode” của Vim chứ không phải trong “visual mode”. Ở config trên, nnoremap <C-J> <C-W>j nghĩa là ở “normal mode”, khi tôi ấn <C-J> thì lệnh tương ứng với <C-W>j sẽ được thực hiện. Thông tin chi tiết, bạn có thể tham khảo ở đây.

Buffer

Vim có thể mở nhiều tab để mở các file khác nhau. Nhưng thông thường, người ta thường dùng buffer và phân chia màn hình. Bạn có thể hiểu buffer là các file đang được mở bởi Vim. Vim cho phép chúng ta dễ dàng truy cập các buffer, bằng lệnh :b <buffer name or number> để chuyển đổi giữa các buffer (tính năng autocomplete cũng hoạt động ở đây). Bạn cũng có thể sử dụng lệnh :ls để đưa ra danh sách tất cả các buffer.

Pro Tip: Kết thúc lệnh :ls, Vim thông báo rằng Hit enter to continue. Thay vì ấn ENTER để kết thúc, bạn có thể gõ lệnh :b <buffer number> và chọn một buffer ngay khi danh sách vẫn đang được hiển thị. Điều này giúp bạn bớt đi một thao tác và cũng giúp bạn không cần phải nhớ hết số hiệu của các buffer.

Thu gọn code

Phần lớn các IDE hiện đại đều cung cấp tính năng thu gọn code (có thể gọi là collapse hoặc fold). Sau khi thu gọn, các class và phương thức chỉ được hiển thị dòng đầu tiên thay vì hiển thị tất cả code. Bạn có thể mở riêng 1 phương thức để đọc cho dễ nhìn thay vì tất cả các phương thức đều được show hết ra.

Bạn cũng có thể dùng chức năng này ở Vim với cấu hình sau:

" Enable folding
set foldmethod=indent
set foldlevel=99

Cấu hình trên hoạt động tốt, tuy nhiên bạn phải gõ za để thu gọn (hoặc để mở ra). Bạn có thể dùng phím cách để làm việc này, bằng cách cấu hình nó trong file .vimrc:

" Enable folding with the spacebar
nnoremap <space> za

Bây giờ, bạn có thể dễ dàng thu gọn, mở ra đoạn code bạn muốn.

Lệnh đầu tiên ở config trên, set foldmethod=indent sẽ thu gọn code của bạn dựa vào indent. Thông thường, config này sẽ thu gọn code hơi quá mức cần thiết một chút. Nhưng không sao, có một số extension có thể cải thiện điều đó. Trong các extension đó, tôi recommend bạn sử dụng SimpylFold. Cài đặt nó rất đơn giản với Vundle bằng cách thêm vào file .vimrc

Plugin 'tmhedberg/SimpylFold'

Đừng quên lệnh :PluginInstall để cài đặt/update các extension

Pro Tip: Nếu bạn muốn nhìn docstrings của code đã thu gọn?

let g:SimpylFold_docstring_preview=1

Indent cho Python

Một điều hiển nhiên là việc indent chính xác là rất quan trọng với những ngôn ngữ như Python. Ngoài ra, việc thu gọn code cũng dựa trên indent nên bạn muốn indent của mình thật chính xác. Về việc này, Vim có vẻ hơi thiếu sót một chút vì không hỗ trợ việc indent tự động sau những khai báo hàm, … Có 2 việc nên làm có liên quan tới việc indent này là:

  1. Indent tuân theo tiêu chuẩn của PEP8.
  2. Hỗ trợ việc indent tự động.

PEP8

Để hộ trợ việc indent đúng theo PEP8, bạn thêm những config sau vào file .vimrc:

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

Với config trên, nó hỗ trợ bạn một số công việc như: sử dụng 4 dấu cách mỗi khi bạn gõ Tab, đảm bảo độ dài mỗi dòng dưới 80 ký tự, lưu file với định dạng unix (dùng CR làm dấu xuống dòng) nên bạn sẽ không gặp những vấn đề về hiển thị khi sử dụng Github hay chia sẻ file với người khác.

Và nếu bạn muốn phát triển cả những ngôn ngữ khác nữa, bạn có thể sử dụng thêm lệnh au cho các loại file khác nhau:

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

Bằng cách tương tự, bạn có thể cấu hình khác nhau cho các ngôn ngữ lập trình khác nhau. Vim cũng có một plugin tên là ftypes cho phép bạn lưu cấu hình cho các ngôn ngữ khác nhau ở các file riêng biệt. Bạn có thể sử dụng nó nếu thích.

Indent tự động

Indent tự động có thể sẽ giúp ích bạn trong rất nhiều trường hợp, ví dụ như trường hợp khai báo hàm quá dài và phải xuống dòng. Tuy nhiên, không phải lúc nào nó cũng indent đúng như bạn muốn, nhất là khi chúng ta phải tuân theo tiêu chuẩn PEP8. Để hỗ trợ việc này, chúng ta sẽ sử dụng plugin indentpython.vim

Plugin 'vim-scripts/indentpython.vim'

Đánh dấu các dấu cách thừa

Chúng ta cũng cần tránh các dấu cách không cần thiết (nhất là những dấu cuối dòng). Chúng ta có thể cấu hình Vim để nó đánh dấu những dấu cách không cần thiết cho chúng ta để chúng ta có thể dễ dàng nhận ra và xóa chúng đi:

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

Với config trên, những dấu cách thừa sẽ được đánh dấu là “bad” và thường được hiển thị màu đỏ.

Hỗ trợ UTF8

Trong phần lớn các trường hợp, bạn sẽ phải sử dụng UTF8 khi làm việc với Python, nhất là khi bạn làm việc với Python 3. Bạn có thể cấu hình để Vim biết và hỗ trợ bạn bằng dòng sau:

set encoding=utf-8

Auto-complete

Theo tôi, plugin tốt nhất để hỗ trợ auto-complete cho Python là YouCompleteMe. Bạn có thể cài đặt nó thông qua Vundle:

Bundle 'Valloric/YouCompleteMe'

Về bản chất, YouCompleteMe sử dụng nhiều công cụ khác nhau (bao gồm cả Jedi cho Python), và nó cũng cần một số thư việc C được cài đặt sẵn trên máy của bạn để hoạt động. Nó có một hướng dẫn cài đặt rất đầy đủ và chi tiết. Bạn hãy tham khảo và làm theo hướng dẫn.

Nó hoạt động rất tốt, tuy nhiên bạn nên thêm những config sau để tùy biến nó:

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

Trong 2 dòng trên, dòng thứ nhất để đảm bảo cửa sổ của auto-complete biến mất sau khi bạn đã hoàn thành, và dòng thứ hai định nghĩa một phím tắt để bạn đọc các hướng dẫn.

Phím <leader> của tôi là phím cách, nên <lead>g nghĩa là tôi gõ space-g để xem hướng dẫn của những gì được gợi ý. Đây là một công cụ rất hữu ích nếu bạn bắt đầu làm quen với những code mới, thư viện mới.

Update

YouCompleteMe hiện nay chưa hỗ trợ Python 3 nên nếu muốn tính năng autocomplete với Python 3, jedi-vim là một plugin khá tốt. Cài đặt jedi-vim với config sau:

Plugin 'davidhalter/jedi-vim'

Có thể bạn vẫn cần YouCompleteMe với các ngôn ngữ khác. Bạn có thể map các key để có thể bật, tắt YouCompleteMe một cách nhanh chóng với config sau:

map <leader>y :let g:ycm_auto_trigger=0<CR>
map <leader>y :let g:ycm_auto_trigger=1<CR>

Hỗ trợ môi trường ảo (virtualenv)

Là một người phát triển Python, chắc chắn bạn sẽ thường xuyên làm việc với virtualenv. Tuy nhiên, có một vấn đề với Vim là nó mặc định không biết gì về virtualenv, do đó bạn cần cấu hình để Vim biết và YouCompleteMe sử dụng virtualenv bằng cách thêm những config sau vào file .vimrc:

"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

Config trên sẽ xác định bạn có đang sử dụng virtualenv hay không, sau đó nó sẽ cấu hình lại hệ thống của bạn sao cho YouCompleteMe có thể tìm thấy các package trên virtualenv này.

Kiểm tra/highlight cú pháp

Bạn có thể cấu hình Vim kiểm tra cú pháp cho bạn mỗi khi lưu file với plugin syntastic:

Plugin 'scrooloose/syntastic'

Bạn cũng có thể thêm kiểm tra PEP8 có được tuân thủ hay không với plugin sau:

Plugin 'nvie/vim-flake8'

Cuối cùng, bạn highlight code để trông nó đẹp hơn:

let python_highlight_all=1
syntax on

Color Scheme

Color scheme là tùy biến giao diện của Vim khiến nó trở nên lung linh hơn. Bạn có thể tham khảo 2 color scheme là solarized cho Vim với GUI và Zenburn cho Vim trên giao diện dòng lệnh:

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

Bạn cần thêm một chút config ở đây để sử dụng color scheme cho Vim tùy vào môi trường mà nó đang chạy:

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

Scheme solarized có 2 chế độ màu nền sáng và tối. Bạn có thể chuyển qua lại giữa 2 chế độ này rất đơn giản (bằng cách ấn phím F5) với config sau:

call togglebg#map("<F5>")

Duyệt file và thư mục

Nếu bạn muốn xem cấu trúc các file và thư mục của project, plugin NERDTree chính là thứ bạn cần.

Plugin 'scrooloose/nerdtree'

Nếu bạn sử dụng các tab, bạn có thể cần thêm vim-nerdtree-tabs:

Plugin 'jistr/vim-nerdtree-tabs'

Bạn có thể bỏ qua các file .pyc trong cửa sổ NERDTree bằng cấu hình sau:

let NERDTreeIgnore=['\.pyc$', '\~$'] "ignore files in NERDTree

Nếu bạn muốn tìm kiếm mọi thứ trong Vim, bạn có thể sử dụng ctrlP:

Plugin 'kien/ctrlp.vim'

Plugin cho phép Vim hoạt động như các editor hiện đại, chỉ cần ấn Ctrl-P là bạn có thể tìm kiếm tất cả mọi thứ. Không chỉ tìm kiếm file, nó có thể tìm kiếm tags, bạn có thể tham khảo qua YouTube video.

Đánh số dòng

Bạn có thể bật chế độ đánh số dòng với config:

set nu

Tích hợp git

Nếu bạn muốn sử dụng một số lệnh git cơ bản mà không cần phải thoát ra ngoài Vim, bạn có thể sử dụng plugin vim-fugitive:

Plugin 'tpope/vim-fugitive'
vim fugitive

Bạn có thể nhìn thấy ví dụ sử dụng thực tế của nó ở Vimcasts.

Powerline

Powerline là thanh status hiển thị cho bạn một số thông tin như virtualenv hiện tại, git branch, file đang được thao tác, v.v…

vim powerline

Powerline được viết bằng Python, và nó hỗ trợ rất nhiều môi trường khác nhau như zsh, bash, tmux, IPython.

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

Bạn có thể tham khảo tài liệu của nó để biết các cấu hình và tùy chọn.

Update

Powerline sử dụng Python trong mã nguồn của nó để có thể hiển thị các thông tin. Tôi đã tìm được 1 plugin khác là vim-airline cũng hiển thị các thông tin tương tự powerline nhưng nó hoàn toàn sử dụng vimscript.

Clipboard

Vim thường sử dụng clipboard của chính nó và bỏ qua clipboard của hệ thống. Nhưng nhiều khi bạn muốn sử dụng những dữ liệu được cut, copy, và paste từ những ứng dụng khác không phải là Vim. Nếu Vim của bạn hỗ trợ clipboard (+clipboard) thì bạn có thể truy cập clipboard của hệ thống với config sau:

set clipboard=unnamed

Update: Kiểm tra chính tả tiếng Việt trong Vim

Các phiên bản Vim gần đây đã hỗ trợ kiểm tra chính tả. Tuy nhiên, mặc định Vim chỉ có kiểm tra chính tả tiếng Anh. Nếu muốn kiểm tra chính tả với các ngôn ngữ, chúng ta phải có file mô tả (.spl) thì Vim mới có thể kiểm tra cho chúng ta.

Mặc dù đã có thêm hỗ trợ cho một số ngôn ngữ khác tuy nhiên ngôn ngữ tiếng Việt vẫn chưa có trong danh sách trên. Thật may, Vim có công cụ cho phép chúng ta tự tạo file .spl từ các file từ điển (lệnh mkspell)

File từ điển cũng không khó tìm kiếm, tôi sử dụng file từ điển từ dự án Chromium, đó là file vi_VN.aff và file vi_VN.dic.

Với 2 file trên, chúng ta có thể tạo file .spl bằng cách mở Vim và thực hiện lệnh:

:mkspell vi vi_VN

Vim sẽ dựa vào nội dung 2 file vi_VN.affvi_VN.dic để tạo ra file vi.utf-8.spl. Công việc của bạn là copy file này vào thư mục ~/.vim/spell để sử dụng sau này.

Đã có file .spl, chúng ta chỉ cần config để vim kiểm tra chính tả cho chúng ta:

set spell
set spelllang=en,vi

Một số lệnh thông dụng trong việc kiểm tra chính tả:

  • ]s di chuyển đến từ sai kế tiếp
  • [s di chuyển đến từ sai trước
  • zg thêm từ vào từ điển
  • zug xóa từ vừa thêm khỏi từ điển
  • z= xem từ đề nghị cho từ sai

Vim trong shell

Cuối cùng, khi bạn đã master Vim và các lệnh của nó rồi, thì bạn sẽ thấy mình muốn mình thao tác với mọi thứ giống như thao tác với Vim. Phần lớn các shell đều có VI mode, bạn có thể bật nó lên bằng cách thêm config sau vào file ~/.inputrc:

set editing-mode vi

Bây giờ, bạn không chỉ có thể sử dụng các tổ hợp phím của Vim trong shell mà bạn còn có thể sử dụng chúng ở trong trình thông dịch lệnh Python và các tool khác có sử dụng GNU Readline (phần lớn các shell của cơ sở dữ liệu). Bây giờ, bạn có Vim ở mọi nơi.

Kết luận

Trên đây là những cấu hình để biến Vim thành một IDE (ít nhất là cho Python). Có hàng trăm hàng nghìn extension khác nhau dành cho Vim mà bạn có thể sử dụng, cũng như có rất nhiều lựa chọn khác nhau để thay thế những extension được giới thiệu trong bài viết này. Bạn có thể lựa chọn và cấu hình Vim theo ý của mình. Đây là cấu hình Vim của tôi, bạn có thể tham khảo nó.

Tôi xin lỗi nếu bài viết có bất kỳ typo nào. Nếu bạn nhận thấy điều gì bất thường, xin hãy cho tôi biết.

Nếu có bất điều gì muốn nói, bạn có thể liên hệ với tôi qua các mạng xã hội, tạo discussion hoặc report issue trên Github.