Closed dther closed 2 months ago
Very interesting! I definitely like this more than the line numbers styling patch from the wiki. This obviously has some footguns like the WIN_HIGHLIGHT
event but I don't really think that's a problem.
I'm going to cherry pick the first two commits since they are unrelated, and leave you to fix the compilation issues. I also want to hear what other people think!
Thanks for checking! It seems I missed a stub function in vis-lua.c. Should be fine now, I've tested it on my system with ./configure --disable-lua && make clean vis
.
Very interesting! I definitely like this more than the line numbers styling patch from the wiki. This obviously has some footguns like the
WIN_HIGHLIGHT
event but I don't really think that's a problem.I also want to hear what other people think!
I really like the simplicity and universal approach of this API.
However, the line numbers patch has the advantage that it allows to easily style lines not currently visible in the viewport.
In LSP land the server provides the information that in the file at line 200 there is a certain diagnostic. vis-lspc can simply tell vis to highlight the line 200, and it will be styled if visible. With this API vis-lspc needs to map the line number in the file to the viewport.
If anyone has a good idea how to efficiently map file line numbers to viewport line number I would gladly support this API in vis-lspc.
Maybe exporting the line range of the viewport to Lua could be a simple solution?
If anyone has a good idea how to efficiently map file line numbers to viewport line number I would gladly support this API in vis-lspc.
This is something I've wanted for a long time too. It would greatly simplify a lot of the code I've written for the experimental mouse support, which relies heavily on translating visual lines to absolute byte position. Granted, I now plan to implement that logic directly in C instead, but I'm glad to see that I'm not the only one who sees value in exposing this data to the Lua API.
Maybe exporting the line range of the viewport to Lua could be a simple solution?
I'm thinking of something along these lines as well. My initial thoughts are to output a simple table/list indexed by viewport lines, with member variables being the actual logical file lines, and perhaps special keys for "first" and "last", since this is what's exposed in view.h
. In the future this might lead to a Lua class that exposes struct View
with more power, but in my opinion it's best we keep things simple for the first prototype.
@rnpnr Should I add the commits for this proposed feature onto this PR? On the one hand, it's a function that's primarily useful due to the new UI_DRAW event, but on the other, I'd like this PR to be merged sooner rather than later, so that others can experiment with what's already possible.
Edit: On the topic of expanding the Lua API's access to UI layout, there's a lot of information in ui-terminal.h that would be useful for properly styling parts of the viewport. sidebar
comes to mind, as it's a simple integer that can be used to figure out how many cells to style in order to highlight an entire line number.
My initial thoughts are to output a simple table/list indexed by viewport lines, with member variables being the actual logical file lines
I think we would want something simpler than that, for example just a Range
with the first and last line in view. We already have File.lines
in lua which lets you get the lines contents by line number. On the C side the first and last line are already easily accessible via win->view
.
Should I add the commits for this proposed feature onto this PR?
It should be a separate submission. From a brief look at what is already available I don't really expect such a feature to need more than ~10 lines of code.
I think we would want something simpler than that, for example just a
Range
with the first and last line in view. We already haveFile.lines
in lua which lets you get the lines contents by line number. On the C side the first and last line are already easily accessible viawin->view
.
Apologies for the confusion- when I mean mapping visual lines to logical lines, I meant by line number-to-line number, not content. While simply returning the first and last line numbers is much simpler than what I've implemented, I didn't have much trouble, and still believe that, exposing lineno
values stored in win->view->lines
should make for much simpler Lua code. I still shudder when I think about how large guess_file_pos
(my lua function for translating terminal x, y coordinates to file lines and columns) ended up being. See #1181.
Sorry, I guess I forgot that the viewport height and width isn't visible from lua right now, only the height/width of windows. Personally I would be ok if those were exposed separately.
Continuing this train of thought, I think long term the useful dimensions are the full UI width/height and the View width/height. With these two you can determine the sidebar width and status line height (if for example the info window is open). The window width and height which includes the sidebar and status line are only useful now while we allow separate windows.
As requested, I've moved the code for view height and width from #1181 over here. I imagine it would be best to make them fields within the new viewport
table, so I plan to do that if no one objects- but I'll hold off on committing until #1181 is merged so that I can fast-forward cleanly.
Well, so much for a clean fast-forward. I'll rebase and force-push later. (unless anyone objects between now and then)
Nope, that is actually preferred. Github doesn't really play nice with it but everyone maintaining vis is used to the patch file/linear history approach.
Thank you both for your work :)
Wanted to leave the function I am going to use in vis-lspc
to map file line number to viewport line number, combining both #1181 and this.
local function file_lineno_to_viewport_lineno(win, file_lineno)
-- The line is not in the current viewport
if file_lineno < win.viewport.lines.start or file_lineno > win.viewport.lines.finish then
return nil
end
-- The line is in the viewport and there is no wrapped line
if win.viewport.lines.finish - win.viewport.lines.start == win.viewport.height then
return file_lineno - win.viewport.lines.start
else -- Determine the position in the viewport considering possible prior wrapped lines
local view_lineno = 0
for n = win.viewport.lines.start, file_lineno do
view_lineno = view_lineno + 1
-- Wrapped line. Shift our line down
if #win.file.lines[n] > win.viewport.width then
view_lineno = view_lineno + #win.file.lines[n] // win.viewport.width
end
end
return view_lineno
end
end
Nope, that is actually preferred. Github doesn't really play nice with it but everyone maintaining vis is used to the patch file/linear history approach.
Fair enough, I'll leave the merge as-is. The git log
output looks funny on my end, but I'll live. @fischerling Sorry for changing up the field name just as you posted that...
@fischerling Sorry for changing up the field name just as you posted that...
No problem I just updated the snippet ;)
Alright I'm going to merge this, thanks for the patch!
There are a couple unrelated issues that this brings to light though:
First, I was doing some experimenting to add custom lexer keywords (here but it's very hacky) and I noticed that some lexers (eg. markdown) are very close to reaching LEXER_MAX. So that probably needs to be increased.
Second it would be good to actually know from lua what the first available user style id is.
Third, as per your status line example, the function that fills in the status line (in vis-std.lua
) should probably be made
configurable so that it doesn't have to be run twice (i.e. store it as a variable in the vis table so that it can get reassigned to your custom function).
Also I'm thinking of a more robust version of win:style_pos
that isn't limited to just the window. But that could be added later and win:style_pos
would just do the bounds check and call that one.
This pull request essentially exposes the new style handling from PR #1154 to the Lua API, allowing plugins to make direct changes to cells using a new
Win
method,Win.style_pos
.It also adds a new style constant,
STYLE_LEXER_MAX
, which provides a reliable way of defining new user styles without needing to interact with the lexer.Finally, a new event in
ui-terminal.c
, UI_DRAW, allows plugin developers the opportunity to override all previous styling. This allows for the creation of new UI elements entirely within the Lua API. This event is emitted at quite a low level (outside of vis.c and in ui_draw, right before the backend blit function), so I'd like opinions on whether it's even a good idea to have events outside of vis.c. In my opinion, it's a reasonably UI-specific event which has different ramifications based on the GUI toolkit being used, so aside from perhaps an extra argument to indicate more information to the user (i.e. "terminal/curses/ansi", "tk", "gnome", w/e). I don't foresee many changes to it.By exposing a low-level styling function, many feature requests become implementable using the Lua API alone. For example, the following snippet can be placed into visrc.lua in order to implement status bar styling (#1128):
And UI_DRAW can be used, for example, to allow tighter integration with debugging tools by visually marking important lines:
And the end result:![image](https://github.com/martanne/vis/assets/25546304/588604fd-26d2-4cc7-a205-e713a7c9ac06)