let $VIMHOME = expand(':p:h') let s:is_windows = has('win32') " Prelude {{{ if has('vim_starting') " Sets the character encoding inside Vim. set encoding=utf-8 scriptencoding utf-8 " Use as many color as possible if !has('gui_running') \ && exists('&termguicolors') " https://medium.com/@dubistkomisch/how-to-actually-get-italics-and-true-colour-to-work-in-iterm-tmux-vim-9ebe55ebc2be if !has('nvim') let &t_8f = "\e[38;2;%lu;%lu;%lum" let &t_8b = "\e[48;2;%lu;%lu;%lum" endif set termguicolors " use truecolor in term if exists('&pumblend') set pumblend=20 endif endif " Disable annoying bells set noerrorbells set novisualbell t_vb= if exists('&belloff') set belloff=all endif " Do not wait more than 100 ms for keys set timeout set ttimeout set ttimeoutlen=100 " Disable unnecessary default plugins let g:loaded_gzip = 1 let g:loaded_tar = 1 let g:loaded_tarPlugin = 1 let g:loaded_zip = 1 let g:loaded_zipPlugin = 1 let g:loaded_rrhelper = 1 let g:loaded_2html_plugin = 1 let g:loaded_vimball = 1 let g:loaded_vimballPlugin = 1 let g:loaded_getscript = 1 let g:loaded_getscriptPlugin = 1 let g:loaded_logipat = 1 let g:loaded_matchparen = 1 " NOTE: " The Netrw is use to download a missing spellfile let g:loaded_netrw = 1 let g:loaded_netrwPlugin = 1 let g:loaded_netrwSettings = 1 let g:loaded_netrwFileHandlers = 1 endif " }}} " Environment {{{ if has('nvim') set undodir=~/.cache/nvim/undo set viewdir=~/.cache/nvim/view set spellfile=~/.cache/nvim/spell/spellfile.utf-8.add else set undodir=~/.cache/vim/undo endif " Make sure required directories exist call mkdir(&viewdir, 'p') call mkdir(&undodir, 'p') call mkdir(fnamemodify(&spellfile, ':p:h'), 'p') " Use PowerShell on Windows if s:is_windows " :help shell-powershell let &shell = executable('pwsh') ? 'pwsh' : 'powershell' let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;' let &shellredir = '-RedirectStandardOutput %s -NoNewWindow -Wait' let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' set shellquote= shellxquote= endif " }}} " Language {{{ " prefer English help set helplang=en,ja " set default language for spell check " cjk - ignore spell check on Asian characters (China, Japan, Korea) set nospell set spelllang=en_us,cjk set fileencodings=ucs-bom,utf-8,euc-jp,iso-2022-jp,cp932,utf-16,utf-16le,cp1250 if s:is_windows set fileformats=dos,unix,mac else set fileformats=unix,dos,mac endif set emoji " use double in unicode emoji characters set ambiwidth=single " use single in ambiguous characters if has('langmap') && exists('+langremap') " Prevent that the langmap option applies to characters that result from a " mapping. If set (default), this may break plugins (but it's backward " compatible). set nolangremap endif " }}} " Interface {{{ set mouse=nvr set foldcolumn=0 " do not show foldcolumn set signcolumn=yes " always shows signcolumn set noshowcmd " do not display incomplete commands on the last line set noshowmode " do not display mode on the last line set laststatus=2 " always shows statusline set showtabline=2 " always shows tabline set breakindent " every wrapped line will continue visually indented set report=0 " reports any changes set previewheight=40 " specify previewwindow height set splitright " vertically split right " Show a few lines of context around the cursor. Note that this makes the " text scroll if you mouse-click near the start or end of the window. set scrolloff=5 " https://ddrscott.github.io/blog/2016/sidescroll/ set sidescroll=1 " Show invisible characters set nolist set listchars=tab:>-,trail:-,extends:>,precedes:<,nbsp:%,eol:$ set fillchars=diff:/ " vertically split buffers for vimdiff if has('vim-8.0.1361') || has('nvim') set diffopt& \ diffopt+=vertical \ diffopt+=hiddenoff endif " Show bracket matches set showmatch " highlight a partner of cursor character (matchparen is not used) set matchtime=1 " highlight a partner ASAP set matchpairs& " reset matchparis " use rich completion system in command line set wildmenu set wildmode=list:longest,full set wildoptions=tagfile if has('nvim') silent! set laststatus=3 else silent! set laststatus=1 endif silent! set cmdheight=0 " }}} " Behavior {{{ set autoread " automatically read set hidden " hide the buffer instead of close set switchbuf=useopen " use an existing buffer instaed of creating a new one set nostartofline " let C-D, C-U,... to keep same column set tagcase=match " use case sensitive for tag set smartcase " override the ignorecase if the search pattern contains " upper case characters " Do NOT store current directory and options/mappings in view set viewoptions& \ viewoptions-=curdir \ viewoptions-=options " Show the effects of a command incrementally if exists('&inccommand') set inccommand=nosplit endif set grepformat=%f:%l:%c:%m,%f:%l:%m,%f:%l%m,%f\ %l%m if executable('rg') set grepprg=rg\ --vimgrep endif " }}} " Editing {{{ set noswapfile set smarttab " insert blanks according to shiftwidth set expandtab " use spaces instead of TAB set softtabstop=-1 " the number of spaces that a TAB counts for set shiftwidth=2 " the number of spaces of an indent set shiftround " round indent to multiple of shiftwidth with > and < set textwidth=0 " do not automatically wrap text set autoindent " copy indent from current line when starting a new line set copyindent " copy the structure of the existing lines indent when " autoindenting a new line set preserveindent " Use :retab to clean up whitespace set undofile " keep undo history on undofile set virtualedit=all " allow virtual editing in all modes set number " Do not recognize octal numbers for Ctrl-A and Ctrl-X, most users find it " confusing. set nrformats-=octal " t - auto-wrap text using textwidth " c - auto-wrap comments using textwidth, inserting the " current comment leader automatically " r - automatically insert the current comment leader after " hitting in Insert mode " o - automatically insert the current comment leader after " hitting o in Insert mode " n - when formatting text, recognize numbered lists " l - long lines are not broken in insert mode " m - also break at a multi-byte character above 255. " B - when joining lines, don't insert a space between two " multi-byte characters " j - where it make sense, remove a comment leader when " joining lines set formatoptions& \ formatoptions+=r \ formatoptions+=o \ formatoptions+=n \ formatoptions+=m \ formatoptions+=B \ formatoptions+=j " use clipboard register " - unnamed : 'selection' in X11; clipboard in Mac OS X and Windows " - unnamedplus : 'clipboard' in X11, Mac OS X, and Windows (but yank) if has('win32') || has('win64') || has('mac') set clipboard=unnamed else set clipboard=unnamed,unnamedplus endif " completion settings set complete& \ complete+=k \ complete+=s \ complete+=i \ complete+=d \ complete+=t set completeopt& \ completeopt+=preview \ completeopt+=menu \ completeopt+=longest set showfulltag " show both the tag name and the search pattern set pumheight=20 " strict the item counts of completion " K to search the help with the cursor word set keywordprg& " Allow backspacing over everything in insert mode. set backspace=indent,eol,start " Do NOT restart search on bottom set nowrapscan " }}} " Functions {{{ function! SafePumVisible() abort try return coc#pum#visible() catch return pumvisible() endtry endfunction function! s:revise_colorscheme() abort if system('defaults read -g AppleInterfaceStyle') ==# "Dark\n" silent! colorscheme nordfox else silent! colorscheme dawnfox endif endfunction command! ReviseColorscheme call s:revise_colorscheme() " }}} " Quickfix {{{ " function! s:quickfixtextfunc_fname(bufnr) abort " let l:fname = bufname(a:bufnr) " if l:fname ==# '' " return '[No name]' " endif " return fnamemodify(l:fname, ':~:.') " endfunction " " function! s:quickfixtextfunc(info) abort " let l:items = a:info.quickfix " \ ? getqflist({ 'id': a:info.id, 'items': v:true }).items " \ : getloclist(a:info.winid, { 'id': a:info.id, 'items': v:true }).items " let l:items = map(l:items, { _, v -> { " \ 'text': v.text, " \ 'valid': v.valid, " \ 'bufnr': v.bufnr, " \ 'fname': v.bufnr ? s:quickfixtextfunc_fname(v.bufnr) : '', " \ 'type': v.type ==# '' ? '' : (' ' .. toupper(v.type)), " \ 'lnum': v.lnum > 99999 ? -1 : v.lnum, " \ 'col': v.col > 999 ? -1 : v.col, " \}}) " let l:n = max(map(copy(l:items), { -> len(v:val.fname) })) " let l:lines = map(l:items, { _, v -> !v.valid ? v.text : printf( " \ printf('%%-%dS |%%5d:%%-3d|%%s %%s', l:n), " \ v.fname, " \ v.lnum, " \ v.col, " \ v.type, " \ v.text, " \)}) " return l:lines " endfunction " set quickfixtextfunc=funcref('s:quickfixtextfunc') " Automatically open quickfix/locationlist augroup my_quickfix autocmd! autocmd QuickFixCmdPost [^l]* nested cwindow autocmd QuickFixCmdPost l* nested lwindow augroup END " }}} " Macros {{{ augroup MyAutoCmd autocmd! augroup END " Open raw content URL for GitHub " https://github.com/lambdalisue/lambdalisue/blob/main/README.md " https://raw.githubusercontent.com/lambdalisue/lambdalisue/main/README.md function! s:edit_github() abort let l:amatch = expand('') let l:m = matchlist( \ l:amatch, \ 'https://github\.com/\([^/]*\)/\([^/]*\)/blob/\(.*\)', \) if empty(l:m) return endif let l:url = printf( \ 'https://raw.githubusercontent.com/%s/%s/%s', \ l:m[1], \ l:m[2], \ l:m[3], \) execute printf( \ 'keepalt keepjumps edit %s', \ fnameescape(l:url), \) execute printf('silent! bwipeout! %s', fnameescape(l:amatch)) endfunction autocmd MyAutoCmd BufReadCmd https://github.com/* ++nested call s:edit_github() " Automatically re-assign filetype {{{ autocmd MyAutoCmd BufWritePost * \ if &filetype ==# '' && exists('b:ftdetect') | \ unlet! b:ftdetect | \ filetype detect | \ endif "}}} " Automatically keep cursor position {{{ augroup restore-cursor autocmd! autocmd BufReadPost * \ : if line("'\"") >= 1 && line("'\"") <= line("$") \ | exe "normal! g`\"zv" \ | endif autocmd BufWinEnter * \ : if empty(&buftype) && line('.') > winheight(0) / 2 \ | execute 'normal! zz' \ | endif augroup END " }}} " Automatically create missing directories {{{ function! s:auto_mkdir(dir, force) abort if empty(a:dir) || a:dir =~# '^\w\+://' || isdirectory(a:dir) || a:dir =~# '^suda:' return endif if !a:force echohl Question call inputsave() try let result = input( \ printf('"%s" does not exist. Create? [y/N]', a:dir), \ '', \) if empty(result) echohl WarningMsg echo 'Canceled' return endif finally call inputrestore() echohl None endtry endif call mkdir(a:dir, 'p') endfunction autocmd MyAutoCmd BufWritePre * \ call s:auto_mkdir(expand(':p:h'), v:cmdbang) " }}} " }}} " Mapping {{{ " define and let g:mapleader = "\" let g:maplocalleader = '\' " Disable dengerous/annoying mappings " ZZ - save and close Vim " ZQ - close Vim nnoremap ZZ nnoremap ZQ " Disable middle mouse button noremap noremap <2-MiddleMouse> noremap <3-MiddleMouse> noremap <4-MiddleMouse> " Emacs like movement in Insert/Command noremap! noremap! noremap! noremap! noremap! " Swap ; and : in normal/visual mode nnoremap ; : xnoremap ; : nnoremap : ; xnoremap : ; " Prefer gF nnoremap gf gFzv nnoremap gF gfzv nnoremap f Fzv nnoremap Fzv nnoremap F fzv " Do NOT yank with x/s nnoremap x "_x nnoremap s "_s " Do NOT rewrite register after paste " http://baqamore.hatenablog.com/entry/2016/07/07/201856 xnoremap p printf('pgv"%sygv', v:register) " https://blog.atusy.net/2024/05/29/vim-hl-enhanced/ nnoremap H H(H) nnoremap L L(L) nnoremap (H)H H(H) nnoremap (L)L Lzb(L) " Use Ctrl-f/b in Normal as well noremap noremap " Better / in Command cnoremap cnoremap cnoremap cnoremap " Fix unreasonable mappings by historical reason nnoremap Y y$ " Tab navigation nnoremap t :tabnew nnoremap :tabnew nnoremap q :tabclose nnoremap :tabclose nnoremap gt nnoremap gT " Open terminal nnoremap tt :tabnew:terminal " CTRL-U in insert mode deletes a lot. Use CTRL-G u to first break undo, " so that you can undo CTRL-U after inserting a line break. " Revert with ":iunmap ". inoremap u " CTRL-L to fix syntax highlight nnoremap empty(get(b:, 'current_syntax')) \ ? "\" \ : "\:syntax sync fromstart\" " }}} " Highlight {{{ function! s:special_highlight() abort syntax match SpecialChar '~' contained endfunction autocmd MyAutoCmd ColorScheme * call s:special_highlight() " }}} set runtimepath^=~/wk/postchan " Postludium {{{ " Plugin source $VIMHOME/jetpack.vim syntax on filetype indent plugin on " Load conf.d/*.vim function! s:load_configurations() abort for path in glob('$VIMHOME/conf.d/*.vim', 1, 1, 1) execute printf('source %s', fnameescape(path)) endfor endfunction call s:load_configurations() set background=dark if has('nvim') silent! colorscheme nordfox else silent! colorscheme iceberg endif if filereadable(expand("~/.vimrc.local")) source ~/.vimrc.local endif set secure " }}} "----------------------------------------------------------------------------- " vim: expandtab softtabstop=2 shiftwidth=2 foldmethod=marker