forgot to push this... lots of changes to add elixir support and other fixes
This commit is contained in:
parent
f6a19a3a75
commit
06d714c945
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"stylua.targetReleaseVersion": "latest"
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,9 @@ vim.g.maplocalleader = ' '
|
||||||
-- - Line/selection movement (Alt + jk)
|
-- - Line/selection movement (Alt + jk)
|
||||||
-- - Quick save and quit (<leader>w, <leader>W, <leader>Q)
|
-- - Quick save and quit (<leader>w, <leader>W, <leader>Q)
|
||||||
local core_keymaps = {
|
local core_keymaps = {
|
||||||
|
-- Quick access to find files by content (shortcut for <leader>sg)
|
||||||
|
{ mode = 'n', lhs = '<leader><space>', rhs = function() require('telescope.builtin').live_grep() end, opts = { desc = 'Search text in all files' } },
|
||||||
|
|
||||||
-- Clear highlights on search when pressing <Esc> in normal mode
|
-- Clear highlights on search when pressing <Esc> in normal mode
|
||||||
{ mode = 'n', lhs = '<Esc>', rhs = '<cmd>nohlsearch<CR>', opts = { desc = 'Clear search highlights' } },
|
{ mode = 'n', lhs = '<Esc>', rhs = '<cmd>nohlsearch<CR>', opts = { desc = 'Clear search highlights' } },
|
||||||
|
|
||||||
|
|
@ -70,8 +73,38 @@ function M.setup_lsp_keymaps(bufnr)
|
||||||
{ mode = 'n', lhs = 'gy', rhs = function() require('telescope.builtin').lsp_type_definitions() end, opts = { desc = 'LSP: Go to type definition' } },
|
{ mode = 'n', lhs = 'gy', rhs = function() require('telescope.builtin').lsp_type_definitions() end, opts = { desc = 'LSP: Go to type definition' } },
|
||||||
|
|
||||||
-- Symbol navigation
|
-- Symbol navigation
|
||||||
{ mode = 'n', lhs = '<leader>ls', rhs = function() require('telescope.builtin').lsp_document_symbols() end, opts = { desc = 'LSP: Document symbols' } },
|
{ mode = 'n', lhs = '<leader>ls', rhs = function()
|
||||||
{ mode = 'n', lhs = '<leader>lS', rhs = function() require('telescope.builtin').lsp_dynamic_workspace_symbols() end, opts = { desc = 'LSP: Workspace symbols' } },
|
-- Explicitly add position_encoding to fix symbols_to_items error
|
||||||
|
require('telescope.builtin').lsp_document_symbols({ position_encoding = 'utf-16' })
|
||||||
|
end, opts = { desc = 'LSP: Document symbols' } },
|
||||||
|
{ mode = 'n', lhs = '<leader>lS', rhs = function()
|
||||||
|
-- Use a safe wrapper to avoid nil indexing errors
|
||||||
|
local status_ok, _ = pcall(function()
|
||||||
|
require('telescope.builtin').lsp_dynamic_workspace_symbols({
|
||||||
|
position_encoding = 'utf-16',
|
||||||
|
show_line = true,
|
||||||
|
fname_width = 50,
|
||||||
|
symbol_width = 35,
|
||||||
|
attach_mappings = function(prompt_bufnr)
|
||||||
|
-- This prevents errors when no results are found
|
||||||
|
require("telescope.actions").select_default:replace(function()
|
||||||
|
local entry = require("telescope.actions.state").get_selected_entry()
|
||||||
|
if not entry then return end
|
||||||
|
require("telescope.actions").close(prompt_bufnr)
|
||||||
|
if entry.value and entry.value.filename then
|
||||||
|
vim.cmd(string.format('edit %s', entry.value.filename))
|
||||||
|
vim.api.nvim_win_set_cursor(0, {entry.value.lnum, entry.value.col})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
if not status_ok then
|
||||||
|
vim.notify("Workspace symbols not available for this language server", vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
end, opts = { desc = 'LSP: Workspace symbols' } },
|
||||||
|
|
||||||
-- Code actions
|
-- Code actions
|
||||||
{ mode = 'n', lhs = '<leader>lr', rhs = vim.lsp.buf.rename, opts = { desc = 'LSP: Rename symbol' } },
|
{ mode = 'n', lhs = '<leader>lr', rhs = vim.lsp.buf.rename, opts = { desc = 'LSP: Rename symbol' } },
|
||||||
|
|
@ -79,7 +112,7 @@ function M.setup_lsp_keymaps(bufnr)
|
||||||
{ mode = 'n', lhs = '<leader>lf', rhs = function() vim.lsp.buf.format({ async = true }) end, opts = { desc = 'LSP: Format code' } },
|
{ mode = 'n', lhs = '<leader>lf', rhs = function() vim.lsp.buf.format({ async = true }) end, opts = { desc = 'LSP: Format code' } },
|
||||||
|
|
||||||
-- Documentation
|
-- Documentation
|
||||||
{ mode = 'n', lhs = 'K', rhs = vim.lsp.buf.hover, opts = { desc = 'LSP: Show documentation' } },
|
{ mode = 'n', lhs = 'K', rhs = function() require('hover').hover() end, opts = { desc = 'Enhanced documentation (hover.nvim)' } },
|
||||||
}
|
}
|
||||||
|
|
||||||
-- First clear any existing LSP keymaps for this buffer
|
-- First clear any existing LSP keymaps for this buffer
|
||||||
|
|
@ -162,8 +195,9 @@ M.diagnostic_keymaps = {
|
||||||
{ mode = 'n', lhs = ']d', rhs = vim.diagnostic.goto_next, opts = { desc = 'Diagnostic: Next' } },
|
{ mode = 'n', lhs = ']d', rhs = vim.diagnostic.goto_next, opts = { desc = 'Diagnostic: Next' } },
|
||||||
|
|
||||||
-- Viewing diagnostics
|
-- Viewing diagnostics
|
||||||
{ mode = 'n', lhs = '<leader>tt', rhs = vim.diagnostic.open_float, opts = { desc = 'Diagnostic: Show details' } },
|
{ mode = 'n', lhs = '<leader>tt', rhs = vim.diagnostic.open_float, opts = { desc = 'Diagnostic: Show details in float' } },
|
||||||
{ mode = 'n', lhs = '<leader>tl', rhs = vim.diagnostic.setloclist, opts = { desc = 'Diagnostic: Show list' } },
|
{ mode = 'n', lhs = '<leader>tl', rhs = vim.diagnostic.setloclist, opts = { desc = 'Diagnostic: Show list' } },
|
||||||
|
{ mode = 'n', lhs = '<leader>td', rhs = function() require('telescope.builtin').diagnostics() end, opts = { desc = 'Diagnostic: Search all diagnostics' } },
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Database keymaps (all under <leader>D for Database)
|
-- Database keymaps (all under <leader>D for Database)
|
||||||
|
|
@ -223,12 +257,31 @@ M.scratch_keymaps = {
|
||||||
-- - <C-/>: Toggle terminal in float window
|
-- - <C-/>: Toggle terminal in float window
|
||||||
M.snacks_keymaps = {
|
M.snacks_keymaps = {
|
||||||
-- Explorer
|
-- Explorer
|
||||||
{ mode = 'n', lhs = '<leader>e', rhs = function() require('snacks.picker').explorer() end, opts = { desc = 'Explorer: Toggle' } },
|
{ mode = 'n', lhs = '<leader>e', rhs = function()
|
||||||
{ mode = 'n', lhs = '<leader>E', rhs = function() require('snacks.picker').explorer({ reveal = true }) end, opts = { desc = 'Explorer: Focus current file' } },
|
-- Open explorer in current window
|
||||||
{ mode = 'n', lhs = '<leader>o', rhs = function() require('snacks.picker').explorer({ reveal = true }) end, opts = { desc = 'Explorer: Focus current file' } },
|
require('snacks').explorer.open()
|
||||||
|
end, opts = { desc = 'Explorer: Toggle' } },
|
||||||
|
|
||||||
|
{ mode = 'n', lhs = '<leader>E', rhs = function()
|
||||||
|
-- Reveal current file in explorer
|
||||||
|
require('snacks').explorer.reveal()
|
||||||
|
end, opts = { desc = 'Explorer: Focus current file' } },
|
||||||
|
|
||||||
|
{ mode = 'n', lhs = '<leader>o', rhs = function()
|
||||||
|
-- Open current file in a new tab and focus it
|
||||||
|
vim.cmd('tab split %')
|
||||||
|
end, opts = { desc = 'Open current file in new tab' } },
|
||||||
|
|
||||||
|
-- Custom function to open explorer files in new tabs
|
||||||
|
{ mode = 'n', lhs = '<leader>f', rhs = function()
|
||||||
|
-- Open explorer in a new tab
|
||||||
|
vim.cmd('tabnew')
|
||||||
|
require('snacks').explorer.open()
|
||||||
|
end, opts = { desc = 'Explorer: Open in new tab' } },
|
||||||
|
|
||||||
-- Terminal
|
-- Terminal
|
||||||
{ mode = 'n', lhs = '<C-/>', rhs = function() require('snacks').terminal.toggle() end, opts = { desc = 'Terminal: Toggle float window' } },
|
{ mode = 'n', lhs = '<C-/>', rhs = function() require('snacks').terminal.toggle() end, opts = { desc = 'Terminal: Toggle float window' } },
|
||||||
|
{ mode = 'n', lhs = '<leader>tc', rhs = function() require('snacks').terminal.toggle() end, opts = { desc = 'Terminal: Toggle console' } },
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Git signs keymaps (all under <leader>g for Git)
|
-- Git signs keymaps (all under <leader>g for Git)
|
||||||
|
|
@ -277,6 +330,35 @@ function M.setup_gitsigns_keymaps()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Elixir keymaps (using 'x' as the prefix - mnemonic for 'eXlixir')
|
||||||
|
M.elixir_keymaps = {
|
||||||
|
{ mode = 'n', lhs = '<leader>xt',
|
||||||
|
rhs = function()
|
||||||
|
require('elixir').run_test_file()
|
||||||
|
end,
|
||||||
|
opts = { desc = 'Elixir: Test file' }
|
||||||
|
},
|
||||||
|
{ mode = 'n', lhs = '<leader>xn',
|
||||||
|
rhs = function()
|
||||||
|
require('elixir').run_nearest_test()
|
||||||
|
end,
|
||||||
|
opts = { desc = 'Elixir: Test nearest' }
|
||||||
|
},
|
||||||
|
{ mode = 'n', lhs = '<leader>xm',
|
||||||
|
rhs = function()
|
||||||
|
vim.cmd('Telescope elixir mix')
|
||||||
|
end,
|
||||||
|
opts = { desc = 'Elixir: Mix tasks' }
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Set up Elixir keymaps
|
||||||
|
function M.setup_elixir_keymaps()
|
||||||
|
for _, mapping in ipairs(M.elixir_keymaps or {}) do
|
||||||
|
vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Leap keymaps
|
-- Leap keymaps
|
||||||
-- 's' for bidirectional search (both forward and backward)
|
-- 's' for bidirectional search (both forward and backward)
|
||||||
-- 'S' for searching in all windows
|
-- 'S' for searching in all windows
|
||||||
|
|
@ -327,7 +409,7 @@ local function init_keymaps()
|
||||||
callback = function()
|
callback = function()
|
||||||
-- Pause snacks explorer updates during write
|
-- Pause snacks explorer updates during write
|
||||||
pcall(function()
|
pcall(function()
|
||||||
local picker = require('snacks.picker')
|
local picker = require('plugins.snacks.picker')
|
||||||
if picker.is_open() then
|
if picker.is_open() then
|
||||||
picker.pause_updates()
|
picker.pause_updates()
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
|
|
@ -406,12 +488,19 @@ local function init_keymaps()
|
||||||
-- Set up database keymaps
|
-- Set up database keymaps
|
||||||
M.setup_dadbod_keymaps()
|
M.setup_dadbod_keymaps()
|
||||||
|
|
||||||
|
-- Set up default tab navigation
|
||||||
|
vim.keymap.set('n', 'gt', ':tabnext<CR>', { silent = true, desc = 'Next tab' })
|
||||||
|
vim.keymap.set('n', 'gT', ':tabprevious<CR>', { silent = true, desc = 'Previous tab' })
|
||||||
|
|
||||||
-- Set up session keymaps
|
-- Set up session keymaps
|
||||||
M.setup_session_keymaps()
|
M.setup_session_keymaps()
|
||||||
|
|
||||||
-- Set up git signs keymaps
|
-- Set up git signs keymaps
|
||||||
M.setup_gitsigns_keymaps()
|
M.setup_gitsigns_keymaps()
|
||||||
|
|
||||||
|
-- Set up Elixir keymaps
|
||||||
|
M.setup_elixir_keymaps()
|
||||||
|
|
||||||
-- Set up leap keymaps
|
-- Set up leap keymaps
|
||||||
M.setup_leap_keymaps()
|
M.setup_leap_keymaps()
|
||||||
end
|
end
|
||||||
|
|
@ -422,5 +511,29 @@ init_keymaps()
|
||||||
-- Export `init_keymaps` as `M.setup` so `require('core.keymaps').setup()` works
|
-- Export `init_keymaps` as `M.setup` so `require('core.keymaps').setup()` works
|
||||||
M.setup = init_keymaps
|
M.setup = init_keymaps
|
||||||
|
|
||||||
|
-- Mini-surround keymaps
|
||||||
|
-- These define how mini.surround plugin works with text objects
|
||||||
|
-- sa - add surroundings (visual mode or with motion like saiw)
|
||||||
|
-- sd - delete surroundings
|
||||||
|
-- sr - replace surroundings
|
||||||
|
-- sn - Find next surrounding
|
||||||
|
-- sN - Find previous surrounding
|
||||||
|
-- sh - Highlight surrounding
|
||||||
|
-- sf - Find surrounding (to use with textobject)
|
||||||
|
-- ss - Go to left surrounding
|
||||||
|
-- sS - Go to right surrounding
|
||||||
|
M.mini_surround_keymaps = {
|
||||||
|
add = 'sa', -- Add surrounding in Normal and Visual modes
|
||||||
|
delete = 'sd', -- Delete surrounding
|
||||||
|
find = 'sf', -- Find surrounding (to the right)
|
||||||
|
find_left = 'sF', -- Find surrounding (to the left)
|
||||||
|
highlight = 'sh', -- Highlight surrounding
|
||||||
|
replace = 'sr', -- Replace surrounding
|
||||||
|
update_n_lines = '', -- Update `n_lines`
|
||||||
|
|
||||||
|
suffix_last = 'l', -- Suffix to search with 'prev' method
|
||||||
|
suffix_next = 'n', -- Suffix to search with 'next' method
|
||||||
|
}
|
||||||
|
|
||||||
-- Return the module
|
-- Return the module
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,58 @@ function M.setup()
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Auto format Go files on save
|
|
||||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
-- Add a smart format-on-save command that only uses null-ls
|
||||||
pattern = '*.go',
|
-- Fix for zig.vim ftplugin error - handles both JSON and struct output
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
pattern = 'zig',
|
||||||
|
group = vim.api.nvim_create_augroup('user-zig-fix', { clear = true }),
|
||||||
callback = function()
|
callback = function()
|
||||||
vim.lsp.buf.format({ async = false })
|
if vim.fn.executable('zig') ~= 1 or vim.g.zig_std_dir then return end
|
||||||
|
|
||||||
|
-- First try with --json flag
|
||||||
|
local handle = io.popen('zig env --json 2>/dev/null')
|
||||||
|
if handle then
|
||||||
|
local result = handle:read('*a')
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
-- Try to parse as JSON first
|
||||||
|
local success, env = pcall(vim.fn.json_decode, result)
|
||||||
|
if success and type(env) == 'table' and env.std_dir then
|
||||||
|
vim.g.zig_std_dir = env.std_dir
|
||||||
|
vim.opt_local.path:prepend(env.std_dir)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If JSON parsing failed, try to parse the struct output
|
||||||
|
handle = io.popen('zig env 2>/dev/null')
|
||||||
|
if handle then
|
||||||
|
local result = handle:read('*a')
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
-- Extract std_dir from struct output
|
||||||
|
local std_dir = result:match('%.std_dir%s*=%s*"([^"]+)"')
|
||||||
|
if std_dir then
|
||||||
|
vim.g.zig_std_dir = std_dir
|
||||||
|
vim.opt_local.path:prepend(std_dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Auto format Zig files on save
|
|
||||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||||
pattern = '*.zig',
|
pattern = '*',
|
||||||
callback = function()
|
callback = function(args)
|
||||||
vim.lsp.buf.format({ async = false })
|
local bufnr = args.buf
|
||||||
|
-- Check if null-ls is the formatter for this buffer
|
||||||
|
local client = vim.lsp.get_clients({ name = 'null-ls', bufnr = bufnr })[1]
|
||||||
|
if not client then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Format the buffer
|
||||||
|
vim.lsp.buf.format({ bufnr = bufnr, filter = function(c) return c.name == 'null-ls' end, async = false })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
---@diagnostic disable: undefined-global
|
||||||
|
-- Direct approach to fix hover documentation with custom function
|
||||||
|
return {
|
||||||
|
"neovim/nvim-lspconfig",
|
||||||
|
config = function()
|
||||||
|
-- Create a direct standalone hover function
|
||||||
|
local function better_hover()
|
||||||
|
-- Save original functions we'll temporarily override
|
||||||
|
local orig_open_floating = vim.lsp.util.open_floating_preview
|
||||||
|
|
||||||
|
-- Replace the floating preview function temporarily
|
||||||
|
vim.lsp.util.open_floating_preview = function(contents, syntax, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
-- Force nicer styling
|
||||||
|
opts.border = "rounded"
|
||||||
|
opts.max_width = math.min(math.floor(vim.o.columns * 0.7), 80)
|
||||||
|
opts.max_height = math.floor(vim.o.lines * 0.3)
|
||||||
|
|
||||||
|
-- Process contents to remove separator lines and improve formatting
|
||||||
|
local cleaned_contents = {}
|
||||||
|
for _, line in ipairs(contents) do
|
||||||
|
-- Skip separator lines
|
||||||
|
if not line:match("^%-%-%-%-+$") then
|
||||||
|
table.insert(cleaned_contents, line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call original with improved options and cleaned content
|
||||||
|
local bufnr, winnr = orig_open_floating(cleaned_contents, syntax, opts)
|
||||||
|
|
||||||
|
-- Enhance the created buffer
|
||||||
|
if bufnr and winnr then
|
||||||
|
-- Set better options for the window
|
||||||
|
vim.api.nvim_win_set_option(winnr, "conceallevel", 2)
|
||||||
|
vim.api.nvim_win_set_option(winnr, "foldenable", false)
|
||||||
|
|
||||||
|
-- If it's markdown, ensure proper highlighting
|
||||||
|
if syntax == "markdown" then
|
||||||
|
vim.api.nvim_buf_set_option(bufnr, "filetype", "markdown")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return bufnr, winnr
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call the regular hover function with our temporary override
|
||||||
|
vim.lsp.buf.hover()
|
||||||
|
|
||||||
|
-- Restore original function
|
||||||
|
vim.lsp.util.open_floating_preview = orig_open_floating
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Directly override the K keymap - this bypasses any conflicts
|
||||||
|
vim.keymap.set("n", "K", better_hover, { noremap = true, silent = true, desc = "LSP: Better hover docs" })
|
||||||
|
end,
|
||||||
|
-- Run this after all other LSP configs are loaded
|
||||||
|
priority = 999,
|
||||||
|
}
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
return {
|
|
||||||
'saghen/blink.cmp',
|
|
||||||
dependencies = 'rafamadriz/friendly-snippets',
|
|
||||||
version = '*',
|
|
||||||
opts = {
|
|
||||||
keymap = { preset = 'default' },
|
|
||||||
appearance = {
|
|
||||||
use_nvim_cmp_as_default = true,
|
|
||||||
nerd_font_variant = 'mono',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -5,6 +5,8 @@ local M = {}
|
||||||
function M.setup()
|
function M.setup()
|
||||||
local cmp = require 'cmp'
|
local cmp = require 'cmp'
|
||||||
local luasnip = require 'luasnip'
|
local luasnip = require 'luasnip'
|
||||||
|
local types = require 'cmp.types'
|
||||||
|
local compare = require 'cmp.config.compare'
|
||||||
luasnip.config.setup {}
|
luasnip.config.setup {}
|
||||||
|
|
||||||
cmp.setup {
|
cmp.setup {
|
||||||
|
|
@ -13,13 +15,127 @@ function M.setup()
|
||||||
luasnip.lsp_expand(args.body)
|
luasnip.lsp_expand(args.body)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
completion = { completeopt = 'menu,menuone,noinsert' },
|
-- Improved completion settings - more like VSCode
|
||||||
|
completion = {
|
||||||
|
completeopt = 'menu,menuone,noinsert',
|
||||||
|
keyword_length = 1, -- Show completions after 1 character
|
||||||
|
autocomplete = { types.cmp.TriggerEvent.TextChanged },
|
||||||
|
get_trigger_characters = function(trigger_characters)
|
||||||
|
-- Always add '.' as a trigger character to ensure method/property completions
|
||||||
|
if not vim.tbl_contains(trigger_characters, '.') then
|
||||||
|
table.insert(trigger_characters, '.')
|
||||||
|
end
|
||||||
|
if not vim.tbl_contains(trigger_characters, ':') then
|
||||||
|
table.insert(trigger_characters, ':')
|
||||||
|
end
|
||||||
|
return trigger_characters
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
-- Custom sorting to prioritize fields and methods over snippets
|
||||||
|
sorting = {
|
||||||
|
priority_weight = 10, -- Increase weight to make priority differences more significant
|
||||||
|
comparators = {
|
||||||
|
-- Custom comparator that puts snippets at the end
|
||||||
|
function(entry1, entry2)
|
||||||
|
local types = require('cmp.types')
|
||||||
|
|
||||||
|
-- Extract the kinds
|
||||||
|
local kind1 = entry1:get_kind()
|
||||||
|
local kind2 = entry2:get_kind()
|
||||||
|
|
||||||
|
-- Define snippet kinds
|
||||||
|
local snippet_kinds = {
|
||||||
|
[types.lsp.CompletionItemKind.Snippet] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Check if either is a snippet
|
||||||
|
local is_snippet1 = snippet_kinds[kind1] or false
|
||||||
|
local is_snippet2 = snippet_kinds[kind2] or false
|
||||||
|
|
||||||
|
-- If one is a snippet and the other isn't, the non-snippet comes first
|
||||||
|
if is_snippet1 and not is_snippet2 then
|
||||||
|
return false
|
||||||
|
elseif not is_snippet1 and is_snippet2 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Otherwise fall through to other comparators
|
||||||
|
return nil
|
||||||
|
end,
|
||||||
|
compare.exact, -- Exact match first
|
||||||
|
compare.kind, -- Sort by kind (functions first, then properties, etc)
|
||||||
|
compare.sort_text, -- Sort by LSP's sortText
|
||||||
|
compare.score, -- Score based
|
||||||
|
compare.offset, -- Closest to cursor
|
||||||
|
compare.length, -- Shorter first
|
||||||
|
compare.order, -- Source order
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- Enhanced VSCode-like icons with more modern symbols
|
||||||
|
formatting = {
|
||||||
|
format = function(entry, vim_item)
|
||||||
|
-- Set icons for completion types
|
||||||
|
local kind_icons = {
|
||||||
|
Text = "", Method = "", Function = "", Constructor = "",
|
||||||
|
Field = "", Variable = "", Class = "", Interface = "",
|
||||||
|
Module = "", Property = "", Unit = "", Value = "",
|
||||||
|
Enum = "", Keyword = "", Snippet = "", Color = "",
|
||||||
|
File = "", Reference = "", Folder = "", EnumMember = "",
|
||||||
|
Constant = "", Struct = "", Event = "", Operator = "",
|
||||||
|
TypeParameter = "", TypeAlias = "", Parameter = "", StaticMethod = "",
|
||||||
|
Macro = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Enhanced formatting with better icons and spacing
|
||||||
|
vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind] or '', vim_item.kind)
|
||||||
|
|
||||||
|
-- Show more detailed source info
|
||||||
|
vim_item.menu = ({
|
||||||
|
buffer = "[Buffer]",
|
||||||
|
nvim_lsp = "[LSP]",
|
||||||
|
luasnip = "[Snippet]",
|
||||||
|
path = "[Path]",
|
||||||
|
})[entry.source.name]
|
||||||
|
|
||||||
|
return vim_item
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
-- Enhanced documentation window
|
||||||
|
window = {
|
||||||
|
completion = cmp.config.window.bordered({
|
||||||
|
winhighlight = "Normal:CmpPmenu,FloatBorder:CmpPmenuBorder,CursorLine:PmenuSel,Search:None",
|
||||||
|
scrollbar = true,
|
||||||
|
col_offset = -3,
|
||||||
|
side_padding = 1,
|
||||||
|
}),
|
||||||
|
documentation = cmp.config.window.bordered({
|
||||||
|
winhighlight = "Normal:CmpDoc",
|
||||||
|
}),
|
||||||
|
},
|
||||||
mapping = cmp.mapping.preset.insert {
|
mapping = cmp.mapping.preset.insert {
|
||||||
['<C-n>'] = cmp.mapping.select_next_item(),
|
['<C-n>'] = cmp.mapping.select_next_item(),
|
||||||
['<C-p>'] = cmp.mapping.select_prev_item(),
|
['<C-p>'] = cmp.mapping.select_prev_item(),
|
||||||
['<C-b>'] = cmp.mapping.scroll_docs(-4),
|
['<C-b>'] = cmp.mapping.scroll_docs(-4),
|
||||||
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
||||||
['<C-y>'] = cmp.mapping.confirm { select = true },
|
['<C-y>'] = cmp.mapping.confirm { select = true },
|
||||||
|
['<Tab>'] = cmp.mapping(function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_next_item()
|
||||||
|
elseif luasnip.expand_or_locally_jumpable() then
|
||||||
|
luasnip.expand_or_jump()
|
||||||
|
else
|
||||||
|
fallback()
|
||||||
|
end
|
||||||
|
end, { 'i', 's' }),
|
||||||
|
['<S-Tab>'] = cmp.mapping(function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_prev_item()
|
||||||
|
elseif luasnip.locally_jumpable(-1) then
|
||||||
|
luasnip.jump(-1)
|
||||||
|
else
|
||||||
|
fallback()
|
||||||
|
end
|
||||||
|
end, { 'i', 's' }),
|
||||||
['<C-Space>'] = cmp.mapping.complete {},
|
['<C-Space>'] = cmp.mapping.complete {},
|
||||||
['<C-l>'] = cmp.mapping(function()
|
['<C-l>'] = cmp.mapping(function()
|
||||||
if luasnip.expand_or_locally_jumpable() then
|
if luasnip.expand_or_locally_jumpable() then
|
||||||
|
|
@ -32,30 +148,112 @@ function M.setup()
|
||||||
end
|
end
|
||||||
end, { 'i', 's' }),
|
end, { 'i', 's' }),
|
||||||
},
|
},
|
||||||
sources = {
|
-- Configure completion sources by priority with tweaked settings
|
||||||
{ name = 'lazydev', group_index = 0 },
|
sources = cmp.config.sources(
|
||||||
{ name = 'nvim_lsp' },
|
{
|
||||||
{ name = 'luasnip' },
|
{ name = 'nvim_lsp', priority = 1000, max_item_count = 50 }, -- LSP comes first with more items
|
||||||
{ name = 'path' },
|
{ name = 'path', priority = 500 }, -- Then paths
|
||||||
{ name = 'buffer' },
|
{ name = 'buffer', priority = 250, keyword_length = 3 }, -- Then current buffer
|
||||||
|
-- Snippets with extremely low priority and limited visibility
|
||||||
|
{ name = 'luasnip', priority = 10, max_item_count = 3, keyword_length = 4 },
|
||||||
|
}
|
||||||
|
),
|
||||||
|
-- Enable experimental features for VSCode-like experience
|
||||||
|
experimental = {
|
||||||
|
ghost_text = true, -- Shows virtual text as preview
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Cmdline completion for search (/, ?) and command (:)
|
-- Cmdline completion for search (/, ?) and command (:)
|
||||||
|
-- Enhanced commandline completion with better history and formatting
|
||||||
cmp.setup.cmdline({ '/', '?' }, {
|
cmp.setup.cmdline({ '/', '?' }, {
|
||||||
mapping = cmp.mapping.preset.cmdline(),
|
mapping = cmp.mapping.preset.cmdline(),
|
||||||
sources = {
|
sources = {
|
||||||
{ name = 'buffer' }
|
{ name = 'buffer', max_item_count = 20 }
|
||||||
|
},
|
||||||
|
window = {
|
||||||
|
completion = cmp.config.window.bordered({
|
||||||
|
winhighlight = "Normal:CmpPmenu,FloatBorder:CmpPmenuBorder,CursorLine:PmenuSel,Search:None",
|
||||||
|
scrollbar = true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
completion = {
|
||||||
|
completeopt = 'menu,menuone,noinsert',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
cmp.setup.cmdline(':', {
|
cmp.setup.cmdline(':', {
|
||||||
mapping = cmp.mapping.preset.cmdline(),
|
mapping = cmp.mapping.preset.cmdline({
|
||||||
|
-- Explicit key mappings for command mode completion
|
||||||
|
['<Tab>'] = {
|
||||||
|
c = function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_next_item()
|
||||||
|
else
|
||||||
|
cmp.complete()
|
||||||
|
cmp.select_next_item()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
['<S-Tab>'] = {
|
||||||
|
c = function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_prev_item()
|
||||||
|
else
|
||||||
|
cmp.complete()
|
||||||
|
cmp.select_prev_item()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
['<C-n>'] = {
|
||||||
|
c = function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_next_item()
|
||||||
|
else
|
||||||
|
cmp.complete()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
['<C-p>'] = {
|
||||||
|
c = function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_prev_item()
|
||||||
|
else
|
||||||
|
cmp.complete()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
['<C-e>'] = {
|
||||||
|
c = cmp.mapping.abort(),
|
||||||
|
},
|
||||||
|
['<CR>'] = {
|
||||||
|
c = cmp.mapping.confirm({ select = true }),
|
||||||
|
},
|
||||||
|
}),
|
||||||
sources = cmp.config.sources({
|
sources = cmp.config.sources({
|
||||||
{ name = 'path' }
|
{ name = 'path', max_item_count = 20 },
|
||||||
}, {
|
{ name = 'cmdline', max_item_count = 30, keyword_length = 1 }
|
||||||
{ name = 'cmdline' }
|
}),
|
||||||
|
window = {
|
||||||
|
completion = cmp.config.window.bordered({
|
||||||
|
winhighlight = "Normal:CmpPmenu,FloatBorder:CmpPmenuBorder,CursorLine:PmenuSel,Search:None",
|
||||||
|
scrollbar = true,
|
||||||
|
col_offset = -3,
|
||||||
|
side_padding = 1,
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
formatting = {
|
||||||
|
format = function(entry, vim_item)
|
||||||
|
-- Only show item kind for cmdline completion
|
||||||
|
vim_item.kind = ' '
|
||||||
|
vim_item.menu = ''
|
||||||
|
return vim_item
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
completion = {
|
||||||
|
completeopt = 'menu,menuone,noinsert',
|
||||||
|
autocomplete = { cmp.TriggerEvent.TextChanged },
|
||||||
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@ return {
|
||||||
require('plugins.coding.zig'),
|
require('plugins.coding.zig'),
|
||||||
require('plugins.coding.clangd'),
|
require('plugins.coding.clangd'),
|
||||||
require('plugins.coding.dap'),
|
require('plugins.coding.dap'),
|
||||||
|
require('plugins.coding.elixir'),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,16 @@
|
||||||
---@diagnostic disable: undefined-global
|
---@diagnostic disable: undefined-global
|
||||||
return {
|
return {
|
||||||
"mfussenegger/nvim-dap",
|
"mfussenegger/nvim-dap",
|
||||||
|
keys = {
|
||||||
|
{ "<leader>pb", desc = "Toggle [B]reakpoint" },
|
||||||
|
{ "<leader>pc", desc = "[C]ontinue debugging" },
|
||||||
|
{ "<leader>pn", desc = "Step over ([N]ext)" },
|
||||||
|
{ "<leader>pi", desc = "Step [I]nto" },
|
||||||
|
{ "<leader>po", desc = "Step [O]ut" },
|
||||||
|
{ "<leader>pr", desc = "Open [R]EPL" },
|
||||||
|
{ "<leader>pl", desc = "Run [L]ast debug session" },
|
||||||
|
{ "<leader>px", desc = "Toggle debug UI" },
|
||||||
|
},
|
||||||
dependencies = {
|
dependencies = {
|
||||||
"rcarriga/nvim-dap-ui",
|
"rcarriga/nvim-dap-ui",
|
||||||
"theHamsta/nvim-dap-virtual-text",
|
"theHamsta/nvim-dap-virtual-text",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
'elixir-tools/elixir-tools.nvim',
|
||||||
|
version = '*',
|
||||||
|
ft = { 'ex', 'exs', 'heex', 'eex', 'elixir' },
|
||||||
|
dependencies = {
|
||||||
|
'neovim/nvim-lspconfig',
|
||||||
|
'nvim-lua/plenary.nvim',
|
||||||
|
},
|
||||||
|
config = function()
|
||||||
|
local elixir = require('elixir')
|
||||||
|
|
||||||
|
-- Configure elixir-tools with LSP disabled (handled by lspconfig)
|
||||||
|
elixir.setup({
|
||||||
|
-- Disable the built-in LSP client to avoid conflicts
|
||||||
|
elixirls = { enable = false },
|
||||||
|
|
||||||
|
-- Enable non-LSP features
|
||||||
|
credo = { enable = true },
|
||||||
|
projectionist = { enable = true },
|
||||||
|
|
||||||
|
-- Configure the test runner
|
||||||
|
test_runner = {
|
||||||
|
enabled = true,
|
||||||
|
runner = 'exunit', -- or 'exunit_individual' for individual test runs
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Enable mix integration
|
||||||
|
mix = {
|
||||||
|
enabled = true,
|
||||||
|
format_on_save = false, -- Disabled to prevent file changed warnings
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Keymaps are now in core/keymaps.lua with <leader>lx prefix
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
---@diagnostic disable: undefined-global
|
||||||
|
-- Test doc window plugin
|
||||||
|
return {
|
||||||
|
"neovim/nvim-lspconfig",
|
||||||
|
config = function()
|
||||||
|
-- Create a test function that shows a styled floating window
|
||||||
|
local function test_doc_window()
|
||||||
|
local contents = {
|
||||||
|
"## Documentation Test",
|
||||||
|
"",
|
||||||
|
"This is a test documentation window to see how styling works.",
|
||||||
|
"",
|
||||||
|
"**Important**: This shows what documentation *should* look like.",
|
||||||
|
"",
|
||||||
|
"```lua",
|
||||||
|
"function example(param)",
|
||||||
|
" -- This is a code sample",
|
||||||
|
" return param + 1",
|
||||||
|
"end",
|
||||||
|
"```",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Create a nicely styled window
|
||||||
|
local opts = {
|
||||||
|
border = "rounded",
|
||||||
|
width = 60,
|
||||||
|
height = 12,
|
||||||
|
wrap = true,
|
||||||
|
pad_left = 1,
|
||||||
|
pad_right = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, contents)
|
||||||
|
vim.api.nvim_buf_set_option(bufnr, "filetype", "markdown")
|
||||||
|
|
||||||
|
-- Position the window near the cursor
|
||||||
|
local cursor_pos = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local row = cursor_pos[1]
|
||||||
|
local col = cursor_pos[2]
|
||||||
|
|
||||||
|
-- Calculate position
|
||||||
|
local ui = vim.api.nvim_list_uis()[1]
|
||||||
|
local width = opts.width or 60
|
||||||
|
local height = opts.height or 12
|
||||||
|
local anchor = "NW"
|
||||||
|
local col_offset = 0
|
||||||
|
|
||||||
|
-- Open the window
|
||||||
|
local winnr = vim.api.nvim_open_win(bufnr, false, {
|
||||||
|
relative = "cursor",
|
||||||
|
row = 1,
|
||||||
|
col = col_offset,
|
||||||
|
width = width,
|
||||||
|
height = height,
|
||||||
|
style = "minimal",
|
||||||
|
border = opts.border,
|
||||||
|
anchor = anchor,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Set window options
|
||||||
|
vim.api.nvim_win_set_option(winnr, "conceallevel", 2)
|
||||||
|
vim.api.nvim_win_set_option(winnr, "concealcursor", "n")
|
||||||
|
vim.api.nvim_win_set_option(winnr, "winblend", 0)
|
||||||
|
|
||||||
|
-- Return window and buffer numbers
|
||||||
|
return bufnr, winnr
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add a command to test the documentation window
|
||||||
|
vim.api.nvim_create_user_command("TestDocWindow", test_doc_window, {})
|
||||||
|
|
||||||
|
-- Also map it to a key for easy testing
|
||||||
|
vim.keymap.set("n", "<leader>td", test_doc_window, { desc = "Test doc window styling" })
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
---@diagnostic disable: undefined-global
|
||||||
|
return {
|
||||||
|
'lewis6991/hover.nvim',
|
||||||
|
event = 'VeryLazy',
|
||||||
|
config = function()
|
||||||
|
require('hover').setup({
|
||||||
|
init = function()
|
||||||
|
-- Required for hover.nvim
|
||||||
|
require('hover.providers.lsp')
|
||||||
|
-- Optional additional providers
|
||||||
|
require('hover.providers.gh')
|
||||||
|
require('hover.providers.man')
|
||||||
|
require('hover.providers.dictionary')
|
||||||
|
end,
|
||||||
|
preview_opts = {
|
||||||
|
border = 'rounded',
|
||||||
|
width = 80,
|
||||||
|
height = 20,
|
||||||
|
},
|
||||||
|
title = true,
|
||||||
|
-- Key mappings
|
||||||
|
-- Use the same mapping as before ('K')
|
||||||
|
mappings = {
|
||||||
|
toggle_hover = 'K',
|
||||||
|
-- Scroll option
|
||||||
|
scroll_up = '<C-u>',
|
||||||
|
scroll_down = '<C-d>',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Style adjustments
|
||||||
|
vim.api.nvim_set_hl(0, 'HoverFloat', { link = 'Normal' })
|
||||||
|
vim.api.nvim_set_hl(0, 'HoverFloatBorder', { link = 'FloatBorder' })
|
||||||
|
|
||||||
|
-- Override the LSP hover handler to ensure our hover.nvim is used
|
||||||
|
vim.api.nvim_create_autocmd('LspAttach', {
|
||||||
|
callback = function(args)
|
||||||
|
-- Clear and override the K mapping to ensure it uses hover.nvim
|
||||||
|
vim.keymap.set('n', 'K', require('hover').hover,
|
||||||
|
{ buffer = args.buf, desc = 'Enhanced documentation (hover.nvim)' })
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -4,41 +4,57 @@
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.setup()
|
function M.setup()
|
||||||
-- Create a wrapper that ensures position_encoding is added to all calls
|
-- Patch the symbols_to_items function to always use utf-16 encoding
|
||||||
local function with_encoding(fn)
|
-- and handle nil values safely
|
||||||
return function(params, ...)
|
local original_symbols_to_items = vim.lsp.util.symbols_to_items
|
||||||
params = params or {}
|
|
||||||
if not params.position_encoding then
|
|
||||||
params.position_encoding = 'utf-16'
|
|
||||||
end
|
|
||||||
return fn(params, ...)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Override standard LSP buffer functions that may be missing position_encoding
|
|
||||||
vim.lsp.buf.code_action = with_encoding(vim.lsp.buf.code_action)
|
|
||||||
vim.lsp.buf.rename = with_encoding(vim.lsp.buf.rename)
|
|
||||||
vim.lsp.buf.hover = with_encoding(vim.lsp.buf.hover)
|
|
||||||
vim.lsp.buf.formatting = with_encoding(vim.lsp.buf.formatting)
|
|
||||||
vim.lsp.buf.range_formatting = with_encoding(vim.lsp.buf.range_formatting)
|
|
||||||
vim.lsp.buf.format = with_encoding(vim.lsp.buf.format)
|
|
||||||
|
|
||||||
-- Patch util functions as well
|
|
||||||
local orig_make_position_params = vim.lsp.util.make_position_params
|
|
||||||
vim.lsp.util.make_position_params = function(window, client, position_encoding)
|
|
||||||
if not position_encoding then
|
|
||||||
position_encoding = 'utf-16'
|
|
||||||
end
|
|
||||||
return orig_make_position_params(window, client, position_encoding)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Override symbols_to_items to ensure position_encoding is set
|
|
||||||
local orig_symbols_to_items = vim.lsp.util.symbols_to_items
|
|
||||||
vim.lsp.util.symbols_to_items = function(symbols, bufnr, position_encoding)
|
vim.lsp.util.symbols_to_items = function(symbols, bufnr, position_encoding)
|
||||||
if not position_encoding then
|
-- Default to utf-16 if not specified
|
||||||
position_encoding = 'utf-16'
|
position_encoding = position_encoding or 'utf-16'
|
||||||
|
|
||||||
|
-- Add extra safety checks for nil values
|
||||||
|
if not symbols or type(symbols) ~= 'table' then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call original with proper encoding
|
||||||
|
return original_symbols_to_items(symbols, bufnr, position_encoding)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Patch workspace_symbol handler to be safer
|
||||||
|
vim.lsp.handlers['workspace/symbol'] = function(err, result, ctx, config)
|
||||||
|
if err or not result or vim.tbl_isempty(result) then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set a default position_encoding
|
||||||
|
local position_encoding = 'utf-16'
|
||||||
|
local client = vim.lsp.get_client_by_id(ctx.client_id)
|
||||||
|
if client and client.offset_encoding then
|
||||||
|
position_encoding = client.offset_encoding
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Process safely
|
||||||
|
local items = vim.lsp.util.symbols_to_items(result, nil, position_encoding) or {}
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Patch all lsp_* functions in telescope.builtin to include position_encoding
|
||||||
|
local telescope_builtin = require('telescope.builtin')
|
||||||
|
local telescope_funcs = {
|
||||||
|
'lsp_references', 'lsp_definitions', 'lsp_implementations',
|
||||||
|
'lsp_type_definitions', 'lsp_document_symbols', 'lsp_workspace_symbols',
|
||||||
|
'lsp_dynamic_workspace_symbols'
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, func_name in ipairs(telescope_funcs) do
|
||||||
|
local original_func = telescope_builtin[func_name]
|
||||||
|
telescope_builtin[func_name] = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
if not opts.position_encoding then
|
||||||
|
opts.position_encoding = 'utf-16'
|
||||||
|
end
|
||||||
|
return original_func(opts)
|
||||||
end
|
end
|
||||||
return orig_symbols_to_items(symbols, bufnr, position_encoding)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,72 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
-- C/C++
|
-- C/C++
|
||||||
clangd = {},
|
clangd = {
|
||||||
|
cmd = {
|
||||||
|
'clangd',
|
||||||
|
'--background-index',
|
||||||
|
'--clang-tidy',
|
||||||
|
'--header-insertion=iwyu',
|
||||||
|
'--completion-style=detailed',
|
||||||
|
'--function-arg-placeholders',
|
||||||
|
'--fallback-style=llvm',
|
||||||
|
},
|
||||||
|
init_options = {
|
||||||
|
usePlaceholders = true,
|
||||||
|
completeUnimported = true,
|
||||||
|
clangdFileStatus = true,
|
||||||
|
},
|
||||||
|
on_attach = function(client, bufnr)
|
||||||
|
-- Set the correct standard based on filetype
|
||||||
|
local filetype = vim.bo[bufnr].filetype
|
||||||
|
if filetype == 'c' then
|
||||||
|
client.config.init_options.fallbackFlags = { '-std=c23' }
|
||||||
|
elseif filetype == 'cpp' then
|
||||||
|
client.config.init_options.fallbackFlags = { '-std=c++23' }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call the default on_attach to setup keymaps and navic
|
||||||
|
require('plugins.lsp.setup').default_on_attach(client, bufnr)
|
||||||
|
end,
|
||||||
|
settings = {
|
||||||
|
clangd = {
|
||||||
|
InlayHints = {
|
||||||
|
Designators = true,
|
||||||
|
Enabled = true,
|
||||||
|
ParameterNames = true,
|
||||||
|
DeducedTypes = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Zig
|
||||||
|
zls = {
|
||||||
|
settings = {
|
||||||
|
zls = {
|
||||||
|
-- Enable semantic highlighting
|
||||||
|
enable_semantic_tokens = true,
|
||||||
|
-- Enable inlay hints for better code understanding
|
||||||
|
enable_inlay_hints = true,
|
||||||
|
-- Enable snippets
|
||||||
|
enable_snippets = true,
|
||||||
|
-- Enable auto-fixing
|
||||||
|
enable_autofix = true,
|
||||||
|
-- Warn about style issues
|
||||||
|
warn_style = true,
|
||||||
|
-- Highlight global variables
|
||||||
|
highlight_global_var_declarations = true,
|
||||||
|
-- Enable build-on-save for faster feedback
|
||||||
|
enable_build_on_save = true,
|
||||||
|
-- Skip std library references for better performance
|
||||||
|
skip_std_references = false,
|
||||||
|
-- Prefer ast-check over zig fmt for faster response
|
||||||
|
prefer_ast_check_as_child_process = true,
|
||||||
|
-- Enable import embedfile argument completions
|
||||||
|
enable_import_embedfile_argument_completions = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
-- SQL
|
-- SQL
|
||||||
sqls = {
|
sqls = {
|
||||||
|
|
@ -66,4 +131,17 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
-- Elixir
|
||||||
|
elixirls = {
|
||||||
|
cmd = { 'elixir-ls' },
|
||||||
|
settings = {
|
||||||
|
elixirLS = {
|
||||||
|
dialyzerEnabled = true,
|
||||||
|
fetchDeps = true,
|
||||||
|
enableTestLenses = true,
|
||||||
|
suggestSpecs = true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,50 @@
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.setup()
|
function M.setup()
|
||||||
|
-- Apply LSP function overrides for position_encoding
|
||||||
|
require('plugins.lsp.overrides').setup()
|
||||||
|
|
||||||
local servers = require('plugins.lsp.servers')
|
local servers = require('plugins.lsp.servers')
|
||||||
|
|
||||||
-- nvim-cmp capabilities
|
-- Enhanced nvim-cmp capabilities (VSCode-like)
|
||||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||||
|
capabilities.textDocument.completion.completionItem = {
|
||||||
|
documentationFormat = { 'markdown', 'plaintext' },
|
||||||
|
snippetSupport = true,
|
||||||
|
preselectSupport = true,
|
||||||
|
insertReplaceSupport = true,
|
||||||
|
labelDetailsSupport = true,
|
||||||
|
deprecatedSupport = true,
|
||||||
|
commitCharactersSupport = true,
|
||||||
|
tagSupport = { valueSet = { 1 } },
|
||||||
|
resolveSupport = {
|
||||||
|
properties = {
|
||||||
|
'documentation',
|
||||||
|
'detail',
|
||||||
|
'additionalTextEdits',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
-- Complete with all available methods and properties
|
||||||
|
capabilities.textDocument.completion.completionList = {
|
||||||
|
itemDefaults = {
|
||||||
|
'commitCharacters',
|
||||||
|
'editRange',
|
||||||
|
'insertTextFormat',
|
||||||
|
'insertTextMode',
|
||||||
|
'data',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
-- Add semantic tokens for better syntax highlighting
|
||||||
|
capabilities.textDocument.semanticTokens = {
|
||||||
|
tokenTypes = { 'namespace', 'type', 'class', 'enum', 'interface', 'struct', 'typeParameter', 'parameter', 'variable', 'property', 'enumMember', 'event', 'function', 'method', 'macro', 'keyword', 'modifier', 'comment', 'string', 'number', 'regexp', 'operator', 'decorator' },
|
||||||
|
tokenModifiers = { 'declaration', 'definition', 'readonly', 'static', 'deprecated', 'abstract', 'async', 'modification', 'documentation', 'defaultLibrary' },
|
||||||
|
formats = { 'relative' },
|
||||||
|
requests = {
|
||||||
|
range = true,
|
||||||
|
full = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)
|
capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)
|
||||||
|
|
||||||
-- Setup mason-lspconfig
|
-- Setup mason-lspconfig
|
||||||
|
|
@ -20,16 +60,27 @@ function M.setup()
|
||||||
config.capabilities = capabilities
|
config.capabilities = capabilities
|
||||||
|
|
||||||
-- Default on_attach to setup keymaps & navic
|
-- Default on_attach to setup keymaps & navic
|
||||||
local function on_attach(client, bufnr)
|
M.default_on_attach = function(client, bufnr)
|
||||||
require('core.keymaps').setup_lsp_keymaps(bufnr)
|
require('core.keymaps').setup_lsp_keymaps(bufnr)
|
||||||
-- Attach navic if available
|
|
||||||
if client.server_capabilities.documentSymbolProvider then
|
-- Only attach navic if:
|
||||||
|
-- 1. The client supports document symbols
|
||||||
|
-- 2. The client isn't elixirls (handled by elixir-tools.nvim)
|
||||||
|
if client.server_capabilities.documentSymbolProvider
|
||||||
|
and client.name ~= 'elixirls' then
|
||||||
|
local status_ok, _ = pcall(require, 'nvim-navic')
|
||||||
|
if status_ok then
|
||||||
require('nvim-navic').attach(client, bufnr)
|
require('nvim-navic').attach(client, bufnr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
config.on_attach = on_attach
|
end
|
||||||
|
|
||||||
-- Disable gopls semantic tokens to avoid issues
|
-- Only set the default on_attach if one isn't already provided
|
||||||
|
if not config.on_attach then
|
||||||
|
config.on_attach = M.default_on_attach
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Enhance LSP capabilities for specific servers
|
||||||
if server_name == 'gopls' and config.on_attach then
|
if server_name == 'gopls' and config.on_attach then
|
||||||
local orig_on_attach = config.on_attach
|
local orig_on_attach = config.on_attach
|
||||||
config.on_attach = function(client, bufnr)
|
config.on_attach = function(client, bufnr)
|
||||||
|
|
@ -38,10 +89,55 @@ function M.setup()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Force all LSP servers to use incremental completions (like VSCode)
|
||||||
|
if not config.settings then config.settings = {} end
|
||||||
|
if not config.settings.completions then config.settings.completions = {} end
|
||||||
|
config.settings.completions.completeFunctionCalls = true
|
||||||
|
|
||||||
|
-- Enhanced settings for Lua LSP
|
||||||
|
if server_name == 'lua_ls' then
|
||||||
|
if not config.settings.Lua then config.settings.Lua = {} end
|
||||||
|
config.settings.Lua.completion = {
|
||||||
|
callSnippet = "Replace",
|
||||||
|
showWord = "Disable",
|
||||||
|
workspaceWord = false,
|
||||||
|
displayContext = 5,
|
||||||
|
keywordSnippet = "Both",
|
||||||
|
postfix = ".",
|
||||||
|
}
|
||||||
|
-- More comprehensive inferencing
|
||||||
|
config.settings.Lua.hint = {
|
||||||
|
enable = true,
|
||||||
|
setType = true,
|
||||||
|
paramType = true,
|
||||||
|
paramName = "Literal",
|
||||||
|
arrayIndex = "Enable",
|
||||||
|
}
|
||||||
|
-- Better type resolution
|
||||||
|
config.settings.Lua.type = {
|
||||||
|
castNumberToInteger = true,
|
||||||
|
}
|
||||||
|
-- Add standard Lua libraries for better completion
|
||||||
|
if not config.settings.Lua.workspace then config.settings.Lua.workspace = {} end
|
||||||
|
if not config.settings.Lua.workspace.library then config.settings.Lua.workspace.library = {} end
|
||||||
|
|
||||||
|
-- Include standard libraries
|
||||||
|
local lua_types = vim.fn.expand('~/.local/share/nvim/mason/packages/lua-language-server/libexec/meta/3rd')
|
||||||
|
if vim.fn.isdirectory(lua_types) == 1 then
|
||||||
|
config.settings.Lua.workspace.library[lua_types] = true
|
||||||
|
end
|
||||||
|
-- Enable all features
|
||||||
|
config.settings.Lua.hover = { enable = true, expandAlias = true }
|
||||||
|
config.settings.Lua.signatureHelp = { enable = true }
|
||||||
|
config.settings.Lua.diagnostics = { enable = true, globals = { "vim" } }
|
||||||
|
end
|
||||||
|
|
||||||
require('lspconfig')[server_name].setup(config)
|
require('lspconfig')[server_name].setup(config)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Hover handler will now be provided by Blink
|
||||||
|
|
||||||
-- Override references handler
|
-- Override references handler
|
||||||
vim.lsp.handlers['textDocument/references'] = function(err, result, ctx, config)
|
vim.lsp.handlers['textDocument/references'] = function(err, result, ctx, config)
|
||||||
if not result or vim.tbl_isempty(result) then
|
if not result or vim.tbl_isempty(result) then
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,43 @@
|
||||||
return {
|
---@diagnostic disable: undefined-global
|
||||||
|
local vim = vim
|
||||||
|
|
||||||
|
local M = {
|
||||||
'nvimtools/none-ls.nvim',
|
'nvimtools/none-ls.nvim',
|
||||||
event = { 'BufReadPre', 'BufNewFile' },
|
event = { 'BufReadPre', 'BufNewFile' },
|
||||||
dependencies = {
|
dependencies = {
|
||||||
'jay-babu/mason-null-ls.nvim',
|
'jay-babu/mason-null-ls.nvim',
|
||||||
},
|
},
|
||||||
config = function()
|
config = function()
|
||||||
require('plugins.null-ls.setup').setup()
|
-- Safely require null-ls
|
||||||
|
local ok, null_ls = pcall(require, 'null-ls')
|
||||||
|
if not ok then
|
||||||
|
vim.notify('Failed to load null-ls', vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Safely require setup
|
||||||
|
local setup_ok, setup = pcall(require, 'plugins.null-ls.setup')
|
||||||
|
if not setup_ok or type(setup.setup) ~= 'function' then
|
||||||
|
vim.notify('Failed to load null-ls setup', vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Initialize null-ls
|
||||||
|
setup.setup()
|
||||||
|
|
||||||
|
-- Additional safety check for sources
|
||||||
|
vim.defer_fn(function()
|
||||||
|
if not null_ls or not null_ls.get_sources then
|
||||||
|
vim.notify('null-ls sources not available', vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local sources = null_ls.get_sources()
|
||||||
|
if #sources == 0 then
|
||||||
|
vim.notify('No null-ls sources registered', vim.log.levels.WARN)
|
||||||
|
end
|
||||||
|
end, 1000) -- Check after 1 second
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ function M.setup()
|
||||||
local diagnostics = null_ls.builtins.diagnostics
|
local diagnostics = null_ls.builtins.diagnostics
|
||||||
|
|
||||||
null_ls.setup {
|
null_ls.setup {
|
||||||
|
|
||||||
root_dir = null_ls_utils.root_pattern('.null-ls-root', 'Makefile', '.git'),
|
root_dir = null_ls_utils.root_pattern('.null-ls-root', 'Makefile', '.git'),
|
||||||
timeout = 10000,
|
timeout = 10000,
|
||||||
debounce = 250,
|
debounce = 250,
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ return { -- Autocompletion
|
||||||
-- `friendly-snippets` contains a variety of premade snippets.
|
-- `friendly-snippets` contains a variety of premade snippets.
|
||||||
-- See the README about individual language/framework/plugin snippets:
|
-- See the README about individual language/framework/plugin snippets:
|
||||||
-- https://github.com/rafamadriz/friendly-snippets
|
-- https://github.com/rafamadriz/friendly-snippets
|
||||||
-- {
|
{
|
||||||
-- 'rafamadriz/friendly-snippets',
|
'rafamadriz/friendly-snippets',
|
||||||
-- config = function()
|
config = function()
|
||||||
-- require('luasnip.loaders.from_vscode').lazy_load()
|
require('luasnip.loaders.from_vscode').lazy_load()
|
||||||
-- end,
|
end,
|
||||||
-- },
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'saadparwaiz1/cmp_luasnip',
|
'saadparwaiz1/cmp_luasnip',
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,42 @@ local go_flags = 'integration' -- add the tags here, instead of searching it bel
|
||||||
return {
|
return {
|
||||||
-- Main LSP Configuration
|
-- Main LSP Configuration
|
||||||
'neovim/nvim-lspconfig',
|
'neovim/nvim-lspconfig',
|
||||||
|
event = { "BufReadPre", "BufNewFile" },
|
||||||
dependencies = {
|
dependencies = {
|
||||||
-- Automatically install LSPs and related tools to stdpath for Neovim
|
-- Automatically install LSPs and related tools to stdpath for Neovim
|
||||||
{ 'williamboman/mason.nvim', config = true }, -- NOTE: Must be loaded before dependants
|
{
|
||||||
|
'williamboman/mason.nvim',
|
||||||
|
cmd = { "Mason", "MasonInstall", "MasonUpdate" },
|
||||||
|
config = function()
|
||||||
|
require("mason").setup({
|
||||||
|
ui = {
|
||||||
|
icons = {
|
||||||
|
package_installed = "✓",
|
||||||
|
package_pending = "➜",
|
||||||
|
package_uninstalled = "✗"
|
||||||
|
},
|
||||||
|
border = "rounded",
|
||||||
|
width = 0.8,
|
||||||
|
height = 0.9,
|
||||||
|
},
|
||||||
|
log_level = vim.log.levels.INFO,
|
||||||
|
max_concurrent_installers = 4,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
'williamboman/mason-lspconfig.nvim',
|
'williamboman/mason-lspconfig.nvim',
|
||||||
|
dependencies = { 'williamboman/mason.nvim' },
|
||||||
|
config = function()
|
||||||
|
require("mason-lspconfig").setup({
|
||||||
|
automatic_installation = true
|
||||||
|
})
|
||||||
|
end
|
||||||
|
},
|
||||||
-- 'folke/neodev.nvim', -- Adds support for Neovim Lua API -- No longer needed with lazydev
|
-- 'folke/neodev.nvim', -- Adds support for Neovim Lua API -- No longer needed with lazydev
|
||||||
{
|
{
|
||||||
'WhoIsSethDaniel/mason-tool-installer.nvim',
|
'WhoIsSethDaniel/mason-tool-installer.nvim',
|
||||||
|
event = "VeryLazy",
|
||||||
config = function()
|
config = function()
|
||||||
require('mason-tool-installer').setup {
|
require('mason-tool-installer').setup {
|
||||||
ensure_installed = {
|
ensure_installed = {
|
||||||
|
|
@ -35,6 +64,8 @@ return {
|
||||||
'debugpy', -- Python debugger
|
'debugpy', -- Python debugger
|
||||||
-- SQL tools
|
-- SQL tools
|
||||||
'sqls', -- Advanced SQL LSP
|
'sqls', -- Advanced SQL LSP
|
||||||
|
-- Elixir
|
||||||
|
'elixir-ls' -- Elixir LSP
|
||||||
},
|
},
|
||||||
auto_update = true,
|
auto_update = true,
|
||||||
run_on_start = true,
|
run_on_start = true,
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,49 @@
|
||||||
return { -- Highlight, edit, and navigate code
|
return {
|
||||||
|
-- Highlight, edit, and navigate code
|
||||||
'nvim-treesitter/nvim-treesitter',
|
'nvim-treesitter/nvim-treesitter',
|
||||||
build = ':TSUpdate',
|
dependencies = {
|
||||||
|
'nvim-treesitter/nvim-treesitter-textobjects',
|
||||||
|
},
|
||||||
|
build = function()
|
||||||
|
local ts_update = require('nvim-treesitter.install').update({ with_sync = true })
|
||||||
|
ts_update()
|
||||||
|
-- Install C++ parser explicitly to avoid tarball issues
|
||||||
|
vim.cmd('silent! TSInstall cpp')
|
||||||
|
end,
|
||||||
main = 'nvim-treesitter.configs', -- Sets main module to use for opts
|
main = 'nvim-treesitter.configs', -- Sets main module to use for opts
|
||||||
-- [[ Configure Treesitter ]] See `:help nvim-treesitter`
|
-- [[ Configure Treesitter ]] See `:help nvim-treesitter`
|
||||||
opts = {
|
opts = {
|
||||||
ensure_installed = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' },
|
-- List of languages to ensure are installed
|
||||||
|
ensure_installed = {
|
||||||
|
'bash', 'c', 'cpp', 'diff', 'html', 'lua', 'luadoc',
|
||||||
|
'markdown', 'markdown_inline', 'python', 'rust',
|
||||||
|
'javascript', 'typescript', 'json', 'yaml', 'query',
|
||||||
|
'vim', 'vimdoc', 'comment', 'regex'
|
||||||
|
},
|
||||||
|
-- Install parsers synchronously (only applied to `ensure_installed`)
|
||||||
sync_install = false,
|
sync_install = false,
|
||||||
|
-- Automatically install missing parsers when entering buffer
|
||||||
auto_install = true,
|
auto_install = true,
|
||||||
ignore_install = {},
|
-- List of parsers to ignore installing (for "all")
|
||||||
|
ignore_install = { 'phpdoc' },
|
||||||
|
|
||||||
highlight = {
|
highlight = {
|
||||||
enable = true,
|
enable = true,
|
||||||
-- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules.
|
-- Additional filetypes to enable highlighting for
|
||||||
-- If you are experiencing weird indenting issues, add the language to
|
|
||||||
-- the list of additional_vim_regex_highlighting and disabled languages for indent.
|
|
||||||
additional_vim_regex_highlighting = { 'ruby' },
|
additional_vim_regex_highlighting = { 'ruby' },
|
||||||
|
-- Disable for large files
|
||||||
|
disable = function(_, buf)
|
||||||
|
local max_filesize = 100 * 1024 -- 100 KB
|
||||||
|
local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf))
|
||||||
|
if ok and stats and stats.size > max_filesize then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
indent = {
|
||||||
|
enable = true,
|
||||||
|
disable = { 'ruby', 'yaml' }
|
||||||
},
|
},
|
||||||
indent = { enable = true, disable = { 'ruby' } },
|
|
||||||
},
|
},
|
||||||
-- There are additional nvim-treesitter modules that you can use to interact
|
-- There are additional nvim-treesitter modules that you can use to interact
|
||||||
-- with nvim-treesitter. You should go explore a few and see what interests you:
|
-- with nvim-treesitter. You should go explore a few and see what interests you:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
---@diagnostic disable: undefined-global
|
||||||
return { -- Useful plugin to show you pending keybinds.
|
return { -- Useful plugin to show you pending keybinds.
|
||||||
'folke/which-key.nvim',
|
'folke/which-key.nvim',
|
||||||
event = 'VimEnter', -- Sets the loading event to 'VimEnter'
|
event = 'VimEnter', -- Sets the loading event to 'VimEnter'
|
||||||
|
|
@ -63,12 +64,12 @@ return { -- Useful plugin to show you pending keybinds.
|
||||||
{ '<leader>l', group = '[L]SP/Language' },
|
{ '<leader>l', group = '[L]SP/Language' },
|
||||||
{ '<leader>m', group = '[M]emory/Sessions' },
|
{ '<leader>m', group = '[M]emory/Sessions' },
|
||||||
{ '<leader>D', group = '[D]atabase' },
|
{ '<leader>D', group = '[D]atabase' },
|
||||||
{ '<leader>t', group = '[T]oggle', desc = {
|
{ '<leader>t', group = '[T]roubleshooting', desc = {
|
||||||
h = 'Toggle inlay [H]ints',
|
d = 'Search all [D]iagnostics',
|
||||||
}},
|
l = 'Diagnostics in [L]ocation list',
|
||||||
{ '<leader>w', group = '[W]orkspace', desc = {
|
t = 'Diagnostic details in floa[T]',
|
||||||
s = '[S]ymbols',
|
|
||||||
}},
|
}},
|
||||||
|
{ '<leader>w', desc = 'Save file' },
|
||||||
{ '<leader>h', group = 'Git [H]unk', mode = { 'n', 'v' } },
|
{ '<leader>h', group = 'Git [H]unk', mode = { 'n', 'v' } },
|
||||||
{ '<leader>g', group = '[G]it', desc = {
|
{ '<leader>g', group = '[G]it', desc = {
|
||||||
s = 'Status',
|
s = 'Status',
|
||||||
|
|
@ -105,6 +106,7 @@ return { -- Useful plugin to show you pending keybinds.
|
||||||
{ '<leader>X', desc = 'Force close buffer' },
|
{ '<leader>X', desc = 'Force close buffer' },
|
||||||
{ '<leader>/', desc = 'Search in current buffer' },
|
{ '<leader>/', desc = 'Search in current buffer' },
|
||||||
{ '<leader><leader>', desc = 'Find buffers' },
|
{ '<leader><leader>', desc = 'Find buffers' },
|
||||||
|
{ '<leader><space>', desc = 'Search text in all files' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue