" .vimrc " augroup: vimrc-startuptime {{{1 if has('vim_starting') && has('reltime') let s:startuptime = reltime() augroup vimrc-startuptime autocmd! autocmd VimEnter * echomsg 'startuptime:' . reltimestr(reltime(s:startuptime)) augroup END endif " globals {{{1 let g:vimrc = { \ 'is_win': has('win32'), \ 'sep': !exists('+shellslash') || &shellslash ? '/' : '\', \} function! vimrc.cache(path, ...) abort let p = self.join(self.cache_dir, a:path) if a:0 && a:1 && !filewritable(p) call mkdir(p, 'p') endif return p endfunction function! vimrc.join(...) abort return join(map(copy(a:000), "substitute(v:val, '[/\\\\]\\+$', '', '')"), self.sep) endfunction function! vimrc.has_plugin(name) abort if has_key(g:, 'plugs') let plug = get(g:plugs, a:name, {}) return !empty(plug) && isdirectory(plug.dir) endif return &runtimepath =~? '\v' . escape(g:vimrc.sep, '\') . a:name endfunction function! vimrc.to_slash(path) abort return self.is_win ? substitute(a:path, '\\', '/', 'g') : a:path endfunction if g:vimrc.is_win let g:vimrc.vimfiles = expand(g:vimrc.join('~', 'vimfiles')) let g:vimrc.cache_dir = g:vimrc.join($LOCALAPPDATA, 'Vim') else let g:vimrc.vimfiles = expand(g:vimrc.join('~', '.vim')) let g:vimrc.cache_dir = g:vimrc.join($XDG_CACHE_HOME !=# '' ? $XDG_CACHE_HOME : expand(g:vimrc.join('~', '.cache')), 'vim') endif let g:user = { \ 'name': 'Akinori Hattori', \ 'email': 'hattya@gmail.com', \} function! user.format() abort return printf('%s <%s>', self.name, self.email) endfunction " encoding {{{1 if has('multi_byte') if g:vimrc.is_win if !has('gui_running') set termencoding=char endif let $LANG = 'ja_JP.UTF-8' set encoding=utf-8 elseif &encoding !=? 'utf-8' set encoding=japan endif scriptencoding utf-8 if has('iconv') " check for iconv supports euc-jisx0213 if iconv("\x87\x64\x87\x6a", 'cp932', 'euc-jisx0213') ==# "\xad\xc5\xad\xcb" let s:eucjp = 'euc-jisx0213,euc-jp' let s:jisx = 'iso-2022-jp-3' else let s:eucjp = 'euc-jp' let s:jisx = 'iso-2022-jp' endif " construct fileencodings let &fileencodings = 'ucs-bom,' . s:jisx if has('guess_encode') let &fileencodings = 'guess,' . &fileencodings endif if &encoding ==? 'utf-8' let &fileencodings .= ',' . s:eucjp . ',utf-8,cp932' elseif &encoding ==? 'cp932' let &fileencodings .= ',utf-8,' . s:eucjp elseif &encoding =~? '^euc-j' " euc-jp variants let &fileencodings .= ',utf-8,cp932' endif unlet s:eucjp unlet s:jisx endif endif " options {{{1 " vim options {{{2 if has('mouse') set mouse=a if &term =~# '^screen' set ttymouse=sgr endif endif set history=1000 set timeoutlen=500 set ttimeoutlen=0 if has('viminfo') let &viminfo = &viminfo . ',n' . g:vimrc.cache('viminfo') endif set wildignorecase " search options {{{2 if executable('jvgrep') set grepprg=jvgrep elseif executable('rg') set grepprg=rg\ --vimgrep elseif executable('ag') set grepprg=ag\ --vimgrep endif set helplang=ja,en set hlsearch set ignorecase set incsearch set smartcase set wrapscan " edit options {{{2 set autoindent set autoread set backspace=indent,eol,start set nobackup set completeopt=menuone,preview set noexpandtab if exists('+fixendofline') set nofixendofline endif set formatoptions-=M set formatoptions+=mBj set hidden if has('langmap') && exists('+langnoremap') set langnoremap endif set modeline set nrformats-=octal set nrformats+=alpha set omnifunc=syntaxcomplete#Complete set shiftwidth=4 set showmatch if v:version > 704 || v:version == 704 && has('patch088') set spelllang+=cjk endif if has('persistent_undo') set undofile let &undodir = g:vimrc.cache('undo', 1) endif set wildmenu " screen options {{{2 if has('multi_byte') && !has('termresponse') || &t_u7 ==# '' set ambiwidth=double endif if exists('+breakindent') set breakindent set breakindentopt=sbr set linebreak set showbreak=»\ endif set cmdheight=2 if exists('+colorcolumn') set colorcolumn=+1 endif set laststatus=2 set list set listchars=eol:¬,tab:»\ ,trail:-,extends:»,precedes:« set nonumber set ruler set scrolloff& set showcmd set statusline=%<%{expand('%:t')}\ %y%m%r%h%w%{'['.(&fenc!=''?&fenc:&enc).':'.&ff.']'}%=%l,%c%V%5P if has('termguicolors') set termguicolors if &term =~# '^screen' let &t_8f = "\e[38;2;%lu;%lu;%lum" let &t_8b = "\e[48;2;%lu;%lu;%lum" endif endif set title set visualbell set wrap " terminal options {{{2 if has('vim_starting') " change cursor style {{{3 if &term =~# '^\%(xterm\|screen\)' let &t_SI .= "\e[5 q" let &t_SR .= "\e[3 q" let &t_EI .= "\e[1 q" endif " change terminal title {{{3 if &term =~# '^screen' let &t_ts = "\e_" let &t_fs = "\e\\" endif " bracketed paste mode {{{3 if has('patch-8.0.0238') if &term =~# '^screen' let &t_BE = "\e[?2004h" let &t_BD = "\e[?2004l" let &t_PS = "\e[200~" let &t_PE = "\e[201~" endif else if has('patch-8.0.0210') set t_BE= endif if &term =~# '^\%(xterm\|screen\)' let &t_ti .= "\e[?2004h" let &t_te .= "\e[?2004l" let &pastetoggle = "\e[201~" noremap [200~ XTermPasteBegin('0i') inoremap [200~ XTermPasteBegin('') vnoremap [200~ XTermPasteBegin('c') cnoremap [200~ cnoremap [201~ function! XTermPasteBegin(rv) abort set paste return a:rv endfunction endif endif " improve vsplit {{{3 if &term =~# '^xterm' let &t_CS = "y" let &t_CV = "\e[%i%p1%d;%p2%ds" let &t_ti .= "\e[?6h\e[?69h" let &t_te .= "\e7\e[?69l\e[?6l\e8" endif " }}}3 endif " mappings {{{1 let mapleader = ',' nnoremap :nohlsearch inoremap u " environ {{{1 if g:vimrc.is_win let $PATHEXT = join(filter(split($PATHEXT, ';'), 'v:val !~? ''\.\%(lua\|p[ly]\|rb\)'''), ';') endif " augroup: vimrc-copyright {{{1 augroup vimrc-copyright autocmd! autocmd BufWritePre * call s:update_copyright_year() augroup END function! s:update_copyright_year() abort if &modified let pos = getpos('.') try let Y = strftime('%Y') silent execute 'g/\v\ccopyright\s*%(\(c\)\s*)?%(' . Y . ')@!\d{4}%(-' . Y . ')@!/s/\v(\d{4})%(-\d{4})?/\1-' . Y . '/' call histdel('/', -1) finally call setpos('.', pos) endtry endif endfunction " augroup: vimrc-misc {{{1 augroup vimrc-misc autocmd! " jump to last editing position autocmd BufReadPost * if line("'\"") && line("'\"") <= line('$') \ | execute 'normal! g`"' \ | endif " auto open/close QuickFix/location list window autocmd QuickFixCmdPost [^l]* cwindow | redraw! autocmd QuickFixCmdPost l* lwindow | redraw! " auto close preview window autocmd InsertLeave * if getcmdwintype() ==# '' && !pumvisible() \ | pclose \ | endif autocmd WinEnter * checktime autocmd InsertEnter * if &l:foldmethod ==# 'expr' \ | let b:foldinfo = [&l:foldmethod, &l:foldexpr] \ | setlocal foldmethod=manual foldexpr=0 \ | endif autocmd InsertLeave * if exists('b:foldinfo') \ | let [&l:foldmethod, &l:foldexpr] = b:foldinfo \ | unlet b:foldinfo \ | endif augroup END " load plugins {{{1 runtime bundle/vim-plug/plug.vim let g:plug_url_format = 'https://github.com/%s' let g:plug_window = 'tabnew' function! PlugBuild(info) abort if a:info.status !=# 'unchanged' || a:info.force if a:info.name ==# 'vimproc.vim' if g:vimrc.is_win let sfx = has('win64') ? 'win64' : 'win32' let dll = g:vimrc.join('lib', printf('vimproc_%s.dll', sfx)) call delete(dll) if filereadable(dll) call rename(dll, dll . '~') endif call vcvars#call('!nmake /nologo /f make_msvc.mak nodebug=1', '2010') else !make endif endif endif endfunction call plug#begin(g:vimrc.join(g:vimrc.vimfiles, 'bundle')) Plug 'cohama/lexima.vim' Plug 'cocopon/vaffle.vim', { 'on': 'Vaffle' } Plug 'ctrlpvim/ctrlp.vim' Plug 'hattya/license.vim' Plug 'hattya/vcs-info.vim' Plug 'hattya/vcvars.vim' Plug 'haya14busa/vim-migemo' Plug 'junegunn/vim-easy-align', { 'on': ['EasyAlign', 'LiveEasyAlign', '(EasyAlign)'] } Plug 'junegunn/vim-plug' Plug 'machakann/vim-swap' Plug 'mattn/emmet-vim' Plug 'mattn/gist-vim', { 'on': 'Gist' } Plug 'mattn/webapi-vim' Plug 'mhinz/vim-signify' Plug 'PProvost/vim-ps1' Plug 'prabirshrestha/async.vim' Plug 'prabirshrestha/vim-lsp' Plug 'saihoooooooo/glowshi-ft.vim' Plug 'Shougo/vimproc.vim' , { 'do': function('PlugBuild') } Plug 'thinca/vim-ambicmd' Plug 'thinca/vim-quickrun' Plug 'thinca/vim-ref' Plug 'thinca/vim-template' Plug 'thinca/vim-themis' Plug 'tpope/vim-surround' Plug 'tyru/capture.vim', { 'on': 'Capture' } Plug 'tyru/open-browser.vim' Plug 'vim-jp/autofmt' Plug 'vim-jp/vimdoc-ja' Plug 'vim-jp/vital.vim' Plug 'vim-scripts/autodate.vim' " status line Plug 'itchyny/lightline.vim' Plug 'mattn/hahhah-vim' " text objects Plug 'kana/vim-textobj-user' Plug 'kana/vim-textobj-diff' Plug 'kana/vim-textobj-indent' Plug 'kana/vim-textobj-syntax' Plug 'thinca/vim-textobj-between' " twitter Plug 'basyura/TweetVim' Plug 'basyura/twibill.vim' Plug 'mattn/favstar-vim', { 'on': 'FavStar' } " unite Plug 'Shougo/unite.vim' Plug 'tsukkee/unite-help' Plug 'tsukkee/unite-tag' Plug 'Shougo/unite-outline' " filetype: go Plug 'fatih/vim-go', { 'for': 'go' } Plug 'rhysd/vim-goyacc', { 'for': 'goyacc' } " filetype: javascript Plug 'pangloss/vim-javascript', { 'for': 'javascript' } " filetype: markdown Plug 'tpope/vim-markdown', { 'for': 'markdown' } " filetype: perl Plug 'vim-perl/vim-perl', { 'for': 'perl' } Plug 'c9s/perlomni.vim', { 'for': 'perl' } " filetype: python Plug 'davidhalter/jedi-vim', { 'for': 'python' } Plug 'hattya/python-indent.vim', { 'for': 'python' } " filetype: rst Plug 'gu-fan/riv.vim', { 'for': 'rst' } " filetype: tmux Plug 'ericpruitt/tmux.vim', { 'for': 'tmux', 'rtp': 'vim' } " filetype: toml Plug 'cespare/vim-toml', { 'for': 'toml' } " filetype: vim Plug 'vim-jp/syntax-vim-ex', { 'for': 'vim' } Plug 'thinca/vim-ft-vim_fold', { 'for': 'vim' } " color scheme Plug 'cocopon/iceberg.vim' Plug 'tomasr/molokai' Plug 'vim-scripts/pyte' for s:p in split(glob(g:vimrc.join(g:plug_home, '*'), 1), '\n') if !has_key(g:plugs, fnamemodify(s:p, ':t')) execute "Plug '" . s:p . "'" endif endfor unlet s:p call plug#end() delcommand PlugUpgrade " color scheme {{{1 if has('gui_running') || &t_Co == 256 if g:vimrc.has_plugin('iceberg.vim') colorscheme iceberg elseif g:vimrc.has_plugin('molokai') let g:molokai_original = 0 colorscheme molokai endif endif " plugin: ambicmd {{{1 if g:vimrc.has_plugin('vim-ambicmd') cnoremap ambicmd#expand("\") cnoremap ambicmd#expand("\") cnoremap ambicmd#expand("\") augroup vimrc-plugin-ambicmd autocmd! autocmd CmdwinEnter * call s:init_cmdwin() augroup END function! s:init_cmdwin() abort inoremap ambicmd#expand("\") inoremap ambicmd#expand("\") startinsert! endfunction endif " plugin: autodate {{{1 if g:vimrc.has_plugin('autodate.vim') let g:autodate_format = '%Y-%m-%d' let g:autodate_keyword_post = '$' endif " plugin: autofmt {{{1 if g:vimrc.has_plugin('autofmt') set formatexpr=autofmt#japanese#formatexpr() let g:autofmt_allow_over_tw = 1 endif " plugin: chagelog {{{1 let g:changelog_username = g:user.format() " plugin: ctrlp {{{1 if g:vimrc.has_plugin('ctrlp.vim') let g:ctrlp_map = '' let g:ctrlp_cache_dir = g:vimrc.cache('ctrlp', 1) let g:ctrlp_user_command = { \ 'types': { \ 'git': ['.git', 'cd %s && git ls-files -co --exclude-standard'], \ 'hg': ['.hg', 'hg --cwd %s status -madcun'], \ }, \} let g:ctrlp_open_multiple_files = 'tjr' let g:ctrlp_key_loop = 1 nnoremap CtrlP nmap CtrlP nnoremap CtrlP :CtrlP nnoremap CtrlPb :CtrlPBuffer nnoremap CtrlPm :CtrlPMRU endif " plugin: eazy-align {{{1 if g:vimrc.has_plugin('vim-easy-align') vmap ga (EasyAlign) nmap ga (EasyAlign) endif " plugin: emmet {{{1 if g:vimrc.has_plugin('emmet-vim') let g:user_emmet_leader_key = '' let g:user_emmet_settings = { \ 'indentation': repeat(' ', 2), \} endif " plugin: gist {{{1 if g:vimrc.has_plugin('gist-vim') let g:gist_update_on_write = 2 endif " plugin: go {{{1 if g:vimrc.has_plugin('vim-go') let g:go_code_completion_enabled = 0 if executable('goimports') let g:go_fmt_command = 'goimports' endif let g:go_highlight_operators = 1 let g:go_highlight_functions = 1 let g:go_highlight_methods = 1 let g:go_highlight_structs = 1 let g:go_highlight_build_constraints = 1 let g:go_template_autocreate = 0 let g:go#use_vimproc = 0 endif " plugin: jedi {{{1 if g:vimrc.has_plugin('jedi-vim') let g:jedi#auto_vim_configuration = 0 let g:jedi#popup_on_dot = 0 let g:jedi#rename_command = 'R' let g:jedi#show_call_signatures = 0 endif " plugin: license {{{1 if g:vimrc.has_plugin('license.vim') let g:license_shiftwidth = 3 let g:license_textwidth = 68 endif " plugin: lightline {{{1 let g:lightline = { \ 'colorscheme': 'Tomorrow', \ 'mode_map': { \ 'c': 'NORMAL', \ }, \ 'active': { \ 'left': [ \ ['mode', 'paste'], \ ['readonly', 'filename', 'modified'], \ ], \ }, \ 'component_function': {}, \ 'vimrc': {}, \} if get(g:, 'colors_name', '') ==# 'iceberg' let g:lightline.colorscheme = 'iceberg' endif if g:vimrc.has_plugin('vcs-info.vim') function! LightlineVCS() abort if winwidth(0) < 100 return '' endif let vcs = g:lightline.vimrc.vcs let buf = [bufnr('%'), bufname('%')] if empty(vcs) || vcs.buf != buf || str2float(reltimestr(reltime(vcs.last))) > 3 call extend(vcs, { \ 'text': '', \ 'buf': buf, \ 'last': reltime(), \}) let info = vcs_info#get() if !empty(info) let vcs.text = info.head if info.action !=# '' let vcs.text .= ':' . info.action endif endif endif return vcs.text endfunction let g:lightline.vimrc.vcs = {} let g:lightline.component_function['vcs'] = 'LightlineVCS' call insert(g:lightline.active.left[1], 'vcs') endif " plugin: hahhah {{{1 if g:vimrc.has_plugin('hahhah-vim') function! LightlineHahHah() abort if winwidth(0) < 100 return '' endif let hahhah = g:lightline.vimrc.hahhah if empty(hahhah) || hahhah.i == 4 call extend(hahhah, { \ 'text': hahhah#get_text(), \ 'i': 0, \}) endif let hahhah.i += 1 return hahhah.text endfunction let g:lightline.vimrc.hahhah = {} let g:lightline.component_function['hahhah'] = 'LightlineHahHah' call add(g:lightline.active.left[1], 'hahhah') endif " plugin: lsp {{{1 if g:vimrc.has_plugin('vim-lsp') function! vimrc.lsp() abort if empty(lsp#get_whitelisted_servers()) return '' endif setlocal omnifunc=lsp#complete map (lsp-definition) map K (lsp-hover) return 'setl ofu< | mapc ' endfunction augroup vimrc-plugin-lsp if executable('clangd') autocmd User lsp_setup call lsp#register_server({ \ 'name': 'clangd', \ 'cmd': {-> ['clangd']}, \ 'whitelist': ['c', 'cpp', 'objc', 'objcpp'], \ 'root_uri': {-> s:root_uri('.git', '.hg')}, \}) endif if executable('gopls') autocmd User lsp_setup call lsp#register_server({ \ 'name': 'gopls', \ 'cmd': {-> ['gopls']}, \ 'whitelist': ['go'], \ 'root_uri': {-> s:root_uri('.git', '.hg')}, \}) endif if executable('typescript-language-server') autocmd User lsp_setup call lsp#register_server({ \ 'name': 'typescript-language-server', \ 'cmd': {-> [&shell, &shellcmdflag, 'typescript-language-server --stdio']}, \ 'root_uri': {-> s:root_uri('tsconfig.json', 'package.json', '.git', '.hg')}, \}) endif augroup END function! s:root_uri(...) abort let root = expand('%:p:h') let prev = '' while root !=# prev for name in a:000 if getftype(g:vimrc.join(root, name)) !=# '' return lsp#utils#path_to_uri(root) endif endfor let prev = root let root = fnamemodify(root, ':h') endwhile return lsp#utils#get_default_root_uri() endfunction endif " plugin: matchit {{{1 runtime macros/matchit.vim " plugin: netrw {{{1 let g:netrw_home = g:vimrc.cache('netrw', 1) " plugin: quickrun {{{1 if g:vimrc.has_plugin('vim-quickrun') let g:quickrun_config = { \ '_': { \ 'runner/vimproc/updatetime': 40, \ }, \ 'python.test': { \ 'command': 'python', \ 'exec': '%c -B -m unittest discover -s %s:h -p %s:t', \ }, \} if has('job') let g:quickrun_config._.runner = 'job' elseif g:vimrc.has_plugin('vimproc.vim') let g:quickrun_config._.runner = 'vimproc' endif if g:vimrc.is_win let g:quickrun_config._['hook/shebang/enable'] = 0 let g:quickrun_config._['hook/output_encode/encoding'] = &termencoding endif endif " plugin: ref {{{1 if g:vimrc.has_plugin('vim-ref') let g:ref_cache_dir = g:vimrc.cache('ref', 1) endif " plugin: riv {{{1 if g:vimrc.has_plugin('riv.vim') let g:riv_file_link_style = 2 let g:riv_disable_folding = 1 endif " plugin: swap {{{1 if g:vimrc.has_plugin('vim-swap') omap i, (swap-textobject-i) xmap i, (swap-textobject-i) omap a, (swap-textobject-a) xmap a, (swap-textobject-a) endif " plugin: template {{{1 if g:vimrc.has_plugin('vim-template') augroup vimrc-plugin-template autocmd! autocmd FileType * execute 'TemplateLoad /filetype/' . &l:filetype autocmd User plugin-template-loaded call s:template_loaded() augroup END function! s:template_loaded() abort let pos = getpos('.') silent %s/<%=\(.\{-}\)%>/\=eval(submatch(1))/ge call histdel('/', -1) call cursor(1, 1) if search('<+CURSOR+>') normal! zv"_da> else call setpos('.', pos) endif endfunction endif " plugin: TweetVim {{{1 if g:vimrc.has_plugin('TweetVim') let g:tweetvim_config_dir = g:vimrc.cache('tweetvim', 1) let g:tweetvim_expand_t_co = 1 endif " plugin: unite {{{1 if g:vimrc.has_plugin('unite.vim') let g:unite_data_directory = g:vimrc.cache('unite', 1) call unite#custom#profile('default', 'context', { \ 'prompt': "'-')/ ", \ 'start_insert': '1', \ 'direction': 'botright', \}) call unite#custom#profile('files', 'substitute_patterns', { \ 'pattern': '[~.:]\@1 nmap u [unite] nnoremap [unite] :Unite nnoremap [unite]a :Unite -profile-name=files file file/new buffer file_mru nnoremap [unite]f :Unite -profile-name=files file file/new nnoremap [unite]r :Unite -profile-name=files file_rec/async:! nnoremap [unite]m :Unite -profile-name=files file_mru nnoremap [unite]b :Unite -immediately buffer nnoremap [unite]t :Unite -immediately tab:no-current nnoremap [unite]w :Unite -immediately window:no-current nnoremap [unite]T :Unite tag nnoremap [unite]h :Unite help nnoremap [unite]o :Unite outline nnoremap [unite]s :Unite source nnoremap [unite]g :Unite grep nnoremap [unite]/ :Unite line endif " plugin: zip {{{1 let g:loaded_zipPlugin = 1 let g:loaded_zip = 1