Di episode ini kita akan meng-upgrade kemampuan editing Neovim dengan plugin otomatisasi: autopairs untuk kurung dan tag, manipulasi surround text, komentar cepat, serta popup bantuan shortcut which-key agar tangan kalian tidak pernah berhenti untuk berpikir.

Setelah di episode 19 sebelumnya kita membangun terminal terintegrasi dan task runner di dalam Neovim, pada episode kali ini kita akan meningkatkan kecepatan editing itu sendiri. Editing yang cepat bukan hanya soal menekan tombol dengan cepat, tapi soal menghilangkan gerakan yang tidak perlu. Bayangkan seorang juru ketik profesional: ia tidak mengetik lebih cepat, ia hanya tidak pernah mengulang kerja. Prinsip yang sama berlaku untuk pemrograman — dan itulah yang akan kita bangun dengan empat plugin produktivitas: nvim-autopairs, nvim-ts-autotag, nvim-surround, dan which-key.nvim.
Kenapa topik ini relevan di dunia kerja nyata? Coba bayangkan kalian sedang melakukan code review terhadap perubahan besar: mengganti semua string "..." menjadi '...', menambahkan <b> di sekitar teks dalam file template, atau mematikan baris kode untuk mencari bug. Tanpa alat bantu, setiap operasi ini membutuhkan beberapa gerakan manual yang membosankan dan rawan salah. Dengan surround, operasi "bungkus teks dengan sesuatu" menjadi satu gerakan. Tanpa autopairs, setiap kurung buka harus diimbangi kurung tutup — sebuah tugas yang secara ironis sangat mudah dilupakan.
Kombinasi dari empat plugin ini secara nyata mengurangi jumlah tombol yang kalian tekan dalam sehari, dan lebih penting lagi, mengurangi interupsi berpikir. Mari kita bangun satu per satu.
nvim-autopairsKonsepnya sederhana: ketika kalian mengetik (, Neovim otomatis menambahkan ) dan menempatkan kursor di tengah. Plugin ini bekerja untuk kurung (), [], {}, tanda kutip ", ', backtick, dan bahkan mendukung html entities. Alih-alih mengetik ( ) dua tombol, kalian cukup mengetik satu tombol.
return {
{
"windwp/nvim-autopairs",
event = "InsertEnter",
opts = {
check_ts = true,
fast_wrap = {
map = "<M-e>",
chars = { "{", "[", "(", '"', "'" },
table = {
{ "{", "}" },
{ "[", "]" },
{ "(", ")" },
{ '"', '"' },
{ "'", "'" },
},
end_key = "$",
},
},
config = function(_, opts)
require("nvim-autopairs").setup(opts)
local cmp_autopairs = require("nvim-autopairs.completion.cmp")
local cmp = require("cmp")
cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done())
end,
},
}Beberapa hal penting dari konfigurasi ini:
check_ts = true — mengaktifkan integrasi dengan Treesitter (yang sudah kita pelajari di episode 14). Autopairs akan lebih pintar: misalnya di dalam komentar atau string, ia tidak akan menambahkan pasangan yang tidak dibutuhkan.fast_wrap — fitur untuk membungkus teks yang sudah ada. Blok visual pilih teks, tekan M-e, lalu tekan karakter pembungkus; teks langsung terbungkus. Fitur ini menghemat gerakan yang di episode 3 kita kenal sebagai text objects manipulation.cmp.event:on("confirm_done", ...) — integrasi dengan nvim-cmp dari episode 16. Setelah memilih item completion dari LSP, terkadang kursor berada tepat sebelum kurung tutup yang sudah ada — plugin ini memastikan kursor tetap berada di dalam pasangan kurung, bukan melewatinya.Important
Integrasi dengan nvim-cmp wajib dilakukan jika kalian memasang autopairs. Tanpa integrasi ini, sering muncul bug klasik: kalian memilih suggestion dari popup completion yang berakhiran ( (misal function call dari LSP), tapi autopairs justru menambahkan ) yang tidak diinginkan sehingga kode menjadi foo()). Integrasi di atas memastikan perilaku tetap konsisten.
nvim-ts-autotagDi dunia frontend, kurung bukan satu-satunya yang perlu ditutup otomatis — tag HTML juga. Mengetik <div> lalu secara manual menambahkan </div> adalah pekerjaan yang sangat rawan lupa dan salah ketik. nvim-ts-autotag memanfaatkan parser Treesitter untuk menutup tag secara otomatis, bahkan menangani kasus yang kompleks:
return {
"windwp/nvim-ts-autotag",
ft = { "html", "xml", "jsx", "tsx", "vue", "svelte", "astro" },
opts = {},
}Yang dilakukan plugin ini sangat kontekstual:
<div → otomatis ditutup menjadi <div></div> dengan kursor di tengah.<div menjadi <section) → tag penutup ikut berubah secara live. Ini fitur yang sangat membantu saat refactoring JSX.Tip
Karena nvim-ts-autotag hanya berguna untuk file bertipe tertentu, kita mendeklarasikannya dengan ft = { "html", ... }. Ini membuat lazy.nvim hanya memuat plugin saat kalian membuka file HTML/JSX — startup time Neovim tetap terjaga di bawah ambang yang kita bahas di episode 23 nanti.
nvim-surroundSekarang kita masuk ke plugin yang menurut banyak orang paling mengubah hidup: nvim-surround. Plugin ini memperluas text objects Neovim (yang sudah kita pelajari di episode 3) dengan kemampuan untuk menambah, mengubah, dan menghapus "surround" — pasangan tanda kutip, kurung, atau tag yang mengelilingi teks.
return {
{
"kylechui/nvim-surround",
version = "*",
opts = {
keymaps = {
insert = "<C-g>s",
insert_line = "<C-g>S",
normal = "ys",
normal_cur = "yss",
normal_line = "yS",
normal_cur_line = "ySS",
visual = "S",
visual_line = "gS",
delete = "ds",
change = "cs",
},
},
},
}Konsep dasarnya menggunakan pola grammar khas Vim: operator + motion + target. Berikut ringkasan operasi yang tersedia:
ys)| Perintah | Aksi |
|---|---|
ysiw" | Bungkus kata dalam "..." |
ysiw' | Bungkus kata dalam '...' |
yss) | Bungkus seluruh baris dalam (...) |
ysiw<b> | Bungkus kata dalam <b>...</b> (tag) |
S (visual) | Bungkus teks yang dipilih dalam visual mode |
cs)| Perintah | Aksi |
|---|---|
cs"' | Ubah "text" menjadi 'text' |
cs'<em> | Ubah 'text' menjadi <em>text</em> |
cst" | Ubah tag HTML menjadi "..." |
ds)| Perintah | Aksi |
|---|---|
ds" | Hapus pasangan tanda kutip ganda |
ds( | Hapus pasangan kurung (tapi sisakan teks di dalamnya) |
dst | Hapus tag HTML pembuka & penutup |
Tip
Analogi yang pas: nvim-surround seperti wrapping dan unwrapping pada editor GUI, tetapi dalam bentuk grammar yang bisa dikombinasikan dengan semua motion yang sudah kalian pelajari. ysiw" bisa dibaca sebagai: yank surround inner word dengan ". Karena menggunakan grammar, kalian bisa membungkus paragraf (ysap"), blok kurung (ysi)"), bahkan teks hasil visual selection.
Note
Apakah harus memakai kylechui/nvim-surround? Ada alternatif populer bernama mini.surround yang menawarkan fungsionalitas serupa dengan footprint yang lebih ringan (tidak perlu dependency eksternal). Jika kalian lebih suka pendekatan minimal, mini.surround bisa dipakai; namun sintaks ys/cs/ds dari nvim-surround lebih dekat dengan ekosistem Vim dan banyak diadopsi di dokumentasi tutorial.
Comment.nvimOperasi yang paling sering dilakukan programmer setelah mengetik kode adalah mengomentari dan mengomentari ulang — untuk menonaktifkan sementara kode saat debug, atau untuk memberi dokumentasi. Comment.nvim menawarkan komentar pintar berbasis text objects dan Treesitter:
return {
{
"numToStr/Comment.nvim",
keys = {
{ "gcc", desc = "Toggle comment baris" },
{ "gc", desc = "Toggle comment (motion/visual)" },
{ "gbc", desc = "Toggle comment block" },
{ "gb", desc = "Toggle comment block (motion/visual)" },
},
config = function()
local comment = require("Comment")
comment.setup({
toggler = {
line = "gcc",
block = "gbc",
},
opleader = {
line = "gc",
block = "gb",
},
mappings = {
basic = true,
extra = true,
},
})
end,
},
}Cara penggunaannya sangat intuitif:
| Perintah | Aksi |
|---|---|
gcc | Toggle komentar pada baris kursor |
gc3j | Komentari 3 baris ke bawah (motion) |
gcap | Komentari seluruh paragraf (text object) |
gc (visual) | Toggle komentar pada area yang dipilih |
gbc | Toggle komentar blok /* */ |
gcgc | Toggle komentar pada baris kosong sekaligus |
Tip
Kekuatan Comment.nvim terletak pada commentstring yang sadar bahasa. Di file Go ia akan memakai //, di Python #, di CSS /* */, dan di file yang sudah memiliki block comment string kustom — ia mengikuti konfigurasi buffer, bukan menebak-nebak. Ini jauh lebih pintar daripada macro manual yang biasa dipakai sebelum plugin ini ada.
which-key.nvimTerakhir, semua shortcut yang kalian buat dari episode 7 hingga sekarang bisa berjumlah puluhan. Manusia tidak mungkin mengingat semuanya — dan di situlah which-key.nvim berperan. Plugin ini menampilkan popup berisi daftar keymap setiap kali kalian menekan leader key atau prefix keymap:
return {
{
"folke/which-key.nvim",
event = "VeryLazy",
opts = {
spec = {
{ "<leader>f", group = "Find", mode = { "n", "v" } },
{ "<leader>g", group = "Git" },
{ "<leader>t", group = "Test / Terminal" },
{ "<leader>l", group = "LSP" },
{ "<leader>c", group = "Code" },
{ "<leader>b", group = "Buffer" },
},
triggers = {
{ "<auto>", mode = "n" },
{ "<leader>", mode = "n" },
},
delay = 0,
icons = {
group = "",
rules = false,
},
},
},
}Ketika kalian menekan <leader>, popup muncul menampilkan semua keymap yang dimulai dengan <leader>, dikelompokkan sesuai group. Ini bukan sekadar cheatsheet: karena setiap keymap kalian harus diberi desc (description), which-key membaca desc tersebut dan menampilkannya di popup. Itulah kenapa dari episode 7 kita selalu menambahkan desc di setiap keymap — sekarang manfaatnya terlihat.
Important
Pastikan setiap keymap yang kalian buat memiliki desc. Tanpa desc, which-key menampilkan keymap tanpa label yang membingungkan. Contoh: vim.keymap.set("n", "<leader>ff", function() ... end, { desc = "Find file" }). Jika kalian sudah membuat keymap di episode-episode sebelumnya tanpa desc, sesuaikan sekarang.
Mari kita praktikkan kombinasi semua plugin dalam satu skenario nyata. Bayangkan kalian sedang mengedit file index.html dan menemukan teks seperti ini:
<p>Halo dunia</p>Kalian ingin membungkusnya dengan <strong> dan mengubah "Halo dunia" menjadi 'Halo dunia'. Dengan nvim-surround:
<p>Halo dunia</p>.cs<p> → tag berubah menjadi... hmm, sebenarnya cs<p> memerlukan target tag. Untuk mengubah tag yang mengelilingi teks, gunakan cst<strong> — ubah tag di sekelilingnya menjadi <strong>.<strong>Halo dunia</strong>.Sekarang komentari baris tersebut sementara untuk debugging: posisikan kursor lalu tekan gcc. Baris menjadi <!-- <strong>Halo dunia</strong> -->. Tekan gcc lagi untuk mengembalikannya. Semua ini dilakukan tanpa mouse dan tanpa berpindah mode manual.
| Kesalahan | Gejala | Solusi |
|---|---|---|
Autopairs konflik dengan nvim-cmp | Popup completion menambah ) ganda, kursor loncat salah | Tambahkan integrasi cmp.event:on("confirm_done", ...) seperti di atas |
| Salah sintaks surround | ys" tidak melakukan apa-apa, atau error | Ingat urutan grammar: operator dulu (ys/cs/ds), lalu text object (iw, ap), lalu target (", ', <b>) |
| Lupa target pada surround | cs" menghapus surround tapi tanpa target baru | cs butuh dua argumen: apa yang dihapus dan apa yang menggantikan, contoh cs"' |
| Which-key delay terasa lambat | Popup muncul telat dan memperlambat mengetik | Turunkan delay = 0 atau atur triggers hanya untuk <leader> |
gcc menimpa keymap lain | Keymap lain dengan gc tidak berfungsi | Cek :verbose map gc untuk melihat tabrakan mapping |
| Autotag berubah nama tag HTML biasa | Tag <div> berubah saat mengedit atribut | Pastikan ft hanya berisi tipe file yang benar; autotag memakai Treesitter sehingga konteks harus valid |
Warning
Kombinasi nvim-autopairs dan nvim-ts-autotag bisa saling "bertabrakan" di file JSX jika tidak diatur. Kasus yang sering terjadi: kalian mengetik > di tengah tag, autopairs menutupnya, dan autotag menambahkan tag penutup — hasil akhirnya kode ganda. Solusi paling aman adalah membiarkan autopairs menangani kurung/kutip dan autotag menangani tag; pastikan check_ts = true aktif agar keduanya sadar konteks.
Pada episode 20 ini kita telah menambahkan empat senjata editing yang menyentuh inti produktivitas: nvim-autopairs dan nvim-ts-autotag untuk menutup pasangan otomatis yang sadar konteks, nvim-surround untuk membungkus dan mengubah teks dengan grammar ys/cs/ds, Comment.nvim untuk toggle komentar secepat satu tombol, serta which-key.nvim untuk menampilkan cheat-sheet shortcut yang hidup.
Yang perlu diingat: plugin-plugin ini bukan tujuan, melainkan cara untuk menghilangkan gerakan berulang sehingga pikiran kalian fokus pada logika, bukan mekanika mengetik. Efek kumulatifnya terasa setelah kalian menggunakannya selama beberapa hari — cobalah berkomitmen satu minggu untuk hanya memakai surround dan comment, dan rasakan perbedaannya.
Setelah editing menjadi cepat, sudah waktunya kita menambahkan "otak kedua" ke dalam Neovim. Di episode 21 selanjutnya, kita akan membahas AI Code Completion Integration — mengintegrasikan GitHub Copilot, Codeium, atau Avante sebagai asisten pemrograman yang bekerja langsung di dalam editor. Pastikan tetap semangat!