Eric Bower
·
2025-09-02
init.lua
1--[[
2 erock's minimal config
3 ======================
4
5 design goals:
6 - single file
7 - use native nvim features (>= v0.12)
8 - use default keybindings unless painful otherwise
9 - plugins must be integral to workflow
10]]
11local o = vim.opt
12o.tabstop = 2
13o.shiftwidth = 2
14o.softtabstop = 2
15o.expandtab = true
16o.wrap = false
17o.autoread = true
18o.list = true -- show trailing characters
19o.signcolumn = "yes"
20o.backspace = "indent,eol,start"
21o.shell = "/bin/bash"
22o.colorcolumn = "100"
23o.completeopt = { "menuone", "noselect", "popup" }
24o.laststatus = 0
25o.winborder = "rounded"
26o.undofile = true
27o.ignorecase = true
28o.smartcase = true
29o.swapfile = false
30o.foldmethod = "expr"
31o.foldlevel = 99
32o.foldnestmax = 1
33vim.g.mapleader = ","
34vim.g.maplocalleader = ","
35vim.diagnostic.config({
36 severity_sort = true,
37})
38
39local opts = { silent = true }
40local map = vim.keymap.set
41map("t", "<Esc>", [[<C-\><C-n>]], opts) -- exit terminal mode
42map("n", "Q", "<nop>", opts) -- disable "Q"
43map("n", "<C-k>", ":wincmd k<CR>", opts) -- navigate splits
44map("n", "<C-j>", ":wincmd j<CR>", opts)
45map("n", "<C-h>", ":wincmd h<CR>", opts)
46map("n", "<C-l>", ":wincmd l<CR>", opts)
47map("n", "<leader>t", ":bd<CR>", opts)
48map("n", "<leader>e", vim.diagnostic.open_float, opts)
49map("n", "<leader>q", vim.diagnostic.setloclist, opts)
50map({ "n", "v" }, "<leader>gy", "<cmd>GitLink<cr>", opts)
51-- https://github.com/shell-pool/shpool/issues/71#issuecomment-2632396805
52map({ "n", "v", "i", "t" }, "<C-space><C-d>", function()
53 vim.cmd("!shpool detach")
54end)
55-- https://github.com/shell-pool/shpool/issues/240#issuecomment-3097566679
56map("n", "<leader>l", function()
57 io.stdout:write("\027[?2048h")
58end, opts)
59
60local augroup = vim.api.nvim_create_augroup("erock.cfg", { clear = true })
61local autocmd = vim.api.nvim_create_autocmd
62local makewrap = "setlocal tabstop=4 shiftwidth=4 softtabstop=4"
63local mdwrap = "setlocal wrap tw=79 formatoptions+=t tabstop=2 shiftwidth=2 softtabstop=2"
64autocmd("Filetype", { group = augroup, pattern = { "qf" }, command = "setlocal wrap" })
65autocmd("Filetype", { group = augroup, pattern = { "make" }, command = makewrap })
66autocmd("Filetype", { group = augroup, pattern = { "markdown" }, command = mdwrap })
67
68local function setup_lsp()
69 vim.lsp.enable({
70 "cssls", -- npm i -g vscode-langservers-extracted
71 "gopls",
72 "html",
73 "jsonls",
74 "lua_ls", -- os package mgr: lua-language-server
75 "pyright", -- npm i -g pyright
76 "ts_ls", -- npm i -g typescript typescript-language-server
77 })
78
79 autocmd("LspAttach", {
80 group = augroup,
81 callback = function(ev)
82 local client = assert(vim.lsp.get_client_by_id(ev.data.client_id))
83 local bufopts = { noremap = true, silent = true, buffer = ev.buf }
84 map("i", "<C-k>", vim.lsp.completion.get, bufopts) -- open completion menu manually
85 map("n", "grd", vim.lsp.buf.definition, bufopts)
86
87 local methods = vim.lsp.protocol.Methods
88 -- https://github.com/neovim/neovim/blob/b2828af5b5aba044cd40594a519d2d9f5dbb69cb/runtime/lua/vim/lsp/protocol.lua?plain=1#L858
89 if client:supports_method(methods.textDocument_completion) then
90 vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
91 end
92 end,
93 })
94end
95
96local function setup_fzf()
97 local fzf = require("fzf-lua")
98 local noprev = { winopts = { preview = { hidden = "hidden" } } }
99 local fzf_files = function()
100 fzf.files(noprev)
101 end
102 local fzf_symbols = function()
103 fzf.lsp_document_symbols(noprev)
104 end
105 local fzf_buffers = function()
106 fzf.buffers(noprev)
107 end
108 map("n", "<leader>s", fzf_files, { desc = "fzf files", noremap = true, silent = true })
109 map("n", "<leader>F", fzf_symbols, { desc = "fzf symbols", noremap = true, silent = true })
110 map("n", "<leader>f", fzf_buffers, { desc = "fzf buffers", noremap = true, silent = true })
111 map("n", "<leader>S", fzf.live_grep, { desc = "fzf grep", noremap = true, silent = true })
112 map("n", "<leader>j", fzf.jumps, { desc = "fzf jumplist", noremap = true, silent = true })
113 map("n", "<leader>m", fzf.marks, { desc = "fzf marks", noremap = true, silent = true })
114 fzf.setup({ "max-perf" })
115end
116
117local function setup_treesitter()
118 local ts_parsers = {
119 "bash",
120 "c",
121 "dockerfile",
122 "fish",
123 "git_config",
124 "git_rebase",
125 "gitattributes",
126 "gitcommit",
127 "gitignore",
128 "go",
129 "gomod",
130 "gosum",
131 "html",
132 "javascript",
133 "json",
134 "lua",
135 "make",
136 "markdown",
137 "python",
138 "rust",
139 "sql",
140 "toml",
141 "tsx",
142 "typescript",
143 "typst",
144 "vim",
145 "yaml",
146 "zig",
147 }
148 local nts = require("nvim-treesitter")
149 nts.install(ts_parsers)
150 autocmd("PackChanged", { -- update treesitter parsers/queries with plugin updates
151 group = augroup,
152 callback = function(ev)
153 local spec = ev.data.spec
154 if spec and spec.name == "nvim-treesitter" and ev.data.kind == "update" then
155 vim.schedule(function()
156 nts.update()
157 end)
158 end
159 end,
160 })
161 autocmd("FileType", { -- enable treesitter highlighting and indents
162 group = augroup,
163 callback = function(ev)
164 local filetype = ev.match
165 local lang = vim.treesitter.language.get_lang(filetype)
166 if vim.treesitter.language.add(lang) then
167 if vim.treesitter.query.get(filetype, "indents") then
168 vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
169 end
170 if vim.treesitter.query.get(filetype, "folds") then
171 vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
172 end
173 vim.treesitter.start()
174 end
175 end,
176 })
177end
178
179vim.pack.add({
180 "https://github.com/Mofiqul/dracula.nvim",
181 { src = "https://github.com/nvim-treesitter/nvim-treesitter", version = "main" },
182 "https://github.com/nvim-treesitter/nvim-treesitter-context",
183 "https://github.com/neovim/nvim-lspconfig",
184 "https://github.com/ibhagwan/fzf-lua",
185 "https://github.com/karb94/neoscroll.nvim",
186 "https://github.com/linrongbin16/gitlinker.nvim",
187 "https://github.com/tpope/vim-fugitive",
188})
189
190require("dracula").setup()
191vim.cmd([[colorscheme dracula]])
192setup_treesitter()
193setup_lsp()
194setup_fzf()
195require("neoscroll").setup({ duration_multiplier = 0.4 })
196require("gitlinker").setup()
197require("treesitter-context").setup({
198 max_lines = 3,
199 multiline_threshold = 1,
200 separator = "-",
201 min_window_height = 20,
202 line_numbers = true,
203})