-- Keybindings local map = vim.api.nvim_set_keymap map('n', '', 'h', { noremap = true }) map('n', '', 'j', { noremap = true }) map('n', '', 'k', { noremap = true }) map('n', '', 'l', { noremap = true }) map('n', '', ':q', { noremap = true }) -- Autocommands vim.cmd('au FileType rust inoremap :update') vim.cmd('au TextChanged,FocusLost,BufEnter *.rs silent update') vim.cmd('au BufEnter * set noro') vim.cmd('au CursorHold * lua vim.lsp.diagnostic.show_line_diagnostics({ focusable = false })') vim.cmd('au CursorHoldI * silent! lua vim.lsp.buf.signature_help()') -- Settings vim.opt.relativenumber = true vim.opt.number = true vim.opt.cursorline = true vim.opt.signcolumn = "yes:3" vim.opt.title = true vim.opt.updatetime = 0 vim.opt.clipboard:prepend('unnamedplus') local runtimedir = os.getenv('XDG_RUNTIME_DIR') vim.opt.directory:prepend(runtimedir..'/vim/swap//') vim.opt.undodir:prepend(runtimedir..'/vim/undo//') vim.opt.swapfile = true vim.opt.undofile = true vim.opt.hlsearch = true vim.opt.ignorecase = true vim.opt.smartcase = true vim.opt.incsearch = true vim.opt.tabstop = 8 vim.opt.softtabstop = 0 vim.opt.expandtab = true vim.opt.shiftwidth = 4 vim.opt.smarttab = true vim.g.signify_priority = 5 vim.g.signify_sign_show_count = 0 vim.g.signify_sign_add = '┃' vim.g.signify_sign_delete = vim.g.signify_sign_add vim.g.signify_sign_delete_first_line = '┏━' vim.g.signify_sign_change = vim.g.signify_sign_add vim.g.signify_sign_change_delete = vim.g.signify_sign_delete -- Theming vim.g.tokyonight_style = 'night' vim.cmd[[ syntax enable colorscheme tokyonight ]] local colors = require("tokyonight.colors").setup {} vim.cmd("highlight SignifySignAdd guifg="..colors.green) vim.cmd("highlight SignifySignChange guifg="..colors.orange) vim.cmd("highlight SignifySignDelete guifg="..colors.red) vim.cmd("highlight SignifySignDeleteFirstLine guifg="..colors.red) vim.cmd("highlight SignifySignChangeDelete guifg="..colors.red) -- Plugins require('nvim-treesitter.configs').setup { highlight = { enable = true }, indent = { enable = false } } require('lualine').setup { options = { theme = 'tokyonight' } } -- Block comments indent workaround -- many thanks to @kristijanhusak -- https://github.com/nvim-treesitter/nvim-treesitter/issues/1167#issuecomment-920824125 function _G.javascript_indent() local line = vim.fn.getline(vim.v.lnum) local prev_line = vim.fn.getline(vim.v.lnum - 1) if line:match('^%s*[%*/]%s*') then if prev_line:match('^%s*%*%s*') then return vim.fn.indent(vim.v.lnum - 1) end if prev_line:match('^%s*/%*%*%s*$') then return vim.fn.indent(vim.v.lnum - 1) + 1 end end return vim.fn['GetJavascriptIndent']() end vim.cmd('au FileType javascript setlocal indentexpr=v:lua.javascript_indent()') -- LSP local nvim_lsp = require('lspconfig') local on_attach = function(client, bufnr) local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') local opts = { noremap = true, silent = true } buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts) buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts) buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) buf_set_keymap('n', 'e', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) buf_set_keymap('n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts) buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts) end vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with( vim.lsp.diagnostic.on_publish_diagnostics, { virtual_text = false, underline = true, signs = true, update_in_insert = true } ) local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities = require('cmp_nvim_lsp').update_capabilities(capabilities) local servers = { 'cssls', 'html', 'rnix', 'rust_analyzer', 'tsserver', 'yamlls' } for _, lsp in ipairs(servers) do nvim_lsp[lsp].setup { capabilities = capabilities, on_attach = on_attach, flags = { debounce_text_changes = 150, } } end -- nvim-cmp local luasnip = require('luasnip') local cmp = require('cmp') cmp.setup { snippet = { expand = function(args) luasnip.lsp_expand(args.body) end }, mapping = { [''] = cmp.mapping.select_next_item(), [''] = cmp.mapping.select_prev_item(), [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.close(), [''] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, select = true, }, [''] = function(fallback) if cmp.visible() then cmp.select_next_item() elseif luasnip.expand_or_jumpable() then vim.fn.feedkeys(vim.api.nvim_replace_termcodes('luasnip-expand-or-jump', true, true, true), '') else fallback() end end, [''] = function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.jumpable(-1) then vim.fn.feedkeys(vim.api.nvim_replace_termcodes('luasnip-jump-prev', true, true, true), '') else fallback() end end }, sources = { { name = 'nvim_lsp' }, { name = 'luasnip' } } } -- LSP/Omnisharp local pid = vim.fn.getpid() require'lspconfig'.omnisharp.setup { capabilities = capabilities, on_attach = on_attach, cmd = { "{{OMNISHARP_PATH}}", "--languageserver", "--hostPID", tostring(pid) } } -- LSP/Diagnostics nvim_lsp.diagnosticls.setup { capabilities = capabilities, on_attach = on_attach, filetypes = { 'javascript', 'javascriptreact', 'typescript', 'typescriptreact' }, init_options = { linters = { eslint = { command = 'eslint_d', rootPatterns = { '.git' }, debounce = 100, args = { '--stdin', '--stdin-filename', '%filepath', '--format', 'json' }, sourceName = 'eslint', parseJson = { errorsRoot = '[0].messages', line = 'line', column = 'column', endLine = 'endLine', endColumn = 'endColumn', message = '[eslint] ${message} [${ruleId}]', security = 'severity' }, securities = { [2] = 'error', [1] = 'warning' } } }, filetypes = { javascript = 'eslint', javascriptreact = 'eslint', typescript = 'eslint', typescriptreact = 'eslint' } } }