From 0bb139e91d3ea3124c8ec06cadcfeae07e6d1051 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Sun, 10 Apr 2022 15:13:36 -0700 Subject: [PATCH 1/6] syntax: match new ~ operator --- syntax/go.vim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/syntax/go.vim b/syntax/go.vim index af30705abf..406c1d8462 100644 --- a/syntax/go.vim +++ b/syntax/go.vim @@ -266,6 +266,8 @@ if go#config#HighlightOperators() syn match goOperator /\%(<<\|>>\|&^\)=\?/ " match remaining two-char operators: := && || <- ++ -- syn match goOperator /:=\|||\|<-\|++\|--/ + " match ~ + syn match goOperator /\~/ " match ... hi def link goPointerOperator goOperator From ddb42921531111d88e4fc485b5e14ded5c8195a8 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Sun, 10 Apr 2022 15:56:23 -0700 Subject: [PATCH 2/6] syntax: add support for generic functions --- syntax/go.vim | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/syntax/go.vim b/syntax/go.vim index 406c1d8462..2355acfa53 100644 --- a/syntax/go.vim +++ b/syntax/go.vim @@ -275,13 +275,36 @@ if go#config#HighlightOperators() endif hi def link goOperator Operator +" -> type constraint opening bracket +" |-> start non-counting group +" || -> any word character +" || | -> at least one, as many as possible +" || | | -> start non-counting group +" || | | | -> match ~ +" || | | | | -> at most once +" || | | | | | -> allow a slice type +" || | | | | | | -> any word character +" || | | | | | | | -> start a non-counting group +" || | | | | | | | | -> that matches word characters and | +" || | | | | | | | | | -> close the non-counting group +" || | | | | | | | | | | -> close the non-counting group +" || | | | | | | | | | | |-> any number of matches +" || | | | | | | | | | | || -> start a non-counting group +" || | | | | | | | | | | || | -> a comma and whitespace +" || | | | | | | | | | | || | | -> at most once +" || | | | | | | | | | | || | | | -> close the non-counting group +" || | | | | | | | | | | || | | | | -> at least one of those non-counting groups, as many as possible +" || | | | | | -------- | | | | || | | | | | -> type constraint closing bracket +" || | | | | || | | | | | || | | | | | | +syn match goTypeParams /\[\%(\w\+\s\+\%(\~\?\%(\[]\)\?\w\%(\w\||\)\)*\%(,\s*\)\?\)\+\]/ nextgroup=goSimpleParams contained + " Functions; if go#config#HighlightFunctions() || go#config#HighlightFunctionParameters() syn match goDeclaration /\/ nextgroup=goReceiver,goFunction,goSimpleParams skipwhite skipnl syn match goReceiverDecl /(\s*\zs\%(\%(\w\+\s\+\)\?\*\?\w\+\)\ze\s*)/ contained contains=goReceiverVar,goReceiverType,goPointerOperator syn match goReceiverVar /\w\+\ze\s\+\%(\w\|\*\)/ nextgroup=goPointerOperator,goReceiverType skipwhite skipnl contained syn match goPointerOperator /\*/ nextgroup=goReceiverType contained skipwhite skipnl - syn match goFunction /\w\+/ nextgroup=goSimpleParams contained skipwhite skipnl + syn match goFunction /\w\+/ nextgroup=goSimpleParams,goTypeParams contained skipwhite skipnl syn match goReceiverType /\w\+\ze\s*)/ contained if go#config#HighlightFunctionParameters() syn match goSimpleParams /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType nextgroup=goFunctionReturn skipwhite skipnl @@ -300,7 +323,7 @@ hi def link goFunction Function " Function calls; if go#config#HighlightFunctionCalls() - syn match goFunctionCall /\w\+\ze(/ contains=goBuiltins,goDeclaration + syn match goFunctionCall /\w\+\ze\%(\[\%(\%(\[]\)\?\w\+\(,\s*\)\?\)\+\]\)\?(/ contains=goBuiltins,goDeclaration endif hi def link goFunctionCall Type From dab58e78805e030f8db7315e57268fcc9861cdac Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Sun, 10 Apr 2022 17:34:02 -0700 Subject: [PATCH 3/6] syntax add support for generic types --- syntax/go.vim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/syntax/go.vim b/syntax/go.vim index 2355acfa53..b72a926e87 100644 --- a/syntax/go.vim +++ b/syntax/go.vim @@ -296,16 +296,16 @@ hi def link goOperator Operator " || | | | | | | | | | | || | | | | -> at least one of those non-counting groups, as many as possible " || | | | | | -------- | | | | || | | | | | -> type constraint closing bracket " || | | | | || | | | | | || | | | | | | -syn match goTypeParams /\[\%(\w\+\s\+\%(\~\?\%(\[]\)\?\w\%(\w\||\)\)*\%(,\s*\)\?\)\+\]/ nextgroup=goSimpleParams contained +syn match goTypeParams /\[\%(\w\+\s\+\%(\~\?\%(\[]\)\?\w\%(\w\||\)\)*\%(,\s*\)\?\)\+\]/ nextgroup=goSimpleParams,goDeclType contained " Functions; if go#config#HighlightFunctions() || go#config#HighlightFunctionParameters() syn match goDeclaration /\/ nextgroup=goReceiver,goFunction,goSimpleParams skipwhite skipnl - syn match goReceiverDecl /(\s*\zs\%(\%(\w\+\s\+\)\?\*\?\w\+\)\ze\s*)/ contained contains=goReceiverVar,goReceiverType,goPointerOperator + syn match goReceiverDecl /(\s*\zs\%(\%(\w\+\s\+\)\?\*\?\w\+\%(\[\%(\%(\[\]\)\?\w\+\%(,\s*\)\?\)\+\]\)\?\)\ze\s*)/ contained contains=goReceiverVar,goReceiverType,goPointerOperator syn match goReceiverVar /\w\+\ze\s\+\%(\w\|\*\)/ nextgroup=goPointerOperator,goReceiverType skipwhite skipnl contained syn match goPointerOperator /\*/ nextgroup=goReceiverType contained skipwhite skipnl syn match goFunction /\w\+/ nextgroup=goSimpleParams,goTypeParams contained skipwhite skipnl - syn match goReceiverType /\w\+\ze\s*)/ contained + syn match goReceiverType /\w\+\%(\[\%(\%(\[\]\)\?\w\+\%(,\s*\)\?\)\+\]\)\?\ze\s*)/ contained if go#config#HighlightFunctionParameters() syn match goSimpleParams /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType nextgroup=goFunctionReturn skipwhite skipnl syn match goFunctionReturn /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType skipwhite skipnl @@ -315,7 +315,7 @@ if go#config#HighlightFunctions() || go#config#HighlightFunctionParameters() hi def link goReceiverVar goParamName hi def link goParamName Identifier endif - syn match goReceiver /(\s*\%(\w\+\s\+\)\?\*\?\s*\w\+\s*)\ze\s*\w/ contained nextgroup=goFunction contains=goReceiverDecl skipwhite skipnl + syn match goReceiver /(\s*\%(\w\+\s\+\)\?\*\?\s*\w\+\%(\[\%(\%(\[\]\)\?\w\+\%(,\s*\)\?\)\+\]\)\?\s*)\ze\s*\w/ contained nextgroup=goFunction contains=goReceiverDecl skipwhite skipnl else syn keyword goDeclaration func endif @@ -350,7 +350,7 @@ hi def link goField Identifier if go#config#HighlightTypes() syn match goTypeConstructor /\<\w\+{\@=/ syn match goTypeDecl /\/ nextgroup=goTypeName skipwhite skipnl - syn match goTypeName /\w\+/ contained nextgroup=goDeclType skipwhite skipnl + syn match goTypeName /\w\+/ contained nextgroup=goDeclType,goTypeParams skipwhite skipnl syn match goDeclType /\<\%(interface\|struct\)\>/ skipwhite skipnl hi def link goReceiverType Type else From 9edad514ef25a02af85a347eea0efe43ac0d43a8 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 12 Apr 2022 23:36:36 -0700 Subject: [PATCH 4/6] add tests for generic receivers --- autoload/go/highlight_test.vim | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/autoload/go/highlight_test.vim b/autoload/go/highlight_test.vim index 1b8b2fc7a7..dc29310331 100644 --- a/autoload/go/highlight_test.vim +++ b/autoload/go/highlight_test.vim @@ -477,6 +477,12 @@ function! Test_goReceiverHighlight() abort \ 'ValueReceiverType': {'group': 'goReceiverType', 'value': "t T\x1f"}, \ 'PointerReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "*T\x1f"}, \ 'ValueReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "T\x1f"}, + \ 'GenericPointerReceiverVar': {'group': 'goReceiverVar', 'value': "g\x1f *G[int]"}, + \ 'GenericValueReceiverVar': {'group': 'goReceiverVar', 'value': "g\x1f G[int]"}, + \ 'GenericPointerReceiverType': {'group': 'goReceiverType', 'value': "g *G\x1f[int]"}, + \ 'GenericValueReceiverType': {'group': 'goReceiverType', 'value': "g G\x1f[int]"}, + \ 'GenericPointerReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "*G\x1f[int]"}, + \ 'GenericValueReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "G\x1f[int]"}, \ } let g:go_highlight_function_parameters = 1 @@ -493,6 +499,7 @@ function! s:receiverHighlightGroup(testname, value) \ printf('package %s', l:package), \ '', \ 'type T struct{}', + \ 'type G[T any] struct{}', \ printf('func (%s) Foo() {}', a:value), \ ]) From 23abf94221a2ba6b919866eac5a1de995662d689 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 12 Apr 2022 23:57:48 -0700 Subject: [PATCH 5/6] add tests for generic types --- autoload/go/highlight_test.vim | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/autoload/go/highlight_test.vim b/autoload/go/highlight_test.vim index dc29310331..27f748050e 100644 --- a/autoload/go/highlight_test.vim +++ b/autoload/go/highlight_test.vim @@ -512,6 +512,39 @@ function! s:receiverHighlightGroup(testname, value) endtry endfunc +function! Test_GoTypeHighlight() abort + syntax on + + let l:tests = { + \ 'StandardType': {'group': 'goTypeName', 'value': "T\x1f"}, + \ 'GenericType': {'group': 'goTypeName', 'value': "G\x1f[T any]"}, + \ } + + let g:go_highlight_types = 1 + for l:kv in items(l:tests) + let l:actual = s:typeHighlightGroup(l:kv[0], l:kv[1].value) + call assert_equal(l:kv[1].group, l:actual, l:kv[0]) + endfor + unlet g:go_highlight_types +endfunc + +function! s:typeHighlightGroup(testname, value) + let l:package = tolower(a:testname) + let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [ + \ printf('package %s', l:package), + \ '', + \ printf('type %s struct{}', a:value), + \ ]) + + try + let l:pos = getcurpos() + let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name') + return l:actual + finally + call delete(l:dir, 'rf') + endtry +endfunc + " restore Vi compatibility settings let &cpo = s:cpo_save unlet s:cpo_save From 6aeeba200462da6578afd027f8fedd92273df5cd Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Wed, 13 Apr 2022 00:46:03 -0700 Subject: [PATCH 6/6] add tests for generic functions --- autoload/go/highlight_test.vim | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/autoload/go/highlight_test.vim b/autoload/go/highlight_test.vim index 27f748050e..afb6fb40d0 100644 --- a/autoload/go/highlight_test.vim +++ b/autoload/go/highlight_test.vim @@ -545,6 +545,76 @@ function! s:typeHighlightGroup(testname, value) endtry endfunc +function! Test_goFunction() abort + syntax on + + let l:tests = { + \ 'StandardFunction': {'group': 'goFunction', 'value': "F\x1f(){}"}, + \ 'GenericFunction': {'group': 'goFunction', 'value': "G\x1f[T any](_ T){}"}, + \ } + + let g:go_highlight_functions = 1 + for l:kv in items(l:tests) + let l:actual = s:functionHighlightGroup(l:kv[0], l:kv[1].value) + call assert_equal(l:kv[1].group, l:actual, l:kv[0]) + endfor + unlet g:go_highlight_functions +endfunc + +function! s:functionHighlightGroup(testname, value) + let l:package = tolower(a:testname) + let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [ + \ printf('package %s', l:package), + \ '', + \ printf('func %s', a:value), + \ ]) + + try + let l:pos = getcurpos() + let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name') + return l:actual + finally + call delete(l:dir, 'rf') + endtry +endfunc + +function! Test_goFunctionCall() abort + syntax on + + let l:tests = { + \ 'StandardFunctionCall': {'group': 'goFunctionCall', 'value': "f\x1f()"}, + \ 'GenericFunctionCall': {'group': 'goFunctionCall', 'value': "g\x1f[int](i)"}, + \ } + + let g:go_highlight_function_calls = 1 + for l:kv in items(l:tests) + let l:actual = s:functionCallHighlightGroup(l:kv[0], l:kv[1].value) + call assert_equal(l:kv[1].group, l:actual, l:kv[0]) + endfor + unlet g:go_highlight_function_calls +endfunc + +function! s:functionCallHighlightGroup(testname, value) + let l:package = tolower(a:testname) + let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [ + \ printf('package %s', l:package), + \ '', + \ 'func f() {}', + \ 'func g[T any](i T) {}', + \ 'func init() {', + \ printf("\t%s", a:value), + \ '}', + \ ]) + + try + let l:pos = getcurpos() + let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name') + return l:actual + finally + call delete(l:dir, 'rf') + endtry +endfunc + " restore Vi compatibility settings let &cpo = s:cpo_save unlet s:cpo_save