" Fold Text
set foldtext=FoldText()
function! FoldText()
  let line = getline(v:foldstart)
  return line.' '.string(v:foldend - v:foldstart).' line fold '
endfunction

" Strip trailing whitespace
function! <SID>StripWhitespace()
  let l = line(".")
  let c = col(".")
  %s/\s\+$//e
  call cursor(l, c)
endfunction
command! StripWhitespace :call <SID>StripWhitespace()
augroup strip_white_space
  " Strip whitespace on buffer write
  autocmd!
  autocmd BufWritePre * :call <SID>StripWhitespace()
augroup END

" Stringify
" Make a code block in to a C string literal
function! <SID>Stringify()
  " Escape existing escape characters
  execute 's/\\/\\\\/ge'
  " Escape quotes
  execute 's/"/\\"/ge'
  " Prepend quote
  execute 's/^/"/g'
  " Append carriage return, quote
  execute 's/$/\\n"/g'
  noh
endfunction
map <silent> <leader>s :call <SID>Stringify()<CR>
" Make a C string literal in to a code block
function! <SID>Destringify()
  " Remove final quote and carriage return
  execute 's/\\n"\s*$//ge'
  " Remove first quote
  execute 's:^\(\s*\)":\1:ge'
  " Remove quote escapes
  execute 's/\\"/"/ge'
  " Remove escapes of escapes characters
  execute 's/\\\\/\\/ge'
  noh
endfunction
map <silent> <leader>S :call <SID>Destringify()<CR>

" Invoke terminal command without prompt and then redraw.
command! -nargs=+ Silent execute 'silent <args>' | redraw!

" Set the tab width for the current filetype
function! <SID>TabWidth(width)
  execute "set tabstop=".a:width
  execute "set shiftwidth=".a:width
  execute "set softtabstop=".a:width
  echo "Tab width is now ".a:width
endfunction
command! -nargs=1 TabWidth :call <SID>TabWidth(<f-args>)

" Toggle task list bullet
function! <SID>TaskToggle()
  " Get current line
  let l:line = getline('.')

  " Get the ' ' or 'x' character from within the task bullet
  let l:pattern = '[-\*+] \[\zs[ x]\ze]'
  let l:char = matchstr(l:line, l:pattern)

  " Toggle the ' ' or 'x' character
  if l:char == 'x'
    let l:char = ' '
  else
    let l:char = 'x'
  endif

  " Replace the current line with a new one
  call setline(line('.'), substitute(l:line, l:pattern, l:char, ''))
endfunction
command! TaskToggle :call <SID>TaskToggle()
nnoremap <leader>x :TaskToggle<CR>

" {Dis,En}able macro mode, use <CR> to repeat last macro
command! MacroModeEnable :call macro_mode#enable()
command! MacroModeDisable :call macro_mode#disable()