require('nvim-autopairs').setup {} -- nvim_lsp object local nvim_lsp = require 'lspconfig' require('cmp_setup') -- 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() 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', } } default_capabilities = require('cmp_nvim_lsp').default_capabilities(default_capabilities) -- Enable rust_analyzer nvim_lsp.rust_analyzer.setup({ on_attach = function(client, bufnr) client.server_capabilities.semanticTokensProvider = nil end, capabilities = default_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, capabilities = default_capabilities, 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, capabilities = default_capabilities, }) --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, capabilities = default_capabilities } nvim_lsp.ts_ls.setup { cmd = { "/home/barak/.yarn/bin/typescript-language-server", "--stdio" } } nvim_lsp.vuels.setup { cmd = { "/home/barak/.yarn/bin/vls" }, capabilities = default_capabilities, } nvim_lsp.hls.setup { cmd = { "haskell-language-server-wrapper", "--lsp" }, capabilities = default_capabilities, } nvim_lsp.svelte.setup { cmd = { "/home/barak/.bun/bin/bunx", "svelteserver", "--stdio" }, capabilities = default_capabilities, } local runtime_path = vim.split(package.path, ';') table.insert(runtime_path, "lua/?.lua") table.insert(runtime_path, "lua/?/init.lua") nvim_lsp.lua_ls.setup { capabilities = default_capabilities, 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, }, } nvim_lsp.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 ) --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 "" --elseif check_back_space() then --return t "" --else --return vim.fn['compe#complete']() --end --end --_G.s_tab_complete = function() --if vim.fn.pumvisible() == 1 then --return t "" --else --return t "" --end --end --vim.api.nvim_set_keymap("i", "", "v:lua.tab_complete()", { expr = true }) --vim.api.nvim_set_keymap("s", "", "v:lua.tab_complete()", { expr = true }) --vim.api.nvim_set_keymap("i", "", "v:lua.s_tab_complete()", { expr = true }) --vim.api.nvim_set_keymap("s", "", "v:lua.s_tab_complete()", { expr = true }) --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 = "", -- cancel the preview and get back to your last window / buffer / cursor --refresh = "r", -- manually refresh jump = { "o", "" }, -- jump to the diagnostic or open / close folds --open_split = { "" }, -- open buffer in new split --open_vsplit = { "" }, -- open buffer in new vsplit open_tab = {}, -- open buffer in new tab jump_close = { "" }, -- 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.sources.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, [""] = trouble_telescope.open, }, i = { [""] = trouble_telescope.open, ["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 = '', show_help = '?', }, } } require "neogen".setup {} require('leap').set_default_keymaps() require("flit").setup {} require('snippy').setup({ mappings = { is = { [',,'] = 'expand_or_advance', [',.'] = 'previous', }, nx = { ['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("hoversplit").setup({}) --require("murdock") --require("ollama_setup") --require("gen_setup") require("lir_setup") require("lualine_setup") require("avante_setup")