mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
489 lines
14 KiB
VimL
489 lines
14 KiB
VimL
" ==========================================================
|
|
" Vim configuration - Sysdev Portable
|
|
" Optimized for Linux kernel development
|
|
" ==========================================================
|
|
|
|
set nocompatible
|
|
set encoding=utf-8
|
|
scriptencoding utf-8
|
|
|
|
" --- leader MUST be set before any mapping
|
|
let mapleader=" "
|
|
let maplocalleader="\\"
|
|
|
|
" ----------------------------------------------------------
|
|
" UI
|
|
" ----------------------------------------------------------
|
|
|
|
set number
|
|
set relativenumber
|
|
set ruler
|
|
set showcmd
|
|
set nowrap
|
|
set splitbelow
|
|
set splitright
|
|
set signcolumn=yes
|
|
set laststatus=2
|
|
set scrolloff=4
|
|
set sidescrolloff=8
|
|
|
|
set wildmenu
|
|
set wildmode=longest:full,full
|
|
|
|
set mouse=
|
|
set ttyfast
|
|
set lazyredraw
|
|
|
|
" ----------------------------------------------------------
|
|
" Editing
|
|
" ----------------------------------------------------------
|
|
|
|
set hidden
|
|
set backspace=indent,eol,start
|
|
|
|
set tabstop=8
|
|
set shiftwidth=8
|
|
set softtabstop=8
|
|
set noexpandtab
|
|
|
|
set autoindent
|
|
" NOTE: cindent supersedes smartindent — smartindent removed (obsolete + redundant)
|
|
set cindent
|
|
set cinoptions=:0,l1,g0,t0,(0,Ws,m1
|
|
|
|
set textwidth=80
|
|
set colorcolumn=81
|
|
|
|
" j: remove comment leader when joining lines (Vim >= 7.4)
|
|
set formatoptions+=croqnj
|
|
set formatoptions-=t
|
|
|
|
" C syntax tweaks (kernel-friendly)
|
|
let c_comment_strings=1
|
|
let c_no_curly_error=1
|
|
|
|
" ----------------------------------------------------------
|
|
" Whitespace (OFF by default, toggle with <leader>l)
|
|
" ----------------------------------------------------------
|
|
|
|
set nolist
|
|
set listchars=tab:>-,trail:·,extends:»,precedes:«,nbsp:␣
|
|
|
|
nnoremap <silent> <leader>l :set list!<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Search
|
|
" ----------------------------------------------------------
|
|
|
|
set incsearch
|
|
set hlsearch
|
|
set ignorecase
|
|
set smartcase
|
|
" NOTE: gdefault removed — it breaks muscle memory and is
|
|
" confusing when reading others' vimrc. Use /g explicitly.
|
|
|
|
nnoremap <silent> <leader>h :set hlsearch!<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Performance
|
|
" ----------------------------------------------------------
|
|
|
|
set updatetime=250
|
|
set timeoutlen=400
|
|
set ttimeoutlen=10
|
|
set shortmess+=c
|
|
|
|
" ----------------------------------------------------------
|
|
" Undo (XDG-aware, robust)
|
|
" ----------------------------------------------------------
|
|
|
|
set undofile
|
|
set undolevels=1000
|
|
|
|
if has("unix")
|
|
if exists("$XDG_CACHE_HOME") && !empty($XDG_CACHE_HOME)
|
|
let s:cache=$XDG_CACHE_HOME
|
|
else
|
|
let s:cache=expand("~/.cache")
|
|
endif
|
|
|
|
let s:undodir=s:cache . "/vim/undo//"
|
|
if !isdirectory(s:undodir)
|
|
silent! call mkdir(s:undodir, "p")
|
|
endif
|
|
execute "set undodir=" . fnameescape(s:undodir)
|
|
endif
|
|
|
|
" ----------------------------------------------------------
|
|
" Swap files (centralized — no .swp in source trees)
|
|
" ----------------------------------------------------------
|
|
|
|
if has("unix")
|
|
if exists("$XDG_CACHE_HOME") && !empty($XDG_CACHE_HOME)
|
|
let s:cache2=$XDG_CACHE_HOME
|
|
else
|
|
let s:cache2=expand("~/.cache")
|
|
endif
|
|
|
|
let s:swpdir=s:cache2 . "/vim/swap//"
|
|
if !isdirectory(s:swpdir)
|
|
silent! call mkdir(s:swpdir, "p")
|
|
endif
|
|
execute "set directory=" . fnameescape(s:swpdir)
|
|
set nobackup
|
|
set nowritebackup
|
|
endif
|
|
|
|
" ----------------------------------------------------------
|
|
" Grep integration
|
|
" ----------------------------------------------------------
|
|
|
|
if executable("rg")
|
|
set grepprg=rg\ --vimgrep\ --no-heading\ --smart-case
|
|
set grepformat=%f:%l:%c:%m
|
|
elseif executable("grep")
|
|
set grepprg=grep\ -nH\ $*
|
|
set grepformat=%f:%l:%m
|
|
endif
|
|
|
|
nnoremap <silent> <leader>g :silent grep! <C-R><C-W> .<CR>:copen<CR>
|
|
nnoremap <leader>/ :silent grep!<Space>
|
|
|
|
" ----------------------------------------------------------
|
|
" Quickfix / location list
|
|
" ----------------------------------------------------------
|
|
|
|
nnoremap <silent> ]q :cnext<CR>
|
|
nnoremap <silent> [q :cprev<CR>
|
|
nnoremap <silent> <leader>qo :copen<CR>
|
|
nnoremap <silent> <leader>qc :cclose<CR>
|
|
|
|
nnoremap <silent> ]l :lnext<CR>
|
|
nnoremap <silent> [l :lprev<CR>
|
|
nnoremap <silent> <leader>lo :lopen<CR>
|
|
nnoremap <silent> <leader>lc :lclose<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Window navigation
|
|
" ----------------------------------------------------------
|
|
|
|
nnoremap <C-h> <C-w>h
|
|
nnoremap <C-j> <C-w>j
|
|
nnoremap <C-k> <C-w>k
|
|
nnoremap <C-l> <C-w>l
|
|
|
|
" ----------------------------------------------------------
|
|
" Basic shortcuts
|
|
" ----------------------------------------------------------
|
|
|
|
nnoremap <silent> <leader>w :w<CR>
|
|
nnoremap <silent> <leader>q :q<CR>
|
|
nnoremap <silent> <leader>x :x<CR>
|
|
|
|
" Fold toggle
|
|
nnoremap <silent> <leader>z za
|
|
|
|
" Diff helpers
|
|
set diffopt=filler,internal,algorithm:histogram,indent-heuristic
|
|
nnoremap <silent> <leader>df :windo diffthis<CR>
|
|
nnoremap <silent> <leader>do :windo diffoff<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Folding
|
|
" ----------------------------------------------------------
|
|
|
|
set foldmethod=syntax
|
|
set foldlevelstart=99 " start with all folds open
|
|
set foldnestmax=3
|
|
|
|
" ----------------------------------------------------------
|
|
" Tags (ctags)
|
|
" ----------------------------------------------------------
|
|
|
|
set tags=./tags;,tags;
|
|
|
|
if filereadable(expand('~/.tags'))
|
|
set tags+=~/.tags
|
|
endif
|
|
|
|
nnoremap <silent> <leader>t :tag <C-R><C-W><CR>
|
|
nnoremap <silent> <leader>pt :ptag <C-R><C-W><CR>
|
|
nnoremap <silent> <leader>po :popen<CR>
|
|
nnoremap <silent> <leader>pc :pclose<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" cscope (essential for kernel navigation)
|
|
" ----------------------------------------------------------
|
|
|
|
if has("cscope")
|
|
set cscopetag " use cscope for :tag and <C-]>
|
|
set cscoperelative " use cscope.out location as prefix
|
|
set cscopeverbose
|
|
|
|
" Auto-load cscope.out walking up the directory tree
|
|
function! s:LoadCscope() abort
|
|
let l:db=findfile("cscope.out", ".;")
|
|
if !empty(l:db)
|
|
let l:path=strpart(l:db, 0, match(l:db, "/cscope.out$"))
|
|
if empty(l:path) | let l:path="." | endif
|
|
silent! execute "cs add " . l:db . " " . l:path
|
|
endif
|
|
endfunction
|
|
autocmd BufEnter /* call s:LoadCscope()
|
|
|
|
" cscope query mappings
|
|
" s: symbol g: definition d: called-by c: callers
|
|
" t: text e: egrep f: file i: #includes
|
|
nnoremap <silent> <leader>cs :cs find s <C-R>=expand("<cword>")<CR><CR>
|
|
nnoremap <silent> <leader>cg :cs find g <C-R>=expand("<cword>")<CR><CR>
|
|
nnoremap <silent> <leader>cd :cs find d <C-R>=expand("<cword>")<CR><CR>
|
|
nnoremap <silent> <leader>cc :cs find c <C-R>=expand("<cword>")<CR><CR>
|
|
nnoremap <silent> <leader>ct :cs find t <C-R>=expand("<cword>")<CR><CR>
|
|
nnoremap <silent> <leader>ce :cs find e <C-R>=expand("<cword>")<CR><CR>
|
|
nnoremap <silent> <leader>cf :cs find f <C-R>=expand("<cfile>")<CR><CR>
|
|
nnoremap <silent> <leader>ci :cs find i <C-R>=expand("<cfile>")<CR><CR>
|
|
endif
|
|
|
|
" ----------------------------------------------------------
|
|
" Man page (K over word)
|
|
" ----------------------------------------------------------
|
|
|
|
function! s:Man() abort
|
|
let l:word=expand("<cword>")
|
|
if exists(":Man")
|
|
execute "Man " . l:word
|
|
else
|
|
execute "!man " . l:word
|
|
endif
|
|
endfunction
|
|
|
|
nnoremap <silent> K :call <SID>Man()<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" ClangFormat
|
|
" ----------------------------------------------------------
|
|
|
|
function! s:ClangFormatRange(line1, line2) abort
|
|
if !executable("clang-format")
|
|
echohl WarningMsg | echo "clang-format not found in PATH" | echohl None
|
|
return
|
|
endif
|
|
let l:view=winsaveview()
|
|
silent execute a:line1 . "," . a:line2 . "!clang-format"
|
|
call winrestview(l:view)
|
|
endfunction
|
|
|
|
command! -range=% ClangFormat call <SID>ClangFormatRange(<line1>, <line2>)
|
|
|
|
nnoremap <silent> <leader>cf :ClangFormat<CR>
|
|
xnoremap <silent> <leader>cf :ClangFormat<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Project root detection
|
|
" ----------------------------------------------------------
|
|
|
|
function! s:GitRoot() abort
|
|
if executable("git")
|
|
let l:r=systemlist("git rev-parse --show-toplevel 2>/dev/null")
|
|
if v:shell_error==0 && len(l:r)>0
|
|
return l:r[0]
|
|
endif
|
|
endif
|
|
return ""
|
|
endfunction
|
|
|
|
function! s:FindProjectRoot() abort
|
|
let l:root=s:GitRoot()
|
|
return !empty(l:root) ? l:root : getcwd()
|
|
endfunction
|
|
|
|
" ----------------------------------------------------------
|
|
" Smart build (ninja > cmake > make)
|
|
" ----------------------------------------------------------
|
|
|
|
function! s:SmartMake() abort
|
|
let l:root=s:FindProjectRoot()
|
|
if filereadable(l:root . "/build.ninja")
|
|
let &makeprg="ninja -C " . fnameescape(l:root)
|
|
elseif filereadable(l:root . "/CMakeLists.txt")
|
|
let &makeprg="cmake --build build"
|
|
elseif filereadable(l:root . "/Makefile")
|
|
let &makeprg="make -C " . fnameescape(l:root)
|
|
else
|
|
let &makeprg="make"
|
|
endif
|
|
silent make!
|
|
copen
|
|
endfunction
|
|
|
|
command! Make call <SID>SmartMake()
|
|
|
|
nnoremap <silent> <leader>m :Make<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Run single file (errors in quickfix, output in terminal)
|
|
" ----------------------------------------------------------
|
|
|
|
function! s:Run() abort
|
|
write
|
|
if &filetype=="c"
|
|
let l:src=expand("%")
|
|
let l:exe=expand("%:r")
|
|
let l:saved=&makeprg
|
|
execute "set makeprg=cc\\ -std=c11\\ -Wall\\ -Wextra\\ -g\\ "
|
|
\ . fnameescape(l:src) . "\\ -o\\ " . fnameescape(l:exe)
|
|
silent make!
|
|
let &makeprg=l:saved
|
|
" Run only if no errors
|
|
if empty(filter(getqflist(), 'v:val.valid'))
|
|
execute "!" . fnameescape(l:exe)
|
|
else
|
|
copen
|
|
endif
|
|
elseif &filetype=="python"
|
|
execute "!python3 " . fnameescape(expand("%"))
|
|
elseif &filetype=="sh"
|
|
execute "!sh " . fnameescape(expand("%"))
|
|
else
|
|
echohl WarningMsg | echo "Run not supported for filetype: " . &filetype | echohl None
|
|
endif
|
|
endfunction
|
|
|
|
command! Run call <SID>Run()
|
|
|
|
nnoremap <silent> <leader>r :Run<CR>
|
|
|
|
" ----------------------------------------------------------
|
|
" Filetypes + syntax
|
|
" ----------------------------------------------------------
|
|
|
|
filetype plugin indent on
|
|
syntax on
|
|
|
|
" ----------------------------------------------------------
|
|
" Autocommands
|
|
" ----------------------------------------------------------
|
|
|
|
augroup sysdev_ft
|
|
autocmd!
|
|
|
|
" Trim trailing whitespace on save
|
|
autocmd BufWritePre * silent! %s/\s\+$//e
|
|
|
|
" Restore last cursor position
|
|
autocmd BufReadPost *
|
|
\ if line("'\"")>0 && line("'\"")<=line("$") |
|
|
\ execute "normal! g`\"" |
|
|
\ endif
|
|
|
|
" C/C++: kernel style, no list (tabs are intentional)
|
|
autocmd FileType c,cpp
|
|
\ setlocal tabstop=8 shiftwidth=8 softtabstop=8 noexpandtab
|
|
\ textwidth=80 colorcolumn=81 cindent
|
|
\ cinoptions=:0,l1,g0,t0,(0,Ws,m1 nolist
|
|
|
|
" Makefiles: tabs are mandatory
|
|
autocmd FileType make setlocal noexpandtab tabstop=8 shiftwidth=8
|
|
|
|
" Assembly: kernel asm style
|
|
autocmd FileType asm,s
|
|
\ setlocal tabstop=8 shiftwidth=8 noexpandtab nolist
|
|
|
|
" Kconfig / Kbuild
|
|
autocmd BufRead,BufNewFile Kconfig*,Kbuild*
|
|
\ setlocal filetype=kconfig noexpandtab tabstop=8
|
|
|
|
" Patch/diff: never touch whitespace
|
|
autocmd FileType diff,patch setlocal nolist
|
|
|
|
" Python: PEP8 (scripts/tooling)
|
|
autocmd FileType python
|
|
\ setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab textwidth=79
|
|
|
|
" Highlight TODO/FIXME/HACK/BUG/XXX/NOTE in all files
|
|
autocmd Syntax *
|
|
\ call matchadd('Todo', '\v\c<(TODO|FIXME|HACK|BUG|XXX|NOTE|WARN|WARNING)>')
|
|
|
|
augroup END
|
|
|
|
" ----------------------------------------------------------
|
|
" Statusline (no plugins)
|
|
" ----------------------------------------------------------
|
|
|
|
set statusline=
|
|
set statusline+=%#PmenuSel#
|
|
set statusline+=\ %f\
|
|
set statusline+=%#LineNr#
|
|
set statusline+=\ %m%r%h%w\
|
|
set statusline+=%=
|
|
set statusline+=\ %{&filetype}\
|
|
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}\
|
|
set statusline+=\ %{&fileformat}\
|
|
set statusline+=\ %l:%c\
|
|
set statusline+=\ %p%%\
|
|
|
|
" ==========================================================
|
|
" Embedded colorscheme: sysdev_black
|
|
" Self-contained — no external files needed
|
|
" ==========================================================
|
|
|
|
if &t_Co>=256
|
|
|
|
highlight clear
|
|
if exists("syntax_on")
|
|
syntax reset
|
|
endif
|
|
|
|
let g:colors_name="sysdev_black"
|
|
set background=dark
|
|
|
|
" Base
|
|
hi Normal ctermfg=252 ctermbg=NONE
|
|
hi Comment ctermfg=244
|
|
hi Constant ctermfg=173
|
|
hi String ctermfg=150
|
|
hi Identifier ctermfg=81
|
|
hi Function ctermfg=110
|
|
hi Statement ctermfg=161
|
|
hi Type ctermfg=149
|
|
hi PreProc ctermfg=179
|
|
hi Special ctermfg=215
|
|
hi Operator ctermfg=252
|
|
|
|
" Selection / search
|
|
hi Visual ctermbg=238
|
|
hi Search ctermfg=16 ctermbg=220
|
|
hi IncSearch ctermfg=16 ctermbg=214
|
|
|
|
" Diff
|
|
hi DiffAdd ctermfg=150 ctermbg=22
|
|
hi DiffDelete ctermfg=203 ctermbg=52
|
|
hi DiffChange ctermfg=110 ctermbg=17
|
|
hi DiffText ctermfg=255 ctermbg=24 cterm=bold
|
|
|
|
" UI chrome
|
|
hi LineNr ctermfg=240
|
|
hi CursorLineNr ctermfg=220
|
|
hi CursorLine ctermbg=236 cterm=NONE
|
|
hi ColorColumn ctermbg=235
|
|
hi SignColumn ctermfg=240 ctermbg=NONE
|
|
hi VertSplit ctermfg=238 ctermbg=NONE
|
|
hi StatusLine ctermfg=252 ctermbg=238 cterm=NONE
|
|
hi StatusLineNC ctermfg=240 ctermbg=234 cterm=NONE
|
|
hi Folded ctermfg=244 ctermbg=234
|
|
hi MatchParen ctermfg=220 ctermbg=NONE cterm=bold,underline
|
|
|
|
" Completion menu
|
|
hi Pmenu ctermfg=252 ctermbg=236
|
|
hi PmenuSel ctermfg=16 ctermbg=220
|
|
hi PmenuSbar ctermbg=238
|
|
hi PmenuThumb ctermbg=244
|
|
|
|
" Errors / warnings / todos
|
|
hi Error ctermfg=255 ctermbg=160 cterm=bold
|
|
hi ErrorMsg ctermfg=255 ctermbg=160
|
|
hi WarningMsg ctermfg=214
|
|
hi Todo ctermfg=16 ctermbg=220 cterm=bold
|
|
|
|
endif
|