dotfiles/vimrc

1425 lines
53 KiB
VimL
Raw Normal View History

" @incomplete Move all leader definitions to the bottom, so that it's easier to see them.
2019-05-24 17:24:38 +00:00
" @incomplete Add setup steps (plugins, cache setup, search tool, etc).
2019-12-31 05:37:09 +00:00
"###################################################################################################
"
" The config is chopped up into sections. These are the headings, which you
" can use to quickly jump to a particular section:
2021-02-08 20:40:32 +00:00
" #0 GLOBALS
" #1 PLUGINS
" #2 BASE CONFIG
" #3 PLUGIN CONFIGS
" #4 VISUALS
" #5 CUSTOM FUNCTIONS / COMMANDS
2019-12-31 05:37:09 +00:00
"
"###################################################################################################
let g:campo_vimrc_initialized = 0 " Will be set to 1 at the end of the file. Can be used to avoid changes on subsequent vimrc reloads.
scriptencoding utf-8
2022-01-22 17:13:54 +00:00
" @note If the file contains a BOM then vim will automatically set `bomb` for
" the buffer so that the BOM is written out again.
2017-03-27 18:39:07 +00:00
set encoding=utf-8 fileencoding=utf-8 fileencodings=ucs-bom,utf8,prc
2017-07-28 15:20:08 +00:00
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 g:vim_dir = $HOME . "/.vim"
let mapleader=","
function! IsWindows()
2019-09-12 03:12:10 +00:00
if s:uname =~ "mingw" || s:uname =~ "msys"
2019-12-31 05:37:09 +00:00
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
"################################################################
"################################################################
"################################################################
2021-02-08 20:40:32 +00:00
"#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 it's sourced. These have been flagged with the
" note :unsupported-in-lvimrc.
"
" Also take note that an .lvimrc has precedence because it's loaded after this
" and the private vimrc.
2021-10-14 18:20:40 +00:00
" --------------------------------------------------------------------------------------------------
2021-10-14 18:20:40 +00:00
" @note :unsupported-in-lvimrc
2022-11-05 04:48:21 +00:00
let g:campo_max_line_length = 120 " 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 ctrlp, ripgrep, compilation errors, etc), in rows
let g:quickfix_pane_height = 20
""""""""""""""
" COLORS
""""""""""""""
2022-12-29 23:53:54 +00:00
let g:campo_light_dark_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
2022-12-06 02:12:30 +00:00
" When set to 1, the whitespace stripping force/ignore file filters below will
" be expected to have full paths to the files, otherwise just the filename is
" required.
let g:campo_use_full_paths_for_whitespace_stripping_file_filters = 1
" If g:campo_strip_trailing_whitespace is 1 then you can stop stripping in
2022-12-06 02:12:30 +00:00
" specific directories by setting this to a list of full directory paths.
" This has no effect when g:campo_strip_trailing_whitespace is 0.
"
2022-12-06 02:12:30 +00:00
" e.g. let g:campo_directories_to_ignore_when_stripping_trailing_whitespace = ['/z/modules', '/d/build']
let g:campo_directories_to_ignore_when_stripping_trailing_whitespace = []
" If g:campo_strip_trailing_whitespace is 1 then you can stop stripping in
" specific files by setting this to a list of full file paths.
" This has no effect when g:campo_strip_trailing_whitespace is 0.
"
" e.g. let g:campo_files_to_ignore_when_stripping_trailing_whitespace = ['/z/modules/test.h', '/d/build/config.h']
let g:campo_files_to_ignore_when_stripping_trailing_whitespace = []
2022-12-06 02:12:30 +00:00
" If g:campo_strip_trailing_whitespace is 0 then you can force whitespace
2022-12-06 02:12:30 +00:00
" stripping in specific directories by setting this to a list of full paths.
" This has no effect when g:campo_strip_trailing_whitespace is 1.
"
" e.g. let g:campo_directories_to_force_stripping_trailing_whitespace = ['/z/modules '/d/build']
let g:campo_directories_to_force_stripping_trailing_whitespace = []
2022-12-06 02:12:30 +00:00
" If g:campo_strip_trailing_whitespace is 0 then you can force whitespace
" stripping in specific files by setting this to a list of full file paths.
" This has no effect when g:campo_strip_trailing_whitespace is 1.
"
" e.g. let g:campo_files_to_force_stripping_trailing_whitespace = ['/z/modules/test.h', '/d/build/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
""""""""""""""
2022-11-29 04:37:35 +00:00
" I use the ctags executable from https://github.com/universal-ctags/ctags-win32/releases
"
" Be sure to check out the ctags plugin config in section #3 for additional API functions.
2022-11-29 04:37:35 +00:00
2021-12-03 02:07:47 +00:00
" 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.
2021-12-03 02:07:47 +00:00
" 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']
2021-12-10 00:54:08 +00:00
let g:campo_extensions_that_run_ctags = ['c','cpp','h','hpp','inc','cs','py','asm','ex','exs']
2021-12-03 02:07:47 +00:00
" Default files and directories that ctags should ignore when doing a
" recursive crawl.
" @note The CreateCtags function will always ignore .git and node_modules
2021-12-03 02:07:47 +00:00
" 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
2021-12-03 02:07:47 +00:00
" 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 = ""
""""""""""""""
" JAI
""""""""""""""
" Set to your Jai install path. Used for various commands, like for example
" searching the modules and how_to directories with CtrlP
let g:campo_jai_path = ''
2023-01-19 23:13:38 +00:00
" Args to include when compiling a Jai file.
let g:campo_jai_build_args = ''
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
2021-02-08 20:40:32 +00:00
"#1 PLUGINS
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
2015-11-29 19:41:56 +00:00
call plug#begin('~/.vim/plugged')
2015-02-24 04:34:00 +00:00
2017-07-10 15:08:49 +00:00
"////////////////////////////////////////////////////////////////
" MISC
"////////////////////////////////////////////////////////////////
2017-04-27 22:39:58 +00:00
Plug 'vim-airline/vim-airline' " Enhanced status/tabline.
2019-12-31 05:37:09 +00:00
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 'sir-pinecone/errormarker.vim' " Build error highlighting (requires skywind3000/asyncrun.vim).
2019-12-31 05:37:09 +00:00
Plug 'skywind3000/asyncrun.vim' " Async commands.
Plug 'nelstrom/vim-qargs' " For the GlobalReplaceIt function (i.e. search and replace).
2018-06-11 17:39:04 +00:00
2019-03-28 00:15:55 +00:00
if IsWindows()
2019-12-31 05:37:09 +00:00
Plug 'suxpert/vimcaps' " Disable capslock (useful if the OS isn't configured to do so).
2017-11-15 16:30:09 +00:00
endif
2017-06-16 20:51:40 +00:00
2017-07-10 15:08:49 +00:00
"////////////////////////////////////////////////////////////////
" COLORS
"////////////////////////////////////////////////////////////////
2017-04-27 22:39:58 +00:00
Plug 'luochen1990/rainbow', { 'commit': '1c45e0f' } " Rainbow parens. Locked to an older commit that still works fine on my PC.
2017-04-27 20:22:32 +00:00
Plug 'vim-airline/vim-airline-themes'
2015-03-24 21:55:35 +00:00
2020-07-26 17:11:49 +00:00
if IsWindows()
Plug 'godlygeek/csapprox' " Try to make gvim themes look decent on Windows.
endif
2022-03-25 00:18:19 +00:00
Plug 'dracula/vim', { 'as': 'dracula' }
2019-12-31 05:37:09 +00:00
"//////////////////////////////
" SYNTAX HIGHLIGHTING
"//////////////////////////////
2017-04-27 22:39:58 +00:00
Plug 'rluba/jai.vim' " Jai
2022-12-28 05:48:50 +00:00
Plug 'bfrg/vim-cpp-modern' " C/C++
2020-10-09 15:54:01 +00:00
Plug 'fedorenchik/fasm.vim' " Flat Assembler
Plug 'elixir-editors/vim-elixir' " Elixir
2022-12-28 05:48:50 +00:00
Plug 'pprovost/vim-ps1' " PowerShell
Plug 'tpope/vim-markdown' " Markdown
"Plug 'vim-ruby/vim-ruby' " Ruby
"Plug 'fatih/vim-go' " Go
"Plug 'rust-lang/rust.vim' " Rust
"Plug 'jdonaldson/vaxe' " Haxe
2019-12-31 05:37:09 +00:00
"//////////////////////////////
2015-11-29 19:41:56 +00:00
call plug#end()
2015-03-21 19:13:17 +00:00
filetype plugin indent on
2015-02-24 04:34:00 +00:00
2019-12-31 05:37:09 +00:00
"---------------------------------------------------------------------------------------------------
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
2021-02-08 20:40:32 +00:00
"#2 BASE CONFIG
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2012-04-19 14:23:13 +00:00
" BASIC EDITING CONFIGURATION
2017-07-10 15:08:49 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2012-04-19 14:23:13 +00:00
set hidden
set history=10000
set expandtab
2019-05-15 18:00:25 +00:00
set tabstop=4
set shiftwidth=4
set softtabstop=4
2011-04-15 18:44:28 +00:00
set autoindent
2012-04-19 14:23:13 +00:00
set laststatus=2
2019-12-31 05:37:09 +00:00
set showcmd " Display incomplete commands.
2012-04-19 14:23:13 +00:00
set showmatch
2019-12-31 05:37:09 +00:00
set incsearch " Highlight matches as you type.
set hlsearch " Highlight matches.
2013-04-20 18:00:26 +00:00
set dictionary+=/usr/share/dict/words
2019-12-31 05:37:09 +00:00
"set clipboard=unnamed " Yank and paste with the system clipboard.
2018-03-15 18:39:50 +00:00
set number
2019-12-31 05:37:09 +00:00
set ignorecase smartcase " Make searches case-sensitive only if they contain upper-case characters.
set visualbell " No bell sounds.
2017-07-28 15:20:08 +00:00
set ttyfast
2012-04-19 14:23:13 +00:00
set cmdheight=2
2017-06-09 22:48:02 +00:00
set switchbuf=useopen,split
2012-04-19 14:23:13 +00:00
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
2019-12-31 05:37:09 +00:00
" @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
2020-03-15 18:44:36 +00:00
"set shell=zsh
set shell=bash
endif
2019-12-31 05:37:09 +00:00
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
2019-07-17 16:00:31 +00:00
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:
2020-06-25 17:30:08 +00:00
"
" 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.
"
2012-04-19 14:23:13 +00:00
set backup
2018-03-15 18:39:50 +00:00
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
2017-07-17 16:38:17 +00:00
2019-12-31 05:37:09 +00:00
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.
2019-03-28 00:15:55 +00:00
set termguicolors
2019-12-31 05:37:09 +00:00
syntax on " Enable highlighting for syntax
2019-03-28 00:15:55 +00:00
2013-08-30 17:11:59 +00:00
set wildmenu
set wildmode=longest,list,full
2019-03-28 00:15:55 +00:00
set wildignore+=*/log/*,*.so,*.swp,*.zip,*/rdoc/*
if executable('rg')
set grepprg=rg\ --vimgrep\ --hidden " Requires ripgrep to be installed.
endif
2019-03-28 00:15:55 +00:00
2019-12-31 05:37:09 +00:00
set list listchars=tab:»·,trail" Show trailing whitespace.
2019-03-28 00:15:55 +00:00
2019-12-31 05:37:09 +00:00
set timeoutlen=300 ttimeoutlen=0 " Adding this since the esc remap on the 'i' key had a long delay when pressed.
2011-04-15 18:44:28 +00:00
2019-09-09 19:44:02 +00:00
" @fixme might be broken if lowered to 100 from original value of 4000. Will
" first try 500 and tweak from there.
2019-09-30 20:51:10 +00:00
" 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.
2019-12-31 05:37:09 +00:00
" Fix vim's background colour erase - http://snk.tuxfamily.org/log/vim-256color-bce.html
if &term =~ '256color'
2019-12-31 05:37:09 +00:00
" 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
2019-12-31 05:37:09 +00:00
" 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>
2013-08-16 20:50:47 +00:00
"---------------------------------------------------------------
" 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
2012-04-19 14:23:13 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" CUSTOM AUTOCMDS
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2017-07-26 16:06:00 +00:00
augroup campoCmds
2020-07-25 23:39:09 +00:00
" Clear all autocmds in the group.
autocmd!
" Automatically wrap at N characters.
autocmd FileType gitcommit setlocal colorcolumn=72
2022-02-10 20:00:15 +00:00
" @flagged for removal. It's a bit annoying. autocmd BufRead,BufNewFile *.{md,txt,plan} exec "setlocal textwidth=".g:campo_max_line_length
2020-07-25 23:39:09 +00:00
2022-12-28 05:48:50 +00:00
" Enable spell checking by default.
2020-07-25 23:39:09 +00:00
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
" Properly indent schemes (scheme, racket, etc).
autocmd BufRead,BufNewFile *.{lisp,scm,rkt} setlocal equalprg=scmindent.vim.rkt
2020-07-25 23:39:09 +00:00
" Elixir indent
autocmd FileType elixir setlocal tabstop=2 | setlocal shiftwidth=2 | setlocal softtabstop=2
2020-10-09 15:54:01 +00:00
" Fasm indent; uses the fedorenchik/fasm.vim plugin.
autocmd BufReadPre *.asm let g:asmsyntax = "fasm"
2020-07-25 23:39:09 +00:00
" 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
autocmd BufWritePost ~/.vimrc_templates.private silent! source $MYVIMRC
2020-07-25 23:39:09 +00:00
" Remove trailing whitespace when saving any file.
function! StripTrailingWhitespaces()
if g:campo_strip_trailing_whitespace == 1
2022-12-06 02:12:30 +00:00
if len(g:campo_directories_to_ignore_when_stripping_trailing_whitespace)
for path in g:campo_directories_to_ignore_when_stripping_trailing_whitespace
if path == expand('%:p:h')
return
endif
endfor
endif
if len(g:campo_files_to_ignore_when_stripping_trailing_whitespace)
2022-12-06 02:12:30 +00:00
for filename in g:campo_files_to_ignore_when_stripping_trailing_whitespace
if (g:campo_use_full_paths_for_whitespace_stripping_file_filters == 1 && filename == expand('%:p')) || (g:campo_use_full_paths_for_whitespace_stripping_file_filters == 0 && filename == expand('%:t'))
return
endif
endfor
endif
else
2022-12-06 02:12:30 +00:00
let l:found_match = 0
if len(g:campo_directories_to_force_stripping_trailing_whitespace)
for path in g:campo_directories_to_force_stripping_trailing_whitespace
if path == expand('%:p:h')
let l:found_match = 1
break
endif
endfor
2022-12-06 02:12:30 +00:00
endif
if l:found_match == 0 && len(g:campo_files_to_force_stripping_trailing_whitespace)
for filename in g:campo_files_to_force_stripping_trailing_whitespace
if (g:campo_use_full_paths_for_whitespace_stripping_file_filters == 1 && filename == expand('%:p')) || (g:campo_use_full_paths_for_whitespace_stripping_file_filters == 0 && filename == expand('%:t'))
let l:found_match = 1
break
endif
endfor
endif
if l:found_match == 0
return
endif
2020-07-25 23:39:09 +00:00
endif
let l = line(".")
let c = col(".")
%s/\s\+$//e
call cursor(l, c)
2020-07-25 23:39:09 +00:00
endfun
autocmd BufWritePre * call StripTrailingWhitespaces()
2017-07-26 16:06:00 +00:00
augroup END
2015-03-21 19:13:17 +00:00
2012-04-19 14:23:13 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" MISC KEY MAPS
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Lowercase the e (have a habit of making it uppercase).
:ca E e
2019-12-31 05:37:09 +00:00
" Mapping ESC in insert mode and command mode to double i.
2018-06-11 17:39:04 +00:00
imap jj <Esc>
2011-04-15 18:44:28 +00:00
2019-12-31 05:37:09 +00:00
" Suspend vim process and return to the shell. Can return to vim with `fg`.
nnoremap <leader>z <c-z>
" edit a file
nnoremap <leader>e :e
2019-12-31 05:37:09 +00:00
" 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>
2019-12-31 05:37:09 +00:00
" 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/
2017-10-10 23:50:00 +00:00
"------------------------------------------------------------
2019-12-31 05:37:09 +00:00
" 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! 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)
2022-12-06 02:12:30 +00:00
"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 .= "--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 .= ' ' . 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()
2022-01-01 18:41:53 +00:00
write!
call CreateCtags()
endfunction
function! DoSingleWriteThenQuit()
2022-01-01 18:41:53 +00:00
write!
call CreateCtags()
quit
endfunction
2022-01-22 17:13:54 +00:00
" @fixme Sometimes a :wa that saves multiple files causes vim to hang and use
" a lot of CPU.
function! DoMultiWrite()
let l:current_buffer = bufnr("%")
bufdo wa
" Restore the last buffer because it may have changed.
exec "buffer " . l:current_buffer
call 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
2022-01-10 16:14:11 +00:00
cnoreabbrev Qa qa
2018-06-11 17:39:04 +00:00
command! Qa qall
2019-12-31 05:37:09 +00:00
" Disable Ex mode.
noremap Q <Nop>
2013-07-10 16:13:13 +00:00
"------------------------------------------------------------
2019-12-31 05:37:09 +00:00
" Open a terminal within vim. Use `exit` to close it.
2023-01-26 20:54:02 +00:00
" DISABLING because I don't use this and I want to use the <leader>t for opening my todo file.
"if exists(':terminal')
" noremap <leader>t :terminal<cr>
" tnoremap <leader>te <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
2015-11-29 23:25:02 +00:00
2019-12-31 05:37:09 +00:00
" 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>
2015-11-29 23:25:02 +00:00
" Make it easier to jump around the command line. The default behaviour is
2019-12-31 05:37:09 +00:00
" using the arrow keys with or without shift.
2015-11-29 23:25:02 +00:00
:cnoremap <C-J> <S-Left>
:cnoremap <C-K> <S-Right>
2015-11-29 21:57:35 +00:00
2013-04-20 18:00:26 +00:00
" 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>
2013-04-20 18:00:26 +00:00
2019-12-31 05:37:09 +00:00
" Forward delete and replace a word.
noremap <leader>d ciw
2020-02-03 23:03:31 +00:00
" 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>
2020-02-03 23:03:31 +00:00
" Toggle line numbers.
noremap <leader>o :set number! number?<cr>
2014-02-17 07:00:21 +00:00
2019-12-31 05:37:09 +00:00
" 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=
2015-02-28 19:28:13 +00:00
2019-12-31 05:37:09 +00:00
" Clear the search buffer (highlighting) when hitting return.
nnoremap <cr> :nohlsearch<cr>
" Switch to the previous file.
2012-04-19 14:23:13 +00:00
nnoremap <leader><leader> <c-^>
2011-04-15 18:44:28 +00:00
2019-12-31 05:37:09 +00:00
" Replace currently selected text with default register without yanking it.
vnoremap p "_dP
2019-12-31 05:37:09 +00:00
" 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>
2017-06-16 20:16:34 +00:00
2019-04-02 15:57:52 +00:00
" Replace all instances of the highlighted text with whatever you enter.
2019-04-27 15:42:58 +00:00
nnoremap <c-g> :%s///g<left><left>
2019-04-02 15:57:52 +00:00
2017-07-10 15:08:49 +00:00
"////////////////////////////////////////////////////////////////
2012-04-19 14:23:13 +00:00
" MULTIPURPOSE TAB KEY
2017-07-10 15:08:49 +00:00
"////////////////////////////////////////////////////////////////
2012-04-19 14:23:13 +00:00
function! InsertTabWrapper()
2016-08-03 04:28:39 +00:00
let l:col = col('.') - 1
if !l:col || getline('.')[l:col - 1] !~ '\k'
2012-04-19 14:23:13 +00:00
return "\<tab>"
else
return "\<c-p>"
2011-04-15 18:44:28 +00:00
endif
2012-04-19 14:23:13 +00:00
endfunction
inoremap <tab> <c-r>=InsertTabWrapper()<cr>
inoremap <s-tab> <c-n>
2019-12-31 05:37:09 +00:00
"---------------------------------------------------------------------------------------------------
2012-04-19 14:23:13 +00:00
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
2021-02-08 20:40:32 +00:00
"#3 PLUGIN CONFIGS
"################################################################
"################################################################
"################################################################
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" LOCAL VIMRC
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:localvimrc_sandbox = 0
let g:localvimrc_ask = 0
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" TAGBAR
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2017-09-22 21:16:30 +00:00
noremap <F12> :TagbarToggle<cr>
2022-01-01 18:41:53 +00:00
" Sort tags by their order in the source file. Press 's' to sort them alphabetically.
let g:tagbar_sort = 0
2017-11-15 16:30:09 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2018-06-11 17:39:04 +00:00
" GITGUTTER
2017-11-15 16:30:09 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2019-12-31 05:37:09 +00:00
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)
2018-06-11 17:39:04 +00:00
nmap ]h <Plug>GitGutterPrevHunk
augroup gitGutterPluginCmds
autocmd!
" Update marks on save
autocmd BufWritePost * GitGutter
augroup END
2017-11-15 16:30:09 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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']
2019-03-28 00:15:55 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" RIPGREP
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:rg_highlight = 1
2021-10-14 18:20:40 +00:00
let g:rg_window_height = g:quickfix_pane_height
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" C-TAGS
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Set extra paths to use when searching for ctags files. By default the current
" directory is always checked. You can use this to combine tag lookups from
" different projects, e.g. set it to the Jai directory and you can look up
" current project tags and Jai module tags (of course this isn't needed if you
" have Jai module tags in your local file).
"
" This destructively overwrites the tags option value.
"
" Call this from a .vimrc.private or .lvimrc file, e.g.
" call g:SetExtraCtagsPaths([g:campo_jai_path.'/tags'])
"
function! g:SetExtraCtagsPaths(paths_array)
let l:list = './tags,tags' " This is the default tags list set by vim.
for path in a:paths_array
let l:list .= ',' . path
endfor
let &tags=l:list
endfunction
2019-03-28 01:35:59 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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.
" CtrlP finds the tags file by using vim's 'tags' option value. I initially
" tried changing the tags value to the working_path if one is provided. I made
" a copy of the current tags value and attempted to restore it when CtrlP was
" exited without an action or a tag action took place. I wasn't able to get
" the tags restored because there's no vim event that gets triggered when a
" tag is opened using the :tag comment. I tried a bunch of autocmds on buffer,
" window and cmdline events but wasn't able to find anything that fired AFTER
" the tag command. So we're instead just setting the tags list once for the
" session and not bothering with changing it on the fly. See g:SetExtraCtagsPaths
function! CtrlP_Search(search_path)
" If a:search_path is empty then ctrlp will use g:ctrlp_working_path_mode to determine the cwd to search in.
execute 'CtrlP ' . a:search_path
endfunction
function! CtrlP_JaiSearch(jai_rel_search_path)
if g:campo_jai_path == ''
call PrintError("g:campo_jai_path isn't set!")
return
endif
let l:path = g:campo_jai_path
if a:jai_rel_search_path != ''
let l:path .= '/' . a:jai_rel_search_path
endif
if !isdirectory(l:path)
call PrintError("Directory ".l:path." doesn't exist.")
return
endif
call CtrlP_Search(l:path)
endfunction
" CtrlP File Searching
noremap <leader>g :call CtrlP_Search('')<cr> " Search in current directory
noremap <leader>gg :call CtrlP_JaiSearch('')<cr> " Search in Jai directory
noremap <leader>gm :call CtrlP_JaiSearch('modules')<cr> " Search in Jai modules
noremap <leader>gh :call CtrlP_JaiSearch('how_to')<cr> " Search in Jai how_to
noremap <leader>ge :call CtrlP_JaiSearch('examples')<cr> " Search in Jai examples
2019-03-28 01:35:59 +00:00
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.
2021-10-14 18:20:40 +00:00
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
2019-03-28 01:35:59 +00:00
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.
2021-10-14 18:20:40 +00:00
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()
2019-03-28 01:35:59 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" GIT
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2021-02-08 20:40:32 +00:00
noremap <leader>gb :Git blame -w<cr>
2018-03-15 18:39:50 +00:00
" Ignore whitespace changes; follow renames and copies.
2021-10-22 00:06:44 +00:00
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']
2022-12-29 23:53:54 +00:00
let s:rainbow_theme = g:campo_light_dark_mode
function! UpdateRainbowConf()
2020-07-25 23:39:09 +00:00
let g:rainbow_conf = {
\ 'ctermfgs': (s:rainbow_theme == "light"? s:dark_rainbow : s:light_rainbow)
2020-07-25 23:39:09 +00:00
\}
"\ 'separately': {
"\ '*': 0, " Disable all
"\ 'c++': {} " Only enable c++
"\ }
endfunction
call UpdateRainbowConf()
function! ReloadRainbow()
2020-07-25 23:39:09 +00:00
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
2017-10-29 20:35:44 +00:00
endif
endfunction
2019-12-31 05:37:09 +00:00
"---------------------------------------------------------------------------------------------------
"################################################################
"################################################################
"################################################################
2021-02-08 20:40:32 +00:00
"#4 VISUALS
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" LAYOUT
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"////////////////////////////////////////////////////////////////
" CENTER THE BUFFER
"////////////////////////////////////////////////////////////////
2020-07-25 23:39:09 +00:00
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
2023-01-22 13:34:06 +00:00
exec 'vertical resize' string(&columns * 0.65)
2020-07-25 23:39:09 +00:00
endfunction
nnoremap <leader>c :call CenterPane()<cr>
function! RemoveCenterPane()
2020-07-25 23:39:09 +00:00
wincmd w
close
endfunction
nnoremap <leader>cw :call RemoveCenterPane()<cr>
2017-07-10 15:08:49 +00:00
"////////////////////////////////////////////////////////////////
" TEXT ALIGNMENT PLUGIN
"////////////////////////////////////////////////////////////////
let b:lion_squeeze_spaces = 1
2017-07-10 15:08:49 +00:00
"////////////////////////////////////////////////////////////////
" 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()"
2022-12-29 23:53:54 +00:00
" Toggle between light and dark themes.
noremap <leader>l :call ToggleLightDarkTheme()<cr>
let s:current_light_dark_mode = g:campo_light_dark_mode
2017-07-10 15:08:49 +00:00
2022-12-29 23:53:54 +00:00
function! ToggleLightDarkTheme()
if s:current_light_dark_mode == 'light'
call ChangeLightDarkMode('dark', 0)
else
call ChangeLightDarkMode('light', 0)
endif
endfunction
function! ChangeLightDarkMode(mode, onlySetTheme)
if a:mode == 'light'
2020-07-25 23:39:09 +00:00
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
2022-12-29 23:53:54 +00:00
let s:current_light_dark_mode = a:mode
2020-07-25 23:39:09 +00:00
if !a:onlySetTheme
2022-12-29 23:53:54 +00:00
exec 'AirlineTheme' a:mode
2020-07-25 23:39:09 +00:00
endif
2017-07-10 15:08:49 +00:00
endfunction
2022-12-29 23:53:54 +00:00
" Set the intial light/dark mode.
if g:campo_light_dark_mode =~ 'light'
call ChangeLightDarkMode('light', 1)
2017-07-10 15:08:49 +00:00
else
2022-12-29 23:53:54 +00:00
call ChangeLightDarkMode('dark', 1)
2017-07-10 15:08:49 +00:00
endif
" Open the current color scheme for editing.
function! EditColorScheme()
let l:path = g:vim_dir . '/colors/' . s:theme . '.vim'
if filereadable(l:path)
execute 'vsplit ' . l:path
else
call PrintError("Failed to open " . l:path . " for editing.")
endif
endfunction
command -nargs=0 EditColorScheme call EditColorScheme()
2017-07-10 15:08:49 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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):/
2017-07-10 15:08:49 +00:00
\ 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):/
2017-07-10 15:08:49 +00:00
\ containedin=.*Comment,vimCommentTitle
augroup END
hi def link MyNotes Notes
augroup vimrc_notices
2022-11-29 04:37:35 +00:00
autocmd!
autocmd Syntax * syn match MyNotices /\v<(WARNING|IMPORTANT):/
2017-07-10 15:08:49 +00:00
\ containedin=.*Comment,vimCommentTitle
augroup END
hi def link MyNotices Notices
2017-11-15 16:30:09 +00:00
augroup vimrc_annotated_todo
autocmd!
2017-11-15 16:30:09 +00:00
" This was a major pain in the ass to get working...
autocmd Syntax * syn match cTodo /@\S\+/
2017-11-15 16:30:09 +00:00
\ containedin=.*Comment,vimCommentTitle
augroup END
augroup vimrc_annotated_notes
autocmd!
autocmd Syntax * syn match cTodo /#\+ .\+$/
2017-11-15 16:30:09 +00:00
\ containedin=.*Comment,vimCommentTitle
augroup END
2017-07-10 15:08:49 +00:00
2019-12-31 05:37:09 +00:00
"---------------------------------------------------------------------------------------------------
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
2021-02-08 20:40:32 +00:00
"#5 CUSTOM FUNCTIONS / COMMANDS
2017-07-10 15:08:49 +00:00
"################################################################
"################################################################
"################################################################
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" BUILD COMMANDS
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" AsyncRun status line
let g:airline_section_error = airline#section#create_right(['%{g:asyncrun_status}'])
" "make" value is needed for asyncrun to work with the errormarker plugin
" https://github.com/skywind3000/asyncrun.vim/wiki/FAQ#can-asyncrunvim-trigger-an-autocommand-quickfixcmdpost-to-get-some-plugin-like-errormaker-processing-the-content-in-quickfix-
2017-07-10 15:08:49 +00:00
let g:asyncrun_auto = "make"
" Error and warning gutter characters.
2017-07-10 15:08:49 +00:00
let errormarker_errortext = "E"
let errormarker_warningtext = "W"
let errormarker_infotext = "I"
" Gutter character colors. See color file for the group definition.
let errormarker_errortextgroup = "BuildError"
let errormarker_warningtextgroup = "BuildWarn"
let errormarker_infotextgroup = "BuildInfo"
" Colors for the marked lines. See color file for the group definition.
let errormarker_errorgroup = "BuildError"
let errormarker_warninggroup = "BuildWarn"
let errormarker_infogroup = "BuildInfo"
2017-07-10 15:08:49 +00:00
"""""""""""""""""""""""""
" Custom error formats
"""""""""""""""""""""""""
" @note: You can debug the error parsing by running :ShowErrorEntries
" This will print the valid entries. You'll know parsing is correct when the
" entries have a type, line num, error message, etc.
function! ShowErrorEntries()
" Prints out valid quickfix errors.
redraw!
for l:d in getqflist()
if l:d.valid == 1
echomsg l:d
endif
endfor
endfunction
command -nargs=0 ShowErrorEntries call ShowErrorEntries()
2022-11-29 04:40:04 +00:00
" Jai
"
" Z:\path\main.jai:100,10: Error: Undeclared identifier 's1'.
set errorformat=\\\ %#%f:%l\\,%c:\ %t%[A-z]%#:\ %m
" Microsoft compiler: cl.exe
2021-02-08 20:40:32 +00:00
"
" Z:\path\main.cpp(2808): error C2220: the following warning is treated as an error
2022-11-29 04:40:04 +00:00
set errorformat+=\\\ %#%f(%l):\ %#%t%[A-z]%#\ %[A-z]%#%n:\ %m
2017-07-10 15:08:49 +00:00
" Microsoft MSBuild errors
"
" @note I got this off the Internet and haven't tested it yet.
"
" Z:\path\main.cpp(2808): error C2220: the following warning is treated as an error
set errorformat+=\\\ %#%f(%l\\,%c):\ %m
2017-07-10 15:08:49 +00:00
" Microsoft HLSL compiler: fxc.exe
"
" @note I got this off the Internet and haven't tested it yet.
" @todo Add an example
2017-07-10 15:08:49 +00:00
set errorformat+=\\\ %#%f(%l\\\,%c-%*[0-9]):\ %#%t%[A-z]%#\ %m
"""""""""""""""""""""""""
" Build functions
"""""""""""""""""""""""""
2017-07-10 15:08:49 +00:00
function! HideBuildResultsAndClearErrors()
2020-07-25 23:39:09 +00:00
RemoveErrorMarkers
2021-10-14 18:20:40 +00:00
call asyncrun#quickfix_toggle(g:quickfix_pane_height, 0)
2017-07-10 15:08:49 +00:00
endfunction
2017-08-21 18:26:22 +00:00
function! HideAsyncResults()
2021-10-14 18:20:40 +00:00
call asyncrun#quickfix_toggle(g:quickfix_pane_height, 0)
2017-08-21 18:26:22 +00:00
endfunction
2017-07-10 15:08:49 +00:00
function! ToggleBuildResults()
2021-10-14 18:20:40 +00:00
call asyncrun#quickfix_toggle(g:quickfix_pane_height)
2017-07-10 15:08:49 +00:00
endfunction
function! StopRunTask()
2020-07-25 23:39:09 +00:00
AsyncStop
call HideAsyncResults()
2017-07-10 15:08:49 +00:00
endfunction
function! Build(optimized=0, silent=0)
let l:ext = tolower(expand('%:e'))
let l:parent_dir = expand('%:p:h')
let l:async_cmd = "AsyncRun! -save=2 "
if a:silent
let l:async_cmd .= "-post=call\\ HideAsyncResults() "
endif
2023-01-19 23:13:38 +00:00
let l:is_jai = 0
let l:cmd = ""
if filereadable(l:parent_dir . "/build.jai")
" Jai build file
2023-01-19 23:13:38 +00:00
let l:is_jai = 1
let l:cmd = "jai " . l:parent_dir . "/build.jai "
if a:optimized == 1
echo "Compiling release build.jai"
let l:cmd .= "-release "
else
echo "Compiling debug build.jai"
endif
elseif l:ext == "jai"
2023-01-19 23:13:38 +00:00
let l:is_jai = 1
let l:cmd = "jai % "
2022-12-06 02:12:30 +00:00
if a:optimized == 1
echo "Compiling release " . expand('%:t')
let l:cmd .= "-release "
else
echo "Compiling debug " . expand('%:t')
endif
" If there's a local modules/ directory then we'll import it.
if isdirectory(l:parent_dir . "/modules")
let l:cmd .= "-import_dir modules "
2022-12-06 02:12:30 +00:00
endif
else
let l:cmd .= './build* '
2022-12-06 02:12:30 +00:00
if a:optimized == 1
let l:cmd .= '-o '
2022-12-06 02:12:30 +00:00
endif
2022-11-29 04:37:35 +00:00
endif
2023-01-19 23:13:38 +00:00
if l:is_jai
let l:cmd .= ' '.g:campo_jai_build_args
endif
exec l:async_cmd . l:cmd
2022-11-29 04:37:35 +00:00
endfunction
2022-12-06 02:12:30 +00:00
function! RunExe()
if tolower(expand('%:e')) == "jai"
if filereadable(expand('%:p:r') . '.exe')
exec "AsyncRun! " . expand('%:p:r') . ".exe"
else
let l:files = systemlist('ls ' . expand('%:p:h') . '/*.exe 2>/dev/null')
if len(l:files) > 0
exec "AsyncRun! " . l:files[0]
else
call PrintError("No exe found. Compile first?")
endif
endif
2022-11-29 04:37:35 +00:00
else
2022-12-06 02:12:30 +00:00
exec "AsyncRun! -post=call\\ StopRunTask() ./run %"
2022-11-29 04:37:35 +00:00
endif
2017-08-21 18:26:22 +00:00
endfunction
2017-07-10 15:08:49 +00:00
" Show results window the moment the async job starts
augroup asyncPluginCmds
autocmd!
2021-10-14 18:20:40 +00:00
autocmd User AsyncRunStart call asyncrun#quickfix_toggle(g:quickfix_pane_height, 1)
2017-07-10 15:08:49 +00:00
augroup END
" Toggle build results
2017-10-25 15:01:42 +00:00
nnoremap <leader>bc :call ToggleBuildResults()<cr>
noremap <F11> :call ToggleBuildResults()<cr>
2017-07-10 15:08:49 +00:00
" Hide build results and clear errors
noremap <F10> :call HideBuildResultsAndClearErrors()<cr>
" Execute build script and keep results.
nnoremap <silent><leader>b :call Build(0)<cr>
" Execute build and hide results.
nnoremap <silent><F8> :call Build(0, 1)<cr>
2022-12-06 02:12:30 +00:00
" Execute optimized build script
nnoremap <leader>bb :call Build(1)<cr>
2017-07-10 15:08:49 +00:00
" Execute run script
nnoremap <silent><leader>br :call RunExe()<cr>
nnoremap <silent><F9> :call RunExe()<cr>
2017-09-22 21:16:30 +00:00
2017-07-10 15:08:49 +00:00
nnoremap <leader>bs :AsyncStop<cr>
"Go to next build error
nnoremap <F7> :cn<CR>
nnoremap <C-n> :cn<CR>
2015-03-21 19:13:17 +00:00
2017-07-10 15:08:49 +00:00
"Go to previous build error
nnoremap <F6> :cp<CR>
nnoremap <C-p> :cp<CR>
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2019-09-09 19:31:47 +00:00
" SEARCH
2017-07-10 15:08:49 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2019-03-28 00:15:55 +00:00
" Search using ripgrep (first install with Rust: cargo install ripgrep).
function! Search(path, search_args, case_insensitive=0)
let l:helper = "Search '" . a:path . "' (" . (len(a:search_args) > 0 ? a:search_args . " | " : '') . (a:case_insensitive ? "INSENSITIVE" : "SENSITIVE") . "): "
2020-07-25 23:39:09 +00:00
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.
2022-06-11 21:16:29 +00:00
let l:rg_args = "--column --line-number --no-heading --fixed-strings --no-ignore --hidden --follow --trim -g \"!tags\" -g \"!.git/\" -g \"!AppData/\" " . a:search_args
2020-07-25 23:39:09 +00:00
if a:case_insensitive
2020-07-25 23:39:09 +00:00
let l:rg_args .= " --ignore-case"
endif
" Some characters need to be escaped.
let l:escaped_term = substitute(l:term, '[#%]', '\\\\\\&', 'g')
let l:format = 'Rg ' . l:rg_args . ' ' . a:path . ' -e %s'
let l:cmd = printf(l:format, shellescape(l:escaped_term))
exec l:cmd
2019-09-09 19:31:47 +00:00
endfunction
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Search in current directory.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Case insensitive:
noremap <leader>s :call Search('.', g:campo_custom_search_args, 1)<cr>
" Case sensitive:
noremap <leader>ss :call Search('.', g:campo_custom_search_args)<cr>
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
" # Search in directory containing the active file.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Case insensitive:
noremap <leader>sf :call Search(expand('%:p:h'), g:campo_custom_search_args, 1)<cr>
" Case sensitive:
noremap <leader>ssf :call Search(expand('%:p:h'), g:campo_custom_search_args)<cr>
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Search in Jai folders
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Case insensitive:
noremap <leader>sg :call Search(g:campo_jai_path, g:campo_custom_search_args, 1)<cr>
noremap <leader>sm :call Search(g:campo_jai_path . '/modules', g:campo_custom_search_args, 1)<cr>
noremap <leader>sh :call Search(g:campo_jai_path . '/how_to', g:campo_custom_search_args, 1)<cr>
noremap <leader>se :call Search(g:campo_jai_path . '/examples', g:campo_custom_search_args, 1)<cr>
" Case sensitive:
noremap <leader>ssg :call Search(g:campo_jai_path, g:campo_custom_search_args)<cr>
noremap <leader>ssm :call Search(g:campo_jai_path . '/modules', g:campo_custom_search_args)<cr>
noremap <leader>ssh :call Search(g:campo_jai_path . '/how_to', g:campo_custom_search_args)<cr>
noremap <leader>sse :call Search(g:campo_jai_path . '/examples', g:campo_custom_search_args)<cr>
2019-09-09 19:31:47 +00:00
" 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
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" @warning I've stopped using this because it sometimes locks up vim and I
" have to force exit the process then clean up the swap files.
" @improve Figure out what's causing vim to freeze and fix it. Seems to happen
" when it quickly changes and saves a handful of buffers.
" 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
2020-07-25 23:39:09 +00:00
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()
2020-07-25 23:39:09 +00:00
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'
2020-07-25 23:39:09 +00:00
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'
2020-07-25 23:39:09 +00:00
endif
call CreateCtags()
2017-07-10 15:08:49 +00:00
else
call PrintError("Unable to search since you're not in a git repo!")
2017-07-10 15:08:49 +00:00
endif
endfunction
noremap <leader>r :call GlobalReplaceIt(0)<cr>
noremap <leader>rr :call GlobalReplaceIt(1)<cr>
2017-07-10 15:08:49 +00:00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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
2022-12-06 02:12:30 +00:00
let l:confirm = confirm("Rename ".l:old_name." to ".l:new_name."?", "&Yes\n&No")
if l:confirm == 1
exec 'saveas' l:new_name
exec 'silent! !rm' l:old_name
redraw!
endif
2017-07-10 15:08:49 +00:00
endif
endfunction
noremap <leader>n :call RenameFile()<cr>
2015-03-21 19:13:17 +00:00
2019-12-31 05:37:09 +00:00
"---------------------------------------------------------------------------------------------------
2015-03-21 19:13:17 +00:00
let g:campo_vimrc_initialized = 1