""" General settings
set autoindent
set backspace=indent,eol,start
set complete-=i      " Set the matches for insert mode completion
set encoding=utf-8   " Set encoding
set expandtab        " Use spaces instead of tabs
set formatoptions+=j " Delete comment character when joining commented lines
set hlsearch         " Highlight all search results
set laststatus=2     " Always status line
set ignorecase       " Ignore cases when searching
set incsearch        " Incremental search
set linebreak        " Break lines at word (requires Wrap lines)
set nowrap           " Don't add an actual linebreak when wrapping
set ruler            " Show line & col number of cursor position
set shiftwidth=4     " Number of auto-indent spaces
set showmatch        " Highlight matching brace
set smartcase        " Better searching btw cases
set smartindent      " Autoindent when starting a new line
set smarttab         " Tab insertion & deletion
set tabstop=4        " One tab = 4 spaces
set textwidth=80     " Line wrap (number of cols)
set visualbell       " Use visual bell (no beeping)
set wildmenu         " Helpful completion menu

" start with crosshairs visible
set cursorline! cursorcolumn!

" Strings to use in 'list' mode and for the :list command
set listchars=tab:>\ ,trail:-,extends:>,precedes:<,nbsp:+

""" Enable syntax
"if has('syntax') && !exists('g:syntax_on')
"    syntax enable
"endif

""" Make , the leader key
let mapleader = ","

" easy escape
imap fd <Esc>

" send to ix.io
noremap <silent> <leader>i :w !ix<CR>

" edit files and buffers, relative to local
nmap ,e  :edit
nmap ;e  :edit <C-R>=expand("%:h") . "/" <CR>
nmap ,o  :buffer
nmap ;o  :buffer <C-R>=expand("%:h") . "/" <CR>

" tags
nmap ,j  :tag

" list buffers
nmap ,l  :ls<cr>

" kill buffer
nmap ,k  :bdelete<cr>

" insert current date
nmap <silent> ,d  :r !date +\%Y.\%m.\%d<cr>
nmap <silent> ,D  :r !date +\%Y.\%m.\%d..\%H.\%M.\%S<cr>

" grep (ripgrep)
nmap ,g  :Rg

" format haskell code
nmap ,f  :!ormolu -m inplace %<cr>

" clear out trailing whitespace and lines ending in whitespace
nmap <silent> ,w   :%s/[\t ]\+$//e<cr>

" Use <C-L> to clear the highlighting of :set hlsearch.
if maparg('<C-L>', 'n') ==# ''
    nnoremap <silent> <C-L> :nohlsearch<C-R>=has('diff')?'<Bar>diffupdate':''<CR><CR><C-L>
endif

" trailing spaces are always bad
syntax match Warning   display "\s\+$"
" mixed tabs and spaces
syntax match Warning   display " \+\t"
syntax match Warning   display "\t\+ "

""" Easily find cursor with crosshair (,c)
":hi CursorLine   cterm=NONE term=reverse ctermbg=7 guibg=Grey90
":hi CursorColumn cterm=NONE term=reverse ctermbg=7 guibg=Grey90
:nnoremap <Leader>c :set cursorline! cursorcolumn!<CR>

""" File browser
let g:netrw_banner=0       " Disable file browser banner
let g:netrw_liststyle=3    " Tree view

""" CTAGS shortcuts
" open definition in a new tab:
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
" open definition in a vertical split:
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

""" Colors!
set termguicolors
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"

""" Show highlighting groups for current word
nmap <C-S-P> :call <SID>SynStack()<CR>
function! <SID>SynStack()
    if !exists("*synstack")
        return
    endif
    echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')
endfunc

set background=dark
colorscheme flattened_dark
" disable my color scheme, it doesn't work with vimdiff
"let g:colors_name = 'bs_monochrome'
"
"let s:white  = ['White', 15]
"let s:black  = ['#0e1111', 16]
"let s:dblack = ['#111111', 1]
"let s:bgray  = ['#181818', 233]
"let s:lgray  = ['LightGray', 255]
"let s:cgray  = ['#737373', 243]
"let s:dgray  = ['DarkGray', 248]
"let s:sblue  = ['LightBlue', 67]
"let s:yellow = ['LightYellow', 226]
"let s:red    = ['LightRed', 160]
"let s:green  = ['LightGreen', 28]
"let s:purple = ['LightMagenta', 13]
""
"let s:default_fg = s:lgray
"let s:default_bg = s:black
"
"let s:italic    = 'italic'
"let s:bold      = 'bold'
"let s:underline = 'underline'
"let s:none      = 'NONE'
"
"let s:default_lst = []
"let s:default_str = ''
"
"if !exists("g:monochrome_italic_comments")
"  let g:monochrome_italic_comments = 0
"endif
"let s:comment_attr = g:monochrome_italic_comments ? s:italic : s:none
""
"" A function for setting colors, if I want it...
"function! s:hi(...)
"    let group = a:1
"    let fg    = get(a:, 2, s:default_fg)
"    let bg    = get(a:, 3, s:default_bg)
"    let attr  = get(a:, 4, s:default_str)
"
"    let cmd = ['hi', group]
"
"    if fg != s:default_lst
"        call add(cmd, 'guifg='.fg[0])
"        call add(cmd, 'ctermfg='.fg[1])
"    endif
"
"    if bg != s:default_lst && bg != s:default_bg
"        call add(cmd, 'guibg='.bg[0])
"        call add(cmd, 'ctermbg='.bg[1])
"    endif
"
"    if attr != s:default_str
"        call add(cmd, 'gui='.attr)
"        call add(cmd, 'cterm='.attr)
"    endif
"
"    exec join(cmd, ' ')
"endfunction
"
"call s:hi('Normal')
"highlight clear Cursor
"highlight clear CursorLine " clear the underline nonsense
"call s:hi('Cursor', s:black, s:sblue)
"call s:hi('lCursor', s:black, s:sblue)
"call s:hi('CursorLine', s:black, s:sblue, s:none)
"call s:hi('CursorLineNr', s:white, s:sblue, s:bold)
"call s:hi('CursorColumn', s:black, s:sblue, s:none)
"call s:hi('ColorColumn', s:lgray, s:dblack, s:none)
"call s:hi('Search', s:black, s:purple)
"call s:hi('Visual', s:black, s:green)
"call s:hi('ErrorMsg', s:white, s:red)
"call s:hi('StatusLine', s:black, s:purple)
"call s:hi('StatusLineNC', s:black, s:purple)
"call s:hi('VertSplit', s:black, s:purple)
""
""" Tildes at the bottom of a buffer, etc.
"call s:hi('NonText', s:dgray)
"
"" Folding.
"call s:hi('FoldColumn', s:dgray)
"call s:hi('Folded')
"
"" Line numbers gutter.
"call s:hi('LineNr', s:dgray)
"
"" Small arrow used for tabs.
"call s:hi('SpecialKey', s:sblue, s:default_bg, s:bold)
"
"" File browsers.
"call s:hi('Directory', s:white, s:default_bg, s:bold)
"
"" Help.
"call s:hi('helpSpecial')
"call s:hi('helpHyperTextJump', s:sblue, s:default_bg, s:underline)
"call s:hi('helpNote')
"
"" Popup menu.
"call s:hi('Pmenu', s:white, s:sblue)
"call s:hi('PmenuSel', s:sblue, s:white)
"
"" Notes.
"call s:hi('Todo', s:black, s:yellow, s:bold)
"
"" Signs.
"call s:hi('SignColumn')
"
"" --- Languages ---------------------------------------------------------------
"call s:hi('Statement', s:white, s:default_bg, s:bold)
"call s:hi('PreProc', s:white, s:default_bg, s:bold)
"call s:hi('String', s:sblue)
"call s:hi('Comment', s:cgray, s:default_bg, s:comment_attr)
"call s:hi('Constant')
"call s:hi('Type', s:white, s:default_bg, s:bold)
"call s:hi('Function', s:white)
"call s:hi('Identifier')
"call s:hi('Special')
"call s:hi('MatchParen', s:black, s:lgray)
"call s:hi('vimOption')
"call s:hi('vimGroup')
"call s:hi('vimHiClear')
"call s:hi('vimHiGroup')
"call s:hi('vimHiAttrib')
"call s:hi('vimHiGui')
"call s:hi('vimHiGuiFgBg')
"call s:hi('vimHiCTerm')
"call s:hi('vimHiCTermFgBg')
"call s:hi('vimSynType')
"hi link vimCommentTitle Comment
"call s:hi('pythonEscape', s:sblue)
"call s:hi('javaScriptFunction', s:white, s:default_bg, s:bold)
"call s:hi('perlSharpBang', s:cgray)
"call s:hi('perlStringStartEnd', s:sblue)
"call s:hi('perlStringEscape', s:sblue)
"call s:hi('perlMatchStartEnd', s:sblue)
"call s:hi('elixirAlias', s:default_fg, s:default_bg, s:none)
"call s:hi('elixirDelimiter', s:sblue)
"call s:hi('elixirSelf', s:default_fg, s:default_bg, s:none)
"" For ||, ->, etc.
"call s:hi('elixirOperator')
"" Module attributes like @doc or @type.
"hi link elixirVariable Statement
"" While rendered as comments in other languages, docstrings are strings,
"" experimental.
"hi link elixirDocString String
"hi link elixirDocTest String
"hi link elixirStringDelimiter String
"call s:hi('rubyConstant')
"call s:hi('rubySharpBang', s:cgray)
"call s:hi('rubyStringDelimiter', s:sblue)
"call s:hi('rubyStringEscape', s:sblue)
"call s:hi('rubyRegexpEscape', s:sblue)
"call s:hi('rubyRegexpAnchor', s:sblue)
"call s:hi('rubyRegexpSpecial', s:sblue)
"
"" --- Diffs --------------------------------------------------------------------
"call s:hi('diffFile', s:cgray)
"call s:hi('diffNewFile', s:cgray)
"call s:hi('diffIndexLine', s:cgray)
"call s:hi('diffLine', s:cgray)
"call s:hi('diffSubname', s:cgray)
"call s:hi('diffAdded', s:white, s:green)
"call s:hi('diffRemoved', s:white, s:red)

" load ~/.vimrc.local last for local overrides
if filereadable('~/.vimrc.local')
    source ~/.vimrc.local
endif