" Basic settings. set number set noshowmode set signcolumn=yes set updatetime=250 set scrolloff=5 " Change directory based on current file. if !empty($NIX_SHELL) " Attempt to conflict less with plugins. autocmd BufEnter * if gitbranch#name() != '' | silent! lcd %:p:h else set autochdir endif " inotify compat? set backupcopy=yes " Old defaults (I think). set splitright set splitbelow " Syntax and indent from filetype. set nocompatible filetype plugin indent on syntax on " Check for SHIFT_JIS. set fileencodings=ucs-bom,utf-8,sjis,default,latin1 " 4 spaces autoindent. set tabstop=4 set shiftwidth=4 set expandtab set autoindent " C syntax preference. let g:c_syntax_for_h=1 let g:c_no_curly_error=1 let g:c_function_pointers=1 set cinoptions=:0,=4,l1,g2,h2,(4,u4,+4,m1,j1,J1 set cindent " Set different format for mail and text files. set nowrap nolinebreak nolist formatoptions=l textwidth=0 autocmd FileType mail,text setlocal wrap formatoptions=l textwidth=0 " Ex tab complete that makes sense to me. set wildmode=longest,list,full set wildmenu " Allow distinguishing from in bindings. let &t_TI = '\[>4;2m' let &t_TE = '\[>4;m' " Treat shift + backspace as normal backspace. tnoremap " System clipboard on linux. set clipboard+=unnamedplus " Session options. set ssop=skiprtp,blank,buffers,folds,winsize,terminal set vop-=curdir if isdirectory(expand('~/c')) let view_dir = expand('~/c/sessions/nvim/views') if !isdirectory(view_dir) call mkdir(view_dir, 'p', 0755) endif let &viewdir=view_dir " Staggered backups. let backup_dir = '/mnt/store/backup/vim' if !isdirectory(backup_dir) let backup_dir = expand('~/c/sessions/nvim/backup//') if !isdirectory(backup_dir) call mkdir(backup_dir, 'p', 0755) endif endif let &backupdir=backup_dir set backup " Swap file directory. let swap_dir = expand('~/c/sessions/nvim/swaps//') if !isdirectory(swap_dir) call mkdir(swap_dir, 'p', 0755) endif let &directory=swap_dir if has('persistent_undo') let undo_dir = expand('~/c/sessions/nvim/undo') if !isdirectory(undo_dir) call mkdir(undo_dir, 'p', 0755) endif let &undodir=undo_dir set undofile endif endif " Colorscheme. set termguicolors colo wal-gui " Cursor blink. "set guicursor=a:blinkon1 " Highlight whitespace. au BufEnter * match ExtraWhitespace /\s\+$/ au InsertEnter * match ExtraWhitespace /\s\+\%#\@ 0 ? ' '.l:branchname.' ' : ' ' endfunction function! StatuslineLsp() abort return luaeval('get_lsp_name()') endfunction " Custom statusline. function! Statusline() abort let focused = g:statusline_winid == win_getid(winnr()) let status = focused ? '%#StatusLine#' : '%#StatusLineNC#' let status .= '%{StatuslineGit()}' let status .= ' %f' let status .= ' vim@%{hostname()}' let status .= '%=' let status .= ' %y' let status .= '%{StatuslineLsp()}' let status .= ' %{&fileencoding}' let status .= '[%{&fileformat}]' let status .= '%3p%%' let status .= ' %3l:%-3c' return status endfunction set statusline=%!Statusline() " Make shift + nav keys no-ops. nmap H nmap J nmap K nmap L " Normal mode tab no-op. nmap " ctrl + c no-op. nmap " Disable F1 for help. nmap " Disable q: for histroy. nmap q: " Simplify split movement. nmap :wincmd h nmap :wincmd j nmap :wincmd k nmap :wincmd l nmap :vsplit " Make ctrl + '.' and ',' map to previous buffer. nmap nmap " Swap ctrl + f and b. "nnoremap "nnoremap " Toggle colorcolumn. nmap C :execute 'set colorcolumn=' . (&colorcolumn == '' ? '101' : '') " Personally intuitive pop-up menu binds. inoremap pumvisible() ? '' : '' inoremap pumvisible() ? '' : '' inoremap pumvisible() ? '' : '' " Lsp Binds. nmap " Fzf binds. nmap \ :Buffers nmap :GGrep nmap :GFiles " Only Neogit bind, handle all further operations from this menu. nmap Y :Neogit nmap L :lua neogit_log_current() " Undotree. nmap U :UndotreeToggle " Toggle hex color highlighting. nnoremap # :CccHighlighterToggle command Tabify set noexpandtab | %retab! | set expandtab command Untabify set expandtab | %retab! " https://stackoverflow.com/a/37040415 function! SyntaxGroup() let l:s = synID(line('.'), col('.'), 1) echo synIDattr(l:s, 'name') . ' -> ' . synIDattr(synIDtrans(l:s), 'name') endfun " https://vi.stackexchange.com/a/456 function! TrimWhitespace() let l:save = winsaveview() keeppatterns %s/\s\+$//e call winrestview(l:save) endfun " https://github.com/junegunn/fzf.vim?tab=readme-ov-file#example-git-grep-wrapper command! -bang -nargs=* GGrep \ call fzf#vim#grep( \ 'git grep --line-number -- '.fzf#shellescape(), \ fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), 0) " https://vim.fandom.com/wiki/Replace_a_builtin_command_using_cabbrev function! CommandCabbr(abbreviation, expansion) execute 'cabbr ' . a:abbreviation . ' =getcmdpos() == 1 && getcmdtype() == ":" ? "' . a:expansion . '" : "' . a:abbreviation . '"' endfunction command! -nargs=+ CommandCabbr call CommandCabbr() CommandCabbr no nohlsearch call Juliana#Init() " Custom insert mode tab behavior inherited from Emacs. inoremap =Juliana#CompleteTab('START') \=Juliana#CompleteTab('TAB') \=Juliana#CompleteTab('ALIGN') \=Juliana#CompleteTab('NEXT') inoremap =Juliana#CompleteSTab('PREV') lua << EOF function get_lsp_name() local active_clients = vim.lsp.get_clients({bufnr = vim.api.nvim_get_current_buf()}) if next(active_clients) == nil then return '' else str = '<' for _, v in pairs(active_clients) do str = str .. v.name .. '+' end return str:sub(1, -2) .. '>' end end buf_is_big = function(bufnr) local max_filesize = 100 * 1024 -- 100KB local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(bufnr)) if ok and stats and stats.size > max_filesize then return true else return false end end -- LSP configs. if os.getenv('NIX_SHELL') ~= nil then vim.diagnostic.config({ virtual_text = true }) vim.lsp.config('clangd', { cmd = { 'clangd', '-j=4', '--log=error', '--malloc-trim', '--background-index', '--clang-tidy', '--completion-style=bundled', '--pch-storage=memory', '--header-insertion=never', '--header-insertion-decorators=0', '--query-driver=gcc' }, capabilities = { textDocument = { semanticHighlightingCapabilities = { semanticHighlighting = true }, completion = { completionItem = { snippetSupport = false } } } }, }) vim.lsp.enable({'clangd', 'ruff', 'ty'}) -- https://github.com/neovim/nvim-lspconfig/issues/2626#issuecomment-2117022664 -- https://github.com/neovim/nvim-lspconfig/issues/2508 vim.api.nvim_create_autocmd('BufReadPre', { callback = function(t) if buf_is_big(t.buf) then vim.o.eventignore = 'FileType' vim.schedule(function() vim.o.eventignore = '' print('Dropped FileType events because the buffer is too big') end) end end }) require('inc_rename').setup({}) vim.keymap.set('n', '', function() return ':IncRename ' .. vim.fn.expand('') end, { expr = true }) end -- Set sessions folder and autowrite. if vim.fn.isdirectory(vim.fn.expand('~/c')) then require('mini.sessions').setup({ autoread = false, autowrite = true, directory = '~/c/sessions' }) end -- Completion. require('mini.completion').setup({ window = { info = { border = 'none' }, signature = { border = 'none' } } }) -- Don't use tabs in Neogit. require('neogit').setup({ disable_hint = true, kind = 'vsplit', commit_editor = { kind = 'split' }, commit_select_view = { kind = 'vsplit' }, commit_view = { kind = 'vsplit' }, log_view = { kind = 'split' }, reflog_view = { kind = 'split' }, preview_buffer = { kind = 'split' }, popup = { kind = 'split' }, refs_view = { kind = 'split' }, -- Allow basic movement in Neogit without mapping conflicts. mappings = { popup = { ['l'] = false, ['L'] = 'LogPopup', ['d'] = false }, status = { ['$'] = false, ['#'] = 'CommandHistory' } }, integrations = {} }) -- Doesn't work consistently. function neogit_log_current() require("neogit").action("log", "log_current", { "--", vim.fn.expand("%:p") })() end -- Preview colors in # format. require('ccc').setup({ highlighter = { auto_enable = false, lsp = true } }) EOF