Referensi cepat Neovim untuk developer. Modes, motions, operators, buffers, plugin management, LSP, dan konfigurasi Lua. Perfect buat yang migrasi dari VS Code ke terminal editor.
# Ubuntu/Debian
sudo apt install neovim
# macOS
brew install neovim
# Arch Linux
sudo pacman -S neovim
# Dari source (latest)
git clone https://github.com/neovim/neovim
cd neovim && make CMAKE_BUILD_TYPE=Release
sudo make install
# Via appimage
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
chmod u+x nvim.appimage
sudo mv nvim.appimage /usr/local/bin/nvimBuka Neovim:
nvim # buka editor
nvim file.txt # buka file
nvim +42 file.txt # buka di line 42
nvim -d file1 file2 # diff mode
nvim -R file.txt # read-only modeNeovim punya beberapa mode dasar yang harus dihafal.
| Mode | Cara masuk | Fungsi |
|---|---|---|
| Normal | Esc atau Ctrl+[ | Navigasi, command |
| Insert | i, a, o, I, A, O | Ketik teks |
| Visual | v (char), V (line), Ctrl+v (block) | Seleksi teks |
| Command | : (dari Normal) | Eksekusi command |
| Replace | R | Overwrite teks |
| Terminal | :terminal | Shell di dalam Neovim |
h k
| |
| <- h j k l ->
| |
v v
j l
j = turun
k = naik
h = kiri
l = kananw " awal word berikutnya
b " awal word sebelumnya
e " akhir word berikutnya
W " awal WORD (spasi-delimited) berikutnya
B " awal WORD sebelumnya
E " akhir WORD berikutnya
ge " akhir word sebelumnyaBedanya word vs WORD:
0 " awal line
^ " karakter non-blank pertama di line
$ " akhir line
g_ " karakter non-blank terakhir
gg " baris pertama file
G " baris terakhir file
5G " ke baris 5
50% " ke 50% file
{ " paragraf sebelumnya
} " paragraf berikutnyaH " top of screen (High)
M " middle of screen (Middle)
L " bottom of screen (Low)
Ctrl+d " scroll down half page
Ctrl+u " scroll up half page
Ctrl+f " scroll down full page
Ctrl+b " scroll up full page
zt " scroll line saat ini ke top
zz " scroll line saat ini ke center
zb " scroll line saat ini ke bottom/pattern " cari ke depan
?pattern " cari ke belakang
n " match berikutnya
N " match sebelumnya
* " cari word di bawah cursor (forward)
# " cari word di bawah cursor (backward)
:set hlsearch " highlight semua matches
:noh " clear search highlighti " insert sebelum cursor
a " insert setelah cursor
I " insert di awal line
A " insert di akhir line
o " buka line baru di bawah, insert mode
O " buka line baru di atas, insert mode
s " hapus karakter, insert mode
S " hapus line, insert mode
cw " change word (delete word, insert mode)
C " change to end of line
Esc " kembali ke Normal modex " hapus karakter (cut)
dd " hapus line (cut)
dw " hapus word
d$ atau D " hapus sampai akhir line
dG " hapus sampai akhir file
dgg " hapus sampai awal file
dt( " hapus sampai sebelum tanda kurung
yy " yank (copy) line
yw " yank word
y$ " yank sampai akhir line
yG " yank sampai akhir file
p " paste setelah cursor
P " paste sebelum cursor
"ay " yank ke register a
"ap " paste dari register a
"+y " yank ke system clipboard
"+p " paste dari system clipboardVim ngikuti pola: [count] [operator] [motion]
Operator Fungsi
d delete (cut)
y yank (copy)
c change (delete + insert)
> indent
< dedent
= auto-indent
~ toggle case
gu lowercase
gU uppercase
! filter through external commandContoh kombinasi:
d2w " hapus 2 words
c$ " change sampai akhir line
>5j " indent 5 baris ke bawah
gg=G " auto-indent seluruh file
gUU " uppercase entire lineu " undo
Ctrl+r " redo
U " undo all changes di line saat inir{x} " replace 1 karakter dengan x
R " replace mode (overwrite)
~ " toggle case karakterv " visual mode (character-wise)
V " visual mode (line-wise)
Ctrl+v " visual block mode
# Setelah seleksi:
d " delete
y " yank
c " change
> " indent
< " dedent
~ " toggle case
u " lowercase
U " uppercase
Esc " keluar visual mode# Multi-line edit (column select):
Ctrl+v " masuk visual block
jjjj " select ke bawah
I " insert sebelum block
# ketik teks, tekan Esc
# teks akan di-insert di semua line yang terseleksi
# Comment multiple lines:
Ctrl+v " visual block
jjjj " select
I// " insert // di awal
Esc " apply ke semua line
# Append text di akhir multiple lines:
Ctrl+v
jjjj " select
$ " extend ke akhir line
A " append
# ketik text, Esc:e file.txt " buka file di buffer baru
:badd file.txt " add buffer tanpa buka
:ls atau :buffers " list semua buffers
:bN " ke buffer N
:bn atau :bnext " buffer berikutnya
:bp atau :bprev " buffer sebelumnya
:bf " buffer pertama
:bl " buffer terakhir
:bd " delete buffer (close file)
:bw " wipe buffer (force delete)
:%bd " close semua buffers
:bufdo %s/old/new/g " run command di semua buffers:sp atau :split " horizontal split
:vs atau :vsplit " vertical split
:sp file.txt " split + buka file
Ctrl+w h " ke window kiri
Ctrl+w j " ke window bawah
Ctrl+w k " ke window atas
Ctrl+w l " ke window kanan
Ctrl+w w " cycle windows
Ctrl+w H " pindah window ke kiri (full height)
Ctrl+w J " pindah window ke bawah
Ctrl+w K " pindah window ke atas
Ctrl+w L " pindah window ke kanan
Ctrl+w = " samakan ukuran
Ctrl+w + " tambah tinggi
Ctrl+w - " kurangi tinggi
Ctrl+w > " tambah lebar
Ctrl+w < " kurangi lebar
10 Ctrl+w + " tambah tinggi 10x
:q " close window
:only atau Ctrl+w o " close semua window kecuali yang aktif:tabnew file.txt " buka tab baru dengan file
:tabnew " tab kosong
:tabn atau :tabnext " tab berikutnya
:tabp atau :tabprev " tab sebelumnya
:tabfirst " tab pertama
:tablast " tab terakhir
:tabc " close tab
:tabo " close semua tab kecuali aktif
:tabm 0 " pindah tab ke posisi pertama
gt " tab berikutnya (Normal mode)
gT " tab sebelumnya (Normal mode)
2gt " ke tab ke-2:w " write (save)
:w file.txt " write as (save as)
:wq atau :x atau ZZ " write + quit
:q " quit
:q! atau ZQ " force quit (no save)
:wqa " write all + quit:s/old/new/ " replace first occurrence di line
:s/old/new/g " replace all di line
:%s/old/new/g " replace all di file
:%s/old/new/gc " replace all dengan confirm
:%s/old/new/gi " replace all, case insensitive
:5,10s/old/new/g " replace di lines 5-10
:'<,'>s/old/new/g " replace di visual selection
:%s/\v pattern/replace/ " very magic mode (less escaping):set number " tampilkan line numbers
:set relativenumber " relative line numbers
:set tabstop=4 " tab width
:set shiftwidth=4 " indent width
:set expandtab " spaces instead of tabs
:set autoindent " auto indent
:set smartindent " smart indent
:set wrap " wrap long lines
:set nowrap " no wrap
:set ignorecase " case insensitive search
:set smartcase " case sensitive kalau ada uppercase
:set hlsearch " highlight search
:set incsearch " incremental search
:set splitright " new splits ke kanan
:set splitbelow " new splits ke bawah
:set mouse=a " enable mouse
:set clipboard=unnamedplus " system clipboardKonfigurasi modern Neovim pakai Lua dan lazy.nvim.
-- ~/.config/nvim/init.lua
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git", "clone", "--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- Install plugins
require("lazy").setup({
-- Color scheme
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 },
-- File explorer
{
"nvim-tree/nvim-tree.lua",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
require("nvim-tree").setup({})
end,
},
-- Fuzzy finder
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
},
-- LSP
{ "neovim/nvim-lspconfig" },
{ "williamboman/mason.nvim" },
{ "williamboman/mason-lspconfig.nvim" },
-- Completion
{ "hrsh7th/nvim-cmp" },
{ "hrsh7th/cmp-nvim-lsp" },
{ "hrsh7th/cmp-buffer" },
{ "hrsh7th/cmp-path" },
{ "L3MON4D3/LuaSnip" },
-- Syntax highlighting
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
},
-- Status line
{ "nvim-lualine/lualine.nvim" },
-- Git
{ "lewis6991/gitsigns.nvim" },
-- Auto pairs
{ "windwp/nvim-autopairs" },
-- Comment toggle
{ "numToStr/Comment.nvim" },
}):Lazy " buka UI
:Lazy install " install semua plugins
:Lazy update " update semua plugins
:Lazy sync " install + clean
:Lazy clean " hapus plugins yang tidak terpakai
:Lazy check " cek updates
:Lazy log " lihat log
:Lazy profile " profiling startup time-- ~/.config/nvim/lua/lsp.lua
require("mason").setup()
require("mason-lspconfig").setup({
ensure_installed = { "lua_ls", "tsserver", "pyright", "gopls", "rust_analyzer" }
})
local lspconfig = require("lspconfig")
-- Setup dengan default capabilities
local capabilities = require("cmp_nvim_lsp").default_capabilities()
lspconfig.lua_ls.setup({ capabilities = capabilities })
lspconfig.ts_ls.setup({ capabilities = capabilities })
lspconfig.pyright.setup({ capabilities = capabilities })
lspconfig.gopls.setup({ capabilities = capabilities })
lspconfig.rust_analyzer.setup({ capabilities = capabilities })-- Global keymaps untuk LSP
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local opts = { buffer = args.buf }
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
vim.keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts)
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
vim.keymap.set("n", "<leader>f", function()
vim.lsp.buf.format({ async = true })
end, opts)
end,
})-- ~/.config/nvim/lua/cmp.lua
local cmp = require("cmp")
local luasnip = require("luasnip")
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
}),
})local telescope = require("telescope.builtin")
vim.keymap.set("n", "<leader>ff", telescope.find_files, {})
vim.keymap.set("n", "<leader>fg", telescope.live_grep, {})
vim.keymap.set("n", "<leader>fb", telescope.buffers, {})
vim.keymap.set("n", "<leader>fh", telescope.help_tags, {})
vim.keymap.set("n", "<leader>fr", telescope.oldfiles, {})
vim.keymap.set("n", "<leader>fs", telescope.lsp_document_symbols, {})
vim.keymap.set("n", "<leader>fw", telescope.lsp_workspace_symbols, {})
vim.keymap.set("n", "<leader>fd", telescope.diagnostics, {})
vim.keymap.set("n", "<leader>gc", telescope.git_commits, {})
vim.keymap.set("n", "<leader>gb", telescope.git_bcommits, {})
vim.keymap.set("n", "<leader>gs", telescope.git_status, {}):Telescope find_files
:Telescope live_grep
:Telescope buffers
:Telescope help_tags
:Telescope git_files
:Telescope oldfiles
:Telescope command_historyrequire("nvim-treesitter.configs").setup({
ensure_installed = {
"lua", "vim", "vimdoc", "query",
"javascript", "typescript", "tsx",
"python", "go", "rust", "c", "cpp",
"html", "css", "json", "yaml", "toml",
"markdown", "markdown_inline", "bash",
},
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
},
},
})Struktur direktori konfigurasi yang clean:
~/.config/nvim/
init.lua " entry point
lua/
core/
options.lua " vim options
keymaps.lua " global keymaps
autocmds.lua " autocommands
plugins/
lsp.lua " LSP config
cmp.lua " completion
telescope.lua " fuzzy finder
treesitter.lua " syntax highlighting
lualine.lua " statuslineContoh init.lua:
-- Require modules
require("core.options")
require("core.keymaps")
require("core.autocmds")
-- Options
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
vim.opt.smartindent = true
vim.opt.wrap = false
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.clipboard = "unnamedplus"
vim.opt.splitright = true
vim.opt.splitbelow = true
vim.opt.termguicolors = true
vim.opt.signcolumn = "yes"
-- Leader key
vim.g.mapleader = " "
-- Load plugins (lazy.nvim sudah setup di atas)
vim.cmd("colorscheme catppuccin-mocha")-- Leader key mappings
local map = vim.keymap.set
-- Clear search highlight
map("n", "<Esc>", "<cmd>nohlsearch<CR>")
-- Better window navigation
map("n", "<C-h>", "<C-w>h")
map("n", "<C-j>", "<C-w>j")
map("n", "<C-k>", "<C-w>k")
map("n", "<C-l>", "<C-w>l")
-- Resize windows
map("n", "<C-Up>", ":resize +2<CR>")
map("n", "<C-Down>", ":resize -2<CR>")
map("n", "<C-Left>", ":vertical resize -2<CR>")
map("n", "<C-Right>", ":vertical resize +2<CR>")
-- Move lines up/down
map("v", "J", ":m '>+1<CR>gv=gv")
map("v", "K", ":m '<-2<CR>gv=gv")
-- Keep cursor centered saat search
map("n", "n", "nzzzv")
map("n", "N", "Nzzzv")
map("n", "*", "*zzzv")
map("n", "#", "#zzzv")
-- Paste tanpa overwrite register
map("x", "<leader>p", '"_dP')
-- Yank ke system clipboard
map("n", "<leader>y", '"+y')
map("v", "<leader>y", '"+y')
map("n", "<leader>Y", '"+Y')
-- Close buffer
map("n", "<leader>q", ":bd<CR>")
map("n", "<leader>Q", ":qa!<CR>")
-- Quick save
map("n", "<leader>w", ":w<CR>")Login atau daftar akun gratis untuk membaca cheat sheet ini.