1287 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
			
		
		
	
	
			1287 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
" @incomplete Move all leader definitions to the bottom, so that it's easier to see them.
 | 
						|
" @incomplete Add setup steps (plugins, cache setup, search tool, etc).
 | 
						|
 | 
						|
"###################################################################################################
 | 
						|
"
 | 
						|
" The config is chopped up into sections. These are the headings, which you
 | 
						|
" can use to quickly jump to a particular section:
 | 
						|
 | 
						|
" #0 GLOBALS
 | 
						|
" #1 PLUGINS
 | 
						|
" #2 BASE CONFIG
 | 
						|
" #3 PLUGIN CONFIGS
 | 
						|
" #4 VISUALS
 | 
						|
" #5 CUSTOM FUNCTIONS / COMMANDS
 | 
						|
"
 | 
						|
"###################################################################################################
 | 
						|
 | 
						|
scriptencoding utf-8
 | 
						|
set encoding=utf-8 fileencoding=utf-8 fileencodings=ucs-bom,utf8,prc
 | 
						|
set nocompatible
 | 
						|
filetype off
 | 
						|
 | 
						|
" Store the current system name so that we can conditionally set configs for
 | 
						|
" different platforms
 | 
						|
let s:uname = system("echo -n \"$(uname)\"")
 | 
						|
let s:vim_dir = $HOME . "/.vim"
 | 
						|
let mapleader=","
 | 
						|
 | 
						|
function! IsWindows()
 | 
						|
    if s:uname =~ "mingw" || s:uname =~ "msys"
 | 
						|
        return 1
 | 
						|
    endif
 | 
						|
    return 0
 | 
						|
endfunction
 | 
						|
 | 
						|
if has('termguicolors')
 | 
						|
    set termguicolors
 | 
						|
    " Set Vim-specific sequences for RGB colors
 | 
						|
    let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
 | 
						|
    let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
 | 
						|
endif
 | 
						|
 | 
						|
function! PrintError(msg) abort
 | 
						|
    exec 'normal! \<Esc>'
 | 
						|
    echohl ErrorMsg
 | 
						|
    echomsg a:msg
 | 
						|
    echohl None
 | 
						|
endfunction
 | 
						|
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"#0 GLOBALS
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
 | 
						|
" @note The following globals can be used to customize various functions in
 | 
						|
" this file. The easiest way to set them is in ~/.vimrc.private or an .lvimrc
 | 
						|
" file in the root folder that you want it applied to.
 | 
						|
"
 | 
						|
" Some variables cannot be customized in an .lvimrc because their value is used
 | 
						|
" by settings in this file when its sourced. These have been flagged with a note.
 | 
						|
"
 | 
						|
" Also take note that an .lvimrc has precedence because it's loaded after this
 | 
						|
" and the private vimrc.
 | 
						|
 | 
						|
" --------------------------------------------------------------------------------------------------
 | 
						|
 | 
						|
" @note unsupported in lvimrc
 | 
						|
let g:campo_max_line_length = 100 " Display a vertical bar at x=<n>.
 | 
						|
 | 
						|
" Set the row height of the quickfix pane, which is used to display results
 | 
						|
" from various plugins (like ctrl-p, ripgrep, compilation errors, etc), in rows
 | 
						|
let g:quickfix_pane_height = 20
 | 
						|
 | 
						|
""""""""""""""
 | 
						|
" COLORS
 | 
						|
""""""""""""""
 | 
						|
let g:campo_default_bg_mode = 'dark' " Start vim with the dark theme. Set to 'light' for the light theme.
 | 
						|
let g:campo_dark_theme = 'campo-dark-simple' "'campo-dark-blue'
 | 
						|
let g:campo_light_theme = 'campo-light-simple' "'campo-light'
 | 
						|
let g:campo_theme_use_rainbow_parens = 1
 | 
						|
 | 
						|
""""""""""""""
 | 
						|
" FORMATTING
 | 
						|
""""""""""""""
 | 
						|
" When set to 1, all files will be stripped of trailing whitespace when the
 | 
						|
" file is saved. Set to 0 to disable. You can customize which files are
 | 
						|
" ignored or always stripped; see below.
 | 
						|
let g:campo_strip_trailing_whitespace = 1
 | 
						|
 | 
						|
" If g:campo_strip_trailing_whitespace is 1 then you can stop stripping in
 | 
						|
" specific files by setting this to a list of filenames. This has no effect
 | 
						|
" when g:campo_strip_trailing_whitespace is 0.
 | 
						|
"
 | 
						|
" e.g. let g:campo_files_to_ignore_when_stripping_trailing_whitespace = ['app.h', 'config.h']
 | 
						|
let g:campo_files_to_ignore_when_stripping_trailing_whitespace = []
 | 
						|
 | 
						|
" If g:campo_strip_trailing_whitespace is 0 then you can force whitespace
 | 
						|
" stripping in specific files by setting this to a list of filenames. This has
 | 
						|
" no effect when g:campo_strip_trailing_whitespace is 1.
 | 
						|
 | 
						|
" e.g. let g:campo_files_to_force_stripping_trailing_whitespace = ['app.h', 'config.h']
 | 
						|
let g:campo_files_to_force_stripping_trailing_whitespace = []
 | 
						|
 | 
						|
""""""""""""""
 | 
						|
" SEARCH
 | 
						|
""""""""""""""
 | 
						|
" This is included in the ripgrep args. You can use this to do things like
 | 
						|
" ignore folders in your project or limit the search to specific file types.
 | 
						|
" For example, if you want to ignore the 3rd_party dir and only search C files
 | 
						|
" (remove the backslash from the first quote as that's just here to escape it
 | 
						|
" in this comment string)
 | 
						|
" let g:campo_custom_search_args = \"-g \"!3rd_party/*\" -tc"
 | 
						|
let g:campo_custom_search_args = ""
 | 
						|
 | 
						|
""""""""""""""
 | 
						|
" CTAGS
 | 
						|
""""""""""""""
 | 
						|
 | 
						|
" If != 0 then ctag generation will always happen on a file save, otherwise
 | 
						|
" it'll only be triggered if the file being saved has an extension in the
 | 
						|
" g:campo_extensions_that_run_ctags list.
 | 
						|
let g:campo_force_ctags_regardless_of_extension = 0
 | 
						|
 | 
						|
" If one of these file types are saved then the ctags creation function will be called.
 | 
						|
" You can append to this list in another config like so:
 | 
						|
"   let g:campo_extensions_that_run_ctags = g:campo_extensions_that_run_ctags + ['foo', 'bar']
 | 
						|
let g:campo_extensions_that_run_ctags = ['c','cpp','h','hpp','inc','cs','py','asm','ex','exs']
 | 
						|
 | 
						|
" Default files and directories that ctags should ignore when doing a
 | 
						|
" recursive crawl.
 | 
						|
" @note The CreateCtags function will always ignore .git and node_modules
 | 
						|
" regardless of this variable's value.
 | 
						|
let g:campo_ctags_exclude = ['*.txt', '*.config', '.cache']
 | 
						|
 | 
						|
" This is included in the ctags autocmd args. You can use this to customize
 | 
						|
" how ctags are built.
 | 
						|
" Examples:
 | 
						|
"  * Recursive ctag generation with `let g:campo_custom_ctags_args = '-R'`
 | 
						|
"  * Create tags for specific langauges: `let g:campo_custom_ctags_args = '--languages=C,C++,Elixir'
 | 
						|
"    * You can see a list of languages with `ctags --list-languages`
 | 
						|
"    * For C# you have to escape the ampersand like so: `--languages=C\\#`
 | 
						|
"  * Exclude a directory with `let g:campo_custom_ctags_args = '--exclude=3rd_party'`
 | 
						|
let g:campo_custom_ctags_args = ""
 | 
						|
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"#1 PLUGINS
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
 | 
						|
call plug#begin('~/.vim/plugged')
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" MISC
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
Plug 'bling/vim-airline'              " Enhanced status/tabline.
 | 
						|
Plug 'embear/vim-localvimrc'          " Add a .lvimrc to a folder to override .vimrc config.
 | 
						|
Plug 'tpope/vim-obsession'            " Continuously updated session files (tracks window positions, open folds, etc).
 | 
						|
Plug 'tpope/vim-fugitive'             " Git wrapper (I particularly like :Gblame, which I've wrapped as :Blame)
 | 
						|
Plug 'sir-pinecone/vim-ripgrep'       " Fast grep-like search. Requires ripgrep; install Rust package: `cargo install ripgrep`.
 | 
						|
Plug 'itchyny/vim-cursorword'         " Underlines all instances of the symbol under the cursor.
 | 
						|
Plug 'airblade/vim-gitgutter'         " Displays a git diff in the vim gutter and allows staging/unstaging of hunks.
 | 
						|
Plug 'ctrlpvim/ctrlp.vim'             " Fuzzy file, buffer, mru, tag, etc finder.
 | 
						|
Plug 'majutsushi/tagbar'              " Display ctags in a window, ordered by scope.
 | 
						|
Plug 'tommcdo/vim-lion'               " For text alignment, use gl= and gL=
 | 
						|
Plug 'tpope/tpope-vim-abolish'        " Easily search for, substitute, and abbreviate multiple variants of a word. Add them to `vim/after/plugin/abolish.vim`
 | 
						|
Plug 'vim-scripts/AnsiEsc.vim'        " Ansi escape sequences concealed, but highlighted as specified.
 | 
						|
Plug 'mh21/errormarker.vim'           " Build error highlighting (requires skywind3000/asyncrun.vim).
 | 
						|
Plug 'skywind3000/asyncrun.vim'       " Async commands.
 | 
						|
Plug 'nelstrom/vim-qargs'             " For the GlobalReplaceIt function (i.e. search and replace).
 | 
						|
 | 
						|
if IsWindows()
 | 
						|
    Plug 'suxpert/vimcaps'            " Disable capslock (useful if the OS isn't configured to do so).
 | 
						|
endif
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" COLORS
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
Plug 'luochen1990/rainbow', { 'commit': '1c45e0f' } " Rainbow parens. Locked to an older commit that still works fine on my PC.
 | 
						|
Plug 'vim-airline/vim-airline-themes'
 | 
						|
 | 
						|
if IsWindows()
 | 
						|
    Plug 'godlygeek/csapprox'         " Try to make gvim themes look decent on Windows.
 | 
						|
endif
 | 
						|
 | 
						|
"//////////////////////////////
 | 
						|
" SYNTAX HIGHLIGHTING
 | 
						|
"//////////////////////////////
 | 
						|
 | 
						|
Plug 'tpope/vim-markdown'               " Markdown
 | 
						|
Plug 'bfrg/vim-cpp-modern'              " C/C++
 | 
						|
Plug 'vim-ruby/vim-ruby'                " Ruby
 | 
						|
Plug 'fatih/vim-go'                     " Go
 | 
						|
Plug 'rust-lang/rust.vim'               " Rust
 | 
						|
Plug 'jdonaldson/vaxe'                  " Haxe
 | 
						|
Plug 'pprovost/vim-ps1'                 " PowerShell
 | 
						|
Plug 'fedorenchik/fasm.vim'             " Flat Assembler
 | 
						|
Plug 'elixir-editors/vim-elixir'        " Elixir
 | 
						|
 | 
						|
"//////////////////////////////
 | 
						|
 | 
						|
call plug#end()
 | 
						|
filetype plugin indent on
 | 
						|
 | 
						|
"---------------------------------------------------------------------------------------------------
 | 
						|
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"#2 BASE CONFIG
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" BASIC EDITING CONFIGURATION
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
set hidden
 | 
						|
set history=10000
 | 
						|
set expandtab
 | 
						|
set tabstop=4
 | 
						|
set shiftwidth=4
 | 
						|
set softtabstop=4
 | 
						|
set autoindent
 | 
						|
set laststatus=2
 | 
						|
set showcmd                       " Display incomplete commands.
 | 
						|
set showmatch
 | 
						|
set incsearch                     " Highlight matches as you type.
 | 
						|
set hlsearch                      " Highlight matches.
 | 
						|
set dictionary+=/usr/share/dict/words
 | 
						|
"set clipboard=unnamed            " Yank and paste with the system clipboard.
 | 
						|
set number
 | 
						|
set ignorecase smartcase          " Make searches case-sensitive only if they contain upper-case characters.
 | 
						|
set visualbell                    " No bell sounds.
 | 
						|
set ttyfast
 | 
						|
set cmdheight=2
 | 
						|
set switchbuf=useopen,split
 | 
						|
set numberwidth=5
 | 
						|
set showtabline=2
 | 
						|
set winwidth=79
 | 
						|
 | 
						|
 " Use abbreviations.
 | 
						|
set shortmess=a
 | 
						|
 | 
						|
" Remove gvim Menubar and Toolbar
 | 
						|
"set guioptions -=m
 | 
						|
"set guioptions -=T
 | 
						|
 | 
						|
" @warning: This must come AFTER `set ignorecase smartcase` otherwise vim spews out a ton of errors. No idea why!
 | 
						|
if IsWindows()
 | 
						|
  " Just assume we don't have a zsh shell
 | 
						|
  set shell=bash
 | 
						|
else
 | 
						|
  "set shell=zsh
 | 
						|
  set shell=bash
 | 
						|
endif
 | 
						|
 | 
						|
set t_ti= t_te=                   " Prevent Vim from clobbering the scrollback buffer. See http://www.shallowsky.com/linux/noaltscreen.html
 | 
						|
set scrolloff=3                   " keep more context when scrolling off the end of a buffer
 | 
						|
set cursorline
 | 
						|
set cursorcolumn
 | 
						|
 | 
						|
"
 | 
						|
" Store swap, backup and undo files in a central spot. I have my settings in a
 | 
						|
" `vimrc.private` so that my drive paths aren't in this config. If you want to
 | 
						|
" set them here then add:
 | 
						|
"
 | 
						|
" set directory=<dir path for swap files>
 | 
						|
" set backupdir=<dir path for backup files>
 | 
						|
" if has('persistent_undo')
 | 
						|
"    set undodir=<dir path for undo files>
 | 
						|
" endif
 | 
						|
"
 | 
						|
" And make sure those directories exist before opening vim.
 | 
						|
"
 | 
						|
set backup
 | 
						|
set backupcopy=yes
 | 
						|
augroup backupCmds
 | 
						|
    autocmd!
 | 
						|
    autocmd BufWritePre * let &bex = '.' . strftime("%Y-%m-%d-%T") . '.bak'
 | 
						|
augroup END
 | 
						|
set writebackup                   " Make buckup before overwriting the current buffer.
 | 
						|
 | 
						|
"
 | 
						|
" Keep undo history across sessions by storing it in a file. The undo save
 | 
						|
" location is set in the vimrc.private file. You can also set it here with:
 | 
						|
" set undodir=<path>
 | 
						|
"
 | 
						|
set undolevels=1000               " Allow undo when going back into a closed file
 | 
						|
set undoreload=10000
 | 
						|
if has('persistent_undo')
 | 
						|
    set undofile
 | 
						|
endif
 | 
						|
 | 
						|
set backspace=indent,eol,start    " Allow backspacing over everything in insert mode.
 | 
						|
 | 
						|
set complete+=kspell              " Spell checking autocomplete.
 | 
						|
set complete-=i                   " Don't scan all included files since it's really slow.
 | 
						|
 | 
						|
set termguicolors
 | 
						|
syntax on                         " Enable highlighting for syntax
 | 
						|
 | 
						|
set wildmenu
 | 
						|
set wildmode=longest,list,full
 | 
						|
set wildignore+=*/log/*,*.so,*.swp,*.zip,*/rdoc/*
 | 
						|
 | 
						|
set grepprg=rg\ --vimgrep         " Requires ripgrep to be installed.
 | 
						|
 | 
						|
set list listchars=tab:»·,trail:· " Show trailing whitespace.
 | 
						|
 | 
						|
set timeoutlen=300 ttimeoutlen=0  " Adding this since the esc remap on the 'i' key had a long delay when pressed.
 | 
						|
 | 
						|
" @fixme might be broken if lowered to 100 from original value of 4000. Will
 | 
						|
" first try 500 and tweak from there.
 | 
						|
" UPDATE: I lowered this to 250 and eventually started seeing some plugin
 | 
						|
" errors related to paren formatting. I think 800 might be the sweet spot.
 | 
						|
set updatetime=800                " I lowered this to make git-gutter updates faster.
 | 
						|
 | 
						|
" Fix vim's background colour erase - http://snk.tuxfamily.org/log/vim-256color-bce.html
 | 
						|
if &term =~ '256color'
 | 
						|
    " Disable Background Color Erase (BCE) so that color schemes
 | 
						|
    " work properly when Vim is used inside tmux and GNU screen.
 | 
						|
    " See also http://snk.tuxfamily.org/log/vim-256color-bce.html
 | 
						|
    set t_ut=
 | 
						|
endif
 | 
						|
 | 
						|
" Disable arrow keys.
 | 
						|
noremap <up> <nop>
 | 
						|
noremap <down> <nop>
 | 
						|
noremap <left> <nop>
 | 
						|
noremap <right> <nop>
 | 
						|
inoremap <up> <nop>
 | 
						|
inoremap <down> <nop>
 | 
						|
inoremap <left> <nop>
 | 
						|
inoremap <right> <nop>
 | 
						|
 | 
						|
"---------------------------------------------------------------
 | 
						|
" Load vimrc.private
 | 
						|
" This should be done after above base settings that don't use the global
 | 
						|
" campo variables.
 | 
						|
"
 | 
						|
" You can further customize things in a private vimrc. I use this for things
 | 
						|
" that I don't want included in my public dotfiles repo such as temp file settings.
 | 
						|
if filereadable($HOME . "/.vimrc.private")
 | 
						|
    source $HOME/.vimrc.private
 | 
						|
endif
 | 
						|
 | 
						|
" Settings that use the global campo variables.
 | 
						|
let &colorcolumn=g:campo_max_line_length
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" CUSTOM AUTOCMDS
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
augroup campoCmds
 | 
						|
    " Clear all autocmds in the group.
 | 
						|
    autocmd!
 | 
						|
 | 
						|
    " Automatically wrap at N characters.
 | 
						|
    autocmd FileType gitcommit setlocal colorcolumn=72
 | 
						|
    autocmd BufRead,BufNewFile *.{md,txt,plan} exec "setlocal textwidth=".g:campo_max_line_length
 | 
						|
 | 
						|
    " Spell checking.
 | 
						|
    autocmd FileType gitcommit,markdown,text setlocal spell
 | 
						|
 | 
						|
    " Jump to last cursor position unless it's invalid or in an event handler.
 | 
						|
    autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
 | 
						|
 | 
						|
    " Indent HTML <p> tags.
 | 
						|
    autocmd FileType html,eruby if g:html_indent_tags !~ '\\|p\>' | let g:html_indent_tags .= '\|p\|li\|dt\|dd' | endif
 | 
						|
 | 
						|
    " Properly indent schemes (scheme, racket, etc).
 | 
						|
    autocmd BufRead,BufNewFile *.{lisp,scm,rkt} setlocal equalprg=scmindent.rkt
 | 
						|
 | 
						|
    " Elixir indent
 | 
						|
    autocmd FileType elixir setlocal tabstop=2 | setlocal shiftwidth=2 | setlocal softtabstop=2
 | 
						|
 | 
						|
    " Fasm indent; uses the fedorenchik/fasm.vim plugin.
 | 
						|
    autocmd BufReadPre *.asm let g:asmsyntax = "fasm"
 | 
						|
 | 
						|
    " Auto reload VIM when settings changed.
 | 
						|
    " Need to use silent! now because the save commands call a custom function
 | 
						|
    " and without the silent we would see an error after sourcing saying that
 | 
						|
    " we can't redefine the function that initiated the save. :ReloadVimrcError
 | 
						|
    "
 | 
						|
    " @fixme Reload lvimrc after sourcing this file on a save. I tried calling
 | 
						|
    " a function that does the source and a call to lvimrc's API but got an
 | 
						|
    " error complaining that the function cannot be created while it's in use.
 | 
						|
    autocmd BufWritePost .vimrc silent! source $MYVIMRC
 | 
						|
    autocmd BufWritePost *.vim silent! source $MYVIMRC
 | 
						|
    autocmd BufWritePost ~/.vimrc.private silent! source $MYVIMRC
 | 
						|
 | 
						|
    " Remove trailing whitespace when saving any file.
 | 
						|
    function! s:StripTrailingWhitespaces()
 | 
						|
        let l:filename = expand('%:t')
 | 
						|
        if g:campo_strip_trailing_whitespace == 1
 | 
						|
            if len(g:campo_files_to_ignore_when_stripping_trailing_whitespace)
 | 
						|
                for ignore in g:campo_files_to_ignore_when_stripping_trailing_whitespace
 | 
						|
                    if ignore == l:filename
 | 
						|
                        return
 | 
						|
                    endif
 | 
						|
                endfor
 | 
						|
            endif
 | 
						|
        else
 | 
						|
            if len(g:campo_files_to_force_stripping_trailing_whitespace)
 | 
						|
                let l:found_match = 0
 | 
						|
                for name in g:campo_files_to_force_stripping_trailing_whitespace
 | 
						|
                    if name == l:filename
 | 
						|
                        let l:found_match = 1
 | 
						|
                        break
 | 
						|
                    endif
 | 
						|
                endfor
 | 
						|
                if l:found_match == 0
 | 
						|
                    return
 | 
						|
                endif
 | 
						|
            else
 | 
						|
                return
 | 
						|
            endif
 | 
						|
        endif
 | 
						|
 | 
						|
        let l = line(".")
 | 
						|
        let c = col(".")
 | 
						|
        %s/\s\+$//e
 | 
						|
        call cursor(l, c)
 | 
						|
    endfun
 | 
						|
    autocmd BufWritePre * call s:StripTrailingWhitespaces()
 | 
						|
 | 
						|
    "////////////////////////////////////////////////////////////////
 | 
						|
    " FILE TEMPLATES
 | 
						|
    "////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
    " C/C++ template.
 | 
						|
    function! s:CFileTemplate()
 | 
						|
        let s:env = {
 | 
						|
            \ 'filename': expand('%:t'),
 | 
						|
            \ 'creation_date': strftime('%Y-%m-%d'),
 | 
						|
            \ 'year': strftime('%Y'),
 | 
						|
            \ 'copyright_owner': 'Jelly Pixel, Inc. All Rights Reserved.'
 | 
						|
            \}
 | 
						|
 | 
						|
         let l:template =<< trim EOS
 | 
						|
            /*==================================================================================================
 | 
						|
            File: ${filename}
 | 
						|
            Creation Date: ${creation_date}
 | 
						|
            Creator: Michael Campagnaro
 | 
						|
            Notice!: (C) Copyright ${year} by ${copyright_owner}
 | 
						|
            ================================================================================================*/
 | 
						|
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
            // # Defines
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
            // # Globals
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
            // # Structs
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
            // # Macros
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
            // # Private API
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
            // # Public API
 | 
						|
            ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
EOS
 | 
						|
        return map(l:template, { _, line -> substitute(line, '${\(.\{-}\)}', '\=get(s:env, submatch(1), submatch(1))', 'g') } )
 | 
						|
    endfunction
 | 
						|
 | 
						|
    function! s:InsertCHeaderGates()
 | 
						|
        let l:gatename = substitute(toupper(expand("%:t")), "\\.", "_", "g")
 | 
						|
        call append(0, '#ifndef '. l:gatename)
 | 
						|
        call append(line('$'), '#define '. l:gatename)
 | 
						|
        call append(line('$'), '#endif')
 | 
						|
    endfunction
 | 
						|
 | 
						|
    " sh template
 | 
						|
    function! s:ShellScriptTemplate()
 | 
						|
         let l:template =<< trim EOS
 | 
						|
            #!/usr/bin/env bash
 | 
						|
 | 
						|
            if which tput >/dev/null 2>&1; then
 | 
						|
              ncolors=$(tput colors)
 | 
						|
            fi
 | 
						|
            if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
 | 
						|
                RED="$(tput setaf 1)"
 | 
						|
                GREEN="$(tput setaf 2)"
 | 
						|
                YELLOW="$(tput setaf 3)"
 | 
						|
                BLUE="$(tput setaf 4)"
 | 
						|
                MAGENTA="$(tput setaf 5)"
 | 
						|
                CYAN="$(tput setaf 6)"
 | 
						|
                BOLD="$(tput bold)"
 | 
						|
                DIM="\e[2m"
 | 
						|
                NORMAL="$(tput sgr0)"
 | 
						|
            else
 | 
						|
                RED=""
 | 
						|
                GREEN=""
 | 
						|
                YELLOW=""
 | 
						|
                BLUE=""
 | 
						|
                MAGENTA=""
 | 
						|
                CYAN=""
 | 
						|
                BOLD=""
 | 
						|
                NORMAL=""
 | 
						|
            fi
 | 
						|
 | 
						|
            error() {
 | 
						|
                printf "${BOLD}${RED}$1${NORMAL}\n"
 | 
						|
            }
 | 
						|
 | 
						|
            abort() {
 | 
						|
                error "\nAborting..."
 | 
						|
                exit 1
 | 
						|
            }
 | 
						|
 | 
						|
            set -e
 | 
						|
 | 
						|
            cwd=$PWD
 | 
						|
 | 
						|
            uname_s="$(uname -s)"
 | 
						|
            case "${uname_s}" in
 | 
						|
                Linux*)   machine=Linux;;
 | 
						|
                Darwin*)  machine=MacOS;;
 | 
						|
                CYGWIN*)  machine=Cygwin;;
 | 
						|
                MINGW*)   machine=MinGw;;
 | 
						|
                *)        machine="UNKNOWN:${uname_s}"
 | 
						|
            esac
 | 
						|
 | 
						|
            printf "${YELLOW}Platform: $machine${NORMAL}\n"
 | 
						|
EOS
 | 
						|
        return l:template
 | 
						|
    endfunction
 | 
						|
 | 
						|
    " Shell script template.
 | 
						|
    autocmd BufNewFile *.sh call append(0, s:ShellScriptTemplate())
 | 
						|
 | 
						|
    " C/C++ file.
 | 
						|
    autocmd BufNewFile *.{c,cc,cpp,h,hpp} call append(0, s:CFileTemplate())
 | 
						|
    autocmd BufNewFile *.{h,hpp} call s:InsertCHeaderGates()
 | 
						|
augroup END
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" MISC KEY MAPS
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
" Lowercase the e (have a habit of making it uppercase).
 | 
						|
:ca E e
 | 
						|
 | 
						|
" Mapping ESC in insert mode and command mode to double i.
 | 
						|
imap jj <Esc>
 | 
						|
 | 
						|
" Suspend vim process and return to the shell. Can return to vim with `fg`.
 | 
						|
nnoremap <leader>z <c-z>
 | 
						|
 | 
						|
" Open the vimrc file for editing / reload vimrc file.
 | 
						|
nnoremap <silent> <leader>ev :vsp $MYVIMRC<cr>
 | 
						|
nnoremap <silent> <leader>pv :vsp ~/.vimrc.private<cr>
 | 
						|
nnoremap <silent> <leader>rv :source $MYVIMRC<cr>
 | 
						|
 | 
						|
" Type %/ in the command bar to have it replaced with the current buffer's
 | 
						|
" path if the file is on disk. One thing I noticed is that you have to type
 | 
						|
" the full %/ quickly otherwise it won't replace it.
 | 
						|
cmap %/ %:p:h/
 | 
						|
 | 
						|
"------------------------------------------------------------
 | 
						|
" Remap saving and quiting.
 | 
						|
"
 | 
						|
" I used to have a BufWritePost autocommand that ran the ctags generator but
 | 
						|
" it ends up running multiple times when saving multiple buffers at once. In
 | 
						|
" order to only call it once for a group of saves I've had to remap the
 | 
						|
" various save commands to a function call.
 | 
						|
 | 
						|
function! s:CreateCtags()
 | 
						|
    " Only allow one instance of ctags to run in this directory at any given time.
 | 
						|
    let l:lock_file = "ctags.lock"
 | 
						|
    if filereadable(l:lock_file) || filereadable("newtags")
 | 
						|
        " Don't print a warning because this will always show when saving multiple files at the same time with a :wa or :xa
 | 
						|
        return
 | 
						|
    endif
 | 
						|
 | 
						|
    let l:extension = tolower(expand('%:e'))
 | 
						|
    if (g:campo_force_ctags_regardless_of_extension == 0) && (index(g:campo_extensions_that_run_ctags, l:extension) < 0)
 | 
						|
        echo "Skipping ctags generation"
 | 
						|
        return
 | 
						|
    endif
 | 
						|
 | 
						|
    " Abort if we're editing a text file. This won't be an exhaustive
 | 
						|
    " filter. We can restrict what goes into the tag file
 | 
						|
    " First determine if we're in a root drive directory. If we are then
 | 
						|
    " we bail because we don't want to recurse across the entire drive!
 | 
						|
    let l:path = expand('%:p:h')
 | 
						|
    let l:path_without_slashes = substitute(l:path, "/", "", "g")
 | 
						|
    if (strchars(l:path) - strchars(l:path_without_slashes)) <= 1
 | 
						|
        call PrintError("Not going to run ctags because the file is in a root drive directory")
 | 
						|
        return
 | 
						|
    endif
 | 
						|
 | 
						|
    " Always ignore .git and node_modules
 | 
						|
    let g:campo_ctags_exclude = g:campo_ctags_exclude + ['.git', 'node_modules']
 | 
						|
    let l:exclude_list = ""
 | 
						|
    for name in g:campo_ctags_exclude
 | 
						|
        let l:exclude_list = l:exclude_list . "--exclude=" . name . " "
 | 
						|
    endfor
 | 
						|
 | 
						|
    " Include local variables for C-like languages.
 | 
						|
    let l:ctags_cmd = 'ctags '.l:exclude_list.' '.g:campo_custom_ctags_args.' --c-types=+l --c++-types=+l -o newtags'
 | 
						|
 | 
						|
    " Add the filename to the ctags command if not running in recursive mode.
 | 
						|
    let l:recursive = matchstr(g:campo_custom_ctags_args, '\(-R\s\)\|\(-R$\)\|\(--recurse=yes\)\|\(--recurse\s\)\|\(--recurse$\)')
 | 
						|
    if l:recursive == ''
 | 
						|
        let l:ctags_cmd = l:ctags_cmd . ' ' . expand('%:t')
 | 
						|
        echo "Creating non-recursive ctags"
 | 
						|
    else
 | 
						|
        echo "Creating recursive ctags"
 | 
						|
    endif
 | 
						|
 | 
						|
    " The ampersand at the end is to make this run in the background. I had to group the
 | 
						|
    " commands in parens to make the chained commands run in the background.
 | 
						|
    let l:cmd = '!(touch '.l:lock_file.'; '.l:ctags_cmd.'; mv newtags tags &>/dev/null; rm '.l:lock_file.') &'
 | 
						|
    silent! exec l:cmd
 | 
						|
endfun
 | 
						|
 | 
						|
" @note We have an autocmd that reloads the vimrc files after they're saved.
 | 
						|
" These write functions below will not be reloaded because they initiate the
 | 
						|
" save. So if you make changes to them then you need to manually reload this
 | 
						|
" file using <leader>rv or whatever. :ReloadVimrcError
 | 
						|
function! DoSingleWrite()
 | 
						|
    write
 | 
						|
    call s:CreateCtags()
 | 
						|
endfunction
 | 
						|
 | 
						|
function! DoSingleWriteThenQuit()
 | 
						|
    write
 | 
						|
    call s:CreateCtags()
 | 
						|
    quit
 | 
						|
endfunction
 | 
						|
 | 
						|
function! DoMultiWrite()
 | 
						|
    let l:current_buffer = bufnr("%")
 | 
						|
    bufdo wa
 | 
						|
    " Restore the last buffer because it may have changed.
 | 
						|
    exec "buffer " . l:current_buffer
 | 
						|
    call s:CreateCtags()
 | 
						|
endfunction
 | 
						|
 | 
						|
cnoreabbrev w  :call DoSingleWrite()
 | 
						|
cnoreabbrev W  :call DoSingleWrite()
 | 
						|
cnoreabbrev wa :call DoMultiWrite()
 | 
						|
cnoreabbrev Wa :call DoMultiWrite()
 | 
						|
cnoreabbrev WA :call DoMultiWrite()
 | 
						|
cnoreabbrev wq :call DoSingleWriteThenQuit()
 | 
						|
cnoreabbrev Wq :call DoSingleWriteThenQuit()
 | 
						|
cnoreabbrev WQ :call DoSingleWriteThenQuit()
 | 
						|
 | 
						|
nnoremap <leader>w :call DoSingleWrite()<cr>
 | 
						|
nnoremap <leader>x :call DoSingleWriteThenQuit()<cr>
 | 
						|
nnoremap <leader>q :q<cr>
 | 
						|
 | 
						|
cnoreabbrev Q q
 | 
						|
command! Qa qall
 | 
						|
" Disable Ex mode.
 | 
						|
noremap Q <Nop>
 | 
						|
 | 
						|
"------------------------------------------------------------
 | 
						|
 | 
						|
" Open a terminal within vim. Use `exit` to close it.
 | 
						|
if exists(':terminal')
 | 
						|
    noremap <leader>t :terminal<cr>
 | 
						|
    tnoremap <leader>e <C-\><C-n>
 | 
						|
    tnoremap <A-h> <C-\><C-n><C-w>h
 | 
						|
    tnoremap <A-j> <C-\><C-n><C-w>j
 | 
						|
    tnoremap <A-k> <C-\><C-n><C-w>k
 | 
						|
    tnoremap <A-l> <C-\><C-n><C-w>l
 | 
						|
    nnoremap <A-h> <C-w>h
 | 
						|
    nnoremap <A-j> <C-w>j
 | 
						|
    nnoremap <A-k> <C-w>k
 | 
						|
    nnoremap <A-l> <C-w>l
 | 
						|
endif
 | 
						|
 | 
						|
" Jump to other buffers.
 | 
						|
noremap <c-k> <c-w><Up>
 | 
						|
noremap <c-j> <c-w><Down>
 | 
						|
noremap <c-l> <c-w><Right>
 | 
						|
noremap <c-h> <c-w><Left>
 | 
						|
 | 
						|
" Make it easier to jump around the command line. The default behaviour is
 | 
						|
" using the arrow keys with or without shift.
 | 
						|
:cnoremap <C-J> <S-Left>
 | 
						|
:cnoremap <C-K> <S-Right>
 | 
						|
 | 
						|
" Window splitting - couldn't figure out how to remap <c-w>v & <c-w>n to <c-m>
 | 
						|
" & <c-n>
 | 
						|
noremap <leader>m :vsplit<cr>
 | 
						|
noremap <leader>mm :split<cr>
 | 
						|
 | 
						|
" Forward delete and replace a word.
 | 
						|
noremap <leader>d ciw
 | 
						|
 | 
						|
" Allow fast pasting by accessing the system clipboard register.
 | 
						|
noremap <leader>p "+p
 | 
						|
" Likely won't need to use this if pasting with <leader>p, but just in case here ya go.
 | 
						|
noremap <leader>pp :set paste! paste?<cr>
 | 
						|
 | 
						|
" Toggle line numbers.
 | 
						|
noremap <leader>o :set number! number?<cr>
 | 
						|
 | 
						|
" Show spell checking.
 | 
						|
" You can add new entries to the dict by moving the cursor over the word and pressing `zg`.
 | 
						|
noremap <leader>j :exec &spell==&spell? "se spell! spelllang=en_us" : "se spell!"<cr>
 | 
						|
noremap <leader>= z=
 | 
						|
 | 
						|
" Clear the search buffer (highlighting) when hitting return.
 | 
						|
nnoremap <cr> :nohlsearch<cr>
 | 
						|
 | 
						|
" Switch to the previous file.
 | 
						|
nnoremap <leader><leader> <c-^>
 | 
						|
 | 
						|
" Replace currently selected text with default register without yanking it.
 | 
						|
vnoremap p "_dP
 | 
						|
 | 
						|
" Switch between C++ source and header files.
 | 
						|
noremap <leader>v :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR>
 | 
						|
"noremap <leader>vv :e %:p:s,.h$,.X123X,:s,.c$,.h,:s,.X123X$,.c,<CR>
 | 
						|
"noremap <leader>vvv :e %:p:s,.h$,.X123X,:s,.cc$,.h,:s,.X123X$,.cc,<CR>
 | 
						|
 | 
						|
" Replace all instances of the highlighted text with whatever you enter.
 | 
						|
nnoremap <c-g> :%s///g<left><left>
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" QUICKLY OPEN C++ SOURCE OR HEADER FILE
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
function! s:CompleteFilenameWithoutExtension(ArgLead, CmdLine, CursorPos)
 | 
						|
    " Returns a matching filename without the period that separates the name
 | 
						|
    " from the extension.
 | 
						|
    let l:file = substitute(glob(a:ArgLead.'*', 0, 0), "[\.].*", "", "*")
 | 
						|
    return l:file
 | 
						|
endfunction
 | 
						|
 | 
						|
" Custom command to open cpp and h files without typing an extension
 | 
						|
"command! -nargs=+ -complete=custom,s:CompleteFilenameWithoutExtension "OpenCppSource exec ':e <args>.cpp'
 | 
						|
":ca c OpenCppSource
 | 
						|
":ca C OpenCppSource
 | 
						|
 | 
						|
"command! -nargs=+ -complete=custom,s:CompleteFilenameWithoutExtension "OpenCppHeader exec ':e <args>.h'
 | 
						|
":ca h OpenCppHeader
 | 
						|
":ca H OpenCppHeader
 | 
						|
 | 
						|
"command! -nargs=+ -complete=custom,s:CompleteFilenameWithoutExtension "OpenCppSourceAndHeader exec ':vsp | :e <args>.h | :sp <args>.cpp'
 | 
						|
":ca b OpenCppSourceAndHeader
 | 
						|
":ca B OpenCppSourceAndHeader
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" MULTIPURPOSE TAB KEY
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
function! InsertTabWrapper()
 | 
						|
    let l:col = col('.') - 1
 | 
						|
    if !l:col || getline('.')[l:col - 1] !~ '\k'
 | 
						|
        return "\<tab>"
 | 
						|
    else
 | 
						|
        return "\<c-p>"
 | 
						|
    endif
 | 
						|
endfunction
 | 
						|
inoremap <tab> <c-r>=InsertTabWrapper()<cr>
 | 
						|
inoremap <s-tab> <c-n>
 | 
						|
 | 
						|
 | 
						|
"---------------------------------------------------------------------------------------------------
 | 
						|
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"#3 PLUGIN CONFIGS
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" LOCAL VIMRC
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
let g:localvimrc_sandbox = 0
 | 
						|
let g:localvimrc_ask = 0
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" TAGBAR
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
noremap <F12> :TagbarToggle<cr>
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" GITGUTTER
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
let g:gitgutter_enabled = 1
 | 
						|
let g:gitgutter_highlight_lines = 0
 | 
						|
nnoremap <leader>hh :GitGutterToggle<cr>
 | 
						|
nmap <leader>ha <Plug>(GitGutterStageHunk)
 | 
						|
nmap [h <Plug>(GitGutterNextHunk)
 | 
						|
nmap ]h <Plug>GitGutterPrevHunk
 | 
						|
 | 
						|
augroup gitGutterPluginCmds
 | 
						|
    autocmd!
 | 
						|
    " Update marks on save
 | 
						|
    autocmd BufWritePost * GitGutter
 | 
						|
augroup END
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" SYNTASTIC
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" NOTE: there is a status line config in the status line section
 | 
						|
let g:syntastic_always_populate_loc_list = 1
 | 
						|
let g:syntastic_auto_loc_list = 1
 | 
						|
let g:syntastic_check_on_open = 0
 | 
						|
let g:syntastic_check_on_wq = 0
 | 
						|
 | 
						|
" Customize Rust
 | 
						|
" https://github.com/rust-lang/rust.vim/issues/130
 | 
						|
" Can remove once this Syntastic PR is merged https://github.com/rust-lang/rust.vim/pull/132
 | 
						|
"let g:syntastic_rust_rustc_exe = 'cargo check'
 | 
						|
"let g:syntastic_rust_rustc_fname = ''
 | 
						|
"let g:syntastic_rust_checkers = ['rustc']
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" RIPGREP
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
let g:rg_highlight = 1
 | 
						|
let g:rg_window_height = g:quickfix_pane_height
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" CTRL-P
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" keybindings:
 | 
						|
"
 | 
						|
" leader-f         = open CtrlP in tag searching mode.
 | 
						|
" leader-g         = open CtrlP in file searching mode.
 | 
						|
" ctrl-f           = toggle search mode
 | 
						|
" enter            = open result in a current buffer or in an already open buffer for that file.
 | 
						|
" ctrl-v           = open result in a vertically-split buffer.
 | 
						|
" ctrl-h           = open result in a horizontally-split buffer.
 | 
						|
" ctrl-t           = open result in a new tab.
 | 
						|
" ctrl-j | ctrl-k  = move up and down the search results.
 | 
						|
" ctrl-y           = create file and open it.
 | 
						|
" ctrl-z           = mark multiple file search results to open (I think you can only use ctrl-v or ctrl-x and not enter).
 | 
						|
" ctrl-o           = ask how to open a file search result.
 | 
						|
" ctrl-o           = ask how to open a file search result.
 | 
						|
" ctrl-p | ctrl-n  = traverse search history.
 | 
						|
 | 
						|
noremap <leader>g :CtrlP<cr>
 | 
						|
let g:ctrlp_map = '<leader>f'
 | 
						|
let g:ctrlp_cmd = 'CtrlPTag' " Search tags by default.
 | 
						|
let g:ctrlp_by_filename = 1  " File search by filename as opposed to full path.
 | 
						|
let g:ctrlp_match_window = 'bottom,order:ttb,min:10,max:'.g:quickfix_pane_height.',results:'.g:quickfix_pane_height
 | 
						|
let g:ctrlp_use_caching = 1
 | 
						|
let g:ctrlp_clear_cache_on_exit = 1 " No need to keep cache for now since I mostly work in git repos. Press F5 inside CtrlP to rebuild the cache.
 | 
						|
let g:ctrlp_working_path_mode = 'ra' " Search from nearest ancestor of the current file that contains .git OR directory of the current file unless it's a subdirectory of the cwd
 | 
						|
let g:ctrlp_switch_buffer = 'et' " If a file is already open, open it again in a new pane instead of switching to the existing pane
 | 
						|
let g:ctrlp_custom_ignore = '\v[\/]\.(git|hg|svn)$'
 | 
						|
let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files -co --exclude-standard'] " If a git repo, use checked in files (ignore things in .gitignore); fallback to globpath()
 | 
						|
 | 
						|
" @fixme Not sure why I can't get these new mappings (c-m, c-cr) to register...
 | 
						|
"let g:ctrlp_prompt_mappings = {
 | 
						|
"  \ 'AcceptSelection("h")': ['<c-x>', '<c-cr>'],
 | 
						|
"  \ 'AcceptSelection("v")': ['<c-v>', '<c-m>'],
 | 
						|
"  \ }
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" GIT
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
noremap <leader>gb :Git blame -w<cr>
 | 
						|
" Ignore whitespace changes; follow renames and copies.
 | 
						|
command! -bar -bang -nargs=* Blame :Git blame<bang> -wCM <args>
 | 
						|
command! -bar -bang -nargs=* Gblame :Git blame<bang> -wCM <args>
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" GIST VIM
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
let g:gist_detect_filetype = 1
 | 
						|
let g:gist_open_browser_after_post = 1
 | 
						|
let g:gist_show_privates = 1
 | 
						|
let g:gist_post_private = 1
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" VIM-CLOJURE-STATIC
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" Default
 | 
						|
let g:clojure_fuzzy_indent = 1
 | 
						|
let g:clojure_align_multiline_strings = 1
 | 
						|
let g:clojure_fuzzy_indent_patterns = ['^match', '^with', '^def', '^let']
 | 
						|
let g:clojure_fuzzy_indent_blacklist = ['-fn$', '\v^with-%(meta|out-str|loading-context)$']
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" RUST.VIM
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
"let g:rustfmt_autosave = 1 " auto run rust formatter when saving
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" RAINBOW
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
let g:rainbow_active = 1 " Always on
 | 
						|
let s:light_rainbow = ['red', 'green', 'magenta', 'cyan', 'yellow', 'white', 'gray', 'blue']
 | 
						|
let s:dark_rainbow = ['darkblue', 'red', 'black', 'darkgreen', 'darkyellow', 'darkred', 'darkgray']
 | 
						|
let s:rainbow_theme = g:campo_default_bg_mode
 | 
						|
 | 
						|
function! UpdateRainbowConf()
 | 
						|
    let g:rainbow_conf = {
 | 
						|
        \   'ctermfgs': (s:rainbow_theme == "light"? s:dark_rainbow : s:light_rainbow)
 | 
						|
     \}
 | 
						|
"\   'separately': {
 | 
						|
"\       '*': 0, " Disable all
 | 
						|
"\       'c++': {} " Only enable c++
 | 
						|
"\   }
 | 
						|
endfunction
 | 
						|
 | 
						|
call UpdateRainbowConf()
 | 
						|
 | 
						|
function! ReloadRainbow()
 | 
						|
    if g:campo_theme_use_rainbow_parens
 | 
						|
        if exists(':RainbowToggle')
 | 
						|
            call UpdateRainbowConf()
 | 
						|
            call rainbow#clear() | call rainbow#hook()
 | 
						|
        endif
 | 
						|
    else
 | 
						|
        let g:rainbow_active = 0
 | 
						|
        if exists(':RainbowToggle')
 | 
						|
            call UpdateRainbowConf()
 | 
						|
            call rainbow#clear()
 | 
						|
        endif
 | 
						|
    endif
 | 
						|
endfunction
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" C-TAGS
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
set tags+=tags;$HOME
 | 
						|
 | 
						|
"---------------------------------------------------------------------------------------------------
 | 
						|
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"#4 VISUALS
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" LAYOUT
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" CENTER THE BUFFER
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
function! CenterPane()
 | 
						|
    " centers the current pane as the middle 2 of 4 imaginary columns
 | 
						|
    " should be called in a window with a single pane
 | 
						|
    " Taken from https://dev.to/vinneycavallo/easily-center-content-in-vim
 | 
						|
    lefta vnew
 | 
						|
    wincmd w
 | 
						|
    exec 'vertical resize' string(&columns * 0.75)
 | 
						|
endfunction
 | 
						|
nnoremap <leader>c :call CenterPane()<cr>
 | 
						|
 | 
						|
function! RemoveCenterPane()
 | 
						|
    wincmd w
 | 
						|
    close
 | 
						|
endfunction
 | 
						|
nnoremap <leader>cw :call RemoveCenterPane()<cr>
 | 
						|
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" TEXT ALIGNMENT PLUGIN
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
let b:lion_squeeze_spaces = 1
 | 
						|
 | 
						|
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
" STATUS LINE
 | 
						|
"////////////////////////////////////////////////////////////////
 | 
						|
set statusline=%<%f\ (%{&ft})\ %-4(%m%)%=%-19(%3l,%02c%03V%)
 | 
						|
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" COLORS
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
exec "autocmd ColorScheme " . g:campo_dark_theme . " call ReloadRainbow()"
 | 
						|
exec "autocmd ColorScheme " . g:campo_light_theme . " call ReloadRainbow()"
 | 
						|
 | 
						|
" Switch between light and dark themes.
 | 
						|
noremap <leader>l :call ChangeBgTheme('light', 0)<cr>
 | 
						|
noremap <leader>ll :call ChangeBgTheme('dark', 0)<cr>
 | 
						|
 | 
						|
function! ChangeBgTheme(bg, onlySetTheme)
 | 
						|
    if a:bg =~ 'light'
 | 
						|
        let s:rainbow_theme = 'light'
 | 
						|
        let s:theme = g:campo_light_theme
 | 
						|
        exe 'colorscheme ' . s:theme
 | 
						|
        set background=light
 | 
						|
    else
 | 
						|
        let s:rainbow_theme = 'dark'
 | 
						|
        let s:theme = g:campo_dark_theme
 | 
						|
        " We have to set the theme twice in order to get its correct dark-theme colors.
 | 
						|
        " Weird stuff.
 | 
						|
        exe 'colorscheme ' . s:theme
 | 
						|
        set background=dark
 | 
						|
        exe 'colorscheme ' . s:theme
 | 
						|
    endif
 | 
						|
 | 
						|
    if !a:onlySetTheme
 | 
						|
        exec 'AirlineTheme' a:bg
 | 
						|
    endif
 | 
						|
endfunction
 | 
						|
 | 
						|
if g:campo_default_bg_mode =~ 'light'
 | 
						|
  call ChangeBgTheme('light', 1)
 | 
						|
else
 | 
						|
  call ChangeBgTheme('dark', 1)
 | 
						|
endif
 | 
						|
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" HIGHLIGHTS - TODO, NOTE, FIXME, etc
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
" NOTE: These depend on custom color names (Bugs, Notes and Notices) defined
 | 
						|
" in the campo color themes. Since most themes won't define these, you can
 | 
						|
" use WildMenu as substitution.
 | 
						|
"
 | 
						|
" FIXME: the custom Bugs, Notes and Notices highlighting for campo-light isn't
 | 
						|
" working...
 | 
						|
 | 
						|
augroup vimrc_bugs
 | 
						|
    autocmd!
 | 
						|
    autocmd Syntax * syn match MyBugs /\v<(FIXME|BUG|DEPRECATED):/
 | 
						|
          \ containedin=.*Comment,vimCommentTitle
 | 
						|
augroup END
 | 
						|
hi def link MyBugs Bugs
 | 
						|
 | 
						|
augroup vimrc_notes
 | 
						|
    autocmd!
 | 
						|
    autocmd Syntax * syn match MyNotes /\v<(IDEA|NOTE|QUESTION|WARNING|IMPORTANT):/
 | 
						|
          \ containedin=.*Comment,vimCommentTitle
 | 
						|
augroup END
 | 
						|
hi def link MyNotes Notes
 | 
						|
 | 
						|
augroup vimrc_notices
 | 
						|
    au!
 | 
						|
    autocmd Syntax * syn match MyNotices /\v<(WARNING|IMPORTANT):/
 | 
						|
          \ containedin=.*Comment,vimCommentTitle
 | 
						|
augroup END
 | 
						|
hi def link MyNotices Notices
 | 
						|
 | 
						|
augroup vimrc_annotated_todo
 | 
						|
    autocmd!
 | 
						|
    " This was a major pain in the ass to get working...
 | 
						|
    autocmd Syntax * syn match cTodo /@\S\+/
 | 
						|
          \ containedin=.*Comment,vimCommentTitle
 | 
						|
augroup END
 | 
						|
 | 
						|
augroup vimrc_annotated_notes
 | 
						|
    autocmd!
 | 
						|
    autocmd Syntax * syn match cTodo /#\+ .\+$/
 | 
						|
          \ containedin=.*Comment,vimCommentTitle
 | 
						|
augroup END
 | 
						|
 | 
						|
"---------------------------------------------------------------------------------------------------
 | 
						|
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"#5 CUSTOM FUNCTIONS / COMMANDS
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
"################################################################
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" BUILD COMMANDS
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" AsyncRun status line
 | 
						|
let g:airline_section_error = airline#section#create_right(['%{g:asyncrun_status}'])
 | 
						|
 | 
						|
" Display error highlighting in source after running GCC with AsyncRun
 | 
						|
" NOTE: error results can be cleared with <leader>cr or by hiding the build
 | 
						|
" result window.
 | 
						|
let g:asyncrun_auto = "make"
 | 
						|
let errormarker_errortext = "E"
 | 
						|
let errormarker_warningtext = "W"
 | 
						|
 | 
						|
" Thanks to https://forums.handmadehero.org/index.php/forum?view=topic&catid=4&id=704#3982
 | 
						|
" for the error message formats
 | 
						|
"
 | 
						|
" Microsoft MSBuild errors
 | 
						|
set errorformat+=\\\ %#%f(%l\\\,%c):\ %m
 | 
						|
" Microsoft compiler: cl.exe
 | 
						|
set errorformat+=\\\ %#%f(%l)\ :\ %#%t%[A-z]%#\ %m
 | 
						|
" Microsoft HLSL compiler: fxc.exe
 | 
						|
set errorformat+=\\\ %#%f(%l\\\,%c-%*[0-9]):\ %#%t%[A-z]%#\ %m
 | 
						|
 | 
						|
function! HideBuildResultsAndClearErrors()
 | 
						|
    RemoveErrorMarkers
 | 
						|
    call asyncrun#quickfix_toggle(g:quickfix_pane_height, 0)
 | 
						|
endfunction
 | 
						|
 | 
						|
function! HideAsyncResults()
 | 
						|
    call asyncrun#quickfix_toggle(g:quickfix_pane_height, 0)
 | 
						|
endfunction
 | 
						|
 | 
						|
function! ToggleBuildResults()
 | 
						|
    call asyncrun#quickfix_toggle(g:quickfix_pane_height)
 | 
						|
endfunction
 | 
						|
 | 
						|
function! StopRunTask()
 | 
						|
    AsyncStop
 | 
						|
    call HideAsyncResults()
 | 
						|
endfunction
 | 
						|
 | 
						|
function! ExecuteRunScript()
 | 
						|
    exec "AsyncRun! -post=call\\ StopRunTask() ./run %"
 | 
						|
endfunction
 | 
						|
 | 
						|
function! SilentBuild()
 | 
						|
    AsyncStop
 | 
						|
    exec "AsyncRun! -save=2 -post=call\\ HideAsyncResults() ./build* %"
 | 
						|
endfunction
 | 
						|
 | 
						|
" Show results window the moment the async job starts
 | 
						|
augroup asyncPluginCmds
 | 
						|
    autocmd!
 | 
						|
    autocmd User AsyncRunStart call asyncrun#quickfix_toggle(g:quickfix_pane_height, 1)
 | 
						|
augroup END
 | 
						|
 | 
						|
" Toggle build results
 | 
						|
noremap <F11> :call ToggleBuildResults()<cr>
 | 
						|
nnoremap <leader>bc :call ToggleBuildResults()<cr>
 | 
						|
 | 
						|
" Hide build results and clear errors
 | 
						|
noremap <F10> :call HideBuildResultsAndClearErrors()<cr>
 | 
						|
 | 
						|
" Execute build script
 | 
						|
nnoremap <leader>b :AsyncRun! -save=2 ./build* %<cr>
 | 
						|
nnoremap <F8> :call SilentBuild()<cr>
 | 
						|
 | 
						|
" Execute run script
 | 
						|
nnoremap <leader>br :call ExecuteRunScript()<cr>
 | 
						|
nnoremap <F9> :call ExecuteRunScript()<cr>
 | 
						|
 | 
						|
nnoremap <leader>bs :AsyncStop<cr>
 | 
						|
 | 
						|
"Go to next build error
 | 
						|
nnoremap <F7> :cn<CR>
 | 
						|
nnoremap <C-n> :cn<CR>
 | 
						|
 | 
						|
"Go to previous build error
 | 
						|
nnoremap <F6> :cp<CR>
 | 
						|
nnoremap <C-p> :cp<CR>
 | 
						|
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" SEARCH
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
" Search using ripgrep (first install with Rust: cargo install ripgrep).
 | 
						|
function! Search(case_sensitive, search_args)
 | 
						|
    let l:helper = "Search [" . a:search_args . " | " . (a:case_sensitive ? "case-sensitive" : "case-insensitive") . "]: "
 | 
						|
    let l:term = input(l:helper)
 | 
						|
    if empty(l:term)
 | 
						|
        return
 | 
						|
    endif
 | 
						|
 | 
						|
    "@note --pretty (i.e. colors) is not enabled in vim-ripgrep because the
 | 
						|
    "quickfix window doesn't seem to parse the ansi color codes.
 | 
						|
    let l:rg_args = "--column --line-number --no-heading --fixed-strings --no-ignore --hidden --follow --trim -g \"!tags\" " . a:search_args
 | 
						|
 | 
						|
    if !a:case_sensitive
 | 
						|
        let l:rg_args .= " --ignore-case"
 | 
						|
    endif
 | 
						|
 | 
						|
    exec 'Rg ' . l:rg_args . ' "' . l:term . '"'
 | 
						|
endfunction
 | 
						|
 | 
						|
" Case insensitive
 | 
						|
noremap <leader>s :call Search(0, g:campo_custom_search_args)<cr>
 | 
						|
noremap <F2> :call Search(0, g:campo_custom_search_args_2)<cr>
 | 
						|
 | 
						|
" Case sensitive
 | 
						|
noremap <leader>ss :call Search(1, g:campo_custom_search_args)<cr>
 | 
						|
noremap <F3> :call Search(1, g:campo_custom_search_args_2)<cr>
 | 
						|
 | 
						|
" Navigation for the vim-ripgrep search results.
 | 
						|
" Hit o on a result line to open the file at that line.
 | 
						|
" Hit p on a result line to open the file at that line and return to the results pane.
 | 
						|
nnoremap <expr> o (&buftype is# "quickfix" ? "<CR>\|:lopen<CR>" : "o")
 | 
						|
nnoremap <expr> p (&buftype is# "quickfix" ? "<CR>\|:copen<CR>" : "p")
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" SEARCH & REPLACE
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
" Replace text in a git repo's committed files.
 | 
						|
" The range identifier allows us to run this once when multiple lines are selected in a file.
 | 
						|
function! GlobalReplaceIt(confirm_replacement) range
 | 
						|
    if exists(':Ggrep')
 | 
						|
        call inputsave()
 | 
						|
        if a:confirm_replacement
 | 
						|
            let l:term = input('Enter search term (w/ confirmation): ')
 | 
						|
        else
 | 
						|
            let l:term = input('Enter search term (no confirmation): ')
 | 
						|
        endif
 | 
						|
        call inputrestore()
 | 
						|
 | 
						|
        if empty(l:term)
 | 
						|
            return
 | 
						|
        endif
 | 
						|
 | 
						|
        call inputsave()
 | 
						|
        let l:replacement = input('Enter replacement: ')
 | 
						|
        call inputrestore()
 | 
						|
        if empty(l:replacement)
 | 
						|
            return
 | 
						|
        endif
 | 
						|
 | 
						|
        if a:confirm_replacement
 | 
						|
            let l:confirm = 'c'
 | 
						|
        else
 | 
						|
            let l:confirm = 'e'
 | 
						|
        endif
 | 
						|
 | 
						|
        " Capture opened buffers and windows so that we can restore everything after running cdo.
 | 
						|
        exec 'mksession! _replace_session.vim'
 | 
						|
 | 
						|
        " Search all committed files in the current directory
 | 
						|
        "  Ignoring binary files (-I)
 | 
						|
        "  Only including a matching filename once (--name-only)
 | 
						|
        exec 'Ggrep --threads 4 -I --name-only' l:term '.'
 | 
						|
 | 
						|
        " cdo will run the command foreach file in the grep results. It opens
 | 
						|
        " the file in a window so we immediately write the changes and then
 | 
						|
        " wipe the buffer (closing the window). If we don't close it then vim
 | 
						|
        " will run out of space when modifying a lot of files. This will
 | 
						|
        " likely close buffers that were open before running the replace, but
 | 
						|
        " we will restore them below from the saved session file.
 | 
						|
        " Note that we don't run autocommands for optimization purposes!
 | 
						|
        :noautocmd exec 'cdo' '%s/'.l:term.'/'.l:replacement.'/g'.l:confirm '| write | bwipe'
 | 
						|
 | 
						|
        " Restore the session.
 | 
						|
        if filereadable('_replace_session.vim')
 | 
						|
            silent! exec 'source _replace_session.vim | !rm _replace_session.vim &>/dev/null'
 | 
						|
        endif
 | 
						|
 | 
						|
        call s:CreateCtags()
 | 
						|
    else
 | 
						|
        call PrintError("Unable to search since you're not in a git repo!")
 | 
						|
    endif
 | 
						|
endfunction
 | 
						|
noremap <leader>r :call GlobalReplaceIt(0)<cr>
 | 
						|
noremap <leader>rr :call GlobalReplaceIt(1)<cr>
 | 
						|
 | 
						|
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
" RENAME CURRENT FILE
 | 
						|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
						|
function! RenameFile()
 | 
						|
    let l:old_name = expand('%')
 | 
						|
    let l:new_name = input('New file name: ', expand('%'), 'file')
 | 
						|
    if l:new_name != '' && l:new_name != l:old_name
 | 
						|
        exec 'saveas' l:new_name
 | 
						|
        exec '!rm' l:old_name
 | 
						|
        redraw!
 | 
						|
    endif
 | 
						|
endfunction
 | 
						|
noremap <leader>n :call RenameFile()<cr>
 | 
						|
 | 
						|
"---------------------------------------------------------------------------------------------------
 | 
						|
 |