-- theming -- Default options vim.opt.termguicolors = true vim.cmd.colorscheme 'duskfox' -- turn on relative line numbers vim.opt.relativenumber = true vim.opt.number = true vim.opt.expandtab = true vim.opt.paste = false vim.opt.autoindent = true vim.opt.linebreak = true vim.opt.mouse = "" -- neovim tabstop and shift behavior got more complicated. -- This should cover all the cases though vim.opt.tabstop = 4 vim.opt.shiftwidth = 4 --vim.opt.smarttab = false vim.g.BASH_AuthorName = 'Jeremy Wall' vim.g.BASH_AuthorRef = 'jw' vim.g.BASH_Email = 'jeremy@marzhillstudios.com' -- We want to use a different leader key vim.g.mapleader = ',' vim.cmd("noswapfile") vim.cmd("syntax on") vim.cmd("filetype plugin on") vim.cmd([[ au BufNewFile,BufRead *Makefile,*.mk set noexpandtab ]]) vim.cmd([[ au BufNewFile,BufRead *.py,*.java set tabstop=2 ]]) vim.cmd([[ au BufNewFile,BufRead *.app set filetype=erlang ]]) vim.cmd([[ au BufNewFile,BufRead *.tf set filetype=terraform ]]) vim.cmd([[ au BufNewFile,BufRead *.hcl,*.hcl2 set filetype=hcl ]]) vim.cmd([[ au BufNewFile,BufRead .bash_* set filetype=sh ]]) vim.cmd([[ au BufNewFile,BufRead *.sil set filetype=tex ]]) vim.cmd([[ au BufNewFile,BufRead *.erl filetype indent off ]]) vim.cmd([[ au BufNewFile,BufRead *.hrl filetype indent off ]]) -- --https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md -- TODO(jwall): See about proper snippet support (ie. license comments?) local cmp = require('cmp') cmp.setup({ -- Enable LSP snippets snippet = { expand = function(args) vim.fn["vsnip#anonymous"](args.body) end, }, mapping = cmp.mapping.preset.insert { [''] = cmp.mapping.select_prev_item(), [''] = cmp.mapping.select_next_item(), [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, select = true, }, }, -- Installed sources: sources = cmp.config.sources( { { name = 'nvim_lsp', keyword_length = 3 }, -- from language server { name = 'nvim_lsp_signature_help' }, -- display function signatures with current parameter emphasized }, { { name = 'path' }, -- file paths }, { { name = 'nvim_lua', keyword_length = 2 }, -- complete neovim's Lua runtime API such vim.lsp.* { name = 'buffer', keyword_length = 2 }, -- source current buffer { name = 'vsnip', keyword_length = 2 }, -- nvim-cmp source for vim-vsnip }), window = { completion = cmp.config.window.bordered(), documentation = cmp.config.window.bordered(), }, }) -- logging --vim.lsp.set_log_level('trace') --vim.lsp.log.set_format_func(vim.inspect) local caps = vim.tbl_deep_extend( 'force', vim.lsp.protocol.make_client_capabilities(), require('cmp_nvim_lsp').default_capabilities(), -- File watching is disabled by default for neovim. -- See: https://github.com/neovim/neovim/pull/22405 { workspace = { didChangeWatchedFiles = { dynamicRegistration = true } } }, { window = { progress = false } } ); local lspconfig = require("lspconfig") -- Terraform lsp setup lspconfig.terraformls.setup {} -- Nix language server support lspconfig.nil_ls.setup { --single_file_support = true, --on_attach = function(client, bufnr) -- -- disable the semanticTokens because it has issues. -- -- client.server_capabilities.semanticTokensProvider = nil --end, capabilities = caps, } --require('roslyn').setup({ -- on_attach = function (client, _) -- --vim.notify(vim.inspect(client)) -- end, -- capabilities = caps, -- log_level = "Trace", --}); local vim_pid = vim.fn.getpid() -- "FormatterOptions:EnableEditorConfigSupport=true" local omnisharp_cmd = { 'omnisharp', '--languageserver', '-v', '--hostPID', tostring(vim_pid), } local function toSnakeCase(str) return string.gsub(str, "%s*[- ]%s*", "_") end lspconfig.omnisharp.setup { cmd = omnisharp_cmd, enable_roslyn_analyzers = true, enable_editorconfig_support = true, enable_import_completion = true, -- Omnisharp has issues with the semanticTokens feature we need to massage it a bit. on_attach = function(client, bufnr) -- https://github.com/OmniSharp/omnisharp-roslyn/issues/2483#issuecomment-1492605642 local tokenModifiers = client.server_capabilities.semanticTokensProvider.legend.tokenModifiers for i, v in ipairs(tokenModifiers) do tokenModifiers[i] = toSnakeCase(v) end local tokenTypes = client.server_capabilities.semanticTokensProvider.legend.tokenTypes for i, v in ipairs(tokenTypes) do tokenTypes[i] = toSnakeCase(v) end end, handlers = { ["textDocument/definition"] = require('omnisharp_extended').handler, }, capabilities = caps, } --ocaml lspconfig.ocamllsp.setup { capabilities = caps } -- Java language server support lspconfig.java_language_server.setup { capabilities = caps } -- Typescript language server support lspconfig.tsserver.setup { capabilities = caps } -- Rust language server support lspconfig.rust_analyzer.setup { settings = { -- https://github.com/rust-lang/rust-analyzer/blob/master/docs/user/generated_config.adoc ['rust-analyzer'] = { cargo = { features = "all" } } }, capabilities = caps } -- lua language server setup. lspconfig.lua_ls.setup { settings = { Lua = { runtime = { version = 'LuaJIT', }, 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), -- Disable the checkThirdParty prompts. checkThirdParty = false, }, telemetry = { enable = false, }, }, }, capabilities = caps } -- lsp configuration vim.api.nvim_create_autocmd('LspAttach', { callback = function(args) local opts = { buffer = args.buf } vim.keymap.set("n", '', function() vim.lsp.buf.hover() end, opts) vim.keymap.set({ "n", "v" }, "a", vim.lsp.buf.code_action, opts) vim.keymap.set("n", "f", vim.lsp.buf.format, opts) local client = vim.lsp.get_client_by_id(args.data.client_id) if client.server_capabilities.codelens then vim.lsp.codelens.refresh() end end, }) vim.api.nvim_create_autocmd({ 'BufEnter', 'InsertLeave', 'CursorHold' }, { callback = function(_) local clients = vim.lsp.get_active_clients() for cid = 1, #clients do if clients[cid].server_capabilities.codelens then vim.lsp.codelens.refresh() break end end end, }) -- LSP Diagnostics Options Setup local sign = function(opts) vim.fn.sign_define(opts.name, { texthl = opts.name, text = opts.text, numhl = '' }) end sign({ name = 'DiagnosticSignError', text = '🔥' }) sign({ name = 'DiagnosticSignWarn', text = '⚠️' }) sign({ name = 'DiagnosticSignHint', text = '➡️' }) sign({ name = 'DiagnosticSignInfo', text = '🗒️' }) vim.diagnostic.config({ virtual_text = false, signs = true, update_in_insert = true, underline = true, severity_sort = false, float = { border = 'rounded', source = 'always', header = '', prefix = '', }, }) vim.cmd([[ set signcolumn=yes autocmd CursorHold * lua vim.diagnostic.open_float(nil, { focusable = false }) ]]) --Set completeopt to have a better completion experience -- :help completeopt -- menuone: popup even when there's only one match -- noinsert: Do not insert text until a selection is made -- noselect: Do not select, force to select one from the menu -- shortness: avoid showing extra messages when using completion -- updatetime: set updatetime for CursorHold vim.opt.completeopt = { 'menuone', 'noselect', 'noinsert' } vim.opt.shortmess = vim.opt.shortmess + { c = true } vim.api.nvim_set_option('updatetime', 300) vim.opt.sessionoptions = { 'buffers', 'curdir', 'skiprtp', 'localoptions', 'terminal', 'tabpages' } -- Fixed column for diagnostics to appear -- Show autodiagnostic popup on cursor hover_range -- Goto previous / next diagnostic warning / error -- Show inlay_hints more frequently vim.cmd([[ set signcolumn=yes autocmd CursorHold * lua vim.diagnostic.open_float(nil, { focusable = false }) ]]) -- Treesitter Plugin Setup require('nvim-treesitter.configs').setup { highlight = { enable = true, additional_vim_regex_highlighting = false, }, indent = { enable = true }, rainbow = { enable = true, extended_mode = true, max_file_lines = nil, }, --textobjects = { -- enable = true, -- select = { -- enable = true, -- lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim -- keymaps = { -- -- You can use the capture groups defined in textobjects.scm -- ['aa'] = '@parameter.outer', -- ['ia'] = '@parameter.inner', -- ['af'] = '@function.outer', -- ['if'] = '@function.inner', -- ['ac'] = '@class.outer', -- ['ic'] = '@class.inner', -- }, -- }, --}, --incremental_selection = { -- enable = true, -- keymaps = { -- init_selection = 'c', -- node_incremental = 'c', -- scope_incremental = 'ci', -- node_decremental = 'cx', -- }, --}, } require 'treesitter-context'.setup { enable = true, -- Enable this plugin (Can be enabled/disabled later via commands) max_lines = 5, -- How many lines the window should span. Values <= 0 mean no limit. min_window_height = 45, -- Minimum editor window height to enable context. Values <= 0 mean no limit. line_numbers = true, multiline_threshold = 20, -- Maximum number of lines to collapse for a single context line trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' -- Separator between context and content. Should be a single character string, like '-'. -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. separator = nil, zindex = 20, -- The Z-index of the context window on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching } vim.g.loaded_netrw = 1 vim.g.loaded_netrwPlugin = 1 -- set termguicolors to enable highlight groups vim.opt.termguicolors = true -- setup nvim-tree require("nvim-tree").setup { hijack_unnamed_buffer_when_opening = true, update_focused_file = { enable = true, }, renderer = { icons = { show = { file = false, }, glyphs = { default = "-", symlink = "S", bookmark = "🎗", modified = "●", folder = { arrow_closed = "→", arrow_open = "↓", default = "📁", open = "📂", empty = "📁", empty_open = "📂", symlink = "S", symlink_open = "S", }, git = { unstaged = "✗", staged = "✓", unmerged = "∦", renamed = "➜", untracked = "★", deleted = "X", ignored = "◌", }, }, }, }, diagnostics = { enable = true, show_on_dirs = true, icons = { hint = "➡️", info = "🗒️", warning = "⚠️", error = "🔥", }, }, } require('trouble').setup { icons = false, signs = { hint = "➡️", information = "🗒️", warning = "⚠️", error = "🔥", other = "?", }, } vim.keymap.set("n", "", function() require("nvim-tree.api").tree.toggle() end) vim.keymap.set("n", "tc", function() vim.cmd("tabclose") end) vim.keymap.set("n", "tn", function() vim.cmd("tabnew") end) vim.keymap.set("n", "tk", function() vim.cmd("tabnext") end) vim.keymap.set("n", "tj", function() vim.cmd("tabprev") end) vim.keymap.set("n", "ts", function() vim.cmd("tabs") end) vim.keymap.set("n", "mg", function() vim.cmd("MagitOnly") end) require('possession').setup { commands = { save = 'SSave', load = 'SLoad', delete = 'SDelete', list = 'SList', }, autosave = { current = true, on_load = true, on_quit = true, }, telescope = { list = { default_action = 'load', mappings = { save = { n = '', i = '' }, load = { n = '', i = '' }, delete = { n = '', i = '' }, rename = { n = '', i = '' }, }, }, }, } -- Telelscope configuration local telescope = require('telescope') local telescope_builtins = require('telescope.builtin') local telescope_actions = require('telescope.actions') telescope.load_extension('possession') -- https://github.com/nvim-telescope/telescope.nvim telescope.setup({ defaults = { initial_mode = "normal", mappings = { n = { ["ql"] = telescope_actions.send_selected_to_qflist + telescope_actions.open_qflist, }, }, }, }) local harpoon = require('harpoon') harpoon:setup() local lean = require 'lean' lean.setup { lsp = { on_attach = function(client, bufnr) local opts = { buffer = bufnr } vim.keymap.set({ "n", "v" }, "ti", function() vim.cmd("LeanInfoviewToggle") end, opts) vim.keymap.set({ "n", "v" }, "sg", function() vim.cmd("LeanGoal") end, opts) vim.keymap.set({ "n", "v" }, "stg", function() vim.cmd("LeanTermGoal") end, opts) vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') end }, mappings = true, } -- telescope keymaps vim.keymap.set("n", "pl", telescope.extensions.possession.list) vim.keymap.set("n", "nff", telescope_builtins.fd) vim.keymap.set("n", "rl", telescope_builtins.lsp_references) vim.keymap.set("n", "rn", vim.lsp.buf.rename) vim.keymap.set("n", "sl", telescope_builtins.lsp_workspace_symbols) vim.keymap.set("n", "dl", telescope_builtins.diagnostics) vim.keymap.set("n", "rg", telescope_builtins.live_grep) vim.keymap.set("n", "bl", function() telescope_builtins.buffers({}) end) -- harpoon keymaps vim.keymap.set("n", "ha", function() harpoon:list():append() end) vim.keymap.set("n", "he", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end) vim.keymap.set("n", "hj", function() harpoon:list():prev() end) vim.keymap.set("n", "hk", function() harpoon:list():next() end) -- codelens keymaps vim.keymap.set("n", "rr", vim.lsp.codelens.run) -- debugging DAP keymaps vim.keymap.set("n", "tdb", function() vim.cmd("DBUIToggle") end) local dap = require('dap') dap.adapters.lldb = { type = "executable", command = "/run/current-system/sw/bin/lldb", name = "lldb", } dap.adapters.coreclr = { type = 'executable', command = '/run/current-system/sw/bin/netcoredbg', args = { '--interpreter=vscode' } } dap.configurations.rust = { { name = 'Launch Rust', type = 'lldb', request = 'launch', program = function() return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') end, cwd = '${workspaceFolder}', stopOnEntry = false, args = {}, }, } dap.configurations.cs = { { name = "Launch - netcoredbg", type = "coreclr", request = "launch", program = function() return vim.fn.input('Path to dll', vim.fn.getcwd(), 'file') end, }, }