diff --git a/.bashrc b/.bashrc index 3b6b80c..4b14722 100644 --- a/.bashrc +++ b/.bashrc @@ -11,11 +11,12 @@ alias cds="cd ~/Source/pl/" PS1="\[$(tput bold)\](\t)[\[$(tput setaf 6)\]\u@\h\[$(tput setaf 2)\] \w]>\[$(tput sgr0)\]" # Source the git bash completion file -if [ -f /etc/bash_completion.d/git ]; then - source /etc/bash_completion.d/git +if [ -f /usr/local/etc/bash_completion.d/git-completion.bash ]; then + source /usr/local/etc/bash_completion.d/git-completion.bash + source /usr/local/etc/bash_completion.d/git-prompt.sh GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWSTASHSTATE=1 - PS1='\[$(tput bold)\](\t)[\[\e[1;32m\]\u@\[\[\e[1;32m\]\h\e[0m\]\[$(tput bold)\]]\e[0m\]\[\e[1;34m\]\[$(__git_ps1)\e[0m\] [\w]: ' + PS1="\[$(tput bold)\](\t)[\[$(tput setaf 6)\]\u@\h\[$(tput setaf 2)\] \$(__git_ps1 \" (%s)\") \w]>\[$(tput sgr0)\]" fi export PS1 diff --git a/.vim/autoload/coffee.vim b/.vim/autoload/coffee.vim new file mode 100644 index 0000000..04d5efb --- /dev/null +++ b/.vim/autoload/coffee.vim @@ -0,0 +1,54 @@ +" Language: CoffeeScript +" Maintainer: Mick Koch +" URL: http://github.com/kchmck/vim-coffee-script +" License: WTFPL + +" Set up some common global/buffer variables. +function! coffee#CoffeeSetUpVariables() + " Path to coffee executable + if !exists('g:coffee_compiler') + let g:coffee_compiler = 'coffee' + endif + + " Options passed to coffee with make + if !exists('g:coffee_make_options') + let g:coffee_make_options = '' + endif + + " Path to cake executable + if !exists('g:coffee_cake') + let g:coffee_cake = 'cake' + endif + + " Extra options passed to cake + if !exists('g:coffee_cake_options') + let g:coffee_cake_options = '' + endif + + " Path to coffeelint executable + if !exists('g:coffee_linter') + let g:coffee_linter = 'coffeelint' + endif + + " Options passed to CoffeeLint + if !exists('g:coffee_lint_options') + let g:coffee_lint_options = '' + endif + + " Pass the litcoffee flag to tools in this buffer if a litcoffee file is open. + " Let the variable be overwritten so it can be updated if a different filetype + " is set. + if &filetype == 'litcoffee' + let b:coffee_litcoffee = '--literate' + else + let b:coffee_litcoffee = '' + endif +endfunction + +function! coffee#CoffeeSetUpErrorFormat() + CompilerSet errorformat=Error:\ In\ %f\\,\ %m\ on\ line\ %l, + \Error:\ In\ %f\\,\ Parse\ error\ on\ line\ %l:\ %m, + \SyntaxError:\ In\ %f\\,\ %m, + \%f:%l:%c:\ error:\ %m, + \%-G%.%# +endfunction diff --git a/.vim/compiler/coffee.vim b/.vim/compiler/coffee.vim new file mode 100644 index 0000000..9a91d35 --- /dev/null +++ b/.vim/compiler/coffee.vim @@ -0,0 +1,82 @@ +" Language: CoffeeScript +" Maintainer: Mick Koch +" URL: http://github.com/kchmck/vim-coffee-script +" License: WTFPL + +" All this is needed to support compiling filenames with spaces, quotes, and +" such. The filename is escaped and embedded into the `makeprg` setting. +" +" Because of this, `makeprg` must be updated on every file rename. And because +" of that, `CompilerSet` can't be used because it doesn't exist when the +" rename autocmd is ran. So, we have to do some checks to see whether `compiler` +" was called locally or globally, and respect that in the rest of the script. + +if exists('current_compiler') + finish +endif + +let current_compiler = 'coffee' +call coffee#CoffeeSetUpVariables() + +" Pattern to check if coffee is the compiler +let s:pat = '^' . current_compiler + +" Get a `makeprg` for the current filename. +function! s:GetMakePrg() + return g:coffee_compiler . + \ ' -c' . + \ ' ' . b:coffee_litcoffee . + \ ' ' . g:coffee_make_options . + \ ' $*' . + \ ' ' . fnameescape(expand('%')) +endfunction + +" Set `makeprg` and return 1 if coffee is still the compiler, else return 0. +function! s:SetMakePrg() + if &l:makeprg =~ s:pat + let &l:makeprg = s:GetMakePrg() + elseif &g:makeprg =~ s:pat + let &g:makeprg = s:GetMakePrg() + else + return 0 + endif + + return 1 +endfunction + +" Set a dummy compiler so we can check whether to set locally or globally. +exec 'CompilerSet makeprg=' . current_compiler +" Then actually set the compiler. +call s:SetMakePrg() +call coffee#CoffeeSetUpErrorFormat() + +function! s:CoffeeMakeDeprecated(bang, args) + echoerr 'CoffeeMake is deprecated! Please use :make instead, its behavior ' . + \ 'is identical.' + sleep 5 + exec 'make' . a:bang a:args +endfunction + +" Compile the current file. +command! -bang -bar -nargs=* CoffeeMake +\ call s:CoffeeMakeDeprecated(, ) + +" Set `makeprg` on rename since we embed the filename in the setting. +augroup CoffeeUpdateMakePrg + autocmd! + + " Update `makeprg` if coffee is still the compiler, else stop running this + " function. + function! s:UpdateMakePrg() + if !s:SetMakePrg() + autocmd! CoffeeUpdateMakePrg + endif + endfunction + + " Set autocmd locally if compiler was set locally. + if &l:makeprg =~ s:pat + autocmd BufWritePre,BufFilePost call s:UpdateMakePrg() + else + autocmd BufWritePre,BufFilePost call s:UpdateMakePrg() + endif +augroup END diff --git a/.vim/ftdetect/ansible.vim b/.vim/ftdetect/ansible.vim new file mode 100644 index 0000000..32ceccd --- /dev/null +++ b/.vim/ftdetect/ansible.vim @@ -0,0 +1,17 @@ +function! s:isAnsible() + let filepath = expand("%:p") + let filename = expand("%:t") + if filepath =~ '\v/(tasks|roles)/.*\.ya?ml$' | return 1 | en + if filepath =~ '\v/(group|host)_vars/' | return 1 | en + if filename =~ '\v(playbook|site)\.ya?ml$' | return 1 | en + + let shebang = getline(1) + if shebang =~# '^#!.*/bin/env\s\+ansible-playbook\>' | return 1 | en + if shebang =~# '^#!.*/bin/ansible-playbook\>' | return 1 | en + + return 0 +endfunction + +:au BufNewFile,BufRead *.yml set ft=ansible +:au BufNewFile,BufRead *.j2 set ft=ansible_template +:au BufNewFile,BufRead hosts set ft=ansible_hosts diff --git a/.vim/ftdetect/coffee.vim b/.vim/ftdetect/coffee.vim new file mode 100644 index 0000000..5056929 --- /dev/null +++ b/.vim/ftdetect/coffee.vim @@ -0,0 +1,17 @@ +" Language: CoffeeScript +" Maintainer: Mick Koch +" URL: http://github.com/kchmck/vim-coffee-script +" License: WTFPL + +autocmd BufNewFile,BufRead *.coffee set filetype=coffee +autocmd BufNewFile,BufRead *Cakefile set filetype=coffee +autocmd BufNewFile,BufRead *.coffeekup,*.ck set filetype=coffee +autocmd BufNewFile,BufRead *._coffee set filetype=coffee + +function! s:DetectCoffee() + if getline(1) =~ '^#!.*\' + set filetype=coffee + endif +endfunction + +autocmd BufNewFile,BufRead * call s:DetectCoffee() diff --git a/.vim/ftdetect/syslog.vim b/.vim/ftdetect/syslog.vim new file mode 100644 index 0000000..55bcfdb --- /dev/null +++ b/.vim/ftdetect/syslog.vim @@ -0,0 +1 @@ +autocmd BufNewFile,BufRead *.log set filetype=syslog diff --git a/.vim/ftdetect/terraform.vim b/.vim/ftdetect/terraform.vim new file mode 100644 index 0000000..c49b1d0 --- /dev/null +++ b/.vim/ftdetect/terraform.vim @@ -0,0 +1,3 @@ +au BufRead,BufNewFile *.tf setlocal filetype=terraform +au BufRead,BufNewFile *.tfvars setlocal filetype=terraform +au BufRead,BufNewFile *.tfstate setlocal filetype=javascript diff --git a/.vim/ftplugin/ansible.vim b/.vim/ftplugin/ansible.vim new file mode 100644 index 0000000..f5e66a9 --- /dev/null +++ b/.vim/ftplugin/ansible.vim @@ -0,0 +1,4 @@ +" Slow yaml highlighting workaround +if exists('+regexpengine') && ('®expengine' == 0) + setlocal regexpengine=1 +endif diff --git a/.vim/ftplugin/ansible_hosts.vim b/.vim/ftplugin/ansible_hosts.vim new file mode 100644 index 0000000..393583b --- /dev/null +++ b/.vim/ftplugin/ansible_hosts.vim @@ -0,0 +1,9 @@ +if exists("b:did_ftplugin") + finish +else + let b:did_ftplugin = 1 +endif + +setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions-=c + +let b:undo_ftplugin = "setl comments< commentstring< formatoptions<" diff --git a/.vim/ftplugin/coffee.vim b/.vim/ftplugin/coffee.vim new file mode 100644 index 0000000..0b63dff --- /dev/null +++ b/.vim/ftplugin/coffee.vim @@ -0,0 +1,405 @@ +" Language: CoffeeScript +" Maintainer: Mick Koch +" URL: http://github.com/kchmck/vim-coffee-script +" License: WTFPL + +if exists('b:did_ftplugin') + finish +endif + +let b:did_ftplugin = 1 +call coffee#CoffeeSetUpVariables() + +setlocal formatoptions-=t formatoptions+=croql +setlocal comments=:# commentstring=#\ %s +setlocal omnifunc=javascriptcomplete#CompleteJS +setlocal suffixesadd+=coffee + +" Create custom augroups. +augroup CoffeeBufUpdate | augroup END +augroup CoffeeBufNew | augroup END + +" Enable coffee compiler if a compiler isn't set already. +if !len(&l:makeprg) + compiler coffee +endif + +" Switch to the window for buf. +function! s:SwitchWindow(buf) + exec bufwinnr(a:buf) 'wincmd w' +endfunction + +" Create a new scratch buffer and return the bufnr of it. After the function +" returns, vim remains in the scratch buffer so more set up can be done. +function! s:ScratchBufBuild(src, vert, size) + if a:size <= 0 + if a:vert + let size = winwidth(bufwinnr(a:src)) / 2 + else + let size = winheight(bufwinnr(a:src)) / 2 + endif + endif + + if a:vert + vertical belowright new + exec 'vertical resize' size + else + belowright new + exec 'resize' size + endif + + setlocal bufhidden=wipe buftype=nofile nobuflisted noswapfile nomodifiable + nnoremap q :hide + + return bufnr('%') +endfunction + +" Replace buffer contents with text and delete the last empty line. +function! s:ScratchBufUpdate(buf, text) + " Move to the scratch buffer. + call s:SwitchWindow(a:buf) + + " Double check we're in the scratch buffer before overwriting. + if bufnr('%') != a:buf + throw 'unable to change to scratch buffer' + endif + + setlocal modifiable + silent exec '% delete _' + silent put! =a:text + silent exec '$ delete _' + setlocal nomodifiable +endfunction + +" Parse the output of coffee into a qflist entry for src buffer. +function! s:ParseCoffeeError(output, src, startline) + " Coffee error is always on first line? + let match = matchlist(a:output, + \ '^\(\f\+\|\[stdin\]\):\(\d\):\(\d\): error: \(.\{-}\)' . "\n") + + if !len(match) + return + endif + + " Consider the line number from coffee as relative and add it to the beginning + " line number of the range the command was called on, then subtract one for + " zero-based relativity. + call setqflist([{'bufnr': a:src, 'lnum': a:startline + str2nr(match[2]) - 1, + \ 'type': 'E', 'col': str2nr(match[3]), 'text': match[4]}], 'r') +endfunction + +" Reset source buffer variables. +function! s:CoffeeCompileResetVars() + " Variables defined in source buffer: + " b:coffee_compile_buf: bufnr of output buffer + " Variables defined in output buffer: + " b:coffee_src_buf: bufnr of source buffer + " b:coffee_compile_pos: previous cursor position in output buffer + + let b:coffee_compile_buf = -1 +endfunction + +function! s:CoffeeWatchResetVars() + " Variables defined in source buffer: + " b:coffee_watch_buf: bufnr of output buffer + " Variables defined in output buffer: + " b:coffee_src_buf: bufnr of source buffer + " b:coffee_watch_pos: previous cursor position in output buffer + + let b:coffee_watch_buf = -1 +endfunction + +function! s:CoffeeRunResetVars() + " Variables defined in CoffeeRun source buffer: + " b:coffee_run_buf: bufnr of output buffer + " Variables defined in CoffeeRun output buffer: + " b:coffee_src_buf: bufnr of source buffer + " b:coffee_run_pos: previous cursor position in output buffer + + let b:coffee_run_buf = -1 +endfunction + +" Clean things up in the source buffers. +function! s:CoffeeCompileClose() + " Switch to the source buffer if not already in it. + silent! call s:SwitchWindow(b:coffee_src_buf) + call s:CoffeeCompileResetVars() +endfunction + +function! s:CoffeeWatchClose() + silent! call s:SwitchWindow(b:coffee_src_buf) + silent! autocmd! CoffeeAuWatch * + call s:CoffeeWatchResetVars() +endfunction + +function! s:CoffeeRunClose() + silent! call s:SwitchWindow(b:coffee_src_buf) + call s:CoffeeRunResetVars() +endfunction + +" Compile the lines between startline and endline and put the result into buf. +function! s:CoffeeCompileToBuf(buf, startline, endline) + let src = bufnr('%') + let input = join(getline(a:startline, a:endline), "\n") + + " Coffee doesn't like empty input. + if !len(input) + " Function should still return within output buffer. + call s:SwitchWindow(a:buf) + return + endif + + " Pipe lines into coffee. + let output = system(g:coffee_compiler . + \ ' -scb' . + \ ' ' . b:coffee_litcoffee . + \ ' 2>&1', input) + + " Paste output into output buffer. + call s:ScratchBufUpdate(a:buf, output) + + " Highlight as JavaScript if there were no compile errors. + if v:shell_error + call s:ParseCoffeeError(output, src, a:startline) + setlocal filetype= + else + " Clear the quickfix list. + call setqflist([], 'r') + setlocal filetype=javascript + endif +endfunction + +" Peek at compiled CoffeeScript in a scratch buffer. We handle ranges like this +" to prevent the cursor from being moved (and its position saved) before the +" function is called. +function! s:CoffeeCompile(startline, endline, args) + if a:args =~ '\' + echoerr 'CoffeeCompile watch is deprecated! Please use CoffeeWatch instead' + sleep 5 + call s:CoffeeWatch(a:args) + return + endif + + " Switch to the source buffer if not already in it. + silent! call s:SwitchWindow(b:coffee_src_buf) + + " Bail if not in source buffer. + if !exists('b:coffee_compile_buf') + return + endif + + " Build the output buffer if it doesn't exist. + if bufwinnr(b:coffee_compile_buf) == -1 + let src = bufnr('%') + + let vert = exists('g:coffee_compile_vert') || a:args =~ '\' + let size = str2nr(matchstr(a:args, '\<\d\+\>')) + + " Build the output buffer and save the source bufnr. + let buf = s:ScratchBufBuild(src, vert, size) + let b:coffee_src_buf = src + + " Set the buffer name. + exec 'silent! file [CoffeeCompile ' . src . ']' + + " Clean up the source buffer when the output buffer is closed. + autocmd BufWipeout call s:CoffeeCompileClose() + " Save the cursor when leaving the output buffer. + autocmd BufLeave let b:coffee_compile_pos = getpos('.') + + " Run user-defined commands on new buffer. + silent doautocmd CoffeeBufNew User CoffeeCompile + + " Switch back to the source buffer and save the output bufnr. This also + " triggers BufLeave above. + call s:SwitchWindow(src) + let b:coffee_compile_buf = buf + endif + + " Fill the scratch buffer. + call s:CoffeeCompileToBuf(b:coffee_compile_buf, a:startline, a:endline) + " Reset cursor to previous position. + call setpos('.', b:coffee_compile_pos) + + " Run any user-defined commands on the scratch buffer. + silent doautocmd CoffeeBufUpdate User CoffeeCompile +endfunction + +" Update the scratch buffer and switch back to the source buffer. +function! s:CoffeeWatchUpdate() + call s:CoffeeCompileToBuf(b:coffee_watch_buf, 1, '$') + call setpos('.', b:coffee_watch_pos) + silent doautocmd CoffeeBufUpdate User CoffeeWatch + call s:SwitchWindow(b:coffee_src_buf) +endfunction + +" Continually compile a source buffer. +function! s:CoffeeWatch(args) + silent! call s:SwitchWindow(b:coffee_src_buf) + + if !exists('b:coffee_watch_buf') + return + endif + + if bufwinnr(b:coffee_watch_buf) == -1 + let src = bufnr('%') + + let vert = exists('g:coffee_watch_vert') || a:args =~ '\' + let size = str2nr(matchstr(a:args, '\<\d\+\>')) + + let buf = s:ScratchBufBuild(src, vert, size) + let b:coffee_src_buf = src + + exec 'silent! file [CoffeeWatch ' . src . ']' + + autocmd BufWipeout call s:CoffeeWatchClose() + autocmd BufLeave let b:coffee_watch_pos = getpos('.') + + silent doautocmd CoffeeBufNew User CoffeeWatch + + call s:SwitchWindow(src) + let b:coffee_watch_buf = buf + endif + + " Make sure only one watch autocmd is defined on this buffer. + silent! autocmd! CoffeeAuWatch * + + augroup CoffeeAuWatch + autocmd InsertLeave call s:CoffeeWatchUpdate() + autocmd BufWritePost call s:CoffeeWatchUpdate() + augroup END + + call s:CoffeeWatchUpdate() +endfunction + +" Run a snippet of CoffeeScript between startline and endline. +function! s:CoffeeRun(startline, endline, args) + silent! call s:SwitchWindow(b:coffee_src_buf) + + if !exists('b:coffee_run_buf') + return + endif + + if bufwinnr(b:coffee_run_buf) == -1 + let src = bufnr('%') + + let buf = s:ScratchBufBuild(src, exists('g:coffee_run_vert'), 0) + let b:coffee_src_buf = src + + exec 'silent! file [CoffeeRun ' . src . ']' + + autocmd BufWipeout call s:CoffeeRunClose() + autocmd BufLeave let b:coffee_run_pos = getpos('.') + + silent doautocmd CoffeeBufNew User CoffeeRun + + call s:SwitchWindow(src) + let b:coffee_run_buf = buf + endif + + if a:startline == 1 && a:endline == line('$') + let output = system(g:coffee_compiler . + \ ' ' . b:coffee_litcoffee . + \ ' ' . fnameescape(expand('%')) . + \ ' ' . a:args) + else + let input = join(getline(a:startline, a:endline), "\n") + + if !len(input) + return + endif + + let output = system(g:coffee_compiler . + \ ' -s' . + \ ' ' . b:coffee_litcoffee . + \ ' ' . a:args, input) + endif + + call s:ScratchBufUpdate(b:coffee_run_buf, output) + call setpos('.', b:coffee_run_pos) + + silent doautocmd CoffeeBufUpdate User CoffeeRun +endfunction + +" Run coffeelint on a file, and add any errors between startline and endline +" to the quickfix list. +function! s:CoffeeLint(startline, endline, bang, args) + let input = join(getline(a:startline, a:endline), "\n") + + if !len(input) + return + endif + + let output = system(g:coffee_linter . + \ ' -s --reporter csv' . + \ ' ' . b:coffee_litcoffee . + \ ' ' . g:coffee_lint_options . + \ ' ' . a:args . + \ ' 2>&1', input) + + " Convert output into an array and strip off the csv header. + let lines = split(output, "\n")[1:] + let buf = bufnr('%') + let qflist = [] + + for line in lines + let match = matchlist(line, '^stdin,\(\d\+\),\d*,\(error\|warn\),\(.\+\)$') + + " Ignore unmatched lines. + if !len(match) + continue + endif + + " The 'type' will result in either 'E' or 'W'. + call add(qflist, {'bufnr': buf, 'lnum': a:startline + str2nr(match[1]) - 1, + \ 'type': toupper(match[2][0]), 'text': match[3]}) + endfor + + " Replace the quicklist with our items. + call setqflist(qflist, 'r') + + " If not given a bang, jump to first error. + if !len(a:bang) + silent! cc 1 + endif +endfunction + +" Complete arguments for Coffee* commands. +function! s:CoffeeComplete(cmd, cmdline, cursor) + let args = ['vertical'] + + " If no partial command, return all possibilities. + if !len(a:cmd) + return args + endif + + let pat = '^' . a:cmd + + for arg in args + if arg =~ pat + return [arg] + endif + endfor +endfunction + +" Set initial state variables if they don't exist +if !exists('b:coffee_compile_buf') + call s:CoffeeCompileResetVars() +endif + +if !exists('b:coffee_watch_buf') + call s:CoffeeWatchResetVars() +endif + +if !exists('b:coffee_run_buf') + call s:CoffeeRunResetVars() +endif + +command! -buffer -range=% -bar -nargs=* -complete=customlist,s:CoffeeComplete +\ CoffeeCompile call s:CoffeeCompile(, , ) +command! -buffer -bar -nargs=* -complete=customlist,s:CoffeeComplete +\ CoffeeWatch call s:CoffeeWatch() +command! -buffer -range=% -bar -nargs=* CoffeeRun +\ call s:CoffeeRun(, , ) +command! -buffer -range=% -bang -bar -nargs=* CoffeeLint +\ call s:CoffeeLint(, , , ) diff --git a/.vim/ftplugin/python.vim b/.vim/ftplugin/python.vim new file mode 100644 index 0000000..4a22137 --- /dev/null +++ b/.vim/ftplugin/python.vim @@ -0,0 +1,5 @@ +set tabstop=8 +set expandtab +set shiftwidth=4 +set softtabstop=4 +syntax on diff --git a/.vim/ftplugin/terraform.vim b/.vim/ftplugin/terraform.vim new file mode 100644 index 0000000..9e2d2e9 --- /dev/null +++ b/.vim/ftplugin/terraform.vim @@ -0,0 +1,66 @@ +" terraform.vim - basic vim/terraform integration +" Maintainer: HashiVim + +if exists("g:loaded_terraform") || v:version < 700 || &cp || !executable('terraform') + finish +endif +let g:loaded_terraform = 1 + +if !exists("g:terraform_fmt_on_save") + let g:terraform_fmt_on_save = 0 +endif + +function! s:commands(A, L, P) + return join([ + \ "apply", + \ "destroy", + \ "fmt", + \ "get", + \ "graph", + \ "import", + \ "init", + \ "output", + \ "plan", + \ "push", + \ "refresh", + \ "remote", + \ "show", + \ "taint", + \ "untaint", + \ "validate", + \ "version", + \ "state" + \ ], "\n") +endfunction + +" Adapted from vim-hclfmt: +" https://github.com/fatih/vim-hclfmt/blob/master/autoload/fmt.vim +function! terraform#fmt() + let l:curw = winsaveview() + let l:tmpfile = tempname() + call writefile(getline(1, "$"), l:tmpfile) + let output = system("terraform fmt -write " . l:tmpfile) + if v:shell_error == 0 + try | silent undojoin | catch | endtry + call rename(l:tmpfile, expand("%")) + silent edit! + let &syntax = &syntax + else + echo output + call delete(l:tmpfile) + endif + call winrestview(l:curw) +endfunction + +augroup terraform + autocmd! + autocmd VimEnter * + \ command! -nargs=+ -complete=custom,s:commands Terraform execute '!terraform '.. ' -no-color' + autocmd VimEnter * command! -nargs=0 TerraformFmt call terraform#fmt() + if get(g:, "terraform_fmt_on_save", 1) + autocmd BufWritePre *.tf call terraform#fmt() + autocmd BufWritePre *.tfvars call terraform#fmt() + endif +augroup END + +" vim:set et sw=2: diff --git a/.vim/indent/ansible.vim b/.vim/indent/ansible.vim new file mode 100644 index 0000000..c9f9fab --- /dev/null +++ b/.vim/indent/ansible.vim @@ -0,0 +1,54 @@ +let s:save_cpo = &cpo +set cpo&vim + +setlocal indentexpr=GetAnsibleIndent(v:lnum) +setlocal indentkeys=!^F,o,O,0#,0},0],<:>,-,* +setlocal nosmartindent +setlocal expandtab +setlocal softtabstop=2 +setlocal shiftwidth=2 +setlocal commentstring=#%s +setlocal formatoptions=cl +" c -> wrap long comments, including # +" l -> do not wrap long lines + +let s:comment = '\v^\s*#' " # comment +let s:array_entry = '\v^\s*-\s' " - foo +let s:named_module_entry = '\v^\s*-\s*(name|hosts):\s*\S' " - name: 'do stuff' +let s:dictionary_entry = '\v^\s*[^:-]+:\s*$' " with_items: +let s:key_value = '\v^\s*[^:-]+:\s*\S' " apt: name=package +let s:scalar_value = '\v:\s*[>|\|]\s*$' " shell: > + +if exists('*GetAnsibleIndent') + finish +endif + +function GetAnsibleIndent(lnum) + if a:lnum == 1 || !prevnonblank(a:lnum-1) + return 0 + endif + let prevlnum = prevnonblank(a:lnum - 1) + let maintain = indent(prevlnum) + let increase = maintain + &sw + + let line = getline(prevlnum) + if line =~ s:array_entry + if line =~ s:named_module_entry + return increase + else + return maintain + endif + elseif line =~ s:dictionary_entry + return increase + elseif line =~ s:key_value + if line =~ s:scalar_value + return increase + else + return maintain + endif + else + return maintain + endif +endfunction + +let &cpo = s:save_cpo diff --git a/.vim/indent/ansible_template.vim b/.vim/indent/ansible_template.vim new file mode 100644 index 0000000..c9f9fab --- /dev/null +++ b/.vim/indent/ansible_template.vim @@ -0,0 +1,54 @@ +let s:save_cpo = &cpo +set cpo&vim + +setlocal indentexpr=GetAnsibleIndent(v:lnum) +setlocal indentkeys=!^F,o,O,0#,0},0],<:>,-,* +setlocal nosmartindent +setlocal expandtab +setlocal softtabstop=2 +setlocal shiftwidth=2 +setlocal commentstring=#%s +setlocal formatoptions=cl +" c -> wrap long comments, including # +" l -> do not wrap long lines + +let s:comment = '\v^\s*#' " # comment +let s:array_entry = '\v^\s*-\s' " - foo +let s:named_module_entry = '\v^\s*-\s*(name|hosts):\s*\S' " - name: 'do stuff' +let s:dictionary_entry = '\v^\s*[^:-]+:\s*$' " with_items: +let s:key_value = '\v^\s*[^:-]+:\s*\S' " apt: name=package +let s:scalar_value = '\v:\s*[>|\|]\s*$' " shell: > + +if exists('*GetAnsibleIndent') + finish +endif + +function GetAnsibleIndent(lnum) + if a:lnum == 1 || !prevnonblank(a:lnum-1) + return 0 + endif + let prevlnum = prevnonblank(a:lnum - 1) + let maintain = indent(prevlnum) + let increase = maintain + &sw + + let line = getline(prevlnum) + if line =~ s:array_entry + if line =~ s:named_module_entry + return increase + else + return maintain + endif + elseif line =~ s:dictionary_entry + return increase + elseif line =~ s:key_value + if line =~ s:scalar_value + return increase + else + return maintain + endif + else + return maintain + endif +endfunction + +let &cpo = s:save_cpo diff --git a/.vim/indent/coffee.vim b/.vim/indent/coffee.vim new file mode 100644 index 0000000..7bd82e3 --- /dev/null +++ b/.vim/indent/coffee.vim @@ -0,0 +1,428 @@ +" Language: CoffeeScript +" Maintainer: Mick Koch +" URL: http://github.com/kchmck/vim-coffee-script +" License: WTFPL + +if exists('b:did_indent') + finish +endif + +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetCoffeeIndent(v:lnum) +" Make sure GetCoffeeIndent is run when these are typed so they can be +" indented or outdented. +setlocal indentkeys+=0],0),0.,=else,=when,=catch,=finally + +" If no indenting or outdenting is needed, either keep the indent of the cursor +" (use autoindent) or match the indent of the previous line. +if exists('g:coffee_indent_keep_current') + let s:DEFAULT_LEVEL = '-1' +else + let s:DEFAULT_LEVEL = 'indent(prevnlnum)' +endif + +" Only define the function once. +if exists('*GetCoffeeIndent') + finish +endif + +" Keywords that begin a block +let s:BEGIN_BLOCK_KEYWORD = '\C^\%(if\|unless\|else\|for\|while\|until\|' +\ . 'loop\|switch\|when\|try\|catch\|finally\|' +\ . 'class\)\>\%(\s*:\)\@!' + +" An expression that uses the result of a statement +let s:COMPOUND_EXPRESSION = '\C\%([^-]-\|[^+]+\|[^/]/\|[:=*%&|^<>]\)\s*' +\ . '\%(if\|unless\|for\|while\|until\|loop\|switch\|' +\ . 'try\|class\)\>' + +" Combine the two above +let s:BEGIN_BLOCK = s:BEGIN_BLOCK_KEYWORD . '\|' . s:COMPOUND_EXPRESSION + +" Operators that begin a block but also count as a continuation +let s:BEGIN_BLOCK_OP = '[([{:=]$' + +" Begins a function block +let s:FUNCTION = '[-=]>$' + +" Operators that continue a line onto the next line +let s:CONTINUATION_OP = '\C\%(\<\%(is\|isnt\|and\|or\)\>\|' +\ . '[^-]-\|[^+]+\|[^-=]>\|[^.]\.\|[<*/%&|^,]\)$' + +" Ancestor operators that prevent continuation indenting +let s:CONTINUATION = s:CONTINUATION_OP . '\|' . s:BEGIN_BLOCK_OP + +" A closing bracket by itself on a line followed by a continuation +let s:BRACKET_CONTINUATION = '^\s*[}\])]\s*' . s:CONTINUATION_OP + +" A continuation dot access +let s:DOT_ACCESS = '^\.' + +" Keywords that break out of a block +let s:BREAK_BLOCK_OP = '\C^\%(return\|break\|continue\|throw\)\>' + +" A condition attached to the end of a statement +let s:POSTFIX_CONDITION = '\C\S\s\+\zs\<\%(if\|unless\|when\|while\|until\)\>' + +" A then contained in brackets +let s:CONTAINED_THEN = '\C[(\[].\{-}\.\{-\}[)\]]' + +" An else with a condition attached +let s:ELSE_COND = '\C^\s*else\s\+\<\%(if\|unless\)\>' + +" A single-line else statement (without a condition attached) +let s:SINGLE_LINE_ELSE = '\C^else\s\+\%(\<\%(if\|unless\)\>\)\@!' + +" Pairs of starting and ending keywords, with an initial pattern to match +let s:KEYWORD_PAIRS = [ +\ ['\C^else\>', '\C\<\%(if\|unless\|when\|else\s\+\%(if\|unless\)\)\>', +\ '\C\'], +\ ['\C^catch\>', '\C\', '\C\'], +\ ['\C^finally\>', '\C\', '\C\'] +\] + +" Pairs of starting and ending brackets +let s:BRACKET_PAIRS = {']': '\[', '}': '{', ')': '('} + +" Max lines to look back for a match +let s:MAX_LOOKBACK = 50 + +" Syntax names for strings +let s:SYNTAX_STRING = 'coffee\%(String\|AssignString\|Embed\|Regex\|Heregex\|' +\ . 'Heredoc\)' + +" Syntax names for comments +let s:SYNTAX_COMMENT = 'coffee\%(Comment\|BlockComment\|HeregexComment\)' + +" Syntax names for strings and comments +let s:SYNTAX_STRING_COMMENT = s:SYNTAX_STRING . '\|' . s:SYNTAX_COMMENT + +" Compatibility code for shiftwidth() as recommended by the docs, but modified +" so there isn't as much of a penalty if shiftwidth() exists. +if exists('*shiftwidth') + let s:ShiftWidth = function('shiftwidth') +else + function! s:ShiftWidth() + return &shiftwidth + endfunction +endif + +" Get the linked syntax name of a character. +function! s:SyntaxName(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') +endfunction + +" Check if a character is in a comment. +function! s:IsComment(lnum, col) + return s:SyntaxName(a:lnum, a:col) =~ s:SYNTAX_COMMENT +endfunction + +" Check if a character is in a string. +function! s:IsString(lnum, col) + return s:SyntaxName(a:lnum, a:col) =~ s:SYNTAX_STRING +endfunction + +" Check if a character is in a comment or string. +function! s:IsCommentOrString(lnum, col) + return s:SyntaxName(a:lnum, a:col) =~ s:SYNTAX_STRING_COMMENT +endfunction + +" Search a line for a regex until one is found outside a string or comment. +function! s:SearchCode(lnum, regex) + " Start at the first column and look for an initial match (including at the + " cursor.) + call cursor(a:lnum, 1) + let pos = search(a:regex, 'c', a:lnum) + + while pos + if !s:IsCommentOrString(a:lnum, col('.')) + return 1 + endif + + " Move to the match and continue searching (don't accept matches at the + " cursor.) + let pos = search(a:regex, '', a:lnum) + endwhile + + return 0 +endfunction + +" Search for the nearest previous line that isn't a comment. +function! s:GetPrevNormalLine(startlnum) + let curlnum = a:startlnum + + while curlnum + let curlnum = prevnonblank(curlnum - 1) + + " Return the line if the first non-whitespace character isn't a comment. + if !s:IsComment(curlnum, indent(curlnum) + 1) + return curlnum + endif + endwhile + + return 0 +endfunction + +function! s:SearchPair(startlnum, lookback, skip, open, close) + " Go to the first column so a:close will be matched even if it's at the + " beginning of the line. + call cursor(a:startlnum, 1) + return searchpair(a:open, '', a:close, 'bnW', a:skip, max([1, a:lookback])) +endfunction + +" Skip if a match +" - is in a string or comment +" - is a single-line statement that isn't immediately +" adjacent +" - has a postfix condition and isn't an else statement or compound +" expression +function! s:ShouldSkip(startlnum, lnum, col) + return s:IsCommentOrString(a:lnum, a:col) || + \ s:SearchCode(a:lnum, '\C\') && a:startlnum - a:lnum > 1 || + \ s:SearchCode(a:lnum, s:POSTFIX_CONDITION) && + \ getline(a:lnum) !~ s:ELSE_COND && + \ !s:SearchCode(a:lnum, s:COMPOUND_EXPRESSION) +endfunction + +" Search for the nearest and farthest match for a keyword pair. +function! s:SearchMatchingKeyword(startlnum, open, close) + let skip = 's:ShouldSkip(' . a:startlnum . ", line('.'), line('.'))" + + " Search for the nearest match. + let nearestlnum = s:SearchPair(a:startlnum, a:startlnum - s:MAX_LOOKBACK, + \ skip, a:open, a:close) + + if !nearestlnum + return [] + endif + + " Find the nearest previous line with indent less than or equal to startlnum. + let ind = indent(a:startlnum) + let lookback = s:GetPrevNormalLine(a:startlnum) + + while lookback && indent(lookback) > ind + let lookback = s:GetPrevNormalLine(lookback) + endwhile + + " Search for the farthest match. If there are no other matches, then the + " nearest match is also the farthest one. + let matchlnum = nearestlnum + + while matchlnum + let lnum = matchlnum + let matchlnum = s:SearchPair(matchlnum, lookback, skip, a:open, a:close) + endwhile + + return [nearestlnum, lnum] +endfunction + +" Strip a line of a trailing comment and surrounding whitespace. +function! s:GetTrimmedLine(lnum) + " Try to find a comment starting at the first column. + call cursor(a:lnum, 1) + let pos = search('#', 'c', a:lnum) + + " Keep searching until a comment is found or search returns 0. + while pos + if s:IsComment(a:lnum, col('.')) + break + endif + + let pos = search('#', '', a:lnum) + endwhile + + if !pos + " No comment was found so use the whole line. + let line = getline(a:lnum) + else + " Subtract 1 to get to the column before the comment and another 1 for + " column indexing -> zero-based indexing. + let line = getline(a:lnum)[:col('.') - 2] + endif + + return substitute(substitute(line, '^\s\+', '', ''), + \ '\s\+$', '', '') +endfunction + +" Get the indent policy when no special rules are used. +function! s:GetDefaultPolicy(curlnum) + " Check whether equalprg is being ran on existing lines. + if strlen(getline(a:curlnum)) == indent(a:curlnum) + " If not indenting an existing line, use the default policy. + return s:DEFAULT_LEVEL + else + " Otherwise let autoindent determine what to do with an existing line. + return '-1' + endif +endfunction + +function! GetCoffeeIndent(curlnum) + " Get the previous non-blank line (may be a comment.) + let prevlnum = prevnonblank(a:curlnum - 1) + + " Bail if there's no code before. + if !prevlnum + return -1 + endif + + " Bail if inside a multiline string. + if s:IsString(a:curlnum, 1) + let prevnlnum = prevlnum + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + + " Get the code part of the current line. + let curline = s:GetTrimmedLine(a:curlnum) + " Get the previous non-comment line. + let prevnlnum = s:GetPrevNormalLine(a:curlnum) + + " Check if the current line is the closing bracket in a bracket pair. + if has_key(s:BRACKET_PAIRS, curline[0]) + " Search for a matching opening bracket. + let matchlnum = s:SearchPair(a:curlnum, a:curlnum - s:MAX_LOOKBACK, + \ "s:IsCommentOrString(line('.'), col('.'))", + \ s:BRACKET_PAIRS[curline[0]], curline[0]) + + if matchlnum + " Match the indent of the opening bracket. + return indent(matchlnum) + else + " No opening bracket found (bad syntax), so bail. + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + endif + + " Check if the current line is the closing keyword in a keyword pair. + for pair in s:KEYWORD_PAIRS + if curline =~ pair[0] + " Find the nearest and farthest matches within the same indent level. + let matches = s:SearchMatchingKeyword(a:curlnum, pair[1], pair[2]) + + if len(matches) + " Don't force indenting/outdenting as long as line is already lined up + " with a valid match + return max([min([indent(a:curlnum), indent(matches[0])]), + \ indent(matches[1])]) + else + " No starting keyword found (bad syntax), so bail. + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + endif + endfor + + " Check if the current line is a `when` and not the first in a switch block. + if curline =~ '\C^when\>' && !s:SearchCode(prevnlnum, '\C\') + " Look back for a `when`. + while prevnlnum + if getline(prevnlnum) =~ '\C^\s*when\>' + " Indent to match the found `when`, but don't force indenting (for when + " indenting nested switch blocks.) + return min([indent(a:curlnum), indent(prevnlnum)]) + endif + + let prevnlnum = s:GetPrevNormalLine(prevnlnum) + endwhile + + " No matching `when` found (bad syntax), so bail. + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + + " If the previous line is a comment, use its indentation, but don't force + " indenting. + if prevlnum != prevnlnum + return min([indent(a:curlnum), indent(prevlnum)]) + endif + + let prevline = s:GetTrimmedLine(prevnlnum) + + " Always indent after these operators. + if prevline =~ s:BEGIN_BLOCK_OP + return indent(prevnlnum) + s:ShiftWidth() + endif + + " Indent if the previous line starts a function block, but don't force + " indenting if the line is non-blank (for empty function bodies.) + if prevline =~ s:FUNCTION + if strlen(getline(a:curlnum)) > indent(a:curlnum) + return min([indent(prevnlnum) + s:ShiftWidth(), indent(a:curlnum)]) + else + return indent(prevnlnum) + s:ShiftWidth() + endif + endif + + " Check if continuation indenting is needed. If the line ends in a slash, make + " sure it isn't a regex. + if prevline =~ s:CONTINUATION_OP && + \ !(prevline =~ '/$' && s:IsString(prevnlnum, col([prevnlnum, '$']) - 1)) + " Don't indent if the continuation follows a closing bracket. + if prevline =~ s:BRACKET_CONTINUATION + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + + let prevprevnlnum = s:GetPrevNormalLine(prevnlnum) + + " Don't indent if not the first continuation. + if prevprevnlnum && s:GetTrimmedLine(prevprevnlnum) =~ s:CONTINUATION + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + + " Continuation indenting seems to vary between programmers, so if the line + " is non-blank, don't override the indentation + if strlen(getline(a:curlnum)) > indent(a:curlnum) + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + + " Otherwise indent a level. + return indent(prevnlnum) + s:ShiftWidth() + endif + + " Check if the previous line starts with a keyword that begins a block. + if prevline =~ s:BEGIN_BLOCK + " Indent if the current line doesn't start with `then` and the previous line + " isn't a single-line statement. + if curline !~ '\C^\' && !s:SearchCode(prevnlnum, '\C\') && + \ prevline !~ s:SINGLE_LINE_ELSE + return indent(prevnlnum) + s:ShiftWidth() + else + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + endif + + " Indent a dot access if it's the first. + if curline =~ s:DOT_ACCESS + if prevline !~ s:DOT_ACCESS + return indent(prevnlnum) + s:ShiftWidth() + else + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + endif + + " Outdent if a keyword breaks out of a block as long as it doesn't have a + " postfix condition (and the postfix condition isn't a single-line statement.) + if prevline =~ s:BREAK_BLOCK_OP + if !s:SearchCode(prevnlnum, s:POSTFIX_CONDITION) || + \ s:SearchCode(prevnlnum, '\C\') && + \ !s:SearchCode(prevnlnum, s:CONTAINED_THEN) + " Don't force indenting. + return min([indent(a:curlnum), indent(prevnlnum) - s:ShiftWidth()]) + else + exec 'return' s:GetDefaultPolicy(a:curlnum) + endif + endif + + " Check if inside brackets. + let matchlnum = s:SearchPair(a:curlnum, a:curlnum - s:MAX_LOOKBACK, + \ "s:IsCommentOrString(line('.'), col('.'))", + \ '\[\|(\|{', '\]\|)\|}') + + " If inside brackets, indent relative to the brackets, but don't outdent an + " already indented line. + if matchlnum + return max([indent(a:curlnum), indent(matchlnum) + s:ShiftWidth()]) + endif + + " No special rules applied, so use the default policy. + exec 'return' s:GetDefaultPolicy(a:curlnum) +endfunction diff --git a/.vim/indent/terraform.vim b/.vim/indent/terraform.vim new file mode 100644 index 0000000..fe3f769 --- /dev/null +++ b/.vim/indent/terraform.vim @@ -0,0 +1,44 @@ +if exists("b:did_indent") + finish +endif + +let b:did_indent = 1 + +setlocal nolisp +setlocal autoindent +setlocal indentexpr=TerraformIndent(v:lnum) +setlocal indentkeys+=<:>,0=},0=) + +if exists("*TerraformIndent") + finish +endif + +function! TerraformIndent(lnum) + " previous non-blank line + let prevlnum = prevnonblank(a:lnum-1) + + " beginning of file? + if prevlnum == 0 + return 0 + endif + + " previous line without comments + let prevline = substitute(getline(prevlnum), '//.*$', '', '') + let previndent = indent(prevlnum) + let thisindent = previndent + + " block open? + if prevline =~ '[\[{]\s*$' + let thisindent += &sw + endif + + " current line without comments + let thisline = substitute(getline(a:lnum), '//.*$', '', '') + + " block close? + if thisline =~ '^\s*[\]}]' + let thisindent -= &sw + endif + + return thisindent +endfunction diff --git a/.vim/syntax/ansible.vim b/.vim/syntax/ansible.vim new file mode 100644 index 0000000..af6ee20 --- /dev/null +++ b/.vim/syntax/ansible.vim @@ -0,0 +1,92 @@ +" Vim syntax file +" Language: Ansible YAML/Jinja templates +" Maintainer: Dave Honneffer +" Last Change: 2015.09.06 + +if exists("b:current_syntax") + finish +endif + +if !exists("main_syntax") + let main_syntax = 'yaml' +endif + +let b:current_syntax = '' +unlet b:current_syntax +runtime! syntax/yaml.vim + +let b:current_syntax = '' +unlet b:current_syntax +syntax include @Yaml syntax/yaml.vim + +let b:current_syntax = '' +unlet b:current_syntax +syntax include @Jinja syntax/jinja2.vim + +" Jinja +" ================================ + +syn cluster jinjaSLSBlocks add=jinjaTagBlock,jinjaVarBlock,jinjaComment +" https://github.com/mitsuhiko/jinja2/blob/6b7c0c23/ext/Vim/jinja.vim +syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment,@jinjaSLSBlocks +syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment,@jinjaSLSBlocks +syn region jinjaComment matchgroup=jinjaCommentDelim start="{#" end="#}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,@jinjaSLSBlocks +highlight link jinjaVariable Constant +highlight link jinjaVarDelim Delimiter + +" YAML +" ================================ + +" Reset some YAML to plain styling +" the number 80 in Ansible isn't any more important than the word root +highlight link yamlInteger NONE +highlight link yamlBool NONE +highlight link yamlFlowString NONE +" but it does make sense we visualize quotes easily +highlight link yamlFlowStringDelimiter Delimiter + +fun! s:attribute_highlight(attributes) + if a:attributes =~ 'a' + syn match ansible_attributes "\v\w+\=" containedin=yamlPlainScalar + else + syn match ansible_attributes "\v^\s*\w+\=" containedin=yamlPlainScalar + endif + if a:attributes =~ 'n' + highlight link ansible_attributes NONE + elseif a:attributes =~ 'd' + highlight link ansible_attributes Comment + else + highlight link ansible_attributes Structure + endif +endfun + +if exists("g:ansible_attribute_highlight") + call s:attribute_highlight(g:ansible_attribute_highlight) +else + call s:attribute_highlight('ad') +endif + +if exists("g:ansible_name_highlight") + syn keyword ansible_name name containedin=yamlBlockMappingKey contained + if g:ansible_name_highlight =~ 'd' + highlight link ansible_name Comment + else + highlight link ansible_name Underlined + endif +endif + +syn keyword ansible_debug_keywords debug containedin=yamlBlockMappingKey contained +highlight link ansible_debug_keywords Debug + +if exists("g:ansible_extra_keywords_highlight") + syn keyword ansible_extra_special_keywords register always_run changed_when failed_when no_log args vars delegate_to ignore_errors containedin=yamlBlockMappingKey contained + highlight link ansible_extra_special_keywords Statement +endif + +syn keyword ansible_special_keywords include until retries delay when only_if become become_user block rescue always notify containedin=yamlBlockMappingKey contained +highlight link ansible_special_keywords Statement + +syn match ansible_with_keywords "\vwith_.+" containedin=yamlBlockMappingKey contained +highlight link ansible_with_keywords Statement + +let b:current_syntax = "ansible" diff --git a/.vim/syntax/ansible_hosts.vim b/.vim/syntax/ansible_hosts.vim new file mode 100644 index 0000000..5ecc4da --- /dev/null +++ b/.vim/syntax/ansible_hosts.vim @@ -0,0 +1,31 @@ +" Vim syntax file +" Language: Ansible hosts files +" Maintainer: Dave Honneffer +" Last Change: 2015.09.23 + +if exists("b:current_syntax") + finish +endif + +syn case ignore +syn match hostsFirstWord "\v^\S+" +syn match hostsAttributes "\v\S*\=" +syn region hostsHeader start="\v^\s*\[" end="\v\]" +syn keyword hostsHeaderSpecials children vars containedin=hostsHeader contained +syn match hostsComment "\v^[#;].*$" + +highlight link hostsFirstWord Label +highlight link hostsHeader Define +highlight link hostsComment Comment +highlight link hostsHeaderSpecials Identifier +highlight link hostsAttributes Structure + +if exists("g:ansible_attribute_highlight") + if g:ansible_attribute_highlight =~ 'n' + highlight link hostsAttributes NONE + elseif g:ansible_attribute_highlight =~ 'd' + highlight link hostsAttributes Comment + endif +endif + +let b:current_syntax = "ansible_hosts" diff --git a/.vim/syntax/ansible_template.vim b/.vim/syntax/ansible_template.vim new file mode 100644 index 0000000..ae0c8ce --- /dev/null +++ b/.vim/syntax/ansible_template.vim @@ -0,0 +1,27 @@ +" Vim syntax file +" Language: Ansible YAML/Jinja templates +" Maintainer: Dave Honneffer +" Last Change: 2015.09.06 + +if exists("b:current_syntax") + finish +endif + +if !exists("main_syntax") + let main_syntax = 'jinja2' +endif + +let b:current_syntax = '' +unlet b:current_syntax +runtime! syntax/jinja2.vim + +if exists("g:ansible_extra_syntaxes") + let s:extra_syntax = split(g:ansible_extra_syntaxes) + for syntax_name in s:extra_syntax + let b:current_syntax = '' + unlet b:current_syntax + execute 'runtime!' "syntax/" . syntax_name + endfor +endif + +let b:current_syntax = "ansible_template" diff --git a/.vim/syntax/coffee.vim b/.vim/syntax/coffee.vim new file mode 100644 index 0000000..7f8df73 --- /dev/null +++ b/.vim/syntax/coffee.vim @@ -0,0 +1,221 @@ +" Language: CoffeeScript +" Maintainer: Mick Koch +" URL: http://github.com/kchmck/vim-coffee-script +" License: WTFPL + +" Bail if our syntax is already loaded. +if exists('b:current_syntax') && b:current_syntax == 'coffee' + finish +endif + +" Include JavaScript for coffeeEmbed. +syn include @coffeeJS syntax/javascript.vim +silent! unlet b:current_syntax + +" Highlight long strings. +syntax sync fromstart + +" These are `matches` instead of `keywords` because vim's highlighting +" priority for keywords is higher than matches. This causes keywords to be +" highlighted inside matches, even if a match says it shouldn't contain them -- +" like with coffeeAssign and coffeeDot. +syn match coffeeStatement /\<\%(return\|break\|continue\|throw\)\>/ display +hi def link coffeeStatement Statement + +syn match coffeeRepeat /\<\%(for\|while\|until\|loop\)\>/ display +hi def link coffeeRepeat Repeat + +syn match coffeeConditional /\<\%(if\|else\|unless\|switch\|when\|then\)\>/ +\ display +hi def link coffeeConditional Conditional + +syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display +hi def link coffeeException Exception + +syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\)\>/ +\ display +" The `own` keyword is only a keyword after `for`. +syn match coffeeKeyword /\/ contained containedin=coffeeRepeat +\ display +hi def link coffeeKeyword Keyword + +syn match coffeeOperator /\<\%(instanceof\|typeof\|delete\)\>/ display +hi def link coffeeOperator Operator + +" The first case matches symbol operators only if they have an operand before. +syn match coffeeExtendedOp /\%(\S\s*\)\@<=[+\-*/%&|\^=!<>?.]\{-1,}\|[-=]>\|--\|++\|:/ +\ display +syn match coffeeExtendedOp /\<\%(and\|or\)=/ display +hi def link coffeeExtendedOp coffeeOperator + +" This is separate from `coffeeExtendedOp` to help differentiate commas from +" dots. +syn match coffeeSpecialOp /[,;]/ display +hi def link coffeeSpecialOp SpecialChar + +syn match coffeeBoolean /\<\%(true\|on\|yes\|false\|off\|no\)\>/ display +hi def link coffeeBoolean Boolean + +syn match coffeeGlobal /\<\%(null\|undefined\)\>/ display +hi def link coffeeGlobal Type + +" A special variable +syn match coffeeSpecialVar /\<\%(this\|prototype\|arguments\)\>/ display +hi def link coffeeSpecialVar Special + +" An @-variable +syn match coffeeSpecialIdent /@\%(\%(\I\|\$\)\%(\i\|\$\)*\)\?/ display +hi def link coffeeSpecialIdent Identifier + +" A class-like name that starts with a capital letter +syn match coffeeObject /\<\u\w*\>/ display +hi def link coffeeObject Structure + +" A constant-like name in SCREAMING_CAPS +syn match coffeeConstant /\<\u[A-Z0-9_]\+\>/ display +hi def link coffeeConstant Constant + +" A variable name +syn cluster coffeeIdentifier contains=coffeeSpecialVar,coffeeSpecialIdent, +\ coffeeObject,coffeeConstant + +" A non-interpolated string +syn cluster coffeeBasicString contains=@Spell,coffeeEscape +" An interpolated string +syn cluster coffeeInterpString contains=@coffeeBasicString,coffeeInterp + +" Regular strings +syn region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/ +\ contains=@coffeeInterpString +syn region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/ +\ contains=@coffeeBasicString +hi def link coffeeString String + +" A integer, including a leading plus or minus +syn match coffeeNumber /\%(\i\|\$\)\@/ display +syn match coffeeNumber /\<0[bB][01]\+\>/ display +syn match coffeeNumber /\<0[oO][0-7]\+\>/ display +syn match coffeeNumber /\<\%(Infinity\|NaN\)\>/ display +hi def link coffeeNumber Number + +" A floating-point number, including a leading plus or minus +syn match coffeeFloat /\%(\i\|\$\)\@/ +\ display +hi def link coffeeReservedError Error + +" A normal object assignment +syn match coffeeObjAssign /@\?\%(\I\|\$\)\%(\i\|\$\)*\s*\ze::\@!/ contains=@coffeeIdentifier display +hi def link coffeeObjAssign Identifier + +syn keyword coffeeTodo TODO FIXME XXX contained +hi def link coffeeTodo Todo + +syn match coffeeComment /#.*/ contains=@Spell,coffeeTodo +hi def link coffeeComment Comment + +syn region coffeeBlockComment start=/####\@!/ end=/###/ +\ contains=@Spell,coffeeTodo +hi def link coffeeBlockComment coffeeComment + +" A comment in a heregex +syn region coffeeHeregexComment start=/#/ end=/\ze\/\/\/\|$/ contained +\ contains=@Spell,coffeeTodo +hi def link coffeeHeregexComment coffeeComment + +" Embedded JavaScript +syn region coffeeEmbed matchgroup=coffeeEmbedDelim +\ start=/`/ skip=/\\\\\|\\`/ end=/`/ keepend +\ contains=@coffeeJS +hi def link coffeeEmbedDelim Delimiter + +syn region coffeeInterp matchgroup=coffeeInterpDelim start=/#{/ end=/}/ contained +\ contains=@coffeeAll +hi def link coffeeInterpDelim PreProc + +" A string escape sequence +syn match coffeeEscape /\\\d\d\d\|\\x\x\{2\}\|\\u\x\{4\}\|\\./ contained display +hi def link coffeeEscape SpecialChar + +" A regex -- must not follow a parenthesis, number, or identifier, and must not +" be followed by a number +syn region coffeeRegex start=#\%(\%()\|\%(\i\|\$\)\@ +" Last Change: 2008 May 9 +" Version: 1.1 +" +" Known Bugs: +" because of odd limitations dicts and the modulo operator +" appear wrong in the template. +" +" Changes: +" +" 2008 May 9: Added support for Jinja2 changes (new keyword rules) + +" .vimrc variable to disable html highlighting +if !exists('g:jinja_syntax_html') + let g:jinja_syntax_html=1 +endif + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if !exists("main_syntax") + if version < 600 + syntax clear + elseif exists("b:current_syntax") + finish +endif + let main_syntax = 'jinja' +endif + +" Pull in the HTML syntax. +if g:jinja_syntax_html + if version < 600 + so :p:h/html.vim + else + runtime! syntax/html.vim + unlet b:current_syntax + endif +endif + +syntax case match + +" Jinja template built-in tags and parameters (without filter, macro, is and raw, they +" have special threatment) +syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained and if else in not or recursive as import + +syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained is filter skipwhite nextgroup=jinjaFilter +syn keyword jinjaStatement containedin=jinjaTagBlock contained macro skipwhite nextgroup=jinjaFunction +syn keyword jinjaStatement containedin=jinjaTagBlock contained block skipwhite nextgroup=jinjaBlockName + +" Variable Names +syn match jinjaVariable containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[a-zA-Z_][a-zA-Z0-9_]*/ +syn keyword jinjaSpecial containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained false true none False True None loop super caller varargs kwargs + +" Filters +syn match jinjaOperator "|" containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained skipwhite nextgroup=jinjaFilter +syn match jinjaFilter contained /[a-zA-Z_][a-zA-Z0-9_]*/ +syn match jinjaFunction contained /[a-zA-Z_][a-zA-Z0-9_]*/ +syn match jinjaBlockName contained /[a-zA-Z_][a-zA-Z0-9_]*/ + +" Jinja template constants +syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/"/ skip=/\(\\\)\@\)*\\"/ end=/"/ +syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/'/ skip=/\(\\\)\@\)*\\'/ end=/'/ +syn match jinjaNumber containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[0-9]\+\(\.[0-9]\+\)\?/ + +" Operators +syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[+\-*\/<>=!,:]/ +syn match jinjaPunctuation containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[()\[\]]/ +syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /\./ nextgroup=jinjaAttribute +syn match jinjaAttribute contained /[a-zA-Z_][a-zA-Z0-9_]*/ + +" Jinja template tag and variable blocks +syn region jinjaNested matchgroup=jinjaOperator start="(" end=")" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaNested matchgroup=jinjaOperator start="\[" end="\]" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaNested matchgroup=jinjaOperator start="{" end="}" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment + +syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment + +" Jinja template 'raw' tag +syn region jinjaRaw matchgroup=jinjaRawDelim start="{%\s*raw\s*%}" end="{%\s*endraw\s*%}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,jinjaComment + +" Jinja comments +syn region jinjaComment matchgroup=jinjaCommentDelim start="{#" end="#}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString + +" Block start keywords. A bit tricker. We only highlight at the start of a +" tag block and only if the name is not followed by a comma or equals sign +" which usually means that we have to deal with an assignment. +syn match jinjaStatement containedin=jinjaTagBlock contained /\({%-\?\s*\)\@<=\<[a-zA-Z_][a-zA-Z0-9_]*\>\(\s*[,=]\)\@!/ + +" and context modifiers +syn match jinjaStatement containedin=jinjaTagBlock contained /\/ + + +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_jinja_syn_inits") + if version < 508 + let did_jinja_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink jinjaPunctuation jinjaOperator + HiLink jinjaAttribute jinjaVariable + HiLink jinjaFunction jinjaFilter + + HiLink jinjaTagDelim jinjaTagBlock + HiLink jinjaVarDelim jinjaVarBlock + HiLink jinjaCommentDelim jinjaComment + HiLink jinjaRawDelim jinja + + HiLink jinjaSpecial Special + HiLink jinjaOperator Normal + HiLink jinjaRaw Normal + HiLink jinjaTagBlock PreProc + HiLink jinjaVarBlock PreProc + HiLink jinjaStatement Statement + HiLink jinjaFilter Function + HiLink jinjaBlockName Function + HiLink jinjaVariable Identifier + HiLink jinjaString Constant + HiLink jinjaNumber Constant + HiLink jinjaComment Comment + + delcommand HiLink +endif + +let b:current_syntax = "jinja" + +if main_syntax == 'jinja' + unlet main_syntax +endif diff --git a/.vim/syntax/syslog.vim b/.vim/syntax/syslog.vim new file mode 100644 index 0000000..c22e4e8 --- /dev/null +++ b/.vim/syntax/syslog.vim @@ -0,0 +1,73 @@ +" Vim syntax file +" Language: /var/log/messages file +" Maintainer: Yakov Lerner +" Latest Revision: 2008-06-29 +" Changes: 2008-06-29 support for RFC3339 tuimestamps James Vega +" 2016 Jan 19: messagesDate changed by Bram + +if exists("b:current_syntax") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +syn match messagesBegin display '^' nextgroup=messagesDate,messagesDateRFC3339 + +syn match messagesDate contained display '[[:lower:][:upper:]][[:lower:][:upper:]][[:lower:][:upper:]] [ 0-9]\d *' + \ nextgroup=messagesHour + +syn match messagesHour contained display '\d\d:\d\d:\d\d\s*' + \ nextgroup=messagesHost + +syn match messagesDateRFC3339 contained display '\d\{4}-\d\d-\d\d' + \ nextgroup=messagesRFC3339T + +syn match messagesRFC3339T contained display '\cT' + \ nextgroup=messagesHourRFC3339 + +syn match messagesHourRFC3339 contained display '\c\d\d:\d\d:\d\d\(\.\d\+\)\=\([+-]\d\d:\d\d\|Z\)' + \ nextgroup=messagesHost + +syn match messagesHost contained display '\S*\s*' + \ nextgroup=messagesLabel + +syn match messagesLabel contained display '\s*[^:]*:\s*' + \ nextgroup=messagesText contains=messagesKernel,messagesPID + +syn match messagesPID contained display '\[\zs\d\+\ze\]' + +syn match messagesKernel contained display 'kernel:' + + +syn match messagesIP '\d\+\.\d\+\.\d\+\.\d\+' + +syn match messagesURL '\w\+://\S\+' + +syn match messagesText contained display '.*' + \ contains=messagesNumber,messagesIP,messagesURL,messagesError + +syn match messagesNumber contained '0x[0-9a-fA-F]*\|\[<[0-9a-f]\+>\]\|\<\d[0-9a-fA-F]*' + +syn match messagesError contained '\c.*\<\(FATAL\|ERROR\|ERRORS\|FAILED\|FAILURE\).*' + + +hi def link messagesDate Constant +hi def link messagesHour Type +hi def link messagesDateRFC3339 Constant +hi def link messagesHourRFC3339 Type +hi def link messagesRFC3339T Normal +hi def link messagesHost Identifier +hi def link messagesLabel Operator +hi def link messagesPID Constant +hi def link messagesKernel Special +hi def link messagesError ErrorMsg +hi def link messagesIP Constant +hi def link messagesURL Underlined +hi def link messagesText Normal +hi def link messagesNumber Number + +let b:current_syntax = "messages" + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/.vim/syntax/terraform.vim b/.vim/syntax/terraform.vim new file mode 100644 index 0000000..f7df240 --- /dev/null +++ b/.vim/syntax/terraform.vim @@ -0,0 +1,606 @@ +" Forked from Larry Gilbert's syntax file +" github.com/L2G/vim-syntax-terraform + +if exists("b:current_syntax") + finish +endif + +syn case match + +syn keyword terraSection connection output provider variable +syn keyword terraValueBool true false on off yes no + +""" data +syn keyword terraDataTypeBI + \ archive_file + \ atlas_artifact + \ aws_acm_certificate + \ aws_ami + \ aws_availability_zone + \ aws_availability_zones + \ aws_billing_service_account + \ aws_caller_identity + \ aws_cloudformation_stack + \ aws_ebs_volume + \ aws_ecs_container_definition + \ aws_elb_service_account + \ aws_iam_policy_document + \ aws_ip_ranges + \ aws_prefix_list + \ aws_redshift_service_account + \ aws_region + \ aws_s3_bucket_object + \ aws_security_group + \ aws_subnet + \ aws_vpc + \ azurerm_client_config + \ consul_keys + \ docker_registry_image + \ fastly_ip_ranges + \ google_iam_policy + \ null_data_source + \ pagerduty_vendor + \ scaleway_bootscript + \ scaleway_image + \ template_cloudinit_config + \ template_file + \ terraform_remote_state +""" end data sources + +""" resource +syn keyword terraResourceTypeBI + \ atlas_artifact + \ aws_alb + \ aws_alb_listener + \ aws_alb_listener_rule + \ aws_alb_target_group + \ aws_alb_target_group_attachment + \ aws_ami + \ aws_ami_copy + \ aws_ami_from_instance + \ aws_ami_launch_permission + \ aws_api_gateway_account + \ aws_api_gateway_api_key + \ aws_api_gateway_authorizer + \ aws_api_gateway_base_path_mapping + \ aws_api_gateway_client_certificate + \ aws_api_gateway_deployment + \ aws_api_gateway_domain_name + \ aws_api_gateway_integration + \ aws_api_gateway_integration_response + \ aws_api_gateway_method + \ aws_api_gateway_method_response + \ aws_api_gateway_model + \ aws_api_gateway_resource + \ aws_api_gateway_rest_api + \ aws_app_cookie_stickiness_policy + \ aws_appautoscaling_policy + \ aws_appautoscaling_target + \ aws_autoscaling_attachment + \ aws_autoscaling_group + \ aws_autoscaling_lifecycle_hook + \ aws_autoscaling_notification + \ aws_autoscaling_policy + \ aws_autoscaling_schedule + \ aws_cloudformation_stack + \ aws_cloudfront_distribution + \ aws_cloudfront_origin_access_identity + \ aws_cloudtrail + \ aws_cloudwatch_event_rule + \ aws_cloudwatch_event_target + \ aws_cloudwatch_log_group + \ aws_cloudwatch_log_metric_filter + \ aws_cloudwatch_log_stream + \ aws_cloudwatch_log_subscription_filter + \ aws_cloudwatch_metric_alarm + \ aws_codecommit_repository + \ aws_codecommit_trigger + \ aws_codedeploy_app + \ aws_codedeploy_deployment_group + \ aws_customer_gateway + \ aws_db_event_subscription + \ aws_db_instance + \ aws_db_option_group + \ aws_db_parameter_group + \ aws_db_security_group + \ aws_db_subnet_group + \ aws_default_network_acl + \ aws_default_route_table + \ aws_default_security_group + \ aws_directory_service_directory + \ aws_dynamodb_table + \ aws_ebs_volume + \ aws_ecr_repository + \ aws_ecr_repository_policy + \ aws_ecs_cluster + \ aws_ecs_service + \ aws_ecs_task_definition + \ aws_efs_file_system + \ aws_efs_mount_target + \ aws_eip + \ aws_eip_association + \ aws_elastic_beanstalk_application + \ aws_elastic_beanstalk_configuration_template + \ aws_elastic_beanstalk_environment + \ aws_elasticache_cluster + \ aws_elasticache_parameter_group + \ aws_elasticache_replication_group + \ aws_elasticache_security_group + \ aws_elasticache_subnet_group + \ aws_elasticsearch_domain + \ aws_elastictranscoder_pipeline + \ aws_elastictranscoder_preset + \ aws_elb + \ aws_elb_attachment + \ aws_emr_cluster + \ aws_emr_instance_group + \ aws_flow_log + \ aws_glacier_vault + \ aws_iam_access_key + \ aws_iam_account_password_policy + \ aws_iam_group + \ aws_iam_group_membership + \ aws_iam_group_policy + \ aws_iam_group_policy_attachment + \ aws_iam_instance_profile + \ aws_iam_policy + \ aws_iam_policy_attachment + \ aws_iam_role + \ aws_iam_role_policy + \ aws_iam_role_policy_attachment + \ aws_iam_saml_provider + \ aws_iam_server_certificate + \ aws_iam_user + \ aws_iam_user_login_profile + \ aws_iam_user_policy + \ aws_iam_user_policy_attachment + \ aws_iam_user_ssh_key + \ aws_instance + \ aws_internet_gateway + \ aws_key_pair + \ aws_kinesis_firehose_delivery_stream + \ aws_kinesis_stream + \ aws_kms_alias + \ aws_kms_key + \ aws_lambda_alias + \ aws_lambda_event_source_mapping + \ aws_lambda_function + \ aws_lambda_permission + \ aws_launch_configuration + \ aws_lb_cookie_stickiness_policy + \ aws_lb_ssl_negotiation_policy + \ aws_load_balancer_backend_server_policy + \ aws_load_balancer_listener_policy + \ aws_load_balancer_policy + \ aws_main_route_table_association + \ aws_nat_gateway + \ aws_network_acl + \ aws_network_acl_rule + \ aws_network_interface + \ aws_opsworks_application + \ aws_opsworks_custom_layer + \ aws_opsworks_ganglia_layer + \ aws_opsworks_haproxy_layer + \ aws_opsworks_instance + \ aws_opsworks_java_app_layer + \ aws_opsworks_memcached_layer + \ aws_opsworks_mysql_layer + \ aws_opsworks_nodejs_app_layer + \ aws_opsworks_permission + \ aws_opsworks_php_app_layer + \ aws_opsworks_rails_app_layer + \ aws_opsworks_stack + \ aws_opsworks_static_web_layer + \ aws_opsworks_user_profile + \ aws_placement_group + \ aws_proxy_protocol_policy + \ aws_rds_cluster + \ aws_rds_cluster_instance + \ aws_rds_cluster_parameter_group + \ aws_redshift_cluster + \ aws_redshift_parameter_group + \ aws_redshift_security_group + \ aws_redshift_subnet_group + \ aws_route + \ aws_route53_delegation_set + \ aws_route53_health_check + \ aws_route53_record + \ aws_route53_zone + \ aws_route53_zone_association + \ aws_route_table + \ aws_route_table_association + \ aws_s3_bucket + \ aws_s3_bucket_notification + \ aws_s3_bucket_object + \ aws_s3_bucket_policy + \ aws_security_group + \ aws_security_group_rule + \ aws_ses_active_receipt_rule_set + \ aws_ses_receipt_filter + \ aws_ses_receipt_rule + \ aws_ses_receipt_rule_set + \ aws_simpledb_domain + \ aws_sns_topic + \ aws_sns_topic_policy + \ aws_sns_topic_subscription + \ aws_spot_datafeed_subscription + \ aws_spot_fleet_request + \ aws_spot_instance_request + \ aws_sqs_queue + \ aws_sqs_queue_policy + \ aws_ssm_activation + \ aws_ssm_association + \ aws_ssm_document + \ aws_subnet + \ aws_volume_attachment + \ aws_vpc + \ aws_vpc_dhcp_options + \ aws_vpc_dhcp_options_association + \ aws_vpc_endpoint + \ aws_vpc_peering_connection + \ aws_vpn_connection + \ aws_vpn_connection_route + \ aws_vpn_gateway + \ aws_vpn_gateway_attachment + \ aws_waf_byte_match_set + \ aws_waf_ipset + \ aws_waf_rule + \ aws_waf_size_constraint_set + \ aws_waf_sql_injection_match_set + \ aws_waf_web_acl + \ aws_waf_xss_match_set + \ azure_affinity_group + \ azure_data_disk + \ azure_dns_server + \ azure_hosted_service + \ azure_instance + \ azure_local_network_connection + \ azure_security_group + \ azure_security_group_rule + \ azure_sql_database_server + \ azure_sql_database_server_firewall_rule + \ azure_sql_database_service + \ azure_storage_blob + \ azure_storage_container + \ azure_storage_queue + \ azure_storage_service + \ azure_virtual_network + \ azurerm_availability_set + \ azurerm_cdn_endpoint + \ azurerm_cdn_profile + \ azurerm_dns_a_record + \ azurerm_dns_aaaa_record + \ azurerm_dns_cname_record + \ azurerm_dns_mx_record + \ azurerm_dns_ns_record + \ azurerm_dns_srv_record + \ azurerm_dns_txt_record + \ azurerm_dns_zone + \ azurerm_eventhub + \ azurerm_eventhub_namespace + \ azurerm_key_vault + \ azurerm_lb + \ azurerm_lb_backend_address_pool + \ azurerm_lb_nat_pool + \ azurerm_lb_nat_rule + \ azurerm_lb_probe + \ azurerm_lb_rule + \ azurerm_local_network_gateway + \ azurerm_network_interface + \ azurerm_network_security_group + \ azurerm_network_security_rule + \ azurerm_public_ip + \ azurerm_resource_group + \ azurerm_route + \ azurerm_route_table + \ azurerm_search_service + \ azurerm_servicebus_namespace + \ azurerm_servicebus_subscription + \ azurerm_servicebus_topic + \ azurerm_sql_database + \ azurerm_sql_firewall_rule + \ azurerm_sql_server + \ azurerm_storage_account + \ azurerm_storage_blob + \ azurerm_storage_container + \ azurerm_storage_queue + \ azurerm_storage_share + \ azurerm_storage_table + \ azurerm_subnet + \ azurerm_template_deployment + \ azurerm_traffic_manager_endpoint + \ azurerm_traffic_manager_profile + \ azurerm_virtual_machine + \ azurerm_virtual_machine_extension + \ azurerm_virtual_machine_scale_set + \ azurerm_virtual_network + \ azurerm_virtual_network_peering + \ bitbucket_default_reviewers + \ bitbucket_hook + \ bitbucket_repository + \ chef_acl + \ chef_client + \ chef_cookbook + \ chef_data_bag + \ chef_data_bag_item + \ chef_environment + \ chef_node + \ chef_role + \ clc_group + \ clc_load_balancer + \ clc_load_balancer_pool + \ clc_public_ip + \ clc_server + \ cloudflare_record + \ cloudstack_affinity_group + \ cloudstack_disk + \ cloudstack_egress_firewall + \ cloudstack_firewall + \ cloudstack_instance + \ cloudstack_ipaddress + \ cloudstack_loadbalancer_rule + \ cloudstack_network + \ cloudstack_network_acl + \ cloudstack_network_acl_rule + \ cloudstack_nic + \ cloudstack_port_forward + \ cloudstack_private_gateway + \ cloudstack_secondary_ipaddress + \ cloudstack_security_group + \ cloudstack_security_group_rule + \ cloudstack_ssh_keypair + \ cloudstack_static_nat + \ cloudstack_static_route + \ cloudstack_template + \ cloudstack_vpc + \ cloudstack_vpn_connection + \ cloudstack_vpn_customer_gateway + \ cloudstack_vpn_gateway + \ cobbler_distro + \ cobbler_kickstart_file + \ cobbler_profile + \ cobbler_snippet + \ cobbler_system + \ consul_agent_service + \ consul_catalog_entry + \ consul_key_prefix + \ consul_keys + \ consul_node + \ consul_prepared_query + \ consul_service + \ datadog_monitor + \ datadog_timeboard + \ digitalocean_domain + \ digitalocean_droplet + \ digitalocean_floating_ip + \ digitalocean_record + \ digitalocean_ssh_key + \ digitalocean_tag + \ digitalocean_volume + \ dme_record + \ dnsimple_record + \ docker_container + \ docker_image + \ docker_network + \ docker_volume + \ dyn_record + \ fastly_service_v1 + \ github_membership + \ github_repository + \ github_repository_collaborator + \ github_team + \ github_team_membership + \ github_team_repository + \ google_compute_address + \ google_compute_autoscaler + \ google_compute_backend_service + \ google_compute_disk + \ google_compute_firewall + \ google_compute_forwarding_rule + \ google_compute_global_address + \ google_compute_global_forwarding_rule + \ google_compute_http_health_check + \ google_compute_https_health_check + \ google_compute_image + \ google_compute_instance + \ google_compute_instance_group + \ google_compute_instance_group_manager + \ google_compute_instance_template + \ google_compute_network + \ google_compute_project_metadata + \ google_compute_route + \ google_compute_ssl_certificate + \ google_compute_subnetwork + \ google_compute_target_http_proxy + \ google_compute_target_https_proxy + \ google_compute_target_pool + \ google_compute_url_map + \ google_compute_vpn_gateway + \ google_compute_vpn_tunnel + \ google_container_cluster + \ google_dns_managed_zone + \ google_dns_record_set + \ google_project + \ google_pubsub_subscription + \ google_pubsub_topic + \ google_sql_database + \ google_sql_database_instance + \ google_sql_user + \ google_storage_bucket + \ google_storage_bucket_acl + \ google_storage_bucket_object + \ google_storage_object_acl + \ heroku_addon + \ heroku_app + \ heroku_cert + \ heroku_domain + \ heroku_drain + \ influxdb_continuous_query + \ influxdb_database + \ influxdb_user + \ librato_alert + \ librato_service + \ librato_space + \ librato_space_chart + \ logentries_log + \ logentries_logset + \ mailgun_domain + \ mysql_database + \ mysql_grant + \ mysql_user + \ null_resource + \ openstack_blockstorage_volume_v1 + \ openstack_blockstorage_volume_v2 + \ openstack_compute_floatingip_v2 + \ openstack_compute_instance_v2 + \ openstack_compute_keypair_v2 + \ openstack_compute_secgroup_v2 + \ openstack_compute_servergroup_v2 + \ openstack_fw_firewall_v1 + \ openstack_fw_policy_v1 + \ openstack_fw_rule_v1 + \ openstack_lb_listener_v2 + \ openstack_lb_loadbalancer_v2 + \ openstack_lb_member_v1 + \ openstack_lb_member_v2 + \ openstack_lb_monitor_v1 + \ openstack_lb_monitor_v2 + \ openstack_lb_pool_v1 + \ openstack_lb_pool_v2 + \ openstack_lb_vip_v1 + \ openstack_networking_floatingip_v2 + \ openstack_networking_network_v2 + \ openstack_networking_port_v2 + \ openstack_networking_router_interface_v2 + \ openstack_networking_router_route_v2 + \ openstack_networking_router_v2 + \ openstack_networking_secgroup_rule_v2 + \ openstack_networking_secgroup_v2 + \ openstack_networking_subnet_v2 + \ openstack_objectstorage_container_v1 + \ packet_device + \ packet_project + \ packet_ssh_key + \ packet_volume + \ pagerduty_escalation_policy + \ pagerduty_schedule + \ pagerduty_service + \ pagerduty_service_integration + \ pagerduty_team + \ pagerduty_user + \ postgresql_database + \ postgresql_extension + \ postgresql_role + \ powerdns_record + \ rabbitmq_binding + \ rabbitmq_exchange + \ rabbitmq_permissions + \ rabbitmq_policy + \ rabbitmq_queue + \ rabbitmq_user + \ rabbitmq_vhost + \ random_id + \ random_shuffle + \ rundeck_job + \ rundeck_private_key + \ rundeck_project + \ rundeck_public_key + \ scaleway_ip + \ scaleway_security_group + \ scaleway_security_group_rule + \ scaleway_server + \ scaleway_volume + \ scaleway_volume_attachment + \ softlayer_ssh_key + \ softlayer_virtual_guest + \ statuscake_test + \ tls_cert_request + \ tls_locally_signed_cert + \ tls_private_key + \ tls_self_signed_cert + \ triton_fabric + \ triton_firewall_rule + \ triton_key + \ triton_machine + \ triton_vlan + \ ultradns_record + \ vcd_dnat + \ vcd_firewall_rules + \ vcd_network + \ vcd_snat + \ vcd_vapp + \ vsphere_file + \ vsphere_folder + \ vsphere_virtual_disk + \ vsphere_virtual_machine +""" end resources + +syn keyword terraTodo contained TODO FIXME XXX BUG +syn cluster terraCommentGroup contains=terraTodo +syn region terraComment start="/\*" end="\*/" contains=@terraCommentGroup,@Spell +syn region terraComment start="#" end="$" contains=@terraCommentGroup,@Spell +syn region terraComment start="//" end="$" contains=@terraCommentGroup,@Spell + +syn match terraResource /\/ nextgroup=terraResourceTypeStr skipwhite +syn region terraResourceTypeStr start=/"/ end=/"/ contains=terraResourceTypeBI + \ nextgroup=terraResourceName skipwhite +syn region terraResourceName start=/"/ end=/"/ + \ nextgroup=terraResourceBlock skipwhite + +syn match terraData /\/ nextgroup=terraDataTypeStr skipwhite +syn region terraDataTypeStr start=/"/ end=/"/ contains=terraDataTypeBI + \ nextgroup=terraDataName skipwhite +syn region terraDataName start=/"/ end=/"/ + \ nextgroup=terraDataBlock skipwhite + +""" provider +syn match terraProvider /\/ nextgroup=terraProviderName skipwhite +syn region terraProviderName start=/"/ end=/"/ nextgroup=terraProviderBlock skipwhite + +""" provisioner +syn match terraProvisioner /\/ nextgroup=terraProvisionerName skipwhite +syn region terraProvisionerName start=/"/ end=/"/ nextgroup=terraProvisionerBlock skipwhite + +""" module +syn match terraModule /\/ nextgroup=terraModuleName skipwhite +syn region terraModuleName start=/"/ end=/"/ nextgroup=terraModuleBlock skipwhite + +""" misc. +syn match terraValueDec "\<[0-9]\+\([kKmMgG]b\?\)\?\>" +syn match terraValueHexaDec "\<0x[0-9a-f]\+\([kKmMgG]b\?\)\?\>" +syn match terraBraces "[{}\[\]]" + +""" skip \" in strings. +""" we may also want to pass \\" into a function to escape quotes. +syn region terraValueString start=/"/ skip=/\\\+"/ end=/"/ contains=terraStringInterp +syn region terraStringInterp matchgroup=terraBrackets start=/\${/ end=/}/ contains=terraValueFunction contained +"" TODO match keywords here, not a-z+ +syn region terraValueFunction matchgroup=terraBrackets start=/[a-z]\+(/ end=/)/ contains=terraValueString,terraValueFunction contained + +hi def link terraComment Comment +hi def link terraTodo Todo +hi def link terraBrackets Operator +hi def link terraProvider Structure +hi def link terraBraces Delimiter +hi def link terraProviderName String +hi def link terraResource Structure +hi def link terraResourceName String +hi def link terraResourceTypeBI Tag +hi def link terraResourceTypeStr String +hi def link terraData Structure +hi def link terraDataName String +hi def link terraDataTypeBI Tag +hi def link terraDataTypeStr String +hi def link terraSection Structure +hi def link terraStringInterp Identifier +hi def link terraValueBool Boolean +hi def link terraValueDec Number +hi def link terraValueHexaDec Number +hi def link terraValueString String +hi def link terraProvisioner Structure +hi def link terraProvisionerName String +hi def link terraModule Structure +hi def link terraModuleName String +hi def link terraValueFunction Identifier + +let b:current_syntax = "terraform" diff --git a/.vimrc b/.vimrc index 6c1fcd7..748131e 100644 --- a/.vimrc +++ b/.vimrc @@ -11,10 +11,32 @@ set term=xterm set background=dark set backupext=.bak set showmatch -syntax on +syntax enable set tabstop=4 +set softtabstop=4 set expandtab set shiftwidth=4 -set softtabstop=4 set background=dark +set showcmd filetype indent on + +set incsearch +set hlsearch + +" Show tabs and trailing whitespace +set lcs=tab:\|\ ,trail:ยท +set list +" Strip trailing whitespace (,ss) +function! StripWhitespace() + let save_cursor = getpos(".") + let old_query = getreg('/') + :%s/\s\+$//e + call setpos('.', save_cursor) + call setreg('/', old_query) +endfunction +noremap ss :call StripWhitespace() +" Save a file as root (,W) +" noremap W :w !sudo tee % > /dev/null + +"F5 to wipe out trailing whitespaces" +nnoremap :let _s=@/:%s/\s\+$//e:let @/=_s