├── .envrc ├── .gitignore ├── .ideavimrc ├── .ripgreprc ├── .vsvimrc ├── LICENSE.txt ├── README.md ├── coc-settings.json ├── coc_nvim.vim ├── colors └── .gitkeep ├── flake.lock ├── flake.nix ├── gui.vim ├── helpers ├── autosave.vim ├── close_initial_empty_tab.vim └── functions.vim ├── init.vim ├── lazy-lock.json ├── lua ├── config │ └── lazy.lua ├── init.lua ├── lsp │ ├── init.lua │ └── lua_ls.lua └── plugins │ ├── cmp.lua │ ├── copilot_chat.lua │ ├── dap.lua │ ├── dap_persistent_breakpoints.lua │ ├── dap_ui.lua │ ├── dap_virtual_text.lua │ ├── mini.lua │ ├── no_config.lua │ ├── overseer.lua │ ├── treesitter.lua │ ├── trouble.lua │ └── which_key.lua ├── manage_plugins.vim ├── maps.vim ├── nerdtree.vim ├── plugins.vim ├── plugins_config.vim ├── queries └── gotmpl │ └── injections.scm ├── session_management.vim ├── shell.nix └── theme.vim /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .netrwhist 2 | autoload/plug.vim 3 | plugged 4 | .session.vim 5 | .session.nvim 6 | *.old 7 | .direnv 8 | -------------------------------------------------------------------------------- /.ideavimrc: -------------------------------------------------------------------------------- 1 | set number 2 | set relativenumber 3 | " display incomplete commands 4 | set showcmd 5 | " Whitespace 6 | set nowrap " don't wrap lines 7 | set tabstop=2 shiftwidth=2 " a tab is two spaces (or set this to 4) 8 | set expandtab " use spaces, not tabs (optional) 9 | set backspace=indent,eol,start " backspace through everything in insert mode 10 | 11 | " Searching 12 | set hlsearch " highlight matches 13 | set incsearch " incremental searching 14 | set ignorecase " searches are case insensitive... 15 | set smartcase " ... unless they contain at least one capital letter 16 | 17 | " My customizations 18 | set ls=2 " always show status bar 19 | set number " show line numbers 20 | set cursorline " display a marker on current line 21 | imap jj 22 | nmap oo ok 23 | nmap OO Oj 24 | au GUIEnter * simalt ~x 25 | nmap :mksession! " Quick write session with F9 26 | nmap :source Session.vim " And load session with F10 27 | set wrapscan 28 | 29 | " remap split navigation 30 | nnoremap 31 | nnoremap 32 | nnoremap 33 | nnoremap 34 | 35 | " highlight trailing white spaces: 36 | highlight ExtraWhitespace ctermbg=red guibg=red 37 | match ExtraWhitespace /\s\+$/ 38 | autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ 39 | autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@ 20 | nmap oo ok 21 | nmap OO Oj 22 | au GUIEnter * simalt ~x 23 | nmap :mksession! " Quick write session with F9 24 | nmap :source Session.vim " And load session with F10 25 | set wrapscan 26 | 27 | " remap split navigation 28 | nnoremap 29 | nnoremap 30 | nnoremap 31 | nnoremap 32 | 33 | " highlight trailing white spaces: 34 | highlight ExtraWhitespace ctermbg=red guibg=red 35 | match ExtraWhitespace /\s\+$/ 36 | autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ 37 | autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@ ~/.vimrc 18 | ``` 19 | 20 | Neovim: 21 | 22 | ```bash 23 | # either clone directory to nvim config dir 24 | git clone --recursive https://github.com/giggio/vimfiles.git ~/.config/nvim/ 25 | # or symlink this directory to ~/.config/nvim 26 | ln -s /path/to/your/clone ~/.config/nvim/ 27 | # sharing with the vim directory, it would be: 28 | ln -s $HOME/.vim ~/.config/nvim/ 29 | ``` 30 | 31 | ### Windows (PowerShell Core) 32 | 33 | Vim: 34 | 35 | ```powershell 36 | git clone --recursive https://github.com/giggio/vimfiles.git ~/.vim 37 | # or git clone --recursive git@github.com:giggio/vimfiles.git ~/.vim 38 | # I'm using scoop to install Python, adapt at your will: 39 | Set-Content -NoNewline -Path ~/_vimrc -Value "let `$PYTHONHOME = '$env:USERPROFILE\scoop\apps\python\current\'`nsource $($($env:USERPROFILE).Replace('\', '/'))/.vim/init.vim`n" 40 | ``` 41 | 42 | Neovim: 43 | 44 | ```powershell 45 | # TBD 46 | ``` 47 | 48 | Notes on Windows' version: The normal Vim home (`runtimepath`) would be at 49 | `~/vimfiles`, but this is changed to `~/.vim` so that Linux and Windows work the 50 | same way. 51 | -------------------------------------------------------------------------------- /coc-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.procMacro.enable": true, 3 | "rust-analyzer.check.command": "clippy", 4 | "languageserver": { 5 | "nixd": { 6 | "command": "nixd", 7 | "rootPatterns": [".nixd.json"], 8 | "filetypes": ["nix"] 9 | }, 10 | "dockerfile": { 11 | "command": "docker-langserver", 12 | "filetypes": ["dockerfile"], 13 | "args": ["--stdio"] 14 | }, 15 | "dockercompose": { 16 | "command": "docker-compose-langserver", 17 | "args": ["--stdio"], 18 | "filetypes": ["dockercompose"], 19 | "rootPatterns": [".git", ".env", "docker-compose.yml", "compose.yml"] 20 | }, 21 | "systemd-language-server": { 22 | "command": "systemd-language-server", 23 | "filetypes": ["systemd"] 24 | }, 25 | "csharp-ls": { 26 | "command": "csharp-ls", 27 | "filetypes": ["cs"], 28 | "rootPatterns": ["*.sln", ".git/"] 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /coc_nvim.vim: -------------------------------------------------------------------------------- 1 | 2 | function! SetupCocCustomizations() 3 | if !exists("g:coc_service_initialized") 4 | return 5 | endif 6 | let g:coc_global_extensions = [ 7 | \ 'coc-angular', 8 | \ 'coc-css', 9 | \ 'coc-html', 10 | \ 'coc-json', 11 | \ 'coc-markdownlint', 12 | \ 'coc-rust-analyzer', 13 | \ 'coc-sh', 14 | \ 'coc-snippets', 15 | \ 'coc-tsserver', 16 | \ 'coc-vimlsp', 17 | \ '@yaegassy/coc-marksman', 18 | \] 19 | let g:coc_snippet_next="" 20 | let g:coc_snippet_prev="" 21 | 22 | if has("autocmd") 23 | augroup SetupCocFileTypes 24 | autocmd! 25 | autocmd FileType yaml if bufname("%") =~# "docker-compose.yml" | set ft=yaml.docker-compose | endif 26 | autocmd FileType yaml if bufname("%") =~# "compose.yml" | set ft=yaml.docker-compose | endif 27 | augroup END 28 | endif 29 | 30 | let g:coc_filetype_map = { 31 | \ 'yaml.docker-compose': 'dockercompose', 32 | \ } 33 | 34 | " this is what the ctrl+. from vscode, now \. 35 | nmap . (coc-codeaction-line) 36 | " this is refactoring, now \, 37 | nmap , (coc-codeaction-refactor) 38 | " im not sure 39 | 40 | " Bellow is from example config: 41 | " https://github.com/neoclide/coc.nvim/blob/master/doc/coc-example-config.vim 42 | 43 | " May need for Vim (not Neovim) since coc.nvim calculates byte offset by count 44 | " utf-8 byte sequence 45 | set encoding=utf-8 46 | " Some servers have issues with backup files, see #649 47 | set nobackup 48 | set nowritebackup 49 | 50 | " Having longer updatetime (default is 4000 ms = 4s) leads to noticeable 51 | " delays and poor user experience 52 | set updatetime=300 53 | 54 | " Always show the signcolumn, otherwise it would shift the text each time 55 | " diagnostics appear/become resolved 56 | set signcolumn=yes 57 | 58 | " Make to accept selected completion item or notify coc.nvim to format 59 | " u breaks current undo, please make your own choice 60 | inoremap coc#pum#visible() ? coc#pum#confirm() 61 | \: "\u\\=coc#on_enter()\" 62 | 63 | function! CheckBackspace() abort 64 | let col = col('.') - 1 65 | return !col || getline('.')[col - 1] =~# '\s' 66 | endfunction 67 | 68 | " Use to trigger completion 69 | if has('nvim') 70 | inoremap coc#refresh() 71 | else 72 | inoremap coc#refresh() 73 | endif 74 | 75 | " Use `[g` and `]g` to navigate diagnostics 76 | " Use `:CocDiagnostics` to get all diagnostics of current buffer in location list 77 | nmap [g (coc-diagnostic-prev) 78 | nmap ]g (coc-diagnostic-next) 79 | 80 | " GoTo code navigation 81 | nmap gd (coc-definition) 82 | nmap gy (coc-type-definition) 83 | nmap gi (coc-implementation) 84 | nmap gr (coc-references) 85 | 86 | " Use K to show documentation in preview window 87 | nnoremap K :call ShowDocumentation() 88 | 89 | function! ShowDocumentation() 90 | if CocAction('hasProvider', 'hover') 91 | call CocActionAsync('doHover') 92 | else 93 | call feedkeys('K', 'in') 94 | endif 95 | endfunction 96 | 97 | " Highlight the symbol and its references when holding the cursor 98 | if has("autocmd") 99 | augroup SetupCocCursorHold 100 | autocmd! 101 | autocmd CursorHold * silent call CocActionAsync('highlight') 102 | augroup END 103 | endif 104 | 105 | " Symbol renaming 106 | nmap rn (coc-rename) 107 | 108 | " Formatting selected code 109 | xmap F (coc-format-selected) 110 | nmap F (coc-format-selected) 111 | 112 | if has("autocmd") 113 | augroup SetupCocFormatExpr 114 | autocmd! 115 | autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') 116 | augroup end 117 | endif 118 | 119 | " Applying code actions to the selected code block 120 | " Example: `aap` for current paragraph 121 | xmap a (coc-codeaction-selected) 122 | nmap a (coc-codeaction-selected) 123 | 124 | " Remap keys for applying code actions at the cursor position 125 | nmap ac (coc-codeaction-cursor) 126 | " Remap keys for apply code actions affect whole buffer 127 | nmap as (coc-codeaction-source) 128 | " Apply the most preferred quickfix action to fix diagnostic on the current line 129 | nmap qf (coc-fix-current) 130 | 131 | " Remap keys for applying refactor code actions 132 | nmap re (coc-codeaction-refactor) 133 | xmap r (coc-codeaction-refactor-selected) 134 | nmap r (coc-codeaction-refactor-selected) 135 | 136 | " Run the Code Lens action on the current line 137 | nmap cl (coc-codelens-action) 138 | 139 | " Map function and class text objects 140 | " NOTE: Requires 'textDocument.documentSymbol' support from the language server 141 | xmap if (coc-funcobj-i) 142 | omap if (coc-funcobj-i) 143 | xmap af (coc-funcobj-a) 144 | omap af (coc-funcobj-a) 145 | xmap ic (coc-classobj-i) 146 | omap ic (coc-classobj-i) 147 | xmap ac (coc-classobj-a) 148 | omap ac (coc-classobj-a) 149 | 150 | " Remap and to scroll float windows/popups 151 | if has('nvim-0.4.0') || has('patch-8.2.0750') 152 | nnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" 153 | nnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" 154 | inoremap coc#float#has_scroll() ? "\=coc#float#scroll(1)\" : "\" 155 | inoremap coc#float#has_scroll() ? "\=coc#float#scroll(0)\" : "\" 156 | vnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" 157 | vnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" 158 | endif 159 | 160 | " Use CTRL-S for selections ranges 161 | " Requires 'textDocument/selectionRange' support of language server 162 | nmap (coc-range-select) 163 | xmap (coc-range-select) 164 | 165 | " Add `:Format` command to format current buffer 166 | command! -nargs=0 Format :call CocActionAsync('format') 167 | 168 | " Add `:Fold` command to fold current buffer 169 | command! -nargs=? Fold :call CocAction('fold', ) 170 | 171 | " Add `:OR` command for organize imports of the current buffer 172 | command! -nargs=0 OR :call CocActionAsync('runCommand', 'editor.action.organizeImport') 173 | 174 | " Add (Neo)Vim's native statusline support 175 | " NOTE: Please see `:h coc-status` for integrations with external plugins that 176 | " provide custom statusline: lightline.vim, vim-airline 177 | set statusline^="%{coc#status()}%{get(b:,'coc_current_function','')}" 178 | 179 | " Mappings for CoCList 180 | " Show all diagnostics 181 | nnoremap a :CocList diagnostics 182 | " Manage extensions 183 | nnoremap e :CocList extensions 184 | " Show commands 185 | nnoremap c :CocList commands 186 | " Find symbol of current document 187 | nnoremap o :CocList outline 188 | " Search workspace symbols 189 | nnoremap s :CocList -I symbols 190 | " Do default action for next item 191 | nnoremap j :CocNext 192 | " Do default action for previous item 193 | nnoremap k :CocPrev 194 | " Resume latest coc list 195 | nnoremap p :CocListResume 196 | endfunction 197 | 198 | if !has('nvim') 199 | " this remap has to be loaded before copilot.vim, or will be incorrectly mapped 200 | " Use tab for trigger completion with characters ahead and navigate 201 | inoremap 202 | \ coc#pum#visible() ? coc#pum#next(1) : 203 | \ CheckBackspace() ? "\" : 204 | \ coc#refresh() 205 | inoremap coc#pum#visible() ? coc#pum#prev(1) : "\" 206 | endif 207 | 208 | if has("autocmd") && !has('nvim') 209 | augroup SetupCoc 210 | autocmd! 211 | autocmd VimEnter * call SetupCocCustomizations() 212 | augroup END 213 | endif 214 | -------------------------------------------------------------------------------- /colors/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giggio/vimfiles/478e06c51febb746347238b243daa279412dfe99/colors/.gitkeep -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1748370509, 24 | "narHash": "sha256-QlL8slIgc16W5UaI3w7xHQEP+Qmv/6vSNTpoZrrSlbk=", 25 | "owner": "nixos", 26 | "repo": "nixpkgs", 27 | "rev": "4faa5f5321320e49a78ae7848582f684d64783e9", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "nixos", 32 | "ref": "nixos-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "vimfiles"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | }; 8 | 9 | outputs = { self, nixpkgs, flake-utils }: 10 | flake-utils.lib.eachDefaultSystem (system: 11 | let 12 | pkgs = import nixpkgs { 13 | inherit system; 14 | }; 15 | in 16 | { 17 | devShells.default = import ./shell.nix { inherit pkgs; }; 18 | } 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /gui.vim: -------------------------------------------------------------------------------- 1 | if has("gui_running") 2 | if has('autocmd') 3 | augroup SetVisualBell 4 | autocmd! 5 | autocmd GUIEnter * set visualbell t_vb= 6 | augroup END 7 | endif 8 | set lines=999 columns=999 9 | if has("gui_gtk2") 10 | set guifont=Inconsolata\ 12 11 | elseif has("gui_macvim") 12 | set guifont=Menlo\ Regular:h14 13 | elseif has("gui_win32") 14 | " au GUIEnter * simalt ~x " todo: maximize the window on Windows only, maybe not necessary, verify, if it works with set lines above, remove 15 | set guifont=CaskaydiaCove\ NF:h11:cANSI,DejaVu_Sans_Mono_for_Powerline:h11:cANSI,Consolas:h11:cANSI,Courier:h12:cANSI 16 | endif 17 | if ! has('nvim') 18 | :set guioptions+=m "add menu bar 19 | :set guioptions+=R "remove right-hand scroll bar 20 | :set guioptions-=T "remove toolbar 21 | :set guioptions-=r "remove right-hand scroll bar 22 | :set guioptions-=l "remove left-hand scroll bar 23 | :set guioptions-=L "remove left-hand scroll bar 24 | endif 25 | endif 26 | 27 | -------------------------------------------------------------------------------- /helpers/autosave.vim: -------------------------------------------------------------------------------- 1 | if has('timers') 2 | let g:autosave_enabled = 1 3 | let g:autosave_timer = 0 4 | 5 | function! RunAutosaveTimer() abort 6 | if !g:autosave_enabled 7 | return 8 | endif 9 | if g:autosave_timer > 0 10 | call timer_stop(g:autosave_timer) 11 | endif 12 | let g:autosave_timer = timer_start(3000, {-> execute('wall')}) 13 | endfunction 14 | 15 | augroup AutoSaveDebounce 16 | autocmd! 17 | autocmd TextChanged,TextChangedI * call RunAutosaveTimer() 18 | augroup END 19 | endif 20 | -------------------------------------------------------------------------------- /helpers/close_initial_empty_tab.vim: -------------------------------------------------------------------------------- 1 | function! s:CheckIfInitialTabIsEmpty() 2 | if g:session_autoloading == 1 3 | return 4 | endif 5 | let g:ace_prev_buf = bufnr('%') 6 | let g:ace_prev_tab = tabpagenr() 7 | " no filename, not modified, exactly 1 liner, that line is empty 8 | let g:ace_prev_empty = empty(bufname(g:ace_prev_buf)) 9 | \ && !getbufvar(g:ace_prev_buf, '&modified') 10 | \ && line("$", bufwinid(g:ace_prev_buf)) == 1 11 | \ && getbufline(g:ace_prev_buf, 1)[0] ==# '' 12 | endfunction 13 | function! s:CloseInitialEmptyTab() 14 | if g:session_autoloading == 1 15 | return 16 | endif 17 | if tabpagenr('$') == 1 " do not close the only tab 18 | unlet g:ace_prev_empty g:ace_prev_buf g:ace_prev_tab 19 | return 20 | endif 21 | if exists('g:ace_prev_empty') && g:ace_prev_empty && bufloaded(g:ace_prev_buf) 22 | execute 'tabclose' g:ace_prev_tab 23 | execute 'silent! bdelete' g:ace_prev_buf 24 | unlet g:ace_prev_empty g:ace_prev_buf g:ace_prev_tab 25 | endif 26 | endfunction 27 | augroup AutoCloseEmptyTab 28 | autocmd! 29 | autocmd TabLeave * call s:CheckIfInitialTabIsEmpty() 30 | autocmd TabEnter * call s:CloseInitialEmptyTab() 31 | augroup END 32 | 33 | 34 | -------------------------------------------------------------------------------- /helpers/functions.vim: -------------------------------------------------------------------------------- 1 | function! g:CatchError(expr) 2 | try 3 | execute a:expr 4 | catch /^Vim\%((\a\+)\)\=:E\w\+/ 5 | call add(g:StartupErrors, {'exception': v:exception, 'stacktrace': v:stacktrace}) 6 | endtry 7 | endfunction 8 | 9 | function! g:AddError(err) 10 | call add(g:StartupErrors, {'txt': err}) 11 | endfunction 12 | 13 | function! g:ShowStartupErrors() 14 | if !empty(g:StartupErrors) | 15 | tabnew 16 | " make it a no-file buffer so Vim won't nag us to save it 17 | setlocal buftype=nofile bufhidden=wipe nobuflisted 18 | file [Startup Errors] " name in the tabline 19 | call append(0, ['=== Startup Errors ===']) 20 | for ex in g:StartupErrors 21 | if has_key(ex, 'txt') 22 | call append(line('$'), ex.txt) 23 | endif 24 | if has_key(ex, 'exception') 25 | call append(line('$'), ex.exception) 26 | endif 27 | if has_key(ex, 'stacktrace') 28 | for stack_item in ex.stacktrace 29 | call append(line('$'), 'at line ' . g:Pad(stack_item.lnum, 5) . "\tin file" . stack_item.filepath) 30 | if has_key(stack_item, 'funcref') 31 | call append(line('$'), 'in function ' . get(stack_item.funcref, 'name')) 32 | endif 33 | if has_key(stack_item, 'event') 34 | call append(line('$'), 'event: ' . stack_item.event) 35 | endif 36 | endfor 37 | endif 38 | call append(line('$'), '') 39 | endfor 40 | normal! gg 41 | endif 42 | endfunction 43 | 44 | function! g:Pad(number, number_of_zeroes) 45 | let char = '0' 46 | return repeat('0', a:number_of_zeroes - len(string(a:number))) . a:number 47 | endfunction 48 | 49 | function! g:VerboseEchomsg(msg) 50 | if &verbose > 0 51 | echomsg a:msg 52 | endif 53 | endfunction 54 | -------------------------------------------------------------------------------- /init.vim: -------------------------------------------------------------------------------- 1 | " init.vim - Neovim entrypoint configuration file 2 | " In my configuration, ~/.vimrc is also loading this file 3 | 4 | if has('nvim') 5 | " vimHome is a variable used for compatibility with both Vim and Neovim. 6 | if has('win32unix') 7 | let g:vimHome = $HOME . '/.vim' 8 | elseif has('unix') 9 | let g:vimHome = '~/.vim' 10 | elseif has('win32') 11 | let g:vimHome = $USERPROFILE . "\\.vim" 12 | else 13 | let g:vimHome = '~/.vim' 14 | endif 15 | " reset runtime path to be the same for all platforms 16 | set runtimepath=$HOME/.vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,$HOME/.vim/after 17 | " todo: check how to work with nvim on Windows, it'll probably have problems 18 | " with the runtimepath 19 | endif 20 | 21 | if has('win32unix') 22 | let g:vimHome = $HOME . '/.vim' 23 | elseif has('unix') 24 | let g:vimHome = '~/.vim' 25 | elseif has('win32') 26 | let g:vimHome = $USERPROFILE . "\\.vim" 27 | else 28 | let g:vimHome = '~/.vim' 29 | endif 30 | 31 | runtime helpers/functions.vim 32 | 33 | " startup errors will accumulate in this list 34 | let g:StartupErrors = [] 35 | 36 | " Disable beep 37 | set noerrorbells visualbell t_vb= 38 | " Based on @mislav post http://mislav.uniqpath.com/2011/12/vim-revisited/ 39 | set nocompatible " choose no compatibility with legacy vi 40 | syntax enable 41 | set encoding=utf-8 42 | set showcmd " display incomplete commands 43 | filetype plugin indent on " load file type plugins + indentation 44 | if has("autocmd") 45 | augroup FileTypes 46 | autocmd! 47 | autocmd BufRead,BufNewFile launch.json set filetype=json5 48 | autocmd BufRead,BufNewFile settings.json set filetype=json5 49 | augroup END 50 | endif 51 | 52 | "" Whitespace 53 | set nowrap " don't wrap lines 54 | set tabstop=2 shiftwidth=2 " a tab is two spaces (or set this to 4) 55 | set expandtab " use spaces, not tabs (optional) 56 | set backspace=indent,eol,start " backspace through everything in insert mode 57 | 58 | "" Searching 59 | set hlsearch " highlight matches 60 | set incsearch " incremental searching 61 | set ignorecase " searches are case insensitive... 62 | set smartcase " ... unless they contain at least one capital letter 63 | 64 | " My customizations 65 | set ls=2 " always show status bar 66 | set number " show line numbers 67 | set cursorline " display a marker on current line 68 | 69 | set completeopt=menuone,longest,preview " simple autocomplete for anything 70 | set wildmenu 71 | set wildmode=list:longest,full " autocomplete for paths and files 72 | set wildignore+=.git " ignore these extensions on autocomplete 73 | 74 | set hidden " change buffers without warnings even when there are unsaved changes 75 | 76 | set backupdir=/tmp " directory used to save backup files 77 | set directory=/tmp " directory used to save swap files 78 | if has("win32") 79 | set backupdir=$TEMP 80 | set directory=$TEMP 81 | endif 82 | set nobackup 83 | set nowritebackup 84 | 85 | let &t_SI = "\e[1 q" " Insert mode, blinking block 86 | let &t_SR = "\e[4 q" " Replace mode, solid underscore 87 | let &t_EI = "\e[2 q" " Normal mode, solid block 88 | 89 | " Always show the signcolumn, otherwise it would shift the text each time 90 | " diagnostics appear/become resolved. 91 | if has("patch-8.1.1564") 92 | " Recently vim can merge signcolumn and number column into one 93 | set signcolumn=number 94 | else 95 | set signcolumn=yes 96 | endif 97 | 98 | let vimlocal = expand("%:p:h") . "/.vimrc.local" 99 | if filereadable(vimlocal) 100 | execute 'source '.vimlocal 101 | endif 102 | set switchbuf+=usetab,newtab 103 | set wrapscan 104 | 105 | set mouse=a 106 | 107 | " open splits in a more natural way: 108 | set splitbelow 109 | set splitright 110 | 111 | set number relativenumber 112 | set diffopt=filler,vertical 113 | 114 | if has("autocmd") 115 | augroup ContinueOnTheSameLineNumber 116 | autocmd! 117 | autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif 118 | augroup END 119 | augroup SetBufferNotListed 120 | autocmd! 121 | autocmd BufEnter * if &buftype != '' | setlocal nobuflisted | endif 122 | augroup END 123 | endif 124 | 125 | set completeopt=longest,menuone,preview 126 | " this setting controls how long to wait (in ms) before fetching type / symbol information. 127 | set updatetime=500 128 | " Remove 'Press Enter to continue' message when type information is longer than one line. 129 | set cmdheight=2 130 | " start with all unfolded. 131 | set foldlevelstart=99 132 | 133 | runtime maps.vim 134 | 135 | runtime session_management.vim 136 | 137 | runtime plugins_config.vim 138 | 139 | runtime gui.vim 140 | 141 | runtime nerdtree.vim 142 | 143 | runtime helpers/autosave.vim 144 | 145 | runtime helpers/close_initial_empty_tab.vim 146 | 147 | runtime theme.vim 148 | 149 | if !has('nvim') 150 | runtime coc_nvim.vim 151 | endif 152 | 153 | runtime plugins.vim 154 | 155 | call g:CatchError('colorscheme material') 156 | 157 | if has("autocmd") 158 | augroup ShowStartupErrorsGroup 159 | autocmd! 160 | autocmd VimEnter * call g:ShowStartupErrors() 161 | augroup END 162 | endif 163 | 164 | if has('nvim') 165 | lua require('init') 166 | endif 167 | -------------------------------------------------------------------------------- /lazy-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, 3 | "CopilotChat.nvim": { "branch": "main", "commit": "16d897fd43d07e3b54478ccdb2f8a16e4df4f45a" }, 4 | "LuaSnip": { "branch": "master", "commit": "458560534a73f7f8d7a11a146c801db00b081df0" }, 5 | "ReplaceWithRegister": { "branch": "master", "commit": "832efc23111d19591d495dc72286de2fb0b09345" }, 6 | "bufferize.vim": { "branch": "main", "commit": "ec7c4445a97f19e5784a6fb6ad3c3d4a8ff505ac" }, 7 | "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, 8 | "cmp-cmdline": { "branch": "main", "commit": "d126061b624e0af6c3a556428712dd4d4194ec6d" }, 9 | "cmp-git": { "branch": "main", "commit": "b24309c386c9666c549a1abaedd4956541676d06" }, 10 | "cmp-nvim-lsp": { "branch": "main", "commit": "a8912b88ce488f411177fc8aed358b04dc246d7b" }, 11 | "cmp-path": { "branch": "main", "commit": "c6635aae33a50d6010bf1aa756ac2398a2d54c32" }, 12 | "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, 13 | "copilot.vim": { "branch": "release", "commit": "3955014c503b0cd7b30bc56c86c56c0736ca0951" }, 14 | "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, 15 | "lua-json5": { "branch": "master", "commit": "d8e962a98b9c66bda02b20df02868a72ef4c8803" }, 16 | "material.vim": { "branch": "main", "commit": "cecac931e8bd9e3d2cbb7c1e24ddb98887176f68" }, 17 | "mini.nvim": { "branch": "main", "commit": "94cae4660a8b2d95dbbd56e1fbc6fcfa2716d152" }, 18 | "nerdtree": { "branch": "master", "commit": "9b465acb2745beb988eff3c1e4aa75f349738230" }, 19 | "nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" }, 20 | "nvim-dap": { "branch": "master", "commit": "ea82027c3447dc1a022be9a9884de276c05cd33a" }, 21 | "nvim-dap-ui": { "branch": "master", "commit": "73a26abf4941aa27da59820fd6b028ebcdbcf932" }, 22 | "nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" }, 23 | "nvim-lightbulb": { "branch": "master", "commit": "aa3a8b0f4305b25cfe368f6c9be9923a7c9d0805" }, 24 | "nvim-lspconfig": { "branch": "master", "commit": "036885e8e5456d3907626b634693234f628afef6" }, 25 | "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, 26 | "nvim-treesitter": { "branch": "main", "commit": "f976acdc9c8214145a11372d2a7ae4a032f62a39" }, 27 | "nvim-treesitter-context": { "branch": "master", "commit": "464a443b5a6657f39772b20baa95d02ffe97b268" }, 28 | "nvim-ts-context-commentstring": { "branch": "main", "commit": "1b212c2eee76d787bbea6aa5e92a2b534e7b4f8f" }, 29 | "overseer.nvim": { "branch": "master", "commit": "72c68aab0358c92f451168b704c411c4a3e3410e" }, 30 | "persistent-breakpoints.nvim": { "branch": "main", "commit": "d1656221836207787b8a7969cc2dc72668c4742a" }, 31 | "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" }, 32 | "rainbow-delimiters.nvim": { "branch": "master", "commit": "55ad4fb76ab68460f700599b7449385f0c4e858e" }, 33 | "trouble.nvim": { "branch": "main", "commit": "85bedb7eb7fa331a2ccbecb9202d8abba64d37b3" }, 34 | "vim-airline": { "branch": "master", "commit": "41c5f54507fd865c8c00fe1f4bb390a59b6894ef" }, 35 | "vim-airline-themes": { "branch": "master", "commit": "0e976956eb674db8a6f72fae4dda6d1277433660" }, 36 | "vim-better-whitespace": { "branch": "master", "commit": "de99b55a6fe8c96a69f9376f16b1d5d627a56e81" }, 37 | "vim-devicons": { "branch": "master", "commit": "71f239af28b7214eebb60d4ea5bd040291fb7e33" }, 38 | "vim-easymotion": { "branch": "master", "commit": "b3cfab2a6302b3b39f53d9fd2cd997e1127d7878" }, 39 | "vim-fugitive": { "branch": "master", "commit": "4a745ea72fa93bb15dd077109afbb3d1809383f2" }, 40 | "vim-nerdtree-syntax-highlight": { "branch": "master", "commit": "35e70334a2ff6e89b82a145d1ac889e82d1ddb4e" }, 41 | "vim-snippets": { "branch": "master", "commit": "f0a3184d9f90b96b044d5914625a25c554d7f301" }, 42 | "vim-tmux-navigator": { "branch": "master", "commit": "97e58f2b3b4f8fd30ce149302f10202f363cc361" }, 43 | "vim-unimpaired": { "branch": "master", "commit": "6d44a6dc2ec34607c41ec78acf81657248580bf1" }, 44 | "vimproc.vim": { "branch": "master", "commit": "63a4ce0768c7af434ac53d37bdc1e7ff7fd2bece" }, 45 | "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" } 46 | } 47 | -------------------------------------------------------------------------------- /lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | -- Bootstrap lazy.nvim 2 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 3 | if not (vim.uv or vim.loop).fs_stat(lazypath) then 4 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 5 | local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) 6 | if vim.v.shell_error ~= 0 then 7 | vim.api.nvim_echo({ 8 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 9 | { out, "WarningMsg" }, 10 | { "\nPress any key to exit..." }, 11 | }, true, {}) 12 | vim.fn.getchar() 13 | os.exit(1) 14 | end 15 | end 16 | vim.opt.rtp:prepend(lazypath) 17 | 18 | -- Make sure to setup `mapleader` and `maplocalleader` before 19 | -- loading lazy.nvim so that mappings are correct. 20 | -- This is also a good place to setup other settings (vim.opt) 21 | vim.g.mapleader = "\\" 22 | vim.g.maplocalleader = "\\" 23 | 24 | require("lazy").setup({ 25 | root = vim.g.nvimPluginInstallPath, 26 | performance = { 27 | reset_packpath = false, 28 | }, 29 | change_detection = { 30 | -- automatically check for config file changes and reload the ui 31 | enabled = true, 32 | notify = false, -- get a notification when changes are found 33 | }, 34 | spec = { 35 | { import = "plugins" }, 36 | LazyPlugSpecs, -- bringing in the plugin in list from vim 37 | }, 38 | checker = { enabled = false }, -- automatically check for plugin updates 39 | }) 40 | -------------------------------------------------------------------------------- /lua/init.lua: -------------------------------------------------------------------------------- 1 | -- empty file so far 2 | require "lsp" 3 | -------------------------------------------------------------------------------- /lua/lsp/init.lua: -------------------------------------------------------------------------------- 1 | local capabilities = require('cmp_nvim_lsp').default_capabilities() 2 | vim.lsp.config('*', { 3 | capabilities = capabilities, 4 | }) 5 | 6 | -- todo: can't use Cspell LS until it supports .yaml and more than one config file 7 | -- see: https://github.com/vlabo/cspell-lsp/issues/13 8 | -- if cspell.yaml exists, use it as the config filename 9 | -- if vim.fn.filereadable('./cspell.yaml') == 1 then 10 | -- vim.lsp.config('cspell_ls', { 11 | -- cmd = { 'cspell-lsp', '--stdio', '--config', 'cspell.yaml' }, 12 | -- }) 13 | -- end 14 | -- vim.lsp.enable('cspell_ls') 15 | 16 | require("lsp.lua_ls") 17 | 18 | vim.lsp.enable('cssls') 19 | vim.lsp.enable('emmet_language_server') 20 | vim.lsp.enable('eslint') 21 | vim.lsp.enable('gopls') 22 | vim.lsp.enable('html') 23 | vim.lsp.enable('jsonls') 24 | vim.lsp.enable('marksman') 25 | vim.lsp.enable('nushell') 26 | vim.lsp.enable('rust_analyzer') 27 | vim.lsp.enable('sqls') 28 | vim.lsp.enable('ts_ls') 29 | vim.lsp.enable('vimls') 30 | 31 | vim.api.nvim_create_augroup("LspDiagnosticsHold", { clear = true }) 32 | vim.api.nvim_create_autocmd({ "CursorHold" }, { 33 | pattern = "*", 34 | callback = function(_) 35 | for _, winid in pairs(vim.api.nvim_tabpage_list_wins(0)) do 36 | if vim.api.nvim_win_get_config(winid).zindex then 37 | return 38 | end 39 | end 40 | vim.diagnostic.open_float({ 41 | bufnr = 0, 42 | scope = "cursor", 43 | focusable = false, 44 | close_events = { 45 | "CursorMoved", 46 | "CursorMovedI", 47 | "BufHidden", 48 | "InsertCharPre", 49 | "WinLeave", 50 | }, 51 | }) 52 | end, 53 | group = "LspDiagnosticsHold", 54 | }) 55 | 56 | -- allow gotmpl files to be recognized as HTML files when hugo config files are present 57 | if vim.fn.filereadable('./hugo.yaml') == 1 or vim.fn.filereadable('./hugo.toml') == 1 or vim.fn.filereadable('./hugo.json') == 1 58 | or vim.fn.glob('./config/**/hugo.yaml') ~= '' or vim.fn.glob('./config/**/hugo.toml') ~= '' or vim.fn.glob('./config/**/hugo.json') ~= '' then 59 | vim.api.nvim_create_autocmd('BufEnter', { 60 | pattern = { '*.html' }, 61 | command = "set filetype=gotmpl", 62 | }) 63 | end 64 | 65 | vim.keymap.set("n", ".", vim.lsp.buf.code_action, { noremap = true, silent = true, desc = "LSP: code action" }) 66 | vim.keymap.set("n", "rn", vim.lsp.buf.rename, { noremap = true, silent = true, desc = "LSP: rename" }) 67 | vim.keymap.set("n", "gd", vim.lsp.buf.definition, { noremap = true, silent = true, desc = "LSP: go to definition" }) 68 | vim.keymap.set("n", "", vim.lsp.buf.definition, { noremap = true, silent = true, desc = "LSP: go to definition" }) 69 | vim.keymap.set("n", "gy", vim.lsp.buf.type_definition, { noremap = true, silent = true, desc = "LSP: go to type definition" }) 70 | -- vim.keymap.set( "n", "gr", vim.lsp.buf.references, { noremap = true, silent = true, desc = "LSP: go to references" }) 71 | vim.keymap.set("n", "gi", vim.lsp.buf.implementation, { noremap = true, silent = true, desc = "LSP: go to implementation" }) 72 | 73 | -- vim.api.nvim_set_keymap('n', 'do', 'lua vim.diagnostic.open_float()', { noremap = true, silent = true }) 74 | vim.keymap.set('n', 'do', function() vim.diagnostic.open_float({ scope = 'buffer' }) end, { noremap = true, silent = true }) 75 | vim.api.nvim_set_keymap('n', 'd[', 'lua vim.diagnostic.goto_prev()', { noremap = true, silent = true }) 76 | vim.api.nvim_set_keymap('n', 'd]', 'lua vim.diagnostic.goto_next()', { noremap = true, silent = true }) 77 | -- The following command requires plug-ins "nvim-telescope/telescope.nvim", "nvim-lua/plenary.nvim", and optionally "kyazdani42/nvim-web-devicons" for icon support 78 | vim.api.nvim_set_keymap('n', 'dd', 'Telescope diagnostics', { noremap = true, silent = true }) 79 | -- If you don't want to use the telescope plug-in but still want to see all the errors/warnings, comment out the telescope line and uncomment this: 80 | -- vim.api.nvim_set_keymap('n', 'dd', 'lua vim.diagnostic.setloclist()', { noremap = true, silent = true }) 81 | 82 | -------------------------------------------------------------------------------- /lua/lsp/lua_ls.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config('lua_ls', { 2 | -- from: https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#lua_ls 3 | on_init = function(client) 4 | if client.workspace_folders then 5 | local path = client.workspace_folders[1].name 6 | if 7 | path ~= vim.fn.stdpath('config') 8 | and (vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc')) 9 | then 10 | return 11 | end 12 | end 13 | client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, { 14 | runtime = { 15 | -- Tell the language server which version of Lua you're using (most 16 | -- likely LuaJIT in the case of Neovim) 17 | version = 'LuaJIT', 18 | -- Tell the language server how to find Lua modules same way as Neovim 19 | -- (see `:h lua-module-load`) 20 | path = { 21 | 'lua/?.lua', 22 | 'lua/?/init.lua', 23 | }, 24 | }, 25 | -- Make the server aware of Neovim runtime files 26 | workspace = { 27 | checkThirdParty = false, 28 | library = { 29 | vim.env.VIMRUNTIME, 30 | -- Depending on the usage, you might want to add additional paths 31 | -- here. 32 | '${3rd}/luv/library' 33 | -- '${3rd}/busted/library' 34 | } 35 | -- Or pull in all of 'runtimepath'. 36 | -- NOTE: this is a lot slower and will cause issues when working on 37 | -- your own configuration. 38 | -- See https://github.com/neovim/nvim-lspconfig/issues/3189 39 | -- library = { 40 | -- vim.api.nvim_get_runtime_file('', true), 41 | -- } 42 | } 43 | }) 44 | end, 45 | settings = { 46 | Lua = {} 47 | } 48 | }) 49 | 50 | vim.lsp.enable('lua_ls') 51 | -------------------------------------------------------------------------------- /lua/plugins/cmp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "hrsh7th/nvim-cmp", 4 | event = { "InsertEnter", "CmdlineEnter" }, 5 | dependencies = { 6 | "hrsh7th/cmp-buffer", 7 | "hrsh7th/cmp-path", 8 | "hrsh7th/cmp-cmdline", 9 | "hrsh7th/cmp-nvim-lsp", 10 | "saadparwaiz1/cmp_luasnip", 11 | { 12 | "L3MON4D3/LuaSnip", 13 | version = "v2.*", 14 | lazy = true, 15 | build = "make install_jsregexp", 16 | dependencies = { 17 | "rafamadriz/friendly-snippets", 18 | "honza/vim-snippets", 19 | }, 20 | config = function() 21 | require("luasnip.loaders.from_vscode").lazy_load() 22 | require("luasnip.loaders.from_snipmate").lazy_load() 23 | end 24 | }, 25 | { 26 | "petertriho/cmp-git", 27 | dependencies = { 28 | "nvim-lua/plenary.nvim", 29 | }, 30 | } 31 | }, 32 | config = function() 33 | local luasnip = require"luasnip" 34 | local cmp = require'cmp' 35 | cmp.setup({ 36 | experimental = { 37 | ghost_text = false -- this feature conflict with copilot.vim's preview. 38 | }, 39 | snippet = { 40 | expand = function(args) 41 | vim.snippet.expand(args.body) -- native neovim snippets 42 | end, 43 | }, 44 | window = { 45 | completion = cmp.config.window.bordered(), 46 | documentation = cmp.config.window.bordered(), 47 | }, 48 | mapping = { 49 | [""] = cmp.mapping(function(fallback) 50 | if cmp.visible() then 51 | cmp.select_next_item() 52 | else 53 | fallback() 54 | end 55 | end, { "i", "s" }), 56 | [""] = cmp.mapping(function(fallback) 57 | if cmp.visible() then 58 | cmp.select_prev_item() 59 | else 60 | fallback() 61 | end 62 | end, { "i", "s" }), 63 | [""] = cmp.mapping(function(fallback) 64 | if luasnip.locally_jumpable(1) then 65 | luasnip.jump(1) 66 | else 67 | fallback() 68 | end 69 | end, { "i", "s" }), 70 | [""] = cmp.mapping(function(fallback) 71 | if luasnip.locally_jumpable(-1) then 72 | luasnip.jump(-1) 73 | else 74 | fallback() 75 | end 76 | end, { "i", "s" }), 77 | [''] = cmp.mapping(function(fallback) 78 | if cmp.visible() then 79 | if luasnip.expandable() then 80 | luasnip.expand() 81 | else 82 | cmp.confirm({ select = true }) 83 | end 84 | else 85 | fallback() 86 | end 87 | end), 88 | [''] = cmp.mapping.scroll_docs(-4), 89 | [''] = cmp.mapping.scroll_docs(4), 90 | [''] = cmp.mapping.complete(), 91 | }, 92 | sources = cmp.config.sources({ 93 | { name = 'nvim_lsp' }, 94 | { name = 'luasnip' }, 95 | }, { 96 | { 97 | name = 'buffer', 98 | option = { 99 | get_bufnrs = function() 100 | return vim.api.nvim_list_bufs() 101 | end 102 | } 103 | }, 104 | }) 105 | }) 106 | 107 | -- To use git you need to install the plugin petertriho/cmp-git and uncomment lines below 108 | -- Set configuration for specific filetype. 109 | cmp.setup.filetype('gitcommit', { 110 | sources = cmp.config.sources({ 111 | { name = 'git' }, 112 | }, { 113 | { name = 'buffer' }, 114 | }) 115 | }) 116 | require("cmp_git").setup() 117 | 118 | -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). 119 | cmp.setup.cmdline({ '/', '?' }, { 120 | mapping = cmp.mapping.preset.cmdline(), 121 | sources = { 122 | { name = 'buffer' } 123 | } 124 | }) 125 | 126 | -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). 127 | cmp.setup.cmdline(':', { 128 | mapping = cmp.mapping.preset.cmdline(), 129 | sources = cmp.config.sources({ 130 | { name = 'path' } 131 | }, { 132 | { name = 'cmdline' } 133 | }), 134 | matching = { disallow_symbol_nonprefix_matching = false } 135 | }) 136 | 137 | end, 138 | }, 139 | } 140 | 141 | -------------------------------------------------------------------------------- /lua/plugins/copilot_chat.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "CopilotC-Nvim/CopilotChat.nvim", 4 | event = "VeryLazy", 5 | dependencies = { 6 | { "github/copilot.vim" }, -- or zbirenbaum/copilot.lua 7 | { "nvim-lua/plenary.nvim", branch = "master" }, -- for curl, log and async functions 8 | }, 9 | build = "make tiktoken", -- Only on MacOS or Linux 10 | opts = { 11 | -- See Configuration section for options 12 | }, 13 | -- See Commands section for default commands if you want to lazy load on them 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /lua/plugins/dap.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "mfussenegger/nvim-dap", 3 | event = "VeryLazy", 4 | dependencies = { 5 | "rcarriga/nvim-dap-ui", 6 | "nvim-neotest/nvim-nio", 7 | "theHamsta/nvim-dap-virtual-text", 8 | "Joakker/lua-json5", 9 | }, 10 | config = function() 11 | local dap = require('dap') 12 | dap.adapters = { 13 | lldb_dap = { -- lldb_dap is the name we use in the configuration.type 14 | type = 'executable', 15 | command = 'lldb-dap', 16 | name = 'lldb-dap' 17 | }, 18 | lldb = { -- use lldb for codelldb as it works the same in vscode 19 | type = "executable", 20 | command = "codelldb", 21 | name = "codelldb", 22 | -- On windows you may have to uncomment this: 23 | -- detached = false, 24 | }, 25 | node = { 26 | type = "server", 27 | host = "localhost", 28 | port = "${port}", 29 | executable = { 30 | command = "js-debug", 31 | args = { "${port}" }, 32 | }, 33 | enrich_config = function(conf, on_config) -- necessary so type 'node' also works 34 | if not vim.startswith(conf.type, "pwa-") then 35 | local config = vim.deepcopy(conf) 36 | config.type = "pwa-" .. config.type 37 | on_config(config) 38 | else 39 | on_config(conf) 40 | end 41 | end 42 | } 43 | } 44 | dap.adapters["pwa-node"] = { 45 | type = "server", 46 | host = "localhost", 47 | port = "${port}", 48 | executable = { 49 | command = "js-debug", 50 | args = { "${port}" }, 51 | }, 52 | } 53 | dap.configurations = 54 | { 55 | rust = { 56 | { 57 | name = 'Debug Rust (nvim - codelldb)', 58 | type = "lldb", 59 | request = "launch", 60 | program = function() 61 | return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') 62 | end, 63 | cwd = '${workspaceFolder}', 64 | stopOnEntry = false, 65 | }, 66 | { 67 | name = 'Debug Rust (nvim - lldb-dap)', 68 | type = 'lldb_dap', 69 | request = 'launch', 70 | program = function() 71 | return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file") 72 | end, 73 | cwd = '${workspaceFolder}', 74 | stopOnEntry = false, 75 | args = { }, 76 | }, 77 | }, 78 | javascript = { 79 | { 80 | name = "Node - Launch file (nvim - js-debug)", 81 | type = "node", 82 | request = "launch", 83 | program = "${file}", 84 | skipFiles = { 85 | "/**" 86 | }, 87 | cwd = "${workspaceFolder}", 88 | }, 89 | { 90 | name = "Node - npm run debug (nvim - js-debug)", 91 | type = "node", 92 | request = "launch", 93 | runtimeArgs = { 94 | "run-script", 95 | "debug" 96 | }, 97 | runtimeExecutable = "npm", 98 | skipFiles = { 99 | "/**" 100 | }, 101 | cwd = "${workspaceFolder}", 102 | }, 103 | }, 104 | } 105 | local ext_vscode = require('dap.ext.vscode') 106 | ext_vscode.json_decode = require'json5'.parse 107 | end 108 | } 109 | -------------------------------------------------------------------------------- /lua/plugins/dap_persistent_breakpoints.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "Weissle/persistent-breakpoints.nvim", 3 | event = "VeryLazy", 4 | opts = { 5 | load_breakpoints_event = { "BufReadPost" }, 6 | always_reload = true, 7 | }, 8 | } 9 | 10 | -------------------------------------------------------------------------------- /lua/plugins/dap_ui.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "rcarriga/nvim-dap-ui", 3 | event = "VeryLazy", 4 | dependencies = { 5 | "Weissle/persistent-breakpoints.nvim", 6 | }, 7 | config = function() 8 | local dap = require('dap') 9 | local ui = require("dapui") 10 | ui.setup() 11 | 12 | vim.g.dap_debugger_running = 0 13 | vim.fn.sign_define("DapBreakpoint", { text = "🛑" }) 14 | dap.listeners.before.attach.dapui_config = function() 15 | ui.open() 16 | vim.g.dap_debugger_running = 1 17 | end 18 | dap.listeners.before.launch.dapui_config = function() 19 | ui.open() 20 | vim.g.dap_debugger_running = 1 21 | end 22 | dap.listeners.before.event_terminated.dapui_config = function() 23 | ui.close() 24 | vim.g.dap_debugger_running = 0 25 | end 26 | dap.listeners.before.event_exited.dapui_config = function() 27 | ui.close() 28 | vim.g.dap_debugger_running = 0 29 | end 30 | end 31 | } 32 | -------------------------------------------------------------------------------- /lua/plugins/dap_virtual_text.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "theHamsta/nvim-dap-virtual-text", 3 | config = function() 4 | require('nvim-dap-virtual-text').setup { 5 | } 6 | end, 7 | requires = { 8 | "nvim-treesitter/nvim-treesitter", 9 | "mfussenegger/nvim-dap", 10 | }, 11 | } 12 | 13 | -------------------------------------------------------------------------------- /lua/plugins/mini.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'echasnovski/mini.nvim', 3 | lazy = false, 4 | event = "VeryLazy", 5 | version = '*', 6 | config = function() 7 | require('mini.pick').setup({ 8 | -- mappings = { 9 | -- choose = '', 10 | -- choose_in_tabpage = '', 11 | -- } 12 | }) 13 | vim.ui.select = require('mini.pick').ui_select 14 | require('mini.icons').setup() 15 | 16 | end, 17 | keys = { 18 | { "", "Pick files" }, 19 | { "\\f", "Pick grep_live" }, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /lua/plugins/no_config.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "neovim/nvim-lspconfig", 3 | { 4 | "numToStr/Comment.nvim", 5 | config = function() 6 | require('Comment').setup() 7 | end, 8 | }, 9 | "JoosepAlviste/nvim-ts-context-commentstring", 10 | { 11 | "kosayoda/nvim-lightbulb", 12 | config = function() 13 | require('nvim-lightbulb').setup { 14 | autocmd = { enabled = true }, 15 | action_kinds = { 16 | "call_hints", 17 | "quickfix", 18 | "diagnostic", 19 | "fix_all", 20 | "inlay_hint", 21 | }, 22 | } 23 | end, 24 | }, 25 | { 26 | "Joakker/lua-json5", 27 | build = "./install.sh", 28 | event = "VeryLazy", 29 | }, 30 | } 31 | 32 | -------------------------------------------------------------------------------- /lua/plugins/overseer.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'stevearc/overseer.nvim', 3 | config = function() 4 | require('overseer').setup { 5 | } 6 | end, 7 | opts = {}, 8 | } 9 | -------------------------------------------------------------------------------- /lua/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-treesitter/nvim-treesitter", 3 | branch = 'main', 4 | lazy = false, 5 | build = ":TSUpdate", 6 | dependencies = { 7 | "HiPhish/rainbow-delimiters.nvim", 8 | "nvim-treesitter/nvim-treesitter-context", 9 | }, 10 | config = function() 11 | local languages = { -- also remeber to add to the autocmd for FileType below 12 | 'awk', 13 | 'bash', 14 | 'c', 15 | 'cpp', 16 | 'css', 17 | 'csv', 18 | 'c_sharp', 19 | 'desktop', 20 | 'editorconfig', 21 | 'diff', 22 | 'fsharp', 23 | 'javascript', 24 | 'git_config', 25 | 'git_rebase', 26 | 'gitattributes', 27 | 'gitcommit', 28 | 'gitignore', 29 | 'go', 30 | 'gotmpl', 31 | 'html', 32 | 'ini', 33 | 'json', 34 | 'json5', 35 | 'jsonc', 36 | 'json', 37 | 'just', 38 | 'lua', 39 | 'make', 40 | 'markdown', 41 | 'nix', 42 | 'nu', 43 | 'powershell', 44 | 'python', 45 | 'razor', 46 | 'regex', 47 | 'ruby', 48 | 'rust', 49 | 'scss', 50 | 'sql', 51 | 'ssh_config', 52 | 'terraform', 53 | 'toml', 54 | 'typescript', 55 | 'vim', 56 | 'xml', 57 | 'yaml', 58 | } 59 | local installed = vim.api.nvim_get_runtime_file("parser/*.so", true) 60 | local missing = {} 61 | for _, lang in ipairs(languages) do 62 | local found = false 63 | for _, file in ipairs(installed) do 64 | if file:match(lang .. '%.so$') then 65 | found = true 66 | break 67 | end 68 | end 69 | if not found then 70 | table.insert(missing, lang) 71 | end 72 | end 73 | if #missing > 0 then 74 | print("Missing parsers: " .. table.concat(missing, ", ")) 75 | require'nvim-treesitter'.install(missing) 76 | end 77 | 78 | vim.api.nvim_create_autocmd('FileType', { 79 | pattern = languages, 80 | callback = function() 81 | vim.treesitter.start() 82 | vim.opt.foldexpr = 'v:lua.vim.treesitter.foldexpr()' 83 | vim.opt.foldmethod = 'expr' 84 | vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" 85 | end, 86 | }) 87 | 88 | require'treesitter-context'.setup{ 89 | enable = true, -- Enable this plugin (Can be enabled/disabled later via commands) 90 | multiwindow = true, -- Enable multiwindow support. 91 | max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit. 92 | min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit. 93 | line_numbers = true, 94 | multiline_threshold = 20, -- Maximum number of lines to show for a single context 95 | trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' 96 | mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' 97 | zindex = 20, -- The Z-index of the context window 98 | } 99 | end, 100 | } 101 | -------------------------------------------------------------------------------- /lua/plugins/trouble.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/trouble.nvim", 3 | opts = {}, 4 | cmd = "Trouble", 5 | keys = { 6 | { 7 | "xx", 8 | "Trouble diagnostics toggle", 9 | desc = "Diagnostics (Trouble)", 10 | }, 11 | { 12 | "xX", 13 | "Trouble diagnostics toggle filter.buf=0", 14 | desc = "Buffer Diagnostics (Trouble)", 15 | }, 16 | { 17 | "cs", 18 | "Trouble symbols toggle focus=false", 19 | desc = "Symbols (Trouble)", 20 | }, 21 | { 22 | "cl", 23 | "Trouble lsp toggle focus=false win.position=right", 24 | desc = "LSP Definitions / references / ... (Trouble)", 25 | }, 26 | { 27 | "xL", 28 | "Trouble loclist toggle", 29 | desc = "Location List (Trouble)", 30 | }, 31 | { 32 | "xQ", 33 | "Trouble qflist toggle", 34 | desc = "Quickfix List (Trouble)", 35 | }, 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /lua/plugins/which_key.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/which-key.nvim", 3 | event = "VeryLazy", 4 | opts = { 5 | -- your configuration comes here 6 | -- or leave it empty to use the default settings 7 | -- refer to the configuration section below 8 | spec = { 9 | -- Debugger 10 | { 11 | "\\d", 12 | group = "Debugger", 13 | nowait = true, 14 | }, 15 | { 16 | "", 17 | function() 18 | require("persistent-breakpoints.api").toggle_breakpoint() 19 | end, 20 | desc = "Toggle Breakpoint", 21 | nowait = true, 22 | }, 23 | { 24 | "", 25 | function() 26 | require("dap").continue() 27 | end, 28 | desc = "Continue", 29 | nowait = true, 30 | }, 31 | { 32 | "", 33 | function() 34 | require("dap").step_into() 35 | end, 36 | desc = "Step Into", 37 | nowait = true, 38 | }, 39 | { 40 | "", 41 | function() 42 | require("dap").step_over() 43 | end, 44 | desc = "Step Over", 45 | nowait = true, 46 | }, 47 | { 48 | "", -- "", 49 | function() 50 | require("dap").step_out() 51 | end, 52 | desc = "Step Out", 53 | nowait = true, 54 | }, 55 | { 56 | "", --"", 57 | function() 58 | require("dap").terminate() 59 | require("dapui").close() 60 | require("nvim-dap-virtual-text").toggle() 61 | end, 62 | desc = "Terminate", 63 | nowait = true, 64 | }, 65 | { 66 | "C-", 67 | function() 68 | require("dap").run_to_cursor() 69 | end, 70 | desc = "Run to cursor", 71 | nowait = true, 72 | }, 73 | { 74 | "", -- "S-F10", 75 | function() require("dap").goto_() 76 | end, 77 | desc = "Set Next Statement", 78 | nowait = true, 79 | }, 80 | { 81 | "\\dr", 82 | function() require("dap").repl.open() 83 | end, 84 | desc = "Open REPL", 85 | nowait = true, 86 | }, 87 | { 88 | "\\dl", 89 | function() 90 | require("dap").run_last() 91 | end, 92 | desc = "Run Last", 93 | nowait = true, 94 | }, 95 | { 96 | "\\db", 97 | function() 98 | require("dap").list_breakpoints() 99 | end, 100 | desc = "List Breakpoints", 101 | nowait = true, 102 | }, 103 | { 104 | "\\de", 105 | function() 106 | require("dap").set_exception_breakpoints({ "all" }) 107 | end, 108 | desc = "Set Exception Breakpoints", 109 | nowait = true, 110 | }, 111 | }, 112 | }, 113 | keys = { 114 | { 115 | "\\?", 116 | function() 117 | require("which-key").show({ global = false }) 118 | end, 119 | desc = "Buffer Local Keymaps (which-key)", 120 | }, 121 | }, 122 | } 123 | -------------------------------------------------------------------------------- /manage_plugins.vim: -------------------------------------------------------------------------------- 1 | " Script adapted from: 2 | " https://github.com/BlueDrink9/env/blob/master/editors/vim/manage_plugins.vim 3 | " See gist: 4 | " https://gist.github.com/BlueDrink9/474b150c44d41b80934990c0acfb00be 5 | 6 | " This command is your main interface to the plugin: 7 | " args: anything vim-plug supports in its extra options, plus: 8 | " * afterLoad: the name of a vimscript function to run after the plugin 9 | " lazy-loads. 10 | " * event: list of autocmd events that the plugin should lazy-load on 11 | " * Any other lazy.nvim spec config options that don't have a Plug alternative 12 | " (Note, for `keys`, modes are only supported via the special MakeLazyKeys 13 | " function.) 14 | command! -bang -nargs=+ Plugin call PluginAdapter() 15 | 16 | function! GetPluginName(pluginUrl) 17 | " Get plugin name out of a plugin spec name/url. Fairly simplistic, so 18 | " don't include .git at the end of your urls. 19 | return split(a:pluginUrl, '/')[-1] 20 | endfunction 21 | 22 | " Define function to check if a plugin is added to the manager. 23 | " Accepts only the last part of the plugin name (See GetPluginName()). 24 | " Usage: IsPluginUsed('nvim-treesitter') 25 | if has('nvim') 26 | lua IsPluginUsed = function(name) local s = require'lazy.core.config'.spec return s ~= nil and s.plugins[name] ~= nil end 27 | endif 28 | 29 | function! IsPluginUsed(name) 30 | if has('nvim') 31 | return has_key(s:plugs, a:name) 32 | else 33 | return has_key(g:plugs, a:name) 34 | endif 35 | endfunction 36 | 37 | " To remove a Plugged repo using UnPlug 'pluginName' 38 | function! s:deregister(name) 39 | " name: See GetPluginName() 40 | try 41 | if has('nvim') 42 | call remove(s:plugs, a:name) 43 | return 44 | else 45 | call remove(g:plugs, a:name) 46 | call remove(g:plugs_order, index(g:plugs_order, a:name)) 47 | endif 48 | " strip anything after period because not legitimate variable. 49 | let l:varname = substitute(a:name, '\..*', '', '') 50 | let l:varname = substitute(l:varname, 'vim-', '', '') 51 | exec 'let g:loaded_' . l:varname . ' = 1' 52 | catch /^Vim\%((\a\+)\)\=:E716:/ 53 | echom 'Unplug failed for ' . a:name 54 | endtry 55 | endfunction 56 | command! -nargs=1 -bar UnPlug call s:deregister() 57 | 58 | if has('nvim') 59 | lua << EOF 60 | -- Allow making a keys table with modes for Lazy.vim in vimscript 61 | -- Expects a dictionary where keys are a string of modes and values are 62 | -- a list of keys. 63 | -- usage: add plugin opt: 64 | -- Plugin 'abc/def', {'keys': MakeLazyKeys({ 65 | -- " \ 'n': ['[', ']'], 66 | -- " \ 'ov': ['i,', 'a', 'I', 'A'], 67 | -- " \ })} 68 | -- Returns a lua function for setting up a lazy keys spec. Need to return a 69 | -- function because can't return a mixed list/dict table in vimscript. 70 | MakeLazyKeys = function(args) 71 | return function() 72 | local ret = {} 73 | for modes, keys in pairs(args) do 74 | for _, key in ipairs(keys) do 75 | modesT = {} 76 | for i = 1, #modes do 77 | modesT[i] = modes:sub(i, i) 78 | end 79 | table.insert(ret, { key, mode = modesT}) 80 | end 81 | end 82 | return ret 83 | end 84 | end 85 | EOF 86 | function! MakeLazyKeys(args) 87 | return luaeval('MakeLazyKeys(_A[1])', [a:args]) 88 | endfunction 89 | else 90 | function! MakeLazyKeys(args) 91 | return [] 92 | endfunction 93 | endif 94 | 95 | " Passes plugin to a lua function that creates a lazy.nvim spec, or to a vimscript 96 | " function to adapt the args for vim-plug. 97 | function! s:PluginAdapter(...) 98 | let l:plugin = a:1 99 | let l:args = {} 100 | if a:0 == 2 101 | let l:args = a:2 102 | endif 103 | if has('nvim') 104 | " Has to be global so lua sees it 105 | let g:__plugin_args = l:args 106 | exec 'lua PlugToLazy("' . l:plugin . '", vim.g.__plugin_args)' 107 | let s:plugs[GetPluginName(l:plugin)] = 1 108 | else 109 | call PlugPlusLazyArgs(l:plugin, l:args) 110 | endif 111 | endfunction 112 | 113 | if has('nvim') 114 | let s:plugs = {} 115 | lua << EOF 116 | LazyPlugSpecs = {} 117 | -- Compatibility function to convert vim-plug's Plug command to lazy.nvim spec 118 | function PlugToLazy(plugin, opts) 119 | -- Build lazy plugin spec, converting any vim-plug options. 120 | local lazySpec = {} 121 | if opts then 122 | lazySpec = opts 123 | lazySpec.ft = opts["for"] 124 | -- lazySpec.for = nil 125 | lazySpec.name = opts["as"] 126 | lazySpec.as = nil 127 | lazySpec.cmd = opts["on"] 128 | lazySpec.on = nil 129 | lazySpec.version = opts["tag"] 130 | if opts['afterLoad'] then 131 | lazySpec['config'] = function() 132 | -- Either call the default afterLoad function... 133 | if opts['afterLoad'] == true then 134 | vim.fn[vim.fn.PluginNameToFunc( 135 | vim.fn.GetPluginName(plugin) 136 | )]() 137 | else 138 | -- ...or call the specified name. 139 | vim.fn[opts['afterLoad']]() 140 | end 141 | end 142 | end 143 | if lazySpec.cmd then 144 | -- Ensure it is a list/table 145 | if type(lazySpec.cmd) == "string" then 146 | lazySpec.cmd = {lazySpec.cmd} 147 | end 148 | -- mappings are commands ('on') for Plug, but keys for Lazy 149 | for k, cmd in pairs(lazySpec.cmd) do 150 | if string.find(string.lower(cmd), "", 1, 6) then 151 | lazySpec.keys = lazySpec.keys or {} 152 | -- Convert plug mappings for all modes, not just default of 'n' 153 | table.insert(lazySpec.keys, {cmd, mode={'n','v','o','l'}}) 154 | lazySpec.cmd[k] = nil 155 | end 156 | end 157 | -- Remove any empty cmd table to prevent lazyload (may be empty if 158 | -- used to force a lazy load in Plug) 159 | if not lazySpec.cmd then lazySpec.cmd = nil end 160 | end 161 | end 162 | lazySpec[1] = plugin 163 | table.insert(LazyPlugSpecs, lazySpec) 164 | end 165 | EOF 166 | endif 167 | 168 | function! PluginNameToFunc(name) 169 | " Convert a plugins name to default function name to use for afterLoad 170 | " functions. 171 | " Has to be a global function so lua can access it. 172 | return 'Plug_after_' . substitute(a:name, '[\\.-]', '_', 'g') 173 | endfunction 174 | 175 | " Rest is entirely plug-specific 176 | if has('nvim') 177 | finish 178 | endif 179 | 180 | function! PlugPlusLazyArgs(plugin, args) 181 | let l:plugin_name = GetPluginName(a:plugin) 182 | let l:args = a:args 183 | " convert lazy args we want to keep when using plug 184 | for dep in get(l:args, 'dependencies', []) 185 | Plug dep 186 | endfor 187 | " Handle hook for after load 188 | let l:func = get(l:args, 'afterLoad', v:false) 189 | " If 'afterLoad' is v:true, call function based off a default name 190 | " convention (the plugin name, with _ replacing . and -). Otherwise 191 | " call the function name passed in. For example, to configure for a 192 | " plugin named 'my-plugin.vim', define a function called 193 | " Plug_after_my_plugin_vim(). 194 | " Only will be called for lazy-loaded plugins, so don't use without 195 | " an 'on' or 'for' mapping. ('keys' gets ignored). 196 | if l:func == v:true 197 | exec 'au User ' . l:plugin_name . ' call ' . PluginNameToFunc(l:plugin_name) . '()' 198 | elseif l:func != v:false 199 | exec 'au User ' . l:plugin_name . ' call ' . l:func . '()' 200 | endif 201 | 202 | for event in get(l:args, 'event', []) 203 | " Removes unsupported events, e.g. VeryLazy. 204 | if !exists('##' . event) 205 | continue 206 | endif 207 | call s:loadPluginOnEvent(l:plugin_name, event) 208 | " Add empty 'on' argument to enable lazyloading. 209 | if !has_key(l:args, 'on') 210 | let l:args['on'] = [] 211 | endif 212 | endfor 213 | 214 | call s:removeUnsupportedArgs(l:args) 215 | Plug a:plugin, l:args 216 | endfunction 217 | 218 | function! s:removeUnsupportedArgs(args) 219 | " Remove args unsupported by Plug 220 | let l:PlugOpts = [ 221 | \ 'branch', 222 | \ 'tag', 223 | \ 'commit', 224 | \ 'rtp', 225 | \ 'dir', 226 | \ 'as', 227 | \ 'do', 228 | \ 'on', 229 | \ 'for', 230 | \ 'frozen', 231 | \ ] 232 | for opt in keys(a:args) 233 | if index(l:PlugOpts, opt) < 0 " If item not in the list. 234 | silent! call remove(a:args, opt) 235 | endif 236 | endfor 237 | endfunction 238 | 239 | " Add support for loading Plug plugins on specific event. 240 | function! s:loadPluginOnEvent(name, event) 241 | " Plug-loads function on autocmd event. 242 | " Plug options should include 'on': [] to prevent load before event. 243 | " name: the last part of the plugin url (See GetPluginName()). 244 | " event: name of autocmd event 245 | " Example: 246 | " Plug 'ycm-core/YouCompleteMe', {'on': []} 247 | " call LoadPluginOnEvent('YouCompleteMe', 'InsertEnter') 248 | let l:plugLoad = 'autocmd ' . a:event . ' * call plug#load("' 249 | let l:plugLoadEnd = '")' 250 | let l:augroupName = a:name . '_' . a:event 251 | let l:undoAutocmd = 'autocmd! ' . l:augroupName 252 | exec 'augroup ' . l:augroupName 253 | autocmd! 254 | exec l:plugLoad . a:name . l:plugLoadEnd . ' | ' . l:undoAutocmd 255 | exec 'augroup END' 256 | endfunction 257 | -------------------------------------------------------------------------------- /maps.vim: -------------------------------------------------------------------------------- 1 | inoremap jj 2 | nnoremap oo ok 3 | nnoremap OO Oj 4 | 5 | " remap split navigation 6 | nnoremap 7 | nnoremap 8 | nnoremap 9 | nnoremap 10 | 11 | " reformat (visual and normal mode) 12 | function! s:Reformat() 13 | mark a 14 | normal! ggVGgq 15 | 'a 16 | delmarks a 17 | endfunction 18 | nnoremap j :call Reformat() 19 | xnoremap j gq 20 | -------------------------------------------------------------------------------- /nerdtree.vim: -------------------------------------------------------------------------------- 1 | function s:OpenNERDTree(bootstrap) 2 | " if the current tab is the first one, open a new NERDTree, 3 | " otherwise mirror the existing NERDTree. 4 | if &filetype =~# 'dap' || g:dap_debugger_running || exists('t:NERDTreeBufName') 5 | return 6 | endif 7 | 8 | if g:NERDTreeShouldBeOpen == 1 9 | if &buftype == '' && getcmdwintype() == '' 10 | if a:bootstrap 11 | silent NERDTree 12 | else 13 | if g:NERDTree.ExistsForTab() 14 | silent NERDTreeToggle 15 | else 16 | silent NERDTree 17 | endif 18 | endif 19 | endif 20 | if &filetype ==# 'nerdtree' | wincmd t | endif " move the cursor to code window 21 | endif 22 | endfunction 23 | 24 | function s:ToggleNERDTreeOnTabEnter() 25 | if &filetype =~# 'dap' || g:dap_debugger_running 26 | return 27 | endif 28 | 29 | if g:NERDTreeShouldBeOpen == 1 30 | if g:NERDTree.ExistsForTab() 31 | if !g:NERDTree.IsOpen() 32 | silent NERDTreeToggle 33 | endif 34 | else 35 | if &buftype == '' && getcmdwintype() == '' 36 | silent NERDTree 37 | endif 38 | endif 39 | if &filetype ==# 'nerdtree' | wincmd t | endif " move the cursor to code window 40 | else 41 | if g:NERDTree.ExistsForTab() 42 | if g:NERDTree.IsOpen() 43 | silent NERDTreeToggle 44 | endif 45 | endif 46 | endif 47 | endfunction 48 | 49 | function s:SelectFileOnNERDTree() 50 | if &filetype =~# 'dap' || g:dap_debugger_running 51 | return 52 | endif 53 | if g:NERDTreeShouldBeOpen == 0 54 | return 55 | endif 56 | if &filetype ==# 'nerdtree' | wincmd t | endif " move the cursor to code window 57 | if &buftype == '' && getcmdwintype() == '' 58 | silent NERDTreeFind 59 | endif 60 | if &filetype ==# 'nerdtree' | wincmd t | endif " move the cursor to code window 61 | endfunction 62 | 63 | function s:OpenInitialNERDTreeWindows() 64 | let s:number_of_tabs = tabpagenr('$') 65 | if (argc() == 0 || s:number_of_tabs > 1) && !exists('s:std_in') 66 | let s:current_tab = tabpagenr() 67 | for i in range(1, s:number_of_tabs) 68 | exec 'tabnext ' . i 69 | call s:OpenNERDTree(i) 70 | endfor 71 | for i in range(1, s:number_of_tabs) 72 | exec 'tabnext ' . i 73 | call s:SelectFileOnNERDTree() 74 | endfor 75 | exec 'tabnext ' . s:current_tab 76 | if &filetype ==# 'nerdtree' | wincmd t | endif " move the cursor to code window 77 | endif 78 | endfunction 79 | 80 | function! g:ToggleNERDTreeOnKeyPress() 81 | if g:NERDTree.IsOpen() 82 | let g:NERDTreeShouldBeOpen=0 83 | else 84 | let g:NERDTreeShouldBeOpen=1 85 | endif 86 | if g:NERDTree.ExistsForTab() 87 | silent NERDTreeToggle 88 | else 89 | silent NERDTree 90 | endif 91 | if &filetype ==# 'nerdtree' | wincmd t | endif " move the cursor to code window 92 | endfunction 93 | 94 | function s:BufferDeleteOrQuit() 95 | call VerboseEchomsg("Starting BufferDeleteOrQuit()") 96 | if &buftype != '' 97 | call VerboseEchomsg("Quitting not normal buffer") 98 | quit 99 | return 100 | endif 101 | let listed_buffers = filter(range(1, bufnr('$')), "buflisted(v:val) && v:val != bufnr('%')") 102 | call VerboseEchomsg("Listed buffers: " . string(listed_buffers)) 103 | if len(listed_buffers) == 0 104 | call VerboseEchomsg("Quitting with no buffers") 105 | quitall 106 | else 107 | if len(filter(tabpagebuflist(), 'buflisted(v:val)')) > 1 108 | call VerboseEchomsg("There is more than one buffer in the current tab, closing it: " . string(len(filter(tabpagebuflist(), 'buflisted(v:val)')))) 109 | let current_buffer = bufnr('%') 110 | if tabpagenr('$') > 1 111 | call VerboseEchomsg("Quitting with buffer: " . current_buffer) 112 | quit 113 | else 114 | call VerboseEchomsg("Buffer to delete: " . current_buffer) 115 | execute "bd " . current_buffer 116 | endif 117 | return 118 | endif 119 | let current_buffer = bufnr('%') 120 | call VerboseEchomsg("Current buffer: " . current_buffer) 121 | let all_buffers_opened_in_all_tabs = [] 122 | for tab in range(1, tabpagenr('$')) 123 | let list = tabpagebuflist(tab) 124 | let all_buffers_opened_in_all_tabs += filter(list, 'buflisted(v:val)') 125 | endfor 126 | let all_buffers_opened_in_all_tabs = filter(all_buffers_opened_in_all_tabs, 'v:val != bufnr("%")') 127 | let hidden_buffers = filter(listed_buffers, 'index(all_buffers_opened_in_all_tabs, v:val) == -1') 128 | if len(hidden_buffers) == 0 129 | call VerboseEchomsg("There are no hidden buffers") 130 | quit 131 | else 132 | call VerboseEchomsg("There are hidden buffers: " . string(hidden_buffers)) 133 | execute 'normal [b' 134 | execute "bd " . current_buffer 135 | endif 136 | endif 137 | call VerboseEchomsg("Finished BufferDeleteOrQuit()") 138 | endfunction 139 | 140 | cnoreabbrev q ((getcmdtype() == ':' && getcmdline() ==# 'q') ? 'call BufferDeleteOrQuit()' : 'q') 141 | 142 | function s:ConfigureNERDTree() 143 | if exists("g:NERDTree") 144 | " from the box NERDTree settings 145 | let g:NERDTreeShowHidden=1 146 | let g:NERDTreeAutoDeleteBuffer=1 147 | let g:NERDTreeExtensionHighlightColor = {} 148 | let g:NERDTreeExtensionHighlightColor['nix'] = "689FB6" 149 | let g:NERDTreeWinPos = "right" 150 | let g:NERDTreeCustomOpenArgs = {'file': {'reuse': 'all', 'where': 'p', 'keepopen': 1, 'stay': 0}, 'dir': {}} " always open new files in new tabs, and reuse existing tabs if they are already open 151 | " my custom NERDTree settings 152 | augroup MyNERDTreeConfig 153 | autocmd! 154 | autocmd BufWinEnter * call s:OpenNERDTree(0) 155 | autocmd BufWinEnter * call s:SelectFileOnNERDTree() 156 | " Close the tab if NERDTree is the only window remaining in it. 157 | autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif 158 | " always select the code window when a tab changes 159 | autocmd TabEnter * call s:ToggleNERDTreeOnTabEnter() 160 | autocmd TabEnter * if &filetype ==# 'nerdtree' | wincmd t | endif 161 | " If another buffer tries to replace NERDTree, put it in the other window, and bring back NERDTree. 162 | autocmd BufEnter * if winnr() == winnr('h') && bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 | 163 | \ let buf=bufnr() | buffer# | execute "normal! \w" | execute 'buffer'.buf | endif 164 | augroup END 165 | map :NERDTreeFind 166 | noremap :call g:ToggleNERDTreeOnKeyPress() 167 | endif 168 | endfunction 169 | 170 | if !exists("g:dap_debugger_running") 171 | let g:dap_debugger_running=0 172 | endif 173 | let g:NERDTreeShouldBeOpen=1 174 | augroup NERDTreeSetup 175 | autocmd! 176 | autocmd StdinReadPre * let s:std_in=1 177 | autocmd VimEnter * call s:ConfigureNERDTree() 178 | autocmd VimEnter * call s:OpenInitialNERDTreeWindows() 179 | augroup END 180 | -------------------------------------------------------------------------------- /plugins.vim: -------------------------------------------------------------------------------- 1 | if !has('nvim') 2 | if empty(glob(g:vimHome . '/autoload/plug.vim')) 3 | if has('unix') 4 | silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim 5 | elseif has('win32') 6 | execute 'silent !powershell -noprofile -c "Invoke-WebRequest -UseBasicParsing https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim | New-Item $env:USERPROFILE/.vim/autoload/plug.vim -Force"' 7 | endif 8 | endif 9 | 10 | if has("autocmd") 11 | augroup InstallPlugins 12 | autocmd! 13 | " Run PlugInstall if there are missing plugins 14 | autocmd VimEnter * if len(filter(values(g:plugs), '!isdirectory(v:val.dir)')) 15 | \| PlugInstall --sync | source $MYVIMRC 16 | \| endif 17 | augroup END 18 | endif 19 | endif 20 | 21 | let g:pluginInstallPath = g:vimHome . '/plugged' 22 | let g:vimPluginInstallPath = g:pluginInstallPath . '/vim' 23 | let g:nvimPluginInstallPath = g:pluginInstallPath . '/nvim' 24 | runtime manage_plugins.vim 25 | 26 | if has('nvim') " editorconfig is on by default on nvim 27 | if filereadable(".editorconfig") 28 | let g:editorconfig_is_enabled=1 29 | else 30 | let g:editorconfig_is_enabled=0 31 | endif 32 | else 33 | let g:editorconfig_is_enabled=0 34 | if &verbose == 0 " todo: Error when loading with verbose, remove when https://github.com/editorconfig/editorconfig-vim/issues/221 is fixed 35 | packadd! editorconfig 36 | if filereadable(".editorconfig") 37 | let g:editorconfig_is_enabled=1 38 | endif 39 | endif 40 | endif 41 | 42 | if !has('nvim') 43 | call plug#begin(g:vimPluginInstallPath) 44 | endif 45 | 46 | " Using 'Plugin' instead of 'Plug' because of the adapter from manage_plugins.vim 47 | if !has('nvim') 48 | " LSP support for Vim. Neovim has built-in LSP support. 49 | Plugin 'neoclide/coc.nvim', {'branch': 'release'} 50 | endif 51 | let g:vim_nerdtree_plug_args = { } 52 | if has('nvim') 53 | let g:vim_nerdtree_plug_args['lazy'] = 'false' 54 | endif 55 | " file explorer 56 | Plugin 'scrooloose/nerdtree', g:vim_nerdtree_plug_args 57 | " icons 58 | Plugin 'ryanoasis/vim-devicons', {'dependencies': ['scrooloose/nerdtree']} 59 | if !has('nvim') 60 | Plugin 'ctrlpvim/ctrlp.vim' 61 | Plugin 'mattn/emmet-vim' 62 | endif 63 | if !has('nvim') 64 | " snippets: 65 | " (using snippes in coc-vim, so that is why only the snipped sources are installed here) 66 | " nvim is using its own snippet sources and providers 67 | Plugin 'honza/vim-snippets' 68 | endif 69 | 70 | Plugin 'Shougo/vimproc.vim', {'do' : 'make'} 71 | Plugin 'tpope/vim-fugitive' 72 | Plugin 'tpope/vim-unimpaired' 73 | Plugin 'vim-airline/vim-airline' 74 | Plugin 'vim-airline/vim-airline-themes' 75 | Plugin 'christoomey/vim-tmux-navigator' 76 | Plugin 'easymotion/vim-easymotion' 77 | Plugin 'vim-scripts/ReplaceWithRegister' 78 | Plugin 'kaicataldo/material.vim', { 'branch': 'main' } 79 | Plugin 'tiagofumo/vim-nerdtree-syntax-highlight' 80 | Plugin 'AndrewRadev/bufferize.vim' 81 | " we don't need to strip whitespace on save if editorconfig is enabled 82 | " as it has its own configuration for this 83 | " this config is for ntpeters/vim-better-whitespace 84 | let g:strip_whitespace_on_save=!g:editorconfig_is_enabled 85 | Plugin 'ntpeters/vim-better-whitespace' 86 | if !has('nvim') 87 | " nvim already has a built-in comment system 88 | Plugin 'tpope/vim-commentary' 89 | " using mini-pick instead of fzf in nvim 90 | Plugin 'junegunn/fzf', { 'lazy': 'true', 'do': { -> fzf#install() } } 91 | " loading in the end as fzf has issues with Buffers (specially NERDTree) 92 | Plugin 'junegunn/fzf.vim', { 'for': 'nerdtree', 'lazy': 'true', 'event': 'VeryLazy', 'dependencies': ['junegunn/fzf'] } 93 | endif 94 | if version >= 900 || has('nvim') 95 | Plugin 'github/copilot.vim' 96 | endif 97 | 98 | if has('nvim') 99 | lua require("config.lazy") 100 | else 101 | call plug#end() 102 | endif 103 | 104 | -------------------------------------------------------------------------------- /plugins_config.vim: -------------------------------------------------------------------------------- 1 | " Easymotion config: 2 | let g:EasyMotion_smartcase = 1 " Turn on case insensitive feature 3 | 4 | if !has('nvim') 5 | " CtrlP config: 6 | let g:ctrlp_max_files=0 7 | let g:ctrlp_custom_ignore = { 8 | \ 'dir': '\v[\/]\.(git|hg|svn|yarn)|node_modules$', 9 | \ 'file': '\v\.(exe|so|dll)$' 10 | \ } 11 | let g:ctrlp_user_command = { 12 | \ 'types': { 13 | \ 1: ['.git', 'cd %s && git ls-files -co --exclude-standard'], 14 | \ 2: ['.hg', 'hg --cwd %s locate -I .'], 15 | \ }, 16 | \ } 17 | let g:ctrlp_switch_buffer = 'ET' " switch to buffer in any tab or window, if file is already open 18 | let g:ctrlp_open_new_file = 'r' " open new file in current window 19 | let g:ctrlp_open_multiple_files = 'v' " open multiple files in vertical splits 20 | 21 | " FZF config: 22 | nmap f :Rg 23 | endif 24 | 25 | " EditorConfig config: 26 | let g:EditorConfig_exclude_patterns = ['fugitive://.*'] " exclude fugitive from editorconfig 27 | 28 | " Used by ripgrep to find the config file hosted at ~/.vim/.ripgreprc 29 | " See more at: https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file 30 | " ripgrep is used by fzf and by mini pick 31 | let $RIPGREP_CONFIG_PATH=expand(vimHome . "/.ripgreprc") 32 | 33 | " Ths if for the futitive command, which uses Git, with the first letter capitalized 34 | cnoreabbrev git ((getcmdtype() == ':' && getcmdline() ==# 'git') ? 'Git' : 'git') 35 | 36 | " Better whitespace options 37 | let g:better_whitespace_operator='_s' 38 | let g:better_whitespace_enabled=1 39 | let g:strip_whitespace_confirm=0 40 | 41 | " vim-airline key maps: 42 | let g:airline#extensions#tabline#buffer_idx_mode = 1 43 | nmap 1 AirlineSelectTab1 44 | nmap 2 AirlineSelectTab2 45 | nmap 3 AirlineSelectTab3 46 | nmap 4 AirlineSelectTab4 47 | nmap 5 AirlineSelectTab5 48 | nmap 6 AirlineSelectTab6 49 | nmap 7 AirlineSelectTab7 50 | nmap 8 AirlineSelectTab8 51 | nmap 9 AirlineSelectTab9 52 | nmap 0 AirlineSelectTab0 53 | nmap ]b :wincmd tAirlineSelectNextTab 54 | nmap [b :wincmd tAirlineSelectPrevTab 55 | -------------------------------------------------------------------------------- /queries/gotmpl/injections.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | 3 | ((text) @injection.content 4 | (#set! injection.language "html") 5 | (#set! injection.combined)) 6 | -------------------------------------------------------------------------------- /session_management.vim: -------------------------------------------------------------------------------- 1 | function! s:SessionAutoStart() 2 | let g:session_autoloading=0 3 | if exists("g:session_disable_autoload") && g:session_disable_autoload == 1 4 | return 5 | endif 6 | if argc() > 0 7 | let s:session_autoload=0 8 | return 9 | endif 10 | let s:session_autoload=1 11 | let g:session_autoloading=1 12 | if filereadable(".session.vim") 13 | source .session.vim 14 | endif 15 | let g:session_autoloading=0 16 | endfunction 17 | 18 | function! SaveSession() 19 | call VerboseEchomsg("Saving session...") 20 | if s:session_autoload == 0 21 | return 22 | endif 23 | if exists("g:session_disable_autoload") && g:session_disable_autoload == 1 24 | return 25 | endif 26 | silent! mksession! .session.vim 27 | call VerboseEchomsg("Session saved.") 28 | endfunction 29 | 30 | set sessionoptions-=options 31 | set sessionoptions-=blank 32 | set sessionoptions-=help 33 | set sessionoptions-=terminal 34 | let s:session_autoload=0 35 | 36 | if has("autocmd") 37 | augroup SessionAuto 38 | autocmd! 39 | autocmd VimLeavePre * call SaveSession() 40 | autocmd VimEnter * nested call s:SessionAutoStart() 41 | augroup END 42 | endif 43 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { }, ... }: 2 | 3 | pkgs.mkShell { 4 | name = "vimfiles"; 5 | nativeBuildInputs = with pkgs; [ 6 | vim-language-server # VImScript language server, LSP for vim script https://github.com/iamcco/vim-language-server 7 | lua-language-server # Lua language server https://github.com/LuaLS/lua-language-server 8 | # I'd add luajit here, but I'm installing it globally, as I need some packages for shared 9 | # extensions, like tiktoken_core, used by Github Copilot Chat. 10 | ]; 11 | shellHook = '' 12 | echo "Let's (Neo)Vim!" 13 | ''; 14 | } 15 | -------------------------------------------------------------------------------- /theme.vim: -------------------------------------------------------------------------------- 1 | " set t_Co=256 " todo: maybe remove? forces terminal to use 256 colors 2 | call g:CatchError('colorscheme slate') " set to a dark theme until the material theme is loaded 3 | let g:airline_powerline_fonts = 1 4 | let g:airline#extensions#tabline#enabled = 1 5 | let g:airline#extensions#tabline#show_buffers = 1 6 | let g:airline#extensions#tabline#tab_nr_type = 1 7 | let g:airline#extensions#tabline#buffer_nr_show = 0 8 | let g:airline#extensions#tabline#show_close_button = 1 9 | let g:airline#extensions#tabline#close_symbol = 'X' 10 | let g:airline#extensions#tabline#formatter = 'unique_tail_improved' 11 | let g:airline#extensions#tabline#fnamecollapse = 1 12 | let g:airline#extensions#branch#enabled = 1 13 | let g:airline#extensions#fzf#enabled = 1 14 | let g:airline_theme='dark' 15 | let g:airline#extensions#tabline#buffer_idx_format = { 16 | \ '0': '0 ', 17 | \ '1': '1 ', 18 | \ '2': '2 ', 19 | \ '3': '3 ', 20 | \ '4': '4 ', 21 | \ '5': '5 ', 22 | \ '6': '6 ', 23 | \ '7': '7 ', 24 | \ '8': '8 ', 25 | \ '9': '9 ' 26 | \} 27 | 28 | if has('nvim') 29 | " enable/disable nvimlsp integration > 30 | let g:airline#extensions#nvimlsp#enabled = 1 31 | " nvimlsp error_symbol > 32 | let g:airline#extensions#nvimlsp#error_symbol = 'E:' 33 | " nvimlsp warning - needs v:lua.vim.diagnostic.get 34 | let g:airline#extensions#nvimlsp#warning_symbol = 'W:' 35 | " nvimlsp show_line_numbers - needs v:lua.vim.diagnostic.get 36 | let g:airline#extensions#nvimlsp#show_line_numbers = 1 37 | " nvimlsp open_lnum_symbol - needs v:lua.vim.diagnostic.get 38 | let g:airline#extensions#nvimlsp#open_lnum_symbol = '(L' 39 | " nvimlsp close_lnum_symbol - needs v:lua.vim.diagnostic.get 40 | let g:airline#extensions#nvimlsp#close_lnum_symbol = ')' 41 | else 42 | " enable/disable coc integration > 43 | let g:airline#extensions#coc#enabled = 1 44 | " change error symbol: > 45 | let g:airline#extensions#coc#error_symbol = 'E:' 46 | " change warning symbol: > 47 | let g:airline#extensions#coc#warning_symbol = 'W:' 48 | " enable/disable coc status display > 49 | let g:airline#extensions#coc#show_coc_status = 1 50 | " change the error format (%C - error count, %L - line number): > 51 | let g:airline#extensions#coc#stl_format_err = '%C(L%L)' 52 | " change the warning format (%C - error count, %L - line number): > 53 | let g:airline#extensions#coc#stl_format_warn = '%C(L%L)' 54 | endif 55 | 56 | set background=dark 57 | let g:material_theme_style = 'darker' " 'default' | 'palenight' | 'ocean' | 'lighter' | 'darker' | 'default-community' | 'palenight-community' | 'ocean-community' | 'lighter-community' | 'darker-community' 58 | let g:material_terminal_italics = 1 59 | let g:airline_theme = 'material' 60 | " Enable true colors 61 | if (has("termguicolors")) 62 | set termguicolors 63 | endif 64 | --------------------------------------------------------------------------------