├── ftdetect └── zig.vim ├── compiler ├── zig_test.vim ├── zig_build_exe.vim ├── zig_build.vim └── zig.vim ├── LICENSE ├── README.md ├── ftplugin └── zig.vim ├── indent └── zig.vim ├── autoload └── zig │ └── fmt.vim └── syntax └── zig.vim /ftdetect/zig.vim: -------------------------------------------------------------------------------- 1 | au BufRead,BufNewFile *.zig setfiletype zig 2 | au BufRead,BufNewFile *.zon setfiletype zig 3 | -------------------------------------------------------------------------------- /compiler/zig_test.vim: -------------------------------------------------------------------------------- 1 | " Vim compiler file 2 | " Compiler: Zig Compiler (zig test) 3 | 4 | if exists('current_compiler') 5 | finish 6 | endif 7 | runtime compiler/zig.vim 8 | let current_compiler = 'zig_test' 9 | 10 | let s:save_cpo = &cpo 11 | set cpo&vim 12 | 13 | 14 | if exists(':CompilerSet') != 2 15 | command -nargs=* CompilerSet setlocal 16 | endif 17 | 18 | if has('patch-7.4.191') 19 | CompilerSet makeprg=zig\ test\ \%:S\ \$* 20 | else 21 | CompilerSet makeprg=zig\ test\ \"%\"\ \$* 22 | endif 23 | 24 | let &cpo = s:save_cpo 25 | unlet s:save_cpo 26 | " vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab 27 | -------------------------------------------------------------------------------- /compiler/zig_build_exe.vim: -------------------------------------------------------------------------------- 1 | " Vim compiler file 2 | " Compiler: Zig Compiler (zig build-exe) 3 | 4 | if exists('current_compiler') 5 | finish 6 | endif 7 | runtime compiler/zig.vim 8 | let current_compiler = 'zig_build_exe' 9 | 10 | let s:save_cpo = &cpo 11 | set cpo&vim 12 | 13 | 14 | if exists(':CompilerSet') != 2 15 | command -nargs=* CompilerSet setlocal 16 | endif 17 | 18 | if has('patch-7.4.191') 19 | CompilerSet makeprg=zig\ build-exe\ \%:S\ \$* 20 | else 21 | CompilerSet makeprg=zig\ build-exe\ \"%\"\ \$* 22 | endif 23 | 24 | let &cpo = s:save_cpo 25 | unlet s:save_cpo 26 | " vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab 27 | -------------------------------------------------------------------------------- /compiler/zig_build.vim: -------------------------------------------------------------------------------- 1 | " Vim compiler file 2 | " Compiler: Zig Compiler (zig build) 3 | 4 | if exists('current_compiler') 5 | finish 6 | endif 7 | runtime compiler/zig.vim 8 | let current_compiler = 'zig_build' 9 | 10 | let s:save_cpo = &cpo 11 | set cpo&vim 12 | 13 | 14 | if exists(':CompilerSet') != 2 15 | command -nargs=* CompilerSet setlocal 16 | endif 17 | 18 | if exists('g:zig_build_makeprg_params') 19 | execute 'CompilerSet makeprg=zig\ build\ '.escape(g:zig_build_makeprg_params, ' \|"').'\ $*' 20 | else 21 | CompilerSet makeprg=zig\ build\ $* 22 | endif 23 | 24 | " TODO: anything to add to errorformat for zig build specifically? 25 | 26 | let &cpo = s:save_cpo 27 | unlet s:save_cpo 28 | " vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab 29 | -------------------------------------------------------------------------------- /compiler/zig.vim: -------------------------------------------------------------------------------- 1 | " Vim compiler file 2 | " Compiler: Zig Compiler 3 | " For bugs, patches and license go to https://github.com/ziglang/zig.vim 4 | 5 | if exists("current_compiler") 6 | finish 7 | endif 8 | let current_compiler = "zig" 9 | 10 | let s:save_cpo = &cpo 11 | set cpo&vim 12 | 13 | if exists(":CompilerSet") != 2 14 | command -nargs=* CompilerSet setlocal 15 | endif 16 | 17 | " a subcommand must be provided for the this compiler (test, build-exe, etc) 18 | if has('patch-7.4.191') 19 | CompilerSet makeprg=zig\ $*\ %:S 20 | else 21 | CompilerSet makeprg=zig\ $*\ \"%\" 22 | endif 23 | 24 | " TODO: improve errorformat as needed. 25 | 26 | let &cpo = s:save_cpo 27 | unlet s:save_cpo 28 | " vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (Expat) 2 | 3 | Copyright (c) 2017 Andrew Kelley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zig.vim 2 | 3 | File detection and syntax highlighting for the 4 | [zig](http://ziglang.org/) programming language. 5 | 6 | ## Installation 7 | 8 | ### If using [**vim-plug**](https://github.com/junegunn/vim-plug) (for Vim or Neovim) 9 | * Open vim config 10 | * Write `Plug 'ziglang/zig.vim'` inside the `plug` command: 11 | ```vim 12 | call plug#begin('~/.vim/plugged') 13 | Plug 'ziglang/zig.vim' 14 | call plug#end() 15 | ``` 16 | 17 | * Restart vim / reload vim config 18 | * type `:PlugInstall` 19 | 20 | ### If using **Vim**: 21 | * Use Vim 8 or newer 22 | * `mkdir -p ~/.vim/pack/plugins/start/` 23 | * `cd ~/.vim/pack/plugins/start/` 24 | * `git clone https://github.com/ziglang/zig.vim` 25 | 26 | ### If using **Neovim**: 27 | * `mkdir -p ~/.local/share/nvim/site/pack/plugins/start/` 28 | * `cd ~/.local/share/nvim/site/pack/plugins/start/` 29 | * `git clone https://github.com/ziglang/zig.vim` 30 | 31 | ## Configuration 32 | 33 | This plugin enables automatic code formatting on save by default using 34 | `zig fmt`. To disable it, you can use this configuration in vimrc: 35 | 36 | ``` 37 | let g:zig_fmt_autosave = 0 38 | ``` 39 | 40 | The default compiler which gets used by `:make` (`:help :compiler` for details) 41 | is `zig_build` and it runs `zig build`. The other options are: 42 | * `:compiler zig_test` which runs `zig test` on the current file. 43 | * `:compiler zig_build_exe` which runs `zig build-exe` on the current file. 44 | * `:compiler zig` which requires that a subcommand is passed as an argument 45 | and it runs on the current file. 46 | -------------------------------------------------------------------------------- /ftplugin/zig.vim: -------------------------------------------------------------------------------- 1 | " Only do this when not done yet for this buffer 2 | if exists("b:did_ftplugin") 3 | finish 4 | endif 5 | 6 | let b:did_ftplugin = 1 7 | 8 | let s:cpo_orig = &cpo 9 | set cpo&vim 10 | 11 | compiler zig_build 12 | 13 | " Match Zig builtin fns 14 | setlocal iskeyword+=@-@ 15 | 16 | " Recomended code style, no tabs and 4-space indentation 17 | if get(g:, 'zig_recommended_style', 1) 18 | setlocal expandtab 19 | setlocal softtabstop=4 20 | setlocal shiftwidth=4 21 | endif 22 | 23 | setlocal formatoptions-=t formatoptions+=croql 24 | 25 | setlocal suffixesadd=.zig,.zon 26 | 27 | if has('comments') 28 | setlocal comments=:///,://!,:// 29 | setlocal commentstring=//\ %s 30 | endif 31 | 32 | if has('find_in_path') 33 | let &l:includeexpr='substitute(v:fname, "^([^.])$", "\1.zig", "")' 34 | let &l:include='\v(\@import>|\@cInclude>|^\s*\#\s*include)' 35 | endif 36 | 37 | let &l:define='\v(|||^\s*\#\s*define)' 38 | 39 | if !exists('g:zig_std_dir') && exists('*zon_decode') && executable('zig') 40 | silent let s:env = system('zig env') 41 | if v:shell_error == 0 42 | let g:zig_std_dir = zon_decode(s:env)['std_dir'] 43 | endif 44 | unlet! s:env 45 | endif 46 | 47 | if exists('g:zig_std_dir') 48 | let &l:path = g:zig_std_dir . ',' . &l:path 49 | endif 50 | 51 | let b:undo_ftplugin = 52 | \ 'setl isk< et< ts< sts< sw< fo< sua< mp< com< cms< inex< inc< pa<' 53 | 54 | augroup vim-zig 55 | autocmd! * 56 | autocmd BufWritePre if get(g:, 'zig_fmt_autosave', 1) | call zig#fmt#Format() | endif 57 | augroup END 58 | 59 | let b:undo_ftplugin .= '|au! vim-zig * ' 60 | 61 | let &cpo = s:cpo_orig 62 | unlet s:cpo_orig 63 | " vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab 64 | -------------------------------------------------------------------------------- /indent/zig.vim: -------------------------------------------------------------------------------- 1 | " indent/zig.vim 2 | 3 | " Only load this indent file when no other was loaded. 4 | if exists("b:did_indent") 5 | finish 6 | endif 7 | let b:did_indent = 1 8 | 9 | if (!has("cindent") || !has("eval")) 10 | finish 11 | endif 12 | 13 | setlocal cindent 14 | 15 | " L0 -> 0 indent for jump labels (i.e. case statement in c). 16 | " j1 -> indenting for "javascript object declarations" 17 | " J1 -> see j1 18 | " w1 -> starting a new line with `(` at the same indent as `(` 19 | " m1 -> if `)` starts a line, match its indent with the first char of its 20 | " matching `(` line 21 | " (s -> use one indent, when starting a new line after a trailing `(` 22 | setlocal cinoptions=L0,m1,(s,j1,J1,l1 23 | 24 | " cinkeys: controls what keys trigger indent formatting 25 | " 0{ -> { 26 | " 0} -> } 27 | " 0) -> ) 28 | " 0] -> ] 29 | " !^F -> make CTRL-F (^F) reindent the current line when typed 30 | " o -> when or `o` is used 31 | " O -> when the `O` command is used 32 | setlocal cinkeys=0{,0},0),0],!^F,o,O 33 | 34 | setlocal indentexpr=GetZigIndent(v:lnum) 35 | 36 | let b:undo_indent = "setlocal cindent< cinkeys< cinoptions< indentexpr<" 37 | 38 | function! GetZigIndent(lnum) 39 | let curretLineNum = a:lnum 40 | let currentLine = getline(a:lnum) 41 | 42 | " cindent doesn't handle multi-line strings properly, so force no indent 43 | if currentLine =~ '^\s*\\\\.*' 44 | return -1 45 | endif 46 | 47 | let prevLineNum = prevnonblank(a:lnum-1) 48 | let prevLine = getline(prevLineNum) 49 | 50 | " for lines that look like 51 | " }, 52 | " }; 53 | " try treating them the same as a } 54 | if prevLine =~ '\v^\s*},$' 55 | if currentLine =~ '\v^\s*};$' || currentLine =~ '\v^\s*}$' 56 | return indent(prevLineNum) - 4 57 | endif 58 | return indent(prevLineNum-1) - 4 59 | endif 60 | if currentLine =~ '\v^\s*},$' 61 | return indent(prevLineNum) - 4 62 | endif 63 | if currentLine =~ '\v^\s*};$' 64 | return indent(prevLineNum) - 4 65 | endif 66 | 67 | 68 | " cindent doesn't handle this case correctly: 69 | " switch (1): { 70 | " 1 => true, 71 | " ~ 72 | " ^---- indents to here 73 | if prevLine =~ '.*=>.*,$' && currentLine !~ '.*}$' 74 | return indent(prevLineNum) 75 | endif 76 | 77 | return cindent(a:lnum) 78 | endfunction 79 | -------------------------------------------------------------------------------- /autoload/zig/fmt.vim: -------------------------------------------------------------------------------- 1 | " Adapted from fatih/vim-go: autoload/go/fmt.vim 2 | " 3 | " Copyright 2011 The Go Authors. All rights reserved. 4 | " Use of this source code is governed by a BSD-style 5 | " license that can be found in the LICENSE file. 6 | 7 | function! zig#fmt#Format() abort 8 | " Save cursor position and many other things. 9 | let view = winsaveview() 10 | 11 | if !executable('zig') 12 | echohl Error | echomsg "no zig binary found in PATH" | echohl None 13 | return 14 | endif 15 | 16 | let cmdline = 'zig fmt --stdin --ast-check' 17 | if expand('%:e') is? 'zon' 18 | let cmdline = cmdline . ' --zon' 19 | endif 20 | 21 | let current_buf = bufnr('') 22 | 23 | " The formatted code is output on stdout, the errors go on stderr. 24 | if exists('*systemlist') 25 | silent let out = systemlist(cmdline, current_buf) 26 | else 27 | silent let out = split(system(cmdline, current_buf)) 28 | endif 29 | let err = v:shell_error 30 | 31 | if err == 0 32 | " remove undo point caused via BufWritePre. 33 | try | silent undojoin | catch | endtry 34 | 35 | " Replace the file content with the formatted version. 36 | if exists('*deletebufline') 37 | call deletebufline(current_buf, len(out), line('$')) 38 | else 39 | silent execute ':' . len(out) . ',' . line('$') . ' delete _' 40 | endif 41 | call setline(1, out) 42 | 43 | " No errors detected, close the loclist. 44 | call setloclist(0, [], 'r') 45 | lclose 46 | elseif get(g:, 'zig_fmt_parse_errors', 1) 47 | let errors = s:parse_errors(expand('%'), out) 48 | 49 | call setloclist(0, [], 'r', { 50 | \ 'title': 'Errors', 51 | \ 'items': errors, 52 | \ }) 53 | 54 | let max_win_height = get(g:, 'zig_fmt_max_window_height', 5) 55 | " Prevent the loclist from becoming too long. 56 | let win_height = min([max_win_height, len(errors)]) 57 | " Open the loclist, but only if there's at least one error to show. 58 | execute 'silent! lwindow ' . win_height 59 | endif 60 | 61 | call winrestview(view) 62 | 63 | if err != 0 64 | echohl Error | echomsg "zig fmt returned error" | echohl None 65 | return 66 | endif 67 | 68 | " Run the syntax highlighter on the updated content and recompute the folds if 69 | " needed. 70 | syntax sync fromstart 71 | endfunction 72 | 73 | " parse_errors parses the given errors and returns a list of parsed errors 74 | function! s:parse_errors(filename, lines) abort 75 | " list of errors to be put into location list 76 | let errors = [] 77 | for line in a:lines 78 | let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') 79 | if !empty(tokens) 80 | call add(errors,{ 81 | \"filename": a:filename, 82 | \"lnum": tokens[2], 83 | \"col": tokens[3], 84 | \"text": tokens[4], 85 | \ }) 86 | endif 87 | endfor 88 | 89 | return errors 90 | endfunction 91 | " vim: sw=2 ts=2 et 92 | -------------------------------------------------------------------------------- /syntax/zig.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Zig 3 | " Maintainer: Andrew Kelley 4 | " Latest Revision: 03 August 2016 5 | 6 | if exists("b:current_syntax") 7 | finish 8 | endif 9 | 10 | let s:cpo_save = &cpo 11 | set cpo&vim 12 | 13 | syntax keyword zigBoolean true false 14 | syntax keyword zigNull null 15 | syntax keyword zigType bool void type anytype anyerror anyframe noreturn anyopaque 16 | syntax keyword zigType i0 u0 isize usize comptime_int comptime_float 17 | syntax keyword zigType f16 f32 f64 f80 f128 18 | syntax keyword zigType c_char c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_longdouble 19 | syntax keyword zigConstant undefined unreachable 20 | syntax keyword zigConditional if else switch 21 | syntax keyword zigRepeat while for 22 | syntax keyword zigComparatorWord and or orelse 23 | syntax keyword zigStructure struct enum union error packed opaque 24 | syntax keyword zigException catch error try 25 | syntax keyword zigAccessModifier pub 26 | syntax keyword zigStorageClass addrspace align allowzero callconv extern export linksection threadlocal volatile 27 | syntax keyword zigDummyVariable _ 28 | syntax keyword zigKeyword var const fn test 29 | syntax keyword zigStatement return break continue asm defer errdefer 30 | syntax keyword zigAsync nosuspend suspend resume 31 | syntax keyword zigPreProc comptime inline noalias noinline 32 | syntax keyword zigBuiltinFn @addrSpaceCast @addWithOverflow @alignCast @alignOf @as @atomicLoad @atomicRmw @atomicStore @bitCast @bitOffsetOf @bitSizeOf @branchHint @breakpoint @mulAdd @byteSwap @bitReverse @offsetOf @call @cDefine @cImport @cInclude @clz @cmpxchgStrong @cmpxchgWeak @compileError @compileLog @constCast @ctz @cUndef @cVaArg @cVaCopy @cVaEnd @cVaStart @disableInstrumentation @disableIntrinsics @divExact @divFloor @divTrunc @embedFile @enumFromInt @errorFromInt @errorName @errorReturnTrace @errorCast @export @extern @field @fieldParentPtr @FieldType @floatCast @floatFromInt @frameAddress @hasDecl @hasField @import @inComptime @intCast @intFromBool @intFromEnum @intFromError @intFromFloat @intFromPtr @max @memcpy @memmove @memset @min @wasmMemorySize @wasmMemoryGrow @mod @mulWithOverflow @panic @popCount @prefetch @ptrCast @ptrFromInt @rem @returnAddress @select @setEvalBranchQuota @setFloatMode @setRuntimeSafety @shlExact @shlWithOverflow @shrExact @shuffle @sizeOf @splat @reduce @src @sqrt @sin @cos @tan @exp @exp2 @log @log2 @log10 @abs @floor @ceil @trunc @round @subWithOverflow @tagName @This @trap @truncate @Type @typeInfo @typeName @TypeOf @unionInit @Vector @volatileCast @workGroupId @workGroupSize @workItemId 33 | 34 | syntax match zigType "\v<[iu][1-9]\d*>" 35 | syntax match zigOperator display "\V\[-+/*=^&?|!><%~]" 36 | syntax match zigArrowCharacter display "\V->" 37 | 38 | " 12_34 (. but not ..)? (12_34)? (exponent 12_34)? 39 | syntax match zigDecNumber display "\v<\d%(_?\d)*%(\.\.@!)?%(\d%(_?\d)*)?%([eE][+-]?\d%(_?\d)*)?" 40 | syntax match zigHexNumber display "\v<0x\x%(_?\x)*%(\.\.@!)?%(\x%(_?\x)*)?%([pP][+-]?\d%(_?\d)*)?" 41 | syntax match zigOctNumber display "\v<0o\o%(_?\o)*" 42 | syntax match zigBinNumber display "\v<0b[01]%(_?[01])*" 43 | 44 | syntax match zigCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/ 45 | syntax match zigCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/ 46 | syntax match zigCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=zigEscape,zigEscapeError,zigCharacterInvalid,zigCharacterInvalidUnicode 47 | syntax match zigCharacter /'\([^\\]\|\\\([nrt\\'"]\|x\x\{2}\|u{\x\+}\)\)'/ contains=zigEscape,zigEscapeError,zigCharacterInvalid 48 | 49 | syntax region zigBlock start="{" end="}" transparent fold 50 | 51 | syntax region zigCommentLine start="//" end="$" contains=zigTodo,@Spell 52 | syntax region zigCommentLineDoc start="//[/!]/\@!" end="$" contains=zigTodo,@Spell 53 | 54 | syntax match zigMultilineStringPrefix /c\?\\\\/ contained containedin=zigMultilineString 55 | syntax region zigMultilineString matchgroup=zigMultilineStringDelimiter start="c\?\\\\" end="$" contains=zigMultilineStringPrefix display 56 | 57 | syntax keyword zigTodo contained TODO 58 | 59 | syntax region zigString matchgroup=zigStringDelimiter start=+c\?"+ skip=+\\\\\|\\"+ end=+"+ oneline contains=zigEscape,zigEscapeError,@Spell 60 | syntax match zigEscapeError display contained /\\./ 61 | syntax match zigEscape display contained /\\\([nrt\\'"]\|x\x\{2}\|u{\x\+}\)/ 62 | 63 | highlight default link zigDecNumber zigNumber 64 | highlight default link zigHexNumber zigNumber 65 | highlight default link zigOctNumber zigNumber 66 | highlight default link zigBinNumber zigNumber 67 | 68 | highlight default link zigBuiltinFn Function 69 | highlight default link zigKeyword Keyword 70 | highlight default link zigType Type 71 | highlight default link zigCommentLine Comment 72 | highlight default link zigCommentLineDoc Comment 73 | highlight default link zigDummyVariable Comment 74 | highlight default link zigTodo Todo 75 | highlight default link zigString String 76 | highlight default link zigStringDelimiter String 77 | highlight default link zigMultilineString String 78 | highlight default link zigMultilineStringContent String 79 | highlight default link zigMultilineStringPrefix String 80 | highlight default link zigMultilineStringDelimiter Delimiter 81 | highlight default link zigCharacterInvalid Error 82 | highlight default link zigCharacterInvalidUnicode zigCharacterInvalid 83 | highlight default link zigCharacter Character 84 | highlight default link zigEscape Special 85 | highlight default link zigEscapeError Error 86 | highlight default link zigBoolean Boolean 87 | highlight default link zigNull Constant 88 | highlight default link zigConstant Constant 89 | highlight default link zigNumber Number 90 | highlight default link zigArrowCharacter zigOperator 91 | highlight default link zigOperator Operator 92 | highlight default link zigStructure Structure 93 | highlight default link zigStatement Statement 94 | highlight default link zigConditional Conditional 95 | highlight default link zigComparatorWord zigStatement 96 | highlight default link zigRepeat Repeat 97 | highlight default link zigSpecial Special 98 | highlight default link zigAccessModifier StorageClass 99 | highlight default link zigStorageClass StorageClass 100 | highlight default link zigAsync Keyword 101 | highlight default link zigPreProc PreProc 102 | highlight default link zigException Exception 103 | 104 | let b:current_syntax = "zig" 105 | 106 | let &cpo = s:cpo_save 107 | unlet! s:cpo_save 108 | --------------------------------------------------------------------------------