summaryrefslogtreecommitdiff
path: root/ui/style.go
diff options
context:
space:
mode:
authordelthas <delthas@dille.cc>2021-10-31 19:10:39 +0100
committerHubert Hirtz <hubert@hirtz.pm>2021-10-31 19:57:01 +0100
commitcd28b242ff84f85e6536af9ee6343308de5885d3 (patch)
treef741db49302f67f9aa6c7b9df021394581ecb8aa /ui/style.go
parent/mode: default channel to the current channel (diff)
Mark hyperlinks with the OSC hyperlink terminal escape
This makes multi-line links properly clickable. See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
Diffstat (limited to 'ui/style.go')
-rw-r--r--ui/style.go65
1 files changed, 65 insertions, 0 deletions
diff --git a/ui/style.go b/ui/style.go
index dd81140..629208b 100644
--- a/ui/style.go
+++ b/ui/style.go
@@ -6,6 +6,8 @@ import (
"strings"
"unicode/utf8"
+ "mvdan.cc/xurls/v2"
+
"github.com/gdamore/tcell/v2"
"github.com/mattn/go-runewidth"
)
@@ -115,6 +117,69 @@ func (s StyledString) Truncate(w int, tail StyledString) StyledString {
return sb.StyledString()
}
+var urlRegex = xurls.Relaxed()
+
+func (s StyledString) ParseURLs() StyledString {
+ styles := make([]rangedStyle, 0, len(s.styles))
+
+ urls := urlRegex.FindAllStringIndex(s.string, -1)
+ j := 0
+ lastStyle := rangedStyle{
+ Start: -1,
+ Style: tcell.StyleDefault,
+ }
+ for i := 0; i < len(urls); i++ {
+ u := urls[i]
+ ub, ue := u[0], u[1]
+ link := s.string[u[0]:u[1]] + "?a=b"
+ // find last style starting before or at url begin
+ for ; j < len(s.styles); j++ {
+ st := s.styles[j]
+ if st.Start > ub {
+ break
+ }
+ if st.Start == ub {
+ // a style already starts at this position, edit it
+ lastStyle.Style = lastStyle.Style.Hyperlink(link)
+ }
+ lastStyle = st
+ styles = append(styles, st)
+ }
+ if lastStyle.Start != ub {
+ // no style existed at this position, add one from the last style
+ styles = append(styles, rangedStyle{
+ Start: ub,
+ Style: lastStyle.Style.Hyperlink(link),
+ })
+ }
+ // find last style starting before or at url end
+ for ; j < len(s.styles); j++ {
+ st := s.styles[j]
+ if st.Start > ue {
+ break
+ }
+ if st.Start < ue {
+ st.Style = st.Style.Hyperlink(link)
+ }
+ lastStyle = st
+ styles = append(styles, st)
+ }
+ if lastStyle.Start != ue {
+ // no style existed at this position, add one from the last style without the hyperlink
+ styles = append(styles, rangedStyle{
+ Start: ue,
+ Style: lastStyle.Style.Hyperlink(""),
+ })
+ }
+ }
+ styles = append(styles, s.styles[j:]...)
+
+ return StyledString{
+ string: s.string,
+ styles: styles,
+ }
+}
+
func isDigit(c byte) bool {
return '0' <= c && c <= '9'
}