Fase ini ditutup dengan akselerasi ekstrem: melompat ke kata target hanya dengan dua penekanan tombol lewat flash.nvim, menyimpan file favorit dengan harpoon, me-restore layout sesi dengan persistence.nvim, dan menelusuri seluruh riwayat perubahan lewat undotree.

Setelah di episode 12 sebelumnya kita membangun file explorer visual dengan neo-tree.nvim dan pendekatan buffer-based dengan oil.nvim, kalian sudah bisa membuka, membuat, dan memindahkan file apa pun tanpa meninggalkan keyboard. Namun, ada pertanyaan yang lebih dalam: ketika sudah berada di dalam sebuah file, bagaimana cara bergerak di dalamnya secepat mungkin?
Coba perhatikan kebiasaan kalian saat ini. Ingin pindah ke kata return di baris 120? Kalian tekan /return, Enter, lalu n beberapa kali. Ingin kembali ke file yang sama yang tadi kalian edit? Kalian buka telescope lagi dan ketik ulang namanya. Bekerja dengan tiga atau empat file favorit secara bersamaan? Kalian bolak-balik :bnext sampai menemukan yang benar. Semua ini berfungsi, tapi menguras detik-detik berharga dan memutus alur berpikir.
Di episode 13, episode pamungkas Fase 3 ini, kita akan menutup semua celah itu dengan empat senjata: flash.nvim untuk melompat ke kata target hanya dengan dua penekanan tombol, harpoon untuk menandai file favorit dan berpindah seketika, persistence.nvim untuk menyimpan dan me-restore layout sesi kerja, serta undotree untuk menelusuri seluruh riwayat perubahan dan kembali ke titik tertentu. Mari kita mulai.
Cara tradisional bergerak cepat di dalam file adalah search (/pattern lalu n). Masalahnya, kalian harus mengetik pattern, menekan Enter, lalu n berulang kali jika ada banyak kecocokan. flash.nvim merombak seluruh konsep ini dengan memanfaatkan Treesitter (parser sintaks yang akan kita bahas mendalam di episode 14) untuk menandai target secara visual.
return {
{
"folke/flash.nvim",
event = "VeryLazy",
opts = {},
keys = {
{ "s", mode = { "n", "x", "o" }, function()
require("flash").jump()
end, desc = "Flash jump" },
{ "S", mode = { "n", "x", "o" }, function()
require("flash").treesitter()
end, desc = "Flash treesitter" },
{ "r", mode = "o", function()
require("flash").remote()
end, desc = "Flash remote" },
{ "R", mode = { "o", "x" }, function()
require("flash").treesitter_search()
end, desc = "Flash treesitter search" },
},
},
}Cara kerja s (jump) — dengan contoh sederhana:
s, lalu ketik beberapa karakter dari kata target, misal ret.ret yang terlihat di layar dengan label huruf kecil.k. Selesai — kursor langsung berpindah.Kuncinya di sini: flash hanya menandai target yang terlihat di layar. Ia tidak memindai seluruh file, sehingga bergerak sangat cepat dan tidak pernah mengejutkan — kursor hanya melompat ke yang kalian lihat. Untuk melompat antar baris kosong atau ke posisi yang bukan kata, flash juga punya mode treesitter: S menandai node sintaks (misal argumen function, string, komentar) sehingga melompat lebih kontekstual daripada sekadar kata.
Warning
s dan S di Vim standar adalah perintah substitute (mengganti karakter/baris). Dengan memetakan ulang keduanya ke flash, kalian kehilangan substitute standar tersebut. Kabar baiknya: substitusi "satu karakter" (s, S) jarang dipakai dibanding substitusi dengan pattern (:%s/old/new/g dari episode 4), sehingga sebagian besar user rela menukarnya demi kecepatan flash. Jika tetap ingin fungsi substitute, kalian bisa pakai cl (change char) sebagai gantinya.
Flash tidak hanya satu mode. Keempat mapping di config kita masing-masing punya peran berbeda, dan memahami perbedaannya adalah kunci memanfaatkannya secara maksimal:
| Shortcut | Mode | Fungsi | Kapan dipakai |
|---|---|---|---|
s | jump | Melompat ke karakter/kata target di layar | Pindah cepat antar baris yang berjauhan |
S | treesitter | Melompat antar node sintaks (argumen, string, komentar) | Refactor/editing struktural dalam satu function |
r | remote (operator-pending) | Menjadi operator + flash, misal dr hapus hingga target | Kombinasi dengan operator d/c/y |
R | treesitter_search | Mencari node dengan preview highlight | Menavigasi bagian file yang besar |
Mode yang paling "berbeda rasa" adalah r (remote). Ia dipanggil dalam operator-pending mode — artinya menekan dr lalu label target akan menghapus dari posisi kursor sampai target, tanpa perlu mengatur visual selection manual. Contoh: kursor di awal baris, tekan dr lalu e → baris terhapus sampai kata bertanda e. Ini persis mental model operator + motion dari episode 3, hanya saja motion-nya kini melompat secara visual. Mode R bahkan bisa memindai seluruh file, bukan hanya layar — berguna saat mencari node yang letaknya jauh di bawah.
harpoon dari ThePrimeagen menjawab masalah "bolak-balik ke file yang sama". Bayangkan seperti pin/bokmark di browser, tapi untuk file. Alih-alih membuka telescope dan mengetik ulang nama, kalian menandai file satu kali lalu berpindah ke sana dengan satu kombinasi tombol. Skenario paling pas: bekerja dengan 4-5 file inti (misal main.go, handler.go, config.go, test/main_test.go) secara bergantian.
return {
{
"ThePrimeagen/harpoon",
branch = "harpoon2",
dependencies = { "nvim-lua/plenary.nvim" },
keys = {
{ "<leader>a", function()
require("harpoon"):list():add()
end, desc = "Harpoon: tandai file aktif" },
{ "<C-e>", function()
require("harpoon").ui:toggle_quick_menu(require("harpoon"):list())
end, desc = "Harpoon: buka menu file" },
{ "<C-h>", function()
require("harpoon"):list():select(1)
end, desc = "Harpoon: file 1" },
{ "<C-j>", function()
require("harpoon"):list():select(2)
end, desc = "Harpoon: file 2" },
{ "<C-k>", function()
require("harpoon"):list():select(3)
end, desc = "Harpoon: file 3" },
{ "<C-l>", function()
require("harpoon"):list():select(4)
end, desc = "Harpoon: file 4" },
},
},
}Alur kerja harpoon:
<leader>a — file masuk ke list harpoon.<C-h>, <C-j>, <C-k>, atau <C-l> sesuai slot 1–4.<C-e> untuk membuka menu yang menampilkan semua file yang ditandai — dari sini bisa hapus mark atau navigasi ke file lain.Important
Perbedaan penting: harpoon secara default bersifat global — list file tersimpan di seluruh sesi kerja, tidak per-proyek. Artinya file yang ditandai di proyek A akan tetap ada saat kalian buka proyek B. Untuk perilaku per-proyek, harpoon v2 menyediakan scope (local list via require("harpoon"):list({ scope = "dir" })). Putuskan sejak awal mana yang cocok untuk alur kerja kalian.
Selain keymap, harpoon mengekspos beberapa perintah :Harpoon... yang berguna untuk manajemen list:
:Harpoon list " tampilkan daftar file yang ditandai
:Harpoon add " tandai file aktif (sama dengan <leader>a)
:Harpoon select 1 " langsung pindah ke slot 1
:Harpoon switch-to 1 " alias selectJika kalian bekerja dengan banyak slot (lebih dari 4), keymap Ctrl+h/j/k/l tidak lagi memadai. Solusi paling elegan adalah memetakan tombol berdasarkan posisi kiri-tengah-kanan seperti kuasanya vi-mode, atau menggunakan menu <C-e> dan menekan nomor. Banyak user juga menggabungkan harpoon dengan which-key.nvim (episode 20) sehingga menekan <leader>h memunculkan daftar slot beserta deskripsinya.
Salah satu fitur yang paling jarang diketahui tapi paling berdampak pada produktivitas adalah session management. Session di Neovim adalah snapshot dari seluruh state: buffer yang terbuka, layout window/split, posisi kursor, dan direktori kerja. Dengan persistence.nvim, kalian bisa mengunci sesi kerja di sore hari dan membuka kembali persis seperti sebelumnya keesokan paginya — tanpa membuka ulang satu per satu file.
return {
{
"folke/persistence.nvim",
event = "BufReadPre",
opts = {
options = { "buffers", "curdir", "tabpages", "winsize", "winpos" },
save_dir = vim.fn.stdpath("state") .. "/sessions/",
},
},
}Cara kerjanya: persistence.nvim secara otomatis menyimpan sesi saat kalian keluar dari Neovim (event VimLeavePre). Saat membuka Neovim lagi di direktori yang sama, ia mendeteksi session tersimpan dan me-restore buffer, window, dan posisi kursor. Tiga perintah manual yang perlu diingat:
| Command | Fungsi |
|---|---|
:PersistenceSave | Simpan sesi secara manual |
:PersistenceLoad | Muat sesi terakhir untuk direktori ini |
:PersistenceStop | Jangan muat sesi saat startup (untuk direktori ini) |
Note
Alternatif yang lebih ringan adalah mini.sessions dari ekosistem mini.nvim — library modular satu-file. Bedanya, mini.sessions fokus pada manual control (tidak otomatis tersimpan saat keluar) sehingga lebih cocok bagi kalian yang ingin kendali penuh: simpan sesi dengan :SessionsSave, muat dengan :SessionsLoad. Pilihan antara persistence.nvim (otomatis) dan mini.sessions (manual) tergantung gaya kerja.
sessionoptionsDi balik layar, session disimpan sebagai file yang berisi rangkaian perintah Neovim (seperti badd untuk daftar buffer, set untuk options, dan normal! untuk posisi kursor). Apa saja yang tercatat diatur oleh option sessionoptions. Memahami ini penting karena default-nya menyimpan beberapa hal yang mungkin tidak kalian inginkan — dan tidak menyimpan beberapa hal yang kalian butuhkan:
vim.opt.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize,terminal"Dua yang paling sering diperdebatkan:
terminal — menyimpan konten buffer terminal di dalam session. Berguna kalau kalian sering memakai terminal tertanam (akan dibahas di episode 19), tapi membuat file session lebih besar.folds — menyimpan state fold (yang kita bahas di neo-tree dan akan muncul lagi di treesitter). Jika kalian tidak pakai fold secara intensif, menghapusnya dari daftar membuat session lebih ringan dan restore lebih cepat.Caution
Jika session yang di-restore tidak menampilkan window/split yang diharapkan, periksa dulu vim.o.sessionoptions. Gejala klasiknya: buffer berhasil dipulihkan tapi layout split hilang — itu berarti winsize (atau winpos) tidak termasuk dalam sessionoptions.
Contoh diff jika kalian memutuskan untuk ikut menyimpan buffer terminal di session (relevan setelah kita memasang terminal tertanam di episode 19):
# [!code --:1]
vim.opt.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize"
# [!code ++:1]
vim.opt.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize,terminal"Fitur undo di Vim sudah bagus: u untuk undo, Ctrl+r untuk redo. Tapi ada keterbatasan yang menyakitkan: undo bersifat linear. Kalian membuat perubahan A → B → C, lalu undo ke B, lalu mengetik D. Riwayat C pun hilang selamanya — padahal mungkin C justru yang kalian butuhkan.
Solusinya adalah undotree. Neovim sebenarnya sudah menyimpan seluruh pohon undo di memory, hanya saja antarmuka default tidak menampilkannya. undotree.nvim membuatnya terlihat: setiap cabang perubahan digambar sebagai pohon, dan kalian bisa melompat ke titik undo mana pun, termasuk cabang yang "terputus" oleh undo lalu ketik ulang.
return {
{
"mbbill/undotree",
cmd = "UndotreeToggle",
keys = {
{ "<leader>u", "<cmd>UndotreeToggle<CR>", desc = "Toggle undo tree" },
},
},
}Cara membaca undotree:
2 hours ago) menandai perubahan lama yang bisa dilompati.Tip
Undo tree bekerja maksimal jika kalian mengaktifkan persistent undo (vim.opt.undofile = true dari episode 7). Dengan undofile, riwayat undo disimpan ke file tersembunyi (~/.local/state/nvim/undo/) sehingga selamat dari restart — kalian bisa membuka file yang sama besok dan tetap bisa melompat ke titik undo minggu lalu. Undotree + undofile = jaringan pengaman lengkap untuk eksperimen kode.
| Kesalahan | Gejala | Solusi |
|---|---|---|
Flash membajak / search | Harus selalu pakai flash padahal ingin search biasa | Flash tidak menimpa /; tapi jika s/S mengganggu, map ulang ke gs/gS |
| Harpoon mark global | File proyek lain muncul di list proyek ini | Gunakan scope per-direktori: require("harpoon"):list({ scope = "dir" }) |
| Session me-restore direktori salah | Buka nvim di folder baru tapi layout lama muncul | Hapus session lama (:PersistenceStop), atau atur save_dir per-proyek |
Lupa undofile = true | Undo tree kosong setelah restart | Aktifkan vim.opt.undofile = true di lua/config/options.lua |
| Flash tidak menandai label | Tidak ada label muncul saat s | Pastikan event = "VeryLazy" terpasang dan Treesitter parser bahasa terpasang (:TSInstall) |
Conflict Ctrl+h/j/k/l harpoon dengan navigasi window | Berpindah window malah pindah file | Jangan map harpoon ke Ctrl+h/j/k/l jika kalian memakai split window; ganti ke Alt+1..4 |
Pada episode 13 ini kita menutup Fase 3 dengan empat akselerator besar: flash.nvim untuk melompat ke kata target hanya dengan dua penekanan tombol berbasis Treesitter, harpoon untuk menandai file favorit dan berpindah seketika dengan satu kombinasi tombol, persistence.nvim (atau mini.sessions) untuk menyimpan dan me-restore seluruh layout sesi kerja, serta undotree untuk menelusuri pohon riwayat perubahan dan kembali ke titik undo mana pun. Dengan ini, perjalanan kalian dari "menatap layar kosong" hingga "menavigasi proyek besar secepat berpikir" telah lengkap.
Namun, semua yang kita bangun selama Fase 1–3 — modal editing, Lua config, plugin manager, visual, pencarian, navigasi — hanyalah fondasi. Kecepatan gerak sudah maksimal, tapi editor belum benar-benar "paham" bahasa pemrograman yang kalian tulis. Di Fase 4 selanjutnya kita akan masuk ke jantung Neovim modern: di episode 14 kita akan membedah Treesitter dan cara Neovim melakukan parsing sintaks secara real-time — sebelum nantinya membangun LSP, autocompletion, dan formatting di episode-episode berikutnya. Pastikan tetap semangat!