"  _  _ ____ _    _    ____      _  _ _ _  _ |
"  |__| |___ |    |    |  |      |  | | |\/| |
"  |  | |___ |___ |___ |__| .     \/  | |  | .
"                           '
" This is the Vim(Neovim) initialization file categorized practically.
" Bundle(plugin) dependent configs are splited into "vimrc.bundle".
"
" Author: Bohr Shaw <pubohr@gmail.com>

" Comments:" {{{
" Be: healthy, stable, efficient, consistent, intuitive, convenient, accessible!

" First and foremost, master the help system. (:h helphelp)
" For an overview, :h quickref, :h index
" Could view and set all options. (:h :options)
" See minimal sensible settings: https://github.com/tpope/vim-sensible/blob/master/plugin/sensible.vim
" Analyse startup performance with vim-profile.sh

" Mapping notes:
" Use <C-c> instead of <Esc> to cancel a mapping
" :h map-which-keys
" Potentially unused keys: "\ <Space> <CR> <BS> Z Q R S X _ !"
" Keys waiting for a second key: "f t d c g z v y m q ' [ ]"
" Special keys like <CR>, <BS> are often mapped solely, as well as 'q' which is
" often mapped to quit a window.
" <Tab>/<C-I>, <CR>/<C-M>, <Esc>/<C-[> are pairs of exactly same keys.
" Some keys like Caps Lock, <C-1>, <C-S-1> etc. are not mappable.
" <C-J> is the same as <C-j>, use <C-S-j> instead.

" }}}
" Starting:" {{{
" Define an augroup for all autocmds in this file and empty it
augroup vimrc | execute 'autocmd!' | augroup END
if has('vim_starting')
  set all& " override system vimrc and cmdline options like --noplugin
  set nocompatible " make Vim behave in a more useful way

  if has('win32')
    " Wish to use a forward slash for path separator? But 'shellslash' is not
    " designed to be set alone. Plugins must explicitly cope with it. Wish a
    " 'internal_shellslash' be available!
    "
    " Plugins like 'fugitive' works regardless of this option. While more
    " plugins like 'gnupg', 'jedi' wouldn't function well when it's set.
    " Troublesomely, 'unite', 'vimproc' have problems when it's not set.
    set shellslash&
  endif

  let $MYVIMRC = empty($MYVIMRC) ? expand('<sfile>:p') : resolve($MYVIMRC)
  let $MYVIM = fnamemodify($MYVIMRC, ':p:h') " be portable
  let g:ported = $MYVIM == expand('~/.vim') ? 0 : 1

  " Cross-platform 'runtimepath'
  set rtp=$MYVIM,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,$MYVIM/after

  if has('gui_running') || $termencoding ==? 'utf-8'
    set encoding=utf-8 " used inside Vim, allow mapping with the ALT key
  endif

  set timeout ttimeout " Nvim has different defaults
  " set timeoutlen=3000 " mapping delay
  set ttimeoutlen=10 " key code delay (instant escape from Insert mode)
  " Deal with meta-key mappings:" {{{
  if has('nvim')
    " Map meta-chords to esc-sequences in terminals
    for c in map(range(33, 123) + range(125, 126), 'nr2char(v:val)')
      execute 'tnoremap '.'<M-'.c.'> <Esc>'.c
    endfor
    tnoremap <M-\|> <Esc>\|
    tnoremap <M-CR> <Esc><CR>
  else
    runtime autoload/key.vim " mappable meta key in terminals
  endif " }}}

  if has('nvim') " skip python check to reduce startup time
    let [g:python_host_skip_check, g:python3_host_skip_check] = [1, 1]
  endif

  " Whether to include the least number of bundles, for shell command line editing
  let g:l = get(g:, 'l', $VL) || argv(0) =~# '^\V'.
        \(empty($TMPPREFIX)?'/tmp/zsh':$TMPPREFIX).'ecl\|'.$TMP.'/bash-fc'

  let $MYVIMRCPRE = g:ported ? $MYVIM.'/vimrc.pre' : $HOME.'/.vimrc.pre'
  if filereadable($MYVIMRCPRE)
    execute 'silent source' $MYVIMRCPRE
  endif
endif " }}}
" Meta:" {{{
" let mapleader = "\r" " replace <Leader> in a map
let maplocalleader = "\t" " replace <LocalLeader> in a map
noremap <Tab> <Nop>
let g:mapinsertleader = "\<M-g>"

" Commands for defining mappings in several modes
command! -nargs=1 NXnoremap nnoremap <args><Bar> xnoremap <args>
command! -nargs=1 NXmap nmap <args><Bar>xmap <args>
command! -nargs=1 NOnoremap nnoremap <args><Bar> onoremap <args>
command! -nargs=1 NOmap nmap <args><Bar>omap <args>
command! -nargs=1 NXOnoremap nnoremap <args><Bar>xnoremap <args><Bar>onoremap <args>
command! -nargs=1 NXOmap nmap <args><Bar>xmap <args><Bar>omap <args>
" Allow chained commands, but also check for a " to start a comment
command! -bar -nargs=1 NXInoremap nnoremap <args><Bar> xnoremap <args><Bar>
      \ inoremap <args>

" Execute a remapped key in its un-remapped(vanilla) state
noremap <expr><M-\> nr2char(getchar())
noremap! <expr><M-\> nr2char(getchar())
" Execte a global key shadowed by the same local one
nnoremap <silent>g\ :call <SID>gmap('n')<CR>
xnoremap <silent>g\ :<C-u>call <SID>gmap('x')<CR>
function! s:gmap(mode) " {{{
  let k = v#getchar()
  let map = maparg(k, a:mode, 0, 1)
  try
    execute a:mode.'unmap <buffer>' k
  catch
    Echow 'No such local mapping.' | return 1
  endtry
  execute 'normal' (a:mode == 'x' ? 'gv' : '').k
  execute a:mode.(map.noremap?'nore':'').'map'
        \ map.silent?'<silent>':'' map.expr?'<expr>':'' map.nowait?'<nowait>':''
        \ '<buffer>' map.lhs map.rhs
endfunction " }}}

" Define a full-id abbreviation with minimal conflict
command! -nargs=1 Abbr execute substitute(<q-args>, '\v\s+\S+\zs', 'SoXx', '')
" Complete and trigger a full-id abbreviation
noremap! <M-]> SoXx<C-]>

" Echo a warning message
command! -bar -nargs=1 Echow echohl WarningMsg | echo <args> | echohl None
" A command doing nothing while accepting args (for quick composition)
command! -nargs=* Nop :
" }}}
" Shortcuts:" {{{
" Escape
inoremap <M-i> <Esc>
if has('nvim')
  tnoremap <M-i> <C-\><C-N>
endif
inoremap <M-o> <C-O>

" Enter the command line
NXnoremap <Space> :
inoremap <M-Space> <Esc>:
inoremap <M-e> <Esc>:
if has('nvim')
  tnoremap <M-Space> <C-\><C-N>:
endif
" Resolve local mapping conflicts with <Space>
autocmd vimrc BufWinEnter option-window autocmd CursorMoved option-window
      \ execute 'nnoremap <silent><buffer><LocalLeader>r '.maparg("<Space>")|
      \ unmap <buffer><Space>|
      \ autocmd! CursorMoved option-window

" The command line window
NXnoremap <M-Space> q:
NXnoremap <M-e> q:
NXnoremap <M-/> q/
" set cedit=<C-G>
cnoremap <M-Space> <C-F>
cnoremap <M-e> <C-F>
autocmd vimrc CmdwinEnter * noremap <buffer> <F5> <CR>q:|
      \ NXInoremap <buffer> <nowait> <CR> <CR>|
      \ NXInoremap <buffer> <M-q> <C-c><C-c>

" Yank till the line end instead of the whole line
nnoremap Y y$

" Character-wise visual mode
nnoremap vv ^vg_
nnoremap vV vg_

" quick access to GUI/system clipboard
NXnoremap "<Space> "+

" Copy from the command line
cabbrev <expr>c getcmdtype() == ':' && getcmdpos() == 2 ? 'copy' : 'c'

" Access to the black hole register
NXnoremap _ "_

" Run the current command with a bang(!)
cnoremap <M-1> <C-\>e<SID>insert_bang()<CR><CR>
" Run the last command with a bang
nnoremap @! :<Up><C-\>e<SID>insert_bang()<CR><CR>
function! s:insert_bang() " {{{
  let [cmd, args] = split(getcmdline(), '\v(^\a+)@<=\ze(\A|$)', 1)
  return cmd.'!'.args
endfunction " }}}
" }}}
" Motion:" {{{
set virtualedit=onemore " consistent cursor position on EOL
set whichwrap& " left/right motions across lines

" Search forward/backward regardless of the direction of the previous character search"{{{
" Note: These are overwritten in Sneak, but the semantics retains.
if 0 && exists('*getcharsearch') " Vim patch 7.4.813
  NXOnoremap <expr>; getcharsearch().forward ? ';' : ','
  NXOnoremap <expr>, getcharsearch().forward ? ',' : ';'
elseif 0
  NOnoremap <silent>F :<C-u>execute 'silent! normal! mzf'.nr2char(getchar()).'g`z'.v:count1.','<CR>
  xnoremap <silent>F :<C-u>execute 'silent! normal! mzf'.nr2char(getchar()).'g`zgv'.v:count1.','<CR>
  NOnoremap <silent>T :<C-u>execute 'silent! normal! mzt'.nr2char(getchar()).'g`z'.v:count1.','<CR>
  xnoremap <silent>T :<C-u>execute 'silent! normal! mzt'.nr2char(getchar()).'g`zgv'.v:count1.','<CR>
endif "}}}

" Display lines up/down (consecutive motions are quicker)
nnoremap <C-j> gj
nnoremap <C-k> gk

" Jump to the middle of the current written line as opposed to the window width
nnoremap <silent> gm :call cursor(0, virtcol('$')/2)<CR>|nnoremap gM gm

set matchpairs+=<:> " character pairs matched by '%'
if !has('nvim') " nvim put it in plugin/
  runtime macros/matchit.vim " extended pair matching with '%'
endif

" Sections backword/forward
nmap <M-[> [[
nmap <M-]> ]]

" Navigate the change list
nnoremap <M-;> g;
nnoremap <M-,> g,
" Go to the second-newest or current position in the change list
nnoremap <silent>g. :try\|execute 'normal! g,g;'\|
      \ catch\|execute 'normal! g,'\|endtry<CR>

" Print the change list or mark list
cabbrev <expr>cs getcmdtype() == ':' && getcmdpos() == 3 ? 'changes' : 'cs'
cabbrev <expr>ms getcmdtype() == ':' && getcmdpos() == 3 ? 'marks' : 'ms'

" Navigate the jumper list
nnoremap <M-i> <C-I>
nnoremap <M-o> <C-O>

" Jump to the definition of the current tag
NXmap <CR> <C-]>

" Auto-place the cursor when switching buffers or files:" {{{
" Don't move the cursor to the start of the line when switching buffers
augroup vimrc_cursor
  autocmd!
  autocmd BufLeave * set nostartofline|
        \autocmd vimrc_cursor CursorMoved * set startofline|
        \autocmd! vimrc_cursor CursorMoved
augroup END
" Jump to the last known position in a file just after opening it
autocmd vimrc BufRead * silent! normal! g`"
" }}}
" }}}
" Search:" {{{
set incsearch " show matches when typing the search pattern
if !&hlsearch|set hlsearch|endif " highlight all matches of a search pattern
set ignorecase " case insensitive in search patterns and command completion
set smartcase " case sensitive only when up case characters present
" Substitute in a visual area:" {{{
xnoremap sv :s/\%V
" Substitute in a visual area (eat the for-expanding-space)
" Hack: Use an expression to save a temporary value.
cabbrev <expr>sv getcmdtype() == ':' && getcmdpos() =~ '[38]' ?
      \ 's/\%V'.setreg('z', nr2char(getchar(0)))[1:0].(@z == ' ' ? '' : @z) : 'sv'
" }}}
" Grep:" {{{
if executable('ag')
  set grepprg=ag\ --column " --nocolor --nobreak implicitly
  set grepformat^=%f:%l:%c:%m " the output format when not running interactively
elseif executable('ack')
  set grepprg=ack\ --column
  set grepformat^=%f:%l:%c:%m
endif
" A wrapper around grep using 'ag' or 'ack' without affecting 'grepprg' and
" 'grepformat'. Notice that a grep command like :grep, :lgrep, :grepadd etc.
" still needs to be explicitly specified.
command! -bar -nargs=+ -complete=file WithAg call grep#grep('ag', <q-args>)
command! -bar -nargs=+ -complete=file WithAck call grep#grep('ack', <q-args>)
" Grep all HELP docs preferably with ag, ack, helpgrep, in this order
command! -nargs=+ -complete=command Help call grep#help(<q-args>)
" A shortcut to ":Help grep"
command! -nargs=+ -complete=command Helpgrep call grep#help('grep '.<q-args>)
" Grep through all buffers
command! -nargs=1 BufGrep cexpr [] | bufdo vimgrepadd <args> %
" command! -nargs=1 BufGrep cexpr [] | mark Z |
"       \ execute "bufdo silent! g/<args>/caddexpr
"       \ expand('%').':'.line('.').':'.getline('.')" | normal `Z
" }}}
" QuickFix:" {{{
" Execute a command in each buffer in the quickfix or location list
command! -nargs=1 -complete=command Qdo call vimrc#errdo('q', <q-args>)
command! -nargs=1 -complete=command Ldo call vimrc#errdo(<q-args>)
" Clear the current quickfix list
command! -bar Cclear call setqflist([])
" Mappings/options for a quickfix/location window
autocmd vimrc FileType qf nnoremap <buffer> <nowait> <CR> <CR>|
      \ nnoremap <buffer> q <C-W>c|
      \ nnoremap <buffer> <M-w>v <C-W><CR><C-W>H|
      \ nnoremap <buffer> <M-w>t <C-W><CR><C-W>T
" }}}
" }}}
" View:" {{{

" Scroll relative to cursor (@_ suppresses [count] for zt)
nnoremap <expr>zt v:count > 0 ? '@_zt'.v:count.'<c-y>' : 'zt'
nnoremap <expr>zb v:count > 0 ? '@_zb'.v:count.'<c-e>' : 'zb'

" The leader key for managing windows and tabs
NXmap <M-w> <C-W>

" Jump to {count}th next/previous window, able to jump back with <C-w>p
nnoremap <silent><C-w>j :<C-u>let _w = winnr() + v:count1 \|
      \ execute (_w > winnr('$') ? _w - winnr('$') : _w).'wincmd w'<CR>
nnoremap <silent><C-w>k :<C-u>let _w = winnr() - v:count1 \|
      \ execute (_w < 1 ? _w + winnr('$') : _w).'wincmd w'<CR>
for i in [2, 3, 4, 5]
  execute 'nmap <C-w>'.i.'j' i.'<C-w>j'
  execute 'nmap <C-w>'.i.'k' i.'<C-w>k'
endfor
nmap <M-j> <C-w>j
nmap <M-k> <C-w>k
nnoremap <M-q> <C-W>q
inoremap <M-q> <Esc><C-W>q

nnoremap <silent><M-l> :<C-u>execute repeat('tabn\|', v:count1-1).'tabn'<CR>
nnoremap <M-h> gT
nnoremap <silent><C-w><M-l> :<C-u>execute 'tabmove+'.v:count1<CR>
nnoremap <silent><C-w><M-h> :<C-u>execute 'tabmove-'.v:count1<CR>
nnoremap <silent><M-Q> :windo quit<CR>
nmap <silent><C-w>Q <M-Q>

" Maxmize the current window by duplicate it in a new tab
nnoremap <silent><C-w><M-t> <C-w>s<C-w>T
nnoremap <silent><C-w><C-t> <C-w>s<C-w>T
" Maxmize the current window or restore the previously window layout
nnoremap <silent><C-w>O :call <SID>win_toggle()<CR>
function! s:win_toggle() " {{{
  if exists('t:winrestcmd')
    execute t:winrestcmd
    unlet t:winrestcmd
  else
    let t:winrestcmd = winrestcmd()
    resize | vertical resize
    cal winrestcmd()
  endif
endfunction " }}}

" Exchange the current window with the {count}th window
nnoremap <silent><C-w>e :<C-u>execute 'buffer '.winbufnr(v:count1).'\|'
      \.v:count1.'wincmd w\|buffer '.winbufnr(0)<CR>
" Attach the current window bellow the last windows with the same width
nnoremap <silent><C-w>a :execute 'close\|$wincmd w\|belowright sbuffer '.bufnr('')<CR>

cabbrev <expr>v getcmdtype() == ':' && getcmdpos() == 2 ? 'vert' : 'v'
cabbrev <expr>t getcmdtype() == ':' && getcmdpos() == 2 ? 'tab' : 't'

" Deal with terminal buffers
if has('nvim')
  tnoremap <M-w> <C-\><C-n><C-w>
  tnoremap <M-j> <C-\><C-n><C-w>w
  tnoremap <M-k> <C-\><C-n><C-w>W
  tnoremap <S-PageUp> <C-\><C-n><C-b>
  tnoremap <S-PageDown> <C-\><C-n><C-f>
  tnoremap <C-PageUp> <C-\><C-n><C-b>
  tnoremap <C-PageDown> <C-\><C-n><C-f>
  cabbrev <expr>st getcmdtype() == ':' && getcmdpos() == 3 ? 'new\|te' : 'st'
  cabbrev <expr>vt getcmdtype() == ':' && getcmdpos() == 3 ? 'vne\|te' : 'vt'
  cabbrev <expr>tt getcmdtype() == ':' && getcmdpos() == 3 ? 'tab new\|te' : 'tt'
  autocmd vimrc BufWinEnter,WinEnter term://* startinsert
  autocmd vimrc BufLeave term://* stopinsert
endif
" }}}
" Fold: "{{{
" Open the fold the cursor is in, recursively
nnoremap z<M-o> zczO

" Focus on a region using manual folding (mnemonic: pick)
nnoremap <silent>zp :set operatorfunc=<SID>fold_others<CR>g@
xnoremap <silent>zp :<C-u>call <SID>fold_others()<CR>
nnoremap <silent>zP :call <SID>fold_restore()<CR>
function! s:fold_others(...) " {{{
  let [line1, line2] = a:0 == 1 ? ["'[", "']"] : ["'<", "'>"]
  let b:fold_opts = [&fdm, &fdl, &fde]
  set fde=0 fdm=expr | redraw " disable existing folding
  set fdm=manual
  execute '1,'.line1.'-1fold|'.line2.'+1,$'.'fold'
endfunction
function! s:fold_restore()
  normal! zE
  let [&fdm, &fdl, &fde] = b:fold_opts
  normal! zvzz
endfunction " }}}

" Toggle fold methods
nnoremap <silent>cof :let &foldmethod = tolower(matchstr(
      \',mmanual,kmarker,iindent,ssyntax,eexpr,ddiff',
      \','.nr2char(getchar()).'\zs\a*\C'))\|set foldmethod<CR>
nmap <silent>zfm cof

" Don't screw up folds when inserting text that might affect them. Also improve
" speed by avoiding updating folds eagerly.
" autocmd vimrc InsertEnter * if !exists('w:vfdml') &&
"       \ &foldmethod != 'manual' && empty(&buftype) |
"       \ let w:vfdml=&foldmethod | set foldmethod=manual | endif
" However, restoring 'foldmethod' on InsertLeave would cause text under the
" cursor be closed if the inserted text creates a new fold level.
" autocmd vimrc InsertLeave * if exists('w:vfdml') && empty(&buftype) |
"       \ let &foldmethod=w:vfdml | unlet w:vfdml |
"       \ execute 'silent! normal! zo' |endif
"}}}
" Buffer:" {{{
set hidden autoread " autowrite

nnoremap <silent><M-b>d :bdelete<CR>
" Delete the current buffer without closing its window
nnoremap <silent><M-b>x :Bdelete<CR>
command! -bang Bdelete try|b#|silent! bd<bang>#|catch|bd|endtry
nnoremap <silent><M-b>w :bwipeout<CR>

cabbrev <expr>vb getcmdtype() == ':' && getcmdpos() == 3 ? 'vert sb' : 'vb'
cabbrev <expr>tb getcmdtype() == ':' && getcmdpos() == 3 ? 'tab sb' : 'tb'

" Delete all buffers in the buffer list except the current one
command! -bang BufOnly let _b = bufnr('') | let _f = &confirm |
      \ try | set noconfirm |
      \   silent! execute '1,'._b.'-bd<bang>|'._b.'+,$bd<bang>' |
      \ finally | let &confirm = _f | endtry

" Wipe out all unlisted buffers
command! BwipeoutUnlisted call vimrc#bufffer_wipe_unlisted()
" }}}
" File:" {{{
nnoremap <silent><M-f>w :write<CR>
nnoremap <silent><M-f><M-f>w :write!<CR>
nnoremap <silent><M-f>u :update<CR>
nnoremap <silent><M-f><M-f>u :update!<CR>
nnoremap <silent><M-f>a :wall<CR>
nnoremap <silent><M-f><M-f>a :wall!<CR>
nnoremap <silent><M-f>A :windo update<CR>
nnoremap <silent><M-f><M-f>A :windo update!<CR>
" Quick save and exit, useful when editing the shell command line
inoremap <M-z> <Esc>ZZ
nnoremap <silent><M-f>e :edit<CR>
nnoremap <silent><M-f><M-f>e :edit!<CR>
cnoremap <M-h> <C-r>=expand('%:h')<CR>/
nnoremap <M-f>f :filetype detect<CR>
nnoremap <M-f>F :silent! unlet b:did_ftplugin b:did_after_ftplugin<Bar>filetype detect<CR>
nnoremap <M-f>c :checktime<CR>
" Switch to the alternative buffer
nnoremap <silent><M-a> :buffer #<CR>
if has('nvim')
  tnoremap <silent><M-a> <C-\><C-n>:buffer #<CR>
endif
nnoremap <silent><C-W><M-s> :sbuffer #<CR>
nnoremap <silent><C-W><M-v> :vert sbuffer #<CR>

" Find a file in 'path'
cabbrev <expr>fi getcmdtype() == ':' && getcmdpos() == 3 ? 'fin' : 'fi'
cabbrev <expr>vf getcmdtype() == ':' && getcmdpos() == 3 ? 'vert sf' : 'vf'
cabbrev <expr>tf getcmdtype() == ':' && getcmdpos() == 3 ? 'tab sf' : 'tf'

" Directories to search by `gf, :find, cd, lcd etc.`
" (dir of the current file, current dir, etc.)
let &g:path = '.,,~,'.$MYVIM.','.$MYVIM.'/after'
set cdpath=,,.,~
if has('vim_starting') && 0 == argc() && has('gui_running') && !g:l
  cd $HOME
endif

" Open a destination file of a link
cnoremap <M-l> <C-\>e<SID>get_link_targets()<CR><CR>
function! s:get_link_targets() " {{{
  let [cmd; links] = split(getcmdline())
  for l in links
    let cmd .= ' '.fnamemodify(resolve(expand(l)), ':~:.')
  endfor
  return cmd
endfunction " }}}

" Easy access to vimrc files
Abbr cabbr <expr>v $MYVIMRC
Abbr cabbr <expr>b $MYBUNDLE
nnoremap <silent><M-f>v :execute 'Be' $MYVIMRC<CR>
nnoremap <silent><M-f>b :execute 'Be' $MYBUNDLE<CR>

" Switch to a file without reloading it
command! -nargs=1 -bang Be execute (buflisted(expand(<q-args>))?'b':
      \filereadable(expand(<q-args>))||<bang>0?'e':'Nop').' '.<q-args>

" Make the file '_' a scratch buffer
autocmd vimrc BufNewFile,BufReadPost _ set buftype=nofile nobuflisted bufhidden=hide
autocmd vimrc SessionLoadPost * silent! bwipeout! _

" Recognise a file's encoding in this order
" set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,latin1

set fileformats=unix,dos,mac " end-of-line formats precedence
set fileformat=unix " only for the initial unnamed buffer

set nowritebackup " write to symbolic files safely on windows
" }}}
" Completion:" {{{
" A smart and light <Tab> to do insert-completion:" {{{
inoremap <expr> <Tab> getline('.')[col('.')-2] !~ '^\s\?$' \|\| pumvisible()
      \ ? '<C-N>' : '<Tab>'
inoremap <expr> <S-Tab> pumvisible() \|\| getline('.')[col('.')-2] !~ '^\s\?$'
      \ ? '<C-P>' : '<Tab>'
" Remove auto-definded mappings
autocmd vimrc CmdwinEnter * silent! iunmap <buffer> <Tab>
" }}}
" CTRL-X completion-sub-mode :" {{{
" Shortcuts
map! <M-x> <C-x>
for s:c in split('lnpkti]fdvuos', '\zs')
  execute 'inoremap <C-X>'.s:c.' <C-X><C-'.s:c.'>'
endfor
" Insert a digraph
noremap! <C-X>g <C-k>
" }}}
" Auto-reverse letter case in insert mode {{{
inoremap <M-l> <C-R>=<SID>toggle(1)<CR>
inoremap <M-L> <C-R>=<SID>toggle(2)<CR>
function! s:toggle(arg)
  let b:case_reverse = get(b:, 'case_reverse') ? 0 : a:arg
  if !exists('#case_reverse#InsertCharPre#<buffer>')
    augroup case_reverse
      autocmd InsertCharPre <buffer> if b:case_reverse|
            \ let v:char = v:char =~# '\l' ? toupper(v:char) : tolower(v:char)|
            \ endif|
            \ if b:case_reverse == 1 && v:char !~ '\h'|
            \ let b:case_reverse = 0|
            \ endif
      " Wouldn't be triggered if leaving insert mode with <C-C>
      autocmd InsertLeave <buffer> let b:case_reverse = 0| autocmd! case_reverse
    augroup END
  endif
  return ''
endfunction
" }}}
set completeopt=menu,longest " insert-completion mode
set complete-=i " don't scan included files when insert-completing by <C-N/P>
set pumheight=15 " max candidates on insert-mode completion

set wildcharm=<Tab> " the key to trigger wildmode expansion in mappings
set wildmenu wildmode=longest:full,full " command line completion mode
silent! set wildignorecase " ignore case when completing file names/directories
" Show all candidates
cnoremap <C-Tab> <C-d>
" Make a command(e.g. `:h ...`) split vertically or in a new tab.
cnoremap <M-w>v <C-\>e'vert '.getcmdline()<CR><CR>
cnoremap <M-w>t <C-\>e'tab '.getcmdline()<CR><CR>
" Expand a mixed case command name:" {{{
cnoremap <M-[> <C-\>e<SID>cmd_expand()<CR><Tab>
function! s:cmd_expand()
  let cmd = getcmdline()
  let [range, abbr] = [matchstr(cmd, '^\A*'), matchstr(cmd, '\a.*')]
  let parts = map(split(abbr, abbr =~ '\s' ? '\s' : '\zs'), 'toupper(v:val[0]).v:val[1:]')
  return range . join(parts, '*')
endfunction " }}}

" Abbreviations
Abbr abbr bs Bohr Shaw

" Type notated keys
noremap! <expr><M-v> <SID>special_key()
function! s:special_key() " {{{
  let c1 = v#getchar(1, 1)
  if empty(c1)
    return ''
  endif
  if strtrans(c1)[0] == '^'
    let c1_2 = strtrans(c1)[1]
    if c1_2 == 'i'
      return '<Tab>'
    elseif c1_2 == 'm'
      return '<CR>'
    elseif c1_2 == '['
      return '<Esc>'
    else
      return '<C-'.tolower(c1_2).'>'
    endif
  elseif has_key(s:keymap, c1) == 1
    return s:keymap[c1]
  endif
  let c2 = v#getchar(1, 1)
  if empty(c2)
    return ''
  endif
  let c2_ = has_key(s:keymap_sp, c2) ? s:keymap_sp[c2] : c2
  let cc = c1.c2
  if has_key(s:keymap, cc) == 1
    return s:keymap[cc]
  elseif c1 ==? 'f'
    let c2 = c2 == 0 ? 1.v#getchar() : c2
    return '<'.toupper(c1).c2.'>'
  elseif cc =~# 'c.'
    return '<C-'.(c2 =~# '\u' ? 'S-'.tolower(c2_) : c2_).'>'
  elseif cc =~# '[Cx].'
    return 'CTRL-'.toupper(c2)
  elseif cc =~# '[md].'
    return '<'.toupper(c1).'-'.c2_.'>'
  else
    return ''
  endif
endfunction
let s:keymap_sp = {
      \"\<Tab>": 'Tab',
      \' ':      'Space',
      \"\<CR>":  'CR',
      \"\<BS>":  'BS',
      \}
let s:keymap = {
      \' ':      '<Space>',
      \"\<BS>":  '<BS>',
      \"\<Left>":  '<Left>',
      \"\<Right>": '<Right>',
      \"\<Up>":    '<Up>',
      \"\<Down>":  '<Down>',
      \'<':      '<lt>',
      \'\':      '<Bslash>',
      \'|':      '<Bar>',
      \'bu':     '<buffer>',
      \'no':     '<nowait>',
      \'nw':     '<nowait>',
      \'nm':     '<nomodeline>',
      \'si':     '<silent>',
      \'sp':     '<special>',
      \'sc':     '<script>',
      \'ex':     '<expr>',
      \'un':     '<unique>',
      \'L':      '<Leader>',
      \'ll':     '<LocalLeader>',
      \'lL':     '<LocalLeader>',
      \'P':      '<Plug>',
      \'S':      '<SID>',
      \'N':      '<Nop>',
      \'l1':     '<line1>',
      \'l2':     '<line2>',
      \'co':     '<count>',
      \'re':     '<reg>',
      \'ba':     '<bang>',
      \'ar':     '<args>',
      \'qa':     '<q-args>',
      \'fa':     '<f-args>',
      \}
" }}}
" }}}
" Repeat:" {{{
" Concisely list the newest leafs in the tree of changes. Er... useless...
command! UndoList echo join(reverse(map(
      \ split(scriptease#capture('undolist'), '\n')[-8:],
      \ "substitute(v:val, '\\s\\+', ' ', 'g')")), ' |')

" Clear undo history (:w to clear the undo file if presented)
command! -bar UndoClear execute 'set undolevels=-1 |move -1 |'.
      \ 'let [&modified, &undolevels] = ['.&modified.', '.&undolevels.']'

" Repeat last change on each line in a visual selection
xnoremap . :normal! .<CR>

" Execute a macro on each one in {count} lines
nnoremap <silent> @. :call <SID>macro()<CR>
function! s:macro() range
  execute a:firstline.','.a:lastline.'normal! @'.nr2char(getchar())
endfunction
" Execute a macro on each line in a visual selection
xnoremap <silent> @ :<C-u>execute ":'<,'>normal! @".nr2char(getchar())<CR>
" Execute a macro repeatedly within a range of lines, similar a recursive macro
nnoremap <silent>@R :set operatorfunc=<SID>repeat_macro<CR>g@
function! s:repeat_macro(...) " {{{
  let r = v#getchar()
  if empty(r) | return | endif
  while line('.') <= line("']") && line('.') >= line("'[")
    execute 'normal @'.r
  endwhile
endfunction " }}}
" Record and execute a recursive macro
nnoremap <silent>9q :call <SID>rec_macro()<CR>
function! s:rec_macro() " {{{
  let r = v#getchar()
  if empty(r) | return | endif
  " Empty the register first
  execute 'normal! q'.r.'q'
  " Setup a temporary mapping to terminate and execute the macro
  execute printf("nnoremap q q:call setreg('%s', '@%s', 'a')<Bar>".
        \"try<Bar>execute 'normal @%s'<Bar>".
        \"finally<Bar>execute 'nunmap q'<Bar>endtry<CR>", r, r, r)
  execute 'normal! q'.r
endfunction " }}}
" Execute a macro without remapping
NXnoremap <expr> <silent> @N repeat(
      \ ':<C-U>normal! <C-R><C-R>'.nr2char(getchar()).'<CR>', v:count1)

" Keep the flags when repeating last substitution
NXnoremap & :&&<CR>

" Refine the last command
NXnoremap @<Space> @:
NXnoremap @; :verbose @:<CR>
NXnoremap @: :Verbose @:<CR>
" }}}
" Diff:" {{{
xnoremap <silent> do :execute &diff ? "'<,'>diffget" : ''<CR>
xnoremap <silent> dp :execute &diff ? "'<,'>diffput" : ''<CR>
nnoremap <silent> du :execute &diff ? 'diffupdate' : ''<CR>
" Switch off diff mode and close other diff panes
nnoremap dO :diffoff \| windo if &diff \| hide \| endif<CR>
" Diff with another file
command! -nargs=? -complete=buffer DiffWith call vimrc#diffwith(<f-args>)
" }}}
" Spell:" {{{
" Enable spell checking for particular file types
autocmd vimrc FileType gitcommit,markdown,txt setlocal spell
if has('patch-7.4.088')
  set spelllang=en,cjk " skip spell check for East Asian characters
endif
set spellfile=$MYVIM/spell/en.utf-8.add
" Clean up spell files
command! SpellCleanup silent runtime spell/cleanadd.vim

" Dictionary files
let s:dictionary = $MYVIM.'/spell/dictionary-oald.txt'
if filereadable(s:dictionary)
  let &dictionary = s:dictionary
elseif !has('win32')
  set dictionary=/usr/share/dict/words
else
  set dictionary=spell " completion from spelling as an alternative
endif

" Thesaurus files
set thesaurus=$MYVIM/spell/thesaurus-mwcd.txt
"}}}
" Persistence:" {{{
let &swapfile = g:l ? 0 : 1 " use a swapfile for the buffer
set undofile " remember undo history across sessions
" Remember uppercase global variables, number of files in which marks are
" remembered(:oldfiles), ... , and viminfo file name.
let &viminfo = "!,'444,<50,s10,h,n".$MYVIM.'/tmp/viminfo'
let _viminfo = &viminfo " for quick interactive restoring
" Exclude options and mappings and be portable
set sessionoptions=blank,buffers,curdir,folds,tabpages,winsize,slash,unix
set viewoptions=folds,cursor,slash,unix
" Set default paths of temporary files
let opts = {'directory': 'swap', 'undodir': 'undo', 'backupdir': 'backup'}
for [opt, val] in items(opts)
  let dir = $MYVIM.'/tmp/'.val
  if !isdirectory(dir) | silent! call mkdir(dir) | endif
  execute 'set' opt.'^='.dir
endfor
set viewdir=$MYVIM/tmp/view
" }}}
" Readline:" {{{
" Readline style insertion adjusted for Vim
" - https://github.com/tpope/vim-rsi
" - https://github.com/bruno-/vim-husk

" Recall older or more recent command-line from history, but the command matches
" the current command-line
cnoremap <M-p> <Up>
cnoremap <M-n> <Down>

" Move the cursor around one character (won't break undo)
if has('patch-7.4.849')
  inoremap <C-f> <C-g>U<Right>
  inoremap <C-b> <C-g>U<Left>
else
  " Trigger the CursorMovedI event
  inoremap <C-f> <C-c>la
  " Won't trigger the CursorMovedI event
  inoremap <C-b> <C-c>i
endif
cnoremap <C-f> <Right>
cnoremap <C-b> <Left>
" Delete one character after the cursor
inoremap <expr> <C-D> col('.')>strlen(getline('.'))?"\<Lt>C-D>":"\<Lt>Del>"
cnoremap <expr> <C-D> getcmdpos()>strlen(getcmdline())?"\<Lt>C-D>":"\<Lt>Del>"

" Move the cursor around one word (break undo)
inoremap <M-f> <S-Right>
inoremap <M-b> <S-Left>
" Move the cursor around one WORD
inoremap <M-F> <C-o>W
inoremap <M-B> <C-o>B
" Delete one word (across lines) (won't break undo)
" Builtin <C-w> or <C-u> stops once at the start position of insert.
inoremap <M-BS> <Space><C-c>"_x"-cb
inoremap <M-d> <Space><C-c>"_x"-ce
" Delete one WORD
inoremap <C-w> <Space><C-c>"_x"-cB
inoremap <M-D> <Space><C-c>"_x"-cE

" Word like motions in Command mode differs that in Insert mode. They're more
" like in Shells so that less motions are needed to go to a specific position,
" though they are also less granular.
cnoremap <expr><M-f> <SID>word_fb("\<Right>")
cnoremap <expr><M-b> <SID>word_fb("\<Left>")
cnoremap <M-F> <S-Right>
cnoremap <M-B> <S-Left>
" Delete till a non-keyword
cnoremap <expr><M-BS> <SID>word_fb("\<BS>")
cnoremap <expr><M-d> <SID>word_fb("\<Del>")
" Delete till a space
cnoremap <expr><C-w> <SID>word_fb("\<BS>", 0)
cnoremap <expr><M-D> <SID>word_fb("\<Del>", 0)
function! s:word_fb(key, ...) " {{{
  let f = a:key == "\<Right>" || a:key == "\<Del>" ? 1 : 0
  let db = a:key == "\<Del>" || a:key == "\<BS>" ? 1 : 0
  let line = getcmdline()
  let pos = getcmdpos()
  let pat1 = a:0 == 0 ?
        \ f ?
        \   db ? '\W*\w+' : '\W*\w+\W*' :
        \   '\w+\W*' :
        \ f ? '\s*\S+' : '\S+\s*'
  let pat2 = '%'.pos.'c'
  let pos2 = match(line, '\v'.(f ? pat2.pat1.'\zs' : pat1.pat2)) + 1
  if db
    let @- = f ? line[pos-1:pos2-2] : line[pos2-1:pos-2]
  endif
  return (wildmenumode() ?  " \<BS>" : '').
        \ repeat(a:key, f ? pos2-pos : pos-pos2)
endfunction " }}}

" Move the cursor around the line
inoremap <C-A> <C-O>^
cnoremap <C-A> <Home>
inoremap <C-E> <End>
" Delete all before the cursor (won't break undo)
inoremap <expr><C-u> "<Space><C-c>\"_xc".
      \(search('^\s*\%#', 'bnc', line('.')) > 0 ? '0' : '^')
cnoremap <expr><C-u> <SID>c_u()
function! s:c_u() " {{{
  let @- = getcmdline()[:getcmdpos()-2]
  return "\<C-U>"
endfunction " }}}
" Delete all after the cursor
inoremap <C-k> <Space><C-c>"_xC
cnoremap <expr><C-k> <SID>c_k()
function! s:c_k() " {{{
  let @- = getcmdline()[getcmdpos()-1:]
  return repeat("\<Del>", strlen(getcmdline()) - getcmdpos() + 1)
endfunction " }}}

" Paste the previous deleted text
noremap! <C-y> <C-r>-

" Transpose two characters around the cursor
cmap <script><C-T> <SID>transposition<SID>transpose
noremap! <expr> <SID>transposition getcmdpos() > strlen(getcmdline()) ?
      \ "\<Left>" : getcmdpos()>1 ? '' : "\<Right>"
noremap! <expr> <SID>transpose "\<BS>\<Right>"
      \ . matchstr(getcmdline()[0 : getcmdpos()-2], '.$')
" }}}
" Bundles:" {{{
if has('vim_starting')
  runtime vimrc.bundle " bundle configuration
  BundleInject " inject bundle paths to 'rtp'
endif
" }}}
" Appearance:" {{{
" List special or abnormal characters:" {{{
set list " show non-normal spaces, tabs etc.
if &encoding ==# 'utf-8' || &termencoding ==# 'utf-8'
  " No reliable way to detect putty
  let s:is_win_ssh = has('win32') || !empty('$SSH_TTY')
  " Special unicode characters/symbols:
  " ¬ ¶ ⏎ ↲ ↪ ␣ ¨ ⣿ │ ░ ▒ ⇥ → ← ⇉ ⇇ ❯ ❮ » « ↓ ↑
  " ◉ ○ ● • · ■ □ ¤ ▫ ♦ ◆ ◇ ▶ ► ▲ ▸ ✚ ★ ✸ ✿ ✜ ☯ ☢ ❀ ♥ ♣ ♠
  let s:lcs = split(s:is_win_ssh ? '· · » « ▫' : '· ␣ ❯ ❮ ▫')
  let &showbreak = s:is_win_ssh ? '→' : '❯'
  set fillchars=vert:│,fold:-,diff:-
else
  let s:lcs = ['>', '-', '>', '<', '+']
endif
execute 'set listchars=tab:'.s:lcs[0].'\ ,trail:'.s:lcs[1]
      \ .',extends:'.s:lcs[2].',precedes:'.s:lcs[3].',nbsp:'.s:lcs[4]
" Avoid showing trailing whitespace when in insert mode
execute 'autocmd vimrc InsertEnter * set listchars-=trail:'.s:lcs[1]
execute 'autocmd vimrc InsertLeave * set listchars+=trail:'.s:lcs[1]
" }}}

" Status line(I name it as "Starline"):" {{{
set laststatus=2 " always display the status line
" Ensure all plugins are loaded before setting 'statusline'
function! Vstatusline()
  set statusline=%1*%{Vmode()}%* " mode
  set statusline+=:%2*%n " buffer number
  set statusline+=%{(&modified?'+':'').(&modifiable?'':'-').(&readonly?'=':'')}%*
  set statusline+=:%.30f " file path, truncated if its length > 30
  set statusline+=:%1*%Y%* " file type
  set statusline+=%{(&fenc!='utf-8'&&&fenc!='')?':'.&fenc:''} " file encoding
  set statusline+=%{&ff!='unix'?':'.&ff:''} " file format
  " Git branch name
  let &statusline .= exists('*fugitive#head') ?
        \ "%{exists('b:git_dir')?':'.fugitive#head(7):''}" : ''
  " set statusline+=%{':'.matchstr(getcwd(),'.*[\\/]\\zs\\S*')}
  set statusline+=%{get(b:,'case_reverse',0)?':CAPS':''} " software caps lock
  set statusline+=%w%q " preview, quickfix
  set statusline+=%= " left/right separator
  set statusline+=%c:%l/%L:%P " cursor position, line percentage
endfunction
function! Vmode() "{{{
  let mode = mode()
  if mode ==# 'i'
    return 'INS'
  elseif mode ==# 'R'
    return 'REP'
  elseif mode ==# 't'
    return 'TERM'
  elseif mode =~# '[VS]'
    return mode.'L'
  elseif mode =~# "[\<C-v>\<C-s>]"
    return strtrans(mode)[1].'B'
  else
    return toupper(mode)
  endif
  return ''
endfunction "}}}
set noshowmode " hide the mode message on the command line
set fillchars+=stl::,stlnc:: " characters to fill the statuslines
execute (has('vim_starting')?'autocmd vimrc VimEnter * ':'').'call Vstatusline()'

" Status line highlight"{{{
" Use a highlight group User{N} to apply only the difference to StatusLine to
" StatusLineNC
autocmd vimrc ColorScheme *
      \ hi User1
      \ term=bold cterm=bold ctermfg=123 ctermbg=233
      \ gui=bold guifg=#87FFFF guibg=#171717|
      \ hi User2
      \ term=bold cterm=bold ctermfg=226 ctermbg=233
      \ gui=bold guifg=#FFFF00 guibg=#171717|
      \ hi StatusLine
      \ term=bold cterm=bold ctermfg=40 ctermbg=233
      \ gui=bold guifg=#00d700 guibg=#171717 |
      \ hi StatusLineNC
      \ term=NONE cterm=NONE ctermfg=131 ctermbg=233
      \ gui=NONE guifg=#be7572 guibg=#171717 |
      \ hi! link TabLineSel StatusLine |
      \ hi! link TabLine StatusLineNC |
      \ hi! link TabLineFill StatusLineNC
if !has('vim_starting')
  doautocmd vimrc ColorScheme *
endif "}}}

" The status line for the quickfix window
autocmd vimrc FileType qf setlocal statusline=%t
      \%{strpart('\ '.get(w:,'quickfix_title',''),0,66)}%=\ %11.(%c,%l/%L,%P%)

" Use CTRL-G, G_CTRL-G to see file and cursor information manually
set ruler " not effective when 'statusline' is set
set rulerformat=%50(%=%m%r%<%f%Y\ %c,%l/%L,%P%)
" }}}

let &showtabline = g:l ? 1 : 2
autocmd vimrc VimEnter * let &titlestring = v:servername.
      \ (g:l ? '(L)' : '').' '.'%{getcwd()}'

" Make it easy to spot the cursor, especially for Gnome-terminal whose cursor
" color is not distinguishable.
set cursorline
" set cursorcolumn

" set number " print the line number in front of each line
set relativenumber " show the line number relative to the current line
set numberwidth=3 " minimal number(2) of columns to use for the line number

" Font, color, window size:" {{{
if has('vim_starting')
  if has('gui_running')
    let &guifont = has('win32') ? 'Consolas:h10' : 'Consolas 10'
    set lines=40 columns=88
    if !g:l " maximize the window
      if has('win32')
        autocmd vimrc GUIEnter * simalt ~x
      else
        set lines=250 columns=200
      endif
    endif
    set linespace=0
  else
    " Assume 256 colors
    if &term =~ '\v(xterm|screen)$' | let &term .= '-256color' | endif
    " Disable Background Color Erase (BCE) so that color schemes
    " render properly when inside 256-color tmux and GNU screen.
    " See also http://snk.tuxfamily.org/log/vim-256color-bce.html
    if &term =~ '256col' | set t_ut= | endif
    " Allow color schemes do bright colors without forcing bold.
    if &t_Co == 8 && &term !~ '^linux' | set t_Co=16 | endif
  endif
  set background=dark " assume a dark background for color schemes
endif
" }}}
set showcmd "show partial commands in status line
" Show matching pairs like (), [], etc." {{{
" set showmatch matchtime=1 " highlighting in plugin/matchparen.vim is better
autocmd vimrc ColorScheme * hi MatchParen cterm=underline ctermbg=NONE ctermfg=NONE
      \ gui=underline guibg=NONE guifg=NONE
" Enable or disable it due to the cost of frequently executed autocmds
nnoremap <expr>c\m ':'.(exists('g:loaded_matchparen') ? 'NoMatchParen' : 'DoMatchParen')."<CR>"
" }}}
silent! set breakindent " indent wrapped lines
set linebreak " don't break a word when displaying wrapped lines
set colorcolumn=+1 " highlight column after 'textwidth'
set display+=lastline " ensure the last line is properly displayed
set guicursor+=a:blinkon0 " don't blink the cursor
" if has('multi_byte_ime')
"   highlight CursorIM guifg=NONE guibg=#007500
" endif
set guiheadroom=0 " occupy more screen space on X11
" }}}
" Misc:" {{{
if has('vim_starting')
  set autoindent " indent at the same level of the previous line
  set shiftwidth=4 " number of spaces to use for each step of (auto)indent
  set shiftround " round indent to multiple of 'shiftwidth'
  set tabstop=4 " number of spaces a tab displayed in
  set softtabstop=4 " number of spaces used when press <Tab> or <BS>
  set expandtab " expand a tab to spaces
  set smarttab " <Tab> in front of a line inserts blanks according to 'shiftwidth'
endif
set mouse=a " enable mouse in all modes
" Sync visual mode selection with the selection register(*) in supported GUI
execute has('gui_gtk')||has('gui_motif')||has('gui_athena') ? 'set go+=a' : ''
" set clipboard+=unnamed " sync the selection register with the unnamed register
set scrolloff=1 " minimum lines to keep above and below cursor
set sidescrolloff=5 " minimal number of screen columns to keep around the cursor
set backspace=indent,eol,start " backspace through anything in insert mode
silent! set formatoptions+=j " remove a comment leader when joining lines
set nrformats-=octal " 01 is treated as decimal
set lazyredraw " don't redraw the screen while executing macros, etc.
set shortmess=aoOtTI " avoid all the hit-enter prompts caused by file messages
" autocmd vimrc GUIEnter * set vb t_vb= " disable error beep and screen flash
set guioptions=M " skip sourcing menu.vim, before enabling filetype/syntax
set guioptions+=c " use a console dialog for confirmation instead of a pop-up
set confirm " prompt for an action instead of fail immediately
set winminheight=0 " the minimal height of a window
set history=10000 " maximum number of commands and search patterns to keep
set synmaxcol=999 " ignore further syntax items to avoid slow redrawing
silent! set cryptmethod=blowfish cm=blowfish2 " acceptable encryption
silent! set langnoremap " 'langmap' doesn't apply to characters resulting from a mapping
" Make 'cw' consistent with 'dw'
" onoremap <silent> w :execute 'normal! '.v:count1.'w'<CR>

" Join lines without any character or with specified characters in between
command! -range -nargs=? Join <line1>,<line2>-1s/\s*\n\s*/<args>/
" Remove trailing white spaces
command! -range=% Trim let _p=getpos('.')|
      \keepj keepp <line1>,<line2>s/\s\+$//| call setpos('.',_p)
" Execute an external command silently
command! -nargs=1 -complete=shellcmd Silent call system(<q-args>)
" Remove duplicate lines:" {{{
" Remove duplicate, consecutive lines (:sort /.\_^/ u)
command! -range=% Uniqc <line1>,<line2>g/\v^(.*)\n\1$/d
" Remove duplicate, nonconsecutive and nonempty lines (g/\v^(.+)$\_.{-}^\1$/d)
command! -range=% Uniqn <line1>,<line2>g/^./
      \ if search('^\V'.escape(getline('.'),'\').'\$', 'bW') |
      \ delete | endif <NL> silent! normal! ``
" }}}
" Toggle full screen
nnoremap <silent><F11> :if has('win32')<Bar>
      \call libcallnr('gvimfullscreen.dll', "ToggleFullScreen", 0)<Bar>endif<CR>
" Mystify texts
command! Mystify call misc#mystify()
" Reverse the selected text
xnoremap cR c<C-O>:set revins<CR><C-R>"<Esc>:set norevins<CR>
" Statistics:" {{{
" Count anything in a range of lines
command! -range=% -nargs=? Count echo vimrc#count
      \(<q-args>, <line1>, <line2>) | normal ``
" Calculate words frequency
command! -range=% WordFrequency echo vimrc#word_frequency(<line1>, <line2>)
" Calculate the total lines of source code minus blank lines and comment lines.
command! -range=% SLOC echo vimrc#count
      \('^[^' . &cms[0] . ']', <line1>, <line2>) | normal ``
" Print the ASCII table in a split window
command! -nargs=? ASCII call ascii#print(<f-args>)
" }}}
" Write HELP docs
command! HelpWrite setlocal buftype= buflisted modifiable noreadonly |
      \ mapclear <buffer> | mapclear! <buffer> |
      \ silent! unlet b:did_ftplugin b:did_after_ftplugin | filetype detect |
      \ setlocal conceallevel=0 spell

let $MYVIMRCAFTER = g:ported ? $MYVIM.'/vimrc.after' : $HOME.'/.vimrc.after'
if filereadable($MYVIMRCAFTER)
  execute 'silent source' $MYVIMRCAFTER
endif

if has('vim_starting')
  " Must be after setting 'rtp'
  filetype plugin indent on
  syntax enable
endif
" }}}

" vim:fdm=marker: