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 ^O series to handle OSC-8 id= search and URIs #251
Conversation
P.S.: that web form seems to not like reverse solidus aka backslash, i do not know how to write the regular expression correctly. Sorry. |
Hello. I am looking into this since yesterday, and repainting was really, really bad. It is very much better now locally, but i still have some problems with ^O^N and ^O^P repositioning. I hope i get this fixed until tomorrow, and i think then this pull request had been polished even without voice of "the expert". I will push it then, and "try to" attach a nice grotty(1) manual file for testing purposes! Oh, i hope you like it then. |
With "Add shared static osc8_search_xy(), properly restore search pattern.." i think we now really handle movement and repaint graceful (expensive though). I still do not use the builtin shell_quote because of our specific needs. This could of course be changed, it would likely look better in almost all cases (when user is prompted to comply visiting external manual etc). One problem is left, a sole "#" URI without any OSC 8 parameter. When then using ^O^O to follow it, it will not "find the pattern". This could be special cased, but seems unlikely in practice. Unfortunately i cannot attach the file! Not as tgz gz whatever, they say "We don't support that file type". $ curl -I https://ftp.sdaoden.eu/z.cat.gz I think this is it now. I hope you consider its inclusion in less. |
Works flawless for me. |
This seems like a pretty big change for a rather niche feature. Couldn't you just temporary turn off -R if you want to search for text in an OSC8 sequence? |
Hm. I would not call it a "niche feature". The next release of groff will bring support for OSC-8 generation in Maybe they get the taste of it then, finally. And come back to the idea It is .. a big change, but the overall change in between the master and
Following external references via LESSOSC8OPEN or the builtin manual (Readily prepared manuals, simply for "$ less --RAW-CONTROL-CHARS
A huge one (~ 1MB) of my mailer, with hundreds of references.
Of the mdocmx extension of the roff mdoc manual macros.
Of the preprocessor for it.) P.S.: i have had to add another commit to the topic branch, Thank you for your message! Ciao and a good and healthy 2023 i wish from Germany! |
Sorry to be so noisy. I had seen you dropped K&R for ISO prototypes. (I added four more commits, in order). Thank you. Ciao and greetings. |
Can someone clarify something for me? I thought the idea of OSC-8 links was that the terminal handles them. You click on them or something to navigate to the link. Why does less need to do anything other than pass the sequence to the terminal? |
@gwsw OSC-8 has a possibility to change how we interact with man pages, and The goal of OSC-8 was perhaps just for that: to display a label instead of a complete URL. Clicking on such a link would open another OS window. And to enable that, the initial OSC-8 support focussed on passing OSC-8 sequence to the terminal. That works all well for Why manpage browsing would benefit from OSC-8? Most man pages end with a section Here's one way it could work (not sure what the PR actually does):
Just these 3 steps will convert our favorite single page navigator less to a multi page navigator. Perhaps a OSC-8 sequence like Note: changing the terminal size will disrupt line numbers, and user won't jump to the same line. Not sure if there is another way to mark a location in a document. Though it's not as big a problem imo... |
Hm. Pushing again as i have seen that i re-brought in the get_seg() function that was gone in less version 244 if that look was correct. Also some "constant" stuff (step_char() is not yet constant in comparison to step_charc() which already is; but could; anyhow). OSC8 on the terminal, yes. If people realize what they get, it could be they start generating manual pages (or converters which do that, effectively) etc which use this feature. You get a notion as via browsing a HTML document in a text mode browser like lynx. I still have the manuals available via download. They were generated via my own mdoc macros for UNIX manuals, which the groff maintainer did not accept for upstreaming, but still they show what is possible. Because they base upon upstream mdoc macros, we only can apply [NUMBER] tags to announce anchors/URLs, not prepend them like lynx(1) does, nor simply enwrap the actual "URL text" as is done by graphical browsers. (Ie, "paint it blue", or the like.) Ie, look at with patched less -RIFe, scroll point-of-interest into view with ^O^I, scroll back with '', just as usual. Small file: |
P.S.: "current" GNU roff / groff generates the needed IDs, finally, and at least. |
@sdaoden, I apologize for my lack of responsiveness to this issue. I have been studying your changes and I have one question. Can you explain the purpose of searching for an id value? From my reading, the main purpose of the id parameter is to allow terminal emulators to highlight the appropriate pieces of text on mouseover. Given that purpose, I don't see why a user would have a need to search for an id value. |
Sure, Mr. Nudelman. To reiterate that the "standard" for OSC8 allows key=value pairs, I personally always found that meaning of ID strange, in But if one extends the meaning of that ID to something This can of course be anything, ie, strings, like a UNIX manual So in short. In addition to the ^O^P and ^O^N, and ^O^O commands, I linked example documents which give this fully interactive But i know people go to the web to look at HTMLified manual pages Thus i for one would add that ^O^I, speculating it will happen for P.S.: it also has to be said that instrumenting manual page source |
@sdaoden Thanks very much for the detailed explanation. When you refer to the "year-long unmaintained document" I assume you're talking about https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda. Is there any kind of formal RFC that specifies the OSC8 behavior other than that page? I'm a little leery about implementing features simply based on you or I "speculating" on how OSC8 might be used in the future. This might lock less into doing something that can't easily be changed due to backwards compatibility, but is in conflict with what actually happens in the future. |
I do not think there is anything else on the internet. I think he is the originator of the OSC8 feature you have implemented in less(1). To reiterate that ^O^[NPO] is unaffected of your doubts. Regarding ^O^I alone i find your statement a bit strong. Hm, i mean .. one could think of extending this even, you know, in making it regular, maybe naming it ^O/ instead (^O^S will not do), so that any user input is searched for only in OSC8 content, VALUEs of any given KEY=, as well as the link itself? |
.. this would be an "any substring matches" search then, affected by the usual less semantics of case-sensitive. I had to look on how to implement this, then. |
(P.S.: to clarify: the one who "picked it up" is on the GNU groff mailing-list for some years.) |
Thanks, your code has been very useful for reference, although I've done the implementation somewhat differently. I have implemented your ^O^N, ^O^P and ^O^O commands. The ^O^O command does open the #-style links you have in your example files, and also file: links which I think your code didn't do. It also allows the user to use environment variables to configure how to open links. I have not yet implemented a search feature like your ^O^I. Given that the URI and id= parameters are not visible to the user, I'm still not convinced that a user would often want to search for them. How would he even know what id values are used in the file? Anyway, the user could always toggle -R and search for them normally. It can be added later if it turns out to be useful. Any feedback would be appreciated. |
Hello! That is wonderful news!! (Of course i am .. but only a bit.) |
^O^L does not seem to do what is documented (anything, in fact). I find the LESS_OSC8_xxx thing a bit excessive compared to my single "muxer" approach; in general i have the impression that "muxing" is preferred "by the people", but then again your omnipresent program has a multi-decade long history with its LESSOPEN mechanism, so if you prefer a different one now, then surely for a reason. The manual says LESS_OSC8_xxx but has LESS_OSC_man and LESS_OSC_file typos. I am very happy that you provide a built-in LESS_OSC8_man -- this is very, very cool, and i really look forward that manual pages make use of this feature! It is, despite for the internal #anchor links, what i was hoping for since 2014! You get a completely interactive UNIX manual session simply by following a link, on a normal terminal! Yes. Ah wait. If i follow an OSC-8 #anchor via ^O^O, and then ^O^L, we scroll back to the OSC-8 which was followed. Hm. Well less(1) has '' to jump back where you were last, but you surely had a use case idea. For me on the dark side is that with that lynx-alike manual page extension i have written, which provides that "numbered link view" that lynx invented, as far as i know, i now have to count links on the current screen, to N^O^N there to ^O^O thereafter, but, well, it is a specific thing. ^O^N and ^O^P do not "wrap around" from the bottom to the top and vice versa. Which i got used to. Likely personal taste only. Dear Mr. Nudelman, thanks for bringing this in. |
@sdaoden thanks for your comments. Regarding LESS_OSC8_xxx, my thinking is someone might want to change, for example, their browser (which opens https: links), or their file viewer (which opens file: links) but in general when they do something like that, they want to leave handling of other types of links unchanged. It seems easier to manage this if the handler for each type of link is separate, rather than having to edit a muxer script that handles many different types of links. You could of course set several LESS_OSC8_xxx variables to point to the same script. But perhaps it would be convenient to have a LESS_OSC8_all or something like that, which would handle all link types that don't have a specific handler. ^O^L was a late addition, and I'm not positive it's really needed, but sometimes I would follow an internal link, then navigate around for a while, then want to return to the original link. The navigation may have overwritten the place where '' (quote-quote) would return, so ^O^L seemed somewhat useful. I agree counting links in order to supply a number to ^O^N is not ideal. I'm thinking of allowing link navigation by just clicking on the link with the mouse, when --mouse is enabled. |
Hello. ^O^L i simply have misunderstood it seems. I think if a fresh mind reads this she or he will get that right immediately. I .. was using local modifications for almost ten years and got used to my flow. I can absolutely follow and agree with your thoughts on the individual handlers. (I have never used lessopen myself; i think somewhen "decades ago" FreeBSD activated lesspipe generically, but this is only dim memory -- installed it still is.) Mouse on the terminal i have not used for long (i disable anything but select and paste in the st(1) i use), so i cannot comment on that. Btw i now (sorry for my short breath, i have to finish a DKIM thing until February 1st before Google requires it, and just today finished the RFC 5322 parser) see that ^O^O seems to perform work on an OSC-8 anchor, ie, an OSC8 link without URI target. |
I said But if you think of such, maybe a shortcut to highlight all OSC8 links (not anchors) in (the visible part of) a document would be of interest? If you want to spend real time that "highlight all OSC8 URIs on the screen" mode could actually glue a generated "N" to the URI and highlight only that. That is a lot of work, but then, at least on the current screen, less(1) would act almost like lynx(1) does. |
Can you give a specific example of this? As far as I know, ^O^N ignores OSC8 sequences where the URI or the marked text is empty. So ^O^O shouldn't operate on them if they aren't selected by ^O^N. For example, in your code-mailx-1.cat file, ^O^N at the beginning of the file goes to the NAME link on line 24, and ignores the three anchors on lines 3, 6 and 23. |
Hello! No, it does not, actually. The difference in between my patch and yours is that your ^O^N interprets these anchor-only OSC8 sequences as links. So i used a plain number-sign "#" as an "anchor URI". |
P.S.: but you can see, that ^O^N finds the "anchor-only", and ^O^O then searches and says "OSC8 link not found". |
P.P.S.: eh! Of course this browser-thing mis-interpreted the things, i had written HTML SPAN and IMG markup tags. |
P.P.P.S.: ;) |
P.P.P.P.S.: on the other hand your approach is just another way of doing things. And converters can, if they do it, simply generate an appropriate -- to your approach -- OSC8 link. What do you think about the "highlight all links" idea? |
In 846bc30 less ignores URIs consisting of a single "#". Although I'm a little uneasy that we seem to be inventing a spec ourselves here. I'm not sure what the user experience would be with the proposed "highlight all links" command. If you highlighted all links and then pressed ^O^O, what would happen? Would it open the first one on the page? I guess I'm not fully understanding this proposal or what it solves. |
Hello! Yes, it was unfortunate how it was done, i tried what i could; i then unsubscribed from the groff lists. Regarding "if you highlighted all links and then pressed ^O^O, what would happen?" I was only thinking that on a normal console without specific OSC8 support, and unless the document is prepared like my example files that you know, with "links standing out in blue", for example, one cannot the links at all. One can hop ^O^N etc link by link, or with trial and error do "10^O^N", for example. (What would need screen reflow and lots of work i think would be that less(1) does something like lynx(1) does then: lynx places a "[NUMBER]" tag right before each href, say, "[3]", and if you then type "3" it says "Follow link (or goto link or page) number: 3", and you only need to hit RETURN to get there. This would likely be the super-luxury variant of a ^O^H :-) Then again i admit that i personally never used a terminal with real OSC8 support, but i presume most people do, so if the terminal already highlights OSC8 links on the screen the functionality as such, but especially the super-luxury variant, is possibly overkill. But, you know, this is where i came from. I came from these lynx(1) user experience impressions, and just wanted to mimic it for plain text. And since 2014 i can look at my own manuals (and did some for NetBSD in the meantime, to get some traction for the idea, and they did install HTML manuals, but, well; this was pre-OSC8, though), and i read through the text, and then simply typed ^O^I and a number, and got there. But i am super happy with that less has now; it is just that, you know, if i see the table of contents, and have to ^O^N repeatedly, or "do binary search", it, well, it sucks a bit. For example,
Without the numbers already such a small and sequential and one-per-line thing is hard for i think most human brains, regarding "NUMBER^O^N". Ciao! (P.S.: i only threw away my topic branch, i was unaware that the issue is then "closed"..) |
As promised in Issue #248, here is a pull request to really and truly handle OSC 8 links with all its powers, instead of just that 2014 hack to make the mdocmx roff macro references work on the terminal, adjusted to use OSC 8.
Even though just finished an hour ago .. i think it is working fine, with the exception as below.
. ^O^I text - will search for the OSC 8 id= "text".
. ^O^N - searches for the next OSC 8 link aka URI.
. ^O^P - searches for the previous OSC 8 link aka URI.
. ^O^O - opens the currently selected OSC 8 link aka URI with the shell command given in the environment variable LESSOSC8OPEN; it will be passed as a properly quoted single argument.
If LESSOSC8OPEN is not set, "man:NAME((.*))?" style links are still understood and opened via man(1).
The good intent of this is reflected by the fact that search.c now has 2442 lines!
So i had prepared a test file with bogus entries and such, and it works very nicely.
I for one see only two problems:
. in the status line when you see those ~ lines because we scrolled "past EOF" there will be input artifacts, ie the repainting is somehow not clean, if you ^O.. ^O.. like grazy at least.
That is to say that those ~ lines may look like "~^O^N", i do not know why.
It is a repainting issue of course.
. i cannot figure out how to configure the search so that for ^O^N and ^O^P do not wrap but get the first / the last link right; for example, in a test file with 34 id=s, i ^O^I34, and (it has a link to, not only an id aka anchor) ^O^N will say "No OSC 8 link found (press RETURN)", but if i then ^O^N again, it will find the links in the last line again, it does not step over it.
Likewise for the first anchor, if i ^O^P, then the search wraps backwards and starts at EOF again.
Other than that .. it is fun! Browsing on the terminal, but in a generic way, not like i did in 2014 with mdocmx only for mdoc man(1)uals using crude hacks!!
I hope you like it!
..and a nice Sunday i wish from Germany.