Files
dotfiles/.vimrc
T
2026-08-12 15:57:01 +00:00

254 lines
7.7 KiB
VimL

" Vim 9 configuration shared across Linux, WSL, Windows, and macOS.
if v:version < 900
echoerr 'This configuration requires Vim 9 or newer.'
finish
endif
let g:dotfiledir = fnamemodify(resolve(expand('<sfile>:p')), ':h') . '/'
let g:dotvimdir = g:dotfiledir . 'config/vim'
let g:vim_dir = has('win32') || has('win64') ? expand('~/vimfiles') : expand('~/.vim')
execute 'set runtimepath^=' . fnameescape(g:dotvimdir)
let g:os = has('win32') || has('win64') ? 'Windows'
\ : has('macunix') ? 'Darwin'
\ : substitute(system('uname'), '\n', '', '')
if g:os ==# 'Windows'
if executable('pwsh')
set shell=pwsh
elseif executable('powershell')
set shell=powershell
endif
endif
let mapleader = ','
let maplocalleader = '_'
filetype plugin indent on
syntax enable
set encoding=utf-8
set belloff=all
set mouse=a
set hidden
set history=1000
set updatetime=300
set shortmess+=filmnrxoOtTF
set backspace=indent,eol,start
set number
set cursorline
set cursorlineopt=number
set noshowmode
set showmatch
set incsearch
set hlsearch
set ignorecase
set smartcase
set wildmenu
set wildmode=list:longest,full
set scrolloff=5
set sidescrolloff=5
set splitright
set splitbelow
set display=lastline
set expandtab
set shiftwidth=4
set tabstop=4
set softtabstop=4
set autoindent
set nojoinspaces
set nospell
set list
set listchars=tab:•\ ,trail:•,extends:»,precedes:«
let &fillchars = 'eob: ,vert:│,stl: ,stlnc: '
set foldmethod=syntax
set foldlevelstart=99
set undofile
set undolevels=1000
set undoreload=10000
set viewoptions=folds
if has('termguicolors')
set termguicolors
endif
for s:dir in ['backup', 'swap', 'undo', 'view']
let s:path = g:vim_dir . '/' . s:dir
if !isdirectory(s:path)
silent! call mkdir(s:path, 'p')
endif
endfor
execute 'set backupdir=' . fnameescape(g:vim_dir . '/backup//')
execute 'set directory=' . fnameescape(g:vim_dir . '/swap//')
execute 'set undodir=' . fnameescape(g:vim_dir . '/undo//')
execute 'set viewdir=' . fnameescape(g:vim_dir . '/view//')
if has('clipboard')
if g:os ==# 'Darwin' || g:os ==# 'Windows'
set clipboard=unnamed
else
set clipboard=unnamedplus
endif
endif
augroup DotfilesCore
autocmd!
autocmd FileType javascript,typescript,lua setlocal tabstop=2 shiftwidth=2 softtabstop=2
autocmd FileType haskell,ruby,yaml setlocal tabstop=2 shiftwidth=2 softtabstop=2
autocmd FileType c,cpp,vim,java,python,lua setlocal colorcolumn=80
autocmd FileType help setlocal colorcolumn=
autocmd FileType * setlocal formatoptions-=o
autocmd BufNewFile,BufRead *.html.twig setfiletype html.twig
autocmd BufNewFile,BufRead *.ts setfiletype typescript
autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line('$') | execute 'normal! g`"' | endif
autocmd BufWinLeave ?* if &buftype ==# '' && !empty(expand('%:p')) | silent! mkview | endif
autocmd BufWinEnter ?* if &buftype ==# '' && !empty(expand('%:p')) | silent! loadview | endif
augroup END
nnoremap j gj
nnoremap k gk
nnoremap Y y$
xnoremap < <gv
xnoremap > >gv
nnoremap <silent> <leader>h :nohlsearch<CR>
nnoremap <leader>ws :%s/\s\+$//e<CR>
nnoremap <Leader>s :%s/\<<C-r><C-w>\>/<C-r><C-w>
nnoremap <silent> <space>q :bprevious<CR>
nnoremap <silent> <space>e :bnext<CR>
nnoremap <silent> <C-w>% :vsplit<CR>
nnoremap <silent> <C-w>" :split<CR>
nnoremap q: <nop>
nnoremap Q <nop>
command! WQ wq
command! Wq wq
command! W write
command! Q quit
" Plugin installation is explicit: run install.sh or :PlugInstall/:PlugUpdate.
let s:plug_vim = g:vim_dir . '/autoload/plug.vim'
if filereadable(s:plug_vim)
execute 'source ' . fnameescape(s:plug_vim)
call plug#begin(g:vim_dir . '/plugged')
Plug 'vim-fuzzbox/fuzzbox.vim'
Plug 'preservim/nerdtree', { 'on': ['NERDTreeToggle', 'NERDTreeFind'] }
Plug 'ryanoasis/vim-devicons'
Plug 'tpope/vim-repeat'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-commentary'
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'
Plug 'mhinz/vim-startify'
Plug 'Donaldttt/vim-bufferline'
Plug 'Donaldttt/vim-global-statusline', { 'branch': 'vim9' }
Plug 'christoomey/vim-tmux-navigator'
Plug 'sainnhe/everforest'
Plug 'bluz71/vim-moonfly-colors', { 'as': 'moonfly' }
Plug 'NLKNguyen/papercolor-theme'
call plug#end()
else
echohl WarningMsg
echom 'vim-plug is not installed; run install.sh to install plugins.'
echohl None
endif
" Fuzzbox replaces the former Fuzzyy plugin and keeps its familiar mappings.
let g:fuzzbox_dropdown = 1
let g:fuzzbox_window_defaults = {'maxwidth': 0.8, 'maxheight': 0.8}
let g:fuzzbox_window_options = {
\ 'files': {'width': 0.8},
\ 'buffers': {'preview': 1, 'width': 0.8, 'preview_ratio': 0.5},
\ 'grep': {'preview': 1, 'width': 0.8, 'preview_ratio': 0.5},
\ 'mru': {'preview': 1}}
nnoremap <silent> <leader>fl :FuzzyCmdHistory<CR>
" NERDTree remains intentionally small; Fuzzbox handles most navigation.
let g:NERDShutUp = 1
let g:NERDTreeMinimalMenu = 1
let g:NERDTreeMinimalUI = 1
let g:NERDTreeChDirMode = 0
let g:NERDTreeQuitOnOpen = 1
let g:NERDTreeMouseMode = 2
let g:NERDTreeShowHidden = 1
let g:NERDTreeMapOpenExpl = ''
let g:NERDTreeDirArrowCollapsible = ''
let g:NERDTreeDirArrowExpandable = ''
function! s:ToggleTree() abort
if exists('t:NERDTreeBufName') && bufwinnr(t:NERDTreeBufName) != -1
NERDTreeClose
elseif &filetype ==# 'startify' || empty(expand('%:p'))
NERDTreeToggle
else
NERDTreeFind
endif
endfunction
nnoremap <silent> <leader>e :call <SID>ToggleTree()<CR>
let g:gitgutter_map_keys = 0
nnoremap <silent> <leader>gt :GitGutterBufferToggle<CR>
let g:tmux_navigator_no_mappings = 1
nnoremap <silent> <C-h> :TmuxNavigateLeft<CR>
nnoremap <silent> <C-j> :TmuxNavigateDown<CR>
nnoremap <silent> <C-k> :TmuxNavigateUp<CR>
nnoremap <silent> <C-l> :TmuxNavigateRight<CR>
let g:bufferline_echo = 0
let g:bufferline_modified = '+'
let g:bufferline_active_buffer_left = '['
let g:bufferline_active_buffer_right = ']'
let g:startify_change_to_dir = 0
let g:startify_files_number = 8
let g:startify_bookmarks = [g:dotfiledir . '.vimrc']
let g:startify_lists = [
\ {'header': [' RECENT'], 'type': 'files'},
\ {'header': [' BOOKMARKS'], 'type': 'bookmarks'}]
function! s:StatuslineHighlights() abort
highlight default DotModeNormal cterm=reverse gui=reverse
highlight default link DotModeInsert DiffAdd
highlight default link DotModeVisual Visual
highlight default link DotModeCommand DiffChange
endfunction
function! s:StatuslineUpdate() abort
if !exists('g:StlSetPart') || !exists('g:StlRefresh')
return
endif
let l:modes = {
\ 'n': [' NORMAL ', 'DotModeNormal'],
\ 'i': [' INSERT ', 'DotModeInsert'],
\ 'v': [' VISUAL ', 'DotModeVisual'],
\ 'V': [' V-LINE ', 'DotModeVisual'],
\ nr2char(22): [' V-BLOCK ', 'DotModeVisual'],
\ 'c': [' COMMAND ', 'DotModeCommand']}
let l:current = get(l:modes, mode(), [' ' . &filetype . ' ', 'StatusLine'])
call g:StlSetPart(0, l:current[0], l:current[1], 'mode')
let l:name = empty(expand('%:t')) ? '[No Name]' : expand('%:t')
call g:StlSetPart(10, ' ' . l:name . (&modified ? ' [+]' : ''), '', 'filename')
try
call g:StlSetPart(30, ' ' . bufferline#get_echo_string(), '', 'buffers')
catch
endtry
call g:StlSetPart(max([0, &columns - 14]), printf(' %d:%d ', line('.'), virtcol('.')), '', 'position')
call g:StlRefresh()
endfunction
augroup DotfilesUi
autocmd!
autocmd VimEnter * call theme#Init() | call <SID>StatuslineHighlights() | call <SID>StatuslineUpdate()
autocmd ModeChanged,BufEnter,BufDelete,BufWritePost * call <SID>StatuslineUpdate()
autocmd CursorHold * call <SID>StatuslineUpdate()
autocmd ColorScheme * call <SID>StatuslineHighlights()
augroup END
nnoremap <silent> <leader>cbg :call theme#toggleBg()<CR>
nnoremap <silent> <leader>ctb :call theme#toggleTransparent()<CR>
if has('gui_running')
set guifont=Hack\ Nerd\ Font:h13
endif