nvim: add psoxizsh.plugins.ide

This commit is contained in:
Paul Stemmet 2024-08-08 12:04:16 +00:00
parent 9add4b0481
commit bf29a51829
Signed by: Paul Stemmet
GPG key ID: EDEA539F594E7E75
7 changed files with 167 additions and 263 deletions

View file

@ -1,41 +0,0 @@
return function()
local lspconfig, cmp, util = require 'lspconfig', require 'cmp_nvim_lsp', require 'psoxizsh.util'
local keys, servers = require 'psoxizsh.key', require 'psoxizsh.lsp.servers'
local defaults = {}
-- This is the default key mappings that are applied on attaching to a LSP.
defaults.on_attach = function(_, bnum)
keys.Buffer.Lsp:register({ buffer = bnum })
end
-- Update LSP capabilities we send to servers to include the features supported by nvim-cmp
defaults.capabilities = cmp.default_capabilities()
-- Ideally, this would be registered on some Psoxizsh.Plug.Post autocmd
-- but I don't feel like refactoring psoxizsh.plugin now.
--
-- This is needed because many other lsp plugins expect:
--
-- 1. To be able to call "require 'lspconfig'" and not blow up (after lspconfig is loaded)
-- 2. To be able to configure lspconfig's defaults before servers are setup (before lspconfig is loaded)
--
-- Therefore, we must defer actually loading servers themselves until
-- after all other relevant plugins have had their say... but before
-- packer_compiled is finished as otherwise we risk starting too late
-- and skipping the first buffer neovim opens because we haven't
-- configured our servers yet. Fun.
--
-- Currently this is called during nlsp-settings's config, but we might
-- need to move this around
_G.PsoxizshLoadLSPServers = function()
-- Ensure we exit any active language servers in case of reloads
vim.cmd 'LspStop'
local user = util.try_mconfig('config.lsp.servers')
for server, spec in pairs(servers:extend(user):get()) do
spec(lspconfig[server], defaults)
end
end
end

View file

@ -1,13 +0,0 @@
return function()
local mason_lsp, util = require 'mason-lspconfig', require 'psoxizsh.util'
-- https://github.com/williamboman/mason-lspconfig.nvim#default-configuration
local defaults = {
-- https://github.com/williamboman/mason-lspconfig.nvim#available-lsp-servers
ensure_installed = {},
automatic_installation = true,
}
mason_lsp.setup(util.mconfig('config.mason-lsp', defaults))
end

View file

@ -1,7 +0,0 @@
return function()
local mason, util = require 'mason', require 'psoxizsh.util'
local defaults = {}
return mason.setup(util.mconfig('config.mason', defaults))
end

View file

@ -1,17 +0,0 @@
return function()
local nlsp, util = require 'nlspsettings', require 'psoxizsh.util'
local defaults = {
loader = 'json',
config_home = vim.fn.stdpath('config') .. '/lsp',
local_settings_dir = '.vim',
nvim_notify = { enabled = true, timeout = 2000, },
append_default_schemas = true,
}
nlsp.setup(util.mconfig('config.nlspsettings', defaults))
-- Remember to move this if you ever delete or add a lspconfig
-- plugin that is loaded after this one
_G.PsoxizshLoadLSPServers()
end

View file

@ -1,58 +0,0 @@
return function()
local nls, util = require 'null-ls', require 'psoxizsh.util'
local S = {
builtin = nls.builtins,
cspell = require 'cspell',
}
local flatten = function(list)
local out = {}
for _, l in ipairs(list) do
for _, v in ipairs(l) do
table.insert(out, v)
end
end
return out
end
local if_exec = function(args)
return vim.fn.executable(args[1]) == 1 and vim.list_slice(args, 2) or {}
end
local cspell_event_handler = function(cfg, params, action)
if action == 'add_to_json' and vim.fn.executable('jq') == 1 then
local cmd = "cat %s | jq -S '.words |= sort' | tee %s > /dev/null"
os.execute(cmd:format(cfg, cfg))
end
end
local cspell_post_handler = function(diagnostic)
local level, levels = diagnostic.severity, vim.diagnostic.severity
-- Cap maximum severity of spelling mistakes
if level == levels.ERROR or level == levels.WARN then
diagnostic.severity = levels.INFO
end
end
local cspell_options = {
config = {
on_success = cspell_event_handler,
},
diagnostics_postprocess = cspell_post_handler
}
local defaults = {
sources = flatten {
if_exec { 'cspell',
S.cspell.diagnostics.with(cspell_options),
S.cspell.code_actions.with(cspell_options),
},
},
}
nls.setup(util.mconfig('config.null-ls', defaults))
end

View file

@ -1,127 +0,0 @@
return function()
local cmp, util = require 'cmp', require 'psoxizsh.util'
local kmap, cfg, lspkind = cmp.mapping, cmp.config, require 'lspkind'
local sources, w = cfg.sources, cfg.window
local mode = { insert = kmap.preset.insert, cmd = kmap.preset.cmdline }
local defaults = { snippet = {}, mapping = {}, sources = {} }
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match('%s') == nil
end
local fkey = function(key, md)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), md or '', true)
end
local buffer_options = {
get_bufnrs = vim.api.nvim_list_bufs
}
-- Snippet provider
defaults.snippet.expand = function(args)
vim.fn['vsnip#anonymous'](args.body)
end
-- Key maps for auto completion
defaults.mapping = {
['<Tab>'] = kmap(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif vim.fn['vsnip#available'](1) == 1 then
fkey '<Plug>(vsnip-expand-or-jump)'
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, { 'i', 's' }),
['<S-Tab>'] = kmap(function()
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn['vsnip#jumpable'](-1) == 1 then
fkey '<Plug>(vsnip-jump-prev)'
end
end, { 'i', 's' }),
['<PageUp>'] = kmap.scroll_docs(-4),
['<PageDown>'] = kmap.scroll_docs(4),
['<C-Space>'] = kmap.confirm({ behavior = cmp.ConfirmBehavior.Insert, select = true }),
}
defaults.mapping = mode.insert(defaults.mapping)
-- Sources of auto completion
--
-- Each group of completions is prioritized in ascending order;
-- that is, 'path's will be shown before 'nvim_lsp's, etc
defaults.sources = sources(
{
{ name = 'async_path', },
},
{
{ name = 'nvim_lsp', keyword_length = 2 },
{ name = 'nvim_lsp_signature_help', },
},
{
{ name = 'vsnip', keyword_length = 2 },
},
{
{ name = 'buffer',
option = buffer_options,
keyword_length = 2,
},
{ name = 'spell', max_item_count = 3, keyword_length = 3 },
}
)
-- Auto completion window settings
defaults.window = {
completion = {
col_offset = -3,
side_padding = 0,
},
documentation = w.bordered(),
}
-- Auto completion item formatting
defaults.formatting = {
fields = { 'kind', 'abbr', 'menu' },
format = function(entry, item)
local kind = lspkind.cmp_format({ mode = 'symbol_text', maxwidth = 50 })(entry, item)
local strings = vim.split(kind.kind, '%s', { trimempty = true })
kind.kind = ' ' .. strings[1] .. ' '
kind.menu = ' (' .. strings[2] .. ')'
return kind
end,
}
-- Performance settings
defaults.performance = {
max_view_entries = 15
}
cmp.setup(util.mconfig('config.nvim-cmp', defaults))
cmp.setup.cmdline(':', {
mapping = mode.cmd(),
sources = sources(
{
{ name = 'async_path', max_item_count = 5 },
{ name = 'cmdline_history', max_item_count = 2 },
{ name = 'cmdline', max_item_count = 3 },
}
)
})
cmp.setup.cmdline({'/', '?', '@'}, {
mapping = mode.cmd(),
sources = sources(
{
{ name = 'cmdline_history', max_item_count = 1 },
{ name = 'cmdline', max_item_count = 4 },
{ name = 'buffer', max_item_count = 10 },
}
)
})
end

View file

@ -0,0 +1,167 @@
-- IDE components, autocompletion, DAPs
return {
-- Autocompletion + snippets + vim.diagnostic sources
-- Completion framework
{ 'hrsh7th/nvim-cmp',
dependencies = {
-- LSP sources
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-nvim-lsp-signature-help',
-- Other sources:
{ url = 'https://codeberg.org/FelipeLema/cmp-async-path' },
'hrsh7th/cmp-buffer',
'hrsh7th/cmp-cmdline',
'dmitmel/cmp-cmdline-history',
},
opts = function(_, opts)
local cmp = require('cmp')
local auto_select = true
local has_words_before = function()
unpack = unpack or table.unpack
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match('%s') == nil
end
opts.preselect = auto_select and cmp.PreselectMode.Item or cmp.PreselectMode.None
opts.completion = { completeopt = "menu,menuone,noinsert" .. (auto_select and "" or ",noselect") }
opts.mapping = cmp.mapping.preset.insert({
['<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif vim.snippet.active({ direction = 1 }) then
vim.schedule(function() vim.snippet.jump(1) end)
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, { 'i', 's' }),
['<S-Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif vim.snippet.active({ direction = -1 }) then
vim.schedule(function() vim.snippet.jump(-1) end)
else
fallback()
end
end, { 'i', 's' }),
['<PageUp>'] = cmp.mapping.scroll_docs(-4),
['<PageDown>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<CR>'] = LazyVim.cmp.confirm({ select = auto_select }),
['<S-CR>'] = LazyVim.cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace }),
['<C-CR>'] = function(fallback)
cmp.abort()
fallback()
end,
})
-- Monkey patch the sources list LazyVim sets by default
-- https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/plugins/coding.lua#L45-L50
local sources = {}
for _, src in ipairs(opts.sources) do
if src and src.name then
-- Insert function signature completions before LSP completions
if src.name == 'nvim_lsp' then
table.insert(sources, { name = 'nvim_lsp_signature_help' })
end
-- Replace path with async_path (less UI freezing)
if src.name == "path" then
table.insert(sources, { name = 'async_path' })
goto continue
end
-- Load completions from all open buffers
if src.name == 'buffer' then
table.insert(sources, { name = 'buffer', option = { get_bufnrs = vim.api.nvim_list_bufs } })
goto continue
end
end
table.insert(sources, src)
::continue::
end
opts.sources = sources
end
},
-- IDE stuff + language highlighting
{ 'williamboman/mason.nvim' },
{ 'williamboman/mason-lspconfig.nvim' },
{ 'neovim/nvim-lspconfig' },
{ import = 'psoxizsh.lsp.keys' },
{ 'vim-perl/vim-perl',
version = false,
ft = { 'perl' },
build = 'make clean carp dancer highlight-all-pragmas moose test-more try-tiny'
},
{ 'rust-lang/rust.vim',
version = false,
ft = { 'rust' }
},
{ 'pearofducks/ansible-vim',
version = false,
ft = { 'yaml.ansible', 'yaml', 'yml.ansible', 'yml' }
},
{ 'kevinoid/vim-jsonc',
version = false,
},
{ 'luochen1990/rainbow',
version = false,
lazy = false,
init = function(_) vim.g['rainbow_active'] = 1 end,
},
{ 'sheerun/vim-polyglot', version = false, lazy = false, },
-- Framework for integrating non-LSP sources into nvim's LSP framework
{ import = 'lazyvim.plugins.extras.lsp.none-ls' },
{ 'nvimtools/none-ls.nvim',
dependencies = { 'nvim-lua/plenary.nvim', 'davidmh/cspell.nvim' },
opts = function(_, opts)
if vim.fn.executable('cspell') == 0 then return end
-- CSpell setup
local cspell = require 'cspell'
local cspell_opts = {
config = {
on_add_to_json = function(payload)
if vim.fn.executable('jq') == 0 then return end
local p = payload.cspell_config_path
os.execute(string.format(
"jq -S '.words |= sort' %s > %s.tmp && mv %s.tmp %s",
p, p, p, p
))
end,
on_add_to_dictionary = function(payload)
if vim.fn.executable('sort') == 0 then return end
local p = payload.dictionary_path
os.execute(string.format('sort --dictionary-order %s -o %s', p, p))
end
},
diagnostics_postprocess = function(d)
local level, levels = d.severity, vim.diagnostic.severity
-- Cap maximum severity of spelling mistakes
if level == levels.ERROR or level == levels.WARN then
d.severity = levels.INFO
end
end,
}
opts.sources = vim.tbl_extend('force', opts.sources or {}, {
cspell.diagnostics.with(cspell_opts),
cspell.code_actions.with(cspell_opts),
})
end,
},
{ 'davidmh/cspell.nvim', version = false },
}