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)
+}
|