diff --git a/.vim/pack/plugins/start/zig.vim/LICENSE b/.vim/pack/plugins/start/zig.vim/LICENSE new file mode 100644 index 0000000..b9f5d0e --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/LICENSE @@ -0,0 +1,21 @@ +The MIT License (Expat) + +Copyright (c) 2017 Andrew Kelley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/.vim/pack/plugins/start/zig.vim/README.md b/.vim/pack/plugins/start/zig.vim/README.md new file mode 100644 index 0000000..57b8510 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/README.md @@ -0,0 +1,26 @@ +# zig.vim + +File detection and syntax highlighting for the +[zig](http://ziglang.org/) programming language. + +## Installation + +If using **Vim**: + * Use Vim 8 or newer + * `mkdir -p ~/.vim/pack/plugins/start/` + * `cd ~/.vim/pack/plugins/start/` + * `git clone https://github.com/ziglang/zig.vim` + +If using **Neovim**: + * `mkdir -p ~/.local/share/nvim/site/pack/plugins/start/` + * `cd ~/.local/share/nvim/site/pack/plugins/start/` + * `git clone https://github.com/ziglang/zig.vim` + +## Configuration + +This plugin enables automatic code formatting on save by default using +`zig fmt`. To disable it, you can use this configuration in vimrc: + +``` +let g:zig_fmt_autosave = 0 +``` diff --git a/.vim/pack/plugins/start/zig.vim/autoload/zig/config.vim b/.vim/pack/plugins/start/zig.vim/autoload/zig/config.vim new file mode 100644 index 0000000..d50b515 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/autoload/zig/config.vim @@ -0,0 +1,39 @@ +function! zig#config#ListTypeCommands() abort + return get(g:, 'zig_list_type_commands', {}) +endfunction + +function! zig#config#ListType() abort + return get(g:, 'zig_list_type', '') +endfunction + +function! zig#config#ListAutoclose() abort + return get(g:, 'zig_list_autoclose', 1) +endfunction + +function! zig#config#ListHeight() abort + return get(g:, "zig_list_height", 0) +endfunction + +function! zig#config#FmtAutosave() abort + return get(g:, "zig_fmt_autosave", 0) +endfunction + +function! zig#config#SetFmtAutosave(value) abort + let g:zig_fmt_autosave = a:value +endfunction + +function! zig#config#FmtCommand() abort + return get(g:, "zig_fmt_command", ['zig', 'fmt', '--color', 'off']) +endfunction + +function! zig#config#FmtFailSilently() abort + return get(g:, "zig_fmt_fail_silently", 0) +endfunction + +function! zig#config#FmtExperimental() abort + return get(g:, "zig_fmt_experimental", 0) +endfunction + +function! zig#config#Debug() abort + return get(g:, 'zig_debug', []) +endfunction diff --git a/.vim/pack/plugins/start/zig.vim/autoload/zig/fmt.vim b/.vim/pack/plugins/start/zig.vim/autoload/zig/fmt.vim new file mode 100644 index 0000000..4bfa269 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/autoload/zig/fmt.vim @@ -0,0 +1,166 @@ +" Adapted from fatih/vim-go: autoload/go/fmt.vim +" +" 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. +" +function! zig#fmt#Format() abort + if zig#config#FmtExperimental() + " Using winsaveview to save/restore cursor state has the problem of + " closing folds on save: + " https://github.com/fatih/vim-go/issues/502 + " One fix is to use mkview instead. Unfortunately, this sometimes causes + " other bad side effects: + " https://github.com/fatih/vim-go/issues/728 + " and still closes all folds if foldlevel>0: + " https://github.com/fatih/vim-go/issues/732 + let l:curw = {} + try + mkview! + catch + let l:curw = winsaveview() + endtry + + " save our undo file to be restored after we are done. This is needed to + " prevent an additional undo jump due to BufWritePre auto command and also + " restore 'redo' history because it's getting being destroyed every + " BufWritePre + let tmpundofile = tempname() + exe 'wundo! ' . tmpundofile + else + " Save cursor position and many other things. + let l:curw = winsaveview() + endif + + " Save cursor position and many other things. + let l:curw = winsaveview() + + let bin_name = zig#config#FmtCommand() + + " Get current position in file + let current_col = col('.') + let orig_line_count = line('$') + + " Save current buffer first, else fmt will run on the original file and we + " will lose our changes. + silent! execute 'write' expand('%') + + let [l:out, l:err] = zig#fmt#run(bin_name, expand('%')) + + if l:err == 0 + call zig#fmt#update_file(expand('%')) + elseif !zig#config#FmtFailSilently() + let errors = s:parse_errors(expand('%'), out) + call s:show_errors(errors) + endif + + let diff_offset = line('$') - orig_line_count + + if zig#config#FmtExperimental() + " restore our undo history + silent! exe 'rundo ' . tmpundofile + call delete(tmpundofile) + + " Restore our cursor/windows positions, folds, etc. + if empty(l:curw) + silent! loadview + else + call winrestview(l:curw) + endif + else + " Restore our cursor/windows positions. + call winrestview(l:curw) + endif + + " be smart and jump to the line the new statement was added/removed + call cursor(line('.') + diff_offset, current_col) + + " Syntax highlighting breaks less often. + syntax sync fromstart +endfunction + +" update_file updates the target file with the given formatted source +function! zig#fmt#update_file(target) + " remove undo point caused via BufWritePre + try | silent undojoin | catch | endtry + + " reload buffer to reflect latest changes + silent edit! + + let l:listtype = zig#list#Type("ZigFmt") + + " the title information was introduced with 7.4-2200 + " https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640 + if has('patch-7.4.2200') + " clean up previous list + if l:listtype == "quickfix" + let l:list_title = getqflist({'title': 1}) + else + let l:list_title = getloclist(0, {'title': 1}) + endif + else + " can't check the title, so assume that the list was for go fmt. + let l:list_title = {'title': 'Format'} + endif + + if has_key(l:list_title, "title") && l:list_title['title'] == "Format" + call zig#list#Clean(l:listtype) + endif +endfunction + +" run runs the gofmt/goimport command for the given source file and returns +" the output of the executed command. Target is the real file to be formatted. +function! zig#fmt#run(bin_name, target) + let l:cmd = [] + call extend(cmd, a:bin_name) + call extend(cmd, [a:target]) + return zig#util#Exec(l:cmd) +endfunction + +" parse_errors parses the given errors and returns a list of parsed errors +function! s:parse_errors(filename, content) abort + let splitted = split(a:content, '\n') + + " list of errors to be put into location list + let errors = [] + for line in splitted + let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') + if !empty(tokens) + call add(errors,{ + \"filename": a:filename, + \"lnum": tokens[2], + \"col": tokens[3], + \"text": tokens[4], + \ }) + endif + endfor + + return errors +endfunction + +" show_errors opens a location list and shows the given errors. If the given +" errors is empty, it closes the the location list +function! s:show_errors(errors) abort + let l:listtype = zig#list#Type("ZigFmt") + if !empty(a:errors) + call zig#list#Populate(l:listtype, a:errors, 'Format') + echohl Error | echomsg "zig fmt returned error" | echohl None + endif + + " this closes the window if there are no errors or it opens + " it if there is any + call zig#list#Window(l:listtype, len(a:errors)) +endfunction + +function! zig#fmt#ToggleFmtAutoSave() abort + if zig#config#FmtAutosave() + call zig#config#SetFmtAutosave(0) + call zig#util#EchoProgress("auto fmt disabled") + return + end + + call zig#config#SetFmtAutosave(1) + call zig#util#EchoProgress("auto fmt enabled") +endfunction + +" vim: sw=2 ts=2 et diff --git a/.vim/pack/plugins/start/zig.vim/autoload/zig/list.vim b/.vim/pack/plugins/start/zig.vim/autoload/zig/list.vim new file mode 100644 index 0000000..d460e22 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/autoload/zig/list.vim @@ -0,0 +1,158 @@ +" Adapted from fatih/vim-go: autoload/go/list.vim +" +" 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. +" + +" Window opens the list with the given height up to 10 lines maximum. +" Otherwise g:zig_loclist_height is used. +" +" If no or zero height is given it closes the window by default. +" To prevent this, set g:zig_list_autoclose = 0 +function! zig#list#Window(listtype, ...) abort + " we don't use lwindow to close the location list as we need also the + " ability to resize the window. So, we are going to use lopen and lclose + " for a better user experience. If the number of errors in a current + " location list increases/decreases, cwindow will not resize when a new + " updated height is passed. lopen in the other hand resizes the screen. + if !a:0 || a:1 == 0 + call zig#list#Close(a:listtype) + return + endif + + let height = zig#config#ListHeight() + if height == 0 + " prevent creating a large location height for a large set of numbers + if a:1 > 10 + let height = 10 + else + let height = a:1 + endif + endif + + if a:listtype == "locationlist" + exe 'lopen ' . height + else + exe 'copen ' . height + endif +endfunction + + +" Get returns the current items from the list +function! zig#list#Get(listtype) abort + if a:listtype == "locationlist" + return getloclist(0) + else + return getqflist() + endif +endfunction + +" Populate populate the list with the given items +function! zig#list#Populate(listtype, items, title) abort + if a:listtype == "locationlist" + call setloclist(0, a:items, 'r') + + " The last argument ({what}) is introduced with 7.4.2200: + " https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640 + if has("patch-7.4.2200") | call setloclist(0, [], 'a', {'title': a:title}) | endif + else + call setqflist(a:items, 'r') + if has("patch-7.4.2200") | call setqflist([], 'a', {'title': a:title}) | endif + endif +endfunction + +" Parse parses the given items based on the specified errorformat and +" populates the list. +function! zig#list#ParseFormat(listtype, errformat, items, title) abort + " backup users errorformat, will be restored once we are finished + let old_errorformat = &errorformat + + " parse and populate the location list + let &errorformat = a:errformat + try + call zig#list#Parse(a:listtype, a:items, a:title) + finally + "restore back + let &errorformat = old_errorformat + endtry +endfunction + +" Parse parses the given items based on the global errorformat and +" populates the list. +function! zig#list#Parse(listtype, items, title) abort + if a:listtype == "locationlist" + lgetexpr a:items + if has("patch-7.4.2200") | call setloclist(0, [], 'a', {'title': a:title}) | endif + else + cgetexpr a:items + if has("patch-7.4.2200") | call setqflist([], 'a', {'title': a:title}) | endif + endif +endfunction + +" JumpToFirst jumps to the first item in the location list +function! zig#list#JumpToFirst(listtype) abort + if a:listtype == "locationlist" + ll 1 + else + cc 1 + endif +endfunction + +" Clean cleans and closes the location list +function! zig#list#Clean(listtype) abort + if a:listtype == "locationlist" + lex [] + else + cex [] + endif + + call zig#list#Close(a:listtype) +endfunction + +" Close closes the location list +function! zig#list#Close(listtype) abort + let autoclose_window = zig#config#ListAutoclose() + if !autoclose_window + return + endif + + if a:listtype == "locationlist" + lclose + else + cclose + endif +endfunction + +function! s:listtype(listtype) abort + let listtype = zig#config#ListType() + if empty(listtype) + return a:listtype + endif + + return listtype +endfunction + +" s:default_list_type_commands is the defaults that will be used for each of +" the supported commands (see documentation for g:zig_list_type_commands). When +" defining a default, quickfix should be used if the command operates on +" multiple files, while locationlist should be used if the command operates on a +" single file or buffer. Keys that begin with an underscore are not supported +" in g:zig_list_type_commands. +let s:default_list_type_commands = { + \ "ZigFmt": "locationlist", + \ } + +function! zig#list#Type(for) abort + let l:listtype = s:listtype(get(s:default_list_type_commands, a:for)) + if l:listtype == "0" + call zig#util#EchoError(printf( + \ "unknown list type command value found ('%s'). Please open a bug report in the zig.vim repo.", + \ a:for)) + let l:listtype = "quickfix" + endif + + return get(zig#config#ListTypeCommands(), a:for, l:listtype) +endfunction + +" vim: sw=2 ts=2 et diff --git a/.vim/pack/plugins/start/zig.vim/autoload/zig/util.vim b/.vim/pack/plugins/start/zig.vim/autoload/zig/util.vim new file mode 100644 index 0000000..bb3ee03 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/autoload/zig/util.vim @@ -0,0 +1,390 @@ +" Adapted from vim-go: autoload/go/util.vim +" +" 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. +" + +" PathSep returns the appropriate OS specific path separator. +function! zig#util#PathSep() abort + if zig#util#IsWin() + return '\' + endif + return '/' +endfunction + +" PathListSep returns the appropriate OS specific path list separator. +function! zig#util#PathListSep() abort + if zig#util#IsWin() + return ";" + endif + return ":" +endfunction + +" LineEnding returns the correct line ending, based on the current fileformat +function! zig#util#LineEnding() abort + if &fileformat == 'dos' + return "\r\n" + elseif &fileformat == 'mac' + return "\r" + endif + + return "\n" +endfunction + +" Join joins any number of path elements into a single path, adding a +" Separator if necessary and returns the result +function! zig#util#Join(...) abort + return join(a:000, zig#util#PathSep()) +endfunction + +" IsWin returns 1 if current OS is Windows or 0 otherwise +function! zig#util#IsWin() abort + let win = ['win16', 'win32', 'win64', 'win95'] + for w in win + if (has(w)) + return 1 + endif + endfor + + return 0 +endfunction + +" IsMac returns 1 if current OS is macOS or 0 otherwise. +function! zig#util#IsMac() abort + return has('mac') || + \ has('macunix') || + \ has('gui_macvim') || + \ zig#util#Exec(['uname'])[0] =~? '^darwin' +endfunction + + " Checks if using: + " 1) Windows system, + " 2) And has cygpath executable, + " 3) And uses *sh* as 'shell' +function! zig#util#IsUsingCygwinShell() + return zig#util#IsWin() && executable('cygpath') && &shell =~ '.*sh.*' +endfunction + +" Check if Vim jobs API is supported. +" +" The (optional) first paramter can be added to indicate the 'cwd' or 'env' +" parameters will be used, which wasn't added until a later version. +function! zig#util#has_job(...) abort + " cwd and env parameters to job_start was added in this version. + if a:0 > 0 && a:1 is 1 + return has('job') && has("patch-8.0.0902") + endif + + " job was introduced in 7.4.xxx however there are multiple bug fixes and one + " of the latest is 8.0.0087 which is required for a stable async API. + return has('job') && has("patch-8.0.0087") +endfunction + +let s:env_cache = {} + +" env returns the go environment variable for the given key. Where key can be +" GOARCH, GOOS, GOROOT, etc... It caches the result and returns the cached +" version. +function! zig#util#env(key) abort + let l:key = tolower(a:key) + if has_key(s:env_cache, l:key) + return s:env_cache[l:key] + endif + + if executable('go') + let l:var = call('zig#util#'.l:key, []) + if zig#util#ShellError() != 0 + call zig#util#EchoError(printf("'go env %s' failed", toupper(l:key))) + return '' + endif + else + let l:var = eval("$".toupper(a:key)) + endif + + let s:env_cache[l:key] = l:var + return l:var +endfunction + +" Run a shell command. +" +" It will temporary set the shell to /bin/sh for Unix-like systems if possible, +" so that we always use a standard POSIX-compatible Bourne shell (and not e.g. +" csh, fish, etc.) See #988 and #1276. +function! s:system(cmd, ...) abort + " Preserve original shell and shellredir values + let l:shell = &shell + let l:shellredir = &shellredir + + if !zig#util#IsWin() && executable('/bin/sh') + set shell=/bin/sh shellredir=>%s\ 2>&1 + endif + + try + return call('system', [a:cmd] + a:000) + finally + " Restore original values + let &shell = l:shell + let &shellredir = l:shellredir + endtry +endfunction + +" System runs a shell command "str". Every arguments after "str" is passed to +" stdin. +function! zig#util#System(str, ...) abort + return call('s:system', [a:str] + a:000) +endfunction + +" Exec runs a shell command "cmd", which must be a list, one argument per item. +" Every list entry will be automatically shell-escaped +" Every other argument is passed to stdin. +function! zig#util#Exec(cmd, ...) abort + if len(a:cmd) == 0 + call zig#util#EchoError("zig#util#Exec() called with empty a:cmd") + return ['', 1] + endif + + let l:bin = a:cmd[0] + + if !executable(l:bin) + call zig#util#EchoError(printf("could not find binary '%s'", a:cmd[0])) + return ['', 1] + endif + + return call('s:exec', [a:cmd] + a:000) +endfunction + +function! s:exec(cmd, ...) abort + let l:bin = a:cmd[0] + let l:cmd = zig#util#Shelljoin([l:bin] + a:cmd[1:]) + if zig#util#HasDebug('shell-commands') + call zig#util#EchoInfo('shell command: ' . l:cmd) + endif + + let l:out = call('s:system', [l:cmd] + a:000) + return [l:out, zig#util#ShellError()] +endfunction + +function! zig#util#ShellError() abort + return v:shell_error +endfunction + +" StripPath strips the path's last character if it's a path separator. +" example: '/foo/bar/' -> '/foo/bar' +function! zig#util#StripPathSep(path) abort + let last_char = strlen(a:path) - 1 + if a:path[last_char] == zig#util#PathSep() + return strpart(a:path, 0, last_char) + endif + + return a:path +endfunction + +" StripTrailingSlash strips the trailing slash from the given path list. +" example: ['/foo/bar/'] -> ['/foo/bar'] +function! zig#util#StripTrailingSlash(paths) abort + return map(copy(a:paths), 'zig#util#StripPathSep(v:val)') +endfunction + +" Shelljoin returns a shell-safe string representation of arglist. The +" {special} argument of shellescape() may optionally be passed. +function! zig#util#Shelljoin(arglist, ...) abort + try + let ssl_save = &shellslash + set noshellslash + if a:0 + return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ') + endif + + return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ') + finally + let &shellslash = ssl_save + endtry +endfunction + +fu! zig#util#Shellescape(arg) + try + let ssl_save = &shellslash + set noshellslash + return shellescape(a:arg) + finally + let &shellslash = ssl_save + endtry +endf + +" Shelllist returns a shell-safe representation of the items in the given +" arglist. The {special} argument of shellescape() may optionally be passed. +function! zig#util#Shelllist(arglist, ...) abort + try + let ssl_save = &shellslash + set noshellslash + if a:0 + return map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')') + endif + return map(copy(a:arglist), 'shellescape(v:val)') + finally + let &shellslash = ssl_save + endtry +endfunction + +" Returns the byte offset for line and column +function! zig#util#Offset(line, col) abort + if &encoding != 'utf-8' + let sep = zig#util#LineEnding() + let buf = a:line == 1 ? '' : (join(getline(1, a:line-1), sep) . sep) + let buf .= a:col == 1 ? '' : getline('.')[:a:col-2] + return len(iconv(buf, &encoding, 'utf-8')) + endif + return line2byte(a:line) + (a:col-2) +endfunction +" +" Returns the byte offset for the cursor +function! zig#util#OffsetCursor() abort + return zig#util#Offset(line('.'), col('.')) +endfunction + +" Windo is like the built-in :windo, only it returns to the window the command +" was issued from +function! zig#util#Windo(command) abort + let s:currentWindow = winnr() + try + execute "windo " . a:command + finally + execute s:currentWindow. "wincmd w" + unlet s:currentWindow + endtry +endfunction + +" snippetcase converts the given word to given preferred snippet setting type +" case. +function! zig#util#snippetcase(word) abort + let l:snippet_case = zig#config#AddtagsTransform() + if l:snippet_case == "snakecase" + return zig#util#snakecase(a:word) + elseif l:snippet_case == "camelcase" + return zig#util#camelcase(a:word) + else + return a:word " do nothing + endif +endfunction + +" snakecase converts a string to snake case. i.e: FooBar -> foo_bar +" Copied from tpope/vim-abolish +function! zig#util#snakecase(word) abort + let word = substitute(a:word, '::', '/', 'g') + let word = substitute(word, '\(\u\+\)\(\u\l\)', '\1_\2', 'g') + let word = substitute(word, '\(\l\|\d\)\(\u\)', '\1_\2', 'g') + let word = substitute(word, '[.-]', '_', 'g') + let word = tolower(word) + return word +endfunction + +" camelcase converts a string to camel case. e.g. FooBar or foo_bar will become +" fooBar. +" Copied from tpope/vim-abolish. +function! zig#util#camelcase(word) abort + let word = substitute(a:word, '-', '_', 'g') + if word !~# '_' && word =~# '\l' + return substitute(word, '^.', '\l&', '') + else + return substitute(word, '\C\(_\)\=\(.\)', '\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g') + endif +endfunction + +" pascalcase converts a string to 'PascalCase'. e.g. fooBar or foo_bar will +" become FooBar. +function! zig#util#pascalcase(word) abort + let word = zig#util#camelcase(a:word) + return toupper(word[0]) . word[1:] +endfunction + +" Echo a message to the screen and highlight it with the group in a:hi. +" +" The message can be a list or string; every line with be :echomsg'd separately. +function! s:echo(msg, hi) + let l:msg = [] + if type(a:msg) != type([]) + let l:msg = split(a:msg, "\n") + else + let l:msg = a:msg + endif + + " Tabs display as ^I or <09>, so manually expand them. + let l:msg = map(l:msg, 'substitute(v:val, "\t", " ", "")') + + exe 'echohl ' . a:hi + for line in l:msg + echom "zig.vim: " . line + endfor + echohl None +endfunction + +function! zig#util#EchoSuccess(msg) + call s:echo(a:msg, 'Function') +endfunction +function! zig#util#EchoError(msg) + call s:echo(a:msg, 'ErrorMsg') +endfunction +function! zig#util#EchoWarning(msg) + call s:echo(a:msg, 'WarningMsg') +endfunction +function! zig#util#EchoProgress(msg) + redraw + call s:echo(a:msg, 'Identifier') +endfunction +function! zig#util#EchoInfo(msg) + call s:echo(a:msg, 'Debug') +endfunction + +" Get all lines in the buffer as a a list. +function! zig#util#GetLines() + let buf = getline(1, '$') + if &encoding != 'utf-8' + let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') + endif + if &l:fileformat == 'dos' + " XXX: line2byte() depend on 'fileformat' option. + " so if fileformat is 'dos', 'buf' must include '\r'. + let buf = map(buf, 'v:val."\r"') + endif + return buf +endfunction + +" Make a named temporary directory which starts with "prefix". +" +" Unfortunately Vim's tempname() is not portable enough across various systems; +" see: https://github.com/mattn/vim-go/pull/3#discussion_r138084911 +function! zig#util#tempdir(prefix) abort + " See :help tempfile + if zig#util#IsWin() + let l:dirs = [$TMP, $TEMP, 'c:\tmp', 'c:\temp'] + else + let l:dirs = [$TMPDIR, '/tmp', './', $HOME] + endif + + let l:dir = '' + for l:d in dirs + if !empty(l:d) && filewritable(l:d) == 2 + let l:dir = l:d + break + endif + endfor + + if l:dir == '' + call zig#util#EchoError('Unable to find directory to store temporary directory in') + return + endif + + " Not great randomness, but "good enough" for our purpose here. + let l:rnd = sha256(printf('%s%s', localtime(), fnamemodify(bufname(''), ":p"))) + let l:tmp = printf("%s/%s%s", l:dir, a:prefix, l:rnd) + call mkdir(l:tmp, 'p', 0700) + return l:tmp +endfunction + +" Report if the user enabled a debug flag in g:zig_debug. +function! zig#util#HasDebug(flag) + return index(zig#config#Debug(), a:flag) >= 0 +endfunction + +" vim: sw=2 ts=2 et diff --git a/.vim/pack/plugins/start/zig.vim/ftdetect/zig.vim b/.vim/pack/plugins/start/zig.vim/ftdetect/zig.vim new file mode 100644 index 0000000..8b094a1 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/ftdetect/zig.vim @@ -0,0 +1,2 @@ +au BufRead,BufNewFile *.zig set filetype=zig +au BufRead,BufNewFile *.zir set filetype=zir diff --git a/.vim/pack/plugins/start/zig.vim/ftplugin/zig.vim b/.vim/pack/plugins/start/zig.vim/ftplugin/zig.vim new file mode 100644 index 0000000..a35b0c8 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/ftplugin/zig.vim @@ -0,0 +1,47 @@ +" Only do this when not done yet for this buffer +if exists("b:did_ftplugin") + finish +endif + +let b:did_ftplugin = 1 + +let s:cpo_orig = &cpo +set cpo&vim + +" Recomended code style, no tabs and 4-space indentation +setlocal expandtab +setlocal tabstop=8 +setlocal softtabstop=4 +setlocal shiftwidth=4 + +setlocal formatoptions-=t formatoptions+=croql + +setlocal suffixesadd=.zig,.zir +setlocal makeprg=zig\ build + +if has('comments') + setlocal comments=:///,://!,://,:\\\\ + setlocal commentstring=//\ %s +endif + +if has('find_in_path') + let &l:includeexpr='substitute(v:fname, "^([^.])$", "\1.zig", "")' + let &l:include='\v(\@import>|\@cInclude>|^\s*\#\s*include)' +endif + +let &l:define='\v(|||^\s*\#\s*define)' + +if exists("*json_decode") && executable('zig') + silent let s:env = system('zig env') + if v:shell_error == 0 + let &l:path=json_decode(s:env)['std_dir'] . ',' . &l:path + endif + unlet! s:env +endif + +let b:undo_ftplugin = + \ 'setl et< ts< sts< sw< fo< sua< mp< com< cms< inex< inc< pa<' + +let &cpo = s:cpo_orig +unlet s:cpo_orig +" vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab diff --git a/.vim/pack/plugins/start/zig.vim/indent/zig.vim b/.vim/pack/plugins/start/zig.vim/indent/zig.vim new file mode 100644 index 0000000..560edf4 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/indent/zig.vim @@ -0,0 +1,76 @@ +" indent/zig.vim + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +if (!has("cindent") || !has("eval")) + finish +endif + +setlocal cindent + +" L0 -> 0 indent for jump labels (i.e. case statement in c). +" j1 -> indenting for "javascript object declarations" +" J1 -> see j1 +" w1 -> starting a new line with `(` at the same indent as `(` +" m1 -> if `)` starts a line, match its indent with the first char of its +" matching `(` line +" (s -> use one indent, when starting a new line after a trailing `(` +setlocal cinoptions=L0,m1,(s,j1,J1,l1 + +" cinkeys: controls what keys trigger indent formatting +" 0{ -> { +" 0} -> } +" 0) -> ) +" 0] -> ] +" !^F -> make CTRL-F (^F) reindent the current line when typed +" o -> when or `o` is used +" O -> when the `O` command is used +setlocal cinkeys=0{,0},0),0],!^F,o,O + +setlocal indentexpr=GetZigIndent(v:lnum) + +function! GetZigIndent(lnum) + let curretLineNum = a:lnum + let currentLine = getline(a:lnum) + + " cindent doesn't handle multi-line strings properly, so force no indent + if currentLine =~ '^\s*\\\\.*' + return -1 + endif + + let prevLineNum = prevnonblank(a:lnum-1) + let prevLine = getline(prevLineNum) + + " for lines that look line + " }, + " }; + " try treat them the same as a } + if prevLine =~ '\v^\s*},$' + if currentLine =~ '\v^\s*};$' || currentLine =~ '\v^\s*}$' + return indent(prevLineNum) - 4 + endif + return indent(prevLineNum-1) - 4 + endif + if currentLine =~ '\v^\s*},$' + return indent(prevLineNum) - 4 + endif + if currentLine =~ '\v^\s*};$' + return indent(prevLineNum) - 4 + endif + + + " cindent doesn't handle this case correctly: + " switch (1): { + " 1 => true, + " ~ + " ^---- indents to here + if prevLine =~ '.*=>.*,$' && currentLine !~ '.*}$' + return indent(prevLineNum) + endif + + return cindent(a:lnum) +endfunction diff --git a/.vim/pack/plugins/start/zig.vim/plugin/zig.vim b/.vim/pack/plugins/start/zig.vim/plugin/zig.vim new file mode 100644 index 0000000..b50f223 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/plugin/zig.vim @@ -0,0 +1,17 @@ +if exists("g:zig_loaded") + finish +endif +let g:zig_loaded = 1 + +function! s:fmt_autosave() + if get(g:, "zig_fmt_autosave", 1) + call zig#fmt#Format() + endif +endfunction + +augroup vim-zig + autocmd! + autocmd BufWritePre *.zig call s:fmt_autosave() +augroup end + +" vim: sw=2 ts=2 et diff --git a/.vim/pack/plugins/start/zig.vim/syntax/zig.vim b/.vim/pack/plugins/start/zig.vim/syntax/zig.vim new file mode 100644 index 0000000..da07f63 --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/syntax/zig.vim @@ -0,0 +1,104 @@ +" Vim syntax file +" Language: Zig +" Maintainer: Andrew Kelley +" Latest Revision: 03 August 2016 + +if exists("b:current_syntax") + finish +endif +let b:current_syntax = "zig" + +syn keyword zigStorage const var extern packed export pub noalias inline noinline comptime callconv volatile allowzero align linksection threadlocal anytype +syn keyword zigStructure struct enum union error opaque +syn keyword zigStatement break return continue asm defer errdefer unreachable try catch async nosuspend await suspend resume +syn keyword zigConditional if else switch and or orelse +syn keyword zigRepeat while for + +syn keyword zigConstant null undefined +syn keyword zigKeyword fn usingnamespace test +syn keyword zigType bool f16 f32 f64 f128 void noreturn type anyerror anyframe +syn keyword zigType i0 u0 isize usize comptime_int comptime_float +syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_longdouble c_void + +syn keyword zigBoolean true false + +syn match zigType "\v<[iu][1-9]\d*>" + +syn match zigOperator display "\V\[-+/*=^&?|!><%~]" +syn match zigArrowCharacter display "\V->" + +syn match zigBuiltinFn "\v\@(addWithOverflow|as|atomicLoad|atomicStore|bitCast|breakpoint)>" +syn match zigBuiltinFn "\v\@(alignCast|alignOf|cDefine|cImport|cInclude)>" +syn match zigBuiltinFn "\v\@(cUndef|canImplicitCast|clz|cmpxchgWeak|cmpxchgStrong|compileError)>" +syn match zigBuiltinFn "\v\@(compileLog|ctz|popCount|divExact|divFloor|divTrunc)>" +syn match zigBuiltinFn "\v\@(embedFile|export|tagName|TagType|errorName|call)>" +syn match zigBuiltinFn "\v\@(errorReturnTrace|fence|fieldParentPtr|field|unionInit)>" +syn match zigBuiltinFn "\v\@(frameAddress|import|newStackCall|asyncCall|intToPtr)>" +syn match zigBuiltinFn "\v\@(memcpy|memset|mod|mulWithOverflow|splat|src)>" +syn match zigBuiltinFn "\v\@(bitOffsetOf|byteOffsetOf|OpaqueType|panic|ptrCast)>" +syn match zigBuiltinFn "\v\@(ptrToInt|rem|returnAddress|setCold|Type|shuffle|reduce)>" +syn match zigBuiltinFn "\v\@(setRuntimeSafety|setEvalBranchQuota|setFloatMode)>" +syn match zigBuiltinFn "\v\@(setGlobalLinkage|setGlobalSection|shlExact|This|hasDecl|hasField)>" +syn match zigBuiltinFn "\v\@(shlWithOverflow|shrExact|sizeOf|bitSizeOf|sqrt|byteSwap|subWithOverflow|intCast|floatCast|intToFloat|floatToInt|boolToInt|errSetCast)>" +syn match zigBuiltinFn "\v\@(truncate|typeInfo|typeName|TypeOf|atomicRmw|bytesToSlice|sliceToBytes)>" +syn match zigBuiltinFn "\v\@(intToError|errorToInt|intToEnum|enumToInt|setAlignStack|frame|Frame|frameSize|bitReverse|Vector)>" +syn match zigBuiltinFn "\v\@(sin|cos|exp|exp2|log|log2|log10|fabs|floor|ceil|trunc|round)>" + +" 12_34 (. but not ..)? (12_34)? (exponent 12_34)? +syn match zigDecNumber display "\v<\d%(_?\d)*%(\.\.@!)?%(\d%(_?\d)*)?%([eE][+-]?\d%(_?\d)*)?" +syn match zigHexNumber display "\v<0x\x%(_?\x)*%(\.\.@!)?%(\x%(_?\x)*)?%([pP][+-]?\d%(_?\d)*)?" +syn match zigOctNumber display "\v<0o\o%(_?\o)*" +syn match zigBinNumber display "\v<0b[01]%(_?[01])*" + +syn match zigCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/ +syn match zigCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/ +syn match zigCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=zigEscape,zigEscapeError,zigCharacterInvalid,zigCharacterInvalidUnicode +syn match zigCharacter /'\([^\\]\|\\\(.\|x\x\{2}\|u\x\{4}\|U\x\{6}\)\)'/ contains=zigEscape,zigEscapeUnicode,zigEscapeError,zigCharacterInvalid + +syn region zigBlock start="{" end="}" transparent fold + +syn region zigCommentLine start="//" end="$" contains=zigTodo,@Spell +syn region zigCommentLineDoc start="//[/!]/\@!" end="$" contains=zigTodo,@Spell + +" TODO: match only the first '\\' within the zigMultilineString as zigMultilineStringPrefix +syn match zigMultilineStringPrefix display contained /c\?\\\\/ +syn region zigMultilineString start="c\?\\\\" end="$" contains=zigMultilineStringPrefix + +syn keyword zigTodo contained TODO + +syn match zigEscapeError display contained /\\./ +syn match zigEscape display contained /\\\([nrt\\'"]\|x\x\{2}\)/ +syn match zigEscapeUnicode display contained /\\\(u\x\{4}\|U\x\{6}\)/ +syn region zigString start=+c\?"+ skip=+\\\\\|\\"+ end=+"+ oneline contains=zigEscape,zigEscapeUnicode,zigEscapeError,@Spell + +hi def link zigDecNumber zigNumber +hi def link zigHexNumber zigNumber +hi def link zigOctNumber zigNumber +hi def link zigBinNumber zigNumber + +hi def link zigBuiltinFn Function +hi def link zigKeyword Keyword +hi def link zigType Type +hi def link zigCommentLine Comment +hi def link zigCommentLineDoc SpecialComment +hi def link zigTodo Todo +hi def link zigString String +hi def link zigMultilineString String +hi def link zigMultilineStringContent String +hi def link zigMultilineStringPrefix Comment +hi def link zigCharacterInvalid Error +hi def link zigCharacterInvalidUnicode zigCharacterInvalid +hi def link zigCharacter Character +hi def link zigEscape Special +hi def link zigEscapeUnicode zigEscape +hi def link zigEscapeError Error +hi def link zigBoolean Boolean +hi def link zigConstant Constant +hi def link zigNumber Number +hi def link zigArrowCharacter zigOperator +hi def link zigOperator Operator +hi def link zigStorage StorageClass +hi def link zigStructure Structure +hi def link zigStatement Statement +hi def link zigConditional Conditional +hi def link zigRepeat Repeat diff --git a/.vim/pack/plugins/start/zig.vim/syntax/zir.vim b/.vim/pack/plugins/start/zig.vim/syntax/zir.vim new file mode 100644 index 0000000..d3c095d --- /dev/null +++ b/.vim/pack/plugins/start/zig.vim/syntax/zir.vim @@ -0,0 +1,50 @@ +" Vim syntax file +" Language: Zir +" Maintainer: Andrew Kelley +" Latest Revision: 00 April 2020 + +if exists("b:current_syntax") + finish +endif +let b:current_syntax = "zir" + +syn region zirCommentLine start=";" end="$" contains=zirTodo,@Spell + +syn region zirBlock start="{" end="}" transparent fold + +syn keyword zirKeyword primitive fntype int str as ptrtoint fieldptr deref asm unreachable export ref fn + +syn keyword zirTodo contained TODO + +syn region zirString start=+c\?"+ skip=+\\\\\|\\"+ end=+"+ oneline contains=zirEscape,zirEscapeUnicode,zirEscapeError,@Spell + +syn match zirEscapeError display contained /\\./ +syn match zirEscape display contained /\\\([nrt\\'"]\|x\x\{2}\)/ +syn match zirEscapeUnicode display contained /\\\(u\x\{4}\|U\x\{6}\)/ + +syn match zirDecNumber display "\<[0-9]\+\%(.[0-9]\+\)\=\%([eE][+-]\?[0-9]\+\)\=" +syn match zirHexNumber display "\<0x[a-fA-F0-9]\+\%([a-fA-F0-9]\+\%([pP][+-]\?[0-9]\+\)\?\)\=" +syn match zirOctNumber display "\<0o[0-7]\+" +syn match zirBinNumber display "\<0b[01]\+\%(.[01]\+\%([eE][+-]\?[0-9]\+\)\?\)\=" + +syn match zirGlobal display "[^a-zA-Z0-9_]\?\zs@[a-zA-Z0-9_]\+" +syn match zirLocal display "[^a-zA-Z0-9_]\?\zs%[a-zA-Z0-9_]\+" + +hi def link zirCommentLine Comment +hi def link zirTodo Todo + +hi def link zirKeyword Keyword + +hi def link zirString Constant + +hi def link zirEscape Special +hi def link zirEscapeUnicode zirEscape +hi def link zirEscapeError Error + +hi def link zirDecNumber Constant +hi def link zirHexNumber Constant +hi def link zirOctNumber Constant +hi def link zirBinNumber Constant + +hi def link zirGlobal Identifier +hi def link zirLocal Identifier