Commit 327ee7143905721c894e27c4b0bc5d67f2e662ad

Parents: cecce19ff7ae63d34c46ee3bce15ed6b89a39780

From: Moritz Poldrack <ich@moritz-poldrack.de>
Date: Mon Jul 19 21:37:07 2021 +0700

added hyperlink insertion

		

Stats

codetable.go +3/-0
demo/main.go +4/-0
hyperlinks.go +34/-0

Changeset

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
diff --git a/codetable.go b/codetable.go
index d23db7fef84c16218e680ffcefc084ef1bbb6b43..7962f1ad6ddb99a166b57934eab5019b59fcbb99 100644
--- a/codetable.go
+++ b/codetable.go
@@ -73,4 +73,7 @@ 	// special
 	escape   = "\x1b["
 	set      = "m"
 	escapeTC = "\x1be["
+
+	// hyperlink
+	hyperlink = "\x1b]8;;%s\x1b\\%s\x1b]8;;\x1b\\\n"
 )
diff --git a/demo/main.go b/demo/main.go
index b71a724309fb0d174f3c462d1b53e24cc723ba55..b38a1d3429ef26923136257f7a683aeefd0557d3 100644
--- a/demo/main.go
+++ b/demo/main.go
@@ -8,6 +8,7 @@ 	"git.sr.ht/~poldi1405/go-ansi"
 )
 
 func main() {
+	goto link
 	fmt.Println("Styles:", "normal", ansi.Bold("bold"), ansi.Faint("faint"), ansi.Italic("italic"), ansi.Underscore("underscore"), ansi.DoubleUnderscore("double underscore"), ansi.Blink("blinking"), ansi.FastBlink("blinking fast"), ansi.ReverseVideo("FG and BG exchanged"), "["+ansi.Conceal("concealed")+"]", ansi.Strikethrough("strikethrough"))
 	fmt.Println("Colors:", "default", ansi.Black("black"), ansi.Red("red"), ansi.Green("green"), ansi.Yellow("yellow"), ansi.Blue("blue"), ansi.Magenta("magenta"), ansi.Cyan("cyan"), ansi.White("white"), ansi.Color256(25, "256color"), ansi.ColorTrue(172, 138, 39, "TrueColor"))
 	fmt.Println("Colors (BG):", "default", ansi.BlackBG("black"), ansi.RedBG("red"), ansi.GreenBG("green"), ansi.YellowBG("yellow"), ansi.BlueBG("blue"), ansi.MagentaBG("magenta"), ansi.CyanBG("cyan"), ansi.WhiteBG("white"), ansi.Color256BG(25, "256color"), ansi.ColorTrueBG(172, 138, 39, "TrueColor"))
@@ -56,4 +57,7 @@ 	time.Sleep(500 * time.Millisecond)
 	fmt.Print(ansi.MoveCursor(25, 60), ansi.ReverseVideo("so… where were we?"))
 	time.Sleep(500 * time.Millisecond)
 	fmt.Print(ansi.RestorePos(), ansi.ReverseVideo("We were here"))
+link:
+	fmt.Println(ansi.LinkString("http://example.com", "an example"))
+	fmt.Println(ansi.LinkFile("test.txt", "a file example"))
 }
diff --git a/hyperlinks.go b/hyperlinks.go
new file mode 100644
index 0000000000000000000000000000000000000000..5184b3de7aceb8c1031fc84e00a4d5b5b8b3fbd2
--- /dev/null
+++ b/hyperlinks.go
@@ -0,0 +1,34 @@
+package ansi
+
+import (
+	"fmt"
+	"net/url"
+	"os"
+	"path/filepath"
+)
+
+// Link creates a terminal Hyperlink that can be clicked, if the terminal
+// emulator supports it.
+func Link(target url.URL, text string) string {
+	return fmt.Sprintf(hyperlink, target.String(), text)
+}
+
+func LinkString(target string, text string) string {
+	return fmt.Sprintf(hyperlink, target, text)
+}
+
+func LinkFile(file string, label string) string {
+	hostname, _ := os.Hostname() // no error checking as most clients also accept file:// links without hostname
+
+	path, err := filepath.Abs(file)
+	if err != nil {
+		path = file
+	}
+
+	u := url.URL{
+		Scheme: "file",
+		Host:   hostname,
+		Path:   path,
+	}
+	return Link(u, label)
+}