Austin Allman
PortfolioBitbucketResumeContact


" folding of this file
" vim:set foldmethod=marker:

" Variables {{{

set autoindent
set cursorline
set foldcolumn=4
set laststatus=2
set lcs=tab:¬ ,trail:·,nbsp:␣
set list
set nowrap
set number
set relativenumber
set scrolloff=8
set shiftwidth=2
set showcmd
set showtabline=2
set sidescroll=1
set sidescrolloff=16
set signcolumn=yes
set softtabstop=2
set spelllang=en_us
set splitbelow
set splitright
set switchbuf=useopen,usetab
set tabpagemax=100
set tabstop=2
set updatetime=250
set wildmenu

let mapleader=" "
let g:netrw_banner=0
let g:use_coc=0


" }}}
" Mappings {{{

" Map Related Functions {{{
" Initialize the custom variable to an empty dictionary
let s:my_diff_buffers = {}

function! ToggleGitGutterDiffOrig()
  for [k, v] in items(s:my_diff_buffers)
    if (bufnr('%') == k && buflisted(v)) || bufnr('%') == v
      " The buffer is open, so close the split
      execute 'bwipeout ' . v
      call remove(s:my_diff_buffers, k)
      return
    endif
  endfor

  " The buffer is closed, so open the split and store the buffer number
  let splitdir = &splitright
  let &splitright = 0
  call gitgutter#difforig()
  let s:my_diff_buffers[bufnr('%')] = bufnr('$')
  let &splitright =  splitdir
endfunction
" }}}

" Fix arrow keys breaking when remapped
imap <Esc>[A <Up>
imap <Esc>[B <Down>
imap <Esc>[C <Right>
imap <Esc>[D <Left>

" Make redo more sensible
nnoremap U <C-R>

" Copy to system clipboard
vnoremap <C-c> "+y
nnoremap <C-c> "+yy

" Navigation
noremap  <silent> <Up>   gk
noremap  <silent> <Down> gj
inoremap <silent> <Up>   <C-o>gk
inoremap <silent> <Down> <C-o>gj
noremap  <silent> <Home> g<Home>
noremap  <silent> <End>  g<End>
inoremap <silent> <Home> <C-o>g<Home>
inoremap <silent> <End>  <C-o>g<End>

" Tab navigation
nnoremap <silent> <C-Left>  :tabprevious<CR>
nnoremap <silent> <C-Right> :tabnext<CR>
nnoremap <silent> <A-Left>  :silent! tabmove -1<CR>
nnoremap <silent> <A-Right> <C-w>:silent! tabmove +1<CR>
inoremap <C-Left> <Esc><C-Left>
inoremap <C-Right> <Esc><C-Right>
inoremap <A-Left> <Esc><A-Left>
inoremap <A-Right> <Esc><A-Right>
tnoremap <silent> <C-Left>  <C-w>:tabprevious<CR>
tnoremap <silent> <C-Right> <C-w>:tabnext<CR>
tnoremap <silent> <A-Left>  <C-w>:silent! tabmove -1<CR>
tnoremap <silent> <A-Right> <C-w>:silent! tabmove +1<CR>

" Fold navigation
nnoremap <silent> <C-Up>   zk
nnoremap <silent> <C-Down> zj
nnoremap <silent> <A-Up>   [z
nnoremap <silent> <A-Down> ]z

" Split navigation
nnoremap <silent> <leader><Left>  <C-W>h
nnoremap <silent> <leader><Right> <C-W>l
nnoremap <silent> <leader><Up>    <C-W>k
nnoremap <silent> <leader><Down>  <C-W>j

" Resize splits
nnoremap <silent> <C-S-Left>  <C-W><
nnoremap <silent> <C-S-Right> <C-W>>
nnoremap <silent> <C-S-Up>    <C-W>+
nnoremap <silent> <C-S-Down>  <C-W>-

tnoremap <Esc><Esc> <C-><C-N>
nnoremap <C-d> :if &buftype == "terminal" <Bar> q <Bar> endif<CR>

" Toggle folds
nnoremap <Space> za
vnoremap <Space> za

" Define function text-object
omap if :normal Vif<CR>
vnoremap if aBob^V

" Goto files in a new tab
nnoremap <silent> gf <C-w>gf

" Open fzf :Files
nnoremap <silent> <leader>f :Files<CR>
nnoremap <silent> <leader>p :GFiles<CR>

" Goto definition using ctags if ctags is installed
nnoremap <silent> <C-]> <C-w><C-]><C-w>T

" Open terminal
nnoremap <silent> <leader>t :term<CR><C-w>T<C-w>:setlocal nonumber norelativenumber foldcolumn=0 signcolumn=no <bar> startinsert<CR>

" Popup spellsuggest
nnoremap <silent> <leader>s a<C-x>s

" Open help in a tab rather than a split
cnoreabbrev <expr> h getcmdtype() == ":" && getcmdline() == 'h' ? 'tab help' : 'h'

" Toggle Margins
nnoremap <silent> <F1> :Margin<CR>

" Map the function to the F2 key
nnoremap <silent> <F2> :call ToggleGitGutterDiffOrig()<CR>

" Toggle syntax highlighting
map <silent> <F6> :if exists("g:syntax_on") <Bar> syntax off <Bar> else <Bar> syntax enable <Bar> endif <CR>
"
" Toggle list
map <silent> <F7> :if &list <Bar> set nolist <Bar> else <Bar> set list <Bar> endif <CR>

" }}}
" Commnds {{{

" Enable wrapping without wrapping in the middle of a word
command                 Wrap     setlocal wrap linebreak breakat&vim

" For renaming files with numbers when bulk renaming in vifm
command -range          Renumber let i=1        | <line1>,<line2>g/d*/ s//=i/ | let i+=1
command -range -nargs=1 Refrom   let i=<f-args> | <line1>,<line2>g/d*/ s//=i/ | let i+=1

command!                Diff     GitGutterDiffOrig

" Show the highlight group of the current cursor position in vim
function! SynGroup()
  let l:s = synID(line('.'), col('.'), 1)
  echo synIDattr(l:s, 'name') . ' -> ' . synIDattr(synIDtrans(l:s), 'name')
endfun
command SynGroup call SynGroup()

command! Gadd Git add % | echo "File added"

let s:margin_left_buffers = {}
let s:margin_right_buffers = {}

function! CreateMargins()
  for [k, v] in items(s:margin_left_buffers)
    if bufnr('%') == k || bufnr('%') == v
      " The buffer is open, so close the split
      execute 'bwipeout ' . s:margin_left_buffers[k]
      execute 'bwipeout ' . s:margin_right_buffers[k]
      call remove(s:margin_left_buffers, k)
      call remove(s:margin_right_buffers, k)
      return
    endif
  endfor
  for [k, v] in items(s:margin_right_buffers)
    if bufnr('%') == v
      " The buffer is open, so close the split
      execute 'bwipeout ' . s:margin_left_buffers[k]
      execute 'bwipeout ' . s:margin_right_buffers[k]
      call remove(s:margin_left_buffers, k)
      call remove(s:margin_right_buffers, k)
      return
    endif
  endfor

  let win_width = winwidth(0)
  let documentwidth = 80 " float2nr(&columns * 0.65)
  let marginwidth = float2nr(abs(win_width - documentwidth) / 2)

  let s:bufnum = bufnr('%')

  " Create left margin buffer
  execute 'leftabove vertical new'
  let s:margin_left_buffers[s:bufnum] = bufnr('$')
  execute 'vertical resize ' . (marginwidth - 1)
  setlocal buftype=nofile bufhidden=hide nobuflisted noswapfile nowrap norelativenumber nonumber readonly foldcolumn=0 signcolumn=no
  silent! setlocal fillchars=
  normal! ggVGd

  " Create right margin buffer
  wincmd l
  execute 'rightbelow vertical new'
  let s:margin_right_buffers[s:bufnum] = bufnr('$')
  execute 'vertical resize ' . (abs(win_width - documentwidth) - marginwidth - 1)
  setlocal buftype=nofile bufhidden=hide nobuflisted noswapfile nowrap norelativenumber nonumber readonly foldcolumn=0 signcolumn=no
  silent! setlocal fillchars=
  normal! ggVGd

  wincmd p
endfunction
command! Margin call CreateMargins()
" }}}
" Autocmmands {{{

  " Filetype {{{
  filetype plugin on
  syntax on

  autocmd FileType css        setlocal expandtab
  autocmd FileType html       setlocal expandtab
  autocmd FileType javascript setlocal expandtab
  autocmd FileType lua        setlocal expandtab
  autocmd FileType markdown   setlocal expandtab
  autocmd FileType php        setlocal expandtab shiftwidth=4 softtabstop=4 tabstop=4
  autocmd FileType python     setlocal expandtab

  autocmd FileType text       setlocal wrap linebreak breakat&vim spell nonumber norelativenumber signcolumn=no foldcolumn=0
  autocmd FileType markdown   setlocal wrap linebreak breakat&vim spell nonumber norelativenumber signcolumn=no foldcolumn=0
  " }}}


  augroup TrimWhitespaceGroup
    autocmd!
    autocmd BufWritePre * %s/s+$//e
  augroup END
  " autocmd BufEnter,BufRead * lcd %:p:h | let git_toplevel = system('git rev-parse --show-toplevel 2>/dev/null') | if v:shell_error == 0 && git_toplevel != "" | execute 'lcd '.git_toplevel | endif

" }}}
" Autocomplete {{{

" If we are using Conquer of Completion configure vim for it's autocomplete
" otherwise use my inhouse method for autocomplete.
if g:use_coc
  " CoC Autocomplete {{{
  " PUM (pop up menu) navigation remapping
  function! s:check_back_space() abort
    let col = col('.') - 1
    return !col || !(getline('.')[col - 1] == "." || getline('.')[col - 1] =~ "w")
  endfunction

  inoremap <silent> <expr> <Up>   coc#pum#visible() ? coc#pum#prev(1) : "<C-o>gk"
  inoremap <silent> <expr> <Down> coc#pum#visible() ? complete_info().selected == -1 ? coc#pum#next(2) : coc#pum#next(1) : "<C-o>gj"

  inoremap <silent> <expr> <TAB>
         pumvisible() ? complete_info().selected == -1 ? "<C-n><C-y>" : "<C-y>" :
         <SID>check_back_space() ? "<TAB>" :
         coc#refresh()

  inoremap <expr> <CR>
         pumvisible() && !&ft ==# "netrw"?
         complete_info().selected == -1 ? "<C-n><C-y>" : "<C-y>" :
         "<CR>"

  " Enable text wrapping and configure it to not break mid word for text
  " and markdown filetypes
  autocmd FileType *        set nospell
  autocmd FileType text     set spell wrap linebreak breakat&vim
  autocmd FileType markdown set spell wrap linebreak breakat&vim

  " }}}
else
  " Custom Autocomplete {{{
  " coc.nvim is not installed

  " Configure autocomplete
  set omnifunc=syntaxcomplete#Complete
  set completeopt+=menuone,noselect,noinsert

  " Initialize both buffer specific variables for managing autocomplete
  " if they have not already been set
  "
  " - b:acc (or auto complete combo) is used to choose which built-in
  "   autocomplete key combination to use. This can be set based on the
  "   filetype or manually.
  "
  " - b:pumdisable is used to shut off the autocomplete. On excessively
  "   large files autocomplete as you type can cause serious performance
  "   issues and this is needed for files that are thousands of lines
  "   long.
  autocmd BufEnter * if !exists("b:acc") | let b:acc="<C-x><C-n>" | endif
  autocmd BufEnter * if !exists("b:pumdisable") | let b:pumdisable=1 | endif

  " This is checked in place of pumvisible() to also check b:pumdisable
  function DontShowPum()
    return pumvisible() || b:pumdisable
  endfunction
  " Quick commands to switch the value of b:pumdisable
  command ACdisable let b:pumdisable = 1
  command ACenable  let b:pumdisable = 0

  " Set the autocomplete mode
  command ACnormal  let b:acc = "<C-x><C-n>"
  command ACspell   let b:acc = "<C-x><C-k>"
  command AComni    let b:acc = "<C-x><C-o>"
  command ACtags    let b:acc = "<C-x><C-]>"

  " Pop up menu navigation
  inoremap <silent> <expr> <Up>   pumvisible() ? "<C-p>" : "<C-o>gk"
  inoremap <silent> <expr> <Down> pumvisible() ? complete_info().selected == -1 ? "<C-n><C-n>" : "<C-n>" : "<C-o>gj"
  inoremap <expr> <CR>
         pumvisible() ? complete_info().selected == -1 ? "<C-n><C-y>" : "<C-y>" : "<CR>"
  inoremap <expr> <Tab>
         pumvisible() ? complete_info().selected == -1 ? "<C-n><C-y>" : "<C-y>" :
         getline('.')[col('.') - 2] == "." ? b:acc :
         getline('.')[col('.') - 2] =~ "\w" ? b:acc : "<Tab>"

  " Show autocomplete pop up menu whenver a letter key or _ is pressed.
  inoremap <expr> a DontShowPum() ? "a" : b:acc . "a"
  inoremap <expr> A DontShowPum() ? "A" : b:acc . "A"
  inoremap <expr> b DontShowPum() ? "b" : b:acc . "b"
  inoremap <expr> B DontShowPum() ? "B" : b:acc . "B"
  inoremap <expr> c DontShowPum() ? "c" : b:acc . "c"
  inoremap <expr> C DontShowPum() ? "C" : b:acc . "C"
  inoremap <expr> d DontShowPum() ? "d" : b:acc . "d"
  inoremap <expr> D DontShowPum() ? "D" : b:acc . "D"
  inoremap <expr> e DontShowPum() ? "e" : b:acc . "e"
  inoremap <expr> E DontShowPum() ? "E" : b:acc . "E"
  inoremap <expr> f DontShowPum() ? "f" : b:acc . "f"
  inoremap <expr> F DontShowPum() ? "F" : b:acc . "F"
  inoremap <expr> g DontShowPum() ? "g" : b:acc . "g"
  inoremap <expr> G DontShowPum() ? "G" : b:acc . "G"
  inoremap <expr> h DontShowPum() ? "h" : b:acc . "h"
  inoremap <expr> H DontShowPum() ? "H" : b:acc . "H"
  inoremap <expr> i DontShowPum() ? "i" : b:acc . "i"
  inoremap <expr> I DontShowPum() ? "I" : b:acc . "I"
  inoremap <expr> j DontShowPum() ? "j" : b:acc . "j"
  inoremap <expr> J DontShowPum() ? "J" : b:acc . "J"
  inoremap <expr> k DontShowPum() ? "k" : b:acc . "k"
  inoremap <expr> K DontShowPum() ? "K" : b:acc . "K"
  inoremap <expr> l DontShowPum() ? "l" : b:acc . "l"
  inoremap <expr> L DontShowPum() ? "L" : b:acc . "L"
  inoremap <expr> m DontShowPum() ? "m" : b:acc . "m"
  inoremap <expr> M DontShowPum() ? "M" : b:acc . "M"
  inoremap <expr> n DontShowPum() ? "n" : b:acc . "n"
  inoremap <expr> N DontShowPum() ? "N" : b:acc . "N"
  inoremap <expr> o DontShowPum() ? "o" : b:acc . "o"
  inoremap <expr> O DontShowPum() ? "O" : b:acc . "O"
  inoremap <expr> p DontShowPum() ? "p" : b:acc . "p"
  inoremap <expr> P DontShowPum() ? "P" : b:acc . "P"
  inoremap <expr> q DontShowPum() ? "q" : b:acc . "q"
  inoremap <expr> Q DontShowPum() ? "Q" : b:acc . "Q"
  inoremap <expr> r DontShowPum() ? "r" : b:acc . "r"
  inoremap <expr> R DontShowPum() ? "R" : b:acc . "R"
  inoremap <expr> s DontShowPum() ? "s" : b:acc . "s"
  inoremap <expr> S DontShowPum() ? "S" : b:acc . "S"
  inoremap <expr> t DontShowPum() ? "t" : b:acc . "t"
  inoremap <expr> T DontShowPum() ? "T" : b:acc . "T"
  inoremap <expr> u DontShowPum() ? "u" : b:acc . "u"
  inoremap <expr> U DontShowPum() ? "U" : b:acc . "U"
  inoremap <expr> v DontShowPum() ? "v" : b:acc . "v"
  inoremap <expr> V DontShowPum() ? "V" : b:acc . "V"
  inoremap <expr> w DontShowPum() ? "w" : b:acc . "w"
  inoremap <expr> W DontShowPum() ? "W" : b:acc . "W"
  inoremap <expr> x DontShowPum() ? "x" : b:acc . "x"
  inoremap <expr> X DontShowPum() ? "X" : b:acc . "X"
  inoremap <expr> y DontShowPum() ? "y" : b:acc . "y"
  inoremap <expr> Y DontShowPum() ? "Y" : b:acc . "Y"
  inoremap <expr> z DontShowPum() ? "z" : b:acc . "z"
  inoremap <expr> Z DontShowPum() ? "Z" : b:acc . "Z"
  inoremap <expr> _ DontShowPum() ? "_" : b:acc . "_"

  " Enable autocomplete for any programming language I use or could
  " conceivably learn
  autocmd FileType markdown        setlocal wrap linebreak breakat&vim | ACspell
  autocmd FileType text            setlocal wrap linebreak breakat&vim | ACspell

  autocmd FileType bash            ACenable
  autocmd FileType c               ACenable
  autocmd FileType cpp             ACenable
  autocmd FileType cs              ACenable
  autocmd FileType css             ACenable
  autocmd FileType dosbatch        ACenable
  autocmd FileType html            ACenable
  autocmd FileType java            ACenable
  autocmd FileType javascript      ACenable
  autocmd FileType javascriptreact ACenable
  autocmd FileType json            ACenable
  autocmd FileType lua             ACenable
  autocmd FileType objc            ACenable
  autocmd FileType php             ACenable
  autocmd FileType python          ACenable
  autocmd FileType rust            ACenable
  autocmd FileType sass            ACenable
  autocmd FileType scheme          ACenable
  autocmd FileType scss            ACenable
  autocmd FileType sh              ACenable
  autocmd FileType sql             ACenable
  autocmd FileType vim             ACenable
  autocmd FileType winbatch        ACenable
  autocmd FileType xml             ACenable

  " }}}
endif

" }}}
" Custom Tab Line {{{

let g:begintab = 1
let g:endtab = 1
let g:previoustab = 1
let g:direction = -1
let g:blinking = 1

" Set cursor character to blink on a timer on :terminal tab
let g:cursorchar = '█'
let g:cursor = g:cursorchar
function! BlinkCursor(timerID)
  if g:cursor == ' '
    let g:cursor = '█'
  else
    let g:cursor = ' '
  endif
  if g:blinking == 0
    g:cursor = g:cursorchar
  endif
  silent redrawtabline
endfunction
call timer_start(1000, 'BlinkCursor', {'repeat': -1})

" Get the name of the selected buffer on a tab page.
function! GetTabName(tabnr)
  let bufnr = tabpagebuflist(a:tabnr)[tabpagewinnr(a:tabnr)-1]
  let filename = fnamemodify(bufname(bufnr), ':t')
  if filename == ''
    let filename = '[No Name]'
  endif

  let j = ' '
  if getbufvar(bufnr, '&modified') != 0 && filename != 'bash'
    let j .= '+ '
  endif

  if filename == 'bash'
    let cwd = getcwd()
    let current_folder = matchstr(cwd, "/\zs[^/]*$")
    let filename = current_folder
    if $USER == "root"
      let filename .= '# ' .. g:cursor
    else
      let filename .= '$ ' .. g:cursor
    endif
  endif

  let j .= filename
  let j .= ' '
  return j
endfunction

" Generate the tabline text
function! MyTabLine()
  let maxwidth = &columns
  let s = ''
  let active = tabpagenr()
  " If the active tab has changed figure out which
  " direction you tabbed
  if g:previoustab != active
    if g:previoustab > active
      let g:direction = -1
    else
      let g:direction = 1
    endif
    let g:previoustab = active
  endif
  " If you tab left set the right-most tab to be displayed
  " to the current active tab number. If you tab right set
  " the left-most tab to be displayed to the current active
  " tab number.
  if g:direction == 1
    let g:begintab = active
  else
    let g:endtab = active
  endif
  " If the starting tab is greater than the ending tab reset both
  if g:begintab > g:endtab
    let g:begintab = active
    let g:endtab = active
  endif
  let numtabs = tabpagenr('$')
  if g:endtab > numtabs
    g:endtab = numtabs
  endif

  " Get the size of each individual tab.
  let sizes = []
  for i in range(1, numtabs)
    call add(sizes, strwidth(GetTabName(i)))
  endfor

  " Figure out how many tabs will fit on screen by adding tabs in the opposite
  " direction of scroll until they don't fit.
  let currentwidth = 10
  for i in range(g:begintab, g:endtab)
    let currentwidth = currentwidth + sizes[i-1]
  endfor
  let numshown = g:endtab - g:begintab + 1
  while currentwidth < maxwidth && numshown < numtabs
    if g:direction == 1
      if g:begintab > 1
        let currentwidth = currentwidth + sizes[g:begintab-2]
        if currentwidth < maxwidth
          let g:begintab = g:begintab - 1
        endif
      else
        let g:direction = -1
      endif
    else
      if g:endtab < numtabs
        let currentwidth = currentwidth + sizes[g:endtab]
        if currentwidth < maxwidth
          let g:endtab = g:endtab + 1
        endif
      else
        let g:direction = 1
      endif
    endif
    let numshown = g:endtab - g:begintab + 1
  endwhile

  " Add left-scroll button
  if g:begintab > 1
    let s .= '%#TabLineFill#'
    let s .= ' '
    let s .= '%#TabLine#'
    let s .= ' < '
    let s .= '%#TabLineFill#'
    let s .= ' '
  endif

  for i in range(g:begintab, g:endtab)
    " set the highlight group for the active tab
    if i == active
      let s .= '%#TabLineSel#'
    else
      let s .= '%#TabLine#'
    endif
    let s .= GetTabName(i)
  endfor

  " Add right-scroll button
  if g:endtab < tabpagenr('$')
    let s .= '%#TabLineFill#'
    let s .= ' '
    let s .= '%#TabLine#'
    let s .= ' > '
    let s .= '%#TabLineFill#'
    let s .= ' '
  endif

  " fill the rest with TabLineFill
  let s .= '%#TabLineFill#'
  let s .= ' '

  " return the tabline string
  return s
endfunction

set tabline=%!MyTabLine()

" }}}
" Custom Status Line {{{

set laststatus=2
set statusline=
set statusline+=%{b:gitbranch}
set statusline+=%f
set statusline+= %m
set statusline+=%=
set statusline+=%l,%c %P

function! StatuslineGitBranch()
  let b:gitbranch=""
  if &modifiable
    try
      let l:dir=expand('%:p:h')
      let l:gitrevparse = system("git -C ".l:dir." rev-parse --abbrev-ref HEAD")
      if !v:shell_error
        let b:gitbranch="(".substitute(l:gitrevparse, 'n', '', 'g').") "
      endif
    catch
    endtry
  endif
endfunction

augroup GetGitBranch
  autocmd!
  autocmd VimEnter,WinEnter,BufEnter * call StatuslineGitBranch()
augroup END

" }}}
" Custom Fold Text {{{

" A prettier formatting for folds. Used primarily for folding functions
exec 'hi FoldMarker gui=NONE cterm=NONE guibg=NONE ctermbg=NONE guifg=' . synIDattr(synIDtrans(hlID('Folded')), 'fg', 'gui') . ' ctermfg=' . synIDattr(synIDtrans(hlID('Folded')), 'fg', 'cterm')
autocmd ColorScheme * exec 'hi FoldMarker gui=NONE cterm=NONE guibg=NONE ctermbg=NONE guifg=' . synIDattr(synIDtrans(hlID('Folded')), 'fg', 'gui') . ' ctermfg=' . synIDattr(synIDtrans(hlID('Folded')), 'fg', 'cterm')
autocmd BufEnter,BufRead * match FoldMarker /([a-zA-Z]+(.*){{{.*|}}})/
set foldtext=MyFoldText()
function! MyFoldText()
  if &diff
    return repeat('=',&columns)
  endif
  let line = getline(v:foldstart)
  let line2 = getline(v:foldstart+1)
  let n = v:foldend - v:foldstart + 1
  let info = '  ' . n . " lines"
  if match( line, '^[ t]*(/*|//)[*/\]*[ t]*$' ) == 0
    let initial = substitute( line, '^([ t])*(/*|//)(.*)', '12', '' )
    let linenum = v:foldstart + 1
    while linenum < v:foldend
      let line = getline( linenum )
      let comment_content = substitute( line, '^([ t/*]*)(.*)$', '2', 'g' )
      if comment_content != ''
        break
      endif
      let linenum = linenum + 1
    endwhile
    let sub = initial . ' ' . comment_content
  else
    let indent_level = indent(v:foldstart)
    let indent = repeat(' ',indent_level)
    let sub = substitute( line, '^[ t]*(.*)$', indent.'1', 'g')
    let startbrace = substitute( line, '^.*{[ t]*$', '{', 'g')
    let startbrace2 = substitute( line2, '^[ t]*{[ t]*$', '{', 'g')
    if startbrace2 == '{'
      let startbrace = startbrace2
      let sub = sub . ' {'
    endif
    if startbrace == '{'
      let startbrace = '{'
      let line = getline(v:foldend)
      let endbrace = substitute( line, '^[ t]*}(.*)$', '}', 'g')
      if endbrace == '}'
        let sub = sub.substitute( line, '^[ t]*}(.*)$', '...}1', 'g')
      endif
    endif
  endif
  let sub = substitute(sub, '([ t]*)W*(.*){'.'{{.*', '1* 2', '')
  let editor_width = winwidth(0) - getwininfo(win_getid())[0].textoff
  let sub = sub . repeat(' ', winsaveview().leftcol + winwidth(0) )
  let sub = strpart( sub, winsaveview().leftcol, editor_width - strlen( info ) - 1)
  return sub . info . " "
endfunction

" }}}
" Enable Truecolor {{{

" Enable truecolor
set termguicolors

" Correct RGB escape codes for vim inside tmux
if !has('nvim') && $TERM ==# 'screen-256color'
  let &t_8f = "<Esc>[38;2;%lu;%lu;%lum"
  let &t_8b = "<Esc>[48;2;%lu;%lu;%lum"
endif

" }}}
" Install Plugins {{{

" Automatically install vim-plug plugin manager if not already installed
let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim'
if empty(glob(data_dir . '/autoload/plug.vim'))
  silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs  https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
  autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif

" Begin plugin list
call plug#begin()

Plug 'drazil100/dusklight.vim'

if g:use_coc
  " Conquer of Completion
  Plug 'neoclide/coc.nvim', {'branch': 'release'}
endif
" GitGutter for viewing git differences in SignColum
Plug 'airblade/vim-gitgutter'
" Git plugin for vim
Plug 'tpope/vim-fugitive'
" vim-surround allows editing parentheses, brackets, quotes, XML tags, and more
Plug 'tpope/vim-surround'
" vim-commentary offers commands to quickly comment and uncomment lines
Plug 'tpope/vim-commentary'
" vim-repeat allows using . to repeat plugin mappings
Plug 'tpope/vim-repeat'
" guicolorscheme converts gui colors to closest cterm colors.
Plug 'vim-scripts/guicolorscheme.vim'
" traces highlights search matches and gives previews for replaced text
Plug 'markonm/traces.vim'
" automatic ctags
if executable('ctags')
  Plug 'ludovicchabant/vim-gutentags'
endif
" Fuzzy Finder
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'

" COLOR PLUGINS
if !has('nvim')
  Plug 'BourgeoisBear/clrzr'
endif

" Plug 'ap/vim-css-color'
" Plug 'gko/vim-coloresque'

" DISABLED
" neural allows you to access chatgpt within vim
" Plug 'dense-analysis/neural'

call plug#end()

" }}}
" Configure Plugins {{{

" Use my personal colorscheme
colorscheme dusklight

" Extension list for Conquer of Completion
let g:coc_global_extensions = ['coc-json', 'coc-tsserver']

" Open files in a new tab when using fzf
let g:fzf_action = { 'enter': 'tab split' }

" GitGutter settings
let g:gitgutter_sign_added = '|+'
let g:gitgutter_sign_modified = '|±'
let g:gitgutter_sign_removed = '|-'
let g:gitgutter_sign_removed_first_line = '|⊼'
let g:gitgutter_sign_modified_removed = '|≥'

" }}}