" Prefer $HOME/.vim to $HOME/.config/nvim (for now): " TODO: refactor file structure for nvim set runtimepath^=~/.vim runtimepath+=~/.vim/after runtimepath+=~/.vim/lua let &packpath = &runtimepath set background=dark syntax on filetype plugin indent on let mapleader=',' " netrw let g:netrw_banner = 0 let g:netrw_liststyle = 1 let g:netrw_list_hide = '^\.' let g:netrw_winsize=25 map n :Lexplore " fix helptags for opt/ plugins " https://vi.stackexchange.com/questions/17210/generating-help-tags-for-packages-that-are-loaded-by-vim-8s-package-management command! -nargs=0 -bar Helptags \ for p in glob('~/.vim/pack/git-plugins/opt/*', 1, 1) \| exe 'packadd ' . fnamemodify(p, ':t') \| endfor \| helptags ALL set shiftwidth=2 set shiftround set tabstop=2 set expandtab set smarttab set splitbelow set splitright set encoding=utf-8 set hidden set nowrap set smartindent set copyindent set autoindent set hlsearch set showmatch set wildmenu set wildmode=list:full,full set number set norelativenumber set ruler set backspace=indent,eol,start set ignorecase set smartcase set incsearch set history=1000 set undolevels=1000 set title set novisualbell set noerrorbells set nobackup set noswapfile set mouse=a set mousemodel=popup_setpos " https://github.com/tpope/vim-sensible/issues/78: set lazyredraw set timeoutlen=1000 set scrolloff=15 set dictionary=/usr/share/dict/words " See :help thesaurus set thesaurus=$HOME/Documents/thesaurus/thesaurus_pkg/thesaurus.txt set shortmess+=I set updatetime=250 set pastetoggle= set pumheight=200 " Required for nvim-compe: set complete-=i set nrformats-=octal set ttimeout set ttimeoutlen=100 set formatoptions+=j set autoread " https://github.com/tpope/vim-sensible/issues/142: set synmaxcol=500 " Enable 24-bit colours. " https://github.com/alacritty/alacritty/issues/109#issuecomment-440353106 if exists('+termguicolors') let &t_8f="\[38;2;%lu;%lu;%lum" let &t_8b="\[48;2;%lu;%lu;%lum" set termguicolors endif " Colour scheme: packadd! nord-vim " https://github.com/arcticicestudio/nord-vim.git colorscheme nord augroup vimrc autocmd! " Automatically load/save views on files. " https://vi.stackexchange.com/posts/13874/revisions autocmd BufWinLeave,BufLeave,BufWritePost,BufHidden,QuitPre ?* nested silent! mkview! autocmd BufWinEnter ?* silent! loadview " set cursor line highlight in insert mode. autocmd InsertEnter * set cul autocmd InsertLeavePre * set nocul " use tabs in .gitconfig autocmd BufEnter .gitconfig setlocal shiftwidth=2 tabstop=2 noexpandtab " Quickfix window is always full-width. " https://github.com/fatih/vim-go/issues/1757#issuecomment-565130503 autocmd FileType qf if (getwininfo(win_getid())[0].loclist != 1) | wincmd J | endif " Remove trailing whitespace pre-save: autocmd FileType go,ruby,markdown,rust,python,markdown,lua autocmd BufWritePre silent! %s/\s\+$//e augroup end " Don't remember the current directory for a given file: set viewoptions-=curdir set viewoptions-=options set sessionoptions-=options " Key mappings: nnoremap j gj nnoremap k gk map map map map imap imap imap imap nmap ]q :cn nmap [q :cp nnoremap w :up nnoremap / :nohlsearch nnoremap :nohlsearch " Select just-pasted text: nnoremap 0 `[v`] " Select just-pasted text and re-indent: nnoremap ) `[v`]= nnoremap 1 :set relativenumber! nnoremap ! :windo set norelativenumber nnoremap m :marks nnoremap v :vsplit nnoremap s :split nnoremap rp "_ddP nnoremap dq ggVG"_d:wq " abbrevs iabbrev esdebug debugger; // eslint-disable-line no-debugger iabbrev bashstrict set -euo pipefailIFS=$'\n\t' " include all lua lua require("main") " Function to eat trailing character when applying iabbrevs. " https://stackoverflow.com/questions/11858927/preventing-trailing-whitespace-when-using-vim-abbreviations func! Eatchar(pat) let c = nr2char(getchar(0)) return (c =~ a:pat) ? '' : c endfunc " Git mappings " " Copy Git permalink to clipboard for either current line or range function! CopyGitURLToLineOrRange() range if a:firstline == a:lastline execute ".GBrowse!" else execute a:firstline . "," . a:lastline . "GBrowse!" endif endfunction function! OpenGitURLToLineOrRange() range if a:firstline == a:lastline execute ".GBrowse" else execute a:firstline . "," . a:lastline . "GBrowse" endif endfunction nnoremap as :Git nnoremap ab :Git blame nnoremap ac :Commits nnoremap ah :GitGutterLineHighlightsToggle nnoremap aY :call CopyGitURLToLineOrRange() vnoremap aY :call CopyGitURLToLineOrRange() nnoremap ao :call OpenGitURLToLineOrRange() nnoremap ap :execute 'silent !ghpr ' \| redraw! " echo filename of current buffer: nmap fe :echom expand("%:p") " yank filename of current buffer: function! CopyToDefaultRegister() let @" = expand("%:p") echom expand("%:p") endfunction nmap fy :call CopyToDefaultRegister() " and into + register: function! CopyToSystemClipboard() let @* = expand("%:p") let @+ = expand("%:p") echom expand("%:p") endfunction nmap fY :call CopyToSystemClipboard() " disable Ex mode nnoremap Q function! ToggleQuickFix() if empty(filter(getwininfo(), 'v:val.quickfix')) copen else cclose endif endfunction nmap q :call ToggleQuickFix() nmap l :lclose " vim-markdown configuration: let g:vim_markdown_conceal = 1 " fzf configuration: let g:fzf_action = { \ 'ctrl-h': 'leftabove vsplit', \ 'ctrl-j': 'rightbelow split', \ 'ctrl-k': 'leftabove split', \ 'ctrl-l': 'rightbelow vsplit', \ 'ctrl-o': 'only | e', \ 'ctrl-s': 'split', \ 'ctrl-t': 'tab split', \ 'ctrl-v': 'vsplit', \ } nmap t :GFiles nmap T :Files nmap b :Buffers nmap rg :Rg " Lightline configuration: packadd! lightline.vim " https://github.com/itchyny/lightline.vim.git set laststatus=2 function! LightlineLSPErrorText() let l:count = luaeval("vim.diagnostic.get(0, [[Error]])") if l:count == 0 return '' endif return l:count . 'E' endfunction function! LightlineLSPWarningText() let l:count = luaeval("vim.diagnostic.get(0, [[Warning]])") if l:count == 0 return '' endif return l:count . 'W' endfunction function! LightlineLSPInformationText() let l:count = luaeval("vim.diagnostic.get(0, [[Information]])") if l:count == 0 return '' endif return l:count . 'I' endfunction let g:lightline = { \ 'colorscheme': 'seoul256', \ 'active': { \ 'left': [ [ 'mode', 'paste' ], \ [ 'readonly', 'filename', 'modified' ], \ [ 'gitbranch' ], ['lsperror', 'lspwarn', 'lspinfo' ] ], \ 'right': [ ['lineinfo'], ['percent'], ['filetype'], ['gobuild'] ], \ }, \ 'component_function': { \ 'gobuild': 'go#statusline#Show', \ 'gitbranch': 'FugitiveStatusline', \ }, \ 'component_expand': { \ 'lsperror': 'LightlineLSPErrorText', \ 'lspwarn': 'LightlineLSPWarningText', \ 'lspinfo': 'LightlineLSPInformationText', \ }, \ 'component_type': { \ 'lsperror': 'error', \ 'lspwarn': 'warning', \ }, \ 'mode_map': { \ 'n' : 'N', \ 'i' : 'I', \ 'R' : 'R', \ 'v' : 'V', \ 'V' : 'V-LINE', \ "\": 'V-BLOCK', \ 'c' : 'C', \ 's' : 'S', \ 'S' : 'S-LINE', \ "\": 'S-BLOCK', \ 't': 'TERM', \ }, \ } " vim-gitgutter configuration packadd! vim-gitgutter " https://github.com/airblade/vim-gitgutter.git set signcolumn=yes nmap ]h (GitGutterNextHunk) nmap [h (GitGutterPrevHunk) omap ih (GitGutterTextObjectInnerPending) omap ah (GitGutterTextObjectOuterPending) xmap ih (GitGutterTextObjectInnerVisual) xmap ah (GitGutterTextObjectOuterVisual) " vim-fugitive packadd! vim-fugitive " https://github.com/tpope/vim-fugitive.git " vim-go " Doesn't work in after/ftplugin/go.vim: let g:go_def_mapping_enabled = 0 packadd! vim-go " https://github.com/fatih/vim-go.git " load internal plugins: runtime macros/matchit.vim " load other plugins: packadd! rust.vim " https://github.com/rust-lang/rust.vim.git packadd! tmux-complete.vim " https://github.com/wellle/tmux-complete.vim.git packadd! vim-commentary " https://github.com/tpope/vim-commentary.git packadd! vim-rails " https://github.com/tpope/vim-rails.git packadd! vim-jsx-pretty " https://github.com/MaxMEllon/vim-jsx-pretty.git " Requires both fzf.vim plugin to be manually installed: " https://github.com/junegunn/fzf/blob/master/plugin/fzf.vim " and also this separate plugin, which is loaded here: packadd! fzf.vim " https://github.com/junegunn/fzf.vim.git packadd! vim-surround " https://github.com/tpope/vim-surround.git packadd! vim-rhubarb " https://github.com/tpope/vim-rhubarb.git packadd! editorconfig-vim " https://github.com/editorconfig/editorconfig-vim.git packadd! vim-wordmotion " https://github.com/chaoren/vim-wordmotion.git " formatter.nvim: see lua/formatter.lua " packadd! formatter.nvim " https://github.com/mhartington/formatter.nvim.git " enable inline vim highlighting: let g:vimsyn_embed= 'lPr' " Treesitter: see lua/treesitter_config.lua " packadd! nvim-treesitter " https://github.com/nvim-treesitter/nvim-treesitter.git " packadd! nvim-treesitter-textobjects " https://github.com/nvim-treesitter/nvim-treesitter-textobjects.git " packadd! nvim-treesitter-refactor " https://github.com/nvim-treesitter/nvim-treesitter-refactor.git " packadd! nvim-treesitter-context " https://github.com/nvim-treesitter/nvim-treesitter-context.git " packadd! playground " https://github.com/nvim-treesitter/playground.git " copilot: see lua/copilot_config.lua " packadd! copilot.lua " https://github.com/zbirenbaum/copilot.lua.git " nvim-cmp: packadd! nvim-cmp " https://github.com/hrsh7th/nvim-cmp.git packadd! copilot-cmp " https://github.com/zbirenbaum/copilot-cmp.git packadd! vim-vsnip " https://github.com/hrsh7th/vim-vsnip.git packadd! cmp-vsnip " https://github.com/hrsh7th/cmp-vsnip.git packadd! cmp-nvim-lsp " https://github.com/hrsh7th/cmp-nvim-lsp.git packadd! cmp-buffer " https://github.com/hrsh7th/cmp-buffer.git packadd! cmp-path " https://github.com/hrsh7th/cmp-path.git packadd! cmp-calc " https://github.com/hrsh7th/cmp-calc lua <'] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.close(), ['C-y'] = cmp.mapping.confirm({ select = true, behaviour = cmp.ConfirmBehavior.Replace }), [''] = cmp.mapping.confirm({ select = true, behaviour = cmp.ConfirmBehavior.Replace }), }), sources = cmp.config.sources({ { name = 'copilot', keyword_length = 0 }, { name = 'nvim_lsp', keyword_length = 3 }, { name = 'buffer', option = { get_bufnrs = function() return vim.api.nvim_list_bufs() end }, }, { name = 'path' }, { name = 'calc' }, }), sorting = { comparators = { function(...) return cmp_buffer:compare_locality(...) end, } }, view = { entries = 'native', }, experimental = { ghost_text = true, }, }) EOF " LSP packadd! nvim-lspconfig " https://github.com/neovim/nvim-lspconfig.git packadd! lsp_signature.nvim " https://github.com/ray-x/lsp_signature.nvim.git packadd! fzf-lsp.nvim " https://github.com/gfanto/fzf-lsp.nvim.git lua <lua vim.lsp.buf.definition()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', 'lua vim.lsp.buf.type_definition()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', 'lua vim.lsp.buf.definition()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', 'lua vim.lsp.buf.type_definition()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'e', 'lua vim.lsp.buf.rename()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'r', 'lua vim.lsp.buf.references()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'i', 'lua vim.lsp.buf.implementation()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ca', 'lua vim.lsp.buf.code_action()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ci', 'lua vim.lsp.buf.incoming_calls()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'co', 'lua vim.lsp.buf.outgoing_calls()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', 'lua vim.lsp.buf.hover()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', ']e', 'lua vim.diagnostic.goto_next({severity="Error"})', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', '[e', 'lua vim.diagnostic.goto_prev({severity="Error"})', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', ']d', 'lua vim.diagnostic.goto_next()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', '[d', 'lua vim.diagnostic.goto_prev()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'cd', 'lua vim.diagnostic.hide(nil, 0)', opts) -- fzf triggers: vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fr', 'References', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fi', 'Implementations', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fs', 'DocumentSymbols', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fw', 'WorkspaceSymbols', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fc', 'CodeActions', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fci', 'IncomingCalls', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'fco', 'OutgoingCalls', opts) require 'lsp_signature'.on_attach({ hint_enable = false, }) require 'copilot_cmp'.setup(); end -- Go local capabilities = require('cmp_nvim_lsp').default_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities.textDocument.completion.completionItem.resolveSupport = { properties = { 'documentation', 'detail', 'additionalTextEdits', } } nvim_lsp.gopls.setup{ settings = { gopls = { staticcheck = true, -- Disalbing linksInHover may not be working as expected: linksInHover = false, usePlaceholders = true, analyses = { unusedparams = true, shadow = true, unusedwrite = true, unusedresult = true, nilness = true, }, }, }, capabilities = capabilities, on_attach = on_attach, } -- Rust nvim_lsp.rust_analyzer.setup{ capabilities = capabilities, on_attach = on_attach, settings = { ["rust-analyzer"] = { imports = { granularity = { group = "module", }, prefix = "self", }, cargo = { buildScripts = { enable = true, }, }, procMacro = { enable = false, }, diagnostics = { disabled = { "unresolved-proc-macro" }, } } } } -- Ruby nvim_lsp.solargraph.setup{ on_attach = on_attach, } -- Typescript -- https://jose-elias-alvarez.medium.com/configuring-neovims-lsp-client-for-typescript-development-5789d58ea9c nvim_lsp.tsserver.setup{ on_attach = on_attach, } local filetypes = { typescript = "eslint", typescriptreact = "eslint", } -- diagnosticls local linters = { eslint = { sourceName = "eslint", -- fallback to global eslint if the local is not found? -- https://github.com/creativenull/diagnosticls-configs-nvim/blob/e7d6f7e99f6b416d2aeee89314bc46fc36df7b22/lua/diagnosticls-configs/fs.lua#L20 command = "./node_modules/.bin/eslint", rootPatterns = {".eslintrc", ".eslintrc.js"}, debounce = 100, args = {"--stdin", "--stdin-filename", "%filepath", "--format", "json"}, parseJson = { errorsRoot = "[0].messages", line = "line", column = "column", endLine = "endLine", endColumn = "endColumn", message = "${message} [${ruleId}]", security = "severity" }, securities = {[1] = "error", [2] = "warning"} } } nvim_lsp.diagnosticls.setup{ on_attach = on_attach, filetypes = vim.tbl_keys(filetypes), init_options = { linters = linters, filetypes = filetypes, } } -- Lua local lua_ls_root_path = os.getenv("HOME").."/dev/lua-language-server" local lua_ls_binary = lua_ls_root_path.."/bin/lua-language-server" 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 { cmd = {lua_ls_binary, "-E", lua_ls_root_path .. "/main.lua"}; settings = { Lua = { runtime = { version = 'LuaJIT', path = runtime_path, }, diagnostics = { globals = {'vim'}, }, workspace = { library = vim.api.nvim_get_runtime_file("", true), }, telemetry = { enable = false, }, }, }, on_attach = on_attach, } EOF