VIM

Introduction

VIM (Vi IMprove) là gì?

Một trình soạn thảo văn bản mã nguồn mở.

Sở hữu nhiều chế độ thao tác trên code.

Bản thân là một ngôn ngữ lập trình: người dùng tương tác với VIM bằng các tổ hợp phím.

Tại sao nên dùng VIM?

Ưu điểm

  • Gọn, nhẹ: Giao diện của VIM không dựa trên tương tác với các menu hay icon mà dựa trên các lệnh được đưa ra từ text user interface. Do đó VIM ngốn ít RAM hơn so với các code editors khác.
  • Tốc độ làm việc nhanh: VIM chủ yếu tương tác với người dùng qua câu lệnh, nên chỉ cần bạn gõ phím ổn là bạn sẽ thấy tốc độ làm việc nhanh lên trông thấy.
  • Khả năng tùy chỉnh cao: Một phần sức mạnh của VIM là nó có thể được tùy biến rộng rãi. Giao diện cơ bản có thể được thay đổi bởi nhiều tùy chọn có sẵn. Hay nói một cách khác là bạn có thể biến VIM theo mong muốn của mình.
  • Nhiều plugins: VIM có một lượng plugin đồ sộ cho phép người dùng nâng cao hiệu suất, cải thiện giao diện, ...
  • Cộng đồng lớn: Vì là một editor thú vị nên cộng động người dùng rất lớn (> 25% lập trình viên đang sử dụng nó).

Nhược điểm

  • Nhiều phím tắt: Vì mục đích của VIM là cải thiện tốc độ làm việc thông qua việc gõ phím, nên lượng phím tắt là vô số kể. Từ đó học VIM rất dễ nản và bỏ cuộc.
  • Giao diện không bắt mắt: bởi vì VIM hoạt động trên text user interface, do đó giao diện có thể gây nhàm chán so với VSCode hoặc các text editor khác.

Tải và cài đặt VIM

Windows

macOS

  • Để cài VIM trên terminal (không có giao diện, tương tác thông qua terminal), mở macOS terminal và chạy lệnh: brew install vim (tham khảo tại https://formulae.brew.sh/formula/vim).
  • Để cài VIM với GUI, ta tải file cài đặt tại đây.
    • GUI (Graphic User Interface): được hiểu là giao diện đồ họa người dùng. GUI VIM sẽ hiển thị VIM bằng một cửa sổ khác, không dùng terminal như trên.

Linux

Trong linux terminal, chạy các lệnh sau trong terminal:

  • sudo apt-get update
  • sudo apt-get install vim

Cài VIM bằng git: Ta chạy các lệnh sau ở Terminal:

  • cd src
  • make distclean # if you build VIM before, clear the previous version
  • make
  • sudo make install

Khởi động VIM

Trong terminal, chạy lệnh: vim filename.txt

  • Trong đó vim là từ khóa để chạy vim và filename.txt là tên file bạn muốn mở bằng VIM.

General Usage

Modal editings

Các modal thường dùng

Normal: dùng để di chuyển trong file và thực hiện chỉnh sửa.

Insert: dùng để thêm ký tự.

Visual: dùng để bôi đen đoạn ký tự.

Command-line: dùng để thực hiện lệnh.

Cơ chế hoạt động

Chế độ mặc định của VIM là Normal mode. Từ đây, ta có thể chuyển sang các mode khác như sau:

  • Nếu muốn chuyển sang Insert mode, ta bấm phím i (insert), a (append), o (open).
  • Nếu muốn chuyển sang Visual mode, ta bấm phím v (visual).
  • Nếu muốn chuyển sang Command-line mode, ta gõ : (dấu hai chấm).
  • Để quay trở lại Normal mode, ta nhấn Esc.

Hotkeys

Lưu ý, VIM có phân biệt giữa ký tự in hoa và in thường.

Open/close file

vim filenamevim path :e path Mở tệp  bằng VIM từ terminal / command prompt
:e filename :e path Mở tệp
:w :w filename :w path Lưu file
:wq Lưu file và đóng VIM
:q! Đóng VIM nhưng không lưu file

Các cụm phím về navigation

Line navigation

4 phím di chuyển cơ bản lần lượt là:

h Di chuyển sang trái
j Di chuyển xuống dưới
k Di chuyển lên trên
l Di chuyển sang phải

Ngoài ra, còn 4 cách giúp di chuyển nhanh là:

0 Về vị trí bắt đầu của dòng hiện tại
^ Về ký tự đầu tiên (không tính khoảng trống) của dòng
$ Đến vị trí cuối cùng của dòng hiện tại
g_ Đến ký tự cuối cùng (không tính khoảng trống) của dòng

Screen navigation

H Đến dòng đầu tiên trên màn hình hiện tại
M Đến dòng ở giữa trên màn hình hiện tại
L Đến dòng ở cuối trên màn hình hiện tại
Ctrl + f Di chuyển xuống một màn hình
Ctrl + b Di chuyển lên một màn hình
Ctrl + d Di chuyển xuống một nửa màn hình
Ctrl + u Di chuyển lên một nửa màn hình

Special navigation

N% Di chuyển vào dòng có N% tương ứng(Ví dụ: có 100 dòng, 70% sẽ xuống dòng thứ 70)
NG Di chuyển vào dòng tương ứng(Ví dụ: 41G sẽ xuống dòng thứ 41)
g Di chuyển lên đầu file
G Di chuyển xuống cuối file
`” Vào vị trí cuối cùng trong Normal mode ở lần đóng file trước
`^ Vào vị trí cuối cùng trong Insert mode ở lần đóng file trước

Word navigation

Quy ước màu cho ví dụ: trước - sau

e Đến vị trí cuối cùng của từ (Ví dụ: example#abc(conmeo/ngoicanh(‘connai’)/ef )
E Đến vị trí cuối cùng của từ, bao gồm metacharacters (Ví dụ: example#abc(conmeo/ngoicanh(‘connai’)/ef)
b Đến vị trí đầu tiên của từ (Ví dụ: example#abc(conmeo/ngoicanh(‘connai’)/ef)
B Đến vị trí đầu tiên của từ, bao gồm metacharacters (Ví dụ: example#abc(conmeo/ngoicanh(‘connai’)/ef)
w Đến từ tiếp theo (Ví dụ: example#abc(connai)  morewords)
W Đến từ tiếp theo, bao gồm metacharacters (Ví dụ: example#abc(connai)  morewords)

Paragraph navigation

{ Di chuyển về đầu đoạn vănNhấn thêm lần nữa để về đầu đoạn văn trước đó
} Di chuyển về cuối đoạn vănNhấn thêm lần nữa để về cuối đoạn văn sau đó

Other navigation

* Chuyển đến lần xuất hiện tiếp theo của từ hiện tại dưới con trỏ
# Chuyển đến lần xuất hiện trước của từ hiện tại dưới con trỏ
% Di chuyển tới dấu ngoặc (vuông, tròn, nhọn) đối xứng

Các cụm phím về mode insert, command, visual

Từ Normal mode, ta dùng các phím sau để bật Insert mode:

i Chèn văn bản vào trước con trỏ
I Chèn văn bản vào ký tự đầu tiên không phải ký tự khoảng trắng (space, tab) của dòng
a Chèn văn bảo vào phía sau con trỏ
A Chèn văn bản vào cuối dòng
o Bắt đầu một dòng mới bên dưới con trỏ hiện tại và chèn văn bản vào đó
O Bắt đầu một dòng mới bên trên con trỏ hiện tại và chèn văn bản vào đó
gi Chèn văn bản vào vị trí cuối cùng của Insert mode trước đó

Các cụm phím về edit

Find

/search-parterm Tìm kiếm cụm từ sau con trỏVd: /Gnu thì sẽ ra aGnu hoặc Gnua
?search-parterm Tìm kiếm cụm từ trước con trỏ VD: ?Gnu thì nó sẽ ra aGnu hoặc Gnua
n Chuyển sang kết quả tiếp theo
N Chuyển về kết quả trước đó
/\<whole-word\> Tìm kiếm chính xác 1 từ trước con trỏ VD: /\<Gnu\> sẽ ra GNU
?\<whole-word\> Tìm kiếm chính xác 1 từ trước con trỏ VD: ?\<Gnu\> sẽ ra GNU
:set ignorecase :set ic Tắt phân biệt chữ hoa chữ thường trong tìm kiếm
:set noignorecase :set noic Bật phân biệt chữ hoa chữ thường trong tìm kiếm

Copy/Cut/Paste

y Cắt phần đã chọn (trong Visual mode)
d Sao chép phần đã chọn (trong Visual mode)
yy Sao chép một dòng
[n]yy Sao chép n dòng
yw Sao chép từ vị trí con trỏ đến đầu từ kế tiếp
yiw Sao chép từ bên dưới con trỏ
yaw Sao chép từ bên dưới con trỏ và khoảng trống trước/sau từ đó
y$ ao chép hết dòng
p Dán từ clipboard vào vị trí sau con trỏ
P Dán vào vị trí trước con trỏ
dd Xóa (cắt) một dòng
[n]dd Xóa (cắt) n dòng
dw óa (cắt) các ký tự của từ từ vị trí con trỏ đến đầu từ tiếp theo
diw Xóa (cắt) từ bên dưới con trỏ
daw Xóa (cắt) từ dưới con trỏ và khoảng trắng xung quanh
D Xóa (cắt) đến cuối dòng
d$ Xóa (cắt) đến cuối dòng
x Xóa (cắt) một ký tự

Undo/redo u (command, visual)

u Undo
U Undo dòng vừa được chỉnh sửa
Ctrl + r Redo
. Lặp lại lệnh vừa rồi

Working with tabs

:tabnew:tabnew {page.words.file} Mở một file trong tab mới
Ctrl + wT Tách cửa sổ hiện tại thành tab riêng
gt :tabn[ext] Chuyển sang tab kế tiếp
gT :tabp[revious] Chuyển đến tab trước đó
#gt Chuyển đến tab số #
:tabm[ove] # Di chuyển tab hiện tại đến vị trí thứ # (bắt đầu từ 0)
:tabc[lose] óng tab hiện tại và tất cả các cửa sổ của nó<
:tabo[nly] Đóng tất cả các tab ngoại trừ tab hiện tại
:tabdo command Chạy lệnh command trên tất cả các tab VD: :tabdo q! (Là thoát ở tất cả các tab)

Multiple files

:e[dit] file Chỉnh sửa tệp trong buffer mới
:bn[ext] Chuyển đến buffer kế tiếp
:bp[revious] Chuyển đến buffer trước đó
:bp[elete] Xóa buffer (đóng tệp)
:b[uffer]# Chuyển đến buffer số  #
:b[uffer] file Chuyển đến buffer của tệp
:ls :buffers Liệt kê tất cả các buffer đang mở
:sp[lit] file
:vs[plit] file Mở một tệp trong buffer mới và chia cửa sổ theo chiều dọc
:vert[ical] ba[ll] Chỉnh sửa tất cả buffer dưới dạng cửa sổ dọc
:tab ba[ll] Chỉnh sửa tất cả buffer dưới dạng tab
Ctrl + ws Chia cửa sổ
Ctrl + wv Chia cửa sổ theo chiều dọc
Ctrl + ww Chuyển cửa sổ
Ctrl + wq Thoát khỏi cửa sổ
Ctrl + wx Đổi cửa sổ hiện tại với cửa sổ tiếp theo
Ctrl + w= Làm tất cả các cửa sổ có chiều cao và chiều rộng bằng nhau
Ctrl + wh Di chuyển con trỏ sang cửa sổ bên trái (khi chia dọc)
Ctrl + wl Di chuyển con trỏ sang cửa sổ bên phải (khi chia dọc)
Ctrl + wj Di chuyển con trỏ đến cửa sổ bên dưới (khi chia ngang)
Ctrl + wk Di chuyển con trỏ đến cửa sổ bên trên (khi chia ngang)
Ctrl + wH Làm cho cửa sổ hiện tại có chiều cao tối đa ở ngoài cùng bên trái (cửa sổ dọc ngoài cùng bên trái)
Ctrl + wL Làm cho cửa sổ hiện tại có chiều cao tối đa ở ngoài cùng bên phải (cửa sổ dọc ngoài cùng bên phải)
Ctrl + wJ Làm cho cửa sổ hiện tại có chiều rộng tối đa ở dưới cùng (cửa sổ nằm ngang dưới cùng)
Ctrl + wK Làm cho cửa sổ hiện tại có chiều rộng tối đa ở trên cùng (cửa sổ nằm ngang trên cùng)

VIM cheatsheet

Config/Custom VIM (Advanced) (P1)

Tại sao lại cần tùy biến (config) lại VIM

Giao diện mặc định của VIM sẽ chỉ giúp ta thao tác với một file, do vậy khi cần thao tác với một project ta sẽ gặp rất nhiều khó khăn. Ví dụ, khi cần edit một file html thì ta sẽ sử dụng cú pháp bên dưới và khi cần mở một file khác ta cần thoát ra và sử dụng cú pháp tương tự để làm việc trên file đó.

Bên cạnh đó, so với các IDE, text editor khác thì giao diện mặc định của VIM có phần thô sơ và thiếu các tính năng hỗ trợ để các lập trình viên code nhanh hơn. Tuy nhiên các nhà phát triển và người dùng VIM đã cho ra đời những plugin để hỗ trợ điều đó. Bên dưới là hình minh họa giao diện VIM trước và sau khi được config.

Có thể thấy sự thay đổi rõ rệt sau khi VIM đã được tùy biến như:

  • Giao diện đẹp, phong phú hơn.
  • File explorer có thể được mở bên cạnh.
  • Highlight code, highlight tag.
  • Các thông tin về git...

Do vậy nếu bạn gặp khó khăn với giao diện mặc định của VIM thì điều này hoàn toàn có thể giải quyết được. Ở những bước dưới mình sẽ nói về cách custom giao diện của VIM, cụ thể hơn là NeoVIM (bản cải tiến của VIM).

Cấu hình VIM

Để cấu hình tất cả plugin của VIM ta cần thực hiện sửa đổi ở file init.vim (đây là nơi chứa các script được chạy trước khi VIM khởi động - VIMscript).

Địa chỉ (đường dẫn) file init.vim (hoặc .vimrc) ở các hệ điều hành:

  • Window: C:\User\{user_name}\AppData\Local\nvim\init.vim
  • Linux:
    • Arch: /home/{user_name}/.vimrc
    • Ubuntu: /home/{user_name}/.config/nvim/init.vim

Lưu ý: nếu không tìm thấy thì phải tự tạo ra folder/file tương ứng.

Cài đặt môi trường cho Plugin

Để có được môi trường cài đặt cho các Plugin thì chúng ta cần cài đặt trước một số chương trình tiên quyết sau:

Git: hỗ trợ việc tải Plugin nhanh và thuận tiện hơn.

NodeJS: môi trường runtime cho Javascript (vì có một số Plugin được viết bằng Javascript).

Python: một số Plugin sẽ được viết bằng ngôn ngữ Python.

Chúng ta có thể dễ dàng cài đặt các nội dung trên bằng cách tìm kiếm ở ngay chính trang chủ của các phần mềm đó.

Để kiểm tra việc cài đặt có thành công chưa, ta có thể sử dụng các lệnh trên terminal bên dưới để hiển thị các phiên bản mà ta đã cài đặt.

Lưu ý: các phiên bản mà bạn cài đặt có thể khác với hình minh họa bên trên do thời điểm cài đặt là khác nhau.

Bên cạnh đó, để liên kết từ VIM sang các môi trường hoạt động khác như NodeJS, Python, Lua,... ta cần một cơ chế kết nối, và nó gọi là Provider. Các Provider sẽ được cài đặt thông qua các package manager (npm: nodejs, pip: python).

Hai dòng lệnh trên minh họa cho việc tải các package manager và ở  dưới hình sẽ mô tả cho việc cài Provider cho NodeJS và Python.

  • NodeJS
    • npm: node package manager.
    • g (global): cài trên toàn hệ thống.
  • Python
    • pip: python installer package.

Chúng ta có thể kiểm tra các Provider đã được cài thành công hay chưa bằng cách gõ :checkhealth ở chế độ Command (Python 3 provider và Node.js provider đã được cài đặt như hình minh họa bên dưới).

Cài đặt Plugin Manager dành cho VIM

Các Plugin của VIM có thể được cài đặt thủ công, tải xuống và di chuyển vào thư mục cài đặt của VIM. Tuy nhiên cách làm này sẽ mất nhiều thời gian và công sức. Vì vậy, các nhà phát triển đã tạo ra các Plugin Manager dành cho VIM. Hiện nay có rất nhiều cơ chế quản lý các Plugin như:

  • vim-plug
  • Vundle
  • Pathogen
  • Dein.vim
  • volt

Ở đây, mình sẽ đề xuất cho mọi người sử dụng VIM Plug (vì Plugin Manager này nhận được lượt rating cao và số lượng người dùng đông đảo nhất). Tùy thuộc vào phiên bản và hệ điều hành các bạn đang sử dụng, github của VIM Plug đã có những hướng dẫn cụ thể cho việc cài đặt các phiên bản và hệ điều hành khác nhau.

Ở file init.vim chúng ta sẽ mở đầu bằng việc trỏ đến thư mục các plugin tải xuống và ở đây sẽ là folder plugged nằm ngay trong nvim. Kết thúc của phần VIM-Plug sẽ là câu lệnh call plug#end().

Mọi người có thể tham khảo script của file init.vim mình đã config (cấu hình) sẵn để bắt đầu thử install các Plugin thông qua Plugin Manager.

Sau khi có được các đoạn script, chúng ta sẽ dùng lệnh :PlugInstall ở mode Command, VIM sẽ tự động cài đặt các Plugin được thêm vào script. Một cửa sổ sẽ được popup bên trái để chúng ta xem được quá trình cài đặt của các plugin.

Save và quit file init.vim. Mở lại bất kì một file nào với VIM bạn sẽ thấy giao diện đã được thay đổi hoàn toàn. Ở phần tiếp theo chúng ta sẽ đi vào tìm hiểu sâu hơn các Plugin đang được sử dụng là gì và tại sao các Plugin lại được tùy biến trong file init.vim như vậy?

Config/Custom VIM (Advanced) (P2)

Theme

Hiện nay nhà phát triển và cộng đồng của VIM đã đóng góp một số lượng cực kì lớn các theme mà người dùng có thể dễ dàng chọn lựa theo sở thích của mình. Mọi người có thể tham khảo các theme phổ biến ở vimcolorschemes.

Sau khi đã lựa chọn ra theme mình ưu thích, mọi người bấm vào mục View <theme> on Github, trang web sẽ dẫn chúng ta đến source code mà tác giả đã đăng lên:

Ở github của những theme này, ta sẽ thấy được rất nhiều thông tin về màu sắc ở các chế độ khác nhau, cách tùy biến,... Nhưng chúng ta chỉ cần quan tâm đến địa chỉ github của source code này (như ở hình minh họa bên dưới địa chỉ của source code này là morhetz/gruvbox).

Tiếp theo, chúng ta quay trở lại với file init.vim, gõ dòng script

Plug <địa chỉ github>. Bên cạnh đó, chúng ta cũng cần config thêm dòng lệnh syntax on, set background = light/dark, color <theme chúng ta chọn> tương tự như hình minh họa phía bên dưới:

Tiếp theo, chúng ta cần sử dụng lệnh :PlugInstall ở chế độ Command để VIM tiến hành cài đặt theme đó. Sau khi cài đặt xong,  chúng ta cần lưu và thoát file init.vim để bật lại VIM với một file bất kỳ, ta sẽ thấy theme mà chúng ta mong muốn đã được cài đặt thành công.

Managing projects (File explorer)

Để làm việc được với nhiều file cùng một lúc ta rất cần đến tính cách duyệt file mà phổ biến nhất hiện nay chính là NerdTree.

Tương tự như cách cài đặt theme, chúng ta cần thêm dòng script  Plug 'preservim/nerdtree' vào file init.vim và :PlugInstall để tải về.

Để bật/tắt (toggle) NerdTree ta sẽ có 2 cách:

  • Sử dụng câu lệnh :NERDTreeToggle ở chế độ Command.
  • Gán câu lệnh với các phím tắt (mapping). Ở ví minh họa phía bên dưới, chúng ta đã gán được câu lệnh với phím tắt F5.
    • <silent>: để không phải hiển thị dòng lệnh :NERDTreeToggle khi nhấn phím tắt (hotkey) F5.

Find file/text

Khi cần thêm chức năng tìm kiếm file/text ở trong VIM mọi người có thể sử dụng Fuzzy Finder.

Tương tự, chúng ta cần thêm đoạn script như hình minh họa bên dưới vào file init.vim và :PlugInstall để tải về.

Một số commands để sử dụng plugin này đã được list rất cụ thể ở Github của tác giả, mọi người có thể sử dụng làm nguồn tra cứu.

Status bar

Status bar là thanh hiển thị trên cùng và  dưới cùng, của một cửa sổ VIM bao gồm các thông tim như tên file, mã encoding, số dòng,... Ở đây, mình khuyến khích mọi người sử dụng VIM Airline.

Tương tự, chúng ta cần thêm đoạn script như hình minh họa bên dưới vào file init.vim và :PlugInstall để tải về.

Sau khi tải thành công, ta sẽ có một giao diện VIM gồm 2 thanh status bar bên trên và bên dưới như hình minh họa.

Terminal

Mặc định VIM đã có một terminal riêng, chúng ta có thể mở terminal bằng cách sử dụng lệnh :terminal, khi này một cửa sổ mới sẽ xuất hiện.

Điều này có thể gây ra một chút bất lợi khi phải chuyển đi chuyển lại giữa tab terminal và file đang làm việc. Cách giải quyết của chúng ta là sử dụng Floating Terminal.

Tương tự, chúng ta cần thêm đoạn script như hình minh họa bên dưới vào file init.vim và :PlugInstall để tải về.

Sau khi tải thành công, ở giao diện VIM khi ta sử dụng câu lệnh :FloatermToggle một cửa sổ terminal nổi sẽ hiện ra và khi cần đóng ta có thể sử dụng câu lệnh trên một lần nữa.

Ta hoàn toàn có thể gán một phím tắt bất kì cho câu lệnh trên để tối ưu được thời gian bật/tắt terminal.

Syntax highlight

Highlight syntax sẽ giúp ta dễ dàng phân biệt được các giá trị, hàm, biến có trong chương trình. Để cài đặt, chúng ta cần thêm đoạn script như hình minh họa bên dưới vào file init.vim và :PlugInstall để tải về.

Mỗi ngôn ngữ lập trình sẽ có các plugin highlight syntax khác nhau, mọi người có thể tìm kiếm và cài đặt các plugin phù hợp với ngôn ngữ mình hay sử dụng.

Git

Để quản lý lịch sử các file, source code trong dự án ta cần sử dụng đến Git. Các nhà phát triển đã làm ra các plugin để chúng ta có thể dễ dàng kiểm tra được các nhánh, tình trạng commit của các file trong VIM. Ở đây, mình khuyến khích các bạn sử dụng plugin VIM Fugitive.

Tương tự các plugin trước, chúng ta cần thêm đoạn script như hình minh họa bên dưới vào file init.vim và :PlugInstall để tải về.

Các câu lệnh :Git add, :Git Commit, :Git diff,... đã được mô tả khá chi tiết ở Github của tác giả, mọi người nên vào trực tiếp để đọc và hiểu rõ hơn cách thức hoạt động

Exercise

  • Hoàn thành OpenVim để thành thạo các cụm phím cơ bản, kết hợp cùng với việc tham khảo mục General Usage
  • Copy file basic vimrc và lưu nó vào init.vim (.vimrc) của chính bạn. Đọc qua các comment và quan sát cách Vim hoạt động khác biệt với một cấu hình mới
  • Customize file config Vim của bạn và tải về những plugins mà bạn thích, tham khảo mục Advanced Part 2
  • Đẩy file config cùng những hình ảnh về giao diện Vim của bạn lên github để cùng chia sẻ với bạn bè cũng như lecturers nha