" ======================================== " プラグインのインストール " ======================================== call plug#begin('~/.vim/plugged') " カラースキーム Plug 'eihigh/vim-aomi-grayscale' Plug 'chriskempson/base16-vim' Plug 'cocopon/iceberg.vim' " モーション / オペレータ Plug 'haya14busa/vim-edgemotion' Plug 'haya14busa/vim-asterisk' Plug 'rhysd/clever-f.vim' Plug 'kana/vim-textobj-user' Plug 'sgur/vim-textobj-parameter' Plug 'kana/vim-textobj-indent' Plug 'hrsh7th/vim-searchx' " テキスト編集 Plug 'tyru/caw.vim' Plug 'machakann/vim-sandwich' Plug 'eihigh/vim-lexiv' " ファイラ / セレクタ Plug 'mattn/vim-findroot' Plug 'cocopon/vaffle.vim' Plug 'ctrlpvim/ctrlp.vim' Plug 'tacahiroy/ctrlp-funky' Plug 'yssl/QFEnter' " パッシブ拡張 " Plug 'wellle/context.vim' Plug 'obcat/vim-sclow' " 言語 Plug 'prabirshrestha/vim-lsp' Plug 'mattn/vim-lsp-settings' Plug 'prabirshrestha/asyncomplete.vim' Plug 'prabirshrestha/asyncomplete-lsp.vim' Plug 'mattn/ctrlp-lsp' Plug 'fatih/vim-go' " ウィンドウ Plug 't9md/vim-choosewin' " 小回り Plug 'vim-jp/vimdoc-ja' Plug 'Shougo/junkfile.vim' " ======================================== " 標準のキーマップの上書き・調整(いくらあってもよいとされている) " ======================================== " 検索ハイライト消去 nnoremap <silent> <Esc> :<C-u>nohlsearch<CR> " インサート中移動で undo block を中断しない inoremap <Left> <C-g>U<Left> inoremap <Right> <C-g>U<Right> " yank 範囲 nnoremap Y y$ " クリックしてもウィンドウの位置をなるべく保つ noremap <LeftMouse> <Cmd>call MyLeftMouse()<CR> map <2-LeftMouse> <LeftMouse> map <3-LeftMouse> <LeftMouse> map <4-LeftMouse> <LeftMouse> " Changelist map <Plug>(cgl) <Nop> map g; g;<Plug>(cgl) map g, g,<Plug>(cgl) map <Plug>(cgl); g;<Plug>(cgl) map <Plug>(cgl), g,<Plug>(cgl) " Asterisk map * <Plug>(asterisk-z*) map # <Plug>(asterisk-z#) map g* <Plug>(asterisk-gz*) map g# <Plug>(asterisk-gz#) " Lexiv inoremap <expr> " lexiv#quote_open('"') inoremap <expr> ' lexiv#quote_open("'") inoremap <expr> ` lexiv#backquote_open() inoremap <expr> { lexiv#paren_open('{') inoremap <expr> ( lexiv#paren_open('(') inoremap <expr> [ lexiv#paren_open('[') inoremap <expr> } lexiv#paren_close('}') inoremap <expr> ) lexiv#paren_close(')') inoremap <expr> ] lexiv#paren_close(']') " Asyncomplete inoremap <silent> <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>" inoremap <silent> <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>" inoremap <silent> <expr> <CR> (pumvisible() ? "\<C-y>" : "") . lexiv#paren_expand() " ======================================== " 標準にはない追加のキーマップ(少ないほどよいとされている) " ======================================== " 保存ショートカット nnoremap <cr> :<C-u>w<CR> " ウィンドウ管理 map - <Plug>(choosewin) map _ <C-w> noremap <C-w>_ :<C-u>below split<CR> noremap <C-w>- :<C-u>above split<CR> noremap <C-w>( :<C-u>lefta vsplit<CR> noremap <C-w>) :<C-u>rightb vsplit<CR> noremap <C-w>! ZZ " ターミナルからの脱出 tnoremap <Esc><Esc> <Esc> tnoremap <Esc>- <C-w>:<C-u>call choosewin#start(range(1, winnr('$')))<CR> tnoremap <Esc>n <C-w>N tnoremap <Esc>h <C-w>:hide \| wincmd p<CR> " z. でカーソル中央固定 set scrolloff=2 noremap <expr> z. &scrolloff == 99 ? ':setlocal scrolloff=2<CR>' : 'zz:setlocal scrolloff=99<CR>' " Sandwich let g:sandwich_no_default_key_mappings = 1 nmap sa <Plug>(sandwich-add) xmap sa <Plug>(sandwich-add) omap sa <Plug>(sandwich-add) nmap sd <Plug>(sandwich-delete-auto) xmap sd <Plug>(sandwich-delete) nmap sr <Plug>(sandwich-replace-auto) xmap sr <Plug>(sandwich-replace) " Edgemotion nmap g< <Plug>(edgemotion-k) xmap g< <Plug>(edgemotion-k) omap g< <Plug>(edgemotion-k) nmap g> <Plug>(edgemotion-j) xmap g> <Plug>(edgemotion-j) omap g> <Plug>(edgemotion-j) " Searchx nnoremap l <Cmd>call searchx#start({ 'dir': 1 })<cr> xnoremap l <Cmd>call searchx#start({ 'dir': 1 })<cr> " これ以上のキーマップは増やしたくないので本当はコマンドパレットを使いたいが " 仕方なく割り当てるやつ nnoremap hh :<C-u>CtrlPMixed<CR> nnoremap he :<C-u>e %:h<CR> nnoremap ht :<C-u>call ReuseShellOrCreate()<CR> nnoremap hs :<C-u>call VimGrepDir(findroot#find(), '')<Left><Left> nnoremap hg :<C-u>vimgrep '' **<Left><Left><Left><Left> nnoremap hr :<C-u>CtrlPMRU<CR> nnoremap hl :<C-u>CtrlPBuffer<CR> nnoremap hc :<C-u>botright copen<CR> " ======================================== " 本体機能の設定 " ======================================== " エンコード set encoding=utf-8 set fileencoding=utf-8 set fileencodings=utf-8,euc-jp,cp932 " 検索 set hlsearch set incsearch set ignorecase set smartcase " テキスト編集 set backspace=eol,indent,start set tabstop=3 set shiftwidth=3 set smartindent " 見た目 set nowrap set number set signcolumn=number set helplang=ja set termguicolors set equalalways " statusline常設 set laststatus=2 " 挙動 set autoread set autochdir " Abbreviation abbrev ret return " マウス set mouse=n " クリップボード " TODO " Esc の遅延解消 set ttimeoutlen=0 " undo 履歴 if isdirectory(expand('~/.cache/vim')) set undofile set undodir=~/.cache/vim/ endif " grepprg if executable('rg') set grepprg=rg\ --vimgrep set grepformat=%f:%l:%c:%m endif " NORMAL/INSERT でカーソル形状を変更 if &term =~ 'xterm' || &term == 'win32' let &t_SI = "\e[5 q" let &t_EI = "\e[2 q" else let &t_SI = "\<Esc>]50;CursorShape=1\x7" let &t_EI = "\<Esc>]50;CursorShape=0\x7" endif " ステータスラインをシュッとさせる " utf-8 以外の注意すべきエンコードなら強調する function! Stl_fenc() abort return &fenc == "utf-8" ? "" : "[".&fenc."]" endfunction set statusline=\ %m%=%{Stl_fenc()}\ %<%F\ " ======================================== " プラグイン機能の設定 " ======================================== " CtrlP " Searchx let g:searchx = {} let g:searchx.auto_accept = v:true let g:searchx.scrolloff = &scrolloff let g:searchx.scrolltime = 500 let g:searchx.nohlsearch = {} let g:searchx.nohlsearch.jump = v:true let g:searchx.markers = split(' HTSRMFGVXBDLCWZK', '.\zs') function g:searchx.convert(input) abort if a:input !~# '\k' return '\V' .. a:input endif return a:input[0] .. substitute(a:input[1:], '\\\@<! ', '.\\{-}', 'g') endfunction " Lexiv " デフォルトだと <cr> が補完確定のマッピングと " 衝突するので、無効にする(fork 元ではできない) let g:lexiv_no_default_key_mappings = 1 " LSP let g:lsp_async_completion = 1 let g:lsp_document_highlight_enabled = 0 let g:lsp_diagnostics_highlights_enabled = 1 let g:lsp_diagnostics_highlights_insert_mode_enabled = 1 let g:lsp_diagnostics_highlights_delay = 100 let g:lsp_diagnostics_signs_enabled = 0 let g:lsp_document_code_action_signs_enabled = 0 let g:lsp_diagnostics_virtual_text_enabled = 1 let g:lsp_diagnostics_virtual_text_delay = 100 let g:lsp_diagnostics_virtual_text_align = "right" let g:lsp_settings_enable_suggestions = 0 " vim-go " LSPに寄せるのでキーマップ無効 let g:go_def_mapping_enabled = 0 " Vaffle let g:vaffle_show_hidden_files = 1 " findroot " 'findroot#find()' 関数目的で入れるので、発火はさせない let g:findroot_mask = '__do_not_fire__' " clever-f let g:clever_f_across_no_line = 1 let g:clever_f_smart_case = 1 let g:clever_f_mark_char_color = 'Search' " Scrollbar " Choosewin " overlay 表示はターミナルで壊れる let g:choosewin_blink_on_land = 0 " ======================================== " Autocmd! " ======================================== autocmd! User lsp_buffer_enabled call s:on_lsp_buffer_enabled() autocmd! VimResized * wincmd = autocmd! WinLeave * call CurWinSaveView() autocmd! WinScrolled * call CurWinSaveViewOnScroll(expand('<afile>')) autocmd! WinClosed * wincmd p autocmd! TerminalOpen * setlocal bufhidden=hide autocmd! FileType vaffle call s:filetype_vaffle() autocmd! FileType go call s:filetype_go() autocmd! FileType qf call s:filetype_qf() autocmd! QuickFixCmdPost make,grep,grepadd,vimgrep botright copen " ======================================== " 自作関数 " ======================================== " vim-lsp " --------------------------------------- function! s:on_lsp_buffer_enabled() abort setlocal omnifunc=lsp#complete if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif nmap <buffer> gd <plug>(lsp-definition) nmap <buffer> gD <plug>(lsp-type-definition) nmap <buffer> gs <plug>(lsp-document-symbol) nmap <buffer> gS <plug>(lsp-workspace-symbol) nmap <buffer> gN <plug>(lsp-previous-diagnostic) nmap <buffer> gn <plug>(lsp-next-diagnostic) nmap <buffer> gh <plug>(lsp-hover) nmap <buffer> gc <plug>(lsp-rename) nmap <buffer> gl <plug>(lsp-code-lens) nmap <buffer> ga <plug>(lsp-code-action) xnoremap <buffer> ga :LspCodeAction<CR> nnoremap <buffer> gq :<C-u>LspStopServer<CR> " gofmt & goimports " autocmd! BufWritePre *.go call execute('LspDocumentFormatSync') | call execute('LspCodeActionSync source.organizeImports') endfunction " Vaffle " --------------------------------------- function! s:filetype_vaffle() abort nmap <buffer> <Left> <Plug>(vaffle-open-parent) nmap <buffer> <Right> <Plug>(vaffle-open-current) nmap <buffer> <End> <Plug>(vaffle-open-current) endfunction " Go " --------------------------------------- function! s:filetype_go() abort " Snippet にするか迷う abbrev <buffer> e_ err != nil abbrev <buffer> a_ append nnoremap g.t :<C-u>GoTest<CR> nnoremap g.f :<C-u>GoTestFunc<CR> endfunction " Quickfix " --------------------------------------- function! s:filetype_qf() abort nnoremap <buffer> <CR> <CR> nnoremap <buffer> o :<C-u>colder<CR> nnoremap <buffer> O :<C-u>cnewer<CR> endfunction " ディレクトリ指定 vimgrep " --------------------------------------- function! VimGrepDir(dir, word) abort let esc = escape(a:word, '"') exe 'vimgrep "' .. esc .. '" ' .. fnameescape(a:dir) .. '/**' endfunction " 既存の隠れた実行中のシェルがあれば再利用、なければ作成 " --------------------------------------- function! ReuseShellOrCreate() abort let bufinfo = getbufinfo()->filter({i, b -> \ getbufvar(b.bufnr, '&buftype') == 'terminal' && \ stridx(b.name, '!'.&shell) == 0 && \ b.changed == 1 && \ b.hidden == 1 \ }) if len(bufinfo) == 0 terminal ++curwin ++open return endif let bufnr = bufinfo[0].bufnr exe 'b '.bufnr endfunction " ウィンドウのカーソル位置を保存 " --------------------------------------- let g:win_views = {} function! CurWinSaveView() abort let g:win_views[winnr()] = winsaveview() endfunction " ウィンドウのカーソル位置を保存(スクロール時) " --------------------------------------- function! CurWinSaveViewOnScroll(winid) abort let winnr = win_id2win(a:winid) let g:win_views[winnr] = winsaveview() endfunction " ウィンドウのカーソル位置を復元(あれば) " --------------------------------------- function! CurWinRestView() abort if g:win_views->has_key(winnr()) call winrestview(g:win_views[winnr()]) endif endfunction " 上記を利用したクリックの挙動 " --------------------------------------- function! MyLeftMouse() abort let prev = winnr() exe "normal! \<LeftMouse>" let curr = winnr() " 同じウィンドウなら通常の挙動 if prev == curr return endif " 異なるウィンドウならカーソル位置を復元 call CurWinRestView() endfunction " 色の切り替え " --------------------------------------- function! Day() abort set background=light colorscheme aomi-grayscale hi link SclowSbar StatusLine hi link EndOfBuffer Ignore endfunction function! Night() abort set background=dark colorscheme aomi-grayscale hi Normal guibg=NONE hi link SclowSbar StatusLine hi link EndOfBuffer Ignore endfunction call plug#end() " 色の設定はプラグイン読み込み後に行う call Day()