fix lsp
This commit is contained in:
parent
bc15b5bca3
commit
4564d7093e
116
init.lua
116
init.lua
|
|
@ -1,108 +1,92 @@
|
||||||
|
-- ~/.config/nvim/init.lua
|
||||||
require 'core.options' -- Load general options
|
require 'core.options' -- Load general options
|
||||||
require 'core.keymaps' -- Load general keymaps
|
require 'core.keymaps' -- Load general keymaps
|
||||||
require 'core.snippets' -- Custom code snippets
|
require 'core.snippets' -- Custom code snippets
|
||||||
|
|
||||||
-- Install package manager
|
-- Install package manager (lazy.nvim)
|
||||||
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
|
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
|
||||||
if not vim.loop.fs_stat(lazypath) then
|
if not vim.loop.fs_stat(lazypath) then
|
||||||
vim.fn.system {
|
vim.fn.system({
|
||||||
'git',
|
'git', 'clone', '--filter=blob:none',
|
||||||
'clone',
|
|
||||||
'--filter=blob:none',
|
|
||||||
'https://github.com/folke/lazy.nvim.git',
|
'https://github.com/folke/lazy.nvim.git',
|
||||||
'--branch=stable', -- latest stable release
|
'--branch=stable', lazypath,
|
||||||
lazypath,
|
})
|
||||||
}
|
|
||||||
end
|
end
|
||||||
vim.opt.rtp:prepend(lazypath)
|
vim.opt.rtp:prepend(lazypath)
|
||||||
|
|
||||||
|
-- Filetypes
|
||||||
vim.filetype.add({
|
vim.filetype.add({
|
||||||
extension = {
|
extension = { templ = 'templ' },
|
||||||
templ = "templ",
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Import color theme based on environment variable NVIM_THEME
|
-- Theme selection (robust against unknown NVIM_THEME)
|
||||||
local default_color_scheme = 'quantum'
|
local default_color_scheme = 'quantum'
|
||||||
local env_var_nvim_theme = os.getenv 'NVIM_THEME' or default_color_scheme
|
local env_var_nvim_theme = os.getenv('NVIM_THEME') or default_color_scheme
|
||||||
|
|
||||||
-- Define a table of theme modules
|
|
||||||
local themes = {
|
local themes = {
|
||||||
quantum = 'plugins.themes.quantum',
|
quantum = 'plugins.themes.quantum',
|
||||||
nord = 'plugins.themes.nord',
|
nord = 'plugins.themes.nord',
|
||||||
onedark = 'plugins.themes.onedark',
|
onedark = 'plugins.themes.onedark',
|
||||||
}
|
}
|
||||||
|
local theme_module = themes[env_var_nvim_theme] or themes[default_color_scheme]
|
||||||
|
|
||||||
-- Setup plugins
|
-- Plugins
|
||||||
require('lazy').setup({
|
require('lazy').setup({
|
||||||
require(themes[env_var_nvim_theme]),
|
require(theme_module),
|
||||||
require 'core.ui',
|
require 'core.ui',
|
||||||
|
|
||||||
require 'plugins.aaa', -- Mason setup
|
-- Load mason early so tools are ready for LSP configs
|
||||||
require 'plugins.aerial',
|
require 'plugins.mason',
|
||||||
require 'plugins.flash',
|
|
||||||
require 'plugins.autocompletion',
|
-- Core dev UX
|
||||||
require 'plugins.bufferline',
|
require 'plugins.treesitter',
|
||||||
require 'plugins.comment',
|
require 'plugins.telescope',
|
||||||
require 'plugins.conform',
|
|
||||||
require 'plugins.database',
|
|
||||||
require 'plugins.debug',
|
|
||||||
require 'plugins.gitsigns',
|
|
||||||
require 'plugins.harpoon',
|
|
||||||
require 'plugins.lazygit',
|
|
||||||
require 'plugins.lsp',
|
|
||||||
require 'plugins.lualine',
|
require 'plugins.lualine',
|
||||||
require 'plugins.none-ls',
|
require 'plugins.bufferline',
|
||||||
require 'plugins.indent-blankline',
|
require 'plugins.indent-blankline',
|
||||||
require 'plugins.neo-tree',
|
require 'plugins.neo-tree',
|
||||||
require 'plugins.misc',
|
|
||||||
require 'plugins.snack',
|
|
||||||
require 'plugins.telescope',
|
|
||||||
require 'plugins.toggleterm',
|
require 'plugins.toggleterm',
|
||||||
require 'plugins.treesitter',
|
|
||||||
require 'plugins.vim-tmux-navigator',
|
require 'plugins.vim-tmux-navigator',
|
||||||
require 'plugins.zellij',
|
require 'plugins.zellij',
|
||||||
|
require 'plugins.flash',
|
||||||
|
require 'plugins.comment',
|
||||||
|
require 'plugins.harpoon',
|
||||||
|
require 'plugins.gitsigns',
|
||||||
|
require 'plugins.lazygit',
|
||||||
|
require 'plugins.aerial',
|
||||||
|
require 'plugins.misc',
|
||||||
|
|
||||||
|
-- LSP & companions
|
||||||
|
require 'plugins.autocompletion',
|
||||||
|
require 'plugins.lsp',
|
||||||
|
require 'plugins.none-ls', -- none-ls/null-ls sources & setup
|
||||||
|
require 'plugins.autoformat', -- your autoformat-on-save/idle logic
|
||||||
|
|
||||||
|
-- Optional: pick one formatter stack. If you keep Conform,
|
||||||
|
-- ensure it doesn't also format Go on save to avoid double-format.
|
||||||
|
require 'plugins.conform',
|
||||||
|
|
||||||
|
-- Debugging / DB (as you had)
|
||||||
|
require 'plugins.debug',
|
||||||
|
require 'plugins.database',
|
||||||
}, {
|
}, {
|
||||||
ui = {
|
ui = {
|
||||||
-- If you have a Nerd Font, set icons to an empty table which will use the
|
|
||||||
-- default lazy.nvim defined Nerd Font icons otherwise define a unicode icons table
|
|
||||||
icons = vim.g.have_nerd_font and {} or {
|
icons = vim.g.have_nerd_font and {} or {
|
||||||
cmd = '⌘',
|
cmd = '⌘', config = '🛠', event = '📅', ft = '📂', init = '⚙',
|
||||||
config = '🛠',
|
keys = '🗝', plugin = '🔌', runtime = '💻', require = '🌙',
|
||||||
event = '📅',
|
source = '📄', start = '🚀', task = '📌', lazy = '💤 ',
|
||||||
ft = '📂',
|
|
||||||
init = '⚙',
|
|
||||||
keys = '🗝',
|
|
||||||
plugin = '🔌',
|
|
||||||
runtime = '💻',
|
|
||||||
require = '🌙',
|
|
||||||
source = '📄',
|
|
||||||
start = '🚀',
|
|
||||||
task = '📌',
|
|
||||||
lazy = '💤 ',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Function to check if a file exists
|
-- (Optional) tiny helper if you ever want to source a session file
|
||||||
local function file_exists(file)
|
local function file_exists(file)
|
||||||
local f = io.open(file, 'r')
|
local f = io.open(file, 'r')
|
||||||
if f then
|
if f then f:close(); return true end
|
||||||
f:close()
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
return false
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Path to the session file
|
-- local session_file = '.session.vim'
|
||||||
local session_file = '.session.vim'
|
-- if file_exists(session_file) then vim.cmd('source ' .. session_file) end
|
||||||
|
|
||||||
-- Check if the session file exists in the current directory
|
|
||||||
-- if file_exists(session_file) then
|
|
||||||
-- -- Source the session file
|
|
||||||
-- vim.cmd('source ' .. session_file)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- The line beneath this is called `modeline`. See `:help modeline`
|
|
||||||
-- vim: ts=2 sts=2 sw=2 et
|
-- vim: ts=2 sts=2 sw=2 et
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
return {
|
|
||||||
{
|
|
||||||
"mason-org/mason.nvim",
|
|
||||||
version = "^1.0.0",
|
|
||||||
config = function()
|
|
||||||
require("mason").setup()
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mason-org/mason-lspconfig.nvim",
|
|
||||||
version = "^1.0.0",
|
|
||||||
config = function()
|
|
||||||
require("mason-lspconfig").setup({
|
|
||||||
ensure_installed = { "ts_ls", "gopls", "templ" },
|
|
||||||
automatic_installation = true,
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
-- lua/plugins/autoformat.lua
|
||||||
|
-- Automatically format Go code on save and when idle after changes
|
||||||
|
|
||||||
|
return {
|
||||||
|
"neovim/nvim-lspconfig",
|
||||||
|
event = { "BufReadPre", "BufNewFile" },
|
||||||
|
config = function()
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- 🧹 Format on save
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||||
|
pattern = "*.go",
|
||||||
|
callback = function()
|
||||||
|
-- Runs both gopls and none-ls formatters in order
|
||||||
|
vim.lsp.buf.format({ async = false })
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- ⚡ Auto-format when idle (after you stop typing)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
local format_timer = vim.loop.new_timer()
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
|
||||||
|
pattern = "*.go",
|
||||||
|
callback = function()
|
||||||
|
-- Cancel previous pending format
|
||||||
|
format_timer:stop()
|
||||||
|
|
||||||
|
-- Wait 1.5 seconds after the last change before formatting
|
||||||
|
format_timer:start(1500, 0, vim.schedule_wrap(function()
|
||||||
|
-- Only format if the buffer still exists and is listed
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
if vim.api.nvim_buf_is_valid(bufnr) and vim.bo[bufnr].modifiable then
|
||||||
|
vim.lsp.buf.format({ async = true })
|
||||||
|
end
|
||||||
|
end))
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- 🧪 Optional: run `goimports` and quick test on save
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
vim.api.nvim_create_autocmd("BufWritePost", {
|
||||||
|
pattern = "*.go",
|
||||||
|
callback = function()
|
||||||
|
-- Automatically fix imports using goimports if available
|
||||||
|
vim.fn.jobstart({ "goimports", "-w", vim.fn.expand("%:p") }, {
|
||||||
|
on_exit = function()
|
||||||
|
-- Optionally, trigger a quick test run for feedback
|
||||||
|
vim.fn.jobstart({ "go", "test", "./..." }, {
|
||||||
|
cwd = vim.fn.getcwd(),
|
||||||
|
stdout_buffered = true,
|
||||||
|
stderr_buffered = true,
|
||||||
|
on_stdout = function(_, data)
|
||||||
|
if data then
|
||||||
|
vim.notify(table.concat(data, "\n"), vim.log.levels.INFO, { title = "go test" })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_stderr = function(_, data)
|
||||||
|
if data then
|
||||||
|
vim.notify(table.concat(data, "\n"), vim.log.levels.ERROR, { title = "go test" })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -2,27 +2,27 @@
|
||||||
return {
|
return {
|
||||||
{
|
{
|
||||||
"neovim/nvim-lspconfig",
|
"neovim/nvim-lspconfig",
|
||||||
|
lazy = false,
|
||||||
config = function()
|
config = function()
|
||||||
local lspconfig = require("lspconfig")
|
local lspconfig = require("lspconfig")
|
||||||
local util = require("lspconfig.util")
|
local util = require("lspconfig.util")
|
||||||
|
local configs = require("lspconfig.configs")
|
||||||
|
|
||||||
-- Ensure *.templ is recognized as 'templ'
|
-- Recognize .templ files
|
||||||
vim.filetype.add({
|
vim.filetype.add({ extension = { templ = "templ" } })
|
||||||
extension = { templ = "templ" },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Go LSP with import organization
|
-- ==============================
|
||||||
|
-- gopls
|
||||||
|
-- ==============================
|
||||||
lspconfig.gopls.setup({
|
lspconfig.gopls.setup({
|
||||||
root_dir = function(fname)
|
root_dir = function(fname)
|
||||||
return util.root_pattern("go.work", "go.mod", ".git")(fname)
|
return util.root_pattern("go.work", "go.mod", ".git")(fname)
|
||||||
or util.path.dirname(fname)
|
or util.path.dirname(fname)
|
||||||
end,
|
end,
|
||||||
handlers = {
|
handlers = {
|
||||||
-- Suppress signature help errors that are common with incomplete Go code
|
|
||||||
["textDocument/signatureHelp"] = function(err, result, ctx, config)
|
["textDocument/signatureHelp"] = function(err, result, ctx, config)
|
||||||
if err and string.find(err.message, "cannot get type") then
|
if err and err.message and err.message:find("cannot get type") then
|
||||||
-- Silently ignore "cannot get type" errors for signature help
|
return
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
return vim.lsp.handlers["textDocument/signatureHelp"](err, result, ctx, config)
|
return vim.lsp.handlers["textDocument/signatureHelp"](err, result, ctx, config)
|
||||||
end,
|
end,
|
||||||
|
|
@ -59,114 +59,121 @@ return {
|
||||||
usePlaceholders = true,
|
usePlaceholders = true,
|
||||||
completeUnimported = true,
|
completeUnimported = true,
|
||||||
staticcheck = true,
|
staticcheck = true,
|
||||||
directoryFilters = { "-.git", "-.vscode", "-.idea", "-.vscode-test", "-node_modules", "-dist", "-build", "-out", "-coverage", "-tmp", "-.cache" },
|
directoryFilters = {
|
||||||
|
"-.git","-.vscode","-.idea","-.vscode-test","-node_modules",
|
||||||
|
"-dist","-build","-out","-coverage","-tmp","-.cache",
|
||||||
|
},
|
||||||
semanticTokens = true,
|
semanticTokens = true,
|
||||||
-- Performance optimizations for large repositories
|
|
||||||
memoryMode = "DegradeClosed",
|
memoryMode = "DegradeClosed",
|
||||||
symbolMatcher = "FastFuzzy",
|
symbolMatcher = "FastFuzzy",
|
||||||
-- Reduce signature help noise
|
|
||||||
["ui.completion.experimentalPostfixCompletions"] = false,
|
["ui.completion.experimentalPostfixCompletions"] = false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
-- TypeScript (make sure you don't also set this up elsewhere to avoid duplicates)
|
-- ==============================
|
||||||
lspconfig.ts_ls.setup({})
|
-- TypeScript / JavaScript (ts_ls OR tsserver fallback)
|
||||||
|
-- ==============================
|
||||||
|
local ts_server = lspconfig.ts_ls or lspconfig.tsserver
|
||||||
|
if ts_server then
|
||||||
|
ts_server.setup({})
|
||||||
|
end
|
||||||
|
|
||||||
-- ✅ Templ LSP: auto-start when in a repo with go.mod or .git
|
-- ==============================
|
||||||
lspconfig.templ.setup({
|
-- Astro (guard if missing)
|
||||||
cmd = { "templ", "lsp" }, -- or absolute path if needed
|
-- ==============================
|
||||||
|
if lspconfig.astro then
|
||||||
|
local function get_typescript_lib()
|
||||||
|
local mason_ts = vim.fs.normalize(
|
||||||
|
"~/.local/share/nvim/mason/packages/typescript-language-server/node_modules/typescript/lib"
|
||||||
|
)
|
||||||
|
if vim.fn.isdirectory(mason_ts) == 1 then return mason_ts end
|
||||||
|
|
||||||
|
local global_ts = (vim.fn.system("npm root -g"):gsub("\n", "")) .. "/typescript/lib"
|
||||||
|
if vim.fn.isdirectory(global_ts) == 1 then return global_ts end
|
||||||
|
|
||||||
|
return vim.fs.normalize(
|
||||||
|
"~/.local/share/nvim/mason/packages/astro-language-server/node_modules/typescript/lib"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
lspconfig.astro.setup({
|
||||||
|
init_options = { typescript = { tsdk = get_typescript_lib() } },
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ==============================
|
||||||
|
-- templ (register config if missing)
|
||||||
|
-- ==============================
|
||||||
|
if not configs.templ then
|
||||||
|
configs.templ = {
|
||||||
|
default_config = {
|
||||||
|
cmd = { "templ", "lsp" },
|
||||||
filetypes = { "templ" },
|
filetypes = { "templ" },
|
||||||
root_dir = util.root_pattern("go.mod", ".git"),
|
root_dir = util.root_pattern("go.mod", ".git"),
|
||||||
single_file_support = true,
|
single_file_support = true,
|
||||||
})
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
lspconfig.templ.setup({})
|
||||||
|
|
||||||
-- LSP client monitoring helper
|
-- ==============================
|
||||||
vim.api.nvim_create_user_command('LspClients', function()
|
-- Utilities
|
||||||
|
-- ==============================
|
||||||
|
vim.api.nvim_create_user_command("LspClients", function()
|
||||||
local clients = vim.lsp.get_clients()
|
local clients = vim.lsp.get_clients()
|
||||||
local client_counts = {}
|
local counts = {}
|
||||||
|
for _, c in ipairs(clients) do
|
||||||
for _, client in ipairs(clients) do
|
counts[c.name] = (counts[c.name] or 0) + 1
|
||||||
client_counts[client.name] = (client_counts[client.name] or 0) + 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
print("=== Active LSP Clients ===")
|
print("=== Active LSP Clients ===")
|
||||||
for name, count in pairs(client_counts) do
|
for name, n in pairs(counts) do
|
||||||
local status = count > 1 and " ⚠️ DUPLICATE" or " ✅"
|
local dup = n > 1 and " ⚠️ DUPLICATE" or " ✅"
|
||||||
print(string.format("%s: %d client(s)%s", name, count, status))
|
print(string.format("%s: %d client(s)%s", name, n, dup))
|
||||||
end
|
end
|
||||||
|
if next(counts) == nil then print("No active LSP clients") end
|
||||||
|
end, {})
|
||||||
|
|
||||||
if next(client_counts) == nil then
|
vim.api.nvim_create_user_command("LspKillDuplicates", function()
|
||||||
print("No active LSP clients")
|
|
||||||
end
|
|
||||||
end, { desc = "Show active LSP clients and detect duplicates" })
|
|
||||||
|
|
||||||
-- Command to kill duplicate gopls clients (keep only the one with settings)
|
|
||||||
vim.api.nvim_create_user_command('LspKillDuplicates', function()
|
|
||||||
local gopls_clients = vim.lsp.get_clients({ name = "gopls" })
|
local gopls_clients = vim.lsp.get_clients({ name = "gopls" })
|
||||||
if #gopls_clients <= 1 then
|
if #gopls_clients <= 1 then
|
||||||
print("No duplicate gopls clients found")
|
print("No duplicate gopls clients found")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
local keep, kill = nil, {}
|
||||||
local client_to_keep = nil
|
for _, c in ipairs(gopls_clients) do
|
||||||
local clients_to_kill = {}
|
local cnt = 0
|
||||||
|
if c.config.settings and c.config.settings.gopls then
|
||||||
-- Find the client with the most settings (should be our configured one)
|
for _ in pairs(c.config.settings.gopls) do cnt = cnt + 1 end
|
||||||
for _, client in ipairs(gopls_clients) do
|
|
||||||
local settings_count = 0
|
|
||||||
if client.config.settings and client.config.settings.gopls then
|
|
||||||
for _ in pairs(client.config.settings.gopls) do
|
|
||||||
settings_count = settings_count + 1
|
|
||||||
end
|
end
|
||||||
|
if cnt > 0 and not keep then keep = c else table.insert(kill, c) end
|
||||||
end
|
end
|
||||||
|
for _, c in ipairs(kill) do
|
||||||
|
print(("Killing duplicate gopls client (id: %d)"):format(c.id))
|
||||||
|
c.stop(true)
|
||||||
|
end
|
||||||
|
if keep then print(("Kept gopls client (id: %d) with settings"):format(keep.id)) end
|
||||||
|
end, {})
|
||||||
|
|
||||||
if settings_count > 0 and not client_to_keep then
|
|
||||||
client_to_keep = client
|
|
||||||
else
|
|
||||||
table.insert(clients_to_kill, client)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Kill the duplicates
|
|
||||||
for _, client in ipairs(clients_to_kill) do
|
|
||||||
print(string.format("Killing duplicate gopls client (id: %d)", client.id))
|
|
||||||
client.stop(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
if client_to_keep then
|
|
||||||
print(string.format("Kept gopls client (id: %d) with settings", client_to_keep.id))
|
|
||||||
end
|
|
||||||
end, { desc = "Kill duplicate gopls clients" })
|
|
||||||
|
|
||||||
-- Safe hover helper
|
|
||||||
local function has_hover(bufnr)
|
local function has_hover(bufnr)
|
||||||
for _, c in pairs(vim.lsp.get_active_clients({ bufnr = bufnr })) do
|
for _, c in pairs(vim.lsp.get_active_clients({ bufnr = bufnr })) do
|
||||||
if c.server_capabilities and c.server_capabilities.hoverProvider then
|
if c.server_capabilities and c.server_capabilities.hoverProvider then return true end
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- LSP keymaps are handled in lsp-keymaps.lua
|
|
||||||
vim.api.nvim_create_autocmd("LspAttach", {
|
vim.api.nvim_create_autocmd("LspAttach", {
|
||||||
callback = function(args)
|
callback = function(args)
|
||||||
local bufnr = args.buf
|
local bufnr = args.buf
|
||||||
|
local lsp_keymaps = require("plugins.lsp-keymaps")
|
||||||
-- Use the centralized keymap system
|
|
||||||
local lsp_keymaps = require('plugins.lsp-keymaps')
|
|
||||||
lsp_keymaps.on_attach(nil, bufnr)
|
lsp_keymaps.on_attach(nil, bufnr)
|
||||||
|
|
||||||
-- Safe hover (keeping this custom logic)
|
|
||||||
local function buf_map(mode, lhs, rhs, desc)
|
local function buf_map(mode, lhs, rhs, desc)
|
||||||
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc })
|
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc })
|
||||||
end
|
end
|
||||||
|
|
||||||
buf_map("n", "K", function()
|
buf_map("n", "K", function()
|
||||||
if not has_hover(bufnr) then
|
if not has_hover(bufnr) then return end
|
||||||
return
|
|
||||||
end
|
|
||||||
local ok, saga_hover = pcall(require, "lspsaga.hover")
|
local ok, saga_hover = pcall(require, "lspsaga.hover")
|
||||||
if ok and saga_hover and saga_hover.render_hover_doc then
|
if ok and saga_hover and saga_hover.render_hover_doc then
|
||||||
pcall(function() saga_hover:render_hover_doc() end)
|
pcall(function() saga_hover:render_hover_doc() end)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
-- lua/plugins/mason.lua
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"williamboman/mason.nvim",
|
||||||
|
lazy = false,
|
||||||
|
config = function()
|
||||||
|
require("mason").setup()
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"williamboman/mason-lspconfig.nvim",
|
||||||
|
lazy = false,
|
||||||
|
dependencies = { "williamboman/mason.nvim" },
|
||||||
|
opts = {
|
||||||
|
ensure_installed = { "gopls", "ts_ls", "templ", "astro" },
|
||||||
|
automatic_installation = true,
|
||||||
|
automatic_setup = false, -- IMPORTANT: don't auto-setup servers
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -1,52 +1,38 @@
|
||||||
-- Format on save and linters
|
-- lua/plugins/none-ls.lua
|
||||||
return {
|
return {
|
||||||
'nvimtools/none-ls.nvim',
|
"nvimtools/none-ls.nvim",
|
||||||
|
event = { "BufReadPre", "BufNewFile" }, -- load early so it can attach
|
||||||
dependencies = {
|
dependencies = {
|
||||||
'nvimtools/none-ls-extras.nvim',
|
"williamboman/mason.nvim",
|
||||||
'gbprod/none-ls-shellcheck.nvim',
|
"jay-babu/mason-null-ls.nvim",
|
||||||
|
"nvimtools/none-ls-extras.nvim", -- optional
|
||||||
},
|
},
|
||||||
config = function()
|
config = function()
|
||||||
local null_ls = require 'null-ls'
|
local null_ls = require("null-ls")
|
||||||
local formatting = null_ls.builtins.formatting -- to setup formatters
|
|
||||||
local diagnostics = null_ls.builtins.diagnostics -- to setup linters
|
|
||||||
|
|
||||||
|
null_ls.setup({
|
||||||
|
sources = {
|
||||||
|
-- Go
|
||||||
|
null_ls.builtins.formatting.gofumpt,
|
||||||
|
null_ls.builtins.formatting.golines, -- optional
|
||||||
|
null_ls.builtins.diagnostics.golangci_lint, -- if installed
|
||||||
|
|
||||||
-- Note: Use Mason to manually install tools:
|
-- Web (keep only what you use)
|
||||||
-- :MasonInstall checkmake prettier stylua eslint_d shfmt ruff goimports
|
null_ls.builtins.formatting.prettierd,
|
||||||
|
null_ls.builtins.diagnostics.eslint_d,
|
||||||
local sources = {
|
},
|
||||||
diagnostics.checkmake,
|
})
|
||||||
formatting.prettier.with { filetypes = { 'html', 'json', 'yaml', 'markdown' } }, -- removed 'templ' for debugging
|
|
||||||
formatting.stylua,
|
require("mason-null-ls").setup({
|
||||||
formatting.shfmt.with { args = { '-i', '4' } },
|
ensure_installed = { "gofumpt", "golines", "golangci-lint", "prettierd", "eslint_d" },
|
||||||
require('none-ls.formatting.ruff').with { extra_args = { '--extend-select', 'I' } },
|
automatic_installation = true,
|
||||||
require 'none-ls.formatting.ruff_format',
|
})
|
||||||
formatting.goimports, -- Add goimports for Go files
|
|
||||||
}
|
-- (optional) format on save for Go
|
||||||
|
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||||
local augroup = vim.api.nvim_create_augroup('LspFormatting', {})
|
pattern = "*.go",
|
||||||
null_ls.setup {
|
callback = function() vim.lsp.buf.format({ async = false }) end,
|
||||||
debug = false, -- Disable debug mode to reduce log spam
|
|
||||||
sources = sources,
|
|
||||||
-- you can reuse a shared lspconfig on_attach callback here
|
|
||||||
on_attach = function(client, bufnr)
|
|
||||||
if client.supports_method 'textDocument/formatting' then
|
|
||||||
-- Skip formatting for .templ files during debugging
|
|
||||||
local filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype')
|
|
||||||
if filetype == 'templ' then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_clear_autocmds { group = augroup, buffer = bufnr }
|
|
||||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
|
||||||
group = augroup,
|
|
||||||
buffer = bufnr,
|
|
||||||
callback = function()
|
|
||||||
vim.lsp.buf.format { async = false }
|
|
||||||
end,
|
|
||||||
})
|
})
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
-- Highlight, edit, and navigate code
|
|
||||||
return {
|
return {
|
||||||
'nvim-treesitter/nvim-treesitter',
|
'nvim-treesitter/nvim-treesitter',
|
||||||
build = ':TSUpdate',
|
build = ':TSUpdate',
|
||||||
|
|
@ -98,7 +98,6 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Register additional file extensions
|
-- Register additional file extensions
|
||||||
vim.filetype.add { extension = { tf = 'terraform' } }
|
vim.filetype.add { extension = { tf = 'terraform' } }
|
||||||
vim.filetype.add { extension = { tfvars = 'terraform' } }
|
vim.filetype.add { extension = { tfvars = 'terraform' } }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
return {
|
||||||
|
'treesitter-context',
|
||||||
|
setup{
|
||||||
|
enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
|
||||||
|
multiwindow = false, -- Enable multiwindow support.
|
||||||
|
max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
|
||||||
|
min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
|
||||||
|
line_numbers = true,
|
||||||
|
multiline_threshold = 20, -- Maximum number of lines to show for a single context
|
||||||
|
trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
|
||||||
|
mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline'
|
||||||
|
-- Separator between context and content. Should be a single character string, like '-'.
|
||||||
|
-- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
|
||||||
|
separator = nil,
|
||||||
|
zindex = 20, -- The Z-index of the context window
|
||||||
|
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue