Port neovim configs from vimscript to lua

This commit is contained in:
2026-07-09 21:15:47 -07:00
parent b650051b81
commit 30effbb474
31 changed files with 1108 additions and 299 deletions
+133
View File
@@ -0,0 +1,133 @@
# nvim config map
Lua config managed by [lazy.nvim](https://github.com/folke/lazy.nvim). Leader is `,`, local leader is `\`.
## Layout
- `init.lua` — bootstraps lazy.nvim, loads `config/` then `plugins/`
- `lua/config/options.lua` — `vim.opt` settings
- `lua/config/keymaps.lua` — keymaps not tied to a specific plugin
- `lua/config/autocmds.lua` — autocommands
- `lua/plugins/*.lua` — one lazy.nvim spec file per topic (each file returns a plugin spec table; lazy.nvim loads every file in the directory automatically)
- `ftplugin/*.lua` — filetype-specific settings (Python, vimwiki)
- `lua/util.lua` — small helper functions (`ranger()`, `delete_trailing_ws()`) used from keymaps
## Plugins
### Navigation & editing (`plugins/editor.lua`)
- **[neo-tree.nvim](https://github.com/nvim-neo-tree/neo-tree.nvim)** — file explorer sidebar
- `<leader>t` — toggle
- `<leader>cd` — cd to current file's directory and open
- **[telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)** — fuzzy finder for files/buffers/grep/LSP symbols
- `<leader>.` — jump to symbol
- `<leader>;` — jump to buffer
- `<leader>be` — jump to buffer, sorted by most recently used
- `<leader>ag` — live grep
- **[flash.nvim](https://github.com/folke/flash.nvim)** — jump to any visible location via search-like labels
- `<leader>/` — jump
- `<leader>s` — search jump
- `<leader><leader>s` — treesitter jump
- `<leader>f` — forward jump
- **[nvim-surround](https://github.com/kylechui/nvim-surround)** — add/change/delete surrounding pairs (quotes, tags, brackets)
- `ys`, `cs`, `ds` — plugin defaults
- **[nvim-autopairs](https://github.com/windwp/nvim-autopairs)** — auto-close brackets/quotes, automatic
- **[nvim-treesitter-context](https://github.com/nvim-treesitter/nvim-treesitter-context)** — sticky header showing enclosing function/class while scrolling, automatic
- **[mini.align](https://github.com/echasnovski/mini.nvim)** — align text on a character
- `ga=`, `ga:`
- **[mini.bufremove](https://github.com/echasnovski/mini.nvim)** — close a buffer without closing its window/split
- `<leader><leader>c`
- **[vim-visual-multi](https://github.com/mg979/vim-visual-multi)** — multiple cursors
- `<C-n>` — add cursor on word
- **[vim-tmux-navigator](https://github.com/christoomey/vim-tmux-navigator)** — move between nvim splits and tmux panes; also works from inside `:terminal` buffers (e.g. the Claude Code terminal)
- `<C-h/j/k/l>` — move left/down/up/right
- **[emmet-vim](https://github.com/mattn/emmet-vim)** — Emmet expansion, HTML/CSS files only
### UI (`plugins/ui.lua`)
- **[gruvbox.nvim](https://github.com/ellisonleao/gruvbox.nvim)** — colorscheme
- **[lualine.nvim](https://github.com/nvim-lualine/lualine.nvim)** — statusline
- **[bufferline.nvim](https://github.com/akinsho/bufferline.nvim)** — buffer tabs along the top
- **[indent-blankline.nvim](https://github.com/lukas-reineke/indent-blankline.nvim)** — indent guides
- **[rainbow-delimiters.nvim](https://github.com/HiPhish/rainbow-delimiters.nvim)** — rainbow-colored matching brackets
- **[nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons)** — filetype icons (dependency for several plugins above)
- **[alpha-nvim](https://github.com/goolord/alpha-nvim)** — start screen shown on launch, see [Dashboard](#dashboard) below
- `<leader><leader>o` — reopen
### Completion & LSP
- **[blink.cmp](https://github.com/Saghen/blink.cmp)** — completion engine (LSP, path, buffer sources) — `plugins/completion.lua`
- **[mason.nvim](https://github.com/mason-org/mason.nvim)** / **[mason-lspconfig.nvim](https://github.com/mason-org/mason-lspconfig.nvim)** — installs/manages LSP servers — `plugins/lsp.lua`
- **[nvim-lspconfig](https://github.com/neovim/nvim-lspconfig)** — LSP client config for `ts_ls`, `svelte`, `html`, `cssls`, `basedpyright`, `ruff`, `bashls` — `plugins/lsp.lua`
- **[rustaceanvim](https://github.com/mrcjkb/rustaceanvim)** — Rust LSP setup (`rust_analyzer`), replaces the standard lspconfig flow for Rust — `plugins/rust.lua`
- `<localleader>rr` — cargo run
LSP buffer keymaps (set on `LspAttach`, see `plugins/lsp.lua`):
- `K` — hover
- `gd` — definition
- `gy` — type definition
- `gi` — implementation
- `gr` — references
- `rn` — rename
- `ff` (visual) — format selection
### Formatting & linting (`plugins/format.lua`)
- **[conform.nvim](https://github.com/stevearc/conform.nvim)** — format-on-save (prettier, ruff_format, rustfmt, stylua per filetype)
- **[nvim-lint](https://github.com/mfussenegger/nvim-lint)** — async linting on save/insert-leave (eslint_d, shellcheck)
### Treesitter (`plugins/treesitter.lua`)
**[nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)** — syntax highlighting, folding, and indentation for the installed parser list. Uses core Neovim's built-in `vim.treesitter.start()`/foldexpr rather than the old treesitter modules.
### Git (`plugins/git.lua`)
- **[gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim)** — git change signs in the gutter, hunk stage/preview/blame
- **[vim-fugitive](https://github.com/tpope/vim-fugitive)** — Git commands
- `:Git`, `:Gdiffsplit`, `:Gvdiffsplit`, `:Gread`, `:Gwrite`, `:Gclog`
### AI (`plugins/ai.lua`)
- **[snacks.nvim](https://github.com/folke/snacks.nvim)** — utility library (terminal provider etc.), dependency for claudecode.nvim
- **[claudecode.nvim](https://github.com/coder/claudecode.nvim)** — Claude Code terminal integration. Diffs render as a single unified (VS Code-style, red/green interleaved) buffer in one new split next to your active pane, and keyboard focus stays in the Claude terminal instead of jumping to the diff.
- `<leader>ac` — toggle
- `<leader>af` — focus
- `<leader>ab` — add current buffer
- `<leader>as` (visual) — send selection
- `<leader>aa` / `<leader>ad` — accept/deny diff
### Wiki / notes (`plugins/vimwiki.lua`)
- **[vimwiki](https://github.com/vimwiki/vimwiki)** — personal wiki across 4 notebooks (bradwiki, work, private, shared under `~/synced-notebooks/`)
- `<leader>m...` — wiki keymaps (`vim.g.vimwiki_map_prefix`)
- **[vim-zettel](https://github.com/michal-h21/vim-zettel)** — Zettelkasten-style note linking on top of vimwiki
- **[vim-table-mode](https://github.com/dhruvasagar/vim-table-mode)** — markdown/wiki table formatting
- `:TableModeToggle`, or `<leader><leader>t...` prefix
- **[markdown-preview.nvim](https://github.com/iamcco/markdown-preview.nvim)** — live browser preview for markdown/vimwiki
- `<localleader>v` — toggle preview
### Misc (`plugins/misc.lua`)
- **[aerial.nvim](https://github.com/stevearc/aerial.nvim)** — code outline/symbol sidebar
- `<leader>ct` — toggle
- **[undotree](https://github.com/jiaoshijie/undotree)** — visual undo history tree
- `<leader>u` — toggle
- **[persistence.nvim](https://github.com/folke/persistence.nvim)** — session save/restore per project
- restore from the dashboard's `s` button
- **[which-key.nvim](https://github.com/folke/which-key.nvim)** — keybinding cheatsheet, built from every mapping's `desc`
- `<leader>?` — browse all keybindings; press a key to drill into a group, `<bs>` to go back up, `<esc>` to close
## Dashboard
The start screen (shown on launch, reopen with `<leader><leader>o`) is [alpha-nvim](https://github.com/goolord/alpha-nvim), configured in `plugins/ui.lua`. It shows a random `fortune | cowthink` header plus buttons:
- `e` — new file
- `f` — find file (Telescope)
- `g` — live grep (Telescope)
- `s` — restore last session (persistence.nvim)
- `q` — quit
## Buffer navigation
`<leader>be` fuzzy-searches open buffers via Telescope, sorted by most recently used, excluding the current buffer. `<leader>;` does the same but in default Telescope order. Both are fuzzy-filterable as you type.
+2
View File
@@ -0,0 +1,2 @@
vim.bo.textwidth = 79
vim.bo.fileformat = "unix"
+36
View File
@@ -0,0 +1,36 @@
local map = function(mode, lhs, rhs)
vim.keymap.set(mode, lhs, rhs, { buffer = true })
end
map("n", "<leader>mm", "<Plug>VimwikiIndex")
map("n", "<leader>mw", "<Plug>VimwikiUISelect")
map("n", "<leader>mhelp", ":verbose map ,m<CR>")
map("n", "<leader>mg", "<Plug>VimwikiGoto")
map("n", "<leader>mf", "<Plug>VimwikiUISelect1<CR>")
map("n", "<leader>m<Space>", "<Plug>VimwikiUISelect2<CR>")
map("n", "<leader>mp", "<Plug>VimwikiUISelect3<CR>")
map("n", "<leader>ms", "<Plug>VimwikiUISelect4<CR>")
map("n", "<leader>m-", "<Plug>VimwikiSplitLink")
map("n", "<leader>m<Bar>", "<Plug>VimwikiVSplitLink")
map("n", "<leader>mnt", "<Plug>VimwikiNextTask")
map("n", "<leader>mnl", "<Plug>VimwikiNextLink")
map("n", "<leader>mNl", "<Plug>VimwikiPrevLink")
map({ "n", "i", "v" }, "<Tab>", "<Plug>VimwikiIncreaseLvlSingleItem")
map({ "n", "i", "v" }, "<S-Tab>", "<Plug>VimwikiDecreaseLvlSingleItem")
map("i", "<C-Space>", "<Esc><Plug>VimwikiToggleListItemA")
map("n", "<C-d><C-Space>", "<Plug>VimwikiRemoveSingleCB")
map("i", "<C-d><C-Space>", "<Esc><Plug>VimwikiRemoveSingleCBa")
map("n", "<leader>mb", "<Plug>VimwikiBackLinks")
map("n", "<leader>mqtoc", "<Plug>VimwikiTOC")
map("n", "<leader>mqgtl", "<Plug>VimwikiRebuildTags<CR><Plug>VimwikiGenerateTagLinks<CR>")
map("v", "<leader>mk", 'c[]<Esc>Pea()<Esc>"+P')
map("i", "<leader>mk", '<Esc>viW<C-k>ea')
map("n", "<leader>mk", 'ciw[]<Esc>Pea()<Esc>"+P')
map("n", "<leader>mag", ":ZettelOpen<CR>")
map("n", "<leader>mat", ":ZettelOpen<CR>title:")
+33
View File
@@ -0,0 +1,33 @@
-- Leader keys MUST be set before lazy.setup() so lazy-loaded `keys = {...}`
-- specs resolve <leader> correctly when they register their keymaps.
vim.g.mapleader = ","
vim.g.maplocalleader = "\\"
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.uv.fs_stat(lazypath) then
local out = vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)
require("config.options")
require("config.keymaps")
require("config.autocmds")
require("lazy").setup("plugins", {
change_detection = { notify = false },
})
+45
View File
@@ -0,0 +1,45 @@
{
"aerial.nvim": { "branch": "master", "commit": "28fe6e822ae344544c379d60fcb13c9519a1f08a" },
"alpha-nvim": { "branch": "main", "commit": "6c6a89d5b068b5251c8bdf0dd57bb921bcfeeb09" },
"blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
"blink.lib": { "branch": "main", "commit": "5876dd95deeb70aadbe9f1c0b7117a135061cdac" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"claudecode.nvim": { "branch": "main", "commit": "2390c6e45c4789072c293ac69de051d169668b29" },
"conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" },
"emmet-vim": { "branch": "master", "commit": "92ef2f74f4093edc99db5e9e4cf7e40116a85bd6" },
"flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
"gitsigns.nvim": { "branch": "main", "commit": "eb60cc7b94c46005237fd34170d76f3a089a90aa" },
"gruvbox.nvim": { "branch": "main", "commit": "154eb5ff5b96d0641307113fa385eaf0d36d9796" },
"indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "47059d71b42d74b0a1e9f61c1d99d301039c3b5b" },
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
"mini.align": { "branch": "main", "commit": "8cebe89d82f20e6d21b27346bcde4b4b6244a9f1" },
"mini.bufremove": { "branch": "main", "commit": "4cfbb201b2760da79ca6e1a00e9f67cbc99cbb8f" },
"neo-tree.nvim": { "branch": "v3.x", "commit": "ebd66767191714e008ce73b769518a763ff31bdc" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" },
"nvim-lint": { "branch": "master", "commit": "a219b2c9e5b4765e5c845aba119dad55806fcaf1" },
"nvim-lspconfig": { "branch": "master", "commit": "d224a1920728ba129880efc700d4a0180ac4ecbb" },
"nvim-surround": { "branch": "main", "commit": "8b47db616ef658b8fc27e61db2896aa2f40134de" },
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
"nvim-treesitter-context": { "branch": "master", "commit": "b311b30818951d01f7b4bf650521b868b3fece16" },
"nvim-web-devicons": { "branch": "master", "commit": "dad71387de386a946b123079d0e53f23028f3abd" },
"persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
"rainbow-delimiters.nvim": { "branch": "master", "commit": "a798325b7f36acc62741d1029930a7b96d4dd4bf" },
"rustaceanvim": { "branch": "main", "commit": "88575b98bb9937fb9983ddec5e532b67e75ce677" },
"snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" },
"telescope.nvim": { "branch": "master", "commit": "427b576c16792edad01a92b89721d923c19ad60f" },
"undotree": { "branch": "main", "commit": "02b69aed427b848c4dca483fc5e9524b6019c296" },
"vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" },
"vim-table-mode": { "branch": "master", "commit": "bb025308a45c67c7c8f0763ba37bc2ee3f534df0" },
"vim-tmux-navigator": { "branch": "master", "commit": "e41c431a0c7b7388ae7ba341f01a0d217eb3a432" },
"vim-visual-multi": { "branch": "master", "commit": "a6975e7c1ee157615bbc80fc25e4392f71c344d4" },
"vim-zettel": { "branch": "master", "commit": "554d16bf65b04ae86b92db08a44b4fbcbc31023f" },
"vimwiki": { "branch": "dev", "commit": "a54a3002e229c4b43d69ced170ff77663a5b2c40" },
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
}
+34
View File
@@ -0,0 +1,34 @@
-- autoread (options.lua) only reloads a buffer once Vim checks the file's
-- timestamp, which by default only happens on a handful of internal
-- triggers. Force that check on focus/buffer-switch/idle so external edits
-- (e.g. from claudecode.nvim) show up immediately instead of surfacing the
-- stale-buffer prompt later.
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" }, {
group = vim.api.nvim_create_augroup("CheckTimeOnFocus", { clear = true }),
callback = function()
if vim.fn.getcmdwintype() == "" then
vim.cmd("checktime")
end
end,
})
local augroup = vim.api.nvim_create_augroup("EnterBuffer", { clear = true })
vim.api.nvim_create_autocmd({ "BufNewFile", "BufReadPre", "FileReadPre", "BufEnter" }, {
group = augroup,
pattern = "Makefile",
callback = function()
vim.bo.expandtab = false
vim.bo.softtabstop = 0
vim.bo.shiftwidth = 8
end,
})
vim.api.nvim_create_autocmd({ "BufNewFile", "BufReadPre", "FileReadPre", "BufEnter" }, {
group = augroup,
pattern = { "*.asm", "*.S" },
callback = function()
vim.bo.softtabstop = 8
vim.bo.shiftwidth = 8
end,
})
+49
View File
@@ -0,0 +1,49 @@
local map = vim.keymap.set
-- Insert/command-mode escape via ,,
map("i", ",,", "<Esc>")
map("c", ",,", "<Esc><Esc>")
-- Move by display line, not physical line
map("n", "j", "gj")
map("n", "k", "gk")
-- Clear search highlight
map("n", "<leader><leader><Esc>", ":nohl<CR>")
-- Hex mode
map("n", "<leader>\\he", ":%!xxd<CR>")
map("n", "<leader>\\hd", ":%!xxd -r<CR>")
-- Toggle whitespace display
map("n", "<leader><leader>lw", ":set list!<CR>")
-- List registers / marks
map("n", "<leader><leader>lr", ":reg<CR>")
map("n", "<leader><leader>lm", ":marks<CR>")
-- Prev/next buffer
map("n", "<leader>q", ":bp<CR>")
map("n", "<leader>w", ":bn<CR>")
-- System clipboard
map({ "n", "v" }, "<leader>y", '"+y')
map({ "n", "v" }, "<leader>Y", '"+Y')
map({ "n", "v" }, "<leader>p", '"+p')
map({ "n", "v" }, "<leader>P", '"+P')
map({ "n", "v" }, "<leader>x", '"+x')
map("n", "<leader>dd", '"+dd')
-- Make split
map("n", "<leader>-", ":sp<Space>")
map("n", "<leader><Bar>", ":vsp<Space>")
-- Open init.lua
map("n", "<leader>v", ":e $MYVIMRC<CR>")
-- Low-light / daylight mode
map("n", "<leader><leader>ll", ":set background=dark<CR>")
map("n", "<leader><leader>LL", ":set background=light<CR>")
-- Ranger / trailing whitespace utilities
map("n", "<leader>ra", function() require("util").ranger() end)
map("n", "<leader>rw", function() require("util").delete_trailing_ws() end)
+61
View File
@@ -0,0 +1,61 @@
local opt = vim.opt
-- Completion / buffers
opt.omnifunc = "syntaxcomplete#Complete"
opt.hidden = true
opt.autoread = true
-- No swap/backup files
opt.swapfile = false
opt.backup = false
opt.number = true
-- matchit is built into Neovim's runtime already; no `runtime macros/matchit.vim` needed
opt.encoding = "utf-8"
opt.lazyredraw = true
opt.backspace = { "indent", "eol", "start" }
opt.history = 700
opt.incsearch = true
opt.ignorecase = true
opt.smartcase = true
opt.scrolloff = 15
opt.wildmode = { "longest", "list", "full" }
opt.wildmenu = true
opt.wildcharm = vim.api.nvim_replace_termcodes("<C-Z>", true, true, true):byte()
opt.mouse = "a"
-- Tabs
opt.tabstop = 4
opt.softtabstop = 4
opt.expandtab = true
opt.shiftwidth = 4
opt.wrap = true
opt.linebreak = true
opt.list = false
opt.ruler = true
opt.showmatch = true
opt.viewoptions:remove("options")
opt.shortmess:append("I")
opt.laststatus = 2
opt.showmode = false
opt.termguicolors = true
vim.g.enable_bold_font = 1
-- Have vrm extend background color to full terminal screen
vim.cmd("set t_ut=")
opt.splitbelow = true
opt.splitright = true
opt.updatetime = 300
opt.shortmess:append("c")
+53
View File
@@ -0,0 +1,53 @@
return {
{ "folke/snacks.nvim", lazy = false },
{
"coder/claudecode.nvim",
dependencies = { "folke/snacks.nvim" },
opts = {
terminal = {
provider = "snacks",
split_side = "right",
split_width_percentage = 0.30,
},
diff_opts = {
keep_terminal_focus = true,
-- Unified (single-buffer, VS Code-style) diff instead of side-by-side
-- splits: it only ever opens one new window, so it can't add a second
-- split and squish the rest of the layout the way the side-by-side
-- diff sometimes did.
layout = "unified",
},
},
config = function(_, opts)
require("claudecode").setup(opts)
-- claudecode picks a window for the diff by scanning all windows for the
-- first non-sidebar/non-terminal one, not the one you're actually
-- focused on, so the diff could land away from your active pane. Prefer
-- the current window when it's a normal editing window.
local diff = require("claudecode.diff")
local default_find_main_editor_window = diff._find_main_editor_window
diff._find_main_editor_window = function()
local win = vim.api.nvim_get_current_win()
local buf = vim.api.nvim_win_get_buf(win)
local buftype = vim.api.nvim_buf_get_option(buf, "buftype")
local win_config = vim.api.nvim_win_get_config(win)
local is_floating = win_config.relative and win_config.relative ~= ""
local is_diff_win = vim.api.nvim_win_get_option(win, "diff")
if not is_floating and not is_diff_win and buftype ~= "terminal" and buftype ~= "prompt" then
return win
end
return default_find_main_editor_window()
end
end,
keys = {
{ "<leader>ac", "<cmd>ClaudeCode<CR>", desc = "Toggle Claude Code" },
{ "<leader>af", "<cmd>ClaudeCodeFocus<CR>", desc = "Focus Claude Code" },
{ "<leader>ab", "<cmd>ClaudeCodeAdd %<CR>", desc = "Add buffer to Claude Code" },
{ "<leader>as", "<cmd>ClaudeCodeSend<CR>", mode = "v", desc = "Send selection to Claude Code" },
{ "<leader>aa", "<cmd>ClaudeCodeDiffAccept<CR>", desc = "Accept Claude Code diff" },
{ "<leader>ad", "<cmd>ClaudeCodeDiffDeny<CR>", desc = "Deny Claude Code diff" },
},
},
}
+10
View File
@@ -0,0 +1,10 @@
return {
"saghen/blink.cmp",
version = "*",
opts = {
keymap = { preset = "default" },
appearance = { nerd_font_variant = "mono" },
completion = { documentation = { auto_show = true } },
sources = { default = { "lsp", "path", "buffer" } },
},
}
+136
View File
@@ -0,0 +1,136 @@
return {
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
},
keys = {
{ "<leader>t", ":Neotree toggle<CR>", desc = "Toggle file explorer" },
{
"<leader>cd",
function()
vim.cmd("cd " .. vim.fn.fnameescape(vim.fn.expand("%:p:h")))
vim.cmd("pwd")
vim.cmd("Neotree dir=" .. vim.fn.fnameescape(vim.fn.getcwd()))
end,
desc = "cd to current file's directory and open explorer",
},
},
opts = {},
},
{
"nvim-telescope/telescope.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
{ "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
},
cmd = "Telescope",
keys = {
{ "<leader>.", "<cmd>Telescope lsp_document_symbols<CR>", desc = "Jump to symbol" },
{ "<leader>;", "<cmd>Telescope buffers<CR>", desc = "Jump to buffer" },
{
"<leader>be",
"<cmd>Telescope buffers sort_mru=true ignore_current_buffer=true<CR>",
desc = "Jump to buffer (MRU)",
},
{ "<leader>ag", "<cmd>Telescope live_grep<CR>", desc = "Grep" },
},
config = function()
local telescope = require("telescope")
telescope.setup({})
telescope.load_extension("fzf")
end,
},
{
"folke/flash.nvim",
event = "VeryLazy",
opts = {},
keys = {
{ "<leader>/", function() require("flash").jump() end, mode = { "n", "x", "o" }, desc = "Flash jump" },
{ "<leader>s", function() require("flash").jump({ search = { mode = "search" } }) end, mode = { "n", "x", "o" }, desc = "Flash search jump" },
{ "<leader><leader>s", function() require("flash").treesitter() end, mode = { "n", "x", "o" }, desc = "Flash treesitter" },
{ "<leader>f", function() require("flash").jump({ search = { forward = true, wrap = false } }) end, mode = { "n", "x", "o" }, desc = "Flash forward" },
},
},
{ "kylechui/nvim-surround", event = { "BufReadPost", "BufNewFile" }, opts = {} },
{ "windwp/nvim-autopairs", event = "InsertEnter", opts = {} },
{
"nvim-treesitter/nvim-treesitter-context",
event = { "BufReadPost", "BufNewFile" },
dependencies = { "nvim-treesitter/nvim-treesitter" },
opts = {},
},
{
"echasnovski/mini.align",
version = "*",
keys = {
{ "ga=", mode = { "n", "x" }, desc = "Align on =" },
{ "ga:", mode = { "n", "x" }, desc = "Align on :" },
},
config = function()
require("mini.align").setup({
mappings = { start = "ga", start_with_preview = "" },
})
end,
},
{ "echasnovski/mini.bufremove", version = "*", keys = {
{ "<leader><leader>c", function() require("mini.bufremove").delete(0, false) end, desc = "Close buffer" },
} },
{
"mg979/vim-visual-multi",
branch = "master",
keys = { "<C-n>" },
init = function()
vim.g.VM_maps = {
["Find Under"] = "<C-n>",
["Find Subword Under"] = "<C-n>",
}
end,
},
{
"christoomey/vim-tmux-navigator",
lazy = false,
-- Plugin's own default mappings rely on a Vim-only <C-w> terminal escape
-- that Neovim doesn't support, so :terminal buffers (e.g. claudecode.nvim)
-- leak the raw keystrokes to the embedded process. Disable them and
-- define our own, using Neovim's actual terminal-mode escape.
init = function()
vim.g.tmux_navigator_no_mappings = 1
end,
keys = {
{ "<C-h>", "<cmd>TmuxNavigateLeft<CR>" },
{ "<C-j>", "<cmd>TmuxNavigateDown<CR>" },
{ "<C-k>", "<cmd>TmuxNavigateUp<CR>" },
{ "<C-l>", "<cmd>TmuxNavigateRight<CR>" },
{ "<C-h>", "<C-\\><C-n><cmd>TmuxNavigateLeft<CR>", mode = "t" },
{ "<C-j>", "<C-\\><C-n><cmd>TmuxNavigateDown<CR>", mode = "t" },
{ "<C-k>", "<C-\\><C-n><cmd>TmuxNavigateUp<CR>", mode = "t" },
{ "<C-l>", "<C-\\><C-n><cmd>TmuxNavigateRight<CR>", mode = "t" },
},
},
{
"mattn/emmet-vim",
ft = { "html", "css" },
init = function()
vim.g.user_emmet_install_global = 0
end,
config = function()
vim.api.nvim_create_autocmd("FileType", {
pattern = { "html", "css" },
callback = function() vim.fn["emmet#install"]() end,
})
end,
},
}
+50
View File
@@ -0,0 +1,50 @@
return {
{
"stevearc/conform.nvim",
event = { "BufWritePre" },
cmd = { "ConformInfo" },
opts = {
formatters_by_ft = {
css = { "prettier" },
svelte = { "prettier" },
pcss = { "prettier" },
html = { "prettier" },
typescript = { "prettier" },
typescriptreact = { "prettier" },
javascript = { "prettier" },
javascriptreact = { "prettier" },
json = { "prettier" },
yaml = { "prettier" },
markdown = { "prettier" },
python = { "ruff_format" },
rust = { "rustfmt" },
lua = { "stylua" },
},
format_on_save = {
lsp_format = "fallback",
timeout_ms = 2000,
},
},
},
{
"mfussenegger/nvim-lint",
event = { "BufWritePost", "BufReadPost", "InsertLeave" },
config = function()
require("lint").linters_by_ft = {
javascript = { "eslint_d" },
typescript = { "eslint_d" },
javascriptreact = { "eslint_d" },
typescriptreact = { "eslint_d" },
svelte = { "eslint_d" },
sh = { "shellcheck" },
}
vim.api.nvim_create_autocmd({ "BufWritePost", "BufReadPost", "InsertLeave" }, {
callback = function()
require("lint").try_lint()
end,
})
end,
},
}
+4
View File
@@ -0,0 +1,4 @@
return {
{ "lewis6991/gitsigns.nvim", event = { "BufReadPre", "BufNewFile" }, opts = {} },
{ "tpope/vim-fugitive", cmd = { "Git", "Gdiffsplit", "Gvdiffsplit", "Gread", "Gwrite", "Gclog" } },
}
+41
View File
@@ -0,0 +1,41 @@
local servers = { "ts_ls", "svelte", "html", "cssls", "basedpyright", "ruff", "bashls" }
return {
{
"mason-org/mason.nvim",
opts = {},
},
{
"mason-org/mason-lspconfig.nvim",
dependencies = { "mason-org/mason.nvim" },
opts = {
ensure_installed = servers,
},
},
{
"neovim/nvim-lspconfig",
dependencies = { "mason-org/mason-lspconfig.nvim", "saghen/blink.cmp", "saghen/blink.lib" },
config = function()
local capabilities = require("blink.cmp").get_lsp_capabilities()
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("LspKeymaps", { clear = true }),
callback = function(args)
local opts = { buffer = args.buf }
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
vim.keymap.set("n", "gy", vim.lsp.buf.type_definition, opts)
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts)
vim.keymap.set("v", "ff", function() vim.lsp.buf.format({ async = true }) end, opts)
end,
})
for _, server in ipairs(servers) do
vim.lsp.config(server, { capabilities = capabilities })
vim.lsp.enable(server)
end
end,
},
}
+38
View File
@@ -0,0 +1,38 @@
return {
{
"stevearc/aerial.nvim",
dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" },
keys = {
{ "<leader>ct", "<cmd>AerialToggle<CR>", desc = "Toggle symbol outline" },
},
opts = {},
},
{
"jiaoshijie/undotree",
dependencies = { "nvim-lua/plenary.nvim" },
keys = {
{ "<leader>u", function() require("undotree").toggle() end, desc = "Toggle undo tree" },
},
opts = {},
},
{
"folke/persistence.nvim",
event = "BufReadPre",
opts = {},
},
{
"folke/which-key.nvim",
event = "VeryLazy",
opts = {},
keys = {
{
"<leader>?",
function() require("which-key").show({ global = true }) end,
desc = "Keybinding cheatsheet",
},
},
},
}
+25
View File
@@ -0,0 +1,25 @@
return {
{
"mrcjkb/rustaceanvim",
version = "^6",
lazy = false,
init = function()
vim.g.rustaceanvim = {
tools = {},
server = {
on_attach = function(_, bufnr)
vim.keymap.set("n", "<localleader>rr", function()
vim.cmd.RustLsp("run")
end, { buffer = bufnr })
end,
},
}
end,
},
{
"mason-org/mason-lspconfig.nvim",
opts = {
automatic_enable = { exclude = { "rust_analyzer" } },
},
},
}
+71
View File
@@ -0,0 +1,71 @@
return {
"nvim-treesitter/nvim-treesitter",
lazy = false,
build = ":TSUpdate",
config = function()
local parsers = {
"javascript",
"typescript",
"tsx",
"svelte",
"html",
"css",
"scss",
"json",
"yaml",
"python",
"rust",
"bash",
"lua",
"vim",
"vimdoc",
"query",
"markdown",
"markdown_inline",
"regex",
}
-- Install parsers
require("nvim-treesitter").install(parsers)
-- Enable treesitter highlighting, folding, and indentation for
-- filetypes with an installed parser. Note some filetype names differ
-- from their parser names (e.g. "bash" parser -> "sh" filetype).
vim.api.nvim_create_autocmd("FileType", {
pattern = {
"javascript",
"typescript",
"typescriptreact",
"javascriptreact",
"svelte",
"html",
"css",
"scss",
"json",
"yaml",
"python",
"rust",
"sh",
"lua",
"vim",
"help",
"query",
"markdown",
},
callback = function()
-- Highlighting, provided by Neovim
vim.treesitter.start()
-- Folding, provided by Neovim
vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.wo.foldmethod = "expr"
-- Indentation, provided by nvim-treesitter
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
end,
})
-- General fold display settings (not treesitter-specific)
vim.opt.foldlevel = 2
vim.opt.foldlevelstart = 2
vim.opt.foldcolumn = "5"
end,
}
+91
View File
@@ -0,0 +1,91 @@
return {
{
"ellisonleao/gruvbox.nvim",
priority = 1000,
opts = {
italic = { strings = true, comments = true, operators = false, folds = true },
invert_selection = true,
invert_signs = false,
},
config = function(_, opts)
require("gruvbox").setup(opts)
vim.o.background = "dark"
local ok = pcall(vim.cmd.colorscheme, "gruvbox")
if not ok then
vim.cmd.colorscheme("desert")
end
end,
},
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
event = "VeryLazy",
opts = {
options = { theme = "gruvbox" },
},
},
{
"akinsho/bufferline.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
event = "VeryLazy",
opts = {},
},
{
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
event = { "BufReadPost", "BufNewFile" },
opts = {},
},
{
"HiPhish/rainbow-delimiters.nvim",
event = { "BufReadPost", "BufNewFile" },
},
{ "nvim-tree/nvim-web-devicons", opts = {} },
{
"goolord/alpha-nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
event = "VimEnter",
config = function()
local alpha = require("alpha")
local dashboard = require("alpha.themes.dashboard")
local function fortune_header()
local cows = vim.fn.systemlist("cowsay -l")
local cow = "default"
if #cows > 1 then
cow = cows[math.random(2, #cows)]
end
local moods = { "b", "d", "g", "p", "s", "t", "w", "y" }
local mood = moods[math.random(#moods)]
local cmd = string.format(
"fortune -a -s | fmt -80 -s | cowthink -%s -f %s -n",
mood,
cow
)
local ok, lines = pcall(vim.fn.systemlist, cmd)
if not ok or #lines == 0 then
return { "Welcome to Neovim" }
end
return lines
end
dashboard.section.header.val = fortune_header()
dashboard.section.buttons.val = {
dashboard.button("e", " New file", ":enew<CR>"),
dashboard.button("f", " Find file", ":Telescope find_files<CR>"),
dashboard.button("g", " Live grep", ":Telescope live_grep<CR>"),
dashboard.button("s", " Restore session", ":lua require('persistence').load()<CR>"),
dashboard.button("q", " Quit", ":qa<CR>"),
}
alpha.setup(dashboard.opts)
vim.keymap.set("n", "<leader><leader>o", ":Alpha<CR>")
end,
},
}
+64
View File
@@ -0,0 +1,64 @@
vim.g.vimwiki_list = {
{
path = "~/synced-notebooks/bradwiki/",
syntax = "markdown",
ext = ".md",
diary_rel_path = "daily_notes/",
diary_index = "index",
diary_header = "Daily Notes",
auto_tags = 1,
auto_diary_index = 1,
auto_generate_links = 1,
auto_generate_tags = 1,
},
{
path = "~/synced-notebooks/work_notebook/",
syntax = "markdown",
ext = ".md",
diary_rel_path = "daily_notes/",
diary_index = "index",
diary_header = "Daily Notes",
auto_tags = 1,
auto_diary_index = 1,
auto_generate_links = 1,
auto_generate_tags = 1,
},
{ path = "~/synced-notebooks/privatewiki/", syntax = "markdown", ext = ".md" },
{ path = "~/synced-notebooks/sharedwiki/", syntax = "markdown", ext = ".md" },
}
vim.g.vimwiki_map_prefix = "<Leader>m"
vim.g.vimwiki_folding = "list"
vim.g.markdown_folding = 1
vim.g.zettel_options = {
{},
{
front_matter = { { "tags", "" }, { "type", "note" } },
template = "~/work_notebook/templates/daily_note.tpl",
},
}
vim.g.table_mode_map_prefix = "<Leader><Leader>t"
vim.api.nvim_create_autocmd("FileType", {
group = vim.api.nvim_create_augroup("VimwikiFiletype", { clear = true }),
pattern = "vimwiki",
callback = function()
vim.opt_local.breakindent = true
vim.opt_local.breakindentopt = "shift:2"
end,
})
return {
{ "vimwiki/vimwiki", lazy = false },
{ "michal-h21/vim-zettel", dependencies = { "vimwiki/vimwiki" }, lazy = false },
{ "dhruvasagar/vim-table-mode", cmd = "TableModeToggle" },
{
"iamcco/markdown-preview.nvim",
build = function() vim.fn["mkdp#util#install"]() end,
ft = { "markdown", "vimwiki" },
keys = {
{ "<localleader>v", "<Plug>MarkdownPreviewToggle", ft = { "markdown", "vimwiki" }, desc = "Toggle markdown preview" },
},
},
}
+28
View File
@@ -0,0 +1,28 @@
local M = {}
-- Open ranger from within nvim; if it writes a chosen path to its return
-- file, open that file. Mirrors the old vimscript Ranger() function.
function M.ranger()
if vim.fn.executable("ranger") == 0 then
vim.notify("ranger is not installed", vim.log.levels.WARN)
return
end
local tmpfile = vim.fn.system("mktemp -u"):gsub("\n", "")
vim.cmd(("silent !RANGER_RETURN_FILE=%s ranger"):format(tmpfile))
if vim.fn.filereadable(tmpfile) == 1 then
local filetoedit = vim.fn.system("cat " .. tmpfile)
vim.cmd("edit " .. filetoedit)
vim.fn.delete(tmpfile)
end
vim.cmd("redraw!")
end
-- Delete trailing whitespace on the current buffer, preserving cursor
-- position. Mirrors the old vimscript DeleteTrailingWS() function.
function M.delete_trailing_ws()
local view = vim.fn.winsaveview()
vim.cmd([[silent! %s/\s\+$//ge]])
vim.fn.winrestview(view)
end
return M