summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-08-14 23:04:05 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2024-08-14 23:04:05 +0900
commit387c6ef664688582ca1be950e2fe260699aa8862 (patch)
tree4478ab1bed3676c1f7ba7059c07f1a1b04b3de22 /src
parent581734c369befcc6544b927042e116e0343a366a (diff)
downloadfzf-387c6ef664688582ca1be950e2fe260699aa8862.tar.gz
Support hyperlinks (OSC 8) in the main window
Close #2557
Diffstat (limited to 'src')
-rw-r--r--src/result.go11
-rw-r--r--src/terminal.go12
-rw-r--r--src/tui/light.go6
-rw-r--r--src/tui/tcell.go19
4 files changed, 35 insertions, 13 deletions
diff --git a/src/result.go b/src/result.go
index e1c20801..f10db19b 100644
--- a/src/result.go
+++ b/src/result.go
@@ -16,6 +16,7 @@ type colorOffset struct {
offset [2]int32
color tui.ColorPair
match bool
+ url *url
}
type Result struct {
@@ -177,8 +178,11 @@ func (result *Result) colorOffsets(matchOffsets []Offset, theme *tui.ColorTheme,
if curr != 0 && idx > start {
if curr < 0 {
color := colMatch
+ var url *url
if curr < -1 && theme.Colored {
- origColor := ansiToColorPair(itemColors[-curr-2], colMatch)
+ ansi := itemColors[-curr-2]
+ url = ansi.color.url
+ origColor := ansiToColorPair(ansi, colMatch)
// hl or hl+ only sets the foreground color, so colMatch is the
// combination of either [hl and bg] or [hl+ and bg+].
//
@@ -194,13 +198,14 @@ func (result *Result) colorOffsets(matchOffsets []Offset, theme *tui.ColorTheme,
}
}
colors = append(colors, colorOffset{
- offset: [2]int32{int32(start), int32(idx)}, color: color, match: true})
+ offset: [2]int32{int32(start), int32(idx)}, color: color, match: true, url: url})
} else {
ansi := itemColors[curr-1]
colors = append(colors, colorOffset{
offset: [2]int32{int32(start), int32(idx)},
color: ansiToColorPair(ansi, colBase),
- match: false})
+ match: false,
+ url: ansi.color.url})
}
}
}
diff --git a/src/terminal.go b/src/terminal.go
index 62d5ae92..1359f35c 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -2460,15 +2460,24 @@ func (t *Terminal) printColoredString(window tui.Window, text []rune, offsets []
var substr string
var prefixWidth int
maxOffset := int32(len(text))
+ var url *url
for _, offset := range offsets {
b := util.Constrain32(offset.offset[0], index, maxOffset)
e := util.Constrain32(offset.offset[1], index, maxOffset)
+ if url != nil && offset.url == nil {
+ url = nil
+ window.LinkEnd()
+ }
substr, prefixWidth = t.processTabs(text[index:b], prefixWidth)
window.CPrint(colBase, substr)
if b < e {
substr, prefixWidth = t.processTabs(text[b:e], prefixWidth)
+ if url == nil && offset.url != nil {
+ url = offset.url
+ window.LinkBegin(url.uri, url.params)
+ }
window.CPrint(offset.color, substr)
}
@@ -2477,6 +2486,9 @@ func (t *Terminal) printColoredString(window tui.Window, text []rune, offsets []
break
}
}
+ if url != nil {
+ window.LinkEnd()
+ }
if index < maxOffset {
substr, _ = t.processTabs(text[index:], prefixWidth)
window.CPrint(colBase, substr)
diff --git a/src/tui/light.go b/src/tui/light.go
index 187ac667..80488bf7 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -1030,13 +1030,13 @@ func cleanse(str string) string {
func (w *LightWindow) CPrint(pair ColorPair, text string) {
_, code := w.csiColor(pair.Fg(), pair.Bg(), pair.Attr())
w.stderrInternal(cleanse(text), false, code)
- w.csi("m")
+ w.csi("0m")
}
func (w *LightWindow) cprint2(fg Color, bg Color, attr Attr, text string) {
hasColors, code := w.csiColor(fg, bg, attr)
if hasColors {
- defer w.csi("m")
+ defer w.csi("0m")
}
w.stderrInternal(cleanse(text), false, code)
}
@@ -1141,7 +1141,7 @@ func (w *LightWindow) CFill(fg Color, bg Color, attr Attr, text string) FillRetu
bg = w.bg
}
if hasColors, resetCode := w.csiColor(fg, bg, attr); hasColors {
- defer w.csi("m")
+ defer w.csi("0m")
return w.fill(text, resetCode)
}
return w.fill(text, w.setBg())
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index d80cd58d..455dcf13 100644
--- a/src/tui/tcell.go
+++ b/src/tui/tcell.go
@@ -604,6 +604,16 @@ func (w *TcellWindow) Print(text string) {
w.printString(text, w.normal)
}
+func (w *TcellWindow) withUrl(style tcell.Style) tcell.Style {
+ if w.uri != nil {
+ style = style.Url(*w.uri)
+ if md := regexp.MustCompile(`id=([^:]+)`).FindStringSubmatch(*w.params); len(md) > 1 {
+ style = style.UrlId(md[1])
+ }
+ }
+ return style
+}
+
func (w *TcellWindow) printString(text string, pair ColorPair) {
lx := 0
a := pair.Attr()
@@ -618,6 +628,7 @@ func (w *TcellWindow) printString(text string, pair ColorPair) {
Blink(a&Attr(tcell.AttrBlink) != 0).
Dim(a&Attr(tcell.AttrDim) != 0)
}
+ style = w.withUrl(style)
gr := uniseg.NewGraphemes(text)
for gr.Next() {
@@ -668,13 +679,7 @@ func (w *TcellWindow) fillString(text string, pair ColorPair) FillReturn {
Underline(a&Attr(tcell.AttrUnderline) != 0).
StrikeThrough(a&Attr(tcell.AttrStrikeThrough) != 0).
Italic(a&Attr(tcell.AttrItalic) != 0)
-
- if w.uri != nil {
- style = style.Url(*w.uri)
- if md := regexp.MustCompile(`id=([^:]+)`).FindStringSubmatch(*w.params); len(md) > 1 {
- style = style.UrlId(md[1])
- }
- }
+ style = w.withUrl(style)
gr := uniseg.NewGraphemes(text)
Loop: