runtime(tohtml): convert tohtml plugin to Vim9 script#19915
runtime(tohtml): convert tohtml plugin to Vim9 script#19915mao-yining wants to merge 22 commits intovim:masterfrom
Conversation
|
You could mark it as draft for now? |
8ee7d85 to
423896c
Compare
|
It used to be @fritzophrenic |
|
@mao-yining Wrapping the main loop in a Changes:
Below is a patch: diff --git a/runtime/syntax/2html.vim b/runtime/syntax/2html.vim
index 026406dc6..306ca9af0 100644
--- a/runtime/syntax/2html.vim
+++ b/runtime/syntax/2html.vim
@@ -1512,7 +1512,11 @@ if !settings.expand_tabs
setlocal isprint+=9
endif
-while lnum <= end
+def ProcessLines()
+ var all_lines = getline(lnum, end)
+ var start_lnum = lnum
+
+ while lnum <= end
# If there are filler lines for diff mode, show these above the line.
Add_diff_fill(lnum)
@@ -1535,7 +1539,7 @@ while lnum <= end
endif
# put numcol in a separate group for sake of unselectable text
- new = (settings.number_lines ? HtmlFormat_n(numcol, FOLDED_ID, 0, lnum): "") .. HtmlFormat_t(new, FOLDED_ID, 0)
+ new = (settings.number_lines ? HtmlFormat_n(numcol, FOLDED_ID, 0, lnum) : "") .. HtmlFormat_t(new, FOLDED_ID, 0)
# Skip to the end of the fold
var new_lnum = foldclosedend(lnum)
@@ -1550,12 +1554,12 @@ while lnum <= end
#
# A line that is not folded, or doing dynamic folding.
#
- var line = getline(lnum)
+ var line = all_lines[lnum - start_lnum]
var len = strlen(line)
if settings.dynamic_folds
# First insert a closing for any open folds that end on this line
- while !empty(foldstack) && get(foldstack, 0).lastline == lnum-1
+ while !empty(foldstack) && get(foldstack, 0).lastline == lnum - 1
new ..= "</span></span>"
remove(foldstack, 0)
endwhile
@@ -1710,9 +1714,9 @@ while lnum <= end
if settings.expand_tabs
var offset = 0
var idx = stridx(expandedtab, "\t")
- var tablist = split(&vts, ',')
+ var tablist = mapnew(split(&vts, ','), (_, v) => str2nr(v))
if empty(tablist)
- tablist = [ &ts ]
+ tablist = [&ts]
endif
var tabidx = 0
var tabwidth = 0
@@ -1789,6 +1793,8 @@ while lnum <= end
pgb.Incr()
endif
endwhile
+enddef
+ProcessLines()
# Diff filler is returned based on what needs inserting *before* the given line.
# So to get diff filler at the end of the buffer, we need to use last line + 1 |
|
@h-east Thanks for your suggestion. I've also optimized another similar place. Does anyone have a better solution for this kind of code? let s:build_fun_lines[-1] =<< trim ENDLET
blablabla
ENDLETMy current solution is: trim_tmp =<< trim ENDLET
blablabla
ENDLET
build_fun_lines += trim_tmp |
|
Thanks guys, this sounds very promising. I haven't been active for a few years on this. I do have a limited test suite over here along with where I had been officially maintaining the script but I don't think I had any work in progress that isn't already included in the officially distributed runtime: https://sourceforge.net/p/vim-tohtml/code/ci/default/tree/ The tests aren't complete yet, I have a couple tests for very basic functionality (and checking the output is valid HTML) but mostly I had been adding tests for new features or bugfixes as I implemented them. Still, it's a lot better than nothing and we should make sure there are not any new test failures comparing the current version to the Vim9 script version. Vim9 script is something I wanted to eventually include (see https://sourceforge.net/p/vim-tohtml/issues/28/ from years ago) but I never got around to experimenting with it even outside the plugin so once this MR is ready to go and is properly tested for regressions I think it should definitely merge. |
|
@fritzophrenic Seems this require java environment which I am not familiarize with. Could you please test it? |
|
Yeah I'll try to give that a try tonight or later in the week. I need to get set up again. It's using java only for running a standalone HTML validator as a test step, not to write or run the tests themselves. |
|
Hey I got the test running (and fixed a test issue caused by a change to diff highlighting sometime in the last few years). After downloading the changes for this pull request, I get several exceptions thrown during the test run, leading to test failures. I'll see if I can extract the exact option combinations leading to each error later, but for now here are the errors: The same error occurs in Test_whole_filler_disabled_one_file(), Test_whole_filler_disabled_two_files(), Test_whole_filler_disabled_uncopyable(), Test_whole_filler_enabled_one_file(), and Test_whole_filler_enabled_two_files(). So there's a good chance this issue is related to diff mode in some way. This error occurs in many tests across several test files so I think it is related to building the dynamic fold column in general. Affected tests:
Also in test Test_script_version_piecemeal(). Also impacts: Test_nodoc_links(), Test_nodoc_modeline_nodoc(), Test_script_tag_blank_linenums(), and Test_script_tag_dyn_folds(). I'll try to provide more info this weekend if I have time. If you want to run on your own, you just need to install a Java JRE and set up to build Vim from source so you're using the latest and greatest. I have the Vim repository checked out to ~/code/vim-src and my TOhtml repository checked out to ~/code/vim-tohtml. I downloaded the vnu.jar file to ~/code/vim-tohtml/testdir and installed OpenJDK JRE 25 from the Linux Mint software manager, then all it took was a "make" command to run the tests. Hope that help, this looks like a really good start! |
|
@h-east What's more. All of these isn't what I expect. This is for extracting |
|
This may be fine, but this does remove the optimization that was here
previously. Was that intentional? This function was previously built
dynamically similar to other functions which run frequently in the inner
loop. This way we can avoid evaluating logic during the loop processing
when it only depends on the tohtml settings (which we know up-front
before processing the file in any way). The better fix might be to go
back to building the function using the build_fun_lines method?
I remove this optimization is because I am confusing with the error of
"lines", I previously thought it is because of execute(), but that seems
not the reason.
|
This is a specification of Vim9 script. vim9cmd echo 'vert:│,fold:·,trunc:…'[charidx('vert:│,fold:·,trunc:…', matchend('vert:│,fold:·,trunc:…', 'fold:'))] |
|
Attaching log from the test run after the recent changes (cleaned up some for readability). The "lines" issue is still there, but we have resolved enough issues to get some interesting feedback from the HTML validator and other checks now as well. I probably won't have much time to dig into this over the weekend but can keep plinking away during the week. |
|
I don't have access to the internet during the week. I'll take another look next weekend. I also have no idea about the lines issue. |
|
After my last two fixes, there is only one remaining test failure:
It looks like this failure comes from a duplicate LineNr style definition being added for some reason. Here's the options line from the generated HTML in case it's relevant:
|
Maybe the issue is in this line: call add(s:lines, '<meta name="settings" content="'..
\ join(filter(keys(s:settings),'s:settings[v:val]'),',')..
\ ',prevent_copy='..s:settings.prevent_copy..
\ ',use_input_for_pc='..s:settings.use_input_for_pc..
\ '"'..s:tag_close)which I've converted to: add(lines, '<meta name="settings" content="' ..
join(filter(keys(settings), (_, k) => {
var v = settings[k]
if type(v) == v:t_number
return v != 0
elseif type(v) == v:t_bool
return !empty(v)
else
return false
endif
}), ',') ..
',prevent_copy=' .. settings.prevent_copy ..
',use_input_for_pc=' .. settings.use_input_for_pc ..
'"' .. tag_close)But I haven't figured out what went wrong yet. |
Signed-off-by: Mao-Yining <mao.yining@outlook.com>
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com> Signed-off-by: Mao-Yining <mao.yining@outlook.com>
Signed-off-by: Mao-Yining <mao.yining@outlook.com>
- Change synIDattr attribute checks from non-empty string to explicit '1' - Fix last_colors_name comparison (null → null_string) - Fix inverse attribute logic in CSS generation - Refactor ProgressBar.CalculateTicks into local function and fix pb_len <= 0 case
- Move lnum and end declarations to global scope for ProcessFolds() - Remove duplicate local declarations - Initialize lnum before optional g:html_start_line check
Co-Authored-By: fritzophrenic <1334420+fritzophrenic@users.noreply.github.com>
Co-Authored-By: fritzophrenic <1334420+fritzophrenic@users.noreply.github.com>
Co-authored-by: fritzophrenic <fritzophrenic@gmail.com>
|
Oh, the meta line is fine as far as I know (I suppose I should check if I have a test for that). I was only providing the meta line so you could see what options are set by the test, to reproduce the issue on your end if you want to debug. The actual issue is there are two duplicate CSS lines generated to define the LineNr highlight. Since I have a specific test for that, I assume there was a bugfix at some point to remove a duplicate LineNr highlight definition which seems to have regressed. |
|
@chrisbra by the way, are you interested in adding the tohtml tests to the automated checks at all? I'm not familiar with how those are configured or anything but would be willing to learn and put together a pull request. They do depend on an external HTML validator tool, which currently is a vnu.jar java file needing a JRE installed, in case that affects the feasibility of adding as an automated test. |
|
I'm still considering the performance issue. It seems we've used too much string concatenation. Would it be better to use a list instead? |

I spent some time converting tohtml to vim9, initially to see if there would be any performance improvements.
But I'm not sure if it's an environment issue or something else — the converted version seems to perform worse than the original, and the progress bar during conversion doesn't show up either. So please do not merge for now.
I'd like to hear some feedback from everyone, and also have the tests run.
Thanks all!