feat: language-manager

This commit is contained in:
2025-10-24 02:21:21 +03:00
parent 9bca643408
commit 2b1b3ebbf0
10 changed files with 385 additions and 401 deletions

View File

@@ -48,8 +48,30 @@ vim.api.nvim_create_autocmd({ 'WinLeave', 'InsertEnter' }, {
end,
})
-- Removes trailing whitespace before saving
vim.api.nvim_create_autocmd({ 'BufWritePre' }, {
pattern = '*',
command = [[%s/\s\+$//e]],
-- Autocompletion
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('minimal_lsp', { clear = true }),
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if not client then
return
end
-- Enable native completion
if client:supports_method('textDocument/completion') then
vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
end
end,
})
vim.lsp.handlers['textDocument/completion'] = function(err, result, ctx, config)
if err or not result then
return
end
for _, item in ipairs(result.items or result) do
if item.kind then
local kind = vim.lsp.protocol.CompletionItemKind[item.kind] or ''
item.menu = '[' .. kind .. ']'
end
end
return vim.lsp.completion._on_completion_result(err, result, ctx, config)
end

View File

@@ -1,25 +0,0 @@
if vim.env.CONTAINER then
vim.g.clipboard = {
name = 'osc52',
copy = {
['+'] = require('vim.ui.clipboard.osc52').copy('+'),
['*'] = require('vim.ui.clipboard.osc52').copy('*'),
},
paste = {
['+'] = require('vim.ui.clipboard.osc52').paste('+'),
['*'] = require('vim.ui.clipboard.osc52').paste('*'),
},
}
end
-- vim.schedule(function()
-- vim.opt.clipboard = 'unnamedplus'
-- end)
-- TEMP: Check if it helps with edge cases
vim.api.nvim_create_user_command('FixClipboard', function()
vim.cmd('lua require("vim.ui.clipboard.osc52")')
vim.schedule(function()
vim.notify('Clipboard provider reloaded (OSC52)')
end)
end, {})

View File

@@ -0,0 +1,42 @@
-- Diagnostics
local special_sources = {
lua_ls = 'lua',
}
vim.diagnostic.config({
underline = true,
severity_sort = true,
virtual_text = {
format = function(diagnostic)
local src = diagnostic.source and (special_sources[diagnostic.source] or diagnostic.source)
if src then
return string.format('%s: %s', src, diagnostic.message)
end
return diagnostic.message
end,
},
float = {
border = 'rounded',
header = '',
format = function(diagnostic)
local src = diagnostic.source and (special_sources[diagnostic.source] or diagnostic.source)
if src then
return string.format('%s: %s', src, diagnostic.message)
end
return diagnostic.message
end,
},
})
-- Override the virtual text diagnostic handler so that the most severe diagnostic is shown first.
local show_handler = vim.diagnostic.handlers.virtual_text.show
assert(show_handler)
local hide_handler = vim.diagnostic.handlers.virtual_text.hide
vim.diagnostic.handlers.virtual_text = {
show = function(ns, bufnr, diagnostics, opts)
table.sort(diagnostics, function(diag1, diag2)
return diag1.severity > diag2.severity
end)
return show_handler(ns, bufnr, diagnostics, opts)
end,
hide = hide_handler,
}

View File

@@ -21,7 +21,7 @@ vim.keymap.set('x', 'K', ":m '<-2<CR>gv=gv")
vim.keymap.set('n', '<leader>s', [[:%s/\<<C-r><C-w>\>/<C-r><C-w>/g<Left><Left><Left>]])
-- Proper registers
-- Easy to use registers
map('x', '<leader>p', '"_dP')
map({ 'n', 'x' }, '<leader>y', '"+y')
map('n', '<leader>Y', '"+y$')
@@ -60,8 +60,12 @@ map('n', '<leader>xr', cmd('TermRelative'))
map('n', '<leader>xs', cmd('TermSplit'))
map('n', '<leader>xv', cmd('TermVSplit'))
map('t', '<Esc>', '<C-\\><C-n>')
map('t', '<C-w>', '<C-\\><C-n><C-w>')
map('t', '<C-w>c', '<C-\\><C-n>:bd!<CR>')
map('t', '<C-w>h', [[<C-\><C-n><C-w>h]])
map('t', '<C-w>j', [[<C-\><C-n><C-w>j]])
map('t', '<C-w>k', [[<C-\><C-n><C-w>k]])
map('t', '<C-w>l', [[<C-\><C-n><C-w>l]])
map('t', '<C-w>c', [[<C-\><C-n><cmd>bd!<CR>]])
map('t', '<C-w><C-w>', [[<C-\><C-n><C-w>w]])
-- File explorer
map('n', '<leader>e', cmd('NvimTreeToggle'))
@@ -77,3 +81,8 @@ end)
map('n', '<leader>q', vim.diagnostic.setloclist)
map('n', '<leader>d', vim.diagnostic.open_float)
map('n', '<leader>s', vim.lsp.buf.signature_help)
map('n', 'gd', vim.lsp.buf.definition)
map('n', 'gr', vim.lsp.buf.references)
map('n', 'K', vim.lsp.buf.hover)
map('n', '<C-s>', vim.lsp.buf.signature_help)

View File

@@ -16,11 +16,15 @@ vim.g.loaded_vimballPlugin = 1
vim.g.loaded_matchit = 1
vim.g.loaded_2html_plugin = 1
vim.g.loaded_rrhelper = 1
vim.g.loaded_matchparen = 1
vim.g.loaded_tutor_mode_plugin = 1
vim.g.loaded_spellfile_plugin = 1
vim.g.loaded_logipat = 1
vim.g.loaded_rplugin = 1
vim.g.loaded_netrw = 1 -- use nvim-tree instead
vim.g.loaded_netrwPlugin = 1
-- UI
vim.g.health = { style = 'float' }
vim.g.have_nerd_font = true
vim.opt.termguicolors = false
@@ -31,9 +35,10 @@ vim.opt.signcolumn = 'no'
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.cursorline = true
vim.opt.ruler = false
vim.opt.winborder = 'rounded'
vim.opt.guicursor = 'n-v-i-c:block'
vim.opt.ruler = false
vim.opt.laststatus = 3
vim.opt.statusline = '── %f %h%w%m%r %= [%l,%c-%L] ──'
vim.opt.fillchars = {
@@ -71,7 +76,7 @@ vim.opt.mouse = 'a' -- Enable mouse support
vim.opt.ignorecase = true
vim.opt.smartcase = true -- Override ignorecase if search contains upper case chars
vim.opt.inccommand = 'split' -- Live substitution preview
vim.opt.completeopt = { 'fuzzy,menuone,popup,preview,noselect' }
vim.opt.completeopt = { 'fuzzy', 'menuone', 'popup', 'noselect' }
-- Splits
vim.opt.splitright = true
@@ -87,3 +92,18 @@ vim.opt.timeout = true
vim.opt.ttimeout = true
vim.opt.timeoutlen = 500
vim.opt.ttimeoutlen = 10
-- Clipboard
if vim.env.CONTAINER then
vim.g.clipboard = {
name = 'osc52',
copy = {
['+'] = require('vim.ui.clipboard.osc52').copy('+'),
['*'] = require('vim.ui.clipboard.osc52').copy('*'),
},
paste = {
['+'] = require('vim.ui.clipboard.osc52').paste('+'),
['*'] = require('vim.ui.clipboard.osc52').paste('*'),
},
}
end

View File

@@ -1,4 +1,6 @@
local term_group = vim.api.nvim_create_augroup('custom-term-open', { clear = true })
local term_group = vim.api.nvim_create_augroup('custom-term', { clear = true })
-- Custom terminal
vim.api.nvim_create_autocmd('TermOpen', {
group = term_group,
callback = function()
@@ -10,18 +12,6 @@ vim.api.nvim_create_autocmd('TermOpen', {
end,
})
-- Close all terminal buffers before quitting
vim.api.nvim_create_autocmd('QuitPre', {
group = vim.api.nvim_create_augroup('shoutoff_terminals', { clear = true }),
callback = function()
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == 'terminal' then
vim.api.nvim_buf_delete(buf, { force = true })
end
end
end,
})
-- Insert when re-entering a terminal window (after switching back)
vim.api.nvim_create_autocmd('BufEnter', {
group = term_group,
@@ -33,30 +23,43 @@ vim.api.nvim_create_autocmd('BufEnter', {
end,
})
local function open_default()
vim.cmd('terminal')
end
-- Close all terminal buffers before quitting
vim.api.nvim_create_autocmd('QuitPre', {
group = term_group,
callback = function()
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == 'terminal' then
vim.api.nvim_buf_delete(buf, { force = true })
end
end
end,
})
local function open_relative()
local shell = vim.o.shell or 'zsh'
local dir = vim.fn.expand('%:p:h')
vim.cmd(string.format('edit term://%s//%s', dir, shell))
end
local commands = {
TermDefault = function()
vim.cmd('terminal')
end,
local function open_split()
vim.cmd('new')
vim.cmd('wincmd J')
vim.api.nvim_win_set_height(0, 12)
vim.wo.winfixheight = true
vim.cmd('term')
end
TermRelative = function()
local shell = vim.o.shell or 'zsh'
local dir = vim.fn.expand('%:p:h')
vim.cmd(string.format('edit term://%s//%s', dir, shell))
end,
local function open_vertical()
vim.cmd('vsplit')
vim.cmd('term')
end
TermSplit = function()
vim.cmd('new')
vim.cmd('wincmd J')
vim.api.nvim_win_set_height(0, 12)
vim.wo.winfixheight = true
vim.cmd('term')
end,
vim.api.nvim_create_user_command('TermDefault', open_default, {})
vim.api.nvim_create_user_command('TermRelative', open_relative, {})
vim.api.nvim_create_user_command('TermSplit', open_split, {})
vim.api.nvim_create_user_command('TermVSplit', open_vertical, {})
TermVSplit = function()
vim.cmd('vsplit')
vim.cmd('term')
end,
}
for name, fn in pairs(commands) do
vim.api.nvim_create_user_command(name, fn, {})
end