diff --git a/setup.sh b/setup.sh index 905b2bf..1c9b791 100755 --- a/setup.sh +++ b/setup.sh @@ -74,10 +74,7 @@ if [ "$XDG_SESSION_DESKTOP" = "gnome" ]; then gsettings set org.gnome.desktop.interface color-scheme prefer-dark gsettings set org.gnome.desktop.interface cursor-blink false gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark - gsettings set org.gnome.desktop.interface font-name 'Cantarell 11' - gsettings set org.gnome.desktop.interface document-font-name 'Cantarell 11' gsettings set org.gnome.desktop.interface monospace-font-name 'Cascadia Mono 10' - gsettings set org.gnome.desktop.interface text-scaling-factor 0.9 gsettings set org.gnome.desktop.media-handling automount false gsettings set org.gnome.desktop.media-handling automount-open false gsettings set org.gnome.desktop.peripherals.touchpad disable-while-typing false diff --git a/ssh/config b/ssh/config index 01abb63..ac616f7 100644 --- a/ssh/config +++ b/ssh/config @@ -19,7 +19,8 @@ Host *.tmate.io Host * IdentitiesOnly yes Ciphers aes256-gcm@openssh.com - KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256@libssh.org + KexAlgorithms sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,mlkem768x25519-sha256,curve25519-sha256,curve25519-sha256@libssh.org HostKeyAlgorithms ssh-ed25519 + UseStrictKeyExchange 2 ForwardAgent no SendEnv COLORTERM diff --git a/vim/autoload/fish.vim b/vim/autoload/fish.vim new file mode 100644 index 0000000..2c4d894 --- /dev/null +++ b/vim/autoload/fish.vim @@ -0,0 +1,67 @@ +function! fish#Indent() + let l:shiftwidth = shiftwidth() + let l:prevlnum = prevnonblank(v:lnum - 1) + if l:prevlnum ==# 0 + return 0 + endif + let l:indent = 0 + let l:prevline = getline(l:prevlnum) + if l:prevline =~# '\v^\s*switch>' + let l:indent = l:shiftwidth * 2 + elseif l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case)>' + let l:indent = l:shiftwidth + endif + let l:line = getline(v:lnum) + if l:line =~# '\v^\s*end>' + return indent(v:lnum) - (l:indent ==# 0 ? l:shiftwidth : l:indent) + elseif l:line =~# '\v^\s*%(case|else)>' + return indent(v:lnum) - l:shiftwidth + endif + return indent(l:prevlnum) + l:indent +endfunction + +function! fish#Format() + if mode() =~# '\v^%(i|R)$' + return 1 + else + let l:command = v:lnum.','.(v:lnum+v:count-1).'!fish_indent' + echo l:command + execute l:command + endif +endfunction + +function! fish#Fold() + let l:line = getline(v:lnum) + if l:line =~# '\v^\s*%(begin|if|while|for|function|switch)>' + return 'a1' + elseif l:line =~# '\v^\s*end>' + return 's1' + else + return '=' + end +endfunction + +function! fish#Complete(findstart, base) + if a:findstart + return getline('.') =~# '\v^\s*$' ? -1 : 0 + else + if empty(a:base) + return [] + endif + let l:results = [] + let l:completions = + \ system('fish -c "complete -C'.shellescape(a:base).'"') + let l:cmd = substitute(a:base, '\v\S+$', '', '') + for l:line in split(l:completions, '\n') + let l:tokens = split(l:line, '\t') + call add(l:results, {'word': l:cmd.l:tokens[0], + \'abbr': l:tokens[0], + \'menu': get(l:tokens, 1, '')}) + endfor + return l:results + endif +endfunction + +function! fish#errorformat() + return '%Afish: %m,%-G%*\\ ^,%-Z%f (line %l):%s' +endfunction diff --git a/vim/autoload/go/complete.vim b/vim/autoload/go/complete.vim new file mode 100644 index 0000000..cc1013b --- /dev/null +++ b/vim/autoload/go/complete.vim @@ -0,0 +1,71 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" This file provides a utility function that performs auto-completion of +" package names, for use by other commands. + +let s:goos = $GOOS +let s:goarch = $GOARCH + +if len(s:goos) == 0 + if exists('g:golang_goos') + let s:goos = g:golang_goos + elseif has('win32') || has('win64') + let s:goos = 'windows' + elseif has('macunix') + let s:goos = 'darwin' + else + let s:goos = '*' + endif +endif + +if len(s:goarch) == 0 + if exists('g:golang_goarch') + let s:goarch = g:golang_goarch + else + let s:goarch = '*' + endif +endif + +function! go#complete#Package(ArgLead, CmdLine, CursorPos) + let dirs = [] + + if executable('go') + let goroot = substitute(system('go env GOROOT'), '\n', '', 'g') + if v:shell_error + echo '\'go env GOROOT\' failed' + endif + else + let goroot = $GOROOT + endif + + if len(goroot) != 0 && isdirectory(goroot) + let dirs += [ goroot ] + endif + + let workspaces = split($GOPATH, ':') + if workspaces != [] + let dirs += workspaces + endif + + if len(dirs) == 0 + " should not happen + return [] + endif + + let ret = {} + for dir in dirs + let root = expand(dir . '/pkg/' . s:goos . '_' . s:goarch) + for i in split(globpath(root, a:ArgLead.'*'), "\n") + if isdirectory(i) + let i .= '/' + elseif i !~ '\.a$' + continue + endif + let i = substitute(substitute(i[len(root)+1:], '[\\]', '/', 'g'), '\.a$', '', 'g') + let ret[i] = i + endfor + endfor + return sort(keys(ret)) +endfunction diff --git a/vim/ftdetect/coffee.vim b/vim/ftdetect/coffee.vim new file mode 100644 index 0000000..25daf12 --- /dev/null +++ b/vim/ftdetect/coffee.vim @@ -0,0 +1,8 @@ +" 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 set filetype=coffee diff --git a/vim/ftdetect/fish.vim b/vim/ftdetect/fish.vim new file mode 100644 index 0000000..cbb7d0d --- /dev/null +++ b/vim/ftdetect/fish.vim @@ -0,0 +1,23 @@ +autocmd BufRead,BufNewFile *.fish setfiletype fish + +" Detect fish scripts by the shebang line. +autocmd BufRead * + \ if getline(1) =~# '\v^#!%(\f*/|/usr/bin/env\s*<)fish>' | + \ setlocal filetype=fish | + \ endif + +" Move cursor to first empty line when using funced. +autocmd BufRead fish_funced_*_*.fish call search('^$') + +" Fish histories are YAML documents. +autocmd BufRead,BufNewFile ~/.config/fish/fish_{read_,}history setfiletype yaml + +" Universal variable storages should not be hand edited. +autocmd BufRead,BufNewFile ~/.config/fish/fishd.* setlocal readonly + +" Mimic `funced` when manually creating functions. +autocmd BufNewFile ~/.config/fish/functions/*.fish + \ call append(0, ['function '.expand('%:t:r'), + \'', + \'end']) | + \ 2 diff --git a/vim/ftdetect/gofiletype.vim b/vim/ftdetect/gofiletype.vim new file mode 100644 index 0000000..b658f6b --- /dev/null +++ b/vim/ftdetect/gofiletype.vim @@ -0,0 +1,23 @@ +" We take care to preserve the user's fileencodings and fileformats, +" because those settings are global (not buffer local), yet we want +" to override them for loading Go files, which are defined to be UTF-8. +let s:current_fileformats = '' +let s:current_fileencodings = '' + +" define fileencodings to open as utf-8 encoding even if it's ascii. +function! s:gofiletype_pre() + let s:current_fileformats = &g:fileformats + let s:current_fileencodings = &g:fileencodings + set fileencodings=utf-8 fileformats=unix + setlocal filetype=go +endfunction + +" restore fileencodings as others +function! s:gofiletype_post() + let &g:fileformats = s:current_fileformats + let &g:fileencodings = s:current_fileencodings +endfunction + +au BufNewFile *.go setlocal filetype=go fileencoding=utf-8 fileformat=unix +au BufRead *.go call s:gofiletype_pre() +au BufReadPost *.go call s:gofiletype_post() diff --git a/vim/ftdetect/swift.vim b/vim/ftdetect/swift.vim new file mode 100644 index 0000000..5be9bf3 --- /dev/null +++ b/vim/ftdetect/swift.vim @@ -0,0 +1,12 @@ +autocmd BufNewFile,BufRead *.swift set filetype=swift +autocmd BufRead * call s:Swift() +function! s:Swift() + if !empty(&filetype) + return + endif + + let line = getline(1) + if line =~ "^#!.*swift" + setfiletype swift + endif +endfunction diff --git a/vim/ftplugin/fish.vim b/vim/ftplugin/fish.vim new file mode 100644 index 0000000..85873eb --- /dev/null +++ b/vim/ftplugin/fish.vim @@ -0,0 +1,39 @@ +setlocal comments=:# +setlocal commentstring=#%s +setlocal define=\\v^\\s*function> +setlocal foldexpr=fish#Fold() +setlocal formatoptions+=ron1 +setlocal formatoptions-=t +setlocal include=\\v^\\s*\\.> +setlocal iskeyword=@,48-57,-,_,.,/ +setlocal suffixesadd^=.fish + +" Use the 'j' format option when available. +if v:version ># 703 || v:version ==# 703 && has('patch541') + setlocal formatoptions+=j +endif + +if executable('fish_indent') + setlocal formatexpr=fish#Format() +endif + +if executable('fish') + setlocal omnifunc=fish#Complete + for s:path in split(system("fish -c 'echo $fish_function_path'")) + execute 'setlocal path+='.s:path + endfor +else + setlocal omnifunc=syntaxcomplete#Complete +endif + +" Use the 'man' wrapper function in fish to include fish's man pages. +" Have to use a script for this; 'fish -c man' would make the the man page an +" argument to fish instead of man. +execute 'setlocal keywordprg=fish\ '.fnameescape(expand(':p:h:h').'/bin/man.fish') + +let b:match_words = + \ escape('<%(begin|function|if|switch|while|for)>:', '<>%|)') + +let b:endwise_addition = 'end' +let b:endwise_words = 'begin,function,if,switch,while,for' +let b:endwise_syngroups = 'fishKeyword,fishConditional,fishRepeat' diff --git a/vim/ftplugin/go/fmt.vim b/vim/ftplugin/go/fmt.vim new file mode 100644 index 0000000..0ee44cd --- /dev/null +++ b/vim/ftplugin/go/fmt.vim @@ -0,0 +1,44 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" fmt.vim: Vim command to format Go files with gofmt. +" +" This filetype plugin add a new commands for go buffers: +" +" :Fmt +" +" Filter the current Go buffer through gofmt. +" It tries to preserve cursor position and avoids +" replacing the buffer with stderr output. +" + +command! -buffer Fmt call s:GoFormat() + +function! s:GoFormat() + let view = winsaveview() + silent %!gofmt + if v:shell_error + let errors = [] + for line in getline(1, line('$')) + let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') + if !empty(tokens) + call add(errors, {"filename": @%, + \"lnum": tokens[2], + \"col": tokens[3], + \"text": tokens[4]}) + endif + endfor + if empty(errors) + % | " Couldn't detect gofmt error format, output errors + endif + undo + if !empty(errors) + call setloclist(0, errors, 'r') + endif + echohl Error | echomsg "Gofmt returned error" | echohl None + endif + call winrestview(view) +endfunction + +" vim:ts=4:sw=4:et diff --git a/vim/ftplugin/go/godoc.vim b/vim/ftplugin/go/godoc.vim new file mode 100644 index 0000000..55195a6 --- /dev/null +++ b/vim/ftplugin/go/godoc.vim @@ -0,0 +1,13 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" godoc.vim: Vim command to see godoc. + +if exists("b:did_ftplugin") + finish +endif + +silent! nmap K (godoc-keyword) + +" vim:ts=4:sw=4:et diff --git a/vim/ftplugin/go/import.vim b/vim/ftplugin/go/import.vim new file mode 100644 index 0000000..6ed5dd4 --- /dev/null +++ b/vim/ftplugin/go/import.vim @@ -0,0 +1,231 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" import.vim: Vim commands to import/drop Go packages. +" +" This filetype plugin adds three new commands for go buffers: +" +" :Import {path} +" +" Import ensures that the provided package {path} is imported +" in the current Go buffer, using proper style and ordering. +" If {path} is already being imported, an error will be +" displayed and the buffer will be untouched. +" +" :ImportAs {localname} {path} +" +" Same as Import, but uses a custom local name for the package. +" +" :Drop {path} +" +" Remove the import line for the provided package {path}, if +" present in the current Go buffer. If {path} is not being +" imported, an error will be displayed and the buffer will be +" untouched. +" +" In addition to these commands, there are also two shortcuts mapped: +" +" \f - Runs :Import fmt +" \F - Runs :Drop fmt +" +" The backslash is the default maplocalleader, so it is possible that +" your vim is set to use a different character (:help maplocalleader). +" +if exists("b:did_ftplugin") + finish +endif + +command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', ) +command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', ) +command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, ) +map f :Import fmt +map F :Drop fmt + +function! s:SwitchImport(enabled, localname, path) + let view = winsaveview() + let path = a:path + + " Quotes are not necessary, so remove them if provided. + if path[0] == '"' + let path = strpart(path, 1) + endif + if path[len(path)-1] == '"' + let path = strpart(path, 0, len(path) - 1) + endif + if path == '' + call s:Error('Import path not provided') + return + endif + + " Extract any site prefix (e.g. github.com/). + " If other imports with the same prefix are grouped separately, + " we will add this new import with them. + " Only up to and including the first slash is used. + let siteprefix = matchstr(path, "^[^/]*/") + + let qpath = '"' . path . '"' + if a:localname != '' + let qlocalpath = a:localname . ' ' . qpath + else + let qlocalpath = qpath + endif + let indentstr = 0 + let packageline = -1 " Position of package name statement + let appendline = -1 " Position to introduce new import + let deleteline = -1 " Position of line with existing import + let linesdelta = 0 " Lines added/removed + + " Find proper place to add/remove import. + let line = 0 + while line <= line('$') + let linestr = getline(line) + + if linestr =~# '^package\s' + let packageline = line + let appendline = line + + elseif linestr =~# '^import\s\+(' + let appendstr = qlocalpath + let indentstr = 1 + let appendline = line + let firstblank = -1 + let lastprefix = "" + while line <= line("$") + let line = line + 1 + let linestr = getline(line) + let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') + if empty(m) + if siteprefix == "" + " must be in the first group + break + endif + " record this position, but keep looking + if firstblank < 0 + let firstblank = line + endif + continue + endif + if m[1] == ')' + " if there's no match, add it to the first group + if appendline < 0 && firstblank >= 0 + let appendline = firstblank + endif + break + endif + let lastprefix = matchstr(m[4], "^[^/]*/") + if a:localname != '' && m[3] != '' + let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath) + endif + let appendstr = m[2] . qlocalpath + let indentstr = 0 + if m[4] == path + let appendline = -1 + let deleteline = line + break + elseif m[4] < path + " don't set candidate position if we have a site prefix, + " we've passed a blank line, and this doesn't share the same + " site prefix. + if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0 + let appendline = line + endif + elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0 + " first entry of site group + let appendline = line - 1 + break + endif + endwhile + break + + elseif linestr =~# '^import ' + if appendline == packageline + let appendstr = 'import ' . qlocalpath + let appendline = line - 1 + endif + let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"') + if !empty(m) + if m[3] == path + let appendline = -1 + let deleteline = line + break + endif + if m[3] < path + let appendline = line + endif + if a:localname != '' && m[2] != '' + let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath) + endif + let appendstr = 'import' . m[1] . qlocalpath + endif + + elseif linestr =~# '^\(var\|const\|type\|func\)\>' + break + + endif + let line = line + 1 + endwhile + + " Append or remove the package import, as requested. + if a:enabled + if deleteline != -1 + call s:Error(qpath . ' already being imported') + elseif appendline == -1 + call s:Error('No package line found') + else + if appendline == packageline + call append(appendline + 0, '') + call append(appendline + 1, 'import (') + call append(appendline + 2, ')') + let appendline += 2 + let linesdelta += 3 + let appendstr = qlocalpath + let indentstr = 1 + endif + call append(appendline, appendstr) + execute appendline + 1 + if indentstr + execute 'normal >>' + endif + let linesdelta += 1 + endif + else + if deleteline == -1 + call s:Error(qpath . ' not being imported') + else + execute deleteline . 'd' + let linesdelta -= 1 + + if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)' + " Delete empty import block + let deleteline -= 1 + execute deleteline . "d" + execute deleteline . "d" + let linesdelta -= 2 + endif + + if getline(deleteline) == '' && getline(deleteline - 1) == '' + " Delete spacing for removed line too. + execute deleteline . "d" + let linesdelta -= 1 + endif + endif + endif + + " Adjust view for any changes. + let view.lnum += linesdelta + let view.topline += linesdelta + if view.topline < 0 + let view.topline = 0 + endif + + " Put buffer back where it was. + call winrestview(view) + +endfunction + +function! s:Error(s) + echohl Error | echo a:s | echohl None +endfunction + +" vim:ts=4:sw=4:et diff --git a/vim/ftplugin/swift.vim b/vim/ftplugin/swift.vim new file mode 100644 index 0000000..0945a75 --- /dev/null +++ b/vim/ftplugin/swift.vim @@ -0,0 +1,4 @@ +setlocal commentstring=//\ %s +" @-@ adds the literal @ to iskeyword for @IBAction and similar +setlocal iskeyword+=@-@,# +setlocal completefunc=syntaxcomplete#Complete diff --git a/vim/indent/coffee.vim b/vim/indent/coffee.vim new file mode 100644 index 0000000..a798cfc --- /dev/null +++ b/vim/indent/coffee.vim @@ -0,0 +1,328 @@ +" 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 + +" Only define the function once. +if exists("*GetCoffeeIndent") + finish +endif + +" Keywords to indent after +let s:INDENT_AFTER_KEYWORD = '^\%(if\|unless\|else\|for\|while\|until\|' +\ . 'loop\|switch\|when\|try\|catch\|finally\|' +\ . 'class\)\>' + +" Operators to indent after +let s:INDENT_AFTER_OPERATOR = '\%([([{:=]\|[-=]>\)$' + +" Keywords and operators that continue a line +let s:CONTINUATION = '\<\%(is\|isnt\|and\|or\)\>$' +\ . '\|' +\ . '\%(-\@\|\*\|/\@' + +" A compound assignment like `... = if ...` +let s:COMPOUND_ASSIGNMENT = '[:=]\s*\%(if\|unless\|for\|while\|until\|' +\ . 'switch\|try\|class\)\>' + +" A postfix condition like `return ... if ...`. +let s:POSTFIX_CONDITION = '\S\s\+\zs\<\%(if\|unless\)\>' + +" A single-line else statement like `else ...` but not `else if ... +let s:SINGLE_LINE_ELSE = '^else\s\+\%(\<\%(if\|unless\)\>\)\@!' + +" 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 + +" Get the linked syntax name of a character. +function! s:SyntaxName(linenum, col) + return synIDattr(synID(a:linenum, a:col, 1), 'name') +endfunction + +" Check if a character is in a comment. +function! s:IsComment(linenum, col) + return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_COMMENT +endfunction + +" Check if a character is in a string. +function! s:IsString(linenum, col) + return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING +endfunction + +" Check if a character is in a comment or string. +function! s:IsCommentOrString(linenum, col) + return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING_COMMENT +endfunction + +" Check if a whole line is a comment. +function! s:IsCommentLine(linenum) + " Check the first non-whitespace character. + return s:IsComment(a:linenum, indent(a:linenum) + 1) +endfunction + +" Repeatedly search a line for a regex until one is found outside a string or +" comment. +function! s:SmartSearch(linenum, regex) + " Start at the first column. + let col = 0 + + " Search until there are no more matches, unless a good match is found. + while 1 + call cursor(a:linenum, col + 1) + let [_, col] = searchpos(a:regex, 'cn', a:linenum) + + " No more matches. + if !col + break + endif + + if !s:IsCommentOrString(a:linenum, col) + return 1 + endif + endwhile + + " No good match found. + return 0 +endfunction + +" Skip a match if it's in a comment or string, is a single-line statement that +" isn't adjacent, or is a postfix condition. +function! s:ShouldSkip(startlinenum, linenum, col) + if s:IsCommentOrString(a:linenum, a:col) + return 1 + endif + + " Check for a single-line statement that isn't adjacent. + if s:SmartSearch(a:linenum, '\') && a:startlinenum - a:linenum > 1 + return 1 + endif + + if s:SmartSearch(a:linenum, s:POSTFIX_CONDITION) && + \ !s:SmartSearch(a:linenum, s:COMPOUND_ASSIGNMENT) + return 1 + endif + + return 0 +endfunction + +" Find the farthest line to look back to, capped to line 1 (zero and negative +" numbers cause bad things). +function! s:MaxLookback(startlinenum) + return max([1, a:startlinenum - s:MAX_LOOKBACK]) +endfunction + +" Get the skip expression for searchpair(). +function! s:SkipExpr(startlinenum) + return "s:ShouldSkip(" . a:startlinenum . ", line('.'), col('.'))" +endfunction + +" Search for pairs of text. +function! s:SearchPair(start, end) + " The cursor must be in the first column for regexes to match. + call cursor(0, 1) + + let startlinenum = line('.') + + " Don't need the W flag since MaxLookback caps the search to line 1. + return searchpair(a:start, '', a:end, 'bcn', + \ s:SkipExpr(startlinenum), + \ s:MaxLookback(startlinenum)) +endfunction + +" Try to find a previous matching line. +function! s:GetMatch(curline) + let firstchar = a:curline[0] + + if firstchar == '}' + return s:SearchPair('{', '}') + elseif firstchar == ')' + return s:SearchPair('(', ')') + elseif firstchar == ']' + return s:SearchPair('\[', '\]') + elseif a:curline =~ '^else\>' + return s:SearchPair('\<\%(if\|unless\|when\)\>', '\') + elseif a:curline =~ '^catch\>' + return s:SearchPair('\', '\') + elseif a:curline =~ '^finally\>' + return s:SearchPair('\', '\') + endif + + return 0 +endfunction + +" Get the nearest previous line that isn't a comment. +function! s:GetPrevNormalLine(startlinenum) + let curlinenum = a:startlinenum + + while curlinenum > 0 + let curlinenum = prevnonblank(curlinenum - 1) + + if !s:IsCommentLine(curlinenum) + return curlinenum + endif + endwhile + + return 0 +endfunction + +" Try to find a comment in a line. +function! s:FindComment(linenum) + let col = 0 + + while 1 + call cursor(a:linenum, col + 1) + let [_, col] = searchpos('#', 'cn', a:linenum) + + if !col + break + endif + + if s:IsComment(a:linenum, col) + return col + endif + endwhile + + return 0 +endfunction + +" Get a line without comments or surrounding whitespace. +function! s:GetTrimmedLine(linenum) + let comment = s:FindComment(a:linenum) + let line = getline(a:linenum) + + if comment + " Subtract 1 to get to the column before the comment and another 1 for + " zero-based indexing. + let line = line[:comment - 2] + endif + + return substitute(substitute(line, '^\s\+', '', ''), + \ '\s\+$', '', '') +endfunction + +function! s:GetCoffeeIndent(curlinenum) + let prevlinenum = s:GetPrevNormalLine(a:curlinenum) + + " Don't do anything if there's no previous line. + if !prevlinenum + return -1 + endif + + let curline = s:GetTrimmedLine(a:curlinenum) + + " Try to find a previous matching statement. This handles outdenting. + let matchlinenum = s:GetMatch(curline) + + if matchlinenum + return indent(matchlinenum) + endif + + " Try to find a matching `when`. + if curline =~ '^when\>' && !s:SmartSearch(prevlinenum, '\') + let linenum = a:curlinenum + + while linenum > 0 + let linenum = s:GetPrevNormalLine(linenum) + + if getline(linenum) =~ '^\s*when\>' + return indent(linenum) + endif + endwhile + + return -1 + endif + + let prevline = s:GetTrimmedLine(prevlinenum) + let previndent = indent(prevlinenum) + + " Always indent after these operators. + if prevline =~ s:INDENT_AFTER_OPERATOR + return previndent + &shiftwidth + endif + + " Indent after a continuation if it's the first. + if prevline =~ s:CONTINUATION + let prevprevlinenum = s:GetPrevNormalLine(prevlinenum) + + " If the continuation is the first in the file, don't run the other checks. + if !prevprevlinenum + return previndent + &shiftwidth + endif + + let prevprevline = s:GetTrimmedLine(prevprevlinenum) + + if prevprevline !~ s:CONTINUATION && prevprevline !~ s:CONTINUATION_BLOCK + return previndent + &shiftwidth + endif + + return -1 + endif + + " Indent after these keywords and compound assignments if they aren't a + " single-line statement. + if prevline =~ s:INDENT_AFTER_KEYWORD || prevline =~ s:COMPOUND_ASSIGNMENT + if !s:SmartSearch(prevlinenum, '\') && prevline !~ s:SINGLE_LINE_ELSE + return previndent + &shiftwidth + endif + + return -1 + endif + + " Indent a dot access if it's the first. + if curline =~ s:DOT_ACCESS && prevline !~ s:DOT_ACCESS + return previndent + &shiftwidth + endif + + " Outdent after these keywords if they don't have a postfix condition or are + " a single-line statement. + if prevline =~ s:OUTDENT_AFTER + if !s:SmartSearch(prevlinenum, s:POSTFIX_CONDITION) || + \ s:SmartSearch(prevlinenum, '\') + return previndent - &shiftwidth + endif + endif + + " No indenting or outdenting is needed. + return -1 +endfunction + +" Wrap s:GetCoffeeIndent to keep the cursor position. +function! GetCoffeeIndent(curlinenum) + let oldcursor = getpos('.') + let indent = s:GetCoffeeIndent(a:curlinenum) + call setpos('.', oldcursor) + + return indent +endfunction diff --git a/vim/indent/fish.vim b/vim/indent/fish.vim new file mode 100644 index 0000000..d1ef6be --- /dev/null +++ b/vim/indent/fish.vim @@ -0,0 +1,2 @@ +setlocal indentexpr=fish#Indent() +setlocal indentkeys+==end,=else,=case diff --git a/vim/indent/go.vim b/vim/indent/go.vim new file mode 100644 index 0000000..faf4d79 --- /dev/null +++ b/vim/indent/go.vim @@ -0,0 +1,65 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" indent/go.vim: Vim indent file for Go. +" +" TODO: +" - function invocations split across lines +" - general line splits (line ends in an operator) + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" C indentation is too far off useful, mainly due to Go's := operator. +" Let's just define our own. +setlocal nolisp +setlocal autoindent +setlocal indentexpr=GoIndent(v:lnum) +setlocal indentkeys+=<:>,0=},0=) + +if exists("*GoIndent") + finish +endif + +function! GoIndent(lnum) + let prevlnum = prevnonblank(a:lnum-1) + if prevlnum == 0 + " top of file + return 0 + endif + + " grab the previous and current line, stripping comments. + let prevl = substitute(getline(prevlnum), '//.*$', '', '') + let thisl = substitute(getline(a:lnum), '//.*$', '', '') + let previ = indent(prevlnum) + + let ind = previ + + if prevl =~ '[({]\s*$' + " previous line opened a block + let ind += &sw + endif + if prevl =~# '^\s*\(case .*\|default\):$' + " previous line is part of a switch statement + let ind += &sw + endif + " TODO: handle if the previous line is a label. + + if thisl =~ '^\s*[)}]' + " this line closed a block + let ind -= &sw + endif + + " Colons are tricky. + " We want to outdent if it's part of a switch ("case foo:" or "default:"). + " We ignore trying to deal with jump labels because (a) they're rare, and + " (b) they're hard to disambiguate from a composite literal key. + if thisl =~# '^\s*\(case .*\|default\):$' + let ind -= &sw + endif + + return ind +endfunction diff --git a/vim/indent/swift.vim b/vim/indent/swift.vim new file mode 100644 index 0000000..dffb02a --- /dev/null +++ b/vim/indent/swift.vim @@ -0,0 +1,294 @@ +" File: swift.vim +" Author: Keith Smiley +" Description: The indent file for Swift +" Last Modified: December 05, 2014 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +let s:cpo_save = &cpo +set cpo&vim + +setlocal nosmartindent +setlocal indentkeys-=e +setlocal indentkeys+=0] +setlocal indentexpr=SwiftIndent() + +function! s:NumberOfMatches(char, string, index) + let instances = 0 + let i = 0 + while i < strlen(a:string) + if a:string[i] == a:char && !s:IsExcludedFromIndentAtPosition(a:index, i + 1) + let instances += 1 + endif + + let i += 1 + endwhile + + return instances +endfunction + +function! s:SyntaxNameAtPosition(line, column) + return synIDattr(synID(a:line, a:column, 0), "name") +endfunction + +function! s:SyntaxName() + return s:SyntaxNameAtPosition(line("."), col(".")) +endfunction + +function! s:IsExcludedFromIndentAtPosition(line, column) + let name = s:SyntaxNameAtPosition(a:line, a:column) + return s:IsSyntaxNameExcludedFromIndent(name) +endfunction + +function! s:IsExcludedFromIndent() + return s:IsSyntaxNameExcludedFromIndent(s:SyntaxName()) +endfunction + +function! s:IsSyntaxNameExcludedFromIndent(name) + return a:name ==# "swiftComment" || a:name ==# "swiftString" || a:name ==# "swiftInterpolatedWrapper" || a:name ==# "swiftMultilineInterpolatedWrapper" || a:name ==# "swiftMultilineString" +endfunction + +function! s:IsCommentLine(lnum) + return synIDattr(synID(a:lnum, + \ match(getline(a:lnum), "\\S") + 1, 0), "name") + \ ==# "swiftComment" +endfunction + +function! SwiftIndent(...) + let clnum = a:0 ? a:1 : v:lnum + + let line = getline(clnum) + let previousNum = prevnonblank(clnum - 1) + while s:IsCommentLine(previousNum) != 0 + let previousNum = prevnonblank(previousNum - 1) + endwhile + + let previous = getline(previousNum) + let cindent = cindent(clnum) + let previousIndent = indent(previousNum) + + let numOpenParens = s:NumberOfMatches("(", previous, previousNum) + let numCloseParens = s:NumberOfMatches(")", previous, previousNum) + let numOpenBrackets = s:NumberOfMatches("{", previous, previousNum) + let numCloseBrackets = s:NumberOfMatches("}", previous, previousNum) + + let currentOpenBrackets = s:NumberOfMatches("{", line, clnum) + let currentCloseBrackets = s:NumberOfMatches("}", line, clnum) + + let numOpenSquare = s:NumberOfMatches("[", previous, previousNum) + let numCloseSquare = s:NumberOfMatches("]", previous, previousNum) + + let currentCloseSquare = s:NumberOfMatches("]", line, clnum) + if numOpenSquare > numCloseSquare && currentCloseSquare < 1 + return previousIndent + shiftwidth() + endif + + if currentCloseSquare > 0 && line !~ '\v\[.*\]' + let column = col(".") + call cursor(line("."), 1) + let openingSquare = searchpair("\\[", "", "\\]", "bWn", "s:IsExcludedFromIndent()") + call cursor(line("."), column) + + if openingSquare == 0 + return -1 + endif + + " - Line starts with closing square, indent as opening square + if line =~ '\v^\s*]' + return indent(openingSquare) + endif + + " - Line contains closing square and more, indent a level above opening + return indent(openingSquare) + shiftwidth() + endif + + if line =~ ":$" && (line =~ '^\s*case\W' || line =~ '^\s*default\W') + let switch = search("switch", "bWn") + return indent(switch) + elseif previous =~ ":$" && (previous =~ '^\s*case\W' || previous =~ '^\s*default\W') + return previousIndent + shiftwidth() + endif + + if numOpenParens == numCloseParens + if numOpenBrackets > numCloseBrackets + if currentCloseBrackets > currentOpenBrackets || line =~ "\\v^\\s*}" + let column = col(".") + call cursor(line("."), 1) + let openingBracket = searchpair("{", "", "}", "bWn", "s:IsExcludedFromIndent()") + call cursor(line("."), column) + if openingBracket == 0 + return -1 + else + return indent(openingBracket) + endif + endif + + return previousIndent + shiftwidth() + elseif previous =~ "}.*{" + if line =~ "\\v^\\s*}" + return previousIndent + endif + + return previousIndent + shiftwidth() + elseif line =~ "}.*{" + let openingBracket = searchpair("{", "", "}", "bWn", "s:IsExcludedFromIndent()") + + let bracketLine = getline(openingBracket) + let numOpenParensBracketLine = s:NumberOfMatches("(", bracketLine, openingBracket) + let numCloseParensBracketLine = s:NumberOfMatches(")", bracketLine, openingBracket) + if numOpenParensBracketLine > numCloseParensBracketLine + let line = line(".") + let column = col(".") + call cursor(openingParen, column) + let openingParenCol = searchpairpos("(", "", ")", "bWn", "s:IsExcludedFromIndent()")[1] + call cursor(line, column) + return openingParenCol + endif + + return indent(openingBracket) + elseif currentCloseBrackets > currentOpenBrackets + let column = col(".") + let line = line(".") + call cursor(line, 1) + let openingBracket = searchpair("{", "", "}", "bWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + + let bracketLine = getline(openingBracket) + + let numOpenParensBracketLine = s:NumberOfMatches("(", bracketLine, openingBracket) + let numCloseParensBracketLine = s:NumberOfMatches(")", bracketLine, openingBracket) + if numCloseParensBracketLine > numOpenParensBracketLine + let line = line(".") + let column = col(".") + call cursor(openingParen, column) + let openingParen = searchpair("(", "", ")", "bWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + return indent(openingParen) + elseif numOpenParensBracketLine > numCloseParensBracketLine + let line = line(".") + let column = col(".") + call cursor(openingParen, column) + let openingParenCol = searchpairpos("(", "", ")", "bWn", "s:IsExcludedFromIndent()")[1] + call cursor(line, column) + return openingParenCol + endif + + return indent(openingBracket) + elseif line =~ '^\s*)$' + let line = line(".") + let column = col(".") + call cursor(line, 1) + let openingParen = searchpair("(", "", ")", "bWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + return indent(openingParen) + else + " - Current line is blank, and the user presses 'o' + return previousIndent + endif + endif + + if numCloseParens > 0 + if currentOpenBrackets > 0 || currentCloseBrackets > 0 + if currentOpenBrackets > 0 + if numOpenBrackets > numCloseBrackets + return previousIndent + shiftwidth() + endif + + if line =~ "}.*{" + let openingBracket = searchpair("{", "", "}", "bWn", "s:IsExcludedFromIndent()") + return indent(openingBracket) + endif + + if numCloseParens > numOpenParens + let line = line(".") + let column = col(".") + call cursor(line - 1, column) + let openingParen = searchpair("(", "", ")", "bWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + return indent(openingParen) + endif + + return previousIndent + endif + + if currentCloseBrackets > 0 + let openingBracket = searchpair("{", "", "}", "bWn", "s:IsExcludedFromIndent()") + return indent(openingBracket) + endif + + return cindent + endif + + if numCloseParens < numOpenParens + if numOpenBrackets > numCloseBrackets + return previousIndent + shiftwidth() + endif + + let previousParen = match(previous, '\v\($') + if previousParen != -1 + return previousIndent + shiftwidth() + endif + + let line = line(".") + let column = col(".") + call cursor(previousNum, col([previousNum, "$"])) + let previousParen = searchpairpos("(", "", ")", "cbWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + + " Match the last non escaped paren on the previous line + return previousParen[1] + endif + + if numOpenBrackets > numCloseBrackets + let line = line(".") + let column = col(".") + call cursor(previousNum, column) + let openingParen = searchpair("(", "", ")", "bWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + return openingParen + 1 + endif + + " - Previous line has close then open braces, indent previous + 1 'sw' + if previous =~ "}.*{" + return previousIndent + shiftwidth() + endif + + let line = line(".") + let column = col(".") + call cursor(previousNum, column) + let openingParen = searchpair("(", "", ")", "bWn", "s:IsExcludedFromIndent()") + call cursor(line, column) + + return indent(openingParen) + endif + + " - Line above has (unmatched) open paren, next line needs indent + if numOpenParens > 0 + let savePosition = getcurpos() + let lastColumnOfPreviousLine = col([previousNum, "$"]) - 1 + " Must be at EOL because open paren has to be above (left of) the cursor + call cursor(previousNum, lastColumnOfPreviousLine) + let previousParen = searchpairpos("(", "", ")", "cbWn", "s:IsExcludedFromIndent()")[1] + " If the paren on the last line is the last character, indent the contents + " at shiftwidth + previous indent + if previousParen == lastColumnOfPreviousLine + return previousIndent + shiftwidth() + endif + + " The previous line opens a closure and doesn't close it + if numOpenBrackets > numCloseBrackets + return previousParen + shiftwidth() + endif + + call setpos(".", savePosition) + return previousParen + endif + + return cindent +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/vim/plugin/godoc.vim b/vim/plugin/godoc.vim new file mode 100644 index 0000000..a9abb7a --- /dev/null +++ b/vim/plugin/godoc.vim @@ -0,0 +1,85 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" godoc.vim: Vim command to see godoc. + +if exists("g:loaded_godoc") + finish +endif +let g:loaded_godoc = 1 + +let s:buf_nr = -1 +let s:last_word = '' + +function! s:GodocView() + if !bufexists(s:buf_nr) + leftabove new + file `="[Godoc]"` + let s:buf_nr = bufnr('%') + elseif bufwinnr(s:buf_nr) == -1 + leftabove split + execute s:buf_nr . 'buffer' + delete _ + elseif bufwinnr(s:buf_nr) != bufwinnr('%') + execute bufwinnr(s:buf_nr) . 'wincmd w' + endif + + setlocal filetype=godoc + setlocal bufhidden=delete + setlocal buftype=nofile + setlocal noswapfile + setlocal nobuflisted + setlocal modifiable + setlocal nocursorline + setlocal nocursorcolumn + setlocal iskeyword+=: + setlocal iskeyword-=- + + nnoremap K :Godoc + + au BufHidden call let buf_nr = -1 +endfunction + +function! s:GodocWord(word) + let word = a:word + silent! let content = system('godoc ' . word) + if v:shell_error || !len(content) + if len(s:last_word) + silent! let content = system('godoc ' . s:last_word.'/'.word) + if v:shell_error || !len(content) + echo 'No documentation found for "' . word . '".' + return + endif + let word = s:last_word.'/'.word + else + echo 'No documentation found for "' . word . '".' + return + endif + endif + let s:last_word = word + silent! call s:GodocView() + setlocal modifiable + silent! %d _ + silent! put! =content + silent! normal gg + setlocal nomodifiable + setfiletype godoc +endfunction + +function! s:Godoc(...) + let word = join(a:000, ' ') + if !len(word) + let word = expand('') + endif + let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g') + if !len(word) + return + endif + call s:GodocWord(word) +endfunction + +command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc() +nnoremap (godoc-keyword) :call Godoc('') + +" vim:ts=4:sw=4:et diff --git a/vim/syntax/coffee.vim b/vim/syntax/coffee.vim new file mode 100644 index 0000000..c324435 --- /dev/null +++ b/vim/syntax/coffee.vim @@ -0,0 +1,236 @@ +" 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 + +" Highlight long strings. +syn sync minlines=100 + +" CoffeeScript identifiers can have dollar signs. +setlocal isident+=$ + +" 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*\)\@<=[+\-*/%&|\^=!<>?.]\+\|[-=]>\|--\|++\|::/ +\ 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 +" An @-variable +syn match coffeeSpecialVar /@\%(\I\i*\)\?/ display +hi def link coffeeSpecialVar Special + +" 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,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 +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 +endif + +" This is separate from `coffeeExtendedOp` since assignments require it. +syn match coffeeAssignOp /:/ contained display +hi def link coffeeAssignOp coffeeOperator + +" Strings used in string assignments, which can't have interpolations +syn region coffeeAssignString start=/"/ skip=/\\\\\|\\"/ end=/"/ contained +\ contains=@coffeeBasicString +syn region coffeeAssignString start=/'/ skip=/\\\\\|\\'/ end=/'/ contained +\ contains=@coffeeBasicString +hi def link coffeeAssignString String + +" A normal object assignment +syn match coffeeObjAssign /@\?\I\i*\s*:\@&;"']|\\[xX][0-9a-f]{1,2}|\\o[0-7]{1,2}|\\u[0-9a-f]{1,4}|\\U[0-9a-f]{1,8}|\\c[a-z]/ +syntax match fishStatement /\v;\s*\zs\k+>/ +syntax match fishCommandSub /\v\(\s*\zs\k+>/ + +syntax region fishLineContinuation matchgroup=fishStatement + \ start='\v^\s*\zs\k+>' skip='\\$' end='$' + \ contains=fishSpecial,fishIdentifier,fishString,fishCharacter,fishStatement,fishCommandSub,fishComment + +highlight default link fishKeyword Keyword +highlight default link fishConditional Conditional +highlight default link fishRepeat Repeat +highlight default link fishLabel Label +highlight default link fishComment Comment +highlight default link fishSpecial Special +highlight default link fishIdentifier Identifier +highlight default link fishString String +highlight default link fishCharacter Character +highlight default link fishStatement Statement +highlight default link fishCommandSub fishStatement + +let b:current_syntax = 'fish' diff --git a/vim/syntax/go.vim b/vim/syntax/go.vim new file mode 100644 index 0000000..1ce6cb2 --- /dev/null +++ b/vim/syntax/go.vim @@ -0,0 +1,207 @@ +" Copyright 2009 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" go.vim: Vim syntax file for Go. +" +" Options: +" There are some options for customizing the highlighting; the recommended +" settings are the default values, but you can write: +" let OPTION_NAME = 0 +" in your ~/.vimrc file to disable particular options. You can also write: +" let OPTION_NAME = 1 +" to enable particular options. At present, all options default to on. +" +" - go_highlight_array_whitespace_error +" Highlights white space after "[]". +" - go_highlight_chan_whitespace_error +" Highlights white space around the communications operator that don't follow +" the standard style. +" - go_highlight_extra_types +" Highlights commonly used library types (io.Reader, etc.). +" - go_highlight_space_tab_error +" Highlights instances of tabs following spaces. +" - go_highlight_trailing_whitespace_error +" Highlights trailing white space. + +" Quit when a (custom) syntax file was already loaded +if exists("b:current_syntax") + finish +endif + +if !exists("go_highlight_array_whitespace_error") + let go_highlight_array_whitespace_error = 1 +endif +if !exists("go_highlight_chan_whitespace_error") + let go_highlight_chan_whitespace_error = 1 +endif +if !exists("go_highlight_extra_types") + let go_highlight_extra_types = 1 +endif +if !exists("go_highlight_space_tab_error") + let go_highlight_space_tab_error = 1 +endif +if !exists("go_highlight_trailing_whitespace_error") + let go_highlight_trailing_whitespace_error = 1 +endif + +syn case match + +syn keyword goDirective package import +syn keyword goDeclaration var const type +syn keyword goDeclType struct interface + +hi def link goDirective Statement +hi def link goDeclaration Keyword +hi def link goDeclType Keyword + +" Keywords within functions +syn keyword goStatement defer go goto return break continue fallthrough +syn keyword goConditional if else switch select +syn keyword goLabel case default +syn keyword goRepeat for range + +hi def link goStatement Statement +hi def link goConditional Conditional +hi def link goLabel Label +hi def link goRepeat Repeat + +" Predefined types +syn keyword goType chan map bool string error +syn keyword goSignedInts int int8 int16 int32 int64 rune +syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr +syn keyword goFloats float32 float64 +syn keyword goComplexes complex64 complex128 + +hi def link goType Type +hi def link goSignedInts Type +hi def link goUnsignedInts Type +hi def link goFloats Type +hi def link goComplexes Type + +" Treat func specially: it's a declaration at the start of a line, but a type +" elsewhere. Order matters here. +syn match goType /\/ +syn match goDeclaration /^func\>/ + +" Predefined functions and values +syn keyword goBuiltins append cap close complex copy delete imag len +syn keyword goBuiltins make new panic print println real recover +syn keyword goConstants iota true false nil + +hi def link goBuiltins Keyword +hi def link goConstants Keyword + +" Comments; their contents +syn keyword goTodo contained TODO FIXME XXX BUG +syn cluster goCommentGroup contains=goTodo +syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell +syn region goComment start="//" end="$" contains=@goCommentGroup,@Spell + +hi def link goComment Comment +hi def link goTodo Todo + +" Go escapes +syn match goEscapeOctal display contained "\\[0-7]\{3}" +syn match goEscapeC display contained +\\[abfnrtv\\'"]+ +syn match goEscapeX display contained "\\x\x\{2}" +syn match goEscapeU display contained "\\u\x\{4}" +syn match goEscapeBigU display contained "\\U\x\{8}" +syn match goEscapeError display contained +\\[^0-7xuUabfnrtv\\'"]+ + +hi def link goEscapeOctal goSpecialString +hi def link goEscapeC goSpecialString +hi def link goEscapeX goSpecialString +hi def link goEscapeU goSpecialString +hi def link goEscapeBigU goSpecialString +hi def link goSpecialString Special +hi def link goEscapeError Error + +" Strings and their contents +syn cluster goStringGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU,goEscapeError +syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup +syn region goRawString start=+`+ end=+`+ + +hi def link goString String +hi def link goRawString String + +" Characters; their contents +syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU +syn region goCharacter start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=@goCharacterGroup + +hi def link goCharacter Character + +" Regions +syn region goBlock start="{" end="}" transparent fold +syn region goParen start='(' end=')' transparent + +" Integers +syn match goDecimalInt "\<\d\+\([Ee]\d\+\)\?\>" +syn match goHexadecimalInt "\<0x\x\+\>" +syn match goOctalInt "\<0\o\+\>" +syn match goOctalError "\<0\o*[89]\d*\>" + +hi def link goDecimalInt Integer +hi def link goHexadecimalInt Integer +hi def link goOctalInt Integer +hi def link Integer Number + +" Floating point +syn match goFloat "\<\d\+\.\d*\([Ee][-+]\d\+\)\?\>" +syn match goFloat "\<\.\d\+\([Ee][-+]\d\+\)\?\>" +syn match goFloat "\<\d\+[Ee][-+]\d\+\>" + +hi def link goFloat Float + +" Imaginary literals +syn match goImaginary "\<\d\+i\>" +syn match goImaginary "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>" +syn match goImaginary "\<\.\d\+\([Ee][-+]\d\+\)\?i\>" +syn match goImaginary "\<\d\+[Ee][-+]\d\+i\>" + +hi def link goImaginary Number + +" Spaces after "[]" +if go_highlight_array_whitespace_error != 0 + syn match goSpaceError display "\(\[\]\)\@<=\s\+" +endif + +" Spacing errors around the 'chan' keyword +if go_highlight_chan_whitespace_error != 0 + " receive-only annotation on chan type + syn match goSpaceError display "\(<-\)\@<=\s\+\(chan\>\)\@=" + " send-only annotation on chan type + syn match goSpaceError display "\(\/ + syn match goExtraType /\/ + syn match goExtraType /\/ + syn match goExtraType /\/ +endif + +" Space-tab error +if go_highlight_space_tab_error != 0 + syn match goSpaceError display " \+\t"me=e-1 +endif + +" Trailing white space error +if go_highlight_trailing_whitespace_error != 0 + syn match goSpaceError display excludenl "\s\+$" +endif + +hi def link goExtraType Type +hi def link goSpaceError Error + +" Search backwards for a global declaration to start processing the syntax. +"syn sync match goSync grouphere NONE /^\(const\|var\|type\|func\)\>/ + +" There's a bug in the implementation of grouphere. For now, use the +" following as a more expensive/less precise workaround. +syn sync minlines=500 + +let b:current_syntax = "go" diff --git a/vim/syntax/godoc.vim b/vim/syntax/godoc.vim new file mode 100644 index 0000000..82f78aa --- /dev/null +++ b/vim/syntax/godoc.vim @@ -0,0 +1,20 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. + +if exists("b:current_syntax") + finish +endif + +syn case match +syn match godocTitle "^\([A-Z]*\)$" + +command -nargs=+ HiLink hi def link + +HiLink godocTitle Title + +delcommand HiLink + +let b:current_syntax = "godoc" + +" vim:ts=4 sts=2 sw=2: diff --git a/vim/syntax/objc.vim b/vim/syntax/objc.vim index bc54444..cbc9155 100644 --- a/vim/syntax/objc.vim +++ b/vim/syntax/objc.vim @@ -39,7 +39,7 @@ syn keyword objcTypeModifier OF_NULL_RESETTABLE_PROPERTY OF_UNAVAILABLE syn keyword objcTypeModifier OF_DESIGNATED_INITIALIZER OF_METHOD_FAMILY syn keyword objcTypeModifier OF_REQUIRES_SUPER OF_ALIGN OF_ALIGNOF OF_ALIGNAS syn keyword objcTypeModifier OF_SENTINEL OF_SUBCLASSING_RESTRICTED -syn keyword objcTypeModifier OF_DIRECT OF_DIRECT_MEMBERS OF_DIRECT_PROPERTY +syn keyword objcTypeModifier OF_DIRECT OF_DIRECT_MEMBERS syn keyword objcTypeModifier _Nonnull _Nullable _Null_unspecified __kindof syn keyword objcConstant nil Nil OFNotFound diff --git a/vim/syntax/swift.vim b/vim/syntax/swift.vim new file mode 100644 index 0000000..3771622 --- /dev/null +++ b/vim/syntax/swift.vim @@ -0,0 +1,305 @@ +" File: swift.vim +" Author: Keith Smiley +" Description: Runtime files for Swift + +if exists("b:current_syntax") + finish +endif + +" Comments +" Shebang +syntax match swiftShebang "\v#!.*$" + +" Comment contained keywords +syntax keyword swiftTodos contained TODO XXX FIXME NOTE +syntax keyword swiftMarker contained MARK + +" In comment identifiers +function! s:CommentKeywordMatch(keyword) + execute "syntax match swiftDocString \"\\v^\\s*-\\s*". a:keyword . "\\W\"hs=s+1,he=e-1 contained" +endfunction + +syntax case ignore + +call s:CommentKeywordMatch("attention") +call s:CommentKeywordMatch("author") +call s:CommentKeywordMatch("authors") +call s:CommentKeywordMatch("bug") +call s:CommentKeywordMatch("complexity") +call s:CommentKeywordMatch("copyright") +call s:CommentKeywordMatch("date") +call s:CommentKeywordMatch("experiment") +call s:CommentKeywordMatch("important") +call s:CommentKeywordMatch("invariant") +call s:CommentKeywordMatch("note") +call s:CommentKeywordMatch("parameter") +call s:CommentKeywordMatch("postcondition") +call s:CommentKeywordMatch("precondition") +call s:CommentKeywordMatch("remark") +call s:CommentKeywordMatch("remarks") +call s:CommentKeywordMatch("requires") +call s:CommentKeywordMatch("returns") +call s:CommentKeywordMatch("see") +call s:CommentKeywordMatch("since") +call s:CommentKeywordMatch("throws") +call s:CommentKeywordMatch("todo") +call s:CommentKeywordMatch("version") +call s:CommentKeywordMatch("warning") + +syntax case match +delfunction s:CommentKeywordMatch + + +" Literals +" Strings +syntax region swiftString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=swiftInterpolatedWrapper oneline +syntax region swiftMultilineString start=/"""/ end=/"""/ contains=swiftMultilineInterpolatedWrapper +syntax region swiftMultilineInterpolatedWrapper start='\v\zs\\\(\s*' end='\v\s*\)' contained containedin=swiftMultilineString contains=swiftInterpolatedString oneline +syntax region swiftInterpolatedWrapper start='\v(^|[^\\])\zs\\\(\s*' end='\v\s*\)' contained containedin=swiftString contains=swiftInterpolatedString,swiftString oneline +syntax match swiftInterpolatedString "\v\w+(\(\))?" contained containedin=swiftInterpolatedWrapper,swiftMultilineInterpolatedWrapper oneline + +" Numbers +syntax match swiftNumber "\v<\d+>" +syntax match swiftNumber "\v<(\d+_+)+\d+(\.\d+(_+\d+)*)?>" +syntax match swiftNumber "\v<\d+\.\d+>" +syntax match swiftNumber "\v<\d*\.?\d+([Ee]-?)?\d+>" +syntax match swiftNumber "\v<0x[[:xdigit:]_]+([Pp]-?)?\x+>" +syntax match swiftNumber "\v<0b[01_]+>" +syntax match swiftNumber "\v<0o[0-7_]+>" + +" BOOLs +syntax keyword swiftBoolean + \ true + \ false + + +" Operators +syntax match swiftOperator "\v\~" +syntax match swiftOperator "\v\s+!" +syntax match swiftOperator "\v\%" +syntax match swiftOperator "\v\^" +syntax match swiftOperator "\v\&" +syntax match swiftOperator "\v\*" +syntax match swiftOperator "\v-" +syntax match swiftOperator "\v\+" +syntax match swiftOperator "\v\=" +syntax match swiftOperator "\v\|" +syntax match swiftOperator "\v\/" +syntax match swiftOperator "\v\<" +syntax match swiftOperator "\v\>" +syntax match swiftOperator "\v\?\?" + +" Methods/Functions/Properties +syntax match swiftMethod "\.\@<=\<\D\w*\>\ze(" +syntax match swiftProperty "\.\@<=\<\D\w*\>(\@!" + +" Swift closure arguments +syntax match swiftClosureArgument "\$\d\+\(\.\d\+\)\?" + +syntax match swiftAvailability "\v((\*(\s*,\s*[a-zA-Z="0-9.]+)*)|(\w+\s+\d+(\.\d+(.\d+)?)?\s*,\s*)+\*)" contains=swiftString +syntax keyword swiftPlatforms OSX iOS watchOS OSXApplicationExtension iOSApplicationExtension contained containedin=swiftAvailability +syntax keyword swiftAvailabilityArg renamed unavailable introduced deprecated obsoleted message contained containedin=swiftAvailability + +" Keywords {{{ +syntax keyword swiftKeywords + \ associatedtype + \ associativity + \ atexit + \ break + \ case + \ catch + \ class + \ continue + \ convenience + \ default + \ defer + \ deinit + \ didSet + \ do + \ dynamic + \ else + \ extension + \ fallthrough + \ fileprivate + \ final + \ for + \ func + \ get + \ guard + \ if + \ import + \ in + \ infix + \ init + \ inout + \ internal + \ lazy + \ let + \ mutating + \ nil + \ nonmutating + \ open + \ operator + \ optional + \ override + \ postfix + \ precedence + \ precedencegroup + \ prefix + \ private + \ protocol + \ public + \ repeat + \ required + \ return + \ self + \ set + \ some + \ static + \ subscript + \ super + \ switch + \ throw + \ try + \ typealias + \ unowned + \ var + \ weak + \ where + \ while + \ willSet + +syntax keyword swiftDefinitionModifier + \ rethrows + \ throws + +syntax match swiftMultiwordKeywords "indirect case" +syntax match swiftMultiwordKeywords "indirect enum" +" }}} + +" Names surrounded by backticks. This aren't limited to keywords because 1) +" Swift doesn't limit them to keywords and 2) I couldn't make the keywords not +" highlight at the same time +syntax region swiftEscapedReservedWord start="`" end="`" oneline + +syntax keyword swiftAttributes + \ @_exported + \ @_functionBuilder + \ @_implementationOnly + \ @_silgen_name + \ @assignment + \ @autoclosure + \ @available + \ @convention + \ @discardableResult + \ @escaping + \ @exported + \ @frozen + \ @IBAction + \ @IBDesignable + \ @IBInspectable + \ @IBOutlet + \ @inlinable + \ @noescape + \ @nonobjc + \ @noreturn + \ @NSApplicationMain + \ @NSCopying + \ @NSManaged + \ @objc + \ @propertyWrapper + \ @testable + \ @UIApplicationMain + \ @usableFromInline + \ @warn_unused_result + +syntax keyword swiftConditionStatement #available + +syntax keyword swiftStructure + \ struct + \ enum + +syntax keyword swiftDebugIdentifier + \ #column + \ #file + \ #function + \ #line + \ __COLUMN__ + \ __FILE__ + \ __FUNCTION__ + \ __LINE__ + +syntax keyword swiftLineDirective #setline + +syntax region swiftTypeWrapper start=":\s*\(\.\)\@!\<\u" skip="\s*,\s*$*\s*" end="$\|/"me=e-1 contains=ALLBUT,swiftInterpolatedWrapper,swiftMultilineInterpolatedWrapper transparent +syntax region swiftTypeCastWrapper start="\(as\|is\)\(!\|?\)\=\s\+" end="\v(\s|$|\{)" contains=swiftType,swiftCastKeyword keepend transparent oneline +syntax region swiftGenericsWrapper start="\v\<" end="\v\>" contains=swiftType transparent oneline +syntax region swiftLiteralWrapper start="\v\=\s*" skip="\v[^\[\]]\(\)" end="\v(\[\]|\(\))" contains=ALL transparent oneline +syntax region swiftReturnWrapper start="\v-\>\s*" end="\v(\{|$)" contains=swiftType transparent oneline +syntax match swiftType "\v<\u\w*" contained containedin=swiftTypeWrapper,swiftLiteralWrapper,swiftGenericsWrapper,swiftTypeCastWrapper +syntax match swiftTypeDeclaration /->/ skipwhite nextgroup=swiftType + +syntax keyword swiftImports import +syntax keyword swiftCastKeyword is as contained + +" 'preprocesor' stuff +syntax keyword swiftPreprocessor + \ #if + \ #elseif + \ #else + \ #endif + \ #selector + \ #warning + \ #error + + +" Comment patterns +syntax match swiftComment "\v\/\/.*$" + \ contains=swiftTodos,swiftDocString,swiftMarker,@Spell oneline +syntax region swiftComment start="/\*" end="\*/" + \ contains=swiftTodos,swiftDocString,swiftMarker,@Spell fold + + +" Set highlights +highlight default link swiftTodos Todo +highlight default link swiftDocString String +highlight default link swiftShebang Comment +highlight default link swiftComment Comment +highlight default link swiftMarker Comment + +highlight default link swiftString String +highlight default link swiftMultilineString String +highlight default link swiftInterpolatedWrapper Delimiter +highlight default link swiftMultilineInterpolatedWrapper Delimiter +highlight default link swiftTypeDeclaration Delimiter +highlight default link swiftNumber Number +highlight default link swiftBoolean Boolean + +highlight default link swiftOperator Operator +highlight default link swiftCastKeyword Keyword +highlight default link swiftKeywords Keyword +highlight default link swiftMultiwordKeywords Keyword +highlight default link swiftEscapedReservedWord Normal +highlight default link swiftClosureArgument Operator +highlight default link swiftAttributes PreProc +highlight default link swiftConditionStatement PreProc +highlight default link swiftStructure Structure +highlight default link swiftType Type +highlight default link swiftImports Include +highlight default link swiftPreprocessor PreProc +highlight default link swiftMethod Function +highlight default link swiftProperty Identifier + +highlight default link swiftDefinitionModifier Define +highlight default link swiftConditionStatement PreProc +highlight default link swiftAvailability Normal +highlight default link swiftAvailabilityArg Normal +highlight default link swiftPlatforms Keyword +highlight default link swiftDebugIdentifier PreProc +highlight default link swiftLineDirective PreProc + +" Force vim to sync at least x lines. This solves the multiline comment not +" being highlighted issue +syn sync minlines=100 + +let b:current_syntax = "swift" diff --git a/vim/vimrc b/vim/vimrc index 359bf67..900c229 100644 --- a/vim/vimrc +++ b/vim/vimrc @@ -23,11 +23,10 @@ if v:version >= 703 end set hlsearch +set t_Co=256 set background=dark -if &t_Co >= 256 - let g:inkpot_black_background=1 - colorscheme inkpot -end +let g:inkpot_black_background=1 +colorscheme inkpot set cinoptions=+4,(4,u4,w4 if v:version >= 703 diff --git a/zshrc b/zshrc index b561edf..d05da37 100644 --- a/zshrc +++ b/zshrc @@ -4,7 +4,6 @@ export XDG_DATA_HOME="$HOME/.local/share" export EDITOR="vim" export VIMINIT="source $XDG_CONFIG_HOME/vim/vimrc" export PAGER="less" -unset HISTFILE export LS_COLORS='di=34:ow=44;37:tw=44;37:st=44;37:ex=31:su=7;31:sg=7;31:ln=33:or=7;33:pi=32:do=32:bd=35:cd=35:so=32:*.bz2=36:*.dmg=36:*.gz=36:*.gpg=36:*.rar=36:*.tar=36:*.tbz2=36:*.tgz=36:*.xz=36:*.zip=36:*.orig=90:*~=90' export SUDO_PROMPT="$(printf "\033[0;31m[\033[1;31msudo → %%U\033[0;31m]\033[0m Password for \033[1m%%p@%%H\033[0m: ")" export GNUPGHOME="$XDG_DATA_HOME/gnupg" @@ -390,6 +389,9 @@ __has_command pkg_rolling-replace && __has_command url2pkg && alias url2pkg="MAKEFLAGS= url2pkg" +# mpv does not like locales that use , as decimal point. +__has_command mpv && alias mpv="LC_ALL=C mpv" + if __has_command gpg gpg2; then alias gssh='SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) ssh -o IdentitiesOnly=no' alias gssh-add='SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) ssh-add' @@ -666,4 +668,4 @@ __EOF__ fi unset fgrep grep grep_color ls ls_color ls_on_cd ls_on_init -: +unset HISTFILE