dotfiles/.vim/nvim.lua

678 lines
17 KiB
Lua

require('nvim-autopairs').setup {}
-- nvim_lsp object
local nvim_lsp = require 'lspconfig'
-- function to attach completion when setting up lsp
local on_attach = function(client)
end
-- Set my preferred diagnostic options
local diagnostic_options = {
virtual_text = false,
signs = true,
update_in_insert = false,
}
local rust_capabilities = vim.lsp.protocol.make_client_capabilities()
rust_capabilities.textDocument.completion.completionItem.snippetSupport = true
rust_capabilities.textDocument.completion.completionItem.resolveSupport = {
properties = {
'documentation',
'detail',
'additionalTextEdits',
}
}
local default_capabilities = vim.lsp.protocol.make_client_capabilities()
default_capabilities.textDocument.completion.completionItem.snippetSupport = true
default_capabilities.textDocument.completion.completionItem.resolveSupport = {
properties = {
'documentation',
'detail',
'additionalTextEdits',
}
}
-- Enable rust_analyzer
nvim_lsp.rust_analyzer.setup({
on_attach = function(client, bufnr)
client.server_capabilities.semanticTokensProvider = nil
end,
capabilities = rust_capabilities,
settings = {
['rust-analyzer'] = {
checkOnSave = {
allFeatures = true,
overrideCommand = {
'cargo', 'clippy', '--workspace', '--message-format=json',
'--all-targets', '--all-features'
}
},
runnables = {
extraEnv = {
TORCH_CUDA_VERSION = "cu121",
}
}
}
}
})
nvim_lsp.gopls.setup({
on_attach = function(client, bufnr)
client.server_capabilities.semanticTokensProvider = {
full = true,
legend = {
--tokenTypes = { 'namespace', 'type', 'class', 'enum', 'interface', 'struct', 'typeParameter', 'parameter', 'variable', 'property', 'enumMember', 'event', 'function', 'method', 'macro', 'keyword', 'modifier', 'comment', 'string', 'number', 'regexp', 'operator', 'decorator', },
tokenTypes = { 'namespace' },
tokenModifiers = { 'declaration', 'definition', 'readonly', 'static', 'deprecated', 'abstract', 'async',
'modification', 'documentation', 'defaultLibrary',
},
}
}
end,
settings = {
gopls = {
semanticTokens = true,
},
},
})
local function filter(arr, func)
-- Filter in place
-- https://stackoverflow.com/questions/49709998/how-to-filter-a-lua-array-inplace
local new_index = 1
local size_orig = #arr
for old_index, v in ipairs(arr) do
if func(v, old_index) then
arr[new_index] = v
new_index = new_index + 1
end
end
for i = new_index, size_orig do arr[i] = nil end
end
local function pyright_accessed_filter(diagnostic)
-- Allow kwargs to be unused, sometimes you want many functions to take the
-- same arguments but you don't use all the arguments in all the functions,
-- so kwargs is used to suck up all the extras
if diagnostic.message == '"kwargs" is not accessed' then
return false
end
-- Allow variables starting with an underscore
if string.match(diagnostic.message, '"_.+" is not accessed') then
return false
end
return true
end
local function pyright_custom_diagnostic(a, params, client_id, c, config)
filter(params.diagnostics, pyright_accessed_filter)
vim.lsp.diagnostic.on_publish_diagnostics(a, params, client_id, c, config)
end
nvim_lsp.pyright.setup({
on_attach = function(client, bufnr)
vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(pyright_custom_diagnostic, diagnostic_options)
end
})
--nvim_lsp.pyright.setup({ on_attach = on_attach })
--nvim_lsp.pylsp.setup({
--on_attach = on_attach,
--settings = {
--pylsp = {
--plugins = {
---- formatter options
----black = { enabled = true },
--autopep8 = { enabled = false },
--yapf = { enabled = false },
---- linter options
--pylint = { enabled = false, executable = "pylint" },
--pyflakes = { enabled = false },
--pycodestyle = { enabled = false },
---- type checker
--pylsp_mypy = { enabled = true },
---- auto-completion options
--jedi_completion = { enabled = false },
---- import sorting
----pyls_isort = { enabled = true },
----flake8 = {
----maxLineLength = 100,
----},
--pycodestyle = {
--maxLineLength = 100,
--},
----rope_autoimport = {
----enabled = true
----},
----rope_completion = {
----enabled = true
----},
--}
--}
--}
--})
nvim_lsp.clangd.setup({ on_attach = on_attach })
nvim_lsp.tsserver.setup {
cmd = { "/home/barak/.yarn/bin/typescript-language-server", "--stdio" }
}
nvim_lsp.vuels.setup {
cmd = { "/home/barak/.yarn/bin/vls" }
}
nvim_lsp.hls.setup {
cmd = { "haskell-language-server-wrapper", "--lsp" }
}
nvim_lsp.svelte.setup {
cmd = { "/home/barak/.bun/bin/bunx", "svelteserver", "--stdio" }
}
local runtime_path = vim.split(package.path, ';')
table.insert(runtime_path, "lua/?.lua")
table.insert(runtime_path, "lua/?/init.lua")
require 'lspconfig'.lua_ls.setup {
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT',
-- Setup your lua path
path = runtime_path,
},
diagnostics = {
-- Get the language server to recognize the `vim` global
globals = { 'vim' },
},
workspace = {
-- Make the server aware of Neovim runtime files
library = vim.api.nvim_get_runtime_file("", true),
},
-- Do not send telemetry data containing a randomized but unique identifier
telemetry = {
enable = false,
},
},
},
}
require('go').setup({
iferr_vertical_shift = 2
})
require('telescope').load_extension('goimpl')
function org_imports(wait_ms)
local params = vim.lsp.util.make_range_params()
params.context = { only = { "source.organizeImports" } }
local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, wait_ms)
for _, res in pairs(result or {}) do
for _, r in pairs(res.result or {}) do
if r.edit then
vim.lsp.util.apply_workspace_edit(r.edit, "utf-8")
else
vim.lsp.buf.execute_command(r.command)
end
end
end
end
-- register linters
local luaformat = require("efmls-configs.formatters.lua_format")
local rustfmt = require('efmls-configs.formatters.rustfmt')
local black = require('efmls-configs.formatters.black')
local mypy = require('efmls-configs.linters.mypy')
local eslint = require('efmls-configs.linters.eslint')
local isort = require('efmls-configs.formatters.isort')
local languages = {
typescript = { eslint },
lua = { luaformat },
python = { black, mypy, isort },
rust = { rustfmt },
}
local efmls_config = {
filetypes = vim.tbl_keys(languages),
settings = {
rootMarkers = { '.git/' },
languages = languages,
},
init_options = {
documentFormatting = true,
documentRangeFormatting = true,
},
}
require('lspconfig').efm.setup(vim.tbl_extend('force', efmls_config, {
-- Pass your custom lsp config below like on_attach and capabilities
on_attach = on_attach,
capabilities = default_capabilities,
}))
-- Enable diagnostics
vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(
vim.lsp.diagnostic.on_publish_diagnostics,
diagnostic_options
)
-- Compe setup
require 'compe'.setup {
enabled = true,
autocomplete = true,
debug = false,
min_length = 1,
preselect = 'disable',
throttle_time = 80,
source_timeout = 200,
incomplete_delay = 400,
max_abbr_width = 100,
max_kind_width = 100,
max_menu_width = 100,
documentation = true,
source = {
path = true,
nvim_lsp = true,
},
}
--signature_cfg = {
--hint_enable = true,
--hint_prefix = "% ",
--handler_opts = {
--border = "none"
--},
--}
--require'lsp_signature'.on_attach(signature_cfg)
local saga_cfg = {
code_action_prompt = {
enable = false,
sign = false,
virtual_text = false,
},
}
-- require'lspsaga'.init_lsp_saga(saga_cfg)
local t = function(str)
return vim.api.nvim_replace_termcodes(str, true, true, true)
end
local check_back_space = function()
local col = vim.fn.col('.') - 1
if col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then
return true
else
return false
end
end
-- Use (s-)tab to:
--- move to prev/next item in completion menuone
--- jump to prev/next snippet's placeholder
_G.tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t "<C-n>"
elseif check_back_space() then
return t "<Tab>"
else
return vim.fn['compe#complete']()
end
end
_G.s_tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t "<C-p>"
else
return t "<S-Tab>"
end
end
vim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_complete()", { expr = true })
vim.api.nvim_set_keymap("s", "<Tab>", "v:lua.tab_complete()", { expr = true })
vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
vim.api.nvim_set_keymap("s", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
require('lspkind').init({
-- disables text annotations
--with_text = false,
--with_text = true,
-- defines how annotations are shown
-- default: symbol
-- options: 'text', 'text_symbol', 'symbol_text', 'symbol'
mode = 'symbol',
-- default symbol map
-- can be either 'default' or 'codicons'
preset = 'default',
-- override preset symbols
-- default: {}
--symbol_map = {
--Method = 'm',
--Function = 'f',
--Text = 'txt',
--Constructor = 'new',
--Variable = 'var',
--Class = 'cls',
--Interface = 'iface',
--Module = 'mod',
--Property = 'prop',
--Unit = 'unit',
--Value = 'val',
--Enum = 'enum',
--Keyword = 'kw',
--Snippet = 'sn',
--Color = 'color',
--File = 'file',
--Folder = 'fold',
--EnumMember = 'enum',
--Constant = 'const',
--Struct = 'struct',
--},
})
--require('rust-tools').setup({
--})
require('trouble').setup {
mode = "document_diagnostics",
auto_close = true,
action_keys = { -- key mappings for actions in the trouble list
-- map to {} to remove a mapping, for example:
-- close = {},
--close = "q", -- close the list
--cancel = "<esc>", -- cancel the preview and get back to your last window / buffer / cursor
--refresh = "r", -- manually refresh
jump = { "o", "<tab>" }, -- jump to the diagnostic or open / close folds
--open_split = { "<c-x>" }, -- open buffer in new split
--open_vsplit = { "<c-v>" }, -- open buffer in new vsplit
open_tab = {}, -- open buffer in new tab
jump_close = { "<cr>" }, -- jump to the diagnostic and close the list
toggle_mode = "m", -- toggle between "workspace" and "document" diagnostics mode
toggle_preview = "P", -- toggle auto_preview
hover = "K", -- opens a small popup with the full multiline message
preview = "p", -- preview the diagnostic location
close_folds = { "zM", "zm" }, -- close all folds
open_folds = { "zR", "zr" }, -- open all folds
toggle_fold = { "zA", "za" }, -- toggle fold of current file
previous = "k", -- previous item
next = "j" -- next item
},
}
local trouble_telescope = require("trouble.providers.telescope")
local builtin = require 'telescope.builtin'
local sendtoqf = function(loc)
local actions = require('telescope.actions')
actions.send_to_qflist(loc)
builtin.quickfix({ initial_mode = "normal" })
end
require('telescope').setup {
defaults = {
mappings = {
n = {
["q"] = require('telescope.actions').close,
["ff"] = sendtoqf,
["<c-t>"] = trouble_telescope.open_with_trouble,
},
i = {
["<c-t>"] = trouble_telescope.open_with_trouble,
["ff"] = require('telescope.actions').send_to_qflist,
},
},
path_display = { "smart", "shorten" },
dynamic_preview_title = true,
},
pickers = {
goimpl = {
theme = "ivy",
layout_config = {
height = 10,
},
},
lsp_code_actions = {
theme = "ivy",
layout_config = {
height = 10,
},
},
lsp_range_code_actions = {
theme = "ivy",
layout_config = {
height = 10,
},
},
lsp_references = {
theme = "ivy",
layout_config = {
height = 15,
},
},
quickfix = {
theme = "ivy",
layout_config = {
height = 15,
},
initial_mode = "normal",
},
git_files = {
theme = "ivy",
},
grep_string = {
theme = "ivy",
layout_config = {
height = 15,
},
initial_mode = "normal",
},
live_grep = {
theme = "ivy",
layout_config = {
height = 15,
},
},
buffers = {
theme = "ivy",
layout_config = {
height = 15,
},
ignore_current_buffer = true,
initial_mode = "normal",
},
},
}
--
-- Treesitter
--
require 'nvim-treesitter.configs'.setup {
-- One of "all", "maintained" (parsers with maintainers), or a list of languages
ensure_installed = {
"c",
"cpp",
"css",
"dockerfile",
"fish",
"go",
"haskell",
"html",
"javascript",
"json",
"lua",
"make",
"markdown",
"proto",
"python",
"query",
"rust",
"terraform",
"toml",
"tsx",
"typescript",
"vim",
"yaml",
},
-- Install languages synchronously (only applied to `ensure_installed`)
sync_install = false,
-- List of parsers to ignore installing
-- ignore_install = { "javascript" },
highlight = {
-- `false` will disable the whole extension
enable = true,
-- list of language that will be disabled
-- disable = { "c", "rust" },
-- Setting this to true will run `:h syntax` and tree-sitter at the same time.
-- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
-- Using this option may slow down your editor, and you may see some duplicate highlights.
-- Instead of true it can also be a list of languages
additional_vim_regex_highlighting = false,
--custom_captures = {
--["generic_type_param"] = "TSCGenericTypeParam",
--["type_identifier"] = "TSCGenericTypeParam",
--},
},
indent = {
enable = true
},
playground = {
enable = true,
disable = {},
updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code
persist_queries = false, -- Whether the query persists across vim sessions
keybindings = {
toggle_query_editor = 'o',
toggle_hl_groups = 'i',
toggle_injected_languages = 't',
toggle_anonymous_nodes = 'a',
toggle_language_display = 'I',
focus_language = 'f',
unfocus_language = 'F',
update = 'R',
goto_node = '<cr>',
show_help = '?',
},
}
}
require "neogen".setup {}
require('leap').set_default_keymaps()
require("flit").setup {}
require('snippy').setup({
mappings = {
is = {
[',,'] = 'expand_or_advance',
[',.'] = 'previous',
},
nx = {
['<leader>x'] = 'cut_text',
},
},
})
---
--- My own "where" clause generator for Rust
---
function string.insert(str1, str2, pos)
return str1:sub(1, pos) .. str2 .. str1:sub(pos + 1)
end
function string.split(s, delimiter)
local result = {};
for match in (s .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result, match);
end
return result;
end
local function rust_whereify_line(line, var_name)
if string.find(line, "fn") == nil then
return nil
end
local paren = string.find(line, "%(")
if paren == nil then return nil end
local open_generic = string.find(line, "<")
if open_generic ~= nil then
if open_generic < paren then
-- TODO(barakmich): it's already generic, we need to do something for that
-- probably a different function
return nil
end
-- just continue otherwise
end
local whitespace = string.match(line, "^(%s*)")
local generic = "<" .. var_name .. ">"
local out = string.insert(line, generic, paren - 1)
local brace = string.find(out, "%{")
if brace == nil then brace = string.len(out) end
out = string.insert(out, "\n" .. whitespace .. "where\n" .. whitespace .. " " .. var_name .. ": ,\n" .. whitespace,
brace - 1)
return string.split(out, "\n")
end
function rust_where_at_line()
local var_name = vim.fn.input("Variable: ")
local lineNum, col = unpack(vim.api.nvim_win_get_cursor(0))
local replacements = rust_whereify_line(vim.api.nvim_get_current_line(), var_name)
vim.api.nvim_buf_set_lines(0, lineNum - 1, lineNum, false, replacements)
vim.api.nvim_win_set_cursor(0, { lineNum + 2, 4 })
end
function neogen_dwim()
local table = {
["function_declaration"] = "func",
["function_definition"] = "func",
["function_item"] = "func",
["function_signature_item"] = "func",
["struct_item"] = "class",
["trait_item"] = "class",
["package_clause"] = "type",
["const_declaration"] = "type",
["var_declaration"] = "type",
["class_definition"] = "class",
}
local ts_utils = require 'nvim-treesitter.ts_utils'
local current_node = ts_utils.get_node_at_cursor()
while (current_node) do
local v = table[current_node:type()]
if v then
require('neogen').generate({ type = v })
break
else
current_node = current_node:parent()
end
end
end
require("murdock")
require("lir_setup")
require("lualine_setup")