" Author: Charles Pascoe " License: MIT (see LICENSE) " Copyright: 2022 Charles Pascoe " Clear any existing syntax first syntax clear if !exists('main_syntax') if exists("b:current_syntax") && !get(g:, "go_highlight_override_existing_syntax", 1) finish endif let b:__vim_go_syntax = 1 endif syntax clear syntax case match syntax sync fromstart " Define 'iskeyword' to include valid UTF-8 multibyte characters, some of which " are technically supported for identifiers. " TODO: Check UTF-16 syntax iskeyword @,48-57,_,192-255 " TODO: Check performance of lookbehinds " TODO: Check correct use of 'skipempty' " Struct and Interface need 'extend' so that simple matches (e.g. /struct {/) " can contain complex nested types by extending the parent match. No other types " should use extend " Some things use 'contains=TOP,@Spell' to allow them to behave predictably when " they are nested within a region with special syntax elements (e.g. " goVarDeclGroup and goConstDeclGroup) or when imported into other syntaxes. " The '@Spell' is required to disable spelling in these items. Only a handful " of things should use 'transparent'. " Config Utils {{{ let s:cleanup = [] com! -nargs=* GoDeferCleanup call add(s:cleanup, ) GoDeferCleanup delcom GoDeferCleanup fun s:Cleanup() for l:cmd in s:cleanup exec l:cmd endfor endfun fun s:getconfig(keys, default) if len(a:keys) == 0 return a:default else return get(g:, a:keys[0], s:getconfig(a:keys[1:], a:default)) endif endfun fun s:HiConfig(group, option_names, opts={}) " Most syntax is highlighted by default, unless turned off by the user let l:opt = s:getconfig(a:option_names, get(a:opts, 'default', 1)) let l:cmd = '' if type(l:opt) == v:t_string if l:opt =~ '^[[:alnum:]]\+$' exec 'hi link '.a:group.' '.l:opt else exec 'hi '.a:group.' '.l:opt endif return 1 elseif !l:opt exec 'hi link '.a:group.' '.get(a:opts, 'offgroup', 'NONE') endif return l:opt endfun if get(g:, 'go_highlight_string_spellcheck', 1) syntax cluster goStringSpell contains=@Spell endif if get(g:, 'go_highlight_comment_spellcheck', 1) syntax cluster goCommentSpell contains=@Spell endif " TODO: Rethink this approach (use string/array approach) if s:getconfig(['go_fold_function_blocks', 'go_syntax_fold'], 1) com! -nargs=* GoFoldFunc fold else com! -nargs=* GoFoldFunc endif GoDeferCleanup delcom GoFoldFunc if s:getconfig(['go_fold_struct_blocks', 'go_syntax_fold'], 1) com! -nargs=* GoFoldStruct fold else com! -nargs=* GoFoldStruct endif GoDeferCleanup delcom GoFoldStruct if s:getconfig(['go_fold_interface_blocks', 'go_syntax_fold'], 1) com! -nargs=* GoFoldInterface fold else com! -nargs=* GoFoldInterface endif GoDeferCleanup delcom GoFoldInterface if s:getconfig(['go_fold_decl_blocks', 'go_syntax_fold'], 1) com! -nargs=* GoFoldDecl fold else com! -nargs=* GoFoldDecl endif GoDeferCleanup delcom GoFoldDecl " }}} Config Utils " Misc {{{ " Two top-level clusters to allow regions to specify what syntax they can " contain " NOTE: goIota technically shouldn't be here (it should only be a part of a " const declaration group), but trying to get it to appear only in " goConstDeclGroup would require compromising the performance of the current " implementation or duplicating goExpr just for goConstDeclGroup. syntax cluster goExpr contains=@goLiteral,goForRange,goDotExpr,goFuncLiteral,goCommaExpr,goOperator,goWordStart,goParenBlock,goBracketBlock,goComment,goIota syntax cluster goStatement contains=@goExpr,@goFlowControl,goReturn,goSemicolon,goBraceBlock,goStatementStart,goConstDecl,goVarDecl,goTypeDecl,goKeywords " 'goWordStart' reduces the number of times each of the 'nextgroups' is checked, " but also prevents 'goImportedPackages' (a keyword syntax element) from " overriding matches (e.g. in 'goStructLiteralField'). syntax match goWordStart /\<\ze\K/ contained nextgroup=goStructLiteral,goFuncCall,goBuiltins,goMakeBuiltin,goNewBuiltin,goImportedPackages " 'goDotExpr' matches a dot that is found as a part of an expression, whereas " 'goDot' is used to highlight a dot in non-expression contexts (e.g. the dot " between a package and a type). 'goDotExpr' significantly improves the " performance of searching for fields and type assertions. syntax match goDot /\./ contained syntax match goDotExpr /\./ nextgroup=@goDotExpr skipwhite skipnl " The cluster of items that could follow a dot in an expression syntax cluster goDotExpr contains=goFuncCall,goStructLiteral,goTypeAssertion,goField,goDotComment " goDotComment is identical to goComment, except it doesn't break field " highlighting across multiple lines, e.g.: " " foo.bar. " baz. " // This is goDotComment instead of a goComment " blah " " Both 'baz' and 'blah' are correctly highlighted as fields syntax region goDotComment start=+//+ end=+$+ contained contains=@goCommentSpell,goCommentTodo keepend skipwhite skipnl nextgroup=@goDotExpr syntax region goDotComment start=+/\*+ end=+\*/+ contained contains=@goCommentSpell,goCommentTodo keepend skipwhite skipnl nextgroup=@goDotExpr syntax match goField /\K\k*/ contained " TODO: Only valid operators? syntax match goAssign /=/ skipwhite nextgroup=@goExpr syntax match goOperator /[-+*/!:=%&^<>|~]\+/ skipwhite nextgroup=@goExpr syntax match goCommaExpr /,/ skipwhite skipnl nextgroup=@goExpr syntax match goComma /,/ contained syntax match goSemicolon /;/ syntax keyword goUnderscore _ hi link goField Identifier hi link goLabel Label hi link goOperator Operator hi link goAssign goOperator hi link goDot goOperator hi link goComma Delimiter hi link goCommaExpr goComma hi link goSemicolon Delimiter hi link goUnderscore Special hi link goDotExpr goDot hi link goDotComment goComment call s:HiConfig('goField', ['go_highlight_fields'], #{default: 1}) call s:HiConfig('goLabel', ['go_highlight_labels']) call s:HiConfig('goOperator', ['go_highlight_operators']) call s:HiConfig('goDot', ['go_highlight_dot']) call s:HiConfig('goComma', ['go_highlight_comma'], #{default: 1}) call s:HiConfig('goSemicolon', ['go_highlight_semicolon'], #{default: 1}) " }}} Misc " Comments {{{ syntax region goComment start=+//+ end=+$+ contains=@goCommentSpell,goCommentTodo,goDirectiveComment keepend syntax region goComment start=+/\*+ end=+\*/+ contains=@goCommentSpell,goCommentTodo keepend syntax keyword goCommentTodo contained TODO FIXME XXX TBD NOTE syntax region goDirectiveComment start=+//\(line \|extern \| export\|[a-z0-9]\+:[a-z0-9]\+\)+ end=+$+ contained hi link goComment Comment hi link goCommentTodo Todo hi link goDirectiveComment PreProc call s:HiConfig('goGenerateComment', ['go_highlight_generate_tags'], #{offgroup: 'goComment'}) " }}} Comments " Literals {{{ syntax cluster goLiteral contains=goString,goRawString,goInvalidRuneLiteral,goNumberLeader,goBooleanTrue,goBooleanFalse,goNil,goSliceOrArrayLiteral,goPrimitiveTypes,goStructType,goInterfaceType,goMapLiteral,goSliceOrArrayLiteral " Strings syntax region goString matchgroup=goStringEnds start='"' skip=/\\\\\|\\"/ end='"\|$' oneline contains=@goStringSpell,goStringEscape,goDoubleQuoteEscape,goStringFormat syntax match goStringEscape /\v\\%(\o{3}|x\x{2}|u\x{4}|U\x{8}|[abfnrtv\\"])/ contained syntax match goStringFormat /\v\%%(\%|[-+# 0]*%([1-9]\d*|%(\[\d+\])?\*)?%(\.%(\d+|%(\[\d+\])?\*)?)?%(\[\d+\])?[EFGOTUXbcdefgopqstwvxf])/ contained contains=goStringFormatInvalidIndex if s:getconfig(['go_highlight_format_string_errors'], 0) syntax match goStringFormatInvalidIndex /\[0\]/ contained hi link goStringFormatInvalidIndex Error endif " 'goInvalidRuneLiteral' is a loose match for all single-quote sequences; they " are highlighted as errors. If they contain a valid 'goRuneLiteral' or the " cursor is present at the end, then the 'goRuneLiteral' highlighting will " override the 'goInvalidRuneLiteral' highlighting and thus look like a string. syntax region goInvalidRuneLiteral start=+'+ skip=+\\.+ end=+'+ keepend oneline contains=goRuneLiteral syntax match goRuneLiteral /\v'%(.*%#|[^\\]|\\%(\o{3}|x\x{2}|u\x{4}|U\x{8}|[abfnrtv\\']))'/ contained contains=goRuneLiteralEscape syntax match goRuneLiteralEscape /\v\\%(\o{3}|x\x{2}|u\x{4}|U\x{8}|[abfnrtv\\'])/ contained syntax region goRawString matchgroup=goRawStringEnds start='`' end='`' keepend " Numbers " 'goNumberZeroLeader' searches for a digit so that the various number patterns " don't have to, improving match performance syntax match goNumberLeader /\ze\<[0-9]/ nextgroup=goNumber,goNumberTypeBinary,goNumberTypeOctal,goNumberTypeHex syntax match goNumberLeader /\ze\.[0-9]/ nextgroup=goNumber " TODO: Highlight all forms of invalid number formatting? E.g. underscores in " certain places " TODO: Highlight floats differently syntax match goNumber /\v<[0-9][0-9_]*%(\.[0-9_]*)?%([eE][-+]?[0-9][0-9_]*)?i?/ contained contains=goNumberDecimalExp syntax match goNumber /\v\.[0-9][0-9_]*%([eE][-+]?[0-9][0-9_]*)?i?/ contained contains=goNumberDecimalExp syntax match goNumberTypeBinary /\c0b/ contained nextgroup=goNumberBinary syntax match goNumberBinary /[01_]\+i\?/ contained syntax match goNumberTypeOctal /\c0o/ contained nextgroup=goNumberOctal syntax match goNumberOctal /[0-7_]\+i\?/ contained syntax match goNumberTypeHex /\c0x/ contained nextgroup=goNumberHex syntax match goNumberHex /\v\c[0-9a-f_]*%(\.[0-9a-f_]*)?%([pP][-+]?[0-9a-f][0-9a-f_]*)?i?/ contained contains=goNumberHexExp syntax match goNumberSpecialChar /[_i]/ contained containedin=goNumber,goNumberBinary,goNumberOctal,goNumberHex syntax match goNumberError /_\{2,\}/ contained containedin=goNumber,goNumberBinary,goNumberOctal,goNumberHex " Exponent markers syntax match goNumberDecimalExp /\ce/ contained syntax match goNumberHexExp /\cp/ contained " Other syntax keyword goBooleanTrue true syntax keyword goBooleanFalse false syntax keyword goNil nil " Highlighting hi link goString String hi link goStringEnds goString hi link goStringEscape SpecialChar hi link goStringFormat SpecialChar hi link goInvalidRuneLiteral Error hi link goRuneLiteral Character hi link goRuneLiteralEscape goStringFormat hi link goRawString String hi link goRawStringEnds goRawString hi link goNumber Number hi link goNumberBinary goNumber hi link goNumberOctal goNumber hi link goNumberHex goNumber hi link goNumberType SpecialChar hi link goNumberTypeBinary goNumberType hi link goNumberTypeOctal goNumberType hi link goNumberTypeHex goNumberType hi link goNumberError Error hi link goNumberDecimalExp SpecialChar hi link goNumberHexExp goNumberDecimalExp hi link goNumberSpecialChar SpecialChar hi link goBooleanTrue Boolean hi link goBooleanFalse Boolean hi link goNil Constant call s:HiConfig('goStringFormat', ['go_highlight_format_strings'], #{offgroup: 'goString'}) call s:HiConfig('goInvalidRuneLiteral', ['go_highlight_rune_literal_error'], #{offgroup: 'goRuneLiteral'}) " TODO: Config for highlighting special chars in numbers " }}} Literals " Simple Blocks {{{ syntax region goBracketBlock matchgroup=goBrackets start='\[' end='\]' transparent extend syntax region goParenBlock matchgroup=goParens start='(' end=')' transparent extend syntax region goBraceBlock matchgroup=goBraces start='{' end='}' transparent extend hi link goBraces Delimiter hi link goBrackets Delimiter hi link goParens Delimiter call s:HiConfig('goBraces', ['go_highlight_braces']) call s:HiConfig('goBrackets', ['go_highlight_brackets']) call s:HiConfig('goParens', ['go_highlight_parens']) " }}} Simple Blocks " Constants and Variables {{{ " TODO Slice/map assignment? syntax match goVarAssign /\<\K\k*\%(\.\K\k*\)*\%(\s*,\s*\%(\K\k*\%(\.\K\k*\)*\)\?\)*\ze\s*\%(<<\|>>\|&^\|[-+*/%&|^]\)\?=[^=]/ contained contains=goComma,goUnderscore,goVarStructAssign skipwhite nextgroup=goOperator syntax match goShortVarDecl /\<\K\k*\%(\s*,\s*\%(\K\k*\)\?\)*\ze\s*:=/ contained contains=goComma,goUnderscore skipwhite nextgroup=goOperator syntax match goVarStructAssign /\<\K\k*\%(\.\K\k*\)\+/ contained contains=goDotExpr " TODO: Should these be skipempty instead of skipnl? syntax keyword goConstDecl const skipwhite skipnl nextgroup=goVarIdentifier,goConstDeclGroup syntax keyword goVarDecl var skipwhite skipnl nextgroup=goVarIdentifier,goVarDeclGroup " TODO: Remove these once you're certain goVarGroupIdentifier is not needed " syntax region goVarDeclGroup matchgroup=goVarDeclParens start='(' end=')' contained contains=@goExpr,goComment,goSemicolon,goVarGroupIdentifier " syntax region goConstDeclGroup matchgroup=goConstDeclParens start='(' end=')' contained contains=@goExpr,goComment,goSemicolon,goVarGroupIdentifier,goIota GoFoldDecl syntax region goVarDeclGroup matchgroup=goVarDeclParens start='(' end=')' contained contains=@goExpr,goSemicolon,goVarIdentifier GoFoldDecl syntax region goConstDeclGroup matchgroup=goConstDeclParens start='(' end=')' contained contains=@goExpr,goSemicolon,goVarIdentifier " TODO: Is it worth supporting comments in goVarComma?? syntax match goVarIdentifier /\<\K\k*/ contained skipwhite nextgroup=goVarComma,@goType syntax match goVarComma /,/ contained skipwhite skipnl nextgroup=goVarIdentifier " TODO: Remove these once you're certain goVarGroupIdentifier is not needed " " goVarGroupIdentifier finds positions inside a var/const declaration group " " (e.g. 'const (...)') that may be followed by an identifier. Prevents " " goVarIdentifier from matching in the wrong places. " syntax match goVarGroupIdentifier /^\ze\s/ contained nextgroup=goVarIdentifier skipwhite " syntax match goVarGroupIdentifier /[(;]\@1<=\ze\s/ contained nextgroup=goVarIdentifier skipwhite " syntax match goVarGroupIdentifier /[(;]\@1<=\ze\<\K/ contained nextgroup=goVarIdentifier syntax keyword goIota iota contained hi link goConstDecl Statement hi link goVarDecl Statement hi link goConstDeclParens goParens hi link goVarDeclParens goParens hi link goVarIdentifier Identifier hi link goVarComma goComma hi link goVarGroupIdentifier goVarIdentifier hi link goShortVarDecl Identifier hi link goVarAssign Special hi link goIota Special let s:assignOrShortDecl = 0 " goStatementStart ideally shouldn't contain goSwitchKeywords, but the without " this, `default:` will be highlighted using `goLabel` instead of `goSwitchKeywords`. syntax cluster goStatementStartGroup contains=goLabel,goSwitchKeywords call s:HiConfig('goVarIdentifier', ['go_highlight_variable_declarations']) if s:HiConfig('goVarAssign', ['go_highlight_variable_assignments'], #{default: 1}) let s:assignOrShortDecl = 1 syntax cluster goStatementStartGroup add=goVarAssign endif if s:HiConfig('goShortVarDecl', ['go_highlight_short_variable_declarations','go_highlight_variable_declarations']) let s:assignOrShortDecl = 1 syntax cluster goStatementStartGroup add=goShortVarDecl endif if s:assignOrShortDecl " This lookbehind is checked for a lot of characters in the file, which is " why goStatementStart is conditional and only added if needed. Splitting " this into two makes it slightly faster overall. " Note: the pattern /[{;]\@1<=/ seems to be equivalent to /[{;]\@1<=./ " which is why it had such poor performance and conflict with other " patterns; splitting it into two specific patterns works better syntax match goStatementStart /[{;]\@1<=\ze\s/ contained skipwhite nextgroup=@goStatementStartGroup syntax match goStatementStart /[{;]\@1<=\ze\<\K/ contained skipwhite nextgroup=@goStatementStartGroup endif syntax match goStatementStart /^\ze\s/ contained skipwhite nextgroup=@goStatementStartGroup syntax match goStatementStart /^\ze\<\K/ contained nextgroup=@goStatementStartGroup " }}} Constants and Variables " Packages {{{ syntax keyword goPackage package syntax keyword goImport import skipwhite nextgroup=goImportItem,goImports syntax region goImports matchgroup=goImportParens start='(' end=')' contained contains=goImportItem,goComment syntax match goImportItem /\(\([\._]\|\K\k*\)\s\+\)\?"[^"]*"/ contained contains=goImportString syntax region goImportString start='"' end='"' keepend contained hi link goPackage Keyword hi link goImport Keyword hi link goImportItem Special hi link goImportString goString hi link goImportParens goParens " }}} Packages " Types {{{ syntax cluster goType contains=goPrimitiveTypes,goFuncType,goStructType,goInterfaceType,goMapType,goSliceOrArrayType,goChannel,goNonPrimitiveType,goPointer,goTypeParens syntax match goPointer /*/ contained nextgroup=@goType " goTypeParens is used to ensure types within parens are highlighted correctly, " e.g. the func type in the slice literal `[](func (a, b int) bool){ ... }` syntax region goTypeParens start='(' end=')' contained contains=@goType,goComment syntax keyword goTypeDecl type skipwhite skipnl nextgroup=goTypeDeclName,goTypeDeclGroup syntax match goTypeDeclName /\K\k*/ contained skipwhite skipnl nextgroup=goTypeDeclTypeParams,goTypeAssign,@goType syntax match goTypeAssign /=/ contained skipwhite nextgroup=@goType syntax region goTypeDeclGroup matchgroup=goTypeDeclGroupParens start='(' end=')' contained contains=goTypeDeclName,goComment syntax region goTypeDeclTypeParams matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=goTypeParam,goComma,goComment skipwhite skipnl nextgroup=@goType " goNonPrimitiveType is used for matching the names and packages of " non-primitive types (i.e. types other than int, bool, string, etc.). Note the " optional non-capturing group is later in the pattern to avoid backtracking. syntax match goNonPrimitiveType /\<\K\k*\%(\.\K\k*\)\?\[\?/ contained contains=goPackageName,goTypeArgs syntax match goPackageName /\<\K\k*\ze\./ contained nextgroup=goDot syntax region goTypeArgs matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=@goType,goUnderscore,goComma,goComment syntax keyword goPrimitiveTypes any bool byte complex128 complex64 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr contained syntax match goFuncType /func\s*(/ contained contains=goFuncTypeParens skipwhite nextgroup=@goType,goFuncTypeMultiReturnType syntax region goFuncTypeParens matchgroup=goFuncParens start='(' end=')' contained contains=goFuncParam,goComma,goComment syntax region goFuncTypeMultiReturnType matchgroup=goFuncMultiReturnParens start='(' end=')' contained contains=goNamedReturnValue,goComma,goComment syntax keyword goMapType map contained skipwhite skipempty nextgroup=goMapTypeKeyType syntax region goMapTypeKeyType matchgroup=goMapBrackets start='\[' end='\]' contained contains=@goType skipwhite nextgroup=@goType syntax keyword goMapLiteral map contained skipwhite skipempty nextgroup=goMapLiteralKeyType syntax region goMapLiteralKeyType matchgroup=goMapBrackets start='\[' end='\]' contained contains=@goType skipwhite nextgroup=goMapLiteralValueType " See comment for goSliceOrArrayLiteralType, which serves the same function as goMapLiteralValueType syntax region goMapLiteralValueType start='\S' end='\ze[{(]\|$' contained contains=goSliceMapLiteralTypeMatch skipwhite skipnl nextgroup=goMapLiteralItems syntax region goMapLiteralItems matchgroup=goMapBraces start='{' end='}' contained contains=goStructLiteralBlock,@goExpr syntax match goSliceOrArrayType /\[\%(\d\+\|\.\.\.\)\?\]/ contained contains=goNumber,goDot skipwhite nextgroup=@goType " A lookbehind is used to distinguish a slice/array literal with slice indexing syntax match goSliceOrArrayLiteral /\k\@1\)\@!\K\k*\s\+\)\?\ze[^,]/ contained contains=goComma skipwhite nextgroup=@goType,goVariadic " syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\)\%(\s*,\?\%(\s\|\n\)*\%#\|\s\+\ze[^,]\)/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType,goVariadic " syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\)\%(\s*,\?\%(\s\|\n\)*\%#\ze)\|\s\+\ze[^,]\)/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType,goVariadic " TODO: Peformance: Figure out how to eliminate at least the first \ze in " '\ze)', because it more than doubles the time it takes to match this regex. " ')\@1<=' didn't work for some reason (i.e. when typing a parameter name, it " was highlighted as a type). " " goFuncParam: Assume the user is typing a parameter name (i.e. avoid " highlighting parameter names as types until proven otherwise). " conditional group allows skipping directly to type, e.g. func(SomeType) " " ┌───────────────────────────────────────────────────────────────────────────────────────────────────┐ " syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\)\%(\s*,\?\%(\s\|\n\)*\%#\ze)\|\s\+\ze[^,]\)\)\?/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType,goVariadic " └──────────────────┘ │ └──────────────┘ │└────────────┘ │└────────────────┘ │ │ │ " " Param must be preceded │ comma/ws/nl │ 'chan' a type, │ comma/ws/nl │ │ │ " " by start of line, '(', │ │ not param name │ │ │ │ " " or ',' followed by └────────────────────────────┘ └────────────────────────┘ └───────────┘ " " whitespace zero or more previous params if this matches, then we otherwise if this " " (e.g. 'a, b, ' in 'a, b, c') have one or more params, matches, we have " " then cursor, then close params then type, " " paren, e.g.: e.g.: " " (a, b, c, |) (a, b foo) " " The above diagrams can be found in the Monodraw file goFuncParam_Diagrams.monopic " goFuncParam: Assume the user is typing a type (i.e. avoid highlighting custom " types as return value names until proven otherwise) syntax match goNamedReturnValue /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\s\+\)\?\ze[^,]/ contained contains=goComma skipwhite nextgroup=@goType syntax keyword goReturn return contained hi link goFuncName Function hi link goFuncCall Function hi link goFuncCallParens goParens hi link goFuncDecl goFuncType hi link goFuncLiteral goFuncDecl hi link goFuncParens goParens hi link goFuncBraces goBraces hi link goFuncMultiReturnParens goParens hi link goReceiverParens goFuncParens hi link goVariadic goOperator hi link goArgSpread goVariadic hi link goTypeParam Identifier hi link goTypeParamComma goComma hi link goFuncParam Identifier hi link goNamedReturnValue NONE hi link goReturn Statement call s:HiConfig('goFuncCall', ['go_highlight_function_calls']) call s:HiConfig('goFuncName', ['go_highlight_functions']) call s:HiConfig('goFuncParens', ['go_highlight_function_parens']) call s:HiConfig('goFuncBraces', ['go_highlight_function_braces']) call s:HiConfig('goFuncParam', ['go_highlight_function_parameters']) call s:HiConfig('goTypeParam', ['go_highlight_type_parameters']) " }}} Functions " Structs and Interfaces {{{ " Note: 'goStructTypeBlock' has 'nextgroup=goStructLiteralBlock' to handle " anonymous struct type literals syntax keyword goStructType struct contained skipempty skipwhite nextgroup=goStructTypeBlock syntax region goStructTypeBlock matchgroup=goStructTypeBraces start='{' end='}' extend contained contains=goEmbeddedType,goStructTypeField,goComment,goStructTypeTag,goDot,goSemicolon skipwhite nextgroup=goStructLiteralBlock syntax region goStructTypeTag start='`' end='`' contained syntax region goStructTypeTag start='"' skip='\\"' end='"' contained oneline syntax match goStructTypeField /\%(_\|\K\k*\)\%(,\s*\%(_\|\K\k*\)\)*/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType syntax match goEmbeddedType /\*\?\K\k*\%(\.\K\k*\)\?\%(\[.*\]\)\?\%#\@1