Skip to content

Instantly share code, notes, and snippets.

@egmontkob
Last active September 17, 2024 13:27
Show Gist options
  • Save egmontkob/eb114294efbcd5adb1944c9f3cb5feda to your computer and use it in GitHub Desktop.
Save egmontkob/eb114294efbcd5adb1944c9f3cb5feda to your computer and use it in GitHub Desktop.
Hyperlinks in Terminal Emulators
@sencer
Copy link

sencer commented Sep 30, 2020

@dcormier
Copy link

@fgarcia
Copy link

fgarcia commented Nov 12, 2020

@dcormier Just web links, it will be 1.5 (in preview) that will also support file links

Copy link

ghost commented Nov 16, 2020

Copy link

ghost commented Nov 19, 2020

This doc is not maintained anymore. Someone SHOULD.

Copy link

ghost commented Nov 19, 2020

I am not an expert at this

@logrusorgru
Copy link

logrusorgru commented Feb 6, 2021

There is no 'backward compatibility' since link URL is hidden and text is just a text. So, if you want to post a link this way, you may found many peoples not found it. Just a text. Like "click this". Without an underline. Without a pointer cursor.`

изображение

xfce4 terminal

@adrian-gierakowski
Copy link

@egmontkob

regarding standard for specifying LINE COLUMN in text file, you wrote:

All this needs cooperation from plenty of parties, probably beginning with a discussion on freedesktop mailing list, followed by a new version of the desktop file specs, followed by implementation, and editors starting to ship corresponding desktop files using these macros or interpreting the URL fragments themselves.

I'm not entirely certain what the best design would be. I'd love to see this happening, I'm happy to cime in in discussions if someone drives it, but I don't have capacity to drive this. And if I just added #L10 to this specification, it would take us nowhere, it presumably wouldn't be sufficient to push all these changes through, and I couldn't implement it in gnome-terminal either.

A much higher level agreement is required on the URI syntax for local files at a given line; that is, an agreement across OSes and desktops and kinds of products (not just terminal emulators). This needs to be followed by implementation in various desktops (such as GNOME). And once it's done, there'll be nothing left to do by terminal emulators, it'll just work.

are you aware of any activity related to this since you wrote the above? If not, what would you recommend should be done to push this forward? Thanks!

@tbross
Copy link

tbross commented Feb 15, 2021

Create a generic alias (tested on MacOS)

alias url=$'printf \'\e]8;;%s\e\\%s\e]8;;\e\\\n\''
url 'http://example.com' 'This is a link'

@drudru
Copy link

drudru commented Apr 7, 2021

@egmontkob - just FYI - I added support for this in Ansi_up a while back. Please add it to your list.
https://github.com/drudru/ansi_up/

@mTvare6
Copy link

mTvare6 commented Apr 19, 2021

How do I check if it terminal supports this feature? So then instead of printing raw text, I just print the url

@ReneDyhr
Copy link

ReneDyhr commented May 5, 2021

Is it possible to make it run a script instead of opening a url?

@lypanov
Copy link

lypanov commented May 5, 2021

Is it possible to make it run a script instead of opening a url?

Thats up to your terminal. I personally override my URL handlers in linux to queue up links in various apps for reading later (Pocket, youtube-dl, Samsung Internet, etc). This is possible at least in Tilix running on my Samsung Tab S6.

@craigbarnes
Copy link

foot is another terminal emulator that supports this (since 1.7.0).

@fun840
Copy link

fun840 commented Aug 22, 2021

is there any parameter to hide the link underline fully? I like the idea of being able to have clickable buttons in the terminal that do things without having to check for cursor position and do math or whatever, and you could use this with file:// to run a program which communicates with the main program, but a dotted underline ruins the effect, especially with buttons bigger than one line.
image

@ismail-yilmaz
Copy link

@fun840

is there any parameter to hide the link underline fully? I like the idea of being able to have clickable buttons in the terminal that do things without having to check for cursor position and do math or whatever, and you could use this with file:// to run a program which communicates with the main program, but a dotted underline ruins the effect, especially with buttons bigger than one line.
image

At the moment, no. The style of hyperlink decorations, or lack thereof, is completely up to the implementing TE.

@Alhadis
Copy link

Alhadis commented Oct 2, 2021

Heads up for anybody who enjoys reading man pages: nascent support for terminal hyperlinking was recently added to GNU Troff's master branch today. Come Groff v1.23.0, references to man pages like

SEE ALSO
	awk(1), ed(1), grep(1), regex(3), re_format(7)

will in hyperlink-supporting terminals be something more along the lines of

SEE ALSO
	awk(1), ed(1), grep(1), regex(3), re_format(7)

(… except those links would point to x-man-page://awk.1 instead of an HTTPS link. 😜 GitHub's filters won't let link to URIs with unrecognised protocols).

I don't recommend it be added to "Supporting applications" lists yet, but just a heads up for those interested.

More info: GNU Troff mailing list announcement

@ZanderBrown
Copy link

Why x-man-page? dnf reports that yelp & khelpcenter provide man:// - but has no providers for x-man-page://

@Alhadis
Copy link

Alhadis commented Oct 2, 2021

@ZanderBrown I imagine it'll be tailored to one's OS, terminal emulator, and/or pager software. On macOS, for example, the URI x-man-page://grep is understood by both Terminal.app and iTerm2. But even on macOS alone, different programs have had different ideas on what a man(1) URL ought to look like.

More extensive research is documented in a utility function I wrote for parsing multiple different man URI formats. Whatever solution Groff settles on for determining the correct URL format, I hope it's less hit-and-miss than my one…

@g-branden-robinson
Copy link

I should note for the sake of full disclosure that a man macro to implement the cross references to which Alhadis refers has not been written. It has, however, been discussed multiple times over the past year on the groff list, and I've pretty much settled on a design. OSC 8 support was a prerequisite for making such a thing really pay dividends on the interface via which most people read man pages. Now that that's done it might prove to be the long pole.

Next to getting man page authors to actually embrace the new macro, that is...if you think the man(7) language is conservative, try meeting the people who write in it!

@g-branden-robinson
Copy link

@lucy
Copy link

lucy commented Oct 28, 2021

weechat is blocked on ncurses adding support for this.

@jasikpark
Copy link

Could https://github.com/trufae/Therm be added to supporting Terminal Emulators? It's an iTerm2 fork, so I've confirmed that it supports the syntax!

image

@SebastianGrans
Copy link

Here's a small python function that does the escaping for you:

def link(uri, label=None, parameters=None):
    if label is None: 
        label = uri
    if parameters is None: 
        parameters = ''

    # OSC 8 ; params ; URI ST <name> OSC 8 ;; ST 
    escape_mask = '\033]8;{};{}\033\\{}\033]8;;\033\\'

    return escape_mask.format(parameters, uri, label)

link()

Examples:

> print(link('http://asdf.com', 'click me')) # A clickable link with the label 'click me' 
click me
> print(link('http://asdf.com')) # If no label is provided, the uri is used as the label
http://asdf.com

@leagris
Copy link

leagris commented Jan 31, 2022

Here is a POSIX-shell implementation with demo: https://gist.github.com/leagris/6443a42b408dfda80c654f808e89c9b2

#!/usr/bin/env sh

# Prints a terminal-clickable hyperlink
# Implements: OSC 8 <URL> ST <Link-text> OSC 8 ST
# See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
#
# @Params
# $1: The hyperlink URL
# $2: The optional hyperlink text (defaults to URL)
#
# @Outputs
# The terminal-clickable hyperlink
#
# shellcheck disable=SC1003 # False positive single-quoted string ends with \
hyperlink(){ printf '\e]8;;%s\e\\%s\e]8;;\e\\' "$1" "${2:-$1}";}


hl=$(
  hyperlink \
    https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda \
    'OSC 8 <URL> ST <Link-text> OSC 8 ST'
)

printf 'Demo of the %s sequence to make hyperlinks clickable in terminal:\n\n' \
  "$hl"

hyperlink https://www.example.com/ 'Example link'
printf \\n
hyperlink https://notext.example.com/
printf \\n

@sje30
Copy link

sje30 commented May 3, 2022

Emacs 28.1 now supports these hyperlinks, see the following extract from the NEWS file:

*** Support for OSC escape sequences.
Adding the new function 'comint-osc-process-output' to
'comint-output-filter-functions' enables the interpretation of OSC
("Operating System Command") escape sequences in comint buffers.  By
default, only OSC 8, for hyperlinks, and OSC 7, for directory
tracking, are acted upon.  Adding more entries to
'comint-osc-handlers' allows a customized treatment of further escape
sequences.

e.g. the following setting will help create hyperlinks in shells.

(add-to-list 'comint-output-filter-functions 'comint-osc-process-output)

@bvtthead
Copy link

Working on a patch for suckless's st to support OSC 8 over at st-osc-8

@logrusorgru
Copy link

This misfeature should be dropped. And this proposal, to drop it, is also a contributing. @egmontkob, just spams all terminals developers, and removes all constructive critics. Good job.

@lypanov
Copy link

lypanov commented Sep 3, 2022

On a more productive note I've used the OSC 8 spec to create an e-ink environment for reading e-mail / RSS / Mastodon to force myself to do so on a weekly vs daily basis. This based around a custom fork of alot (a Python email client) to deal with OSC 8 output of mailcap entries, a wrapper around elinks which can transform it's hyperlink output into OSC 8, and a custom terminal emulator running over VNC (which runs well on my Boox eink reader) which supports OSC 8 (built upon the awesome mtm). Hyperlinks are navigated to via keyboard shortcuts vs mouse (in my case they are multiplexed to multiple services via a xdg-open replacement, they go to either Pinboard, or YouTube Watch Later). As per usual, I really should open source all of this. But I'm time limited and never happy with my code.

@egmontkob
Copy link
Author

I've removed most of the messages from a counterproductive conversation (and will also remove followup messages, if any).

In case anyone is interested, I've made web.archive.org crawl the page before every deletion (and will do so in case of followup messages, too), so everything is still available there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment