orbitalquark / textadept

Textadept is a fast, minimalist, and remarkably extensible cross-platform text editor for programmers.
https://orbitalquark.github.io/textadept
MIT License
636 stars 38 forks source link

How to get the number of the last visible line of the in the view shown buffer? #458

Closed oOosys closed 11 months ago

oOosys commented 11 months ago

It seems that the Lua API does not come with the view.last_visible_line in addition to the view.first_visible_line and calculation of the last visible line number using view.first_visible_line + view.lines_on_screen is not helpful in case there are wrapped long lines shown in the view ...

What I need this for? I have implemented Emacs "follow mode" which shows in different views of same buffer the preceding/following lines, but it works correctly only without wrapping of lines switched on in which case the number of lines in the view can be because of wrapping significantly larger than the number of actual buffer lines shown in the view .

orbitalquark commented 11 months ago

You'd probably want to use buffer:doc_line_from_visible(buffer.first_visible_line + buffer.lines_on_screen) (https://orbitalquark.github.io/textadept/api.html#view.doc_line_from_visible). The file-diff module does something similar when it tries to keep split views in sync while scrolling during comparison: https://github.com/orbitalquark/textadept-file-diff/blob/05f6af85f4f36b9ddae303e403f286f36204d249/init.lua#L119-L129

Or it might be view:visible_from_doc_line(). I always get the two confused.

oOosys commented 11 months ago

Thanks for the hints. May you explain a bit more how line wrapping is done? Is the entire buffer wrapped to obtain a new buffer text with actual lines making it necessary to perform correction of line numbering and converting from one line numbering to the other? Is there a mapping of not wrapped line numbers to mapped ones? Probably also view.wrap_count(line_no) can help to re-calculate the line numbers fitting to a view?

orbitalquark commented 11 months ago

Scintilla (Textadept's editing component) handles wrapping. Wrapping does not change any internal structures, it just changes how Scintilla computes and lays out lines for display. The functions I mentioned are used to map actual buffer/document lines to display/visible lines in the view. If you were to ignore the line number margin, think of visible lines as actual, standalone lines. You'd convert visible lines to buffer lines using a function, and vice-versa. Note that more than one visible line can map to a single buffer line. view:wrap_count(line) would tell you how many for a given buffer line.

Hopefully this helps a bit. It's all pretty confusing to me too, and I'm not sure I understand it all.

oOosys commented 11 months ago

Once understood the concept of mapping lines displayed on screen to actual lines of the text is very helpful in dissolving the confusion resulting from not knowing that there are two kinds of line numbering (lines of the text itself as it is and lines of the displayed text taking hidden, wrapped, etc. lines into account) with separate methods of getting the appropriate line numbers of required kind.