Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syntax support for toolchain directive #3633

Merged
merged 1 commit into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions autoload/go/highlight_test.vim
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,120 @@ function! s:functionCallHighlightGroup(testname, value)
endtry
endfunc

function! Test_gomodToolchainVersion_highlight() abort
try
syntax on

let g:go_gopls_enabled = 0
let l:wd = getcwd()
let l:dir = gotest#write_file('gomodtest/go.mod', [
\ 'module github.com/fatih/vim-go',
\ '',
\ 'toolchain default',
\ 'toolchain go1',
\ 'toolchain go1',
\ 'toolchain go1.21',
\ 'toolchain go1.21rc3',
\ 'toolchain go1.21.3-somesuffix',
\ 'toolchain go1.21rc2-somesuffix',
\ 'toolchain go1.21 some-suffix',
\ ''])

let l:lineno = 3
let l:lineclose = line('$')
while l:lineno < l:lineclose
let l:line = getline(l:lineno)
let l:split_idx = stridx(l:line, ' ')
let l:idx = 0
let l:col = 1

while l:idx < len(l:line) - 1
call cursor(l:lineno, l:col)
let l:synname = synIDattr(synID(l:lineno, l:col, 1), 'name')
let l:errlen = len(v:errors)

if l:idx < l:split_idx
call assert_equal('gomodToolchain', l:synname, 'toolchain on line ' . l:lineno . ' and col ' . l:col)
elseif l:idx > l:split_idx
call assert_equal('gomodToolchainVersion', l:synname, 'version on line ' . l:lineno . ' and col ' . l:col)
endif

if l:errlen < len(v:errors)
break
endif

let l:col += 1
let l:idx += 1
endwhile
let l:lineno += 1
endwhile

finally
call go#util#Chdir(l:wd)
call delete(l:dir, 'rf')
endtry
endfunc

function! Test_gomodToolchainVersion_invalid_highlight() abort
try
syntax on
let g:go_gopls_enabled = 0
let l:wd = getcwd()

" 1. No release candidate for patch versions
" 2+3. Release version can only be followed by 'rcN' or a valid suffix
" 4+5. toolchain version must start with 'go'
let l:dir = gotest#write_file('gomodtest/go.mod', [
\ 'module github.com/fatih/vim-go',
\ '',
\ 'toolchain go2',
\ 'toolchain go1.21.1.4',
\ 'toolchain go1.21.1blah',
\ 'toolchain go1.21!some-suffix',
\ 'toolchain something-else',
\ ''])

let l:lineno = 3
let l:lineclose = line('$')
while l:lineno < l:lineclose
let l:line = getline(l:lineno)
let l:col = col([l:lineno, '$']) - 1
let l:idx = len(l:line) - 1
" e.g. go1.21.1rc2 is valid until 'rc2'
" each 'go*' test above has last version number '1'
let l:valid_version_start_idx = strridx(l:line, '1')

if l:valid_version_start_idx != -1
let l:end_idx = l:valid_version_start_idx
else
" the whole version is invalid
let l:end_idx = stridx(l:line, ' ') + 1
endif

while l:idx > l:end_idx
call cursor(l:lineno, l:col)
let l:synname = synIDattr(synID(l:lineno, l:col, 1), 'name')
let l:errlen = len(v:errors)

call assert_notequal('gomodToolchainVersion', l:synname, 'version on line ' . l:lineno . ' and col ' . l:col)

if l:errlen < len(v:errors)
break
endif

let l:col -= 1
let l:idx -= 1
endwhile
let l:lineno += 1
endwhile

finally
call go#util#Chdir(l:wd)
call delete(l:dir, 'rf')
endtry
endfunc


" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
Expand Down
39 changes: 27 additions & 12 deletions syntax/gomod.vim
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,30 @@ syntax case match
" https://golang.org/ref/mod#go-mod-file-grammar

" match keywords
syntax keyword gomodModule module
syntax keyword gomodGo go contained
syntax keyword gomodRequire require
syntax keyword gomodExclude exclude
syntax keyword gomodReplace replace
syntax keyword gomodRetract retract
syntax keyword gomodModule module
syntax keyword gomodGo go contained
syntax keyword gomodToolchain toolchain contained
syntax keyword gomodRequire require
syntax keyword gomodExclude exclude
syntax keyword gomodReplace replace
syntax keyword gomodRetract retract

" require, exclude, replace, and go can be also grouped into block
syntax region gomodRequire start='require (' end=')' transparent contains=gomodRequire,gomodVersion
syntax region gomodExclude start='exclude (' end=')' transparent contains=gomodExclude,gomodVersion
syntax region gomodReplace start='replace (' end=')' transparent contains=gomodReplace,gomodVersion
syntax region gomodRetract start='retract (' end=')' transparent contains=gomodVersionRange,gomodVersion
syntax match gomodGo '^go .*$' transparent contains=gomodGo,gomodGoVersion
syntax match gomodToolchain '^toolchain .*$' transparent contains=gomodToolchain,gomodToolchainVersion

" set highlights
highlight default link gomodModule Keyword
highlight default link gomodGo Keyword
highlight default link gomodRequire Keyword
highlight default link gomodExclude Keyword
highlight default link gomodReplace Keyword
highlight default link gomodRetract Keyword
highlight default link gomodModule Keyword
highlight default link gomodGo Keyword
highlight default link gomodToolchain Keyword
highlight default link gomodRequire Keyword
highlight default link gomodExclude Keyword
highlight default link gomodReplace Keyword
highlight default link gomodRetract Keyword

" comments are always in form of // ...
syntax region gomodComment start="//" end="$" contains=@Spell
Expand All @@ -45,6 +48,18 @@ highlight default link gomodString String
syntax match gomodReplaceOperator "\v\=\>"
highlight default link gomodReplaceOperator Operator

" match toolchain versions, based on https://go.dev/doc/toolchain#version,
" * default
" * go1
" * go1.X.Y
" * go1.X
" * go1.XrcN
" * go1.XrcN-somesuffix
" * go1.X.Y-somesuffix
syntax match gomodToolchainVersion "default$" contained
syntax match gomodToolchainVersion "go1\(.\d\+\)\{,2\}\(rc\d\+\)\?\([ \t-].*\)\?" contained
highlight default link gomodToolchainVersion Identifier

" match go versions
syntax match gomodGoVersion "1\.\d\+" contained
highlight default link gomodGoVersion Identifier
Expand Down
Loading