" _ " __ _(_)_ __ ___ _ __ ___ " \ \ / / | '_ ` _ \| '__/ __| " \ V /| | | | | | | | | (__ " (_)_/ |_|_| |_| |_|_| \___| " " @kawarimidoll " https://twitter.com/kawarimidoll " https://github.com/kawarimidoll if has('nvim') lua if vim.loader then vim.loader.enable() end else set nocompatible set encoding=utf-8 scriptencoding utf-8 filetype plugin indent on packadd matchit " syntax enable autocmd FileType * ++once ++nested syntax enable let g:qf_disable_statusline = 1 endif " language ja_JP.UTF-8 " let g:did_install_default_menus = 1 " let g:did_install_syntax_menu = 1 " let g:did_indent_on = 1 " " load ftplugin to set commentstring " " let g:did_load_ftplugin = 1 " let g:loaded_2html_plugin = 1 " let g:loaded_getscript = 1 " let g:loaded_getscriptPlugin = 1 " let g:loaded_gzip = 1 " let g:loaded_logiPat = 1 " let g:loaded_logipat = 1 " let g:loaded_man = 1 " let g:loaded_matchit = 1 " let g:loaded_matchparen = 1 " let g:loaded_netrw = 1 " let g:loaded_netrwFileHandlers = 1 " let g:loaded_netrwPlugin = 1 " let g:loaded_netrwSettings = 1 " let g:loaded_remote_plugins = 1 " let g:loaded_rrhelper = 1 " let g:loaded_shada_plugin = 1 " let g:loaded_spellfile_plugin = 1 " let g:loaded_sql_completion = 1 " let g:loaded_tar = 1 " let g:loaded_tarPlugin = 1 " let g:loaded_tutor_mode_plugin = 1 " let g:loaded_vimball = 1 " let g:loaded_vimballPlugin = 1 " let g:loaded_zip = 1 " let g:loaded_zipPlugin = 1 " let g:skip_defaults_vim = 1 " let g:skip_loading_mswin = 1 " let g:vimsyn_embed = 1 " avoid to set expandtab in default ftplugin let g:markdown_recommended_style = 0 " {{{ Keymap " https://zenn.dev/kawarimidoll/articles/513d603681ece9 function! s:keymap(force_map, modes, ...) abort let arg = join(a:000, ' ') let cmd = a:force_map ? 'map' : 'noremap' for mode in split(a:modes, '.\zs') if stridx('nvsxoilct', mode) < 0 echoerr '[keymap] invalid mode is detected: ' mode arg continue endif execute mode .. cmd arg endfor endfunction command! -nargs=+ -bang Keymap call s:keymap(<bang>0, <f-args>) " }}} " perl -e 'print sort { length($a) <=> length($b) } <>' /usr/share/dict/words > ~/.cache/vim/sorted_words set dictionary+=~/.cache/vim/sorted_words let s:word_1000_dict_path = expand('~/.cache/vim/google-10000-english-no-swears.txt') let s:word_1000_dict_url = 'https://raw.githubusercontent.com/first20hours/' \ .. 'google-10000-english/master/google-10000-english-no-swears.txt' execute 'set dictionary+=' .. s:word_1000_dict_path command! -bang DownloadDictFile call mi#utils#download(s:word_1000_dict_url, s:word_1000_dict_path, <bang>0) command! -nargs=+ -bang -complete=expression NotifyShow call mi#notify#show([<args>], <bang>0 ? 3 : 2) command! -bang NotifyHistory call mi#notify#history(<bang>0) command! NotifyForget call mi#notify#forget() " function! s:look_completefunc() abort " let col = col('.') " if col < 2 " return '' " endif " let line = getline('.')[0:col-2] " let start_idx = matchend(line, '.*\A') " if start_idx < 0 " let start_idx = 0 " endif " let word = line[start_idx:] " let results = systemlist($"look {word}") " call sort(results, {a,b -> strlen(a) - strlen(b)}) " call complete(start_idx + 1, results) " return '' " endfunction " inoremap <c-x><c-k> <c-r>=<sid>look_completefunc()<cr> " alc represents auto look completeion let s:alc_enable = v:false function! s:toggle_alc() abort let s:alc_enable = !s:alc_enable augroup vimrc_alc autocmd! if s:alc_enable autocmd TextChangedI * echomsg getline('.')[col('.')-1] " autocmd TextChangedI * " \ if !pumvisible() && getline('.')[col('.')-1] =~ '\a' " \ | call feedkeys("\<c-x>\<c-k>", 'm') " \ | else " \ | echo 'not fit' " \ | endif endif augroup END echo 'look auto completion:' (s:alc_enable ? 'enabled' : 'disabled') endfunction command! ToggleAutoLookCompletion call s:toggle_alc() let s:dotfiles_dict_path = expand('~/dotfiles/.config/cspell/dotfiles.txt') execute 'set dictionary+=' .. s:dotfiles_dict_path set ambiwidth=single set breakindent set breakindentopt=min:50,shift:4,sbr,list:-1 set cedit=\<C-Q> " set clipboard& " set clipboard^=unnamed " set clipboard^=unnamedplus set complete=.,w,k,b,u set completeopt=menuone,noselect,fuzzy set expandtab set fileencodings=ucs-bom,utf-8,iso-2022-jp-3,euc-jp,cp932 set fillchars+=vert:│,eob:\\x20 set foldcolumn=0 set formatoptions+=jmM1 set history=2000 set ignorecase set infercase set laststatus=2 set lazyredraw set linebreak set list set listchars=tab:^-,trail:~,extends:»,precedes:«,nbsp:% set nobackup set nofixeol set nomodeline set nonumber set noshowmode set noswapfile set nowritebackup set runtimepath+=~/dotfiles/.vim set runtimepath+=~/dotfiles/.vim/after set scrolloff=5 set shiftround set shiftwidth=2 set shortmess+=scCI set showbreak=↪ set showtabline=0 set signcolumn=number set smartcase set smartindent set softtabstop=2 set spelllang+=cjk set spelloptions=camel set splitbelow set splitright set switchbuf+=usetab set tabstop=2 set termguicolors set title set updatetime=300 set whichwrap=b,s,h,l,<,>,[,],~ set wildmode=longest,full set wrap set wrapscan if executable('rg') set grepprg=rg\ --vimgrep\ --trim\ --hidden\ --glob=!.git set grepformat=%f:%l:%c:%m endif if has('nvim') set inccommand=split set scrollback=2000 else " :h vim-differences " :h nvim-defaults set autoindent set autoread set background=dark set backspace=indent,eol,start set belloff=all set completeopt+=popuphidden set display=lastline set hidden set hlsearch set incsearch set nojoinspaces set noruler set nostartofline set showcmd set smartcase set smarttab set ttimeout set ttimeoutlen=50 set ttyfast set viminfo='20,<50,s10,h set viminfofile=~/.vim/viminfo set wildmenu set wildoptions=pum,tagfile nnoremap Y y$ nnoremap <C-l> <Cmd>nohlsearch<Bar>diffupdate<Bar>normal! <C-l><CR> inoremap <C-u> <C-g>u<C-u> inoremap <C-w> <C-g>u<C-w> nnoremap & :&&<CR> nnoremap <C-a> <Cmd>call mi#dial#increment(v:count1)<CR> nnoremap <C-x> <Cmd>call mi#dial#decrement(v:count1)<CR> command! LazyGit tab terminal ++close ++norestore lazygit Keymap nx <expr> gc mi#comment#operator_toggle() nnoremap <expr> gcc mi#comment#operator_toggle() .. '_' " Keymap nx <expr> sa mi#surround#add() Keymap nx <expr> sa mi#surround#operator('add') nnoremap <expr> sd mi#surround#operator('delete') .. ' ' nnoremap <expr> sr mi#surround#operator('replace') .. ' ' let g:mi#ft#multiline = 1 Keymap nx f <cmd>call mi#ft#smart('f')<CR> Keymap nx F <cmd>call mi#ft#smart('F')<CR> Keymap nx t <cmd>call mi#ft#smart('t')<CR> Keymap nx T <cmd>call mi#ft#smart('T')<CR> Keymap nx ; <cmd>call mi#ft#repeat(';')<CR> Keymap nx , <cmd>call mi#ft#repeat(',')<CR> onoremap <expr> f mi#ft#smart_expr('f') onoremap <expr> F mi#ft#smart_expr('F') onoremap <expr> t mi#ft#smart_expr('t') onoremap <expr> T mi#ft#smart_expr('T') onoremap <expr> ; mi#ft#repeat_expr(';') onoremap <expr> , mi#ft#repeat_expr(',') noremap sf f noremap sF F noremap st t noremap sT T noremap s; ; noremap s, , nnoremap . <cmd>call mi#common#dot_repeat()<cr> nnoremap <c-e> <cmd>call mi#window#resize()<cr> " let s:help_dir = expand('~/.vim/vimdoc-ja') " execute 'set runtimepath+=' .. s:help_dir " function! s:ja_doc_update() abort " if isdirectory(s:help_dir) " echo '[ja_doc] pull latest version...' " echo system(printf('git -C %s reset --hard', s:help_dir)) " echo system(printf('git -C %s pull --rebase', s:help_dir)) " echo system(printf('git -C %s gc --prune=now', s:help_dir)) " else " echo '[ja_doc] clone latest version...' " echo system(printf('git clone --depth 1 https://github.com/vim-jp/vimdoc-ja.git %s', s:help_dir)) " endif " execute 'helptags' s:help_dir .. '/doc' " echo '[ja_doc] successfully updated.' " endfunction " command! JaDocUpdate call s:ja_doc_update() " prev/next use nnoremap [u *2Nzz<cmd>nohlsearch<cr> nnoremap ]u *zz<cmd>nohlsearch<cr> " word search with keep positions " https://twitter.com/Bakudankun/status/1207057884581900289 " `doautocmd CursorMoved` is required to show searchprop nnoremap <silent><expr> * v:count ? '*' : \ '<cmd>silent execute "keepjump normal! *" <bar> call winrestview(' \ .. string(winsaveview()) .. ')<cr><cmd>doautocmd CursorMoved<cr>' nnoremap <silent><expr> # v:count ? '#' : \ '<cmd>silent execute "keepjump normal! #" <bar> call winrestview(' \ .. string(winsaveview()) .. ')<cr><cmd>doautocmd CursorMoved<cr>' " :h termcap-cursor-shape@en " https://vim.fandom.com/wiki/Change_cursor_shape_in_different_modes if &term =~ 'xterm' || &term == 'win32' " Use DECSCUSR escape sequences " vertical bar in insert mode let &t_SI = "\e[5 q" " underline in replace mode let &t_SR = "\e[3 q" " block in normal mode let &t_EI = "\e[1 q" " change shape enter / escape termcap let &t_ti ..= "\e[1 q" let &t_te ..= "\e[0 q" " 0 -> default (depends on terminal, normally blinking block) " 1 -> blinking block " 2 -> solid block " 3 -> blinking underscore " 4 -> solid underscore " 5 -> blinking vertical bar " 6 -> solid vertical bar endif endif let g:my_vimrc = $MYVIMRC let g:vimrc_snr = expand('<SID>') command! RcEdit execute 'edit' g:my_vimrc command! RcReload write | execute 'source' g:my_vimrc | nohlsearch | redraw | echo g:my_vimrc .. ' is reloaded.' function! s:copy_path(target, with_lnum) abort let expr = '%' if a:target == 'full path' let expr ..= ':p' elseif a:target == 'dir name' let expr ..= ':h' elseif a:target == 'file name' let expr ..= ':t' endif let @*=expand(expr) .. (a:with_lnum ? ':' .. line('.') : '') echo 'copy ' .. a:target .. (a:with_lnum ? ' with line num' : '') endfunction command! -bang CopyFullPath call s:copy_path('full path', <bang>0) command! -bang CopyDirName call s:copy_path('dir name', <bang>0) command! -bang CopyFileName call s:copy_path('file name', <bang>0) command! -bang CopyRelativePath call s:copy_path('relative path', <bang>0) command! CopyLastCmd let @* = @: command! -nargs=+ -bang Grep call mi#qf#async_grep(<q-args>, {'add': <bang>0}) command! -nargs=+ -bang GrepF call mi#qf#async_grep(<q-args>, {'add': <bang>0, 'fixed': 1}) command! -nargs=+ -bang LGrep call mi#qf#async_grep(<q-args>, {'add': <bang>0, 'loc': 1}) command! -nargs=+ -bang LGrepF call mi#qf#async_grep(<q-args>, {'add': <bang>0, 'loc': 1, 'fixed': 1}) command! -nargs=1 -complete=file VDiff vertical diffsplit <args> command! VDiffAlt vertical diffsplit # command! SudoWrite write !sudo tee > /dev/null % nnoremap <silent> mm <Cmd>call mi#mark#auto_set()<CR> nnoremap <silent> m, <Cmd>call mi#mark#jump_to_last()<CR> nnoremap <silent> RR R nnoremap <expr> R mi#operator#replace() nnoremap <expr> J mi#operator#join() nnoremap <expr> JJ mi#operator#join() .. 'j' xnoremap <expr> J mi#operator#join() " like helix nnoremap U <c-r> " kensaku let g:kensaku#args = '--dict ~/.local/share/jsmigemo/no-abbrev-compact-dict' nnoremap J/ <cmd>call mi#kensaku#start()<cr> nnoremap J? <cmd>call mi#kensaku#start({ 'init': mi#kensaku#last_query() })<cr> nnoremap n <cmd>call mi#kensaku#next(0)<cr> nnoremap N <cmd>call mi#kensaku#next(1)<cr> " https://zenn.dev/yahomi_dev/articles/216231f2902f32 function! s:split_line() abort normal! mz call execute('s/\v\{\zs\s?|,\zs\s|\s?\ze\}/\r/g', 'silent!') normal! =`z nohlsearch endfunction nnoremap Jp <cmd>call <sid>split_line()<cr> " https://zenn.dev/mattn/articles/83c2d4c7645faa nmap gj gj<SID>g nmap gk gk<SID>g nnoremap <script> <SID>gj gj<SID>g nnoremap <script> <SID>gk gk<SID>g nmap <SID>g <Nop> noremap h <cmd>call mi#hjkl#h(v:count1)<cr> noremap l <cmd>call mi#hjkl#l(v:count1)<cr> " noremap j <cmd>call mi#hjkl#j(v:count1)<cr> " noremap k <cmd>call mi#hjkl#k(v:count1)<cr> noremap sj <cmd>call mi#hjkl#j(v:count1, v:true)<cr> noremap sk <cmd>call mi#hjkl#k(v:count1, v:true)<cr> " noremap gj j " noremap gk k noremap gV `[v`] " https://github.com/yuki-yano/zero.vim/blob/main/plugin/zero.vim noremap <silent><expr> H (mi#utils#not_q() && getline('.')[:col('.')-2] =~# '^\s\+$')? '0' : '^' " https://github.com/yuki-yano/dotfiles/blob/c56b219116de1693c45c20b03b109497896d5b16/.vimrc#L602-L605 nnoremap <expr> i len(getline('.')) ? 'i' : '"_cc' nnoremap <expr> A len(getline('.')) ? 'A' : '"_cc' noremap L $ map M % map gM g% noremap gm gM nnoremap / /\v nnoremap ? /\V nnoremap F<cr> { nnoremap f<cr> } nnoremap <script> <c-g> 2<c-g><sid>(cg) nnoremap <sid>(cg)<c-g> <cmd>echomsg 'hello'<cr> nnoremap <sid>(cg)e <cmd>echomsg 'hello'<cr> nnoremap <sid>(cg)p <cmd>CopyFullPath<cr> nnoremap <sid>(cg)P <cmd>CopyFullPath!<cr> nnoremap <sid>(cg)d <cmd>CopyDirName<cr> nnoremap <sid>(cg)D <cmd>CopyDirName!<cr> nnoremap <sid>(cg)f <cmd>CopyFileName<cr> nnoremap <sid>(cg)F <cmd>CopyFileName!<cr> nnoremap <sid>(cg)r <cmd>CopyRelativePath<cr> nnoremap <sid>(cg)R <cmd>CopyRelativePath!<cr> nnoremap <sid>(cg)c <cmd>CopyLastCmd<cr> nnoremap <sid>(cg)C <cmd>CopyLastCmd!<cr> " nnoremap <script> <sid><c-g><c-g> <cmd>let @*=expand("%:~:.")<cr> nmap <sid>(cg) <nop> nnoremap s <NOP> if has('nvim') " in neovim, :source can read lua file nnoremap so <Cmd>execute 'source' (filereadable(@%) ? @% : '')<Bar>nohlsearch<CR> else function s:source() abort let fname = filereadable(@%) ? @% : '' let is_lua = &filetype == 'lua' || fname =~ 'lua$' if !is_lua execute 'source' fname elseif !empty(fname) execute 'luafile' fname else execute 'lua' getline(1, '$')->join(' ') endif " nohlsearch endfunction nnoremap so <Cmd>call <sid>source()<Bar>nohlsearch<CR> endif nnoremap s/ :%s/\v nnoremap s? :%s/\V nnoremap S :%s/\V\<<C-r><C-w>\>//g<Left><Left> " https://thinca.hatenablog.com/entry/q-as-prefix-key-in-vim nnoremap <script><expr> q empty(reg_recording()) ? '<sid>(q)' : 'q' nnoremap <sid>(q)q qq nnoremap <script><expr> Q empty(reg_recording()) ? '@q' : 'q@q' xnoremap <expr> Q ':global/^/normal Q' .. repeat('<left>', 9) nnoremap <sid>(q)/ q/ nnoremap <sid>(q): q: nnoremap <sid>(q)a <Cmd>call mi#qf#add_curpos()<CR> nnoremap <sid>(q)c <Cmd>call mi#qf#toggle()<CR> nnoremap <sid>(q)d <Cmd>quit<CR> nnoremap <sid>(q)D <Cmd>quitall!<CR> nnoremap <sid>(q)g :<C-u>global/^/normal<Space> nnoremap <sid>(q)h <Cmd>call mi#common#half_move('left', v:count1)<CR> nnoremap <sid>(q)i <Cmd>call mi#common#half_move('center', v:count1)<CR> nnoremap <sid>(q)j <Cmd>call mi#common#half_move('down', v:count1)<CR> nnoremap <sid>(q)k <Cmd>call mi#common#half_move('up', v:count1)<CR> nnoremap <sid>(q)l <Cmd>call mi#common#half_move('right', v:count1)<CR> nnoremap <sid>(q)o <Cmd>only!<CR> nnoremap <sid>(q)t <C-^> nnoremap <sid>(q)x <Cmd>call mi#qf#clear()<CR> nnoremap <sid>(q)w <Cmd>write<CR> " reserve for neovim if has('nvim') for c in ['d', 'z'] execute printf('nnoremap <sid>(q)%s <Plug>(rc-q-%s)', c, c) endfor endif " function! s:sync_unnamed() abort " if empty(@") " let @" = @* " endif " endfunction nnoremap p ]p`] nnoremap P [P`] " nnoremap p <cmd>call <sid>sync_unnamed()<cr>]p`] " nnoremap P <cmd>call <sid>sync_unnamed()<cr>[P`] "nnoremap gp p "nnoremap gP P nnoremap x "_d nnoremap X "_D " nnoremap ' ` nmap <SID>[ <Nop> nmap <SID>] <Nop> function! s:neighbor_submode_map(key, prev_rhs, next_rhs) abort execute printf('nmap [%s %s<SID>[', a:key, a:prev_rhs) execute printf('nmap ]%s %s<SID>]', a:key, a:next_rhs) execute printf('nnoremap <script> <SID>[%s %s<SID>[', a:key, a:prev_rhs) execute printf('nnoremap <script> <SID>]%s %s<SID>]', a:key, a:next_rhs) endfunction call s:neighbor_submode_map('b', '<cmd>bprevious<cr>', '<cmd>bnext<cr>') call s:neighbor_submode_map('q', '<cmd>call mi#qf#cycle_p()<cr>', '<cmd>call mi#qf#cycle_n()<cr>') call s:neighbor_submode_map('w', '<c-w>w', '<c-w>W') " nnoremap [m [` " nnoremap ]m ]` " nnoremap [p { " nnoremap ]p } nnoremap [B <Cmd>bfirst<CR> nnoremap ]B <Cmd>blast<CR> nnoremap <silent><expr> [Q '<Cmd>' .. v:count1 .. 'colder<CR>' nnoremap <silent><expr> ]Q '<Cmd>' .. v:count1 .. 'cnewer<CR>' " for 40% keyboard nmap <BS> [ nmap ' ] " https://twitter.com/mo_naqa/status/1467626946293284865 " nnoremap gf gFzz " nnoremap gx :<C-u>!open <C-r><C-a> command! -nargs=* SmartOpen call mi#open#smart_open(<q-args>) Keymap nx gf <Cmd>call mi#open#smart_open()<CR> "for c in g:mi#const#alpha_all->split('\zs') " execute 'nnoremap <Space>' .. c '<NOP>' "endfor nmap <Space>8 * nmap <Space>3 # nnoremap <Space>b <Cmd>call mi#fzf#bufs()<CR> nnoremap <Space>d <Cmd>call mi#buf#delete()<CR> nnoremap <Space>D <Cmd>call mi#buf#delete({'force': v:true})<CR> nnoremap <Space>f <Cmd>call mi#fzf#files()<CR> nnoremap <Space>g <Cmd>copy.<CR> nnoremap <Space>G <Cmd>copy-1<CR> nnoremap <space>h <Cmd>call mi#fzf#mru()<CR> nnoremap <Space>m <Cmd>marks<bar>execute $'normal! `{input("jump to: ")}'<CR> nnoremap <expr> <Space>o mi#blank#below() nnoremap <expr> <Space>O mi#blank#above() nnoremap <expr> <Space>p exists('b:fmt_cmd') \ ? '<cmd>call mi#fmt#run(b:fmt_cmd)<cr>' \ : '<cmd>KeepCursor %call mi#common#trim()<cr>mzgg=G`z' xnoremap <expr> <Space>p exists('b:fmt_cmd') \ ? '<cmd>call mi#fmt#run(b:fmt_cmd)<cr>' \ : ':call mi#common#trim()<cr>gv=gv' nnoremap <Space>q <cmd>confirm quit<CR> nnoremap <Space>r <Cmd>registers<bar>execute $'normal "{input("paste reg: ")}p'<CR> nnoremap <Space>Q <cmd>quitall!<CR> nnoremap <Space>w <cmd>w<CR> nnoremap <Space>wq <cmd>confirm wq<CR> nnoremap <Space>; @: nnoremap <Space>/ :<C-u>Grep<Space> nnoremap <Space>? :<C-u>GrepF <C-r><C-w> xnoremap <Space>? "zy:<C-u>GrepF <C-r>z nnoremap <silent><expr> <C-k> $'<Cmd>move-1-{v:count1}<CR>=l' nnoremap <silent><expr> <C-j> $'<Cmd>move+{v:count1}<CR>=l' nnoremap <Space>L <Cmd>LazyGit<CR> " https://zenn.dev/kawarimidoll/articles/17dad86545cbb4 nnoremap <C-f> <Cmd>set scroll=0<CR><Cmd>execute 'normal!' repeat('<C-d>', v:count1 * 2)<CR> nnoremap <C-b> <Cmd>set scroll=0<CR><Cmd>execute 'normal!' repeat('<C-u>', v:count1 * 2)<CR> " command " cnoremap <expr> s getcmdtype() == ':' && getcmdline() == 's' ? '<BS>%s/' : 's' cnoremap <expr> % getcmdtype() == ':' && getcmdpos() > 2 && getcmdline()[getcmdpos()-2] == '%' ? \ '<BS>' .. expand('%:h') .. '/' : '%' cnoremap <expr> / getcmdtype() == '/' ? '\/' : '/' cnoremap <expr> <C-n> wildmenumode() ? '<C-n>' : '<Down>' cnoremap <expr> <C-p> wildmenumode() ? '<C-p>' : '<Up>' cnoremap <C-b> <Left> cnoremap <C-f> <Right> cnoremap <C-a> <Home> cnoremap <C-e> <End> cnoremap <C-d> <Del> cmap <c-h> <bs> " cnoremap <C-r><C-r> <cmd>call <sid>sync_unnamed()<cr><C-r><C-r>" cnoremap <C-r><C-r> <C-r><C-r>" " cnoremap <c-c> <home>Capture <cr> cnoremap <expr> <C-k> repeat('<Del>', strchars(getcmdline()[getcmdpos() - 1:])) cnoremap <s-cr> <cmd>call mi#cmdline#set_by_spec(extend(mi#cmdline#get_spec(), {'bang': v:true}))<cr><cr> cnoremap <cr> <cmd>call mi#cmdline#proxy_convert()<cr><cr> cnoremap <expr> <C-x> mi#magic#expr() " {{{ AbbrevCmd " expand abbreviations immediately in command-line let s:abbrev_cmds = {} function! s:abbrev_cmd(raw_rhs, cmd_lhs, ...) abort " backspace cmd_lhs let bs = repeat('<bs>', strchars(a:cmd_lhs) - 1) const rhs = a:raw_rhs ? string(bs) .. ".." .. join(a:000, ' ') : \ string(bs .. join(a:000, ' ')) const [lhs_except_last, lhs_last] = matchlist(a:cmd_lhs, '^\(.*\)\(.\)$')[1:2] if !has_key(s:abbrev_cmds, lhs_last) let s:abbrev_cmds[lhs_last] = {} endif let s:abbrev_cmds[lhs_last][lhs_except_last] = rhs " can't use string() not to quote values const rhs_list = map(items(s:abbrev_cmds[lhs_last]), {_,val -> $"':{val[0]}':{val[1]}"}) " range is not supported apart from visual selection const fmt = "cnoremap <expr> %s get({%s},getcmdtype()..getcmdline()->substitute(\"^'<,'>\",'',''),'%s')" execute printf(fmt, lhs_last, join(rhs_list, ','), lhs_last) endfunction command! -nargs=+ -bang AbbrevCmd call s:abbrev_cmd(<bang>0, <f-args>) " }}} AbbrevCmd cfi Cfilter AbbrevCmd cap Capture AbbrevCmd coc CopyLastCmd AbbrevCmd cod CopyDirName AbbrevCmd cof CopyFileName AbbrevCmd coa CopyFullPath AbbrevCmd cor CopyRelativePath AbbrevCmd yep echo 'yep' AbbrevCmd mes messages AbbrevCmd mec messages clear AbbrevCmd ec echo AbbrevCmd ed edit AbbrevCmd en enew AbbrevCmd plgs PlugSync AbbrevCmd plugs PlugSync AbbrevCmd! sv 'saveas ' .. @% AbbrevCmd! rn 'Rename ' .. @% AbbrevCmd! ss '%s/' .. @/ .. '//g<Left><Left>' " AbbrevCmd! ss '%s/' .. @/ .. "//g\<Left>\<Left>" olso ok AbbrevCmd! gld 'global //d_<left><left><left>' " cnoremap <expr> v getcmdtype() == ':' && getcmdline() == 's' ? '<c-u>saveas ' .. @% : 'v' " cnoremap <expr> n getcmdtype() == ':' && getcmdline() == 'r' ? '<c-u>Rename ' .. @% : 'n' " cnoremap <expr> s getcmdtype() == ':' && getcmdline() =~ '^plu\?g$' ? '<c-u>PlugSync' : 's' cnoremap <expr> . getcmdtype() == '/' && getcmdpos() > 2 && getcmdline()[getcmdpos()-2] == ',' ? \ '<c-u>\<' .. substitute(getcmdline()[:-2], '\\v', '', 'gi') .. '\>' : '.' " https://zenn.dev/monaqa/articles/2020-12-22-vim-abbrev cnoreabbrev <expr> w getcmdtype() .. getcmdline() ==# ":'<,'>w" ? "\<C-u>w" : 'w' " https://zenn.dev/vim_jp/articles/2023-06-30-vim-substitute-tips " cnoreabbrev <expr> s getcmdtype() .. getcmdline() ==# ':s' ? [getchar(), ''][1] .. "%s/" .. escape(@/, '/') .. "//g<Left><Left>" : 's' " " insert " function s:next_or_cmp() " if pumvisible() " return feedkeys("\<c-n>", 'ni') " endif " call s:my_cmp() " endfunction " function s:my_cmp(phase = 0) " if pumvisible() " return " endif " let cmp_keys = ["\<c-f>", "\<c-v>", "\<c-n>", "\<c-k>"] " if &filetype != 'vim' && &filetype != 'help' " call remove(cmp_keys, 1) " endif " let col = col('.') - 2 " let prev_char = col < 0 ? '' getline('.')[col] " if empty(prev_char) || prev_char =~ '\s' " call remove(cmp_keys, 0) " endif " let next_cmp = get(cmp_keys, a:phase, '') " if empty(next_cmp) " return feedkeys("\<c-n>", 'ni') " endif " let recall = $"\<cmd>call {expand('<SID>')}my_cmp({a:phase + 1})\<cr>" " call feedkeys($"\<c-x>{next_cmp}{recall}", 'ni') " endfunction " inoremap <tab> <cmd>call <sid>next_or_cmp()<cr> " inoremap <c-x><c-y> <cmd>call <sid>my_cmp()<cr> imap <c-h> <bs> " inoremap <silent> <C-r><C-r> <cmd>call <sid>sync_unnamed()<cr><C-r><C-r>" inoremap <silent> <C-r><C-r> <C-r><C-r>" inoremap <C-k> <C-o>D inoremap <expr> <Tab> pumvisible() ? '<C-n>' : '<C-t>' inoremap <expr> <S-Tab> pumvisible() ? '<C-p>' : '<C-d>' inoremap <C-g><C-u> <esc>gUvbgi inoremap <C-g><C-l> <esc>guvbgi inoremap <right> <c-g>U<right> inoremap <left> <c-g>U<left> inoremap <home> <c-g>U<home> inoremap <end> <c-g>U<end> imap <c-f> <right> imap <c-b> <left> imap <c-a> <home> imap <c-e> <end> inoremap <c-j> <del> inoremap <c-x><c-v> <c-x><c-v><c-n> " https://zenn.dev/kawarimidoll/articles/262785e8ca05b0 inoremap <expr> <c-g><c-f> &completeopt =~ 'fuzzy' \ ? '<cmd>set completeopt-=fuzzy<cr>a<bs>' \ : '<cmd>set completeopt+=fuzzy<cr>a<bs>' " https://zenn.dev/kawarimidoll/articles/54e38aa7f55aff inoremap <expr> / \ complete_info(['mode']).mode == 'files' && complete_info(['selected']).selected >= 0 \ ? '<c-x><c-f>' \ : '/' inoremap <expr> . \ complete_info(['mode']).mode == 'files' && complete_info(['selected']).selected >= 0 \ ? '.<c-x><c-f>' \ : '.' " sticky-shift " https://vim-jp.org/vim-users-jp/2009/08/09/Hack-54.html function s:sticky_shift() abort let char = getcharstr()[0] return char ==# ' ' ? \ ';' \ : char =~# '^\p' ? \ mi#utils#upper_key(char) \ : '' endfunction noremap! <expr> ; <sid>sticky_shift() function s:caps() abort if exists('#capslock#KeyInputPre') autocmd! capslock return endif augroup capslock autocmd! autocmd KeyInputPre * if v:char =~# '^\l' \ | let v:char = mi#utils#upper_key(v:char) \ | endif autocmd CmdlineLeave,InsertLeave * autocmd! capslock augroup END endfunction noremap! C <Cmd>call <SID>caps()<CR> " https://zenn.dev/vim_jp/articles/b4294351def1ba function! s:symbol_cmp() abort let triggers = 'hjklnmfdsavcuiorew'->split('\zs') let comp_list = b:symbol_list->copy() \ ->map({i, v -> {'word': v, 'menu': get(triggers, i, '')}}) call complete(col('.')-1, comp_list) augroup symbolselect autocmd! autocmd KeyInputPre * call s:symbol_select() autocmd ModeChanged * autocmd! symbolselect augroup END endfunction function! s:symbol_select() abort let items = complete_info(['items']).items let idx = indexof(items, {_,v -> get(v, 'menu', '') ==# v:char}) if idx >= 0 let v:char = "\<bs>" call feedkeys(items[idx].word, 'ni') endif endfunction inoremap <expr> , exists('b:symbol_list') \ ? ',<cmd>call <sid>symbol_cmp()<cr>' \ : ',' " function! s:imap_up() abort " if line('.') == 1 " call feedkeys("\<c-g>U\<home>", 't') " return " endif " if exists('g:mi#dot_repeating') " call feedkeys("\<up>", 't') " return " endif " call appendbufline(0, line('.'), getline('.')) " call setbufline(0, line('.'), getline(line('.')-1)) " call deletebufline(0, line('.')-1) " endfunction " function! s:imap_down() abort " if line('.') == line('$') " call feedkeys("\<c-g>U\<end>", 't') " return " endif " if exists('g:mi#dot_repeating') " call feedkeys("\<down>", 't') " return " endif " call appendbufline(0, line('.')-1, getline('.')) " call setbufline(0, line('.'), getline(line('.')+1)) " call deletebufline(0, line('.')+1) " endfunction " if !has('nvim') " inoremap <c-l> <c-@> " inoremap <up> <cmd>call <sid>imap_up()<cr> " inoremap <down> <cmd>call <sid>imap_down()<cr> " endif let s:ft_expand_targets = { \ 'javascript': { \ ';p': "console.log()\<left>", \ ';if': "if() {}\<left>\<cr>\<c-o>\<up>\<home>\<c-o>f)", \ }, \ 'vim': { \ ';p': 'echomsg ', \ ';if': "if\<cr>endif\<c-o>\<up>\<end> ", \ ';fun': "function! abort\nendfunction\<up>\<c-o>E\<right>", \ }, \ } let s:expand_targets = { \ '%': { ->@% }, \ ';p': "print()\<left>", \ } let s:ft_aliases = { \ 'typescript': 'javascript', \ 'javascriptreact': 'javascript', \ 'typescriptreact': 'javascript', \ } function! s:expand_snippet(fallback) abort const prev_idx = getcharpos('.')[2] - 2 if prev_idx < 0 return a:fallback endif const line = getline('.') const prev_cursor = line[:prev_idx] const prev_len = strlen(prev_cursor) const filetype = get(s:ft_aliases, &filetype, &filetype) const targets_current_ft = get(s:ft_expand_targets, filetype, {}) const targets = extend(copy(s:expand_targets), targets_current_ft) for target_key in keys(targets) let match_idx = strridx(prev_cursor, target_key) if match_idx >= 0 && match_idx + strlen(target_key) == prev_len const replacement = type(targets[target_key]) == v:t_func ? targets[target_key]() \ : type(targets[target_key]) == v:t_list ? join(targets[target_key], "\<cr>") \ : targets[target_key] return repeat("\<bs>", strcharlen(target_key)) .. replacement endif endfor return a:fallback endfunction inoremap <expr> <c-x> <sid>expand_snippet("\<c-x>") " visual " xnoremap p <cmd>call <sid>sync_unnamed()<cr>P xnoremap p P xnoremap <silent> y y`] xnoremap x "_x xnoremap < <gv xnoremap > >gv " xmap <Tab> > " xmap <S-Tab> < xnoremap <silent><C-k> :m'<-2<CR>gv=gv xnoremap <silent><C-j> :m'>+1<CR>gv=gv xnoremap S "zy:%s/<C-r>z//gce<Left><Left><Left><Left> " ref: https://github.com/monaqa/dotfiles/blob/f214e9628cbac0803ad9d9bc2ad1582c696c4e6b/.config/nvim/scripts/keymap.vim#L63-L69 xnoremap * "zy/\V<C-r><C-r>=substitute(escape(@z, '/\'), '\_s\+', '\\_s\\+', 'g')<CR><CR>`` xnoremap # "zy?\V<C-r><C-r>=substitute(escape(@z, '/\'), '\_s\+', '\\_s\\+', 'g')<CR><CR>`` xnoremap R "zy:,$s//<C-r><C-r>=escape(@z, '/\&~')<CR>/gce<Bar>1,''-&&<CR> xnoremap so :source<cr><cmd>nohlsearch<cr>gv " operator onoremap x d " terminal tnoremap <C-w><C-n> <C-\><C-n> tnoremap <C-p> <Up> tnoremap <C-n> <Down> " https://qiita.com/monaqa/items/dcd43a53d3040293142a let s:jp_digraphs = [ \ ['aa', 'あ'], ['ii', 'い'], ['uu', 'う'], ['ee', 'え'], ['oo', 'お'], \ ['aA', 'ぁ'], ['iI', 'ぃ'], ['uU', 'ぅ'], ['eE', 'ぇ'], ['oO', 'ぉ'], \ ['Aa', 'ア'], ['Ii', 'イ'], ['Uu', 'ウ'], ['Ee', 'エ'], ['Oo', 'オ'], \ ['AA', 'ァ'], ['II', 'ィ'], ['UU', 'ゥ'], ['EE', 'ェ'], ['OO', 'ォ'], \ ['nn', 'ん'], ['Nn', 'ン'], ['j(', '('], ['j)', ')'], ['j[', '「'], \ ['j]', '」'], ['j{', '『'], ['j}', '』'], ['j<', '【'], ['j>', '】'], \ ['j,', '、'], ['j.', '。'], ['j!', '!'], ['j?', '?'], ['j:', ':'], \ ['j0', '0'], ['j1', '1'], ['j2', '2'], ['j3', '3'], ['j4', '4'], \ ['j5', '5'], ['j6', '6'], ['j7', '7'], ['j8', '8'], ['j9', '9'], \ ['j~', '〜'], ['j/', '・'], ['j ', ' '], \ ] call digraph_setlist(s:jp_digraphs) noremap f<C-j> f<C-k>j noremap F<C-j> F<C-k>j noremap t<C-j> t<C-k>j noremap T<C-j> T<C-k>j Keymap xo il <Cmd>call mi#textobject#line()<CR> Keymap xo al <Cmd>call mi#textobject#line({'no_trim': 1})<CR> Keymap xo iu <Cmd>call mi#textobject#fname()<CR> Keymap xo iy <Cmd>call mi#textobject#lastpaste()<CR> Keymap xo id <Cmd>call mi#textobject#datetime()<CR> Keymap xo iA <Cmd>call mi#textobject#alphabet()<CR> Keymap xo aA <Cmd>call mi#textobject#alphabet({'with_num': 1})<CR> Keymap xo ie <Cmd>call mi#textobject#entire()<CR> Keymap xo ae <Cmd>call mi#textobject#entire({'charwise': 1})<CR> Keymap xo iS <Cmd>call mi#textobject#space()<CR> Keymap xo aS <Cmd>call mi#textobject#space({'with_tab': 1})<CR> Keymap xo io <Cmd>call mi#textobject#outline()<CR> Keymap xo ao <Cmd>call mi#textobject#outline({'from_parent': 1, 'with_blank': 1})<CR> if !has('nvim') Keymap xo i<space> iW Keymap xo ib <cmd>call mi#textobject#pair('i')<cr> Keymap xo ab <cmd>call mi#textobject#pair('a')<cr> Keymap xo iq <cmd>call mi#textobject#quote('i')<cr> Keymap xo aq <cmd>call mi#textobject#quote('a')<cr> " Keymap xo i<space> <cmd>call mi#textobject#between(' ', 0)<cr> Keymap xo a<space> <cmd>call mi#textobject#between(' ', 1)<cr> Keymap xo i<bar> <cmd>call mi#textobject#between("\<bar>", 0)<cr> Keymap xo a<bar> <cmd>call mi#textobject#between("\<bar>", 1)<cr> " does not works <bslash>... " Keymap xo i<bslash> <cmd>call mi#textobject#between("\<bslash>", 0)<cr> " Keymap xo a<bslash> <cmd>call mi#textobject#between("\<bslash>", 1)<cr> for i in range(33, 126) let c = nr2char(i) if c !~ '[[:punct:]]' || stridx('\|<>(){}[]"`''', c) >= 0 continue endif execute 'Keymap xo i' .. c .. ' <cmd>call mi#textobject#between(''' .. c .. ''', 0)<cr>' execute 'Keymap xo a' .. c .. ' <cmd>call mi#textobject#between(''' .. c .. ''', 1)<cr>' endfor Keymap xo i? <cmd>call mi#textobject#input(0)<cr> Keymap xo a? <cmd>call mi#textobject#input(1)<cr> endif " {{{ Rename " https://vim-jp.org/vim-users-jp/2009/05/27/Hack-17.html command! -nargs=1 -complete=file Rename \ execute 'autocmd BufWritePost <buffer> ++once call delete("' .. expand('%') .. '")' | \ file <args> " }}} " {{{ EditProjectMru() " https://zenn.dev/kawarimidoll/articles/057e0c26c6d6e3 " remove function after startup because it is only for `$ vim -c 'call EditProjectMru()'` function! EditProjectMru() abort execute 'edit' get(mi#mru#list(v:true), 0, '') call timer_start(10, {->execute('delfunction! EditProjectMru')}) endfunction " }}} function! s:apply_user_highlight() abort highlight Reverse cterm=reverse gui=reverse " highlight Pmenu ctermfg=254 ctermbg=237 guifg=#e3e1e4 guibg=#37343a " highlight PmenuSel ctermfg=237 ctermbg=254 guifg=#37343a guibg=#e3e1e4 " highlight PmenuSbar ctermbg=238 guibg=#423f46 " highlight PmenuThumb ctermbg=255 guibg=#f8f8f2 highlight Underlined ctermfg=NONE cterm=underline guifg=NONE gui=underline highlight ExtraWhitespace ctermbg=darkmagenta guibg=darkmagenta if !has('nvim') highlight! link StatusLine Comment highlight! link StatusLineNC Comment highlight! link VertSplit Comment endif endfunction " https://zenn.dev/hokorobi/articles/98f79339d7d114 function! s:syntax_off_on_heavy_file() if getfsize(@%) > 512 * 1000 setlocal syntax=OFF NotifyShow 'syntax off: too heavy file.' if &filetype !=# 'help' call interrupt() endif endif endfunction command! -nargs=* -bang -complete=command Capture call mi#capture#run(<bang>0, <q-args>) " https://github.com/thinca/config/blob/78a1d2d4725e2ff064722b48cea5b5f1c44f49f9/dotfiles/dot.vim/vimrc#L1407-L1408 command! -nargs=+ KeepCursor call mi#utils#keep_cursor(<q-args>) function! s:visualize_autocmds() let events = [ \ 'FileType', 'BufNewFile', 'BufEnter', 'BufRead', 'BufWinEnter', 'WinEnter', \ 'TabEnter', 'WinNew', 'TabNew', 'VimEnter', \ ] augroup v_au if exists('s:enable_v_au') autocmd! unlet! s:enable_v_au echo 'disable visualize autocmds' else for event in events execute printf('autocmd %s * echomsg ''au %s'' expand(''<amatch>'')', event, event) endfor let s:enable_v_au = 1 echo 'enable visualize autocmds' endif augroup END endfunction command! VisualizeAutocmds call s:visualize_autocmds() " enable when vim is starting " call s:visualize_autocmds() function! s:pin_help_buffer() let is_help = &buftype == 'help' if is_help let w:pin_buf_type = 'help' return endif let is_not_pinned = get(w:, 'pin_buf_type', '') != 'help' if is_not_pinned return endif let bufnr = bufnr() for winnr in range(1, winnr('$')) let win_id = win_getid(winnr) if getwinvar(win_id, 'pin_buf_type') == '' edit # call win_gotoid(win_id) execute 'buffer' bufnr return endif endfor echomsg 'all buffers are pinned.' endfunction " function! s:dprint(line1, line2) " if &filetype !~ '\v^%(%(type|java)script(react)?|markdown|jsonc?|toml|dockerfile)$' " echo '[dprint] filetype ' .. &filetype .. ' is not suppported' " return " endif " let curpos = getpos('.')[1:2] " execute printf('%s,%s!dprint fmt --stdin %s', a:line1, a:line2, @%) " call cursor(curpos[0], curpos[1]) " endfunction " command! -range=% Dprint call s:dprint(<line1>, <line2>) function! s:cased_substitute(query, line1, line2) abort let [from, to] = split(a:query, '/') execute printf('silent! %s,%ss/\C%s/%s/g', a:line1, a:line2, toupper(from), toupper(to)) execute printf('silent! %s,%ss/\C%s/%s/g', a:line1, a:line2, toupper(from[0]) .. from[1:], toupper(to[0]) .. to[1:]) execute printf('silent! %s,%ss/\C%s/%s/g', a:line1, a:line2, tolower(from), tolower(to))) endfunction command! -range -nargs=* CasedSubstitute call s:cased_substitute(<q-args>, <line1>, <line2>) command! -range -nargs=* CS call s:cased_substitute(<q-args>, <line1>, <line2>) function! s:enable_autosave() abort autocmd InsertLeave,TextChanged,BufLeave <buffer> silent update endfunction let s:memo_path = expand('~/.local/share/memo.md') function! s:memo() abort if expand('%') ==# s:memo_path bdelete return endif execute 'edit' s:memo_path setlocal bufhidden=wipe noswapfile call s:enable_autosave() endfunction command! Memo call s:memo() nnoremap mo <Cmd>Memo<CR> if !has('nvim') function! s:silicon(line1, line2, args, highlight_lines) let cmd = ['silicon'] if &filetype != '' call add(cmd, '--language') call add(cmd, &filetype) endif " TODO: use args let output = $'~/Downloads/silicon-{strftime("%Y%m%d-%H%M%S")}.png' call add(cmd, '--font') call add(cmd, 'UDEV Gothic 35NF') call add(cmd, '--output') call add(cmd, output) let in_opts = { 'buf': bufnr() } if a:highlight_lines call add(cmd, '--highlight-lines') call add(cmd, a:line1 .. '-' .. a:line2) else let in_opts['top'] = a:line1 let in_opts['bot'] = a:line2 endif let opts = { \ 'in': in_opts, \ 'exit': {_->execute($'echo "[silicon] output to {output}"', '')} \ } call mi#job#start(cmd, opts) endfunction command! -range=% -bang Silicon call s:silicon(<line1>, <line2>, <q-args>, <bang>0) endif " skip autocmds after vim is started if !has('vim_starting') finish endif augroup vimrc autocmd! let g:vimsyn_embed='l' autocmd FileType vim syn match luaParen "(\|)" autocmd BufEnter *.sh setlocal filetype=bash autocmd BufEnter * call s:pin_help_buffer() autocmd WinLeave,WinClosed * unlet! w:pin_buf_type autocmd BufEnter * call s:syntax_off_on_heavy_file() " Highlight extra whitespaces " https://zenn.dev/kawarimidoll/articles/450a1c7754bde6 " u00A0 ' ' no-break space " u2000 ' ' en quad " u2001 ' ' em quad " u2002 ' ' en space " u2003 ' ' em space " u2004 ' ' three-per em space " u2005 ' ' four-per em space " u2006 ' ' six-per em space " u2007 ' ' figure space " u2008 ' ' punctuation space " u2009 ' ' thin space " u200A ' ' hair space " u200B '' zero-width space " u3000 ' ' ideographic (zenkaku) space highlight ExtraWhitespace ctermbg=darkmagenta guibg=darkmagenta autocmd VimEnter,WinEnter * if !exists('w:highlight_extra_whitespace') \ | let w:highlight_extra_whitespace = matchadd('ExtraWhitespace', "[\u00A0\u2000-\u200B\u3000]") \ | endif autocmd ColorScheme * call s:apply_user_highlight() autocmd VimEnter * ++once call s:apply_user_highlight() " https://zenn.dev/kawarimidoll/articles/5490567f8194a4 " this not works in ftplugin autocmd BufNew,BufEnter * if &filetype == 'markdown' | syntax match markdownError '\w\@<=\w\@=' | endif autocmd BufNewFile * ++nested call mi#open#reopen_with_lnum() " https://github.com/Shougo/shougo-s-github/blob/1327ad8140fc5f47ad15f316d55b2bed6dfd6ca5/vim/rc/options.rc.vim#L87-L97 autocmd CmdlineEnter * \ : let s:save_iskeyword = &l:iskeyword \ | setlocal iskeyword+=. \ | setlocal iskeyword+=- \ | setlocal iskeyword+=+ \ | setlocal iskeyword-=/ \ | setlocal iskeyword-=\: \ | setlocal iskeyword-=: autocmd CmdlineLeave * \ let &l:iskeyword = s:save_iskeyword if has('nvim') " https://jdhao.github.io/2020/05/22/highlight_yank_region_nvim/ autocmd TextYankPost * silent! lua vim.highlight.on_yank({ timeout=500 }) autocmd TermOpen * if exists('w:highlight_extra_whitespace') && exists('b:terminal_job_id') \ | silent! call matchdelete(w:highlight_extra_whitespace) \ | endif else " https://github.com/NI57721/dotfiles/blob/a695ab1d29465dc54254c933f13ac46911a07afd/.vimrc#L255-L260 autocmd Filetype xml,html inoremap <buffer><expr> </ \ &completeopt=~'noinsert\\|noselect' ? '</<c-x><c-o><c-n><c-y>' : '</<c-x><c-o><c-y>' " autocmd WinEnter,BufEnter * setlocal statusline=%!mi#statusline#active() " autocmd WinLeave,BufLeave * setlocal statusline=%!mi#statusline#inactive() " set statusline=%!mi#statusline#horizontal_line() set statusline=─ set fillchars+=stl:─,stlnc:─ set laststatus=0 autocmd Filetype * ++once \ execute 'colorscheme' mi#utils#pick_one(['slate', 'habamax', 'lunaperche', 'sorbet', \ 'murphy', 'retrobox', 'wildcharm', 'zaibatsu']) \ | doautocmd ColorScheme autocmd Filetype typescript,typescriptreact,javascript,javascriptreact,markdown,json,jsonc \ let b:fmt_cmd = $'deno fmt --ext {expand("%:e")} -' autocmd Filetype sql let b:fmt_cmd = 'sql-formatter --config ~/dotfiles/.config/sql_formatter/sql_formatter.json' autocmd Filetype nix let b:fmt_cmd = 'alejandra -q -' autocmd Filetype gleam let b:fmt_cmd = 'gleam format --stdin' autocmd Filetype vim let b:symbol_list = [ \ '..=', '=>', '<=', '==', '->', \ '==#', '==?', '!=#', '!=?', '>#', '>?', '>=#', '>=?', \ '<#', '<?', '<=#', '<=?', '=~#', '=~?', '!~#', '!~?', \] autocmd Filetype typescript,typescriptreact,javascript,javascriptreact let b:symbol_list = ['=>', '==='] autocmd Filetype gleam let b:symbol_list = ['->', '|>', '<>', '<-', '_ ->'] autocmd FileType * call mi#cmp#apply_syn_keywords_dict() endif " {{{ restore-cursor " :h restore-cursor autocmd BufReadPost * \ if line("'\"") > 1 && line("'\"") <= line("$") && &ft !~# 'commit' \ | execute 'normal! g`"zz' \ | endif " }}} " {{{ ensure_dir " https://vim-jp.org/vim-users-jp/2011/02/20/Hack-202.html function! s:ensure_dir(dir, force) if !isdirectory(a:dir) && (a:force || confirm($'"{a:dir}" does not exist. Create?', "y\nN")) call mkdir(iconv(a:dir, &encoding, &termencoding), 'p') endif endfunction autocmd BufWritePre * call s:ensure_dir(expand('<afile>:p:h'), v:cmdbang) " }}} " {{{ validate_filename " https://zenn.dev/vim_jp/articles/f02adb4f325e51 " :h interrupt function! s:validate_filename(filename, force) abort if a:force return endif const invalid_chars = '!&()[]{}<>^*=+:;''",`~?|' for char in split(invalid_chars, '\zs') if stridx(a:filename, char) >= 0 echoerr 'Invalid filename:' a:filename call interrupt() endif endfor const valid_extension = '\.\?[[:alnum:]]\+$' if a:filename !~ valid_extension echoerr 'Invalid filename:' a:filename call interrupt() endif endfunction autocmd BufWritePre * call s:validate_filename(expand('<afile>:p'), v:cmdbang) " }}} " {{{ hist_clean " https://blog.atusy.net/2023/07/24/vim-clean-history/ function! s:hist_clean() abort const cmd = histget(':', -1) if cmd =~# '^e\%[dit]!\?$' || cmd =~# '^enew\?$' || cmd =~# '^[wx]\?q\?a\?!\?$' call histdel(':', -1) endif endfunction autocmd ModeChanged c:* call s:hist_clean() " }}} " https://zenn.dev/kawarimidoll/articles/33cf46fae69809 function! s:check_prefix_match_files() abort let fname = expand('<afile>') let dname = fnamemodify(fname, ':h') let files_in_dir = split(glob(dname == '.' ? '*' : $'{dname}/*'), "\n") let possible = filter(copy(files_in_dir), $'v:val =~# "^\\V{fname}"') if empty(possible) return endif let choice = confirm($'"{fname}" does not exist. Do you want to open file below?', \ possible->copy()->map({k, v -> $'&{k+1} {v}'})->join("\n"), 0) if choice == 0 return endif call timer_start(0, {->execute($'edit {possible[choice - 1]} | bwipeout! #')}) endfunction autocmd BufNewFile * call s:check_prefix_match_files() augroup END call timer_start(100, {->execute('source ~/dotfiles/.vim/ready.vim')}) if !has('nvim') " ref: https://zenn.dev/vim_jp/articles/20240304_ekiden_disable_plugin let s:save_rtp = &runtimepath set runtimepath-=$VIMRUNTIME autocmd SourcePre */plugin/* ++once let &runtimepath = s:save_rtp endif