設定(NeoVim)
設定
$ :h config
Unix類系統的設定檔位於~/.config/nvim/init.lua
$ :options
即時更改選項
$ :checkhealth
1. 建立/修改~/.config/nvim/init.lua
code:init.lua
require("config.options")
2. 建立~/.config/nvim/lua/config/options.lua
code:options.lua
local opt = vim.opt
更改設定後需重新啟動NeoVim才會套用
剪貼簿
NeoVim預設的剪貼簿和系統不同,彼此無法互通
需要額外安裝xclip(X11)/wl-clipboard(Wayland)
code:options.lua
opt.clipboard = "unnamedplus"
換行
1. 建立/修改~/.config/nvim/init.lua
code:init.lua
require("config.keymaps")
2. 建立~/.config/nvim/lua/config/keymaps.lua
<leader>預設為\
code:keymaps.lua
local keymap = vim.keymap
keymap.set("n", "<leader>w", ":set wrap!<CR>", { desc = "Toggle wrap" })
隱藏狀態列
code:options.lua
opt.laststatus = 0
opt.statusline = "-"
opt.fillchars:append({ stl = "-", stlnc = "-" })
顯示行數
code:options.lua
opt.number = true
調整tab寬度
code:options.lua
opt.tabstop = 2
opt.softtabstop = 2
opt.shiftwidth = 2
opt.expandtab = true
套件管理
folke/lazy.nvim: 💤 A modern plugin manager for Neovim
安裝
🛠️ Installation | lazy.nvim
1. 建立/修改~/.config/nvim/init.lua
code:init.lua
require("config.lazy")
2. 建立~/.config/nvim/lua/config/lazy.lua
code:lazy.lua
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)
-- Make sure to setup mapleader and maplocalleader before
-- loading lazy.nvim so that mappings are correct.
-- This is also a good place to setup other settings (vim.opt)
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
-- Setup lazy.nvim
require("lazy").setup({
spec = {
-- import your plugins
{ import = "plugins" },
},
-- Configure any other settings here. See the documentation for more details.
-- colorscheme that will be used when installing plugins.
install = { colorscheme = { "habamax" } },
-- automatically check for plugin updates
checker = { enabled = true },
})
bug: No specs found for module "plugins" (Structured Setup) · folke/lazy.nvim · Discussion #1875
NeoVim啟動時,會先從多個路徑尋找init.lua
NeoVim使用lua撰寫模組,同樣透過require載入,並根據lua的模組搜尋路徑
因此當插件資料夾為空時,使用預設設定啟動時會發生錯誤,無視並繼續設定即可
想改為從其他路徑,或是單獨載入各個插件時,則修改lazy.lua中的sepc = { ... }部分
:Lazy/:Lazy home
開啟lazy.nvim的UI
可查看/更新目前已安裝/載入的插件
快捷鍵:L
插件
📂 Structuring Your Plugins | lazy.nvim
Plugins | LazyVim
建立~/.config/nvim/lua/plugins/[PLUGIN].lua
code:lua
return {
-- 想追加的插件
-- 公開在GitHub上的插件,使用"user/repo"格式
}
2024-12-11 lazy.nvimの使い方から起動を爆速にする方法までを解説 | eiji.page
Lua的插件說明內,寫在require("[PLUGIN]").setup({之後的設定值,可直接移到opts參數中
code:lua
return {
opts = {
some_config_here = {}
}
}
會在內部轉換為執行呼叫setup()
若還有進一步的設定,則寫在config參數中
Vim Script的插件則是將config改為init
⚙️ Configuration | lazy.nvim
擴充功能(NeoVim)
LSP
2023-12-11 Neovim の LSP を設定するための基本知識
將自動補完的相關產生和變數定義搜尋從編輯器獨立出來,即Language Server
編輯器改為傳送請求到Language Server,並透過取得的資訊提供編輯功能
LSP則為訂定雙方通訊的內容
在NeoVim上的詳細說明可參照:h lsp
2025-10-04 今からNeovimを始める人のLSP最短設定 (0.11, 2025-10-04現在)
nvim-lspconfig
neovim/nvim-lspconfig: Quickstart configs for Nvim LSP
coc
neoclide/coc.nvim: Nodejs extension host for vim & neovim, load extensions like VSCode and host language servers.
Using coc extensions · neoclide/coc.nvim Wiki
Node.js環境
mason.nvim
mason-org/mason.nvim: Portable package manager for Neovim that runs everywhere Neovim runs. Easily install and manage LSP servers, DAP servers, linters, and formatters.
管理和安裝LSP伺服器、DAP伺服器、linter、formatter
$ :Mason
$ :MasonInstall
$ :MasonUpdate
mason-org/mason-lspconfig.nvim: Extension to mason.nvim that makes it easier to use lspconfig with mason.nvim.
copilot-language-server
GitHub Copilot
typescript-language-server
html-lsp
css-lsp
eslint_d
biome
oxlint
Formatter
stevearc/conform.nvim: Lightweight yet powerful formatter plugin for Neovim
建立~/.config/nvim/lua/plugins/conform.lua
code:conform.lua
return {
"stevearc/conform.nvim",
opts = {
formatters_by_ft = {
lua = { "stylua" },
-- Conform will run multiple formatters sequentially
python = { "isort", "black" },
-- You can customize some of the format options for the filetype (:help conform.format)
rust = { "rustfmt", lsp_format = "fallback" },
-- Conform will run the first available formatter
javascript = { "biome", stop_after_first = true },
javascriptreact = { "biome", stop_after_first = true },
typescript = { "biome", stop_after_first = true },
typescriptreact = { "biome", stop_after_first = true },
},
},
}
安裝相關formatter
stylua
prettier
修改~/.config/nvim/lua/config/keymaps.lua
code:keymaps.lua
keymap.set("n", "<leader>f", function()
require("conform").format({ async = true })
end, { desc = "Format file" })
AI編程
folke/sidekick.nvim: Your Neovim AI sidekick
code:sidekick.lua
{
"folke/sidekick.nvim",
opts = {
-- add any options here
cli = {
mux = {
backend = "tmux",
enabled = true,
},
},
},
keys = {
{
"<tab>",
function()
-- if there is a next edit, jump to it, otherwise apply it if any
if not require("sidekick").nes_jump_or_apply() then
return "<Tab>" -- fallback to normal tab
end
end,
expr = true,
desc = "Goto/Apply Next Edit Suggestion",
},
{
"<c-.>",
function() require("sidekick.cli").toggle() end,
desc = "Sidekick Toggle",
mode = { "n", "t", "i", "x" },
},
{
"<leader>aa",
function() require("sidekick.cli").toggle() end,
desc = "Sidekick Toggle CLI",
},
{
"<leader>as",
function() require("sidekick.cli").select() end,
-- Or to select only installed tools:
-- require("sidekick.cli").select({ filter = { installed = true } })
desc = "Select CLI",
},
{
"<leader>ad",
function() require("sidekick.cli").close() end,
desc = "Detach a CLI Session",
},
{
"<leader>at",
function() require("sidekick.cli").send({ msg = "{this}" }) end,
mode = { "x", "n" },
desc = "Send This",
},
{
"<leader>af",
function() require("sidekick.cli").send({ msg = "{file}" }) end,
desc = "Send File",
},
{
"<leader>av",
function() require("sidekick.cli").send({ msg = "{selection}" }) end,
mode = { "x" },
desc = "Send Visual Selection",
},
{
"<leader>ap",
function() require("sidekick.cli").prompt() end,
mode = { "n", "x" },
desc = "Sidekick Select Prompt",
},
-- Example of a keybinding to open Claude directly
{
"<leader>ac",
function() require("sidekick.cli").toggle({ name = "claude", focus = true }) end,
desc = "Sidekick Toggle Claude",
},
},
}
copilot-language-server
$ :LspCopilotSignIn
yetone/avante.nvim: Use your Neovim like using Cursor AI IDE!
djoshea/vim-autoread: Have Vim automatically reload a file that has changed externally