summaryrefslogtreecommitdiff
path: root/ui/style.go
diff options
context:
space:
mode:
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'
}