" Set Vim's internal encodding. " Note: This option must be set before 'scriptencoding' is set. set encoding=utf-8 " Set this file's encoding. scriptencoding utf-8 " Global settings {{{1 " The ideom to get ||. {{{2 function! s:get_sid() abort return matchstr(expand(''), '\zs\d\+\ze_get_sid$') endfunction let s:SID = s:get_sid() let s:SNR = '' . s:SID . '_' delfunction s:get_sid " Global variables. {{{2 let g:MY_ENV = {} if has('mac') let g:MY_ENV.os = 'mac' elseif has('win32unix') || has('win32') || has('win64') let g:MY_ENV.os = 'windows' else let g:MY_ENV.os = 'unknown' endif let g:MY_ENV.vim_dir = !empty($XDG_CONFIG_HOME) ? expand('$XDG_CONFIG_HOME/vim') : \ g:MY_ENV.os ==# 'windows' ? expand('$HOME/vimfiles') : \ expand('$HOME/.vim') let g:MY_ENV.my_dir = g:MY_ENV.vim_dir . '/my' let g:MY_ENV.plug_dir = g:MY_ENV.vim_dir . '/plugged' let g:MY_ENV.cache_dir = !empty($XDG_CACHE_HOME) ? expand('$XDG_CACHE_HOME/vim') : \ g:MY_ENV.vim_dir . '/cache' let g:MY_ENV.undo_dir = g:MY_ENV.cache_dir . '/undo' let g:MY_ENV.backup_dir = g:MY_ENV.cache_dir . '/backup' let g:MY_ENV.swap_dir = g:MY_ENV.cache_dir . '/swap' let g:MY_ENV.yankround_dir = g:MY_ENV.cache_dir . '/yankround' for [s:k, s:v] in items(g:MY_ENV) if s:k =~# '_dir$' && !isdirectory(s:v) call mkdir(s:v, 'p') endif endfor unlet s:k s:v " The autogroup used in .vimrc {{{2 augroup Vimrc autocmd! augroup END " Note: |:autocmd| does not accept |-bar|. command! -nargs=* \ Autocmd \ autocmd Vimrc " Language {{{2 " Disable L10N. language messages C language time C " Options {{{1 " * Use |:set|, not |:setglobal|. " |:setglobal| does not set local options, so options are not set in " the starting buffer you specified as commandline arguments like " "$ vim ~/.vimrc". " Initialize all options with Vim's default values. set all& " Moving around, searching and patterns {{{2 set nowrapscan set incsearch set ignorecase set smartcase " Tags {{{2 set tags+=../tags \ tags+=../../tags set tagcase=match " Displaying text {{{2 set scrolloff=7 set wrap set linebreak set breakindent set breakindentopt+=sbr " Use let statement to avoid trailing space. let &showbreak = '> ' set sidescrolloff=20 set display=lastline " Use let statement to avoid trailing space. let &fillchars = 'stl: ,stlnc: ,vert: ,fold: ,diff: ' set cmdheight=2 set list let &listchars="eol:\u00ac,tab:\u25b8 ,extends:\u00bb,precedes:\u00ab" set conceallevel=2 set concealcursor=cnv " Syntax, highlighting and spelling {{{2 set background=dark set synmaxcol=200 set hlsearch " Execute nohlsearch to avoid highlighting last searched pattern when reloading " .vimrc. nohlsearch if exists('+termguicolors') if g:MY_ENV.os ==# 'mac' set termguicolors endif endif set t_Co=256 set nocursorline set colorcolumn=+1 " Multiple windows {{{2 set laststatus=2 set equalalways set eadirection=both set winminheight=0 set hidden set switchbuf=usetab " Multiple tabpages {{{2 set showtabline=2 " Terminal {{{2 set notitle " Using the mouse {{{2 set mouse= " GUI {{{2 if has('gui_running') set guifont=Ricty\ 14 " set guifontwide=Ricty\ 14 if exists('+antialias') set antialias endif set guioptions+=M \ guioptions+=c \ guioptions+=i \ guioptions-=A \ guioptions-=L \ guioptions-=P \ guioptions-=R \ guioptions-=T \ guioptions-=a \ guioptions-=b \ guioptions-=e \ guioptions-=h \ guioptions-=l \ guioptions-=m \ guioptions-=r set langmenu=none set winaltkeys=no set guicursor+=a:blinkon0 endif " Messages and info {{{2 set shortmess+=a \ shortmess+=s \ shortmess+=I \ shortmess+=c set showcmd set noshowmode set report=999 set confirm set belloff=all set helplang=en,ja " Selecting text {{{2 set clipboard= " Editing text {{{2 set undofile let &undodir = g:MY_ENV.undo_dir set textwidth=0 set backspace=indent,eol,start "TODO: set formatoptions+= set complete+=t set completeopt-=preview set pumheight=10 set noshowmatch set matchpairs+=<:> set nojoinspaces set nrformats-=octal " Tabs and indenting {{{2 " Note: you should also set them for each file types. " These following settings are global, used for unknown file types. set tabstop=4 set shiftwidth=4 set smarttab set softtabstop=4 set expandtab set autoindent set smartindent set copyindent set preserveindent " Folding {{{2 " TODO set foldlevelstart=0 set foldopen+=insert set foldmethod=marker " Diff mode {{{2 set diffopt+=vertical \ diffopt+=foldcolumn:3 " Mapping {{{2 set maxmapdepth=10 set notimeout set ttimeout set ttimeoutlen=100 " Reading and writing files {{{2 set nofixendofline " Note: if 'fileformat' is empty, the first item of 'fileformats' is used. set fileformats=unix,dos,mac " Note: these settings make one backup. If you want more backups, see " |'backupext'|. set backup let &backupdir = g:MY_ENV.backup_dir set autowrite " Instead, use 'confirm'. " set noautowriteall& set autoread " The swap file {{{2 " Note: 'dictionary' is swap files' directory. " '//' is converted to swap file's path. " If you are editing 'a/b.vim', Vim makes '{g:MY_ENV.cache_dir}/swap/a/b.vim'. let &directory = g:MY_ENV.swap_dir . '//' " Command line editing {{{2 set history=200 set wildignore+=*.o,*.obj,*.lib set wildignorecase set wildmenu " Executing external commands {{{2 set shell=zsh set keywordprg= " multi-byte characters {{{2 " Note: if 'fileencoding' is empty, 'encoding' is used. set fileencodings=utf-8,cp932,euc-jp set termencoding=utf-8 set ambiwidth=double " Misc. {{{2 set maxfuncdepth=50 set sessionoptions+=localoptions \ sessionoptions+=resize \ sessionoptions+=winpos let &viminfo .= ',n' . g:MY_ENV.cache_dir . '/viminfo' " Note: List of options that may break plugins' behaviors. {{{2 " I will check these options in my plugins. " * autochdir (as much as possible) " * gdefault " * magic " * selection " * startofline " * whichwrap " I will not check these options in my plugins, and suppose that they are left " default. " * compatible " * cpoptions (i.e., do not use |use-cpo-save| ideom) " * edcompatible " * remap " * cedit (map to ) " Installed plugins {{{1 call plug#begin(g:MY_ENV.plug_dir) " Filetype-specific plugins are placed at the first letter of the filetype. " E.g., plugins for Vim Script are placed in "V", even if their name don't " begin with "V". " A {{{2 " Switch to related files. Plug 'kana/vim-altr' " Async job control and completion API for vim-lsp. " Plug 'prabirshrestha/async.vim' " Plug 'prabirshrestha/asyncomplete.vim' " Plug 'prabirshrestha/asyncomplete-lsp.vim' " Extend * and #. Plug 'haya14busa/vim-asterisk' " If a directory is missing, make it automatically. Plug 'mopp/autodirmake.vim' " Auto-format python code by using autopep8. Plug 'tell-k/vim-autopep8' " B {{{2 " C {{{2 " Capture the output of a command. Plug 'tyru/capture.vim' " Comment out. Plug 'tyru/caw.vim' " Integrate with clang-format, the formater for C/C++. Plug 'rhysd/vim-clang-format' " Show highlight. Plug 'cocopon/colorswatch.vim' " Write git commit message. Plug 'rhysd/committia.vim' " Make gui-only color schemes 256colors-compatible. Plug 'godlygeek/csapprox' " D {{{2 " E {{{2 " Align text. Plug 'junegunn/vim-easy-align' " Motion on speed. Plug 'easymotion/vim-easymotion' " F {{{2 " Makes folding text cool. Plug 'LeafCage/foldCC.vim' " G {{{2 " H {{{2 " Syntax for HCL. Plug 'b4b4r07/vim-hcl' " I {{{2 " Extend incremental search. Plug 'haya14busa/incsearch.vim' " Incremntal search on EasyMotion. Plug 'haya14busa/incsearch-easymotion.vim' " Show indent. Plug 'Yggdroot/indentLine' " J {{{2 " Modern JavaScript Plug 'pangloss/vim-javascript' " Extend J. Plug 'osyo-manga/vim-jplus' " Filetype JSON5 Plug 'GutenYe/json5.vim' " K {{{2 " L {{{2 " Insert parentheses, 'end' and so on. Plug 'cohama/lexima.vim' " Cool status line. Plug 'itchyny/lightline.vim' " LSP; Language Server Protocol " Plug 'prabirshrestha/vim-lsp' " M {{{2 " MoonScript Plug 'leafo/moonscript-vim' " N {{{2 " Improve behaviors of I, A and gI in Blockwise-Visual mode. Plug 'kana/vim-niceblock' " Awesome filer. Plug 'scrooloose/nerdtree' " Syntax highlighting for Nginx conf file. Plug 'chr4/nginx.vim' " O {{{2 " Extract expression and make assingment statement. Plug 'tek/vim-operator-assign' " Replace text without updating registers. Plug 'kana/vim-operator-replace' " Reverse text. Plug 'tyru/operator-reverse.vim' " Search in a specific region. Plug 'osyo-manga/vim-operator-search' " Shiffle text. Plug 'pekepeke/vim-operator-shuffle' " Sort text characterwise and linewise. Plug 'emonkak/vim-operator-sort' " Support to define user-defined operator. Plug 'kana/vim-operator-user' " Emacs' org-mode Plug 'jceb/vim-orgmode' " P {{{2 " Highlight matched parentheses. Plug 'itchyny/vim-parenmatch' " Pretty printing for Vim script. Plug 'thinca/vim-prettyprint' " Q {{{2 " Edit QuickFix and reflect to original buffers. Plug 'thinca/vim-qfreplace' " Highlight specified words. Plug 't9md/vim-quickhl' " Run anything. Plug 'thinca/vim-quickrun' " R {{{2 " Extend dot-repeat. Plug 'tpope/vim-repeat' " Integration with ripgrep, fast alternative of grep command. Plug 'jremmen/vim-ripgrep' " Rust the programming language. Plug 'rust-lang/rust.vim' " S {{{2 " Super surround. Plug 'machakann/vim-sandwich' " Judge Vim power. Plug 'thinca/vim-scouter' " Split one line format and Join multiline format. Plug 'AndrewRadev/splitjoin.vim' " Introduce user-defined mode. Plug 'kana/vim-submode' " Swap arguments. Plug 'machakann/vim-swap' " T {{{2 Plug 'osyo-manga/vim-textobj-blockwise' " Text object for comment. Plug 'thinca/vim-textobj-comment' " Text object for continuous line. Plug 'rhysd/vim-textobj-continuous-line' " Text object for entire file. Plug 'kana/vim-textobj-entire' " Text object for function. Plug 'kana/vim-textobj-function' " Text object for indent. Plug 'kana/vim-textobj-indent' " Text object for last inserted text. Plug 'rhysd/vim-textobj-lastinserted' " Text object for last pasted text. Plug 'gilligan/textobj-lastpaste' " Text object for last searched pattern. Plug 'kana/vim-textobj-lastpat' " Text object for line. Plug 'kana/vim-textobj-line' " Text object for parameter. Plug 'sgur/vim-textobj-parameter' " Text object for space. Plug 'saihoooooooo/vim-textobj-space' " Text object for syntax. Plug 'kana/vim-textobj-syntax' " Text object for URL. Plug 'mattn/vim-textobj-url' " Support to define user-defined text object. Plug 'kana/vim-textobj-user' " Text object for words in words. Plug 'h1mesuke/textobj-wiw' " TOML. Plug 'cespare/vim-toml' " TypeScript Plug 'leafgarland/typescript-vim' " U {{{2 " V {{{2 " Vim documentation in Japanese. Plug 'vim-jp/vimdoc-ja' " W {{{2 " Adjust window size. Plug 'rhysd/vim-window-adjuster' " X {{{2 " Y {{{2 " Remember yank history and paste them. Plug 'LeafCage/yankround.vim' " Z {{{2 " Mine {{{2 Plug g:MY_ENV.my_dir call plug#end() " Autocommands {{{1 Autocmd VimResized * wincmd = " Calculate 'numberwidth' to fit file size. " Note: extra 2 is the room of left and right spaces. Autocmd BufEnter,WinEnter,BufWinEnter * \ let &l:numberwidth = len(line('$')) + 2 " Syntax highlight for .vimrc {{{2 Autocmd Filetype vim \ if expand('%') =~? 'vimrc' | call s:highlight_vimrc() | endif function! s:highlight_vimrc() abort " Autocmd syn keyword vimrcAutocmd Autocmd skipwhite nextgroup=vimAutoEventList " Plugin manager command syn keyword vimrcPluginManager Plug hi def link vimrcAutocmd vimAutocmd hi def link vimrcPluginManager vimCommand endfunction Autocmd ColorScheme ocean call s:extra_highlight() function! s:extra_highlight() abort if &background != 'dark' return endif hi! link YankRoundRegion DiffChange hi! link OperatorSandwichBuns DiffChange hi! link OperatorSandwichStuff DiffChange hi! link OperatorSandwichDelete DiffChange hi! link OperatorSandwichAdd OperatorSandwichBuns hi EasyMotionShade guifg=#4d4d4d guibg=NONE gui=NONE cterm=NONE hi EasyMotionTarget guifg=#ff7100 guibg=NONE gui=underline cterm=underline hi! link EasyMotionMoveHL IncSearch endfunction " Mappings {{{1 " Fix the search direction. {{{2 nnoremap gn v:searchforward ? 'gn' : 'gN' onoremap gn v:searchforward ? 'gn' : 'gN' xnoremap gn v:searchforward ? 'gn' : 'gN' nnoremap gN v:searchforward ? 'gN' : 'gn' onoremap gN v:searchforward ? 'gN' : 'gn' xnoremap gN v:searchforward ? 'gN' : 'gn' nnoremap n v:searchforward ? 'n' : 'N' onoremap n v:searchforward ? 'n' : 'N' xnoremap n v:searchforward ? 'n' : 'N' nnoremap N v:searchforward ? 'N' : 'n' onoremap N v:searchforward ? 'N' : 'n' xnoremap N v:searchforward ? 'N' : 'n' nnoremap & :%&& xnoremap & :%&& " Registers and macros. {{{2 " Access an resister in the same way in Insert and Commandline mode. nnoremap " xnoremap " " Paste clipboard content with 'paste' enabled function! s:paste_clipboard_content_with_paste_opt() abort let old_paste = &paste set paste set pastetoggle=(pastetoggle) if old_paste return "\+" else " 'paste' was off when the function was called. Then, 'paste' will be " disabled via 'pastetoggle'. return "\+\(pastetoggle)" endif endfunction " Automatically enable 'paste' and disable it after pasting clipboard's " content. inoremap + paste_clipboard_content_with_paste_opt() let @j = 'j.' let @k = 'k.' let @n = 'n.' nnoremap @N N. " Repeat the last executed macro as many times as possible. " a => all " Note: "let @a = '@@'" does not work well. nnoremap @a 9999@@ " Execute the laste executed macro again. nnoremap ` @@ " Emacs like key mappings in Insert and CommandLine mode. {{{2 function! s:go_to_beginning_of_line() abort if col('.') == match(getline('.'), '\S') + 1 return repeat("\U\", col('.') - 1) else return (col('.') < match(getline('.'), '\S')) ? \ repeat("\U\", match(getline('.'), '\S') - col('.') + 1) : \ repeat("\U\", col('.') - 1 - match(getline('.'), '\S')) endif endfunction inoremap " Go elsewhere without deviding the undo history. inoremap go_to_beginning_of_line() inoremap repeat('U', col('$') - col('.')) inoremap U inoremap U " Delete something deviding the undo history. inoremap u inoremap u cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap inoremap cnoremap inoremap function! s:my_gA() let line = getline('.') if match(line, ';;$') != -1 " For OCaml. return "A\U\\U\" elseif match(line, '[,;)]$') != -1 return "A\U\" else return 'A' endif endfunction nnoremap gA my_gA() " QuickFix or location list. {{{2 nnoremap bb :cc nnoremap bn :=v:count1cnext nnoremap bp :=v:count1cprevious nnoremap bf :cfirst nnoremap bl :clast nnoremap bS :colder nnoremap bs :cnewer " Operators {{{2 " Throw deleted text into the black hole register ("_). nnoremap c "_c xnoremap c "_c nnoremap C "_C xnoremap C "_C nnoremap g= = onoremap g= = xnoremap g= = nnoremap ml gu onoremap ml gu xnoremap ml gu nnoremap mu gU onoremap mu gU xnoremap mu gU nnoremap gu onoremap gu xnoremap gu nnoremap gU onoremap gU xnoremap gU xnoremap u xnoremap U xnoremap x "_x nnoremap Y y$ " In Blockwise-Visual mode, select text linewise. " In default, select text characterwise, neither blockwise nor linewise. xnoremap Y mode() ==# 'V' ? 'y' : 'Vy' " Swap the keys entering Replace mode and Visual-Replace mode. nnoremap R gR nnoremap gR R nnoremap r gr nnoremap gr r nnoremap U " Motions {{{2 nnoremap H ^ onoremap H ^ xnoremap H ^ nnoremap L $ onoremap L $ xnoremap L $ nnoremap M % onoremap M % xnoremap M % nnoremap gw b onoremap gw b xnoremap gw b nnoremap gW B onoremap gW B xnoremap gW B nnoremap k gk onoremap k gk xnoremap k gk nnoremap j gj onoremap j gj xnoremap j gj nnoremap gk k onoremap gk k xnoremap gk k nnoremap gj j onoremap gj j xnoremap gj j nnoremap gff gF " Tabpages and windows. {{{2 function! s:move_current_window_to_tabpage() abort if winnr('$') == 1 " Leave the current window and open it in a new tabpage. " Because :wincmd T fails when the current tabpage has only one window. tab split else " Close the current window and re-open it in a new tabpage. wincmd T endif endfunction function! s:bdelete_bang_with_confirm() abort if s:getchar_with_prompt('Delete? (y/n) ') ==? 'y' bdelete! else echo 'Canceled' endif endfunction nnoremap tt :tabnew nnoremap tT :call move_current_window_to_tabpage() nnoremap tn :=(tabpagenr() + v:count1 - 1) % tabpagenr('$') + 1tabnext nnoremap tp :=(tabpagenr('$') * 10 + tabpagenr() - v:count1 - 1) % tabpagenr('$') + 1tabnext nnoremap tN :tabmove + nnoremap tP :tabmove - nnoremap tsh :leftabove vsplit nnoremap tsj :rightbelow split nnoremap tsk :leftabove split nnoremap tsl :rightbelow vsplit nnoremap tsH :topleft vsplit nnoremap tsJ :botright split nnoremap tsK :topleft split nnoremap tsL :botright vsplit nnoremap twh :leftabove vnew nnoremap twj :rightbelow new nnoremap twk :leftabove new nnoremap twl :rightbelow vnew nnoremap twH :topleft vnew nnoremap twJ :botright new nnoremap twK :topleft new nnoremap twL :botright vnew nnoremap th h nnoremap tj j nnoremap tk k nnoremap tl l nnoremap tH H nnoremap tJ J nnoremap tK K nnoremap tL L nnoremap tx x " r => manual resize. " R => automatic resize. nnoremap tRH _ nnoremap tRW nnoremap tRR _ nnoremap t= = nnoremap tq :bdelete nnoremap tQ :call bdelete_bang_with_confirm() nnoremap tc c nnoremap to o nnoremap tO :tabonly function! s:smart_open(command) abort if winwidth(winnr()) < 150 let modifiers = 'topleft' else let modifiers = 'vertical botright' endif try execute modifiers a:command catch echohl Error echo v:exception echohl None return endtry if &filetype ==# 'help' if &l:textwidth > 0 execute 'vertical resize' &l:textwidth endif " Help tags are often rust-justfied, moving the cursor to BoL. normal! 0 endif endfunction command! -nargs=+ -complete=command \ SmartOpen \ call s:smart_open() " Disable unuseful mappings. {{{2 " Avoid entering Select mode. nnoremap gh nnoremap gH " See below about `g`. nnoremap ZZ nnoremap ZQ " Help {{{2 " Search help. nnoremap :SmartOpen help " For writing Vim script. {{{2 if !v:vim_did_enter function! SourceThisFile() abort let filename = expand('%') if &filetype ==# 'vim' || expand('%:e') ==# 'vim' || filename =~# '\.g\?vimrc' if &filetype !=# 'vim' setfiletype vim endif update unlet! g:loaded_{expand('%<')} source % else echo filename ' is not a Vim Script.' endif endfunction endif nnoremap XV :tabedit $MYVIMRC nnoremap XX :call SourceThisFile() " See |numbered-function|. nnoremap XF :function {=v:count} nnoremap XM :messages " Misc. {{{2 onoremap gv :normal! gv " Swap : and ;. nnoremap ; : nnoremap : ; xnoremap ; : xnoremap : ; nnoremap @; @: xnoremap @; @: cnoremap ; : inoremap ; : " Since may be mapped to something else somewhere, it should be :map, not " :noremap. imap jk cmap jk nnoremap :nohlsearch nnoremap o :call insert_blank_line(0) nnoremap O :call insert_blank_line(1) function! s:insert_blank_line(offset) abort for i in range(v:count1) call append(line('.') - a:offset, '') endfor endfunction nnoremap w :write " Abbreviations {{{1 inoreabbrev retrun return inoreabbrev reutrn return inoreabbrev tihs this " Commands {{{1 " Set 'makeprg' to `ninja` if `build.ninja` exists in the current working " directory. Then, execute :make command. command! -bang -bar -nargs=* \ Make \ if filereadable('build.ninja') | \ let &makeprg = 'ninja' | \ endif | \ make " The current search pattern will not changed by :global in a user function. " See :Reverse's comment below. function! s:reverse_lines(from, to) abort execute printf("%d,%dg/^/m%d", a:from, a:to, a:from - 1) endfunction " Reverse a selected range in line-wise. " Note: directly calling `g/^/m` will overwrite the current search pattern with " '^' and highlight it, which is not expected. " :h autocmd-searchpat " :h :nohlsearch command! -bar -range=% \ Reverse \ call reverse_lines(, ) " ftplugin {{{1 " This command do the followings: " * Execute |:setlocal| for each options. " * Set information to restore the original setting to b:|undo_ftplugin|. " This command is used in ftplugin/*.vim. " Note: specify only single option. command! -nargs=+ \ FtpluginSetLocal \ call s:ftplugin_setlocal() function! s:ftplugin_setlocal(qargs) abort execute 'setlocal' a:qargs let option_name = substitute(a:qargs, '\L.*', '', '') if exists('b:undo_ftplugin') let b:undo_ftplugin .= '|setlocal ' . option_name . '<' else let b:undo_ftplugin = 'setlocal ' . option_name . '<' endif endfunction " Color scheme {{{1 " A command which changes color scheme with fall back. command! -bang -nargs=? \ ColorScheme \ call s:colorscheme(0, ) function! s:colorscheme(bang, name) abort try if get(g:, 'colors_name') isnot# a:name || a:bang execute 'colorscheme' a:name endif catch " Loading colorscheme failed. " The color scheme, "desert", is one of the built-in ones. Probably, it " will be loaded without any errors. colorscheme desert endtry endfunction ColorScheme! ocean " Plugins configuration {{{1 " Disable standard plugins. {{{2 let g:loaded_2html_plugin = 1 let g:loaded_getscriptPlugin = 1 let g:loaded_gzip = 1 let g:loaded_logiPat = 1 let g:loaded_matchparen = 1 let g:loaded_netrwPlugin = 1 let g:loaded_rrhelper = 1 let g:loaded_spellfile_plugin = 1 let g:loaded_tarPlugin = 1 let g:loaded_vimballPlugin = 1 let g:loaded_zipPlugin = 1 " altr {{{2 " For vim call altr#define('autoload/%.vim', 'doc/%.txt', 'plugin/%.vim') " For C and C++ call altr#define('%.c', '%.cpp', '%.cc', '%.h', '%.hh', '%.hpp') " Go to File Alternative nmap gfa (altr-forward) " asterisk {{{2 function! s:asterisk(ret, keeppos) let g:asterisk#keeppos = a:keeppos return a:ret endfunction " Do not keep the relative cursor position. nmap * asterisk('(asterisk-z*)', 0) omap * asterisk('(asterisk-z*)', 0) xmap * asterisk('(asterisk-z*)', 0) nmap g* asterisk('(asterisk-gz*)', 0) omap g* asterisk('(asterisk-gz*)', 0) xmap g* asterisk('(asterisk-gz*)', 0) " Keep the relative cursor position (use offset like /s+1). " Note: I fix the search direction in typing 'n' and 'N', so there is no " difference between '*' and '#'. nmap # asterisk('(asterisk-z*)', 1) omap # asterisk('(asterisk-z*)', 1) xmap # asterisk('(asterisk-z*)', 1) nmap g# asterisk('(asterisk-gz*)', 1) omap g# asterisk('(asterisk-gz*)', 1) xmap g# asterisk('(asterisk-gz*)', 1) " autodirmake {{{2 let g:autodirmake#msg_highlight = 'Question' " autopep8 {{{2 let g:autopep8_on_save = 1 let g:autopep8_disable_show_diff = 1 command! \ Autopep8Disable \ let g:autopep8_on_save = 0 " caw {{{2 let g:caw_no_default_keymappings = 1 nmap m// (caw:hatpos:toggle) xmap m// (caw:hatpos:toggle) nmap m/w (caw:wrap:comment) xmap m/w (caw:wrap:comment) nmap m/W (caw:wrap:uncomment) xmap m/W (caw:wrap:uncomment) nmap m/b (caw:box:comment) xmap m/b (caw:box:comment) " clang-format {{{2 let g:clang_format#auto_format = 1 Autocmd FileType javascript ClangFormatAutoDisable " easyalign {{{2 nmap = (EasyAlign) xmap = (EasyAlign) " easymotion {{{2 let g:EasyMotion_keys = 'asdfghweryuiocvbnmjkl;' let g:EasyMotion_space_jump_first = 1 let g:EasyMotion_do_shade = 0 let g:EasyMotion_do_mappings = 0 let g:EasyMotion_smartcase = 1 let g:EasyMotion_verbose = 0 let g:EasyMotion_startofline = 0 nmap f (easymotion-fl) omap f (easymotion-fl) xmap f (easymotion-fl) nmap F (easymotion-Fl) omap F (easymotion-Fl) xmap F (easymotion-Fl) omap t (easymotion-tl) xmap t (easymotion-tl) omap T (easymotion-Tl) xmap T (easymotion-Tl) " Note: Don't use the following key sequences! It is used 'vim-sandwich'. " * sa " * sd " * sr nmap ss (easymotion-s2) omap ss (easymotion-s2) xmap ss (easymotion-s2) nmap sw (easymotion-bd-w) omap sw (easymotion-bd-w) xmap sw (easymotion-bd-w) nmap sn (easymotion-n) omap sn (easymotion-n) xmap sn (easymotion-n) nmap sN (easymotion-N) omap sN (easymotion-N) xmap sN (easymotion-N) nmap sj (easymotion-j) omap sj (easymotion-j) xmap sj (easymotion-j) nmap sk (easymotion-k) omap sk (easymotion-k) xmap sk (easymotion-k) " foldcc {{{2 set foldtext=FoldCCtext() let g:foldCCtext_head = 'repeat(">", v:foldlevel) . " "' " incsearch {{{2 " let g:incsearch#magic = '\v' nmap / (incsearch-forward) omap / (incsearch-forward) xmap / (incsearch-forward) nmap ? (incsearch-backward) omap ? (incsearch-backward) xmap ? (incsearch-backward) nmap g/ (incsearch-stay) omap g/ (incsearch-stay) xmap g/ (incsearch-stay) " incsearch-easymotion {{{2 nmap s/ (incsearch-easymotion-stay) omap s/ (incsearch-easymotion-stay) xmap s/ (incsearch-easymotion-stay) nmap s? (incsearch-easymotion-stay) omap s? (incsearch-easymotion-stay) xmap s? (incsearch-easymotion-stay) nmap sg/ (incsearch-easymotion-stay) omap sg/ (incsearch-easymotion-stay) xmap sg/ (incsearch-easymotion-stay) " indentline {{{2 let g:indentLine_fileTypeExclude = ['help', 'chart'] " jplus {{{2 let g:jplus#input_config = { \ '__DEFAULT__': {'delimiter_format': ' %d '}, \ '__EMPTY__': {'delimiter_format': ''}, \ ' ': {'delimiter_format': ' '}, \ ',': {'delimiter_format': '%d '}, \ ';': {'delimiter_format': '%d '}, \ 'l': {'delimiter_format': ''}, \ 'L': {'delimiter_format': ''}, \ } nmap J (jplus-getchar) xmap J (jplus-getchar) nmap gJ (jplus-input) xmap gJ (jplus-input) " lexima {{{2 " TODO: work around cmap imap " To make .vimrc reloadable let g:lexima_no_default_rules = 1 call lexima#set_default_rules() " Note: lexima.vim cannot recognizes , so use in lexima.vim's " configuration. " For ruby's multiline comment. " =begin " =end call lexima#add_rule({ \ 'char': '', \ 'at': '\V\^=begin\>\s\*\%#', \ 'input_after': '=end', \ 'filetype': 'ruby', \ }) " lightline {{{2 let g:lightline = { \ 'colorscheme': 'jellybeans', \ 'active': { \ 'left': [['mode', 'paste'], ['readonly', 'filename', 'modified']], \ 'right': [['linenum'], ['fileencoding', 'fileformat', 'filetype']] \ }, \ 'inactive': { \ 'left': [['readonly', 'filename', 'modified']], \ 'right': [['linenum'], ['fileencoding', 'fileformat', 'filetype']] \ }, \ 'component_function': { \ 'linenum': s:SNR .. 'lightline_linenum', \ 'fileformat': s:SNR .. 'lightline_fileformat', \ }, \ 'mode_map': { \ 'n' : 'N', \ 'i' : 'I', \ 'R' : 'R', \ 'v' : 'V', \ 'V' : 'V-L', \ "\": 'V-B', \ 'c' : 'C', \ 's' : 'S', \ 'S' : 'S-L', \ "\": 'S-B', \ 't': 'T', \ }, \ 'tabline': { \ 'left': [['tabs']], \ 'right': [], \ }, \ 'tab': { \ 'active': ['tabnum', 'filename', 'modified'], \ 'inactive': ['tabnum', 'filename', 'modified'], \ }, \ } function! s:lightline_linenum() return line('.') . '/' . line('$') endfunction function! s:lightline_fileformat() if &fileformat ==# 'unix' return 'lf' elseif &fileformat ==# 'dos' return 'crlf' elseif &fileformat ==# 'mac' return 'cr' else return 'unknown' endif endfunction " vim-lsp {{{2 " TODO " niceblock {{{2 xmap I (niceblock-I) xmap gI (niceblock-gI) xmap A (niceblock-A) " operator-replace {{{2 nmap (operator-replace) omap (operator-replace) xmap (operator-replace) " operator-search {{{2 " Note: m/ is the prefix of comment out. nmap m? (operator-search) omap m? (operator-search) xmap m? (operator-search) " prettyprint {{{2 let g:prettyprint_indent = 2 let g:prettyprint_string = ['split'] let g:prettyprint_show_expression = 1 " qfreplace {{{2 nnoremap br :Qfreplace SmartOpen " quickhl {{{2 " TODO: CUI let g:quickhl_manual_colors = [ \ 'guifg=#101020 guibg=#8080c0 gui=bold', \ 'guifg=#101020 guibg=#80c080 gui=bold', \ 'guifg=#101020 guibg=#c08080 gui=bold', \ 'guifg=#101020 guibg=#80c0c0 gui=bold', \ 'guifg=#101020 guibg=#c0c080 gui=bold', \ 'guifg=#101020 guibg=#a0a0ff gui=bold', \ 'guifg=#101020 guibg=#a0ffa0 gui=bold', \ 'guifg=#101020 guibg=#ffa0a0 gui=bold', \ 'guifg=#101020 guibg=#a0ffff gui=bold', \ 'guifg=#101020 guibg=#ffffa0 gui=bold', \ ] nmap " (quickhl-manual-this) xmap " (quickhl-manual-this) nnoremap :nohlsearch QuickhlManualReset " quickrun {{{2 let g:quickrun_no_default_key_mappings = 1 if !exists('g:quickrun_config') let g:quickrun_config = {} endif let g:quickrun_config.cpp = { \ 'cmdopt': '--std=c++17 -Wall -Wextra', \ } let g:quickrun_config.d = { \ 'exec': 'dub run', \ } let g:quickrun_config.haskell = { \ 'exec': ['stack build', 'stack exec %{matchstr(globpath(".,..,../..,../../..", "*.cabal"), "\\w\\+\\ze\\.cabal")}'], \ } let g:quickrun_config.python = { \ 'command': 'python3', \ } nmap BB (quickrun) xmap BB (quickrun) " nnoremap BB make " repeat {{{2 nmap U (RepeatRedo) " Work around. vim-repeatの内部構造に大きく依存する。 " repeat#setregの呼び出しが(ほぼ)副作用を持たないことが必要 " Autoload vim-repeat immediately in order to make (RepeatRedo) available. " repeat#setreg() does nothing here. call repeat#setreg('', '') " ripgrep {{{2 " Workaround: do not open quickfix window. " exe g:rg_window_location 'copen' let g:rg_window_location = 'silent! echo' command! -nargs=* -complete=file -bar \ RG \ Rg " rust {{{2 let g:rustfmt_autosave = 1 " sandwich {{{2 " splitjoin {{{2 " Note: Don't use J{any sign}, 'Jl' and 'JL'. They will conflict with 'vim-jplus'. let g:splitjoin_split_mapping = '' let g:splitjoin_join_mapping = '' nnoremap JS :SplitjoinSplit nnoremap JJ :SplitjoinJoin " submode {{{2 " Global settings {{{3 let g:submode_always_show_submode = 1 let g:submode_keyseqs_to_leave = ['', ''] let g:submode_keep_leaving_key = 1 " yankround {{{3 call submode#enter_with('YankRound', 'nv', 'rs', 'gp', '(yankround-p)') call submode#enter_with('YankRound', 'nv', 'rs', 'gP', '(yankround-P)') call submode#map('YankRound', 'nv', 'rs', 'p', '(yankround-prev)') call submode#map('YankRound', 'nv', 'rs', 'P', '(yankround-next)') " swap {{{3 call submode#enter_with('Swap', 'n', 'r', 'g>', '(swap-next)') call submode#map('Swap', 'n', 'r', '<', '(swap-prev)') call submode#enter_with('Swap', 'n', 'r', 'g<', '(swap-prev)') call submode#map('Swap', 'n', 'r', '>', '(swap-next)') " Resizing a window (height) {{{3 call submode#enter_with('WinResizeH', 'n', '', 'trh') call submode#enter_with('WinResizeH', 'n', '', 'trh') call submode#map('WinResizeH', 'n', '', '+', '+') call submode#map('WinResizeH', 'n', '', '-', '-') " Resizing a window (width) {{{3 call submode#enter_with('WinResizeW', 'n', '', 'trw') call submode#enter_with('WinResizeW', 'n', '', 'trw') call submode#map('WinResizeW', 'n', '', '+', '>') call submode#map('WinResizeW', 'n', '', '-', '') " Super undo/redo {{{3 call submode#enter_with('Undo/Redo', 'n', '', 'gu', 'g-') call submode#map('Undo/Redo', 'n', '', 'u', 'g-') call submode#enter_with('Undo/Redo', 'n', '', 'gU', 'g+') call submode#map('Undo/Redo', 'n', '', 'U', 'g+') " swap {{{2 let g:swap_no_default_key_mappings = 1 " textobj-continuousline {{{2 let g:textobj_continuous_line_no_default_key_mappings = 1 omap aL (textobj-continuous-cpp-a) xmap aL (textobj-continuous-cpp-a) omap iL (textobj-continuous-cpp-i) xmap iL (textobj-continuous-cpp-i) Autocmd FileType vim omap aL (textobj-continuous-vim-a) Autocmd FileType vim xmap aL (textobj-continuous-vim-a) Autocmd FileType vim omap iL (textobj-continuous-vim-i) Autocmd FileType vim xmap iL (textobj-continuous-vim-i) " textobj-lastpaste {{{2 let g:textobj_lastpaste_no_default_key_mappings = 1 omap iP (textobj-lastpaste-i) xmap iP (textobj-lastpaste-i) omap aP (textobj-lastpaste-a) xmap aP (textobj-lastpaste-a) " textobj-space {{{2 let g:textobj_space_no_default_key_mappings = 1 omap a (textobj-space-a) xmap a (textobj-space-a) omap i (textobj-space-i) xmap i (textobj-space-i) " textobj-wiw {{{2 let g:textobj_wiw_no_default_key_mappings = 1 nmap (textobj-wiw-n) omap (textobj-wiw-n) xmap (textobj-wiw-n) nmap g (textobj-wiw-p) omap g (textobj-wiw-p) xmap g (textobj-wiw-p) nmap (textobj-wiw-N) omap (textobj-wiw-N) xmap (textobj-wiw-N) nmap g (textobj-wiw-P) omap g (textobj-wiw-P) xmap g (textobj-wiw-P) omap a (textobj-wiw-a) xmap a (textobj-wiw-a) omap i (textobj-wiw-i) xmap i (textobj-wiw-i) " window-adjuster {{{2 nnoremap tRw :AdjustScreenWidth nnoremap tRh :AdjustScreenHeight nnoremap tRr :AdjustScreenWidth AdjustScreenHeight " yankround {{{2 let g:yankround_dir = g:MY_ENV.cache_dir . '/yankround' let g:yankround_use_region_hl = 1 " Utilities {{{1 "" Wrapper of |getchar()|. function! s:getchar() let ch = getchar() while ch == "\" let ch = getchar() endwhile return type(ch) == v:t_number ? nr2char(ch) : ch endfunction "" Wrapper of |:echo| and |:echohl|. function! s:echo(message, ...) abort let highlight = get(a:000, 0, 'None') redraw execute 'echohl' highlight echo a:message echohl None endfunction "" Wrapper of |getchar()|. function! s:getchar_with_prompt(prompt) abort call s:echo(a:prompt) return s:getchar() endfunction "" Wrapper of |input()|. "" Only when it is used in a mapping, |inputsave()| and |inputstore()| are "" required. function! s:input(...) abort call inputsave() let result = call('input', a:000) call inputrestore() return result endfunction " They are not used any longer. {{{2 if 0 "" @param nr (WinNr or WinId) 0 means the current window. "" @return (Number) The window width applied 'numberwidth' and 'foldcolumn' to. function! s:displayed_winwidth(nr) abort let winwidth = winwidth(a:nr) let foldcolumn = getwinvar(a:nr, '&foldcolumn') let numberwidth = getwinvar(a:nr, '&number') ? \ max([getwinvar(a:nr, '&numberwidth'), len(line('$'))]) : 0 return winwidth - foldcolumn - numberwidth endfunction "" Wrapper of |char2nr()|. function! s:char2nr(x, ...) abort return type(a:x) == v:t_number ? \ a:x : \ char2nr(a:x, get(a:000, 0, 0)) endfunction "" Wrapper of |nr2char()|. function! s:nr2char(x, ...) abort return type(a:x) == v:t_string ? \ a:x : \ nr2char(a:x, get(a:000, 0, 0)) endfunction "" @param begin (Char) "" @param end (Char) Included "" @return ([Char]) "" e.g.) s:char_range('1', '5') "" => ['1', '2', '3', '4', '5'] function! s:char_range(begin, end) abort return map(range(s:char2nr(a:begin), s:char2nr(a:end)), 's:nr2char(v:val)') endfunction "" Splits a string character by character. "" @param str (String) "" @return ([Char]) "" e.g.) s:each_char('bar') "" => ['b', 'a', 'r'] function! s:each_char(str) abort return split(a:str, '\zs') endfunction "" Returns a list of pairs of index and item. "" @param list (List) "" @return ([[Number, Any]]) "" e.g.) s:with_index(['a', 'b', 'c']) "" => [[0, 'a'], [1, 'b'], [2, 'c']] function! s:with_index(list) abort return map(a:list, '[v:key, v:val]') endfunction "" Concatenates all passed lists and returns it. "" @param ... ([Any]) "" @return ([List]) function! s:extend_list(...) abort let ret = [] for list in a:000 call extend(ret, list) endfor return ret endfunction "" @param list ([Any]) "" @param length (Number) "" @param [filled_item] (Any) function! s:normalize_list_length(list, length, ...) abort let delta = len(a:list) - a:length if delta < 0 " too short let filled_item = a:1 return expand(a:list, repeat(filled_item, -delta)) else " too long return a:list[:(delta - 1)] endif endfunction " If the current line contains any multibyte characters, It doesn't work: " getline('.')[col('.') - 1] " This function can handle multibyte characters. function! s:get_cursor_char() abort return matchstr(getline('.'), '.' , col('.') - 1) endfunction endif " Modelines {{{1 " vim: expandtab:softtabstop=4:shiftwidth=4:textwidth=80:colorcolumn=+1: " vim: foldenable:foldmethod=marker:foldlevel=0: