0

I want to translate the following functions to vim9script and also combine them into one because they basically do the same

function! Hi_Py()
  let b:current_syntax=''
  unlet b:current_syntax
  syntax include @py syntax/python.vim
  syntax region pythoncode matchgroup=Snip start="#begin=py" end="#end=py" contains=@py
endfunction
function! Hi_Java()
  let b:current_syntax=''
  unlet b:current_syntax
  syntax include @java syntax/java.vim
  syntax region javacode matchgroup=Snip start="#begin=java" end="#end=java" contains=@java
endfunction

autocmd BufNewFile,BufReadPost *.sh call Hi_Py()
autocmd BufNewFile,BufReadPost *.sh call Hi_Java()
2
  • It's unclear what you want. You want to learn how to translate this to vim9script? You want to combine the two functions into one and translate it to vim9script (why?)? You want to know how to call both in vim9script?
    – Heptite
    Jan 21, 2023 at 2:13
  • 2
    We don’t put answers in questions here. To mark the solution, use the green checkmark button.
    – D. Ben Knoble
    Jan 21, 2023 at 14:49

3 Answers 3

1

It is more readable with :help interpolated-string. Available in vim from May 2022 (> 8.2.4883).

vim9script

def HiLang(short_name: string, long_name: string)
    b:current_syntax = ''
    unlet b:current_syntax
    execute $'syntax include @{short_name} syntax/{long_name}.vim'
    execute $'syntax region {long_name}code matchgroup=Comment start="#begin={short_name}" end="#end={short_name}" contains=@{short_name}'
enddef

augroup hil
    au!
    autocmd Filetype *sh call HiLang("py", "python")
    autocmd Filetype *sh call HiLang("java", "java")
augroup END
1
  • Oh... Good to know string interpolation can be done with execute $'string with @{variable} stuff'. Thanks.
    – gildux
    Jan 25, 2023 at 13:50
1

Your two functions looks similar, and lines that differ are the 4th and the 5th. From there, I think you'll need two parameters:

Hi_Py Hi_Java line 4 line 5
py java @this start="#begin=this" end="#end=this" contains=@this
python java syntax/this.vim thiscode

It also look like that you have no return value (i.e. void) or is it a function (i.e. func)? I can't say. Let's start the skeleton and deal with variables according to :h vim9-declaration and advices from :h convert_legacy_function_to_vim9

vim9script
def! Hi_MyLang(short_name: string,
               long_name: string
              ): void
  # let b:current_syntax=''
  # but here, don't replace "let" with "var" because of the "b:" in name
  # E1016: Cannot declare a buffer variable: b:current_syntax
  b:current_syntax = ''
  # unlet b:current_syntax
  unlet b:current_syntax
  # syntax include @py syntax/python.vim
  # # to do later
  # syntax region pythoncode matchgroup=Snip start="#begin=py" end="#end=py" contains=@py
  # # to do later
enddef

Seems easy. Now let's deal with the :syntax include and :syntax region parts. I think there's no need to prepend colon here. And we'll need some concatenations and grouping.

  # syntax include @py syntax/python.vim
  var at_grouplist_name:string = "@" .. short_name
  var file_name: string = "syntax/" .. long_name .. ".vim"
  syntax include at_grouplist_name file_name
  # syntax region pythoncode matchgroup=Snip start="#begin=py" end="#end=py" contains=@py
  var group_name: string = long_name .. "code"
  var snip_star: string = "start=\"#begin=" .. short_name .. "\""
  var snip_stop: string = "end=\"#end=" .. short_name .. "\""
  var snip_mark: string = "contains=" .. at_grouplist_name
  syntax region group_name matchgroup=Snip snip_start snip_stop snip_mark

Caution: I did not try, the above should be read as a starting hint.

Update: After tries (see comments), it appears that vim9script can't distinguish variables easily in Ex commands call. So :syntax include at_grouplist_name file_name is literally seeking for a file named file_name... To solve this one should use indirect invocation (or other solution?): :execute "syntax include at_grouplist_name file_name" Well, but vim9script in another hand doesn't evaluate strings dynamically (not a bad point per se) hence use concatenation for execute argument. Wait, there's some good point here: that command eats unlimited arguments that are concatenated with space. So far so good, that last part becomes:

  var at_grouplist_name:string = "@" .. short_name
  var file_name: string = "syntax/" .. long_name .. ".vim"
  execute "syntax include" at_grouplist_name file_name
  var group_name: string = long_name .. "code"
  var snip_star: string = 'start="#begin=' .. short_name .. '"'
  var snip_stop: string = 'end="#end=' .. short_name .. '"'
  var snip_mark: string = "contains=" .. at_grouplist_name
  execute "syntax region" group_name "matchgroup=Snip" snip_start snip_stop snip_mark

Of course, choose better variable names and improve the underlying routines.

8
  • E1016: Cannot declare a buffer variable: b:current_syntax
    – whoopdedoo
    Jan 21, 2023 at 13:41
  • You're right, it should only be affected. Fixing my answer.
    – gildux
    Jan 21, 2023 at 13:46
  • can't open file syntax include at_grouplist_name file_name
    – whoopdedoo
    Jan 21, 2023 at 14:11
  • Weird. I think it's not seeing the variable (and thinks file_name is the file name haha) Maybe we should go with an indirect invocation here? Try :execute "syntax include at_grouplist_name file_name" and let me know.
    – gildux
    Jan 21, 2023 at 14:18
  • 1
    My bad, there's no string interpolation... It should be explicit concatenation like :execute "syntax include " .. at_grouplist_name .. " " .. file_name
    – gildux
    Jan 21, 2023 at 14:33
0

If highlighting gets out of sync execute :syn sync fromstart

def HiLang(short_name: string, long_name: string): void
  b:current_syntax = ''
  unlet b:current_syntax
  #syntax include @py syntax/python.vim
  #syntax region pythoncode matchgroup=Snip start="#begin=py" end="#end=py" contains=@py
  var at_grouplist_name: string = "@" .. short_name
  var file_name: string = "syntax/" .. long_name .. ".vim"
  execute "syntax include " .. at_grouplist_name .. " " .. file_name
  var group_name: string = long_name .. "code"
  var snip_start: string = "start=\"#begin=" .. short_name .. "\""
  var snip_stop: string = "end=\"#end=" .. short_name .. "\""
  var snip_mark: string = "contains=" .. at_grouplist_name
  execute "syntax region " .. group_name .. " matchgroup=Snip " .. snip_start  .. " " .. snip_stop .. " " .. snip_mark
enddef
autocmd BufNewFile,BufReadPost *.sh HiLang("py", "python")
autocmd BufNewFile,BufReadPost *.sh HiLang("java", "java")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.