Sau phần một của chuỗi bài viết về Vim, hôm nay tôi sẽ nói về các phím tắt tôi dùng, một vài phím tắt tôi học lỏm được trên mạng, các dotfiles của những người đi trước. Vì đây là bài viết thứ hai trong chuỗi nên tôi sẽ không giới thiệu dài dòng nữa, bắt đầu nhé!
Cơ bản
Ghi chú
Trong bài viết này sẽ có hai dạng biểu diễn phím tắt bạn nên để ý kỹ:
Giữ cùng lúc nhiều phím: Ctrl+c, Alt+P.
Bấm lần lượt, bấm phím này xong buông ra bấm phím tiếp theo: dd, Leaderpv.
Đồng thời, phím c và C là khác nhau nhé!
Tải lại
Sau mỗi lần thay đổi file vimrc
, không cần phải dùng lệnh :source $MYVIMRC
nữa, chỉ cần bấm Leaderr.
noremap <Leader>r :so $MYVIMRC<CR>
Vimrc
Khi ở bất kỳ đâu trong Vim, chỉ cần bấm Leader, để mở vimrc
trong một tab mới.
noremap <Leader>, :tabnew $MYVIMRC<CR>
Đừng thoát!
Mặc định Vim sẽ thoát ngay lập tức khi bấm Q, dòng này chỉ để tắt chức năng này để không phải thoát nhầm mà không lưu lại gì.
noremap Q <nop>
Chỉnh sửa văn bản
Thay thế toàn tệp
Trong Normal Mode, bấm S để gõ nhanh cú pháp tìm và thay thế trong toàn tệp.
nnoremap S :%s//g<Left><Left>
Dịch chuyển
Khi trong Normal Mode, chọn cả dòng bằng cách bấm V, sau đó dùng phím J và K để dời một hoặc nhiều dòng đang chọn lên xuống.
vnoremap <silent> J :m'>+<CR>gv=gv
vnoremap <silent> K :m-2<CR>gv=gv
Thêm dòng trống
Trong Normal Mode:
- Leadero thêm một dòng trống phía dưới dòng hiện tại.
- LeaderO thêm một dòng trống phía trên dòng hiện tại.
noremap <Leader>o m`o<Esc>``
noremap <Leader>O :call append(line('.')-1, '')<CR>
Dùng clipboard hệ thống
Phần này hơi phức tạp, bạn có thể bỏ qua phần giải thích, chỉ cần biết là Leadery sẽ copy vào clipboard hệ thống, Leaderp sẽ paste từ clipboard hệ thống.
noremap <Leader>y "+y
noremap <Leader>Y "+yy
noremap <Leader>p "+p
Mặc định, khi dùng yy, dd…, Vim sẽ không copy vào clipboard của hệ thống. Nghĩa là khi bạn sao chép một đoạn văn bản trong Vim bằng yy, vào Firefox, Ctrl+v sẽ không dán đoạn bạn đã sao chép. Điều này là bởi mặc định Vim sẽ dùng registers của riêng nó, không dùng chung với clipboard của X server.
Ví dụ một vài Vim Registers
/
nội dung bạn vừa tìm kiếm
"
nội dung bạn vừa x, y…
+
clipboard của hệ thốngTìm hiểu tất cả tại đây.
Registers có thể được xem như những cái hộp, nơi Vim sẽ chứa nội dung bạn vừa sao chép hoặc cắt để đặt vào nơi khác. Để gọi tên một register, ta dùng phím "+
.
Vì thế, để tương tác với clipboard của hệ thống ta phải dùng các tổ hợp phím như sau:
Sao chép cả dòng: "+yy
Cắt từ con trỏ đến cuối dòng: "+D
Dán: "+p
Bạn có thể coi đây như một trở ngại rườm rà, nhưng điều này cho phép ta thao tác với nội dung vừa được sao chép, làm đủ trò với chúng. Nói chung là một tí bất tiện thôi nhưng mở ra bao nhiêu khả năng mới mà các trình chỉnh sửa văn bản khác không thể.
Lưu ý
Lưu ý rằng bạn phải cài bản Vim được build với tùy chọn
+clipboard
thì mới dùng được tính năng này nhé. Để kiểm tra Vim có hỗ trợ tương tác với clipboard hệ thống không hãy gõ dòng lệnh này vào Vim:
:echo has('clipboard')
Nếu kết quả trả lại là 0
thì Vim của bạn hiện không hỗ trợ thao tác này. Hãy thử gỡ Vim từ terminal và cài lại bản có hỗ trợ bằng lệnh sau:
# Debian
sudo apt purge vim
sudo apt install vim-gtk
# Arch Linux
sudo pacman -Rns vim
sudo pacman -Sy gvim
# Void Linux
sudo xbps-remove -R vim
sudo xbps-install -S gvim
Xóa thật sự
Mặc định, các thao tác yank
và cut
trong Vim sẽ đưa phần văn bản được chọn vào register "
. Điều này dẫn đến việc nếu bạn dd hai lần, dòng đầu tiên bạn cắt sẽ bị dòng sau ghi đè, và để xóa dòng hai mà không mất dòng một trong register "
, bạn phải xóa nó vào một register khoảng không. Register này được gọi tên với tổ hợp "_.
Vì thế khi lỡ yank
hoặc cut
một dòng, muốn xóa dòng khác mà không mất dòng ban đầu tôi sẽ dùng các phím tắt Leaderdd để xóa cả dòng,Leaderd$ để xóa từ con trỏ đến cuối dòng,Leaderdw để xóa một từ.
noremap <Leader>dd "_dd
noremap <Leader>d$ "_d$
noremap <Leader>dw "_dw
Di chuyển
Mode toggle
Một phím tắt duy nhất để thay đổi qua lại giữa Insert Mode và Normal Mode. Ctrl+c là phím tắt tôi hay dùng nhất khi thao tác với các phần mềm trong terminal. Thay vì dùng i và Esc để thay đổi qua lại, giờ ta chỉ cần một phím tắt rất tiện cho tay trái.
nnoremap <C-c> i
inoremap <C-c> <Esc>
Từng dòng một
Mặc định của Vim khi dùng j và k để di chuyển lên xuống xong Normal Mode sẽ di chuyển theo đoạn trong văn bản, không phải dòng hiển thị trong terminal. Ví dụ có một đoạn văn bản như sau, khi ta bấm phím j, mặc định con trỏ sẽ nhảy xuống dòng số 2.
Điều này là hoàn toàn hợp lý vì Vim sẽ dời con trỏ xuống một dòng trong file, vì Vim đang gói (wrap) dòng của chúng ta nên hiển thị trong terminal có vẻ đã xuống dòng nhưng thực tế trong văn bản không hề xuống dòng.
Việc di chuyển như vậy có phần khó khăn khi muốn chỉnh sửa đoạn giữa hoặc cuối của một dòng dài. May mắn thay, phím tắt gj sẽ đưa con trỏ xuống một dòng thay vì một đoạn. Và hầu hết lúc nào tôi cũng di chuyển như vậy nên tôi sẽ gán j và k thành gj và gk trong cả Normal Mode và Visual Mode.
Ngoài ra thao tác di chuyển theo đoạn như trên cũng có ích trong vài trường hợp, nên việc thay thế j, kthành gj,gk làm mất đi chức năng di chuyển đoạn mặc định của j và k. Do đó tôi sẽ thay thế cả hai chiều, nghĩa là gj, gk cũng sẽ thành j, k tương ứng.
nnoremap k gk
nnoremap gk k
nnoremap j gj
nnoremap gj j
vnoremap k gk
vnoremap gk k
vnoremap j gj
vnoremap gj j
Cửa sổ
Khi đang chỉnh sửa nhiều văn bản trong các cửa sổ (thường gọi là buffers hoặc windows), bấm Ctrl và tương ứng các phím hjkl để focus vào từng cửa sổ trên màn hình.
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
Luôn ở giữa
Khi tìm kiếm bằng /, dùng n và N để di chuyển đến kết quả tìm kiếm tiếp theo, dòng chứa kết quả sẽ luôn ở chính giữa màn hình.
nnoremap n nzzzv
nnoremap N Nzzzv
Giữ con trỏ luôn ở giữa màn hình khi di chuyển nửa màn hình bằng tổ hợp phím Ctrl+u và Ctrl+d.
nnoremap <C-u> <C-u>zz
nnoremap <C-d> <C-d>zz
Chẻ ngang dọc
Khi đang có hai cửa sổ trên màn hình, bấm Leaderwv để sang chế độ bổ dọc (vertical split) và Leaderwh sẽ chuyển từ bổ dọc thành bổ ngang (horizontal split).
noremap <Leader>wv :wincmd H<CR>
noremap <Leader>wh :wincmd K<CR>
Tabs
Ngoài chế độ cửa sổ, Vim còn có chế độ tab. Ví dụ đang chỉnh sửa file a
muốn mở tab mới để chỉnh sửa file b
bạn có thể dùng lệnh :tabnew b
Tab kế bên
Khi có nhiều tabs đang mở, phím tắt dưới đây sẽ cho phép bạn di chuyển qua lại giữa các tab theo thứ tự từ trái sang phải bằng phím LeaderTab.
noremap <Leader><Tab> gt
Nhảy đến tab
Vì muốn Leader có vai trò tương tự phím Mod của dwm nên tôi gán Leader1-9 thành di chuyển đến tab theo số thứ tự. Chức năng này mặc định Vim không có (hoặc tôi không biết là Vim có) nên tôi phải dùng một hàm loop
để gán phím.
for i in range(1, 9)
execute "nnoremap <Leader>" . i . " :" . i . "tabnext<CR>"
endfor
Tab cuối
Vì đã quen di chuyển các tabs bằng duy nhất tay trái nên việc bấm Leader9 là hơi bất tiện, hoặc là có hơn 9 tabs đang bật, nên tôi sẽ gán Leader` thành di chuyển đến tab cuối cùng (tận cùng phải).
noremap <Leader>` :tablast<CR>
Kết lại
Như thường lệ, file vimrc
của tôi sẽ được công khai tại GitLab. Phần tiếp theo tôi sẽ nói về cách quản lý các plugins.