Repository navigation
Expand file tree
/
Copy pathplugin_config.lua
More file actions
291 lines (282 loc) · 10.8 KB
/
Copy pathplugin_config.lua
File metadata and controls
291 lines (282 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
local is_vscode = vim.g.vscode
-- fzf
-- git clone --depth 1 https://github.com/ibhagwan/fzf-lua.git ~/.config/nvim/pack/plugins/start/fzf-lua
local ok, fzf = pcall(require, "fzf-lua")
if ok and not is_vscode then
-- fzf picker for vim.ui.select
fzf.register_ui_select()
fzf.setup({
files = {
rg_opts = [[--color=never --hidden --files -g "!.git" -g "!.jj"]],
hidden = true,
actions = {
["ctrl-alt-h"] = fzf.actions.toggle_hidden,
},
},
grep = {
rg_opts = table.concat({
"--hidden",
"--column",
"--line-number",
"--no-heading",
"--color=always",
"--smart-case",
"--max-columns=4096 -e",
}, " "),
hidden = true,
actions = {
["ctrl-alt-h"] = fzf.actions.toggle_hidden,
},
},
})
vim.keymap.set("n", "<leader><leader>", fzf.files)
vim.keymap.set("n", "<leader>/", fzf.live_grep)
vim.keymap.set("n", "<leader>sl", fzf.lines)
vim.keymap.set("n", "<leader>sb", fzf.buffers)
vim.keymap.set("n", "<leader>st", fzf.tabs)
vim.keymap.set("n", "<leader>sm", fzf.marks)
vim.keymap.set("n", "<leader>gc", fzf.git_commits, { desc = "Git commits (repo)" })
vim.keymap.set("n", "<leader>gb", fzf.git_bcommits, { desc = "Git commits (buffer)" })
vim.keymap.set("n", "<leader>gB", fzf.git_branches, { desc = "Git branches" })
vim.keymap.set("n", "<leader>gs", fzf.git_status, { desc = "Git status" })
vim.keymap.set("n", "<leader>lr", fzf.lsp_references, { desc = "LSP references (fzf)" })
vim.keymap.set("n", "<leader>ls", fzf.lsp_document_symbols, { desc = "LSP document symbols" })
vim.keymap.set("n", "<leader>lS", fzf.lsp_live_workspace_symbols, { desc = "LSP workspace symbols" })
end
-- sneaks — intentionally remaps s/S to 2-char forward/backward seek motion
-- git clone --depth 1 https://github.com/justinmk/vim-sneak ~/.config/nvim/pack/plugins/start/vim-sneak
-- vim-sneak is a Vimscript plugin: plugin/sneak.vim sets g:loaded_sneak_plugin at startup.
local sneaks_ok = vim.g.loaded_sneak_plugin ~= nil
if sneaks_ok then
vim.g["sneak#label"] = 1 -- label mode: shows jump targets (EasyMotion-style)
vim.g["sneak#use_ic_scs"] = 1 -- respect smartcase (so type P will specifically match P)
-- these have match highlight
vim.keymap.set({ "n", "x", "o" }, "f", "<Plug>Sneak_f")
vim.keymap.set({ "n", "x", "o" }, "F", "<Plug>Sneak_F")
-- t means stop 1 char before match
vim.keymap.set({ "n", "x", "o" }, "t", "<Plug>Sneak_t")
vim.keymap.set({ "n", "x", "o" }, "T", "<Plug>Sneak_T")
end
-- lsp
-- git clone https://github.com/neovim/nvim-lspconfig ~/.config/nvim/pack/nvim/start/nvim-lspconfig
-- after v12, neovim will have built-in package manager
-- lua
if not is_vscode then
vim.lsp.config("luals", {
cmd = { "lua-language-server" },
filetypes = { "lua" },
root_markers = { ".luarc.json", ".luarc.jsonc", ".git" },
settings = {
Lua = {
runtime = {
version = "LuaJIT",
},
},
},
})
-- brew install lua-language-server
vim.lsp.enable("luals")
-- uv tool install pyright
vim.lsp.config("pyright", {
settings = {
python = {
analysis = {
diagnosticMode = "workspace",
},
},
},
})
vim.lsp.enable("pyright")
-- install via uv: uv tool install pyrefly, then pyrefly init inside project folder (will transfer configs from pyright if available)
-- pyrefly seems capable of showing more type issues as far as I can tell
vim.lsp.enable("pyrefly")
-- install using system package manager
vim.lsp.enable("clangd")
-- npm instal -g typescript-language-server
vim.lsp.enable("ts_ls")
-- rust
vim.lsp.enable("rust_analyzer")
-- go
vim.lsp.enable("gopls")
-- swift
vim.lsp.config("sourcekit", {
cmd = { "sourcekit-lsp" },
filetypes = { "swift", "objective-c", "objective-cpp" },
root_markers = { "Package.swift", "compile_commands.json", ".git" },
})
vim.lsp.enable("sourcekit")
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client and client:supports_method("textDocument/completion") then
pcall(function()
vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
end)
end
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { buffer = ev.buf })
vim.keymap.set("n", "<leader>la", vim.lsp.buf.code_action, { buffer = ev.buf, desc = "LSP code action" })
end,
})
vim.api.nvim_create_user_command("LspToggle", function(opts)
local name = opts.args
for _, client in ipairs(vim.lsp.get_clients({ bufnr = 0, name = name })) do
if vim.fn.has('nvim-0.12') == 1 then
client:stop()
else
vim.lsp.stop_client(client.id)
end
return
end
vim.lsp.enable(name)
end, {
nargs = 1,
complete = function()
return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients({ bufnr = 0 }))
end,
desc = "Stop or re-enable a named LSP client for the current buffer",
})
end
-- conform (formatting)
local conform_ok, conform = pcall(require, "conform")
if conform_ok and not is_vscode then
conform.setup({
default_format_opts = {
lsp_format = "fallback",
},
formatters_by_ft = {
lua = { "stylua" },
python = { "ruff_format" },
javascript = { "prettier" },
javascriptreact = { "prettier" },
typescript = { "prettier" },
typescriptreact = { "prettier" },
},
})
-- conform derives the range from the live selection in visual mode;
-- the '< '> marks are stale until visual mode is left, so don't use them here
vim.keymap.set({ "n", "v" }, "<leader>lf", function()
conform.format()
end, { desc = "Format buffer or selection" })
end
-- fff
-- rebuild the rust binary whenever vim.pack installs/updates fff.nvim
vim.api.nvim_create_autocmd("PackChanged", {
callback = function(ev)
local name, kind = ev.data.spec.name, ev.data.kind
if name == "fff.nvim" and (kind == "install" or kind == "update") then
if not ev.data.active then
vim.cmd.packadd("fff.nvim")
end
require("fff.download").download_or_build_binary()
end
end,
})
vim.g.fff = {
lazy_sync = true,
debug = {
enabled = true,
show_scores = true,
},
}
if not is_vscode then
local function fff_call(fn)
return function()
local fff_ok, fff = pcall(require, "fff")
if not fff_ok then
vim.notify("fff.nvim is not installed (run :SyncPkgs)", vim.log.levels.WARN)
return
end
fff[fn]()
end
end
vim.keymap.set("n", "<leader>ff", fff_call("find_files"), { desc = "fff files" })
-- you can toggle between grep, fuzzy grep, regex grep with shift+tab after launching fff grep
vim.keymap.set("n", "<leader>fg", fff_call("live_grep"), { desc = "fff grep" })
end
-- diffview
local diffview_ok, diffview = pcall(require, "diffview")
if diffview_ok and not is_vscode then
diffview.setup({
use_icons = false,
})
vim.keymap.set("n", "<leader>gd", "<cmd>DiffviewOpen<CR>", { desc = "Git diff (working tree)" })
vim.keymap.set("n", "<leader>gh", "<cmd>DiffviewFileHistory %<CR>", { desc = "Git file history" })
end
-- gitsigns
local gitsigns_ok, gitsigns = pcall(require, "gitsigns")
if gitsigns_ok and not is_vscode then
gitsigns.setup()
end
-- git change navigation (]g / [g)
-- use native diff/hunk jump in diff view
-- use gitsigns diff/hunk jump in regular view
if not is_vscode then
vim.keymap.set("n", "]g", function()
if vim.wo.diff then
vim.cmd("normal! " .. vim.v.count1 .. "]c")
elseif gitsigns_ok then
gitsigns.nav_hunk("next")
end
end, { desc = "Next git change (hunk / diff)" })
vim.keymap.set("n", "[g", function()
if vim.wo.diff then
vim.cmd("normal! " .. vim.v.count1 .. "[c")
elseif gitsigns_ok then
gitsigns.nav_hunk("prev")
end
end, { desc = "Prev git change (hunk / diff)" })
end
-- treesitter textobjects (move keymaps for function/class navigation)
local tso_ok, tso = pcall(require, "nvim-treesitter-textobjects")
if tso_ok and not is_vscode then
tso.setup({
move = {
set_jumps = true,
},
})
local move = require("nvim-treesitter-textobjects.move")
vim.keymap.set({ "n", "x", "o" }, "]f", function()
move.goto_next_start("@function.outer", "textobjects")
end, { desc = "Next function start" })
vim.keymap.set({ "n", "x", "o" }, "[f", function()
move.goto_previous_start("@function.outer", "textobjects")
end, { desc = "Prev function start" })
vim.keymap.set({ "n", "x", "o" }, "]c", function()
move.goto_next_start("@class.outer", "textobjects")
end, { desc = "Next class start" })
vim.keymap.set({ "n", "x", "o" }, "[c", function()
move.goto_previous_start("@class.outer", "textobjects")
end, { desc = "Prev class start" })
vim.keymap.set({ "n", "x", "o" }, "]F", function()
move.goto_next_end("@function.outer", "textobjects")
end, { desc = "Next function end" })
vim.keymap.set({ "n", "x", "o" }, "[F", function()
move.goto_previous_end("@function.outer", "textobjects")
end, { desc = "Prev function end" })
vim.keymap.set({ "n", "x", "o" }, "]C", function()
move.goto_next_end("@class.outer", "textobjects")
end, { desc = "Next class end" })
vim.keymap.set({ "n", "x", "o" }, "[C", function()
move.goto_previous_end("@class.outer", "textobjects")
end, { desc = "Prev class end" })
end
-- obsidian
local obsidian_ok, obsidian = pcall(require, "obsidian")
if obsidian_ok then
obsidian.setup({
legacy_commands = false, -- use :Obsidian <subcommand>; legacy :Obsidian* commands warn at startup
workspaces = {
{
name = "notes",
path = "~/Git/notes",
},
{
name = "home", -- this is just a fallback in case none of the other workspaces exist (the plugin will complain)
path = "~",
},
},
daily_notes = {
folder = "journal",
},
})
end