" .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  <expr> <Esc>[200~ XTermPasteBegin('0i')
      inoremap <expr> <Esc>[200~ XTermPasteBegin('')
      vnoremap <expr> <Esc>[200~ XTermPasteBegin('c')
      cnoremap        <Esc>[200~ <Nop>
      cnoremap        <Esc>[201~ <Nop>

      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 <silent> <Esc><Esc> :<C-U>nohlsearch<CR>
inoremap <C-U> <C-G>u<C-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', '<Plug>(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 <expr> <Space> ambicmd#expand("\<Space>")
  cnoremap <expr> <CR>    ambicmd#expand("\<CR>")
  cnoremap <expr> <C-F>   ambicmd#expand("\<Right>")

  augroup vimrc-plugin-ambicmd
    autocmd!
    autocmd CmdwinEnter * call s:init_cmdwin()
  augroup END
  function! s:init_cmdwin() abort
    inoremap <buffer> <expr> <Space> ambicmd#expand("\<Space>")
    inoremap <buffer> <expr> <CR>    ambicmd#expand("\<CR>")
    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  <Nop>
  nmap     <C-P>  CtrlP
  nnoremap CtrlP  :<C-U>CtrlP<CR>
  nnoremap CtrlPb :<C-U>CtrlPBuffer<CR>
  nnoremap CtrlPm :<C-U>CtrlPMRU<CR>
endif

" plugin: eazy-align {{{1
if g:vimrc.has_plugin('vim-easy-align')
  vmap ga <Plug>(EasyAlign)
  nmap ga <Plug>(EasyAlign)
endif

" plugin: emmet {{{1
if g:vimrc.has_plugin('emmet-vim')
  let g:user_emmet_leader_key = '<C-E>'
  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 = '<Leader>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 <buffer> <C-]> <Plug>(lsp-definition)
    map <buffer> K     <Plug>(lsp-hover)

    return 'setl ofu< | mapc <buffer>'
  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, <Plug>(swap-textobject-i)
  xmap i, <Plug>(swap-textobject-i)
  omap a, <Plug>(swap-textobject-a)
  xmap a, <Plug>(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<!/',
  \  'subst':    '*/*',
  \  'priority': 20,
  \})
  call unite#custom#profile('files', 'substitute_patterns', {
  \  'pattern':  '/\*\@!',
  \  'subst':    '/*',
  \  'priority': 10,
  \})
  call unite#custom#profile('files', 'substitute_patterns', {
  \  'pattern':  '^@@',
  \  'subst':    '\=fnamemodify(expand("#"), ":p:h") . "/*"',
  \  'priority': 2,
  \})
  call unite#custom#profile('files', 'substitute_patterns', {
  \  'pattern':  '^@',
  \  'subst':    '\=getcwd() . "/*"',
  \  'priority': 1,
  \})
  call unite#custom#profile('files', 'substitute_patterns', {
  \  'pattern':  '^;v',
  \  'subst':    g:vimrc.to_slash(g:vimrc.join(g:vimrc.vimfiles, '*')),
  \  'priority': 0,
  \})
  call unite#custom#profile('files', 'substitute_patterns', {
  \  'pattern':  '\*\{2,}',
  \  'subst':    '*',
  \  'priority': -1,
  \})
  call unite#custom#profile('files', 'substitute_patterns', {
  \  'pattern':  '\\\s\@!',
  \  'subst':    '/',
  \  'priority': -30,
  \})

  call unite#filters#matcher_default#use(['matcher_fuzzy'])
  call unite#custom#source('buffer,file,file_rec', 'sorters', 'sorter_rank')

  nnoremap [unite]   <Nop>
  nmap     <Leader>u [unite]
  nnoremap [unite]   :<C-U>Unite<Space>
  nnoremap [unite]a  :<C-U>Unite -profile-name=files file file/new buffer file_mru<CR>
  nnoremap [unite]f  :<C-U>Unite -profile-name=files file file/new<CR>
  nnoremap [unite]r  :<C-U>Unite -profile-name=files file_rec/async:!<CR>
  nnoremap [unite]m  :<C-U>Unite -profile-name=files file_mru<CR>
  nnoremap [unite]b  :<C-U>Unite -immediately buffer<CR>
  nnoremap [unite]t  :<C-U>Unite -immediately tab:no-current<CR>
  nnoremap [unite]w  :<C-U>Unite -immediately window:no-current<CR>
  nnoremap [unite]T  :<C-U>Unite tag<CR>
  nnoremap [unite]h  :<C-U>Unite help<CR>
  nnoremap [unite]o  :<C-U>Unite outline<CR>
  nnoremap [unite]s  :<C-U>Unite source<CR>
  nnoremap [unite]g  :<C-U>Unite grep<CR>
  nnoremap [unite]/  :<C-U>Unite line<CR>
endif

" plugin: zip {{{1
let g:loaded_zipPlugin = 1
let g:loaded_zip = 1