Vim: Một trình soạn thảo văn bản mạnh mẽ và tối ưu

CEO Long Timo
Ảnh minh họa Vim là một trình soạn thảo văn bản được biết đến với tốc độ và tính năng mạnh mẽ. Nó có thể chạy trực tiếp trên terminal, nhưng vẫn cung cấp giao...

image.png Ảnh minh họa

Vim là một trình soạn thảo văn bản được biết đến với tốc độ và tính năng mạnh mẽ. Nó có thể chạy trực tiếp trên terminal, nhưng vẫn cung cấp giao diện đồ họa trực quan cho người dùng. Vim được tạo ra để tối ưu hóa mọi thao tác cần thiết trong quá trình soạn thảo văn bản của bạn chỉ bằng sử dụng bàn phím. Điều này là điểm mạnh nhất mà mình rất thích ở Vim 🤯🤯

Vim là một phiên bản nâng cấp từ trình soạn thảo Vi được trình làng từ năm 1976, và sau đó chúng ta có phiên bản Vi Improved hay còn gọi là Vim như hiện tại.

Bạn có thể tự đặt câu hỏi, tại sao chúng ta lại cần xem xét việc sử dụng Vim trong thời đại hiện tại? Với cá nhân mình, lý do chủ yếu là do mình quá lười 😅 Khi mà đã bắt đầu quá trình viết code, mình muốn bàn tay mình dính luôn vào bàn phím! Thực sự việc nhấc tay lên để sử dụng con chuột kéo kéo thả thả có chút làm đứt mạch code của mình. Và Vim nổi lên như một giải pháp.

Với mình, học cách code sử dụng Vim cũng giống như học cách chơi nhạc cụ. Ban đầu có thể gặp khó khăn, nhưng dần dần, những khó khăn ấy sẽ trở thành sự chính xác và hiệu quả trong tương lai.

Trong bài viết này, mình sẽ giới thiệu cho các bạn những thao tác cơ bản mà làm nên tên tuổi của Vim!

Để làm rõ hơn, mình là một PHP + JS developer, chủ yếu làm việc trên Ubuntu. Máy tính cá nhân của mình sử dụng WSL Ubuntu 20.04, và máy công ty sử dụng Ubuntu 22.04.

Vim thường được cài đặt sẵn khi bạn cài đặt các hệ điều hành Linux, BSD hoặc MacOS. Trong loạt bài viết này, mình sẽ cài đặt lại phiên bản WSL Ubuntu-22.04 từ đầu.

Thoát khỏi Vim

Vim có thể được cài đặt và sử dụng trên hầu hết các nền tảng. Đôi khi, bạn có thể rơi vào trạng thái không thể thoát khỏi Vim 😂 Ví dụ như khi gặp vấn đề không thể merge non fast-forward với Git.

Đầu tiên, bạn nên học cách thoát khỏi Vim. Nếu bạn chưa thay đổi bất cứ thứ gì, bạn có thể thoát an toàn bằng cách gõ ":q". ":" để vào trạng thái Command và "q" là viết tắt của quit. Nếu bạn muốn thoát ra mà lại không lưu thay đổi, bạn có thể gõ ":q!" để thoát Vim hoặc ":wq" để lưu lại thay đổi và thoát.

Mở Vim

Bạn có thể mở Vim bằng cách gõ "vim" trực tiếp trên terminal. Khi đó, bạn có thể thêm đường dẫn tới file mà bạn muốn mở. Vim cũng có thể mở file chưa tồn tại. Hãy mở terminal và gõ "vim hello.txt" để mở một file mới. Nếu bạn đang chạy hệ điều hành mới cài đặt và chưa có file nào, bạn sẽ nhìn thấy giao diện như hình bên dưới.

image.png

Các trạng thái trong Vim

Vim có nhiều chế độ (trạng thái) khác nhau. Dưới đây là 4 chế độ cơ bản mà bạn cần biết:

  1. Normal Mode - chế độ mặc định để điều hướng con trỏ
  2. Edit Mode - chế độ để nhập dữ liệu
  3. Command Line Mode - chế độ để chạy các lệnh
  4. Visual Mode - chế độ để chọn văn bản

Bạn có thể chuyển đổi giữa các chế độ này bằng cách sử dụng các phím tắt tương ứng. Hiện tại, mình đang ở chế độ Normal Mode.

Để viết dòng chữ "Hello, World", bạn cần nhấn phím "i" để chuyển sang Edit Mode, sau đó nhập và gõ "Esc" để trở lại Normal Mode. Bạn hãy thử chuyển sang Edit Mode và nhập vài từ, thậm chí sao chép đoạn code nào đó 😂

Điều hướng cơ bản

Điều hướng từng block

Bạn đã quen với việc di chuyển trái phải lên xuống bằng các phím mũi tên, đúng không? Hãy tiếp tục thực hành di chuyển bằng cách sử dụng phím "hjkl". Điều này khá hữu ích. Lý do chính cho việc bố trí này là vì một lập trình viên thường gõ bằng 10 ngón (nếu bạn chưa biết, hãy học gõ 10 ngón ngay), 2 ngón trỏ đặt trên 2 phím "f" và "j", và việc gõ phím diễn ra xung quanh khu vực này. Như vậy, nếu bạn làm quen với việc điều hướng ngay tại hàng phím cơ bản, bạn sẽ không cần phải nhấc tay phải lên tìm phím mũi tên, ấn ấn để điều hướng rồi lại nhấc tay phải trở lại phím "j" để hạ ngón trỏ xuống 😰

Có một mẹo nhỏ cho bạn là "h" nằm ở bên trái nhất và "l" nằm ở bên phải nhất, vì vậy bạn sẽ dễ nhớ hơn. Cái còn lại, "j" là phím có vị trí nằm ngay dưới, vì việc đi xuống dưới thường phổ biến hơn việc đi lên trên, vì chúng ta đọc văn bản từ trên xuống dưới mà 😂 Còn lại, "k" là đi lên.

Điều hướng với từng dòng

  • "0" - di chuyển đến đầu dòng hiện tại
  • "^" - di chuyển đến chữ cái đầu tiên của dòng hiện tại
  • "$" - di chuyển đến chữ cái cuối cùng của dòng hiện tại
  • "g_" - di chuyển đến chữ cái cuối cùng của dòng hiện tại (bất kể dòng có trống hay không)
  • "f{i}" - tức là forward, bạn gõ "f" và một ký tự. Vim sẽ đưa con trỏ đến vị trí ngay bên cạnh có ký tự đó. Nếu muốn tiếp tục tìm kiếm ký tự đó, hãy ấn ";"
  • "F{i}" - tương tự như trên, nhưng tìm kiếm theo hướng ngược lại
  • "t{i}" - tức là til, tương tự như "f{i}", nhưng con trỏ sẽ dừng ngay trước vị trí có ký tự đó
  • "T{i}" - tương tự như trên, nhưng tìm kiếm theo hướng ngược lại

Điều hướng cả màn hình

  • "H" - di chuyển đến khối đầu tiên trên màn hình hiện tại
  • "L" - di chuyển đến khối cuối cùng trên màn hình hiện tại
  • "gg" - di chuyển đến khối đầu tiên của file
  • "G" - di chuyển đến khối cuối cùng của file

Nhiều khi file code của bạn khá dài, và bạn thường sử dụng Page Up/Page Down đúng không? Ở đây chúng ta cũng có:

  • "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 nửa màn hình
  • "ctrl u" - di chuyển lên nửa màn hình

Mình thường sử dụng hai phím cuối nhiều hơn khi cần đi lên xuống mà vẫn muốn theo dõi vị trí hiện tại, phần trước/sau là gì.

Điều hướng giữa các từ

Ở đây mình muốn điều hướng giữa các từ. Trong Vim, có hai loại từ mà bạn có thể chọn.

  • "word" - là tập hợp các chữ cái, chữ số và dấu gạch dưới "_"
  • "WORD" - là tập hợp các ký tự không rỗng, được phân tách nhau bằng dấu cách "space"

Bạn có thể điều hướng giữa các từ như sau:

  • "w" - di chuyển đến từ kế tiếp bên phải
  • "W" - di chuyển đến từ kế tiếp bên phải (với "WORD")
  • "b" - di chuyển đến từ trước đó bên trái
  • "B" - di chuyển đến từ trước đó bên trái (với "WORD")
  • "e" - di chuyển đến từ cuối cùng bên phải
  • "E" - di chuyển đến từ cuối cùng bên phải (với "WORD")

Tìm kiếm trong file

  • "*" - di chuyển đến xuất hiện tiếp theo của từ cùng loại với từ hiện tại
  • "#" - di chuyển đến xuất hiện trước đó của từ cùng loại với từ hiện tại
  • "/{index}" - gõ "/" để vào Command Mode, sau đó gõ từ khóa cần tìm kiếm và nhấn Enter. Vim sẽ đưa bạn đến vị trí xuất hiện tiếp theo của từ khóa đó. Bạn có thể nhấn "n" để tìm kiếm tiếp theo hoặc "N" để tìm kiếm theo hướng ngược lại.
  • "?{index}" - tương tự như trên, nhưng tìm kiếm theo hướng ngược lại

Motion

Những lệnh điều hướng cơ bản mà mình đã đề cập được gọi là Motion trong Vim. Bạn có thể sử dụng cú pháp "{count} {motion}" để lặp lại hoạt động nhiều lần. Ví dụ, nếu bạn muốn đi xuống 9 dòng, thay vì gõ "jjjjjjjjj", bạn có thể gõ "9j" và sẽ có kết quả tương tự 🤯

Chỉnh sửa văn bản

Ở phần trước, mình đã đề cập đến việc sử dụng "i" để chuyển sang Insert Mode và thực hiện thao tác chỉnh sửa. Rồi trở lại Normal Mode bằng cách ấn "Esc". Để nói đúng hơn, "i" ở đây không phải là Insert mà nó hơn là Inside, có nghĩa là vào bên trong. Chúng ta hãy tìm hiểu thêm.

  • "i" - chuyển sang Inside Mode và đặt con trỏ vào bên trái khối hiện tại. Ví dụ, nếu con trỏ đang ở vị trí giữa từ "abcde", bạn gõ "i" và gõ các ký tự muốn chèn vào giữa "b" và "c"

  • "a" - chuyển sang Inside Mode và đặt con trỏ vào bên phải khối hiện tại. Ví dụ, nếu con trỏ đang ở vị trí giữa từ "abcde", bạn gõ "a" và gõ các ký tự muốn chèn vào giữa "c" và "d"

  • "I" - di chuyển con trỏ vào khối đầu tiên không rỗng của dòng và chuyển sang Inside Mode bên trái

  • "A" - di chuyển con trỏ vào khối cuối cùng của dòng và chuyển sang Inside Mode bên phải

  • "o" - tạo một dòng mới ngay dưới dòng hiện tại và chuyển sang Inside Mode

  • "O" - tạo một dòng mới ngay phía trên dòng hiện tại và chuyển sang Inside Mode

  • "x" - trong Normal Mode, gõ "x" để xóa một ký tự ở vị trí hiện tại của con trỏ

  • "r{c}" - trong Normal Mode, gõ "r" và gõ ký tự khác để thay thế ký tự hiện tại tại vị trí đang đứng của con trỏ

  • "u" - trong Normal Mode, gõ "u" để undo thao tác trước đó

  • "ctrl r" - trong Normal Mode, gõ "ctrl r" để redo thao tác sau đó

Chọn văn bản

Trong Normal Mode, bạn có thể tạo một phạm vi văn bản, còn được gọi là "bôi đen" 😂

  • "v" - vào Visual Mode và sử dụng các motion để chọn một đoạn văn bản
  • "V" - tương tự như trên, nhưng chọn một dòng văn bản trên từng dòng

Tổ hợp hành động

Giới thiệu về tổ hợp

Trong Vim, chúng ta có 4 hành động chính có thể sử dụng trong hầu hết các chế độ, trừ Insert Mode, lần lượt là:

  • "d" - viết tắt của delete, sử dụng để xóa văn bản và lưu phần đã xóa vào clipboard
  • "c" - viết tắt của change hoặc cut, sử dụng để xóa văn bản và lưu phần đã xóa vào clipboard, sau đó chuyển sang Insert Mode
  • "y" - viết tắt của yank, trong Vim có nghĩa là thực hiện sao chép
  • "p" - viết tắt của paste, sử dụng để dán nội dung trong clipboard

Một tổ hợp hành động sẽ có dạng "{action} {count} {motion}". Dưới đây là một số ví dụ về tổ hợp hành động, với sử dụng motion đã được nêu để bạn có thể hiểu rõ hơn:

  • Xóa dòng hiện tại và 5 dòng phía trên: "d5k" (bạn ấn "5k" để di chuyển đến dòng nào thì "d5k" sẽ xóa từng dòng đó)
  • Xóa dòng hiện tại và 3 dòng phía dưới, sau đó chuyển sang Insert Mode: "c3j"
  • Sao chép từ vị trí con trỏ tới từ cuối cùng và 2 từ tiếp theo: "y3w"
  • Xóa các ký tự từ vị trí con trỏ đến khi gặp ký tự "'", xóa luôn ký tự "'", và lưu nội dung đã xóa vào clipboard: "df'"
  • Xóa các ký tự từ vị trí con trỏ đến khi gặp ký tự "'", không xóa ký tự "'", và lưu nội dung đã xóa vào clipboard: "dt'"
  • Đối với lệnh paste, bạn chỉ cần ấn "p" để dán vào vị trí con trỏ hiện tại, hoặc nếu bạn muốn dán liên tiếp 3 lần thì gõ "3p"

Ngoài ra, chúng ta còn một số tổ hợp hành động tương tự:

  • "dd" - xóa dòng đang đứng và lưu vào clipboard
  • "cc" - xóa dòng đang đứng và lưu vào clipboard, sau đó chuyển sang Insert Mode ngay tại dòng vừa bị xóa
  • "yy" - sao chép dòng nơi con trỏ đang đứng và lưu dòng đó vào clipboard
  • "D" - tương đương với "d$", xóa từ vị trí con trỏ hiện tại tới cuối dòng và lưu vào clipboard
  • "C" - tương đương với "c$", xóa từ vị trí con trỏ hiện tại tới cuối dòng, sau đó chuyển sang Insert Mode và lưu vào clipboard
  • "Y" - tương đương với "yy", sao chép cả dòng hiện tại

Tổ hợp với Inside/Around

Có hai ký hiệu mà mình hay sử dụng ở trên là "i" và "a", trong đó giờ được sử dụng làm count, viết tắt của inside và around. Ví dụ, mình đang có text "Hello, World" và đặt con trỏ ở bất kỳ vị trí nào trong đoạn này.

  • "i" - tương tự như bên trong. Muốn xóa từ "Hello, World" đi? Gõ "di"", điều này sẽ tìm tới cặp dấu "" và xóa mọi thứ bên trong cặp dấu đó.
  • "a" - tương tự như bên trong. Muốn thay đổi "Hello, World" thành "'Hi!'"? Gõ "ca"", rồi gõ "'Hi!'"

Count trong trường hợp này hỗ trợ một số ký tự:

  • "w" và "W" - tương ứng với "word" và "WORD"
  • "s" - viết tắt của sentence, được sử dụng khi kết hợp với cái Inside/Around này, định nghĩa là một nhóm từ, một câu kết thúc bằng dấu ".", "!", "?"
  • "p" - viết tắt của paragraph, được sử dụng khi kết hợp với cái Inside/Around này, bao gồm một đoạn văn gồm nhiều câu trên nhiều dòng, cho đến khi xuống dòng.

Count cũng có một số ký tự khác:

  • "b" - đại diện cho cặp ngoặc tròn (), "dab" tương đương với "da()" và "da)"
  • "B" - đại diện cho cặp ngoặc nhọn {}, "daB" tương đương với "da{}" và "da}"

Bạn có thể thấy hơi bị khó khăn với lượng keymap "cơ bản" này. Tuy nhiên, khi bạn đạt đến mức độ thành thạo và tự tin trong việc nhớ các thao tác cơ bản này và trở thành một "chiến binh Vim", việc điều hướng và chỉnh sửa văn bản của bạn sẽ trở nên dễ dàng hơn rất nhiều.

Mong rằng bài viết này đã gợi lên sự tò mò trong bạn. Trong các bài viết tiếp theo, mình sẽ giới thiệu chi tiết hơn về các phần khác liên quan đến Vim. Hãy theo dõi để không bỏ lỡ và hẹn gặp lại bạn!

1