" vim: shiftwidth=2 vim9script noclear # Encoding if !v:vim_did_enter set encoding=utf-8 scriptencoding utf-8 $MYVIMRC = resolve(expand('')) endif # Local utility functions export def SIDPrefix(): string # Returns "{script-ID}_" return expand('') enddef def SNR(): string return matchstr(SIDPrefix(), '\zs\d\+\ze_$') enddef def Rc(fname: string): string return Filesystem.rcfile_prefix .. fname enddef export def JoinPath(...arg: list): string return join(arg, Filesystem.slash) enddef export def Has(object: any, to_search: any): bool var obj_type = type(object) if obj_type == v:t_string return HasInString(object, to_search) elseif obj_type == v:t_list return HasInList(object, to_search) elseif obj_type == v:t_dict return HasInDict(object, to_search) endif return false enddef export def HasInString(object: string, to_search: string): bool return stridx(object, to_search) != -1 enddef export def HasInList(object: list, to_search: any): bool return index(object, to_search) != -1 enddef export def HasInDict(object: dict, to_search: string): bool return has_key(object, to_search) enddef def GetMsgString(msg: string): string return '[vimrc] ' .. msg enddef def EchomsgWithColor(msg: string, hl_group: string): void execute 'echohl' hl_group echomsg GetMsgString(msg) echohl NONE enddef export def Echomsg(msg: string): void call EchomsgWithColor(msg, 'NONE') enddef export def EchomsgError(msg: string): void call EchomsgWithColor(msg, 'Error') enddef export def EchomsgWarning(msg: string): void call EchomsgWithColor(msg, 'WarningMsg') enddef export def Echo(msg: string): void echo GetMsgString(msg) enddef export def EchoQuestion(question: string): void echon GetMsgString(question) .. ' ' echohl Question echon '[Y/N]' echohl NONE echon "\n" enddef export def Glob(expr: string, nosuf: bool = false, alllinks: bool = false): list return glob(expr, nosuf, true, alllinks) enddef export def GetcharString(...expr: list): any return nr2char(call('getchar', expr)) enddef export def Ask(question: string): bool EchoQuestion(question) return GetcharString() =~? 'y' enddef export def Mkdir(dir: string, ...opt: list): bool if isdirectory(dir) return true endif if !exists('*mkdir') EchomsgError('built-in mkdir() not found.') return false endif return call('mkdir', [dir] + opt) ? true : false enddef export def Input(prompt: string, ...opt: list): string try return call('input', [prompt] + opt) catch /\C^Vim:Interrupt$/ return '' endtry return '' enddef # Global utility functions legacy def! VimrcFunc(funcname: string): func return function(SIDPrefix() .. funcname) enddef export def VimrcVar(varname: string): any return eval(varname) enddef export def SetUndoFtplugin(config: string) var restorer = 'execute ' .. string(config) if exists('b:undo_ftplugin') b:undo_ftplugin = restorer .. '|' .. b:undo_ftplugin else setbufvar('%', 'undo_ftplugin', restorer) endif enddef command! -nargs=1 -complete=command SetUndoFtplugin \ call SetUndoFtplugin() final IsWindows = has('win32') final IsLinux = has('linux') final IsMac = has('mac') final IsUnix = IsLinux || IsMac final IsWSL = IsLinux && system('uname -r') =~? 'microsoft' export var Filesystem: dict if IsWindows $DOT_VIM = expand('~\vimfiles') Filesystem = { slash: '\', path_separator: ';', rcfile_prefix: '_' } else $DOT_VIM = expand('~/.vim') Filesystem = { slash: '/', path_separator: ':', rcfile_prefix: '.' } endif # Startup config if !v:vim_did_enter if has('multi_lang') && has('menu') set langmenu=ja.utf-8 endif if &term =~# '\<256color\>' && expand('$TERM_PROGRAM') !=# 'Apple_Terminal' set termguicolors # Use true color if possible. endif if &term =~# '\' &t_EI = "\[2 q" # Use Block style cursor in Normal-mode. &t_SI = "\[6 q" # Use Bar style cursor in Insert-mode. &t_SR = "\[4 q" # Use underline style cursor in Replace-mode. set mouse=a endif if expand('$TERM_PROGRAM') ==# 'WezTerm' &t_Cs = "\e[4:3m" &t_Ce = "\e[4:0m" endif # disable default plugins g:loaded_2html_plugin = 1 g:loaded_getscriptPlugin = 1 g:loaded_gzip = 1 g:loaded_zipPlugin = 1 g:loaded_tarPlugin = 1 g:loaded_vimballPlugin = 1 g:loaded_netrwPlugin = 1 &runtimepath ..= ',' .. escape(JoinPath($DOT_VIM, 'runtime'), ' \') # Set environmental variables on gVim. { var envrc_ = JoinPath(expand('~'), Rc('envrc')) if has('gui_running') && filereadable(envrc_) var lines = readfile(envrc_) ->map((_, val): string => substitute(val, '\v%(\_^|\s)#.*$', '', 'g')) ->filter((_, val): bool => !empty(val)) for line in lines var name: string var value: string [name, value] = line->split('=') execute '$' .. name .. ' = ' .. value->expand()->string() endfor endif } endif # Initialize autocmd (filename: string) => { var pattern = '^\s*aug\%[roup]\s\+\zs\S\+\ze\s*' var augroups = readfile(filename) ->filter((_, line): bool => stridx(line, 'aug') != -1) ->filter((_, line): bool => line =~# pattern) ->map((_, line): string => matchstr(line, pattern)) ->filter((_, augroup): bool => augroup !=? 'END') ->sort() ->uniq() for augroup in augroups execute 'augroup ' .. augroup autocmd! execute 'augroup END' endfor }(expand('')) # minpac var PluginList: list var OptPluginList: list if &loadplugins PluginList = Glob(JoinPath($DOT_VIM, 'pack', 'minpac', 'start', '*')) ->filter((_, val): bool => isdirectory(val)) ->map((_, val): string => fnamemodify(val, ':p:h:t')) OptPluginList = Glob(JoinPath($DOT_VIM, 'pack', 'minpac', 'opt', '*')) ->filter((_, val): bool => isdirectory(val)) ->map((_, val): string => fnamemodify(val, ':p:h:t')) def PluginExists(plugin: string): bool return HasInList(PluginList, plugin) enddef def OptPluginExists(plugin: string): bool return HasInList(OptPluginList, plugin) enddef else def PluginExists(plugin: string): bool return false enddef def OptPluginExists(plugin: string): bool return false enddef endif def PackRegister() minpac#add('k-takata/minpac', {type: 'opt'}) minpac#add('itchyny/vim-cursorword') minpac#add('kamichidu/vim-textobj-function-go') minpac#add('kana/vim-altr') minpac#add('kana/vim-operator-user') minpac#add('kana/vim-textobj-user') minpac#add('lambdalisue/gina.vim') minpac#add('lambdalisue/vim-findent') minpac#add('lambdalisue/vim-gista') minpac#add('mityu/vim-brownie') minpac#add('mityu/vim-gram') minpac#add('mityu/vim-gram-sources') minpac#add('mityu/vim-vim9context') minpac#add('mityu/vim-wispath') minpac#add('osyo-manga/vim-jplus') minpac#add('previm/previm') minpac#add('skanehira/gh.vim') minpac#add('thinca/vim-ambicmd') minpac#add('thinca/vim-ft-help_fold') minpac#add('thinca/vim-partedit') minpac#add('thinca/vim-prettyprint') minpac#add('thinca/vim-qfreplace') minpac#add('thinca/vim-quickrun') minpac#add('thinca/vim-themis') minpac#add('tyru/capture.vim') # minpac#add('tyru/eskk.vim') minpac#add('tyru/open-browser.vim') minpac#add('vim-jp/autofmt') minpac#add('vim-jp/vimdoc-ja') minpac#add('vim-jp/vital.vim') minpac#add('vim-scripts/autodate.vim') minpac#add('lambdalisue/suda.vim', {type: 'opt'}) minpac#add('mattn/vim-lsp-settings', {type: 'opt'}) minpac#add('prabirshrestha/asyncomplete-lsp.vim', {type: 'opt'}) minpac#add('prabirshrestha/asyncomplete.vim', {type: 'opt'}) minpac#add('prabirshrestha/vim-lsp', {type: 'opt'}) minpac#add('tweekmonster/helpful.vim', {type: 'opt'}) minpac#add('y0za/vim-reading-vimrc', {type: 'opt'}) # Operator-user plugins minpac#add('osyo-manga/vim-operator-swap', {type: 'opt'}) minpac#add('kana/vim-operator-replace', {type: 'opt'}) minpac#add('rhysd/vim-operator-surround', {type: 'opt'}) # minpac#add('tyru/caw.vim', {type: 'opt'}) minpac#add('mityu/caw.vim', {type: 'opt', branch: 'support-vim9script-tmp'}) # tmp minpac#add('sgur/vim-operator-openbrowser', {type: 'opt'}) # Textobj-user plugins minpac#add('kana/vim-textobj-entire', {type: 'opt'}) minpac#add('kana/vim-textobj-function', {type: 'opt'}) minpac#add('kana/vim-textobj-indent', {type: 'opt'}) minpac#add('kana/vim-textobj-line', {type: 'opt'}) minpac#add('mityu/vim-textobj-commentblock', {type: 'opt'}) minpac#add('thinca/vim-textobj-between', {type: 'opt'}) enddef def PackInit(): bool silent! packadd minpac silent! minpac#init() if !exists('*minpac#init()') # Download minpac... var minpac_path = JoinPath($DOT_VIM, 'pack', 'minpac', 'opt', 'minpac') Echomsg('Downloading minpac...') system('git clone https://github.com/k-takata/minpac ' .. minpac_path) silent! packadd minpac silent! minpac#init() if !exists('*minpac#init()') return false endif endif PackRegister() return true enddef def PackUpdate() if PackInit() minpac#update() endif enddef def PackClean() if PackInit() minpac#clean() endif enddef def PackStatus() if exists('*minpac#status') minpac#status() else EchomsgError('minpac isn''t loaded yet.') endif enddef command! -bar PackInit call PackInit() command! -bar PackUpdate call PackUpdate() command! -bar PackClean call PackClean() command! -bar PackStatus call PackStatus() # Options {{{ if !v:vim_did_enter syntax on filetype plugin indent on endif if !exists('g:colors_name') # Don't override colorscheme colorscheme domusaurea endif language C set relativenumber number set wrap set smartindent autoindent set cinoptions=:0,g0,N-s,E-s set backspace=eol,start,indent set pumheight=10 set completeopt=menuone,noselect set noequalalways set scrolloff=1 set colorcolumn=78 set tabstop=4 set shiftwidth=4 set expandtab set smarttab set softtabstop=4 set hlsearch set display=lastline set listchars=tab:\|- set autoread set incsearch ignorecase set showmatch matchtime=1 set cursorline cursorlineopt=number set laststatus=2 set showtabline=2 set cmdheight=2 cmdwinheight=10 set wildmenu set wildignore& wildignore+=*.DS_STORE set history=500 set keywordprg=:help set shortmess& shortmess+=Ic set helplang=ja set hidden set diffopt=internal,algorithm:histogram #set breakindent #set virtualedit& virtualedit+=block set virtualedit=block set complete=.,i,d,w,b,u set noimdisable set lazyredraw set previewpopup=highlight:Normal set termwinkey= set noesckeys set nowrapscan set timeoutlen=3000 ttimeoutlen=100 # }}} export final CacheDir = JoinPath(expand('~'), '.cache', 'vimrc') Mkdir(CacheDir, 'p') { final undodir_ = JoinPath(CacheDir, 'undodir') if Mkdir(undodir_, 'p') set undofile &undodir = undodir_ else set noundofile endif final directory_ = JoinPath(CacheDir, 'swapfile') if Mkdir(directory_, 'p') set swapfile &directory = JoinPath(fnamemodify(directory_, ':p'), '') else set noswapfile endif set nobackup nowritebackup } if has('kaoriya') set fileencodings=guess,utf-8 set ambiwidth=auto else set fileencodings=utf-8,euc-jp,cp932,sjis set ambiwidth=double endif if IsUnix set path& path+=/usr/local/include endif if executable('rg') &grepprg = 'rg --vimgrep' &grepformat = '%f:%l:%c:%m' elseif executable('ag') &grepprg = 'ag --vimgrep' &grepformat = '%f:%l:%c:%m' endif augroup vimrc_filetype autocmd FileType c,cpp setlocal foldmethod=indent autocmd BufRead .envrc set filetype=sh autocmd FileType makefile setlocal noexpandtab nosmarttab augroup END augroup vimrc_mru autocmd BufRead,BufWritePost * call vimrc#mru#onReadFile() augroup END augroup vimrc_checktime autocmd CursorHold * if getcmdwintype() ==# '' | checktime | endif augroup END if executable('chmod') # This hack is from github.com/thinca/config/dotfiles/dot.vim/vimrc. Thanks! augroup vimrc_autoexecutable autocmd BufWritePost * AddPermissionX() augroup END def AddPermissionX() var file = expand('%:p') if stridx(getline(1), '#!') == 0 && !executable(file) silent! call system('chmod a+x ' .. shellescape(file)) endif enddef endif augroup vimrc_quickfix_window autocmd QuickfixCmdPost [^l]* cwindow autocmd QuickfixCmdPost l* lwindow augroup END # Mapping {{{ nnoremap : q:A vnoremap : q:A nnoremap : q:k vnoremap : q:k nnoremap / q/A vnoremap / q/A nnoremap / q/k vnoremap / q/k nnoremap ? q?A vnoremap ? q?A nnoremap ? q?k vnoremap ? q?k nnoremap ; : vnoremap ; : noremap - noremap + noremap ( [( noremap ) ]) noremap j gj noremap k gk noremap gj j noremap gk k nnoremap o nnoremap Y y$ nnoremap nohlsearch nnoremap s belowright wincmd s nnoremap belowright wincmd s nnoremap v belowright wincmd v nnoremap belowright wincmd v nnoremap c belowright copen nnoremap t tabnew nnoremap tabnew nnoremap th vertical terminal ++close nnoremap tj belowright terminal ++close nnoremap tk terminal ++close nnoremap tl belowright vertical terminal ++close nnoremap tt tab terminal ++close nnoremap w update nnoremap q q nnoremap ZZ nnoremap ZQ nnoremap Q nnoremap 7gk nnoremap 7gj # Avoid textobj-function calls appearing on command history nnoremap . . nnoremap * *N nnoremap m vnoremap m inoremap u inoremap u inoremap u inoremap inoremap inoremap inoremap =vimrc#pinsnip#expand() vnoremap g+ g vnoremap g- g vnoremap 7gk vnoremap 7gj vnoremap * *Ngvnenohlsearch vnoremap g* g*Ngvnenohlsearch vnoremap n nnohlsearch vnoremap N Nnohlsearch cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap nnoremap , call ToggleQuickfix() def ToggleQuickfix() var wincount = winnr('$') try cclose if wincount == winnr('$') cwindow if wincount == winnr('$') EchomsgError('No quickfix window') endif endif catch echo v:exception endtry enddef nnoremap . call ToggleLocationlist() def ToggleLocationlist() var wincount = winnr('$') try lclose if wincount == winnr('$') lwindow endif catch /^Vim(\S\{-})\:E776\:/ echohl ErrorMsg echomsg matchstr(v:exception, '^Vim(\S\{-})\:\zs.*$') echohl NONE catch echoerr v:exception endtry enddef # }}} def TerminalMap(mapcmd: string, lhs: string, rhs: string) execute printf('%s %s%s %s%s', mapcmd, &termwinkey, lhs, &termwinkey, rhs) enddef TerminalMap('tnoremap', ':', ':A') TerminalMap('tnoremap', ':', ':k') TerminalMap('tnoremap', '', 'N') TerminalMap('tnoremap', 'p', '""') TerminalMap('tnoremap', '', '"') TerminalMap('tnoremap', 't', 'tabnew') TerminalMap('tnoremap', 'n', 'botright new') # Loop def LoopDefine(config: dict) var prefix = printf('(-loop-%s)', config.id) var enter_with = config.enter_with var mode = get(config, 'mode', 'n') var plug_map: dict for key in ['prefix', 'main', 'do'] plug_map[key] = printf('%s(%s)', prefix, key) endfor execute printf('%snoremap %s ', mode, plug_map.prefix) for mapping in config.map var lhs: string var rhs: string var commands: list> [lhs, rhs] = mapping->map((_, val): string => substitute(val, '|', '', 'g')) commands->add([mode .. 'noremap', plug_map.do .. lhs, rhs]) ->add([mode .. 'map', enter_with .. lhs, plug_map.main .. lhs]) ->add([mode .. 'map', plug_map.main .. lhs, plug_map.do .. lhs .. plug_map.prefix]) ->add([mode .. 'map', plug_map.prefix .. lhs, plug_map.main .. lhs]) execute commands->mapnew('join(v:val)')->join("\n") endfor if mode ==# 'n' var t_config = deepcopy(config) t_config.mode = 't' if t_config.enter_with[: strlen(&termwinkey)] !=# &termwinkey && t_config.enter_with[0] !=# printf('"\%s"', &termwinkey)->eval() t_config.enter_with = &termwinkey .. config.enter_with endif t_config.map->map('LoopDefineGenerateTmap(v:val)') LoopDefine(t_config) endif enddef def LoopDefineGenerateTmap(value: list): list var rhs = value[1] ->substitute('\c', SIDPrefix(), 'g') ->substitute('\zs<\ze.\{-}>', '\\', 'g') rhs = 'execute "normal! ' .. rhs .. '"' return [value[0], rhs] enddef def SimpleLoopDefine(config: dict) var new_config = deepcopy(config) new_config.map = config.follow_key->split('\zs') ->mapnew((_, val): list => [val, config.enter_with .. val]) LoopDefine(new_config) enddef # Window management SimpleLoopDefine({ id: 'Window', enter_with: '', follow_key: 'hjklHJKLq<>-+_|=', }) LoopDefine({ id: 'Tab', enter_with: 'g', map: [ ['h', 'gT'], ['l', 'gt'], ['T', 'call MapTabmove(-1)'], ['t', 'call MapTabmove(1)'], ] }) def MapTabmove(delta: number) var tab_count = tabpagenr('$') if tab_count == 1 return endif var current = tabpagenr() - 1 var move_to = current + delta if move_to < 0 while move_to < 0 move_to += tab_count endwhile endif if move_to >= tab_count move_to = move_to % tab_count endif var movement = move_to - current var movecmd = 'tabmove ' if movement < 0 movecmd ..= string(movement) else movecmd ..= '+' .. string(movement) endif execute movecmd enddef # f F t T ; , declarations {{{ map f vimrc#charjump#jump(v:true, v:false) map F vimrc#charjump#jump(v:false, v:false) map t vimrc#charjump#jump(v:true, v:true) map T vimrc#charjump#jump(v:false, v:true) noremap ; call vimrc#charjump#repeat(v:false) noremap , call vimrc#charjump#repeat(v:true) # }}} def CmdwinEnter() # Type to execute current line in command-line window. # This mapping is overwritten when ambicmd.vim is installed. nnoremap # Return back to the current window from command-line window with # inputting once. nnoremap nmap q imap inoremap inoremap # Make executing a previous command easier. nnoremap / call CmdwinSelectHistory() vimrc#incsearch#setup() final cmdwin_type = expand('') if cmdwin_type ==# ':' inoremap CmdwinCompletion(0) inoremap CmdwinCompletion(1) b:completeopt_save = &completeopt setlocal completeopt=menu,preview execute printf(':silent! :1,$-%d delete _', &cmdwinheight) normal! G if exists('g:asyncomplete_loaded') && g:asyncomplete_loaded asyncomplete#disable_for_buffer() endif endif enddef def CmdwinLeave() if exists('b:completeopt_save') &completeopt = b:completeopt_save endif enddef def CmdwinCompletion(select_next: bool): string if pumvisible() return select_next ? "\" : "\" else return "\\" endif enddef def CmdwinSelectHistory() var history = split(execute('history ' .. getcmdwintype()), "\n")[1 :] map(history, (_, val) => matchstr(val, '^>\?\s*\d\+\s\+\zs.\+$')) reverse(history) gram#select({ name: getcmdwintype() .. 'history', items: history, callback: SIDPrefix() .. 'CmdwinSelectHistoryCallback', }) enddef def CmdwinSelectHistoryCallback(item: dict) if getline('$') ==# '' setline('$', item.word) else append('$', item.word) endif noautocmd normal! G$ enddef augroup vimrc_mapping autocmd CmdWinEnter * call CmdwinEnter() autocmd CmdWinLeave * call CmdwinLeave() augroup END if IsMac g:mapleader = '_' endif # Mapping for commands { var map_ = [] add(map_, ['nnoremap', 'ev', 'edit $MYVIMRC']) add(map_, ['nnoremap', 'sv', 'source $MYVIMRC']) add(map_, ['nnoremap', 'k', 'call vimrc#mru#start()']) add(map_, ['nnoremap', 'b', 'call gram#sources#buffers#launch()']) add(map_, ['nnoremap', 'j', 'call GofForMapping()']) add(map_, ['nnoremap', 'f', 'call vimrc#filore#start()']) execute map_->mapnew((_, val): string => [val[0], '' .. val[1], printf('%s', val[2])]->join())->join("\n") } # Abbreviates inoreabbrev todo: TODO: inoreabbrev fixme: FIXME: inoreabbrev xxx: XXX: inoreabbrev note: NOTE: # Commands # Declarations command! -bar CdCurrent cd %:p:h command! -bar LcdCurrent lcd %:p:h command! -bar TcdCurrent tcd %:p:h command! -nargs=1 -complete=file Rename file |call delete(expand('#')) command! -nargs=? CopyToClipboard call setreg('+', getreg(, 1)) command! -bar -nargs=? ClipBuffer call vimrc#clipbuffer() command! ClearMessage execute repeat("echom ''\n", 201) command! Helptags helptags ALL command! -bang -nargs=+ -complete=command Filter call Filter(0, ) command! -bar Draft call Draft() command! -bar -nargs=+ -complete=command Vimrc $MYVIMRC command! -bar -nargs=* -complete=file ListTasks call vimrc#list_tasks() command! DeleteUndoFiles call vimrc#delete_undofiles() command! -nargs=? -complete=dir Gof call Gof() command! -bar SwapBackslashAndBar call SwapBackslashAndBar() command! -bar -nargs=? -complete=dir GitInitRepo call vimrc#git_init_repo() command! -bar LocalPackUpdate call vimrc#update_local_packages() # Thanks to cohama command! EditAsUtf8 edit ++enc=utf-8 % command! EditAsCp932 edit ++enc=cp932 % command! EditAsUnix edit ++ff=unix % command! EditAsDos edit ++ff=dos % command! WriteAsUtf8 set fenc=utf-8|w # Plugin Shortcuts command! -bar -nargs=* MruEditHistoryStart call vimrc#mru#edit_history_start() command! -bar MruDeleteUnexistHistory call vimrc#mru#delete_unexist_file_history() command! -bar -nargs=? -complete=dir Filore call vimrc#filore#start() command! -bar -bang -nargs=? -complete=dir Ls call vimrc#shcmd#ls(0, ) command! -bar -bang -nargs=+ -complete=dir Mkdir call vimrc#shcmd#mkdir(0, ) command! -bar -nargs=+ -complete=dir Touch call vimrc#shcmd#touch() command! -bar -nargs=+ -complete=dir CpFile call vimrc#shcmd#cpfile() command! -bar -bang -nargs=+ -complete=file Rm call vimrc#shcmd#rm(0, ) def Filter(bang: bool, pat: string, ...cmd: list) var output = execute(join(cmd, ' ')) ->split("\n") ->filter((_: number, val: string): bool => val =~? pat) ->join("\n") if bang echomsg output else echo output endif enddef def Draft() setlocal buftype=nofile noswapfile enddef def FindGitroot(arg_target: string = bufname('%')): string var target: string = resolve(arg_target) var git_dir: string = finddir('.git', target .. ';') if git_dir ==# '' EchomsgWarning('Not a git repository: ' .. target) return '' endif return fnamemodify(git_dir, ':p:h:h') enddef def Gof(path: string) if !executable('gof') echo '"gof" command not found.' return endif var gofcmd = 'gof -f -tf "Tapi_gof"' if !empty(path) gofcmd ..= ' -d ' .. path endif var minwidth = min([&columns, 100]) var minheight = min([&lines, 40]) popup_create(term_start(gofcmd, {hidden: 1, term_finish: 'close'}), \ {minwidth: minwidth, minheight: minheight}) enddef def GofForMapping() var git_root = FindGitroot() Gof(git_root ==# '' ? getcwd(winnr()) : git_root) enddef legacy def! Tapi_gof(bufnum: number, file_info: dict) # Be global var winid = win_getid(winnr('#')) var buftype = getwinvar(winid, '&buftype') var open_cmd = 'edit' if !(buftype ==# 'nofile' || buftype ==# '') open_cmd = 'split' endif win_execute(winid, open_cmd .. ' ' .. fnameescape(file_info.fullpath)) enddef def SwapBackslashAndBar() if maparg('\', 'i') ==# "\" inoremap \ _ inoremap _ \ else iunmap \ iunmap _ endif enddef # Installed plugins if PluginExists('vim-cursorword') g:cursorword_highlight = 0 augroup vimrc_cursorword autocmd ColorScheme * highlight CursorWord0 gui=underline cterm=underline term=underline guibg=NONE ctermbg=NONE autocmd ColorScheme * highlight CursorWord1 gui=underline cterm=underline term=underline guibg=NONE ctermbg=NONE augroup END highlight CursorWord0 gui=underline cterm=underline term=underline guibg=NONE ctermbg=NONE highlight CursorWord1 gui=underline cterm=underline term=underline guibg=NONE ctermbg=NONE endif if PluginExists('vim-altr') command! -bar AlterForward call altr#forward() command! -bar AlterBack call altr#back() endif if PluginExists('gina.vim') g:gina#action#mark_sign_text = '*' g:gina#core#console#enable_message_history = 1 def GinaConfig() def Gina_nnoremap(scheme: string, lhs: string, rhs: string) gina#custom#mapping#nmap(scheme, lhs, rhs, {noremap: 1, silent: 1}) # Set mapping manually for the first time. # TODO: More smart solution if HasInString(&filetype, scheme) execute 'nnoremap ' lhs rhs endif enddef Gina_nnoremap('status', '', 'Gina commit') Gina_nnoremap('commit', '', 'Gina status') Gina_nnoremap('status', 'g', 'Gina commit') Gina_nnoremap('commit', 'g', 'Gina status') Gina_nnoremap('status', '', 'Gina status') Gina_nnoremap('log', '', 'Gina log') Gina_nnoremap('branch', 'N', 'call gina#action#call("branch:new")') Gina_nnoremap('/\v%(status|branch|log)', 'q', 'close') # Jump between unadded files with n/p .. var rhs_base = printf( 'call %sGinaStatusSelectAnother(v:count1, %%s)', SIDPrefix()) Gina_nnoremap('status', 'n', printf(rhs_base, 'v:false')) Gina_nnoremap('status', 'N', printf(rhs_base, 'v:true')) # NOTE: Using v:true and v:false as variables above doesn't work because # it seems to be changed into 'false' and 'true' (without v: namespace). Gina_nnoremap('status', 'dd', printf('call %sGinaDiff()', SIDPrefix())) gina#custom#action#alias('branch', 'merge', 'commit:merge:no-ff') gina#custom#action#alias('branch', 'merge-ff', 'commit:merge:ff') gina#custom#command#option('\v%(^<%(cd|lcd|qrep)>)@ q q cursor(1, 0) endif enddef augroup vimrc_gina autocmd Filetype gina-* ++once GinaConfig() augroup END nnoremap g Gina status endif if PluginExists('vim-findent') augroup vimrc_findent autocmd FileType * if &l:modifiable | execute 'Findent' | endif augroup END endif if PluginExists('vim-brownie') g:brownie_template_dirs = [JoinPath(expand('$DOT_VIM'), 'runtime', 'extension', 'brownie')] g:brownie_extra_imports = { cpp: ['c'], vimspec: ['vim'], } def BrownieFiletype(): string return getbufvar(brownie#get_current_bufnr(), '&filetype') enddef def VimrcTemplateComplete(arg: string, line: string, pos: number): list return filter(brownie#list(BrownieFiletype(), 'template'), (_, val) => stridx(val, arg) == 0) enddef command! -nargs=1 -complete=customlist,VimrcTemplateComplete Template \ call brownie#extract(BrownieFiletype(), 'template', ) endif if PluginExists('vim-gram') augroup vimrc_gram_init autocmd User gram-first-start ++once InitGramMapping() augroup END def InitGramMapping() gram#custom#map_action('n', '', 'select-item') gram#custom#map_action('n', 'q', 'quit') gram#custom#map_action('n', 'j', 'select-next-item') gram#custom#map_action('n', 'k', 'select-prev-item') gram#custom#map_action('n', 'i', 'start-insert') gram#custom#map_action('n', 'p', 'preview') gram#custom#map_action('i', '', 'stop-insert') gram#custom#map_action('i', '', 'stop-insert') gram#custom#map_action('i', '', 'stop-insert') gram#custom#map_action('i', '', 'delete-char') gram#custom#map_action('i', '', 'delete-word') gram#custom#map_action('i', '', 'move-to-right') gram#custom#map_action('i', '', 'move-to-left') gram#custom#map_action('i', '', 'move-to-head') gram#custom#map_action('i', '', 'move-to-tail') gram#custom#map_action('i', '', 'delete-to-head') gram#custom#map_key('n', '', '') gram#custom#map_key('i', '', '') gram#custom#map_key('i', '', '') enddef endif if PluginExists('vim-wispath') imap (wispath-complete) endif if PluginExists('vim-jplus') map J (jplus) endif if PluginExists('previm') g:previm_show_header = 0 g:previm_enable_realtime = 1 if IsWSL g:previm_open_cmd = '/mnt/c/Program Files/Google/Chrome/Application/chrome.exe' endif endif if PluginExists('vim-ambicmd') def AmbicmdExpand(key: string): string var expander = ambicmd#expand(key) return (expander ==# key ? '' : "\u") .. expander enddef augroup vimrc_ambicmd autocmd CmdWinEnter : call SetupAmbicmdForCmdwin() augroup END cnoremap ambicmd#expand("\") cnoremap ambicmd#expand("\") cnoremap ambicmd#expand("\") def SetupAmbicmdForCmdwin() inoremap AmbicmdExpand("\") inoremap AmbicmdExpand("\") inoremap AmbicmdExpand("\") inoremap AmbicmdExpand('') enddef g:ambicmd#show_completion_menu = 1 def AmbicmdBuildRule(cmd: string): list var rule = [] rule += ['\c^' .. cmd .. '$'] rule += ['\c^' .. cmd] for len in range(1, strlen(cmd)) var prefix = strpart(cmd, 0, len)->toupper()->substitute('.\zs', '.\\{-}', 'g') var suffix = cmd[len :] var matcher = '\C^' .. prefix .. suffix rule += [matcher .. '$', matcher] endfor rule += ['\c' .. cmd] rule += ['.\\{-}' .. substitute(cmd, '.\zs', '.\\{-}', 'g')] return rule enddef g:ambicmd#build_rule = SIDPrefix() .. 'AmbicmdBuildRule' endif if PluginExists('vim-quickrun') g:quickrun_config = {} g:quickrun_config['_'] = { ['outputter']: 'multi', ['outputter/multi/targets']: ['buffer', 'error'], ['outputter/error/success']: 'buffer', ['outputter/error/error']: 'quickfix', ['outputter/buffer/close_on_empty']: 1, runner: 'job', } g:quickrun_config.cpp = { cmdopt: '-std=c++17' } g:quickrun_config['cpp/sfml'] = { type: 'cpp', cmdopt: '-std=c++17 -lsfml-audio -lsfml-graphics -lsfml-network -lsfml-system -lsfml-window', } g:quickrun_config.objc = { command: 'cc', execute: ['%c %s -o %s:p:r -framework Foundation', '%s:p:r %a', 'rm -f %s:p:r'], tempfile: '%{tempname()}.m', } g:quickrun_config.applescript = { command: 'osascript', execute: '%c %s:p', tempfile: '%{tempname()}.applescript', } g:quickrun_config.python = { command: 'python3', ['hook/eval/template']: 'print(%s)' } g:quickrun_config.python2 = { command: 'python', ['hook/eval/template']: 'print(%s)' } if IsWSL g:quickrun_config.dosbatch = { command: 'cmd.exe', exec: '%c /Q /c \$(wslpath -w %s) %a' } endif nnoremap quickrun#is_running() ? \ 'call quickrun#sweep_sessions()' : \ '' nmap r (quickrun) vmap r (quickrun) augroup vimrc_filetype autocmd FileType quickrun nnoremap q q augroup END endif if PluginExists('capture.vim') augroup vimrc_filetype autocmd Filetype capture nnoremap q q augroup END endif if PluginExists('autofmt') set formatexpr=autofmt#japanese#formatexpr() endif if OptPluginExists('asyncomplete.vim') def AsyncompletePreprocessor(context: dict, matches_dict: dict) var base = tolower(context.base) var completions: list> var subcompletions: list> var fuzzycompletions: list> if trim(context.base) !=# '' for matches in values(matches_dict) for candidate in matches.items var idx = stridx(tolower(candidate.word), base) if idx == -1 continue elseif idx == 0 add(completions, candidate) else add(subcompletions, candidate) endif endfor endfor endif completions += subcompletions if !empty(completions) asyncomplete#preprocess_complete(context, completions) return endif # Workaround; matchfuzzy() always returns list var items: list = matches_dict->values()->mapnew((_, val): list => val.items)->flattennew() if trim(context.base) !=# '' items = matchfuzzy(items, context.base, {key: 'word'}) endif asyncomplete#preprocess_complete(context, items) enddef g:asyncomplete_auto_popup = 1 g:asyncomplete_preprocessor = [function('s:AsyncompletePreprocessor')] g:asyncomplete_auto_completeopt = 0 endif if OptPluginExists('vim-lsp') # Lazy-loading augroup vimrc_lsp_lazyload autocmd BufReadPre * LoadLspPlugins() autocmd BufNewFile * { LoadLspPlugins() doautocmd lsp BufNewFile } if !v:vim_did_enter autocmd VimEnter * { # Do not load lsp plugins on git commit if argc() != 0 && argv()[0] !~# '\$' LoadLspPlugins() doautocmd lsp BufReadPost endif } endif augroup END def LoadLspPlugins() # Load completion plugin first. if OptPluginExists('asyncomplete.vim') # asyncomplete-lsp.vim must be loaded before asyncomplete.vim if OptPluginExists('asyncomplete-lsp.vim') packadd asyncomplete-lsp.vim endif packadd asyncomplete.vim endif # vim-lsp-settings must be loaded before vim-lsp if OptPluginExists('vim-lsp-settings') packadd vim-lsp-settings endif packadd vim-lsp # Plugin initializations inoremap \ pumvisible() ? "\" : asyncomplete#close_popup() .. "\\" inoremap \ pumvisible() ? "\" : asyncomplete#close_popup() .. "\\" inoremap pumvisible() ? asyncomplete#cancel_popup() : "\" lsp#enable() autocmd! vimrc_lsp_lazyload command! -bar LoadLspPlugins { echohl WarningMsg echo 'Lsp plugins are already loaded' echohl NONE } enddef command! -bar LoadLspPlugins LoadLspPlugins()|echo 'Loaded lsp plugins' g:lsp_diagnostics_signs_enabled = 1 g:lsp_diagnostics_signs_error = {'text': '>>'} g:lsp_diagnostics_signs_warning = {'text': '--'} g:lsp_diagnostics_signs_information = {'text': '--'} g:lsp_diagnostics_signs_hint = {'text': '!?'} g:lsp_diagnostics_enabled = 1 g:lsp_diagnostics_float_delay = 10 g:lsp_diagnostics_float_cursor = 1 def LspDefineBufferAutocmds() LspClearBufferAutocmds() if &filetype ==# 'go' augroup vimrc_lsp_buffer_go autocmd BufWritePre silent LspDocumentFormatSync autocmd BufWritePre silent LspCodeActionSync source.organizeImports autocmd Filetype ++once LspClearBufferAutocmds() augroup END endif augroup vimrc_lsp_buffer autocmd BufWritePost lclose | silent LspDocumentDiagnostics augroup END enddef def LspClearBufferAutocmds() augroup vimrc_lsp_buffer autocmd! * augroup END if &filetype ==# 'go' augroup vimrc_lsp_buffer_go autocmd! * augroup END endif enddef def LspEnableForBuffer() setlocal omnifunc=lsp#complete nnoremap (-open-folding) zv nmap gd (lsp-declaration)(-open-folding) LspDefineBufferAutocmds() enddef def LspDisableForBuffer() setlocal omnifunc= nunmap gd LspClearBufferAutocmds() enddef augroup vimrc_lsp autocmd User lsp_buffer_enabled call LspEnableForBuffer() autocmd User lsp_buffer_disabled call LspDisableForBuffer() augroup END endif # Textobj/Operator-user plugins # @param # - plugin_name: the name of plugin # - info: mapping-information. The keys are: # - rhs (string) # - lhs (string) # - modes (string) # - on_load: the hook fired just after loading plugin # TODO: Support Funcref as on_load? def MapOperator(plugin_name: string, info_arg: dict, on_load: string = '') var info = extend(info_arg, {modes: 'nxo'}, 'keep') MapTextModifierPlugin(plugin_name, info, on_load) enddef def MapTextobj(plugin_name: string, info_arg: dict, on_load: string = '') var info = extend(info_arg, {modes: 'xo'}, 'keep') MapTextModifierPlugin(plugin_name, info, on_load) enddef def MapTextModifierPlugin( plugin_name: string, info: dict, on_load: string = '') # When the plugin is already loaded, do not use loader mapping. This load # guard is mainly for vimrc-reloading if HasInString(&runtimepath, plugin_name) return endif for key in ['rhs', 'lhs', 'modes'] if !has_key(info, key) EchomsgError('MapTextModifierPlugin: This key is missing: ' .. key) return endif endfor var loadermap = printf('LoadTextModifierPlugin("%s", %s, "%s")', plugin_name, string(info)->substitute('<', '', 'g'), on_load) for mode in info.modes execute mode .. 'map ' info.lhs loadermap endfor enddef def LoadTextModifierPlugin(plugin: string, info: dict, on_load: string): string if !(HasInString(&runtimepath, plugin .. ',') || &runtimepath[-len(plugin) :] == plugin) execute 'packadd' plugin if on_load !=# '' call(on_load, []) endif endif # "\" -> '' var rhs = info.rhs->substitute("\\C\", '', 'g') for mode in info.modes execute mode .. 'map' info.lhs rhs endfor # '' -> "\" return info.rhs->substitute('\c', "\", 'g') enddef if OptPluginExists('vim-operator-replace') MapOperator('vim-operator-replace', {lhs: 'ms', rhs: '(operator-replace)'}) endif if OptPluginExists('vim-operator-surround') MapOperator('vim-operator-surround', {lhs: 'ma', rhs: '(operator-surround-append)'}) MapOperator('vim-operator-surround', {lhs: 'md', rhs: '(operator-surround-delete)'}) MapOperator('vim-operator-surround', {lhs: 'mr', rhs: '(operator-surround-replace)'}) endif if OptPluginExists('caw.vim') inoremap (vimrc:caw:prefix) u inoremap (vimrc:caw:comment:here) \ =b:caw_oneline_comment def CawMap(): string var kind = '' if col('.') == 1 kind = 'zeropos' elseif col('.') == col('$') kind = 'dollarpos' elseif getline('.') =~# '^\s\+$' kind = 'hatpos' else return "\(vimrc:caw:comment:here)" endif return "\(vimrc:caw:prefix)\(caw:" .. kind .. ":comment)" enddef imap (vimrc:caw:map) CawMap() MapOperator('caw.vim', {lhs: 'mc', rhs: '(caw:hatpos:toggle:operator)'}) MapOperator('caw.vim', {lhs: 'm/', rhs: '(caw:hatpos:toggle:operator)'}) MapTextModifierPlugin('caw.vim', {lhs: '', rhs: '(vimrc:caw:map)', modes: 'i'}) g:caw_no_default_keymappings = 1 g:caw_dollarpos_sp_left = ' ' g:caw_dollarpos_sp_right = ' ' g:caw_hatpos_sp = ' ' g:caw_zeropos_sp = ' ' endif if OptPluginExists('vim-operator-swap') MapOperator('vim-operator-swap', {lhs: 'my', rhs: '(operator-swap-marking)'}) MapOperator('vim-operator-swap', {lhs: 'mp', rhs: '(operator-swap)'}) endif if OptPluginExists('vim-textobj-entire') MapTextobj('vim-textobj-entire', {lhs: 'aa', rhs: '(textobj-entire-a)'}) MapTextobj('vim-textobj-entire', {lhs: 'ia', rhs: '(textobj-entire-i)'}) g:textobj_entire_no_default_key_mappings = 1 endif if OptPluginExists('vim-textobj-function') augroup vim_textobj_function autocmd Filetype c,java,vim ++once { packadd vim-textobj-function execute 'runtime ftplugin/vim-textobj-function/' .. expand('') .. '/textobj-function.vim' } augroup END def CleanTextobjFunctionAutocmd() augroup vim_textobj_function autocmd! augroup END enddef MapTextobj('vim-textobj-function', {lhs: 'af', rhs: '(textobj-function-a)'}, 'CleanTextobjFunctionAutocmd') MapTextobj('vim-textobj-function', {lhs: 'if', rhs: '(textobj-function-i)'}, 'CleanTextobjFunctionAutocmd') g:textobj_function_no_default_key_mappings = 1 endif if OptPluginExists('vim-textobj-indent') MapTextobj('vim-textobj-indent', {lhs: 'ai', rhs: '(textobj-indent-a)'}) MapTextobj('vim-textobj-indent', {lhs: 'aI', rhs: '(textobj-indent-same-a)'}) MapTextobj('vim-textobj-indent', {lhs: 'ii', rhs: '(textobj-indent-i)'}) MapTextobj('vim-textobj-indent', {lhs: 'iI', rhs: '(textobj-indent-same-i)'}) g:textobj_indent_no_default_key_mappings = 1 endif if OptPluginExists('vim-textobj-line') MapTextobj('vim-textobj-line', {lhs: 'al', rhs: '(textobj-line-a)'}) MapTextobj('vim-textobj-line', {lhs: 'il', rhs: '(textobj-line-i)'}) g:textobj_line_no_default_key_mappings = 1 endif if OptPluginExists('vim-textobj-commentblock') MapTextobj('vim-textobj-commentblock', {lhs: 'ac', rhs: '(textobj-commentblock-a)'}, 'OnLoadingTextobjCommentblock') MapTextobj('vim-textobj-commentblock', {lhs: 'ic', rhs: '(textobj-commentblock-i)'}, 'OnLoadingTextobjCommentblock') g:textobj_commentblock_no_default_key_mapings = 1 def OnLoadingTextobjCommentblock() augroup vimrc_textobj_commentblock autocmd! autocmd Filetype * TextobjCommentblockPickerCaw() augroup END TextobjCommentblockPickerCaw() enddef def TextobjCommentblockPickerCaw() if exists('g:loaded_caw') textobj#commentblock#pick#caw() else textobj#commentblock#pick#commentblock() endif enddef endif if OptPluginExists('vim-textobj-between') MapTextobj('vim-textobj-between', {lhs: 'ad', rhs: '(textobj-between-a)'}) MapTextobj('vim-textobj-between', {lhs: 'id', rhs: '(textobj-between-i)'}) g:textobj_between_no_default_key_mappings = 1 omap i/ id/ omap a/ ad/ vmap i/ id/ vmap a/ ad/ endif # ReadingVimrc command! -bar ReadingVimrc call ReadingVimrc() augroup vimrc-readingvimrc autocmd BufReadCmd readingvimrc://* OnOpenReadingVimrcBuffer() augroup END def ReadingVimrc() try packadd vim-reading-vimrc # Use :execute here because :ReadingVimrcNext command doesn't defined yet # when compiling this function and E476 error is given execute 'ReadingVimrcNext' command! ReadingVimrc ReadingVimrcNext catch EchomsgError(v:throwpoint .. v:exception) endtry enddef def OnOpenReadingVimrcBuffer() var bufname = expand('')->matchstr('readingvimrc://\zs.*') if bufname ==# 'next' if winnr('$') == 1 return endif var curwinnr = winnr() for winnr in range(1, winnr('$')) if winnr == curwinnr continue elseif line('$') > 1 || winbufnr(winnr)->getbufline(1)[0] !=# '' wincmd T return endif endfor only else vmap y (reading_vimrc-update_clipboard) if winnr('$') > 1 wincmd T endif endif enddef # Additional plugins # Taking notes # autocmd User vimrc_initialize ++once call vimrc#notes#load() command! -bar -nargs=* MemoNew call vimrc#notes#memo_new() command! -bar -nargs=+ -complete=customlist,vimrc#notes#memo_complete \ MemoDelete call vimrc#notes#memo_delete() command! -bar MemoList call vimrc#notes#memo_list() command! -bar -nargs=* OtameshiNew call vimrc#notes#otameshi_new() command! -bar -nargs=+ -complete=customlist,vimrc#notes#otameshi_complete \ OtameshiDelete call vimrc#notes#otameshi_delete() command! -bar OtameshiList call vimrc#notes#otameshi_list() # working-plugin command! -bar -nargs=+ -complete=customlist,vimrc#workingplugin#complete \ WorkingPluginLoad call vimrc#workingplugin#load() command! -bar -bang -nargs=1 -complete=customlist,vimrc#workingplugin#complete \ WorkingPluginCd call vimrc#workingplugin#cd(0, ) command! -bar -nargs=+ WorkingPluginClone call vimrc#workingplugin#clone() command! -bar -nargs=+ WorkingPluginNew call vimrc#workingplugin#new() command! -bar -nargs=+ -complete=customlist,vimrc#workingplugin#complete \ WorkingPluginRm call vimrc#workingplugin#rm() # Sessions final SessionDir = JoinPath(CacheDir, 'sessions') { Mkdir(SessionDir) command! MkSession call vimrc#session#make() command! -nargs=+ -complete=custom,vimrc#session#complete DelSession \ call vimrc#session#delete(1, ) command! -nargs=1 -complete=custom,vimrc#session#complete RestoreSession \ call vimrc#session#restore() } # Showmode def ShowmodeInit() var colors = { normal: [['22', '148'], ['#005f00', '#afdf00']], insert: [['23', '117'], ['#005f5f', '#87dfff']], visual: [['88', '208'], ['#870000', '#ff8700']], replace: [['231', '160'], ['#ffffff', '#df0000']], } for [mode, color] in items(colors) execute printf( 'highlight VimrcShowMode%s ctermfg=%s ctermbg=%s guifg=%s guibg=%s', mode, color[0][0], color[0][1], color[1][0], color[1][1]) endfor enddef def ShowmodeMode(): string ShowmodeHighlight() var map = { n: 'NORMAL', i: 'INSERT', R: 'REPLACE', v: 'VISUAL', V: 'V-LINE', ["\"]: 'V-BLOCK', c: 'COMMAND', ce: 'EX-COM', s: 'SELECT', S: 'S-LINE', ["\"]: 'S-BLOCK', t: 'T-INSERT', no: 'OPERATOR', niI: 'N-INSERT', niR: 'N-REPLACE', niV: 'N-V-REPLACE', } return get(map, mode(), 'UNKNOWN') enddef def ShowmodeHighlight() var type = get({ i: 'insert', t: 'insert', R: 'replace', v: 'visual', V: 'visual', ["\"]: 'visual', }, mode(), 'normal') execute 'highlight link VimrcShowMode VimrcShowMode' .. type enddef def ShowmodeLabel(): string if win_getid() == g:statusline_winid && getwinvar(g:statusline_winid, '&modifiable') return '%#VimrcShowMode# %{ShowmodeMode()} %#Statusline#' endif return '' enddef augroup vimrc_showmode autocmd ColorScheme * ShowmodeInit() autocmd User vimrc_initialize ++once ShowmodeInit() augroup END # statusline if PluginExists('gina.vim') augroup vimrc_gina autocmd CursorHold * ++once call gina#component#repo#branch() | redrawstatus augroup END def StatuslineGitBranch(): string if exists('*gina#component#repo#branch') var branch = gina#component#repo#branch() if branch ==# '' return 'no-git' else var ahead: any = gina#component#traffic#ahead() var behind: any = gina#component#traffic#behind() var staged = !!gina#component#status#staged()->str2nr() var unstaged = !!gina#component#status#unstaged()->str2nr() var icon_modified = (staged || unstaged) ? '*' : '' var icon_ahead = ahead->type() == v:t_number && !!ahead ? '↑' : '' var icon_behind = behind->type() == v:t_number && !!behind ? '↓' : '' return branch .. icon_modified .. icon_ahead .. icon_behind endif else return 'loading...' endif enddef else def StatuslineGitBranch(): string return 'no-gina' enddef endif def StatuslineGenerator(): string var statusline = '%m' .. ShowmodeLabel() .. '[%{&ft ==# "" ? "No ft" : &ft}]' .. '[#%{bufnr("%")}]' .. '[%{StatuslineGitBranch()}]' .. '%{FilenameLabel(bufnr("%"))}' .. '%<%=' .. '[%{pathshorten(getcwd(winnr()))}]' return substitute(statusline, '\c', SIDPrefix(), 'g') enddef def FilenameLabel(bufnr: number): string var buftype = getbufvar(bufnr, '&buftype') var bufname = bufname(bufnr) if buftype ==# 'help' return fnamemodify(bufname, ':t') elseif buftype ==# 'quickfix' return '[quickfix]' elseif getbufvar(bufnr, '&previewwindow') return '[preview]' elseif buftype ==# 'terminal' return 'terminal:' .. bufname elseif buftype ==# 'prompt' return '[prompt]' else return (buftype ==# 'nofile' ? ' *NoFile* ' : '') .. (bufname ==# '' ? '[NoName]' : pathshorten(fnamemodify(bufname, ':.'))) endif enddef &statusline = printf('%%!%sStatuslineGenerator()', SIDPrefix()) # tabline &tabline = printf('%%!%sTabline()', SIDPrefix()) def GenerateTabinfo(tabnr: number): string var tablist = tabpagebuflist(tabnr) var info = '' info ..= len(filter(copy(tablist), 'getbufvar(v:val, "&mod")')) > 0 ? '[+]' : '' info ..= '[' .. tabpagewinnr(tabnr, '$') .. ']' return info enddef def Tabline(): string var tabline = '%#TabLine#|' var t = tabpagenr() for n in range(1, tabpagenr('$')) tabline ..= '%' .. n .. 'T' var info = ' ' .. GenerateTabinfo(n) .. ' ' if t == n tabline ..= '%#TabLineSel# %999Xx%X' .. info .. '%#TabLine#' else tabline ..= info endif tabline ..= '%T|' endfor tabline ..= '%>%=[%{pathshorten(getcwd())}]' return substitute(tabline, '\c', SIDPrefix(), 'g') enddef # :terminal augroup vimrc_terminal autocmd TerminalWinOpen * setlocal nonumber norelativenumber augroup END # EmphasisIndent highlight link VimrcEmphasisIndent CursorLine augroup vimrc_emphasize_indent autocmd WinEnter * EmphasizeIndent() autocmd OptionSet expandtab,smarttab,tabstop,shiftwidth EmphasizeIndent() autocmd User vimrc_initialize ++once EmphasizeIndent() augroup END def EmphasizeIndent() if exists('w:disable_emphasis_indent') && w:disable_emphasis_indent return endif if exists('w:emphasis_indent_id') matchdelete(w:emphasis_indent_id) endif var pat = '\v%%(^%%(%s)*)@<=%s' if &l:expandtab pat = printf(pat, repeat('\s', shiftwidth()), '\s') else pat = printf(pat, '\t\t', '\t') endif w:emphasis_indent_id = matchadd('VimrcEmphasisIndent', pat) enddef def EmphasisIndentEnable() w:disable_emphasis_indent = 0 EmphasizeIndent() enddef def EmphasisIndentDisable() w:disable_emphasis_indent = 0 if exists('w:emphasis_indent_id') matchdelete(w:emphasis_indent_id) unlet w:emphasis_indent_id endif enddef command! EmphasisIndentDisable call EmphasisIndentDisable() command! EmphasisIndentEnable call EmphasisIndentEnable() # WarningSpace highlight link WarningSpace Error augroup vimrc_warningspace autocmd WinEnter * WarningSpace() autocmd OptionSet * WarningSpace() # TODO: specify option? autocmd User vimrc_initialize ++once WarningSpace() augroup END def WarningSpace() # Clean up. if exists('w:twobyte_space_id') matchdelete(w:twobyte_space_id) unlet w:twobyte_space_id endif if exists('w:end_of_line_space_id') matchdelete(w:end_of_line_space_id) unlet w:end_of_line_space_id endif if &buftype !=# '' || !&modifiable return endif # Zenkaku space # NOTE: '\%d12288' means one zenkaku space. HINT: nr2char(12288) w:twobyte_space_id = matchadd('WarningSpace', '\%d12288') # White spaces in the end of line w:end_of_line_space_id = matchadd('WarningSpace', '\s\+$') enddef command! ReplaceTwobyteSpace keeppatterns :%s/\%d12288/ /g command! DeleteLineEndSpace keeppatterns :%s/\s\+$//g # mru g:mru_history_file = JoinPath(CacheDir, 'mru', 'history') { var dir_ = JoinPath(CacheDir, 'mru') if !isdirectory(dir_) Mkdir(dir_) endif } g:mru_ignore_pattern = [ \ '\.git\>', \ '^\V\%(' .. escape(expand('~'), '\') .. '\)\@!' \ ] # filore def FiloreMapping() var mapping: list = [ ['q', 'exit'], ['o', 'toggle-directory-folding'], ['l', 'enter-directory'], ['h', 'leave-directory'], ['.', 'toggle-show-hidden-files'], ['k', 'loop-cursor-up'], ['j', 'loop-cursor-down'], ['', 'open-file'], ['/', 'filter-files'], ['', 'start-history'], ]->mapnew((_: number, val: list): string => ('nmap ' .. val[0] .. ' (filore-' .. val[1] .. ')')) execute join(mapping, "\n") enddef augroup vimrc_additional_plugins autocmd FileType filore call FiloreMapping() augroup END # git def GitDiffGetcmd(arg_target: string): string var target: string = resolve(arg_target) var gitroot: string = FindGitroot(target) if gitroot ==# '' return '' endif return printf('git -C %s --no-pager diff --no-color %s', gitroot, target) enddef def GitDiff(arg_target: string): void var target: string if arg_target ==# '' target = bufname('%') else target = arg_target endif target = resolve(target) if getftype(target) ==# '' EchomsgError('File or directory does not exists: ' .. target) return endif var cmd: string = GitDiffGetcmd(target) if cmd ==# '' return endif var bufnr = term_start(cmd, { term_name: '[git diff] ' .. fnamemodify(target, ':~:.'), norestore: 1, }) if bufnr != 0 setlocal nocursorline nocursorcolumn filetype=diff nnoremap q quit cursor(1, 0) endif return enddef command! -nargs=? -complete=file GitDiff call GitDiff() # gyoza augroup vimrc_gyoza autocmd User vimrc_initialize ++once vimrc#gyoza#enable() augroup END # splash command! Splash call vimrc#splash#show() if !v:vim_did_enter && !has('gui_running') augroup vimrc_splash autocmd! autocmd VimEnter * ++once ++nested call vimrc#splash#intro() autocmd StdinReadPre * ++once autocmd! vimrc_splash VimEnter augroup END endif # gvimrc if has('gui_running') if !v:vim_did_enter if IsLinux && executable('i3') # It seems that too large window on i3 does not work properly. set lines=50 set columns=200 else set lines=999 set columns=9999 endif endif set guioptions& guioptions-=e guioptions-=T guioptions-=m set guioptions-=R guioptions-=r guioptions-=L guioptions-=l set mouse=a set nomousefocus set mousehide if has('win32') set guifont=Cica:h14,MS_Gothic:h10:cSHIFTJIS set linespace=1 elseif has('mac') set guifont=Cica:h14,Osaka-Mono:h14 elseif has('xfontset') #for unix (use xfontset) set guifont=a14,r14,k14 elseif has('linux') set guifont=Cica\ 14,DejaVu\ Sans\ Mono\ 14 endif if has('multi_byte_ime') || has('xim') set iminsert=0 imsearch=0 augroup vimrc_iminsert autocmd InsertLeave * set iminsert=0 augroup END endif endif # lvimrc { var lvimrc_ = Rc('lvimrc') lvimrc_ = JoinPath('~', lvimrc_) execute 'command! -bar -nargs=* LVimrc ' .. 'execute ( ==# "" ? "edit" : )' string(lvimrc_) if filereadable(expand(lvimrc_)) execute 'source' lvimrc_ endif } # Initialize when loading this file. augroup vimrc_initialize_dummy # Not to provide an error. For more information, see `:h E217` autocmd User vimrc_initialize ++once # Do nothing. augroup END if v:vim_did_enter doautocmd User vimrc_initialize else augroup vimrc_initialize autocmd VimEnter * ++once doautocmd User vimrc_initialize augroup END endif