"!!! makes use of marker ' " Sessions set sessionoptions=blank,buffers,curdir,folds,help,options,tabpages " some conditional configs if has('mouse') set mouse=a endif if &t_Co > 2 || has("gui_running") syntax on set hlsearch "Highlight search results endif if v:version > 702 set cm=blowfish end if v:version > 800 set cm=blowfish2 end set nocompatible """""""""""""""" " set linespace=0 set scrolloff=6 set history=50 " keep 50 lines of command line history set nonumber " set relativenumber set langmenu=en_UK let $LANG = 'en_UK' source $VIMRUNTIME/delmenu.vim source $VIMRUNTIME/menu.vim set guioptions-=r set guioptions-=R set guioptions-=l set guioptions-=L try set undodir=$HOME/.vimundo set undofile catch echom "Undofile doesn't work :(" endtry filetype plugin on filetype indent on set ruler set backspace=eol,start,indent set path+=** " Enable fuzzy search " STAAAAAARS set wildmenu "Menu for tab completion set enc=utf8 " Search Stuff set ignorecase set smartcase noh set incsearch set lazyredraw set magic "Who doesn't want to be a vim-wizard? set showmatch " Backup and file stuff set nobackup set nowb " set noswapfile set swapfile " Indentation, etc. set tabstop=2 set softtabstop=2 set shiftwidth=2 set noexpandtab set smarttab set autoindent set smartindent set smarttab set shiftwidth=2 set gdefault set wrap au BufEnter,BufRead * set linebreak set breakat=\ .,{ set display+=lastline if v:version>=800 set breakindent set breakindentopt=sbr au WinNew * set breakindentopt=sbr set showbreak=.\ else set showbreak=+->\ end set listchars=eol:¶,tab:»\ ,trail:.,nbsp:. set modeline " Allows setting vim options in other files set statusline=(%n)\ %f\ [%M%R]\ [%Y]%=%l,%c%V\ %4.P set laststatus=2 set cmdheight=1 set timeoutlen=1200 " Clipboard and Copy/Paste things if has('unnamedplus') " Allow copying to and from OS clipboard set clipboard=unnamedplus else set clipboard=unnamed end " === GENERAL UTILITIES === function! s:autoClose_HelperOpen(open, close) let next_c = getline(".")[col(".")-1] if match(next_c, "\s") return a:open.a:close."\" else return a:open end endfunc function! s:autoClose_HelperClose(open, close) if getline(".")[col(".")-1] ==# a:close return "\" elseif getline(line(".")+1) if match(getline(line(".")+1), "\M^\s*".escape(a:close, "\\")) return "\\\f".a:close."\" end else return a:close end endfunc function! s:autoClose_HelperDouble(open) if getline(".")[col(".")-1] ==# a:open " Step over return "\" else return a:open.a:open."\" end endfunc function! s:autoClose_HelperEnter() if exists("b:autoClose_Pairs") let next_c = getline(".")[col(".")-1] let prev_c = getline(".")[col(".")-2] if (next_c !=# "") && (prev_c !=# "") if exists("b:autoClose_Pairs[prev_c]") if (next_c ==# b:autoClose_Pairs[prev_c]) return "\m'\\`'\" end end end end return "\" endfunc function! s:autoClose_HelperSpace() if exists("b:autoClose_Pairs") let next_c = getline(".")[col(".")-1] let prev_c = getline(".")[col(".")-2] if (next_c !=# "") && (prev_c !=# "") if exists("b:autoClose_Pairs[prev_c]") if (next_c ==# b:autoClose_Pairs[prev_c]) return "\\h\" end end end end return "\" endfunc function! s:autoClose_AddPair(open, close) "TODO: Improve with expand('') if !exists("b:autoClose_Pairs") let b:autoClose_Pairs = {} end let b:autoClose_Pairs[a:open] = a:close if a:open!=#a:close exe "inoremap ".a:open." autoClose_HelperOpen('".a:open."', '".a:close."')" exe "inoremap ".a:close." autoClose_HelperClose('".a:open."', '".a:close."')" else exe "inoremap ".a:open." autoClose_HelperDouble('".a:open."')" end inoremap autoClose_HelperEnter() inoremap autoClose_HelperSpace() endfunc function! MatchingLines(pattern) let list = [] let pattern = a:pattern exec "g/".pattern."/ call add(list, expand('%').'('.line('.').') : '.matchstr(getline('.'), '".pattern."'))" return list endfunc function! s:mld_helper(list, pattern) " Helper function for MatchingLinesDict call add(a:list, {'filename': expand("%"), 'lnum': line("."), 'col': match(getline("."), a:pattern)+1, 'text': matchstr(getline("."), a:pattern)}) endfunc function! MatchingLinesDict(pattern) let list = [] silent! exec "g/".a:pattern."/ call s:mld_helper(list, a:pattern)" return list endfunc function! LocationAddLineCol(filename, lnum, text, col) call setloclist(0, [{'filename': a:filename, 'lnum': a:lnum, 'desc': a:text, 'col': a:col}], 'a') endfunction function! QuickfixAddLineCol(filename, lnum, text, col) call setqflist([{'filename': a:filename, 'lnum': a:lnum, 'desc': a:text, 'col': a:col}], 'a') endfunction function! LocationAddLine(filename, lnum, text) call setloclist(0, [{'filename': a:filename, 'lnum': a:lnum, 'desc': a:text}], 'a') endfunction function! QuickfixAddLine(filename, lnum, text) call setqflist([{'filename': a:filename, 'lnum': a:lnum, 'desc': a:text}], 'a') endfunction " Original implementation: https://stackoverflow.com/a/6271254/4984564 function! VisualSelection() if mode()=="v" let [line_start, column_start] = getpos("v")[1:2] let [line_end, column_end] = getpos(".")[1:2] else let [line_start, column_start] = getpos("'<")[1:2] let [line_end, column_end] = getpos("'>")[1:2] end if (line2byte(line_start)+column_start) > (line2byte(line_end)+column_end) let [line_start, column_start, line_end, column_end] = \ [line_end, column_end, line_start, column_start] end let lines = getline(line_start, line_end) if len(lines) == 0 return '' endif let lines[-1] = lines[-1][: column_end - 1] let lines[0] = lines[0][column_start - 1:] return join(lines, "\n") endfunction function! StringReverse(str) return join(reverse(split(str, ".\\zs")), "") endfunc function! ShiftMarker(m,n) let [bufn,line,column,offset]=getpos("'".a:m) call setpos("'".a:m,[bufn,line,column+a:n,offset]) endfunc function! ShiftSelection(n) call ShiftMarker("<", a:n) call ShiftMarker(">", a:n) endfunc " Auto-close quickfix list when leaving it function! s:autobd() au! WinLeave bd! endfun " === GENERAL COMMANDS === command! L lopen | set number | set norelativenumber command! LAddLine call LocationAddLine(expand("%"), line("."), getline(".")) command! QAddLine call QuickfixAddLine(expand("%"), line("."), getline(".")) command! LAddCursor call LocationAddLineCol(expand("%"), line("."), getline("."), col(".")) command! QAddCursor call QuickfixAddLineCol(expand("%"), line("."), getline("."), col(".")) command! Fixme call setloclist(0, MatchingLinesDict("\\c\\)) command! -nargs=1 QFind call setqflist(MatchingLinesDict()) function! s:hex(...) if !(a:000 == [""]) let l:args = map(copy(a:000), {i,val -> "-".val}) else let l:args = [] end if !exists("b:hex") exec '%!xxd '.join(l:args, " ") let b:hex = 1 let b:prev_filetype = &filetype let &filetype = "xxd" else exec '%!xxd -r '.join(l:args, " ") unlet b:hex let &filetype = b:prev_filetype unlet b:prev_filetype end endfunction command! -nargs=* Hex call hex() function! s:unsaved() if &mod let l:filetype = &filetype diffthis below new set modifiable r # diffthis au BufUnload diffoff! let &filetype = l:filetype set nomodifiable set buftype=nofile set bufhidden=delete silent exec "file =".expand("#:t")."@".strftime("%H:%M") exec "normal \k" set foldlevel=999 else echom "No changes to show :)" end endfun command! Unsaved call unsaved() function! s:snapshot() let l:filetype = &filetype let l:clipboard = @" let l:pos = getpos(".") silent 0,$yank " below new set modifiable silent put " 1,1del let &filetype = l:filetype set nomodifiable set buftype=nofile set bufhidden=hide call setpos(".", l:pos) silent exec "file ¬".expand("#:t")."@".strftime("%H:%M") exec "normal \k" set foldlevel=999 let @" = l:clipboard endfun command! Snapshot call snapshot() " === GENERAL KEY MAPPINGS === let mapleader = "\\" " --- /dev/null --- noremap d "_d noremap d "_d noremap x "_x noremap x x " --- Numbvers --- nnoremap - nnoremap = " --- MOVEMENT --- nnoremap j gj nnoremap k gk " --- CLIPBOARD --- nnoremap Y y$ " --- OTHER --- " Don't exit visual mode when "shifting" vnoremap < >gv vnoremap " `>a"`<":call ShiftSelection(1)gv vnoremap ' `>a'`<':call ShiftSelection(1)gv vnoremap ( `>a)`<(:call ShiftSelection(1)gv vnoremap [ `>a]`<[:call ShiftSelection(1)gv vnoremap { `>a}`<{:call ShiftSelection(1)gv nnoremap :L noremap : noremap @: noremap Q @q nnoremap gQ " noremap :w noremap :echo "Calm the fuck down! There's \ no need to save every 10 seconds FFS!" nnoremap :bnext nnoremap :bprevious nnoremap j :lnext nnoremap k :lNext nnoremap j :cnext nnoremap k :cNext nnoremap Bi i nnoremap Ea a " This one does nothing, but I'm adding it to remember not to remap the tab key nnoremap nnoremap noremap :setl number! noremap :setl relativenumber! noremap :setl autowriteall!:setl autowriteall? noremap :setl list! nnoremap ge nnoremap gE com! SetWD :cd %:p:h com! SetLWD :lcd %:p:h com! Removetrailingspaces let _s=@/ | %s/\v(\\@t :Removetrailingspaces nnoremap :copy . nnoremap dx 0"_d$ nnoremap dcx 0d$ nnoremap : :let @* = @: nnoremap ":%s/\\<".expand("")."\\>/" vnoremap ":%s/".VisualSelection()."/" " Put in new line with indentation nnoremap ]p :let [content, type]= \[getreg(v:register), getregtype(v:register)] \| \call setreg(v:register, content, "V")]p \:call setreg(v:register, content, type) nnoremap [p :let [content, type]= \[getreg(v:register), getregtype(v:register)] \| \call setreg(v:register, content, "V")[p \:call setreg(v:register, content, type) " Empty Lines nnoremap :call Enter(0) nnoremap :call Enter(1) function! s:Enter(shift) if !a:shift silent exe "normal o\0\"_d$" else silent exe "normal O\0\"_d$j" endif endfunction " Markdown Stuff vnoremap * `>a*` vnoremap _ `>a__` " === GENERAL ABBREVIATIONS === cabbr rcpath fnamemodify($MYVIMRC, ":p:h") cabbr %% expand('%:p:h') digraph <3 9829 digraph ue 252 digraph UE 220 digraph ae 228 digraph AE 196 digraph oe 246 digraph OE 214 digraph ss 223 " === GENERAL AUTOCOMMANDS === nnoremap h :call toggleWUC() function! s:updateWUC() if exists("b:hlwuc") if b:hlwuc > 1 call matchdelete(b:hlwuc) end end if exists("b:word_hl") let hl = b:word_hl else let hl = "Underlined" endif let str = "\\<".escape(expand(""), "\\")."\\>" let b:hlwuc = matchadd(hl, str) "echom str endfunc function! s:toggleWUC() augroup hlwuc if exists("b:hlwuc") autocmd! if b:hlwuc > 1 call matchdelete(b:hlwuc) end unlet b:hlwuc else call updateWUC() autocmd CursorMoved call updateWUC() autocmd CursorMovedI call updateWUC() endif augroup END endfunction " Autosave when vim loses focus :) function! TryAutosave() if &autowriteall==1 silent w redraw echo "Autosaving buffers..." endif endfunction au FocusLost * call TryAutosave() " au WinLeave * call TryAutosave() vnoremap g :call GrepOperator(visualmode()) nnoremap g :set operatorfunc=GrepOperatorg@ function! s:GrepOperator(type) let reg1 = @@ if a:type==# 'v' execute "normal! `y" elseif a:type==# 'char' execute "normal! `[y`]" else return end echom "vimgrep! /\\M".escape(@@, "\\")."/ *" silent! execute "vimgrep /\\M".escape(@@, "\\")."/j *" let @@ = reg1 copen set nowrap endfunction " Window Height stuff command! EqualH call Equal() command! -nargs=1 WinHeight call SetWinMinHeight() function! Equal() set winminheight=0 set winheight=1 set equalalways! set equalalways! endfunc function! SetWinMinHeight(num) execute "set winminheight=".0 if a:num>=0 execute "set winheight=".(a:num+1) execute "set winminheight=".a:num endif execute "set winheight=".9999 endfunc " call SetWinMinHeight(2) function! AddWinMinHeight(num) let a:new = &winminheight + a:num call SetWinMinHeight(a:new) set winminheight? endfunc " Window Width Stuff command! EqualW silent! call EqualW() command! -nargs=1 WinWidth call SetWinMinWidth() function! EqualW() set winminwidth=0 set winwidth=1 set equalalways! set equalalways! endfunc function! SetWinMinWidth(num) execute "set winminwidth=".0 if a:num>=0 execute "set winwidth=".(a:num+1) execute "set winminwidth=".a:num endif execute "set winwidth=".9999 endfunc function! AddWinMinWidth(num) let a:new = &winminwidth + a:num call SetWinMinWidth(a:new) set winminwidth? endfunc " === GENERIC AUTOCOMMANDS === if has("autocmd") " Enable file type detection. " Use the default filetype settings, so that mail gets 'tw' set to 72, " 'cindent' is on in C files, etc. " Also load indent files, to automatically do language-dependent indenting. filetype plugin indent on " Put these in an autocmd group, so that we can delete them easily. " For all text files set 'textwidth' to 78 characters. " autocmd FileType text setlocal textwidth=78 " When editing a file, always jump to the last known cursor position. " Don't do it when the position is invalid or when inside an event handler " (happens when dropping a file on gvim). autocmd BufReadPost * \ if line("'\"") >= 1 && line("'\"") <= line("$") | \ exe "normal! g`\"" | \ endif endif " === FILETYPE SPECIFIC STUFF === " --- GENERIC STUFF --- au BufNewFile,BufRead * :call init_generic_file() function! s:init_generic_file() call s:autoClose_AddPair("[", "]") call s:autoClose_AddPair("(", ")") call s:autoClose_AddPair("{", "}") call s:autoClose_AddPair('"', '"') endfunc " Vimscript Stuff au BufNewFile,BufRead *.vim,*vimrc :call init_vim_file() function! s:init_vim_file() setl number nnoremap :w:so % nnoremap c A" nnoremap if ofunction! m'()endfunction`'l command! -buffer Functions lex MatchingLines("^\\s*fun\\(ction\\)\\?\\>!.*$") command! -buffer Commands lex MatchingLines("^\\s*com\\(mand\\)\\?\\>!.*$") command! -buffer Autocommands lex MatchingLines("^\\s*au\\(tocmd\\)\\?\\>!\\@!.*$") endfunction " --- C / C++ Stuff --- " Insert Stuff au BufNewFile,BufRead *.c,*.cpp,*.h,*.hpp :nnoremap ii O#include <>i au BufNewFile,BufRead *.c,*.cpp,*.h,*.hpp :nnoremap ip oprintf("m'\n");`'a au BufNewFile,BufRead *.c,*.cpp,*.h,*.hpp :nnoremap im oint main(int argc, char *args[]) {}O " Other Stuff au BufNewFile,BufRead *.c,*.cpp,*.h,*.hpp :nnoremap ; m'$a;`' " --- Ruby Stuff --- au BufNewFile,BufRead *.rb :call init_ruby_file() function! s:init_ruby_file() set makeprg=ruby\ -wc\ % setl number command! -buffer Defines lex MatchingLines("^\\s*def\\>\\s\\+\\zs.*$") | lopen command! -buffer Functions Defines " Alias command! -buffer Methods Defines " Alias command! -buffer Classes lex MatchingLines("^\\s*class\\>\\s\\+\\zs.*$") | lopen command! -buffer Modules lex MatchingLines("^\\s*module\\>\\s\\+\\zs.*$") | lopen command! -buffer Requires lex MatchingLines("^\\s*require\\(_relative\\)\\?\\>\\s\\+\\zs.*$") | lopen nnoremap ic oclass m'end`'a nnoremap id odef m'()end`'a nnoremap :w:!ruby % nnoremap :lmake:lopen nnoremap ~ :call RubyComment(0) nnoremap # :call RubyComment(1) vnoremap ~ :call RubyComment(0) vnoremap # :call RubyComment(1) endfunction function! s:RubyComment(a) if a:a==0 " silent! exec '.s/\m^\s*\zs#*//' silent! exec '.s/\v^(\s|#)*//' normal == elseif a:a==1 " silent! exec '.s/\v^(\s*#)@!/#/' silent! exec '.s/\v^(\s|#)*/# /' normal == end endfunction " augroup rbindent " autocmd! " au BufNewFile,BufRead *.rb :set noexpandtab | :retab! | " " au BufWritePre *.rb :let ts = &tabstop | set expandtab | set tabstop=2 | retab | let &tabstop=ts | :set noexpandtab " " au BufWritepost *.rb :silent! :undo | :exe "normal \" " augroup END " --- Lua Stuff --- " Matches all types of Lua string! " \v(["'])\zs.{-}\ze\\@1init_lua_file() function! s:init_lua_file() setl number command! -buffer Requires call setloclist(0, MatchingLinesDict("\\vrequire\\s*\\(?(([\"'])\\zs.{-}\\ze\\\\@1init_html_file() function! s:init_html_file() setl number command! -buffer -nargs=1 Tag normal \ i<><m'/>`' nnoremap t ""ciw<""p>m'""p>`'l nnoremap T ""diw"_cc<""p>o""p>O inoremap ""ciw<""p>m'""p>`'l inoremap ""diw"_cc<""p>o""p>O endfunction