Setelah plugin manager terpasang, kini saatnya membuat Neovim tampil memukau: pilih colorscheme modern seperti Tokyo Night dan Catppuccin, susun statusline informatif dengan lualine.nvim, lalu lengkapi dengan bufferline, indent guide, dan devicons untuk pengalaman editor yang nyaman dipandang berjam-jam.

Setelah di episode 9 sebelumnya kita membahas plugin manager modern lazy.nvim, mulai dari bootstrap script di init.lua, struktur modular lua/plugins/*.lua, sampai cara memakai UI :Lazy untuk install, update, dan clean plugin, kalian sekarang sudah punya fondasi yang memungkinkan Neovim diperluas dengan ekosistem plugin yang hampir tak terbatas. Pada episode kali ini, kita akan memanfaatkan fondasi itu untuk mengubah tampilan Neovim dari "editor polos" menjadi IDE yang nyaman dipandang.
Kenapa topik ini penting di dunia kerja nyata? Karena sebagai engineer, kalian bisa menghabiskan 8 jam lebih setiap hari menatap layar editor. Warna yang salah, kontras yang buruk, dan statusline yang tidak informatif bukan sekadar soal estetika — ini menyangkut kesehatan mata, daya tahan fokus, dan kecepatan kerja. Di episode ini kita akan membangun empat lapis kustomisasi visual sekaligus: colorscheme sebagai fondasi warna, lualine.nvim sebagai statusline, bufferline.nvim sebagai tab bar ala VS Code, serta indent-blankline dan nvim-web-devicons sebagai penyempurna detail. Mari kita mulai.
Coba analogikan Neovim kalian dengan cockpit pesawat. Setiap pilot punya preferensi susunan instrumen yang berbeda, tapi tujuannya sama: membaca informasi penting dalam sepersekian detik tanpa mengalihkan pandangan. Statusline adalah panel instrumen utama kita — ia memberi tahu file apa yang sedang dibuka, di cabang git mana kita berada, berubah-ubah atau tidak file-nya, di baris mana kursor berdiri, dan mode editing apa yang aktif. Tanpa itu, kita sering "tersesat" di dalam proyek besar.
Tapi ada prinsip yang lebih mendasar: kontras dan konsistensi warna memengaruhi kecepatan parsing otak. Ketika sintaks diwarnai konsisten, mata kalian otomatis mengenali pola — string selalu hijau, function selalu biru, keyword selalu ungu — tanpa perlu membaca teksnya huruf demi huruf. Inilah alasan memilih colorscheme yang bagus (kontras tinggi, tidak mencolok, konsisten) sama pentingnya dengan memilih font yang enak dibaca.
Note
Sebelum masuk ke plugin, pastikan dulu dua prasyarat visual dari episode 0: terminal kalian mendukung True Color (termguicolors) dan sudah memakai Nerd Font. Keduanya akan kita jadikan batu pijakan di seluruh episode Fase 3 ini.
Neovim default memakai skema warna yang terbatas dan terkadang membosankan. Colorscheme modern membawa tiga hal: palet warna yang dirancang (bukan asal), dukungan Treesitter (highlight akurat per jenis token, bukan sekadar per keyword), dan integrasi plugin (statusline, LSP, git signs ikut tercantum). Ini alasan mengapa theme seperti Tokyo Night atau Catppuccin begitu populer — bukan karena cantiknya saja, tapi karena konsistensinya di seluruh UI.
Berikut empat theme yang paling sering dipakai komunitas:
| Theme | Gaya | Kesan | Highlight |
|---|---|---|---|
| Tokyo Night | Dark gelap dengan aksen biru-ungu | Modern, kontras tinggi, fokus | tokyonight-night, tokyonight-storm |
| Catppuccin | Pastel lembut, 4 flavour | Lembut, ringan di mata | latte, frappe, macchiato, mocha |
| Gruvbox | Retro, hangat (orange/krem) | Nyaman untuk sesi panjang | gruvbox-material vs gruvbox klasik |
| Kanagawa | Terinspirasi lukisan ukiyo-e | Tenang, elegan, dark pekat | wave, dragon, lotus |
Tidak ada yang "paling benar" — pilihan ini subjektif dan sangat personal. Saran praktis: pilih satu theme dengan flavour paling gelap sebagai default, karena kebanyakan developer coding di lingkungan low-light. Kalian bisa mengganti kapan saja, dan di episode 11 kita akan pasang picker colorscheme supaya gonta-ganti theme tidak perlu ubah file.
Karena sudah memakai lazy.nvim, menginstal theme cukup dengan menambahkan satu spec plugin. Dua contoh paling populer:
return {
{
"folke/tokyonight.nvim",
lazy = false,
priority = 1000,
opts = {
style = "night",
transparent = false,
terminal_colors = true,
},
config = function(_, opts)
require("tokyonight").setup(opts)
vim.cmd.colorscheme("tokyonight")
end,
},
}Dua atribut kunci yang wajib kalian pahami:
lazy = false — theme harus dimuat sebelum UI dirender, bukan saat event tertentu. Kalau di-lazy, kalian akan melihat "flash putih" (FOUC) saat Neovim dibuka, karena warna baru muncul setelah plugin selesai dimuat.priority = 1000 — lazy.nvim memuat plugin dengan priority tertinggi lebih dulu. Theme harus menang dari plugin lain agar tidak ada plugin yang menimpa warna highlight.Important
Warna yang di-set di dalam opts hanya aktif saat plugin dimuat. Karena itu jangan lupa panggil vim.cmd.colorscheme("tokyonight") di dalam config setelah require(...).setup(opts). Banyak pemula menaruh vim.cmd.colorscheme di init.lua sebelum plugin dimuat, hasilnya: tidak terjadi apa-apa atau malah error E185: Cannot find color scheme.
Tip
Belum yakin memilih theme? Di episode 11 kita akan memasang picker colorscheme di telescope, yang memungkinkan kalian gonta-ganti theme secara live tanpa mengedit file. Jadi tidak ada alasan takut salah pilih — install dua atau tiga theme sekaligus, bandingkan, lalu kunci pilihan kalian.
Sebagai gambaran bagaimana mengubah opsi theme, contoh diff berikut mengaktifkan transparansi pada Tokyo Night — baris -- adalah baris lama yang dihapus, baris ++ adalah baris penggantinya:
return {
{
"folke/tokyonight.nvim",
lazy = false,
priority = 1000,
opts = {
style = "night",
# [!code --:1]
transparent = false,
# [!code ++:1]
transparent = true,
terminal_colors = true,
},
config = function(_, opts)
require("tokyonight").setup(opts)
vim.cmd.colorscheme("tokyonight")
end,
},
}Ingat konsekuensinya: dengan transparent = true, latar belakang Neovim ikut warna terminal — indah jika terminal kalian punya wallpaper gelap, tapi sulit dibaca jika wallpapernya terang atau terminalnya tidak menyediakan background gelap yang konsisten.
vim.api.nvim_set_hlColorscheme yang bagus tetap belum tentu cocok dengan selera pribadi untuk highlight group tertentu — misal kalian merasa warna komentar terlalu redup, atau garis kursor (CursorLine) kurang kontras. Di sinilah kita belajar salah satu API paling berguna dari episode 6: vim.api.nvim_set_hl (set highlight).
Setiap elemen di layar Neovim — keyword, string, nomor baris, tanda kolom, garis kursor — direpresentasikan oleh sebuah highlight group bernama. Beberapa group yang paling sering diubah secara manual:
vim.api.nvim_set_hl(0, "Comment", { fg = "#565f89", italic = true })
vim.api.nvim_set_hl(0, "CursorLine", { bg = "#1c2433" })
vim.api.nvim_set_hl(0, "LineNr", { fg = "#3b4261" })
vim.api.nvim_set_hl(0, "CursorLineNr", { fg = "#7aa2f7", bold = true })Hal-hal yang perlu diperhatikan:
0) berarti apply ke namespace global — berlaku di semua buffer. Bisa juga memakai nvim_create_namespace untuk highlight per-buffer.#565f89). Nilai ini diambil dari palet theme — cara termudah mengetahuinya adalah menjalankan :hi Comment di Neovim lalu melihat nilai guifg saat ini.nvim_set_hl harus terjadi setelah vim.cmd.colorscheme(...) dipanggil.Note
Cara praktis mengeksplorasi: jalankan :Inspect (atau :InspectTree jika Treesitter sudah terpasang) sambil menempatkan kursor di atas teks apa pun — Neovim akan menampilkan highlight group yang sedang aktif beserta nilainya. Kombinasi :Inspect + nvim_set_hl adalah resep standar para power user untuk "membuat theme menjadi milik sendiri".
Statusline bawaan Vim/Neovim (laststatus = 2) hanya menampilkan nama file dan koordinat kursor. lualine.nvim menggantinya dengan statusline modern yang bisa di-susun seperti rak modul. Analoginya seperti dashboard mobil: kita memilih modul speedometer (mode), indikator bahan bakar (git branch), dan odometer (baris/kolom) — sesuai kebutuhan.
return {
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {
options = {
theme = "auto",
section_separators = { left = "", right = "" },
component_separators = { left = "", right = "" },
globalstatus = true,
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff", "diagnostics" },
lualine_c = { { "filename", path = 1 } },
lualine_x = { "encoding", "fileformat", "filetype" },
lualine_y = { "progress" },
lualine_z = { "location" },
},
},
},
}Poin penting:
globalstatus = true — menjadikan satu statusline melintang di seluruh window (bukan satu statusline per split). Ini menyelamatkan ruang vertikal saat kalian membuka banyak split.sections — lualine_a sampai lualine_z adalah posisi dari kiri ke kanan. Modul branch memakai git bawaan, diff menampilkan jumlah baris berubah, dan diagnostics menampilkan jumlah error/warning dari LSP (akan kita bangun di episode 15).theme = "auto" — lualine otomatis membaca colorscheme aktif, jadi tidak perlu hardcode warna yang rawan konflik saat ganti theme.Tip
Bagian lualine_c yang menampilkan filename dengan path = 1 memberi kalian konteks file di proyek besar: misal tampil src/components/Button.tsx alih-alih hanya Button.tsx. Ini sangat membantu saat membuka file yang sama namanya di folder berbeda.
Yang membuat lualine unggul adalah kemampuannya menerima component kustom berupa function Lua. Component ini dijalankan ulang setiap kali state berubah, sehingga kalian bisa menampilkan informasi yang tidak disediakan bawaan. Contoh paling berguna adalah indikator status LSP — akan terasa relevan penuh setelah kita bangun LSP di episode 15, tapi mari pasang kerangkanya sekarang:
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff", "diagnostics" },
lualine_c = { { "filename", path = 1 } },
lualine_x = {
{
function()
local clients = vim.lsp.get_clients({ bufnr = 0 })
if #clients == 0 then
return ""
end
local names = {}
for _, client in ipairs(clients) do
table.insert(names, client.name)
end
return table.concat(names, ", ")
end,
color = { fg = "#9ece6a", gui = "bold" },
},
"encoding",
"fileformat",
"filetype",
},
lualine_y = { "progress" },
lualine_z = { "location" },
},Fungsi di atas memanggil vim.lsp.get_clients (API Neovim bawaan untuk mengecek Language Server yang aktif di buffer saat ini) lalu menampilkan nama server — misalnya gopls, tsserver, atau lua_ls. Ketika tidak ada LSP, string kosong dikembalikan sehingga statusline tetap bersih. Inilah pola yang sama persis yang akan kalian pakai untuk indikator format-on-save, status linter, dan sebagainya di episode-episode berikutnya.
Jika kalian terbiasa dengan VS Code atau JetBrains, buffer yang sedang dibuka biasanya terlihat sebagai tab di baris atas. bufferline.nvim menghadirkan pengalaman itu di Neovim, lengkap dengan indikator modifikasi, ikon filetype, dan navigasi :bnext/:bprevious yang lebih visual.
return {
{
"akinsho/bufferline.nvim",
event = "VeryLazy",
version = "*",
opts = {
options = {
mode = "tabs",
diagnostics = "nvim_lsp",
always_show_tabline = true,
show_buffer_close_icons = false,
show_buffer_icons = true,
},
},
},
}Perhatikan perbedaan konsep yang sering membingungkan: tab page (workspace layout) berbeda dengan buffer (file yang dimuat). Bufferline menampilkan buffer, bukan tab page. Ini justru bagus karena kita memakai tab page jarang-jarang (akan dibahas di episode tentang window/tab), sementara buffer adalah cara kita bekerja sehari-hari — berpindah file tanpa kehilangan perubahan yang belum disimpan.
Untuk bernavigasi di antara tab bufferline, kalian bisa memakai kombinasi perintah bawaan dan keymap Neovim:
:BufferLinePick " pilih buffer dengan menekan angka/nomor
:BufferLineCycleNext " pindah ke buffer berikutnya
:BufferLineCyclePrev " pindah ke buffer sebelumnya
:bn " cara klasik: next buffer
:bp " cara klasik: prev bufferYang sering kalian lihat di config orang lain adalah mapping <S-h> dan <S-l> untuk berpindah buffer secara visual — bergerak ke kiri/kanan layaknya berpindah tab di browser. Ini bukan bawaan bufferline, jadi cukup tambahkan di lua/config/keymaps.lua:
vim.keymap.set("n", "<S-h>", ":BufferLineCyclePrev<CR>", { desc = "Buffer sebelumnya" })
vim.keymap.set("n", "<S-l>", ":BufferLineCycleNext<CR>", { desc = "Buffer berikutnya" })Dua plugin kecil yang dampaknya besar terhadap keterbacaan:
indent-blankline.nvim — menggambar garis panduan indentasi vertikal. Di bahasa Python, YAML, atau Lua yang mementingkan indentasi, kalian bisa langsung melihat "seberapa dalam" blok kode ini berada tanpa menghitung spasi secara manual.nvim-web-devicons — menampilkan ikon spesifik per filetype (.ts biru, .lua biru dongker, .md abu-abu, dan seterusnya) di file explorer, bufferline, dan picker. Ini yang membuat editor terasa "hidup".return {
{
"lukas-reineke/indent-blankline.nvim",
event = "BufReadPre",
main = "ibl",
opts = {
indent = {
char = "│",
tab_char = "│",
},
scope = {
enabled = true,
show_start = true,
show_end = true,
},
},
},
{ "nvim-tree/nvim-web-devicons", lazy = true },
}Warning
nvim-web-devicons membutuhkan Nerd Font. Tanpa patched font, ikon akan tampil sebagai kotak persegi (tofu) yang justru merusak tampilan. Jika kalian belum memakai Nerd Font dari episode 0, ini saatnya pasang (misal JetBrainsMono Nerd Font atau FiraCode Nerd Font) dan set sebagai font default terminal.
Setelah kedua file di atas dibuat, jalankan :Lazy lalu tekan I (Install) atau cukup restart Neovim. lazy.nvim akan mengunduh semua plugin sekaligus.
| Kesalahan | Gejala | Solusi |
|---|---|---|
| Theme di-load secara lazy | Flash putih saat startup | Set lazy = false dan priority = 1000 |
vim.cmd.colorscheme dieksekusi terlalu dini | E185: Cannot find color scheme | Panggil di dalam config plugin |
transparent = true tanpa alasan | Teks sulit dibaca di atas wallpaper | Atur transparent = false atau siapkan background gelap |
nvim-web-devicons tanpa Nerd Font | Kotak persegi (tofu) di ikon | Install & aktifkan Nerd Font di terminal |
Lupa dependencies devicons di lualine | Ikon filetype tidak muncul di statusline | Tambahkan nvim-web-devicons sebagai dependency |
globalstatus = false dengan banyak split | Statusline ganda membuang ruang | Set globalstatus = true |
Pada episode 10 ini kita telah merombak tampilan Neovim secara menyeluruh: memilih dan menginstal colorscheme modern (Tokyo Night, Catppuccin, Gruvbox, atau Kanagawa) dengan mekanisme lazy = false + priority = 1000 yang benar, membangun statusline informatif dengan lualine.nvim, menambahkan tab bar ala VS Code dengan bufferline.nvim, serta indent guide dan file icons sebagai penyempurna keterbacaan. Kunci dari semua ini adalah urutan muat yang tepat dan konsistensi antara theme, statusline, dan plugin visual lainnya.
Sekarang Neovim kalian sudah terlihat seperti IDE profesional. Namun, editor yang cantik belum tentu cepat — di episode 11 selanjutnya kita akan membangun mesin pencarian dan navigasi file revolusioner dengan telescope.nvim, lengkap dengan akselerasi fzf-native berbasis C. Di sanalah kecepatan berpindah antar file kalian akan benar-benar terasa. Pastikan tetap semangat!