Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package glow for openSUSE:Factory checked in at 2026-08-21 16:53:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/glow (Old) and /work/SRC/openSUSE:Factory/.glow.new.1258 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "glow" Fri Aug 21 16:53:24 2026 rev:10 rq:1372566 version:3.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/glow/glow.changes 2026-04-10 18:03:19.335375177 +0200 +++ /work/SRC/openSUSE:Factory/.glow.new.1258/glow.changes 2026-08-21 16:54:43.491939998 +0200 @@ -1,0 +2,18 @@ +Thu Aug 13 16:01:36 UTC 2026 - [email protected] + +- Update to 3.0.0: + * This quiet release updates Bubble Tea, Lip Gloss, and Bubbles + to their glorious v2s. While there are no UX changes, there's + a ton great stuff with the Bubble Tea v2 ecosystem, most + notably faster, more accurate rendering. + * This upgrade literally let @andrinoff close a ton of issues. + * fix: adaptive document(s) (#998) + * chore(deps): bump lipgloss to v2.0.6 (#1011) + * chore(v3): prepare v3 (#1009) + * chore: bump bubbletea to v2 (#1002) + * chore: govulncheck bumps (#1004) + +- Remove fix-CVE-2025-47911_CVE-2025-58190.patch (obsolete now + with golang.org/x/net v0.53.0) + +------------------------------------------------------------------- Old: ---- fix-CVE-2025-47911_CVE-2025-58190.patch glow-2.1.2.tar.gz New: ---- glow-3.0.0.tar.gz ----------(Old B)---------- Old: - Remove fix-CVE-2025-47911_CVE-2025-58190.patch (obsolete now with golang.org/x/net v0.53.0) ----------(Old E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ glow.spec ++++++ --- /var/tmp/diff_new_pack.P0oZ8F/_old 2026-08-21 16:54:48.755126883 +0200 +++ /var/tmp/diff_new_pack.P0oZ8F/_new 2026-08-21 16:54:48.757126954 +0200 @@ -21,7 +21,7 @@ %global _lto_cflags %nil Name: glow -Version: 2.1.2 +Version: 3.0.0 Release: 0 Summary: Render markdown on the CLI License: MIT @@ -30,10 +30,9 @@ # vendoring obtained by `osc service manualrun`. See README.suse-maint.md for details. Source1: vendor.tar.zst Source2: README.suse-maint.md -Source3: fix-CVE-2025-47911_CVE-2025-58190.patch BuildRequires: golang-packaging BuildRequires: zstd -BuildRequires: golang(API) >= 1.23 +BuildRequires: golang(API) >= 1.26 %description Glow is a terminal based markdown reader designed from the ground up to bring @@ -78,11 +77,6 @@ %prep %autosetup -a1 -p1 -patch -d vendor/golang.org/x/net/ -p1 -i %{SOURCE3} - -%if 0%{?suse_version} <= 1600 -go mod edit -go=1.25.8 -%endif %build %ifnarch ppc64 @@ -93,7 +87,7 @@ export CGO_CPPFLAGS="%{optflags}" export GOFLAGS="-mod=vendor $BUILDMOD -trimpath -ldflags=-linkmode=external" mkdir -p build -go build -v -ldflags "-s -X main.Version=%{version}" -o build . +go build -ldflags "-s -X main.Version=%{version}" -o build . %install install -D -m 0755 -t %{buildroot}%{_bindir} build/%{name} ++++++ _service ++++++ --- /var/tmp/diff_new_pack.P0oZ8F/_old 2026-08-21 16:54:48.826129405 +0200 +++ /var/tmp/diff_new_pack.P0oZ8F/_new 2026-08-21 16:54:48.830129547 +0200 @@ -1,7 +1,7 @@ <services> - <service name="download_files" mode="manual"/> - <service name="go_modules" mode="manual"> - <param name="compression">zst</param> - </service> + <service name="download_files" mode="manual"/> + <service name="go_modules" mode="manual"> + <param name="compression">zst</param> + </service> </services> ++++++ glow-2.1.2.tar.gz -> glow-3.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/.github/CODEOWNERS new/glow-3.0.0/.github/CODEOWNERS --- old/glow-2.1.2/.github/CODEOWNERS 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/.github/CODEOWNERS 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -* @charmbracelet/everyone diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/README.md new/glow-3.0.0/README.md --- old/glow-2.1.2/README.md 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/README.md 2026-08-11 19:45:40.000000000 +0200 @@ -107,7 +107,7 @@ Or just install it with `go`: ```bash -go install github.com/charmbracelet/glow/v2@latest +go install charm.land/glow/v3@latest ``` ### Build (requires Go 1.21+) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/go.mod new/glow-3.0.0/go.mod --- old/glow-2.1.2/go.mod 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/go.mod 2026-08-11 19:45:40.000000000 +0200 @@ -1,19 +1,19 @@ -module github.com/charmbracelet/glow/v2 +module charm.land/glow/v3 -go 1.25.9 +go 1.26.5 require ( + charm.land/bubbles/v2 v2.1.1 + charm.land/bubbletea/v2 v2.0.8 + charm.land/glamour/v2 v2.0.1 + charm.land/lipgloss/v2 v2.0.6 github.com/atotto/clipboard v0.1.4 github.com/caarlos0/env/v11 v11.3.1 - github.com/charmbracelet/bubbles v0.21.0 - github.com/charmbracelet/bubbletea v1.3.10 - github.com/charmbracelet/glamour v0.10.0 - github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 github.com/charmbracelet/log v0.4.2 github.com/charmbracelet/x/editor v0.1.0 github.com/dustin/go-humanize v1.0.1 github.com/fsnotify/fsnotify v1.9.0 - github.com/mattn/go-runewidth v0.0.19 + github.com/mattn/go-runewidth v0.0.24 github.com/mitchellh/go-homedir v1.1.0 github.com/muesli/gitcha v0.3.0 github.com/muesli/go-app-paths v0.2.2 @@ -21,12 +21,12 @@ github.com/muesli/reflow v0.3.0 github.com/muesli/roff v0.1.0 github.com/muesli/termenv v0.16.0 - github.com/sahilm/fuzzy v0.1.1 + github.com/sahilm/fuzzy v0.1.3 github.com/spf13/cobra v1.10.2 github.com/spf13/viper v1.21.0 - golang.org/x/sys v0.42.0 - golang.org/x/term v0.41.0 - golang.org/x/text v0.32.0 + golang.org/x/sys v0.47.0 + golang.org/x/term v0.42.0 + golang.org/x/text v0.39.0 mvdan.cc/sh/v3 v3.13.1 ) @@ -34,23 +34,25 @@ github.com/alecthomas/chroma/v2 v2.14.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect - github.com/charmbracelet/x/ansi v0.10.1 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13 // indirect + github.com/charmbracelet/colorprofile v0.4.3 // indirect + github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect + github.com/charmbracelet/ultraviolet v0.0.0-20260811164956-006e29f97886 // indirect + github.com/charmbracelet/x/ansi v0.11.8 // indirect + github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect - github.com/clipperhouse/uax29/v2 v2.2.0 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect + github.com/charmbracelet/x/termios v0.1.1 // indirect + github.com/charmbracelet/x/windows v0.2.2 // indirect + github.com/clipperhouse/displaywidth v0.11.0 // indirect + github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/dlclark/regexp2 v1.11.0 // indirect - github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.4.1 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-localereader v0.0.1 // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect - github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/mango v0.2.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect @@ -64,10 +66,11 @@ github.com/spf13/pflag v1.0.10 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/yuin/goldmark v1.7.8 // indirect + github.com/yuin/goldmark v1.7.17 // indirect github.com/yuin/goldmark-emoji v1.0.5 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect - golang.org/x/net v0.40.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sync v0.22.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/go.sum new/glow-3.0.0/go.sum --- old/glow-2.1.2/go.sum 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/go.sum 2026-08-11 19:45:40.000000000 +0200 @@ -1,3 +1,11 @@ +charm.land/bubbles/v2 v2.1.1 h1:7r55WzBxpo/R3z98hGmY7KKPd3ET6vsf0Fb9sDHOV60= +charm.land/bubbles/v2 v2.1.1/go.mod h1:GE6M31gaWZVXzGw73OeuTTgy4lX+OtkH0E5ymnNsHxo= +charm.land/bubbletea/v2 v2.0.8 h1:SxTJMhCAI3lbPmy4SgX5LWZ24AdINr4I6UEqzZvYJuY= +charm.land/bubbletea/v2 v2.0.8/go.mod h1:2SkdgoTXluXJHOUwAoRlRXF/28vklb1rFl6GcgV1/ss= +charm.land/glamour/v2 v2.0.1 h1:xl+r00A4aJWU0z8fgwKd9fQQ4rsphqGUzuEiXZP5n+c= +charm.land/glamour/v2 v2.0.1/go.mod h1:jo9z8XqVKPeEFMVdvCRLGk++RyJ3CdUwgNr7EvXLw3k= +charm.land/lipgloss/v2 v2.0.6 h1:EaGKeuA8FvF+v2BT5VmZd2LoYLaMZJXA5n34th8nCIQ= +charm.land/lipgloss/v2 v2.0.6/go.mod h1:ipDDJNSGa1hlwDtSfW1s2/xR8Vdhbut4PXh2zEKZd0Q= github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE= github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= @@ -8,38 +16,40 @@ github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= -github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= +github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= +github.com/aymanbagabas/go-udiff v0.4.1/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= -github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs= -github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg= -github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= -github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= -github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY= -github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk= +github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= +github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= -github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= -github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/ultraviolet v0.0.0-20260811164956-006e29f97886 h1:rdnVWKgJpTVXKuKuJyxDJ+NFJdUaUqGvyGy61OcvlbA= +github.com/charmbracelet/ultraviolet v0.0.0-20260811164956-006e29f97886/go.mod h1:nAw0d9PhFp1qdzi2xhQU5YOu5sVpDIHWlaW2Uz/bCro= +github.com/charmbracelet/x/ansi v0.11.8 h1:JMFwp0CgDC2+jcOB162HH5k7I3FVbgFSMMYg7dSPBQQ= +github.com/charmbracelet/x/ansi v0.11.8/go.mod h1:ZNN+3mXny/516oTQPLMPIBeSINvNJJQ8uQXDgbeJxY0= +github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= +github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/editor v0.1.0 h1:p69/dpvlwRTs9uYiPeAWruwsHqTFzHhTvQOd/WVSX98= github.com/charmbracelet/x/editor v0.1.0/go.mod h1:oivrEbcP/AYt/Hpvk5pwDXXrQ933gQS6UzL6fxqAGSA= -github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= -github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA= +github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f/go.mod h1:IfZAMTHB6XkZSeXUqriemErjAWCCzT0LwjKFYCZyw0I= github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI= github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= -github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= -github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= +github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= +github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM= +github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k= +github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= +github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= +github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= +github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -48,8 +58,6 @@ github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= @@ -77,21 +85,17 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.4.1 h1:1EO+WB73+EH8EVbzlrG3KLAfEypQWVHIBqlTf+2hNss= +github.com/lucasb-eyer/go-colorful v1.4.1/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= -github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= -github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU= +github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/gitcha v0.3.0 h1:+PJkVKrDXVB0VgRn/yVx2CqSVSDGMSepzvohsCrPYtQ= @@ -125,8 +129,8 @@ github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ= github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= -github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= -github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/sahilm/fuzzy v0.1.3 h1:juByESSS32nVD81vr6tHmKmA/8zde7gE+x5CLxrzXPU= +github.com/sahilm/fuzzy v0.1.3/go.mod h1:au6//VbVSqu6DFrkL2CfjlJ5iURpNCPeE+1GwY3XsT8= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= @@ -149,24 +153,25 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= -github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.17 h1:p36OVWwRb246iHxA/U4p8OPEpOTESm4n+g+8t0EE5uA= +github.com/yuin/goldmark v1.7.17/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk= github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= -golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= +golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/main.go new/glow-3.0.0/main.go --- old/glow-2.1.2/main.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/main.go 2026-08-11 19:45:40.000000000 +0200 @@ -15,12 +15,11 @@ "mvdan.cc/sh/v3/shell" + "charm.land/glamour/v2" + "charm.land/glamour/v2/styles" + "charm.land/glow/v3/ui" + "charm.land/glow/v3/utils" "github.com/caarlos0/env/v11" - "github.com/charmbracelet/glamour" - "github.com/charmbracelet/glamour/styles" - "github.com/charmbracelet/glow/v2/ui" - "github.com/charmbracelet/glow/v2/utils" - "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/log" gap "github.com/muesli/go-app-paths" "github.com/spf13/cobra" @@ -292,7 +291,6 @@ // initialize glamour r, err := glamour.NewTermRenderer( - glamour.WithColorProfile(lipgloss.ColorProfile()), utils.GlamourStyle(style, isCode), glamour.WithWordWrap(int(width)), //nolint:gosec glamour.WithBaseURL(baseURL), @@ -402,7 +400,7 @@ rootCmd.PersistentFlags().StringVar(&configFile, "config", "", fmt.Sprintf("config file (default %s)", viper.GetViper().ConfigFileUsed())) rootCmd.Flags().BoolVarP(&pager, "pager", "p", false, "display with pager") rootCmd.Flags().BoolVarP(&tui, "tui", "t", false, "display with tui") - rootCmd.Flags().StringVarP(&style, "style", "s", styles.AutoStyle, "style name or JSON path") + rootCmd.Flags().StringVarP(&style, "style", "s", "auto", "style name or JSON path") rootCmd.Flags().UintVarP(&width, "width", "w", 0, "word-wrap at width (set to 0 to disable)") rootCmd.Flags().BoolVarP(&showAllFiles, "all", "a", false, "show system files and directories (TUI-mode only)") rootCmd.Flags().BoolVarP(&showLineNumbers, "line-numbers", "l", false, "show line numbers (TUI-mode only)") @@ -421,7 +419,7 @@ _ = viper.BindPFlag("showLineNumbers", rootCmd.Flags().Lookup("line-numbers")) _ = viper.BindPFlag("all", rootCmd.Flags().Lookup("all")) - viper.SetDefault("style", styles.AutoStyle) + viper.SetDefault("style", "auto") viper.SetDefault("width", 0) viper.SetDefault("all", true) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/style.go new/glow-3.0.0/style.go --- old/glow-2.1.2/style.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/style.go 2026-08-11 19:45:40.000000000 +0200 @@ -1,6 +1,6 @@ package main -import "github.com/charmbracelet/lipgloss" +import "charm.land/lipgloss/v2" var ( keyword = lipgloss.NewStyle(). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/config.go new/glow-3.0.0/ui/config.go --- old/glow-2.1.2/ui/config.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/config.go 2026-08-11 19:45:40.000000000 +0200 @@ -15,6 +15,5 @@ Path string // For debugging the UI - HighPerformancePager bool `env:"GLOW_HIGH_PERFORMANCE_PAGER" envDefault:"true"` - GlamourEnabled bool `env:"GLOW_ENABLE_GLAMOUR" envDefault:"true"` + GlamourEnabled bool `env:"GLOW_ENABLE_GLAMOUR" envDefault:"true"` } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/editor.go new/glow-3.0.0/ui/editor.go --- old/glow-2.1.2/ui/editor.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/editor.go 2026-08-11 19:45:40.000000000 +0200 @@ -1,7 +1,7 @@ package ui import ( - tea "github.com/charmbracelet/bubbletea" + tea "charm.land/bubbletea/v2" "github.com/charmbracelet/x/editor" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/pager.go new/glow-3.0.0/ui/pager.go --- old/glow-2.1.2/ui/pager.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/pager.go 2026-08-11 19:45:40.000000000 +0200 @@ -7,12 +7,12 @@ "strings" "time" + "charm.land/bubbles/v2/viewport" + tea "charm.land/bubbletea/v2" + "charm.land/glamour/v2" + "charm.land/glow/v3/utils" + "charm.land/lipgloss/v2" "github.com/atotto/clipboard" - "github.com/charmbracelet/bubbles/viewport" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/glamour" - "github.com/charmbracelet/glow/v2/utils" - "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/log" "github.com/fsnotify/fsnotify" runewidth "github.com/mattn/go-runewidth" @@ -26,56 +26,7 @@ lineNumberWidth = 4 ) -var ( - pagerHelpHeight int - - mintGreen = lipgloss.AdaptiveColor{Light: "#89F0CB", Dark: "#89F0CB"} - darkGreen = lipgloss.AdaptiveColor{Light: "#1C8760", Dark: "#1C8760"} - - lineNumberFg = lipgloss.AdaptiveColor{Light: "#656565", Dark: "#7D7D7D"} - - statusBarNoteFg = lipgloss.AdaptiveColor{Light: "#656565", Dark: "#7D7D7D"} - statusBarBg = lipgloss.AdaptiveColor{Light: "#E6E6E6", Dark: "#242424"} - - statusBarScrollPosStyle = lipgloss.NewStyle(). - Foreground(lipgloss.AdaptiveColor{Light: "#949494", Dark: "#5A5A5A"}). - Background(statusBarBg). - Render - - statusBarNoteStyle = lipgloss.NewStyle(). - Foreground(statusBarNoteFg). - Background(statusBarBg). - Render - - statusBarHelpStyle = lipgloss.NewStyle(). - Foreground(statusBarNoteFg). - Background(lipgloss.AdaptiveColor{Light: "#DCDCDC", Dark: "#323232"}). - Render - - statusBarMessageStyle = lipgloss.NewStyle(). - Foreground(mintGreen). - Background(darkGreen). - Render - - statusBarMessageScrollPosStyle = lipgloss.NewStyle(). - Foreground(mintGreen). - Background(darkGreen). - Render - - statusBarMessageHelpStyle = lipgloss.NewStyle(). - Foreground(lipgloss.Color("#B6FFE4")). - Background(green). - Render - - helpViewStyle = lipgloss.NewStyle(). - Foreground(statusBarNoteFg). - Background(lipgloss.AdaptiveColor{Light: "#f2f2f2", Dark: "#1B1B1B"}). - Render - - lineNumberStyle = lipgloss.NewStyle(). - Foreground(lineNumberFg). - Render -) +var pagerHelpHeight int type ( contentRenderedMsg string @@ -107,9 +58,7 @@ func newPagerModel(common *commonModel) pagerModel { // Init viewport - vp := viewport.New(0, 0) - vp.YPosition = 0 - vp.HighPerformanceRendering = config.HighPerformancePager + vp := viewport.New() m := pagerModel{ common: common, @@ -121,14 +70,14 @@ } func (m *pagerModel) setSize(w, h int) { - m.viewport.Width = w - m.viewport.Height = h - statusBarHeight + m.viewport.SetWidth(w) + m.viewport.SetHeight(h - statusBarHeight) if m.showHelp { if pagerHelpHeight == 0 { pagerHelpHeight = strings.Count(m.helpView(), "\n") } - m.viewport.Height -= (statusBarHeight + pagerHelpHeight) + m.viewport.SetHeight(m.viewport.Height() - (statusBarHeight + pagerHelpHeight)) } } @@ -174,7 +123,7 @@ } m.state = pagerStateBrowse m.viewport.SetContent("") - m.viewport.YOffset = 0 + m.viewport.SetYOffset(0) m.unwatchFile() } @@ -185,7 +134,7 @@ ) switch msg := msg.(type) { - case tea.KeyMsg: + case tea.KeyPressMsg: switch msg.String() { case "q", keyEsc: if m.state != pagerStateBrowse { @@ -194,26 +143,14 @@ } case "home", "g": m.viewport.GotoTop() - if m.viewport.HighPerformanceRendering { - cmds = append(cmds, viewport.Sync(m.viewport)) - } case "end", "G": m.viewport.GotoBottom() - if m.viewport.HighPerformanceRendering { - cmds = append(cmds, viewport.Sync(m.viewport)) - } case "d": - m.viewport.HalfViewDown() - if m.viewport.HighPerformanceRendering { - cmds = append(cmds, viewport.Sync(m.viewport)) - } + m.viewport.HalfPageDown() case "u": - m.viewport.HalfViewUp() - if m.viewport.HighPerformanceRendering { - cmds = append(cmds, viewport.Sync(m.viewport)) - } + m.viewport.HalfPageUp() case "e": lineno := int(math.RoundToEven(float64(m.viewport.TotalLineCount()) * m.viewport.ScrollPercent())) @@ -239,9 +176,6 @@ case "?": m.toggleHelp() - if m.viewport.HighPerformanceRendering { - cmds = append(cmds, viewport.Sync(m.viewport)) - } } // Glow has rendered the content @@ -249,9 +183,6 @@ log.Info("content rendered", "state", m.state) m.setContent(string(msg)) - if m.viewport.HighPerformanceRendering { - cmds = append(cmds, viewport.Sync(m.viewport)) - } cmds = append(cmds, m.watchFile) // The file was changed on disk and we're reloading it @@ -301,25 +232,26 @@ ) showStatusMessage := m.state == pagerStateStatusMessage + styles := m.common.styles // Logo - logo := glowLogoView() + logo := glowLogoView(m.common.styles) // Scroll percent percent := math.Max(minPercent, math.Min(maxPercent, m.viewport.ScrollPercent())) scrollPercent := fmt.Sprintf(" %3.f%% ", percent*percentToStringMagnitude) if showStatusMessage { - scrollPercent = statusBarMessageScrollPosStyle(scrollPercent) + scrollPercent = styles.statusBarMessageScrollPosStyle(scrollPercent) } else { - scrollPercent = statusBarScrollPosStyle(scrollPercent) + scrollPercent = styles.statusBarScrollPosStyle(scrollPercent) } // "Help" note var helpNote string if showStatusMessage { - helpNote = statusBarMessageHelpStyle(" ? Help ") + helpNote = styles.statusBarMessageHelpStyle(" ? Help ") } else { - helpNote = statusBarHelpStyle(" ? Help ") + helpNote = styles.statusBarHelpStyle(" ? Help ") } // Note @@ -336,9 +268,9 @@ ansi.PrintableRuneWidth(helpNote), )), ellipsis) if showStatusMessage { - note = statusBarMessageStyle(note) + note = styles.statusBarMessageStyle(note) } else { - note = statusBarNoteStyle(note) + note = styles.statusBarNoteStyle(note) } // Empty space @@ -351,9 +283,9 @@ ) emptySpace := strings.Repeat(" ", padding) if showStatusMessage { - emptySpace = statusBarMessageStyle(emptySpace) + emptySpace = styles.statusBarMessageStyle(emptySpace) } else { - emptySpace = statusBarNoteStyle(emptySpace) + emptySpace = styles.statusBarNoteStyle(emptySpace) } fmt.Fprintf(b, "%s%s%s%s%s", @@ -402,7 +334,7 @@ s = strings.Join(lines, "\n") } - return helpViewStyle(s) + return m.common.styles.helpViewStyle(s) } // COMMANDS @@ -420,14 +352,14 @@ // This is where the magic happens. func glamourRender(m pagerModel, markdown string) (string, error) { - trunc := lipgloss.NewStyle().MaxWidth(m.viewport.Width - lineNumberWidth).Render + trunc := lipgloss.NewStyle().MaxWidth(m.viewport.Width() - lineNumberWidth).Render - if !config.GlamourEnabled { + if !m.common.cfg.GlamourEnabled { return markdown, nil } isCode := !utils.IsMarkdownFile(m.currentDocument.Note) - width := max(0, min(int(m.common.cfg.GlamourMaxWidth), m.viewport.Width)) //nolint:gosec + width := max(0, min(int(m.common.cfg.GlamourMaxWidth), m.viewport.Width())) //nolint:gosec if isCode { width = 0 } @@ -464,7 +396,7 @@ var content strings.Builder for i, s := range lines { if isCode || m.common.cfg.ShowLineNumbers { - content.WriteString(lineNumberStyle(fmt.Sprintf("%"+fmt.Sprint(lineNumberWidth)+"d", i+1))) + content.WriteString(m.common.styles.lineNumberStyle(fmt.Sprintf("%"+fmt.Sprint(lineNumberWidth)+"d", i+1))) content.WriteString(trunc(s)) } else { content.WriteString(s) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/stash.go new/glow-3.0.0/ui/stash.go --- old/glow-2.1.2/ui/stash.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/stash.go 2026-08-11 19:45:40.000000000 +0200 @@ -8,12 +8,12 @@ "strings" "time" - "github.com/charmbracelet/bubbles/paginator" - "github.com/charmbracelet/bubbles/spinner" - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "charm.land/bubbles/v2/paginator" + "charm.land/bubbles/v2/spinner" + "charm.land/bubbles/v2/textinput" + tea "charm.land/bubbletea/v2" "github.com/charmbracelet/log" + "github.com/dustin/go-humanize/english" "github.com/muesli/reflow/ansi" "github.com/muesli/reflow/truncate" "github.com/sahilm/fuzzy" @@ -29,25 +29,6 @@ var stashingStatusMessage = statusMessage{normalStatusMessage, "Stashing..."} -var ( - dividerDot = darkGrayFg.SetString(" • ") - dividerBar = darkGrayFg.SetString(" │ ") - - logoStyle = lipgloss.NewStyle(). - Foreground(lipgloss.Color("#ECFD65")). - Background(fuchsia). - Bold(true) - - stashSpinnerStyle = lipgloss.NewStyle(). - Foreground(gray) - stashInputPromptStyle = lipgloss.NewStyle(). - Foreground(yellowGreen). - MarginRight(1) - stashInputCursorStyle = lipgloss.NewStyle(). - Foreground(fuchsia). - MarginRight(1) -) - // MSG type ( @@ -82,8 +63,28 @@ cursor int } -// map sections to their associated types. -var sections = map[sectionKey]section{} +// newSections returns the default set of sections. +func newSections() map[sectionKey]section { + return map[sectionKey]section{ + documentsSection: { + key: documentsSection, + paginator: paginator.Model{Type: paginator.Dots}, + }, + filterSection: { + key: filterSection, + paginator: paginator.Model{Type: paginator.Dots}, + }, + } +} + +// stylePaginators updates the paginators with the current styles. +func (m *stashModel) stylePaginators(styles Styles) { + for i := range m.sections { + p := &m.sections[i].paginator + p.ActiveDot = styles.brightGrayFg("•") + p.InactiveDot = styles.darkGrayFg.Render("•") + } +} // filterState is the current filtering state in the file listing. type filterState int @@ -110,29 +111,16 @@ message string } -func initSections() { - sections = map[sectionKey]section{ - documentsSection: { - key: documentsSection, - paginator: newStashPaginator(), - }, - filterSection: { - key: filterSection, - paginator: newStashPaginator(), - }, - } -} - // String returns a styled version of the status message appropriate for the // given context. -func (s statusMessage) String() string { +func (s statusMessage) String(styles Styles) string { switch s.status { //nolint:exhaustive case subtleStatusMessage: - return dimGreenFg(s.message) + return styles.dimGreenFg(s.message) case errorStatusMessage: - return redFg(s.message) + return styles.redFg(s.message) default: - return greenFg(s.message) + return styles.greenFg(s.message) } } @@ -208,9 +196,9 @@ m.common.width = width m.common.height = height - m.filterInput.Width = width - stashViewHorizontalPadding*2 - ansi.PrintableRuneWidth( + m.filterInput.SetWidth(width - stashViewHorizontalPadding*2 - ansi.PrintableRuneWidth( m.filterInput.Prompt, - ) + )) m.updatePagination() } @@ -374,16 +362,24 @@ // INIT func newStashModel(common *commonModel) stashModel { + styles := common.styles sp := spinner.New() sp.Spinner = spinner.Line - sp.Style = stashSpinnerStyle + sp.Style = styles.stashSpinnerStyle si := textinput.New() si.Prompt = "Find:" - si.PromptStyle = stashInputPromptStyle - si.Cursor.Style = stashInputCursorStyle + // The filter input is rendered inline into the larger stash view, so draw + // the cursor as part of the string rather than moving the real one. + si.SetVirtualCursor(true) + tsi := si.Styles() + tsi.Focused.Prompt = styles.stashInputPromptStyle + tsi.Blurred.Prompt = styles.stashInputPromptStyle + tsi.Cursor.Color = styles.fuchsia + si.SetStyles(tsi) si.Focus() + sections := newSections() s := []section{ sections[documentsSection], } @@ -395,18 +391,11 @@ serverPage: 1, sections: s, } + m.stylePaginators(styles) return m } -func newStashPaginator() paginator.Model { - p := paginator.New() - p.Type = paginator.Dots - p.ActiveDot = brightGrayFg("•") - p.InactiveDot = darkGrayFg.Render("•") - return p -} - // UPDATE func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) { @@ -449,7 +438,7 @@ cmds = append(cmds, m.handleDocumentBrowsing(msg)) case stashStateShowingError: // Any key exists the error view - if _, ok := msg.(tea.KeyMsg); ok { + if _, ok := msg.(tea.KeyPressMsg); ok { m.viewState = stashStateReady } } @@ -465,7 +454,7 @@ switch msg := msg.(type) { // Handle keys - case tea.KeyMsg: + case tea.KeyPressMsg: switch msg.String() { case "k", "ctrl+k", "up": m.moveCursorUp() @@ -579,7 +568,7 @@ cmds = append(cmds, cmd) // Extra paginator keystrokes - if key, ok := msg.(tea.KeyMsg); ok { + if key, ok := msg.(tea.KeyPressMsg); ok { switch key.String() { case "b", "u": m.paginator().PrevPage() @@ -602,7 +591,7 @@ var cmds []tea.Cmd // Handle keys - if msg, ok := msg.(tea.KeyMsg); ok { //nolint:nestif + if msg, ok := msg.(tea.KeyPressMsg); ok { //nolint:nestif switch msg.String() { case keyEsc: // Cancel filtering @@ -634,7 +623,7 @@ // Add new section if it's not present if m.sections[len(m.sections)-1].key != filterSection { - m.sections = append(m.sections, sections[filterSection]) + m.sections = append(m.sections, newSections()[filterSection]) } m.sectionIndex = len(m.sections) - 1 @@ -671,7 +660,7 @@ var s string switch m.viewState { case stashStateShowingError: - return errorView(m.err, false) + return errorView(m.common.styles, m.err, false) case stashStateLoadingDocument: s += " " + m.spinner.View() + " Loading document..." case stashStateReady: @@ -687,13 +676,13 @@ // Rules for the logo, filter and status message. logoOrFilter := " " if m.showStatusMessage && m.filterState == filtering { - logoOrFilter += m.statusMessage.String() + logoOrFilter += m.statusMessage.String(m.common.styles) } else if m.filterState == filtering { logoOrFilter += m.filterInput.View() } else { - logoOrFilter += glowLogoView() + logoOrFilter += glowLogoView(m.common.styles) if m.showStatusMessage { - logoOrFilter += " " + m.statusMessage.String() + logoOrFilter += " " + m.statusMessage.String(m.common.styles) } } logoOrFilter = truncate.StringWithTail(logoOrFilter, uint(m.common.width-1), ellipsis) //nolint:gosec @@ -727,9 +716,9 @@ // One could argue, in fact, that using pointers in // a functional framework is an antipattern and our use of // pointers in our model should be refactored away. - p := *(m.paginator()) + p := *m.paginator() p.Type = paginator.Arabic - pagination = paginationStyle.Render(p.View()) + pagination = m.common.styles.paginationStyle.Render(p.View()) } } @@ -747,11 +736,12 @@ return "\n" + indent(s, stashIndent) } -func glowLogoView() string { - return logoStyle.Render(" Glow ") +func glowLogoView(styles Styles) string { + return styles.logoStyle.Render(" Glow ") } func (m stashModel) headerView() string { + styles := m.common.styles localCount := len(m.markdowns) var sections []string //nolint:prealloc @@ -759,17 +749,17 @@ // Filter results if m.filterState == filtering { if localCount == 0 { - return grayFg("Nothing found.") + return styles.grayFg("Nothing found.") } if localCount > 0 { sections = append(sections, fmt.Sprintf("%d local", localCount)) } for i := range sections { - sections[i] = grayFg(sections[i]) + sections[i] = styles.grayFg(sections[i]) } - return strings.Join(sections, dividerDot.String()) + return strings.Join(sections, styles.dividerDot.String()) } // Tabs @@ -778,21 +768,20 @@ switch v.key { case documentsSection: - s = fmt.Sprintf("%d documents", localCount) - + s = fmt.Sprintf("%s", english.Plural(localCount, "document", "")) case filterSection: s = fmt.Sprintf("%d “%s”", len(m.filteredMarkdowns), m.filterInput.Value()) } if m.sectionIndex == i && len(m.sections) > 1 { - s = selectedTabStyle.Render(s) + s = styles.selectedTabStyle.Render(s) } else { - s = tabStyle.Render(s) + s = styles.tabStyle.Render(s) } sections = append(sections, s) } - return strings.Join(sections, dividerBar.String()) + return strings.Join(sections, styles.dividerBar.String()) } func (m stashModel) populatedView() string { @@ -803,7 +792,7 @@ // Empty states if len(mds) == 0 { f := func(s string) { - b.WriteString(" " + grayFg(s)) + b.WriteString(" " + m.common.styles.grayFg(s)) } switch m.sections[m.sectionIndex].key { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/stashhelp.go new/glow-3.0.0/ui/stashhelp.go --- old/glow-2.1.2/ui/stashhelp.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/stashhelp.go 2026-08-11 19:45:40.000000000 +0200 @@ -30,7 +30,7 @@ } // render returns styled and formatted rows from keys and values. -func (h helpColumn) render(height int) (rows []string) { +func (h helpColumn) render(styles Styles, height int) (rows []string) { keyWidth, valWidth := h.maxWidths() for i := 0; i < height; i++ { @@ -44,11 +44,11 @@ switch k { case "s": - k = greenFg(k) - v = semiDimGreenFg(v) + k = styles.greenFg(k) + v = styles.semiDimGreenFg(v) default: - k = grayFg(k) - v = midGrayFg(v) + k = styles.grayFg(k) + v = styles.midGrayFg(v) } } b.WriteString(k) @@ -181,7 +181,7 @@ } var ( - truncationChar = subtleStyle.Render("…") + truncationChar = m.common.styles.subtleStyle.Render("…") truncationWidth = ansi.PrintableRuneWidth(truncationChar) ) @@ -199,13 +199,13 @@ k := entries[i] v := entries[i+1] - k = grayFg(k) - v = midGrayFg(v) + k = m.common.styles.grayFg(k) + v = m.common.styles.midGrayFg(v) next = fmt.Sprintf("%s %s", k, v) if i < len(entries)-2 { - next += dividerDot.String() + next += m.common.styles.dividerDot.String() } // Only this (and the following) help text items if we have the @@ -243,7 +243,7 @@ // Build columns for _, c := range columns { - renderedCols = append(renderedCols, c.render(tallestCol)) + renderedCols = append(renderedCols, c.render(m.common.styles, tallestCol)) } // Merge columns diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/stashitem.go new/glow-3.0.0/ui/stashitem.go --- old/glow-2.1.2/ui/stashitem.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/stashitem.go 2026-08-11 19:45:40.000000000 +0200 @@ -4,7 +4,7 @@ "fmt" "strings" - "github.com/charmbracelet/lipgloss" + "charm.land/lipgloss/v2" "github.com/charmbracelet/log" "github.com/muesli/reflow/truncate" "github.com/sahilm/fuzzy" @@ -30,6 +30,7 @@ isSelected := index == m.cursor() isFiltering := m.filterState == filtering singleFilteredItem := isFiltering && len(m.getVisibleMarkdowns()) == 1 + styles := m.common.styles // If there are multiple items being filtered don't highlight a selected // item in the results. If we've filtered down to one item, however, @@ -37,48 +38,48 @@ if isSelected && !isFiltering || singleFilteredItem { //nolint:nestif // Selected item if m.statusMessage == stashingStatusMessage { - gutter = greenFg(verticalLine) - icon = dimGreenFg(icon) - title = greenFg(title) - date = semiDimGreenFg(date) - editedBy = semiDimGreenFg(editedBy) - separator = semiDimGreenFg(separator) + gutter = styles.greenFg(verticalLine) + icon = styles.dimGreenFg(icon) + title = styles.greenFg(title) + date = styles.semiDimGreenFg(date) + editedBy = styles.semiDimGreenFg(editedBy) + separator = styles.semiDimGreenFg(separator) } else { - gutter = dullFuchsiaFg(verticalLine) + gutter = styles.dullFuchsiaFg(verticalLine) if m.currentSection().key == filterSection && m.filterState == filterApplied || singleFilteredItem { - s := lipgloss.NewStyle().Foreground(fuchsia) + s := lipgloss.NewStyle().Foreground(styles.fuchsia) title = styleFilteredText(title, m.filterInput.Value(), s, s.Underline(true)) } else { - title = fuchsiaFg(title) - icon = fuchsiaFg(icon) + title = styles.fuchsiaFg(title) + icon = styles.fuchsiaFg(icon) } - date = dimFuchsiaFg(date) - editedBy = dimDullFuchsiaFg(editedBy) - separator = dullFuchsiaFg(separator) + date = styles.dimFuchsiaFg(date) + editedBy = styles.dimDullFuchsiaFg(editedBy) + separator = styles.dullFuchsiaFg(separator) } } else { gutter = " " if m.statusMessage == stashingStatusMessage { - icon = dimGreenFg(icon) - title = greenFg(title) - date = semiDimGreenFg(date) - editedBy = semiDimGreenFg(editedBy) - separator = semiDimGreenFg(separator) + icon = styles.dimGreenFg(icon) + title = styles.greenFg(title) + date = styles.semiDimGreenFg(date) + editedBy = styles.semiDimGreenFg(editedBy) + separator = styles.semiDimGreenFg(separator) } else if isFiltering && m.filterInput.Value() == "" { - icon = dimGreenFg(icon) - title = dimNormalFg(title) - date = dimBrightGrayFg(date) - editedBy = dimBrightGrayFg(editedBy) - separator = dimBrightGrayFg(separator) + icon = styles.dimGreenFg(icon) + title = styles.dimNormalFg(title) + date = styles.dimBrightGrayFg(date) + editedBy = styles.dimBrightGrayFg(editedBy) + separator = styles.dimBrightGrayFg(separator) } else { - icon = greenFg(icon) + icon = styles.greenFg(icon) - s := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#1a1a1a", Dark: "#dddddd"}) + s := lipgloss.NewStyle().Foreground(styles.adaptive("#1a1a1a", "#dddddd")) title = styleFilteredText(title, m.filterInput.Value(), s, s.Underline(true)) - date = grayFg(date) - editedBy = midGrayFg(editedBy) - separator = brightGrayFg(separator) + date = styles.grayFg(date) + editedBy = styles.midGrayFg(editedBy) + separator = styles.brightGrayFg(separator) } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/styles.go new/glow-3.0.0/ui/styles.go --- old/glow-2.1.2/ui/styles.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/styles.go 2026-08-11 19:45:40.000000000 +0200 @@ -1,46 +1,168 @@ package ui -import "github.com/charmbracelet/lipgloss" +import ( + "image/color" -// Colors. -var ( - normalDim = lipgloss.AdaptiveColor{Light: "#A49FA5", Dark: "#777777"} - gray = lipgloss.AdaptiveColor{Light: "#909090", Dark: "#626262"} - midGray = lipgloss.AdaptiveColor{Light: "#B2B2B2", Dark: "#4A4A4A"} - darkGray = lipgloss.AdaptiveColor{Light: "#DDDADA", Dark: "#3C3C3C"} - brightGray = lipgloss.AdaptiveColor{Light: "#847A85", Dark: "#979797"} - dimBrightGray = lipgloss.AdaptiveColor{Light: "#C2B8C2", Dark: "#4D4D4D"} - cream = lipgloss.AdaptiveColor{Light: "#FFFDF5", Dark: "#FFFDF5"} - yellowGreen = lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#ECFD65"} - fuchsia = lipgloss.AdaptiveColor{Light: "#EE6FF8", Dark: "#EE6FF8"} - dimFuchsia = lipgloss.AdaptiveColor{Light: "#F1A8FF", Dark: "#99519E"} - dullFuchsia = lipgloss.AdaptiveColor{Dark: "#AD58B4", Light: "#F793FF"} - dimDullFuchsia = lipgloss.AdaptiveColor{Light: "#F6C9FF", Dark: "#7B4380"} - green = lipgloss.Color("#04B575") - red = lipgloss.AdaptiveColor{Light: "#FF4672", Dark: "#ED567A"} - semiDimGreen = lipgloss.AdaptiveColor{Light: "#35D79C", Dark: "#036B46"} - dimGreen = lipgloss.AdaptiveColor{Light: "#72D2B0", Dark: "#0B5137"} + "charm.land/lipgloss/v2" ) -// Ulimately, we'll transition to named styles. -var ( - dimNormalFg = lipgloss.NewStyle().Foreground(normalDim).Render - brightGrayFg = lipgloss.NewStyle().Foreground(brightGray).Render - dimBrightGrayFg = lipgloss.NewStyle().Foreground(dimBrightGray).Render - grayFg = lipgloss.NewStyle().Foreground(gray).Render - midGrayFg = lipgloss.NewStyle().Foreground(midGray).Render - darkGrayFg = lipgloss.NewStyle().Foreground(darkGray) - greenFg = lipgloss.NewStyle().Foreground(green).Render - semiDimGreenFg = lipgloss.NewStyle().Foreground(semiDimGreen).Render - dimGreenFg = lipgloss.NewStyle().Foreground(dimGreen).Render - fuchsiaFg = lipgloss.NewStyle().Foreground(fuchsia).Render - dimFuchsiaFg = lipgloss.NewStyle().Foreground(dimFuchsia).Render - dullFuchsiaFg = lipgloss.NewStyle().Foreground(dullFuchsia).Render - dimDullFuchsiaFg = lipgloss.NewStyle().Foreground(dimDullFuchsia).Render - redFg = lipgloss.NewStyle().Foreground(red).Render - tabStyle = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#909090", Dark: "#626262"}) - selectedTabStyle = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#333333", Dark: "#979797"}) - errorTitleStyle = lipgloss.NewStyle().Foreground(cream).Background(red).Padding(0, 1) - subtleStyle = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#9B9B9B", Dark: "#5C5C5C"}) - paginationStyle = subtleStyle -) +// Styles contains all styles used in the UI. They are resolved from light and +// dark color variants according to the terminal's background color, which +// Bubble Tea reports via tea.BackgroundColorMsg. Until then, we default to +// a dark background. +type Styles struct { + lightDark lipgloss.LightDarkFunc + + fuchsia color.Color + + dimNormalFg func(...string) string + brightGrayFg func(...string) string + dimBrightGrayFg func(...string) string + grayFg func(...string) string + midGrayFg func(...string) string + darkGrayFg lipgloss.Style + greenFg func(...string) string + semiDimGreenFg func(...string) string + dimGreenFg func(...string) string + fuchsiaFg func(...string) string + dimFuchsiaFg func(...string) string + dullFuchsiaFg func(...string) string + dimDullFuchsiaFg func(...string) string + redFg func(...string) string + + tabStyle lipgloss.Style + selectedTabStyle lipgloss.Style + errorTitleStyle lipgloss.Style + subtleStyle lipgloss.Style + paginationStyle lipgloss.Style + + statusBarScrollPosStyle func(...string) string + statusBarNoteStyle func(...string) string + statusBarHelpStyle func(...string) string + statusBarMessageStyle func(...string) string + statusBarMessageScrollPosStyle func(...string) string + statusBarMessageHelpStyle func(...string) string + helpViewStyle func(...string) string + lineNumberStyle func(...string) string + + dividerDot lipgloss.Style + dividerBar lipgloss.Style + logoStyle lipgloss.Style + stashSpinnerStyle lipgloss.Style + stashInputPromptStyle lipgloss.Style +} + +// newStyles builds all styles for the given terminal background. +func newStyles(isDark bool) Styles { + s := Styles{lightDark: lipgloss.LightDark(isDark)} + + // Colors + normalDim := s.adaptive("#A49FA5", "#777777") + gray := s.adaptive("#909090", "#626262") + midGray := s.adaptive("#B2B2B2", "#4A4A4A") + darkGray := s.adaptive("#DDDADA", "#3C3C3C") + brightGray := s.adaptive("#847A85", "#979797") + dimBrightGray := s.adaptive("#C2B8C2", "#4D4D4D") + cream := s.adaptive("#FFFDF5", "#FFFDF5") + yellowGreen := s.adaptive("#04B575", "#ECFD65") + s.fuchsia = s.adaptive("#EE6FF8", "#EE6FF8") + dimFuchsia := s.adaptive("#F1A8FF", "#99519E") + dullFuchsia := s.adaptive("#F793FF", "#AD58B4") + dimDullFuchsia := s.adaptive("#F6C9FF", "#7B4380") + green := lipgloss.Color("#04B575") + red := s.adaptive("#FF4672", "#ED567A") + semiDimGreen := s.adaptive("#35D79C", "#036B46") + dimGreen := s.adaptive("#72D2B0", "#0B5137") + + // Pager colors + mintGreen := s.adaptive("#89F0CB", "#89F0CB") + darkGreen := s.adaptive("#1C8760", "#1C8760") + lineNumberFg := s.adaptive("#656565", "#7D7D7D") + statusBarNoteFg := s.adaptive("#656565", "#7D7D7D") + statusBarBg := s.adaptive("#E6E6E6", "#242424") + + // Render-func styles + s.dimNormalFg = lipgloss.NewStyle().Foreground(normalDim).Render + s.brightGrayFg = lipgloss.NewStyle().Foreground(brightGray).Render + s.dimBrightGrayFg = lipgloss.NewStyle().Foreground(dimBrightGray).Render + s.grayFg = lipgloss.NewStyle().Foreground(gray).Render + s.midGrayFg = lipgloss.NewStyle().Foreground(midGray).Render + s.darkGrayFg = lipgloss.NewStyle().Foreground(darkGray) + s.greenFg = lipgloss.NewStyle().Foreground(green).Render + s.semiDimGreenFg = lipgloss.NewStyle().Foreground(semiDimGreen).Render + s.dimGreenFg = lipgloss.NewStyle().Foreground(dimGreen).Render + s.fuchsiaFg = lipgloss.NewStyle().Foreground(s.fuchsia).Render + s.dimFuchsiaFg = lipgloss.NewStyle().Foreground(dimFuchsia).Render + s.dullFuchsiaFg = lipgloss.NewStyle().Foreground(dullFuchsia).Render + s.dimDullFuchsiaFg = lipgloss.NewStyle().Foreground(dimDullFuchsia).Render + s.redFg = lipgloss.NewStyle().Foreground(red).Render + + // Named styles + s.tabStyle = lipgloss.NewStyle().Foreground(s.adaptive("#909090", "#626262")) + s.selectedTabStyle = lipgloss.NewStyle().Foreground(s.adaptive("#333333", "#979797")) + s.errorTitleStyle = lipgloss.NewStyle().Foreground(cream).Background(red).Padding(0, 1) + s.subtleStyle = lipgloss.NewStyle().Foreground(s.adaptive("#9B9B9B", "#5C5C5C")) + s.paginationStyle = s.subtleStyle + + // Pager styles + s.statusBarScrollPosStyle = lipgloss.NewStyle(). + Foreground(s.adaptive("#949494", "#5A5A5A")). + Background(statusBarBg). + Render + + s.statusBarNoteStyle = lipgloss.NewStyle(). + Foreground(statusBarNoteFg). + Background(statusBarBg). + Render + + s.statusBarHelpStyle = lipgloss.NewStyle(). + Foreground(statusBarNoteFg). + Background(s.adaptive("#DCDCDC", "#323232")). + Render + + s.statusBarMessageStyle = lipgloss.NewStyle(). + Foreground(mintGreen). + Background(darkGreen). + Render + + s.statusBarMessageScrollPosStyle = lipgloss.NewStyle(). + Foreground(mintGreen). + Background(darkGreen). + Render + + s.statusBarMessageHelpStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#B6FFE4")). + Background(green). + Render + + s.helpViewStyle = lipgloss.NewStyle(). + Foreground(statusBarNoteFg). + Background(s.adaptive("#f2f2f2", "#1B1B1B")). + Render + + s.lineNumberStyle = lipgloss.NewStyle(). + Foreground(lineNumberFg). + Render + + // Stash styles + s.dividerDot = s.darkGrayFg.SetString(" • ") + s.dividerBar = s.darkGrayFg.SetString(" │ ") + + s.logoStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#ECFD65")). + Background(s.fuchsia). + Bold(true) + + s.stashSpinnerStyle = lipgloss.NewStyle(). + Foreground(gray) + s.stashInputPromptStyle = lipgloss.NewStyle(). + Foreground(yellowGreen). + MarginRight(1) + + return s +} + +// adaptive returns a color appropriate for the current terminal background. +func (s Styles) adaptive(light, dark string) color.Color { + return s.lightDark(lipgloss.Color(light), lipgloss.Color(dark)) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/ui/ui.go new/glow-3.0.0/ui/ui.go --- old/glow-2.1.2/ui/ui.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/ui/ui.go 2026-08-11 19:45:40.000000000 +0200 @@ -8,12 +8,10 @@ "strings" "time" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/glamour/styles" - "github.com/charmbracelet/glow/v2/utils" + tea "charm.land/bubbletea/v2" + "charm.land/glow/v3/utils" "github.com/charmbracelet/log" "github.com/muesli/gitcha" - te "github.com/muesli/termenv" ) const ( @@ -21,31 +19,20 @@ ellipsis = "…" ) -var ( - config Config - - markdownExtensions = []string{ - "*.md", "*.mdown", "*.mkdn", "*.mkd", "*.markdown", - } -) +var markdownExtensions = []string{ + "*.md", "*.mdown", "*.mkdn", "*.mkd", "*.markdown", +} // NewProgram returns a new Tea program. func NewProgram(cfg Config, content string) *tea.Program { log.Debug( "Starting glow", - "high_perf_pager", - cfg.HighPerformancePager, "glamour", cfg.GlamourEnabled, ) - config = cfg - opts := []tea.ProgramOption{tea.WithAltScreen()} - if cfg.EnableMouse { - opts = append(opts, tea.WithMouseCellMotion()) - } m := newModel(cfg, content) - return tea.NewProgram(m, opts...) + return tea.NewProgram(m) } type errMsg struct{ err error } @@ -95,6 +82,7 @@ cwd string width int height int + styles Styles } type model struct { @@ -120,10 +108,6 @@ m.pager.showHelp = false var batch []tea.Cmd - if m.pager.viewport.HighPerformanceRendering { - batch = append(batch, tea.ClearScrollArea) //nolint:staticcheck - } - if !m.stash.shouldSpin() { batch = append(batch, m.stash.spinner.Tick) } @@ -131,18 +115,9 @@ } func newModel(cfg Config, content string) tea.Model { - initSections() - - if cfg.GlamourStyle == styles.AutoStyle { - if te.HasDarkBackground() { - cfg.GlamourStyle = styles.DarkStyle - } else { - cfg.GlamourStyle = styles.LightStyle - } - } - common := commonModel{ - cfg: cfg, + cfg: cfg, + styles: newStyles(true), } m := model{ @@ -184,7 +159,7 @@ } func (m model) Init() tea.Cmd { - cmds := []tea.Cmd{m.stash.spinner.Tick} + cmds := []tea.Cmd{m.stash.spinner.Tick, tea.RequestBackgroundColor} switch m.state { case stateShowStash: @@ -205,7 +180,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // If there's been an error, any key exits if m.fatalErr != nil { - if _, ok := msg.(tea.KeyMsg); ok { + if _, ok := msg.(tea.KeyPressMsg); ok { return m, tea.Quit } } @@ -213,7 +188,10 @@ var cmds []tea.Cmd switch msg := msg.(type) { - case tea.KeyMsg: + case tea.BackgroundColorMsg: + m.common.styles = newStyles(msg.IsDark()) + m.stash.stylePaginators(m.common.styles) + case tea.KeyPressMsg: switch msg.String() { case "esc": if m.state == stateShowDocument || m.stash.viewState == stashStateLoadingDocument { @@ -324,20 +302,26 @@ return m, tea.Batch(cmds...) } -func (m model) View() string { - if m.fatalErr != nil { - return errorView(m.fatalErr, true) +func (m model) View() tea.View { + var content string + switch { + case m.fatalErr != nil: + content = errorView(m.common.styles, m.fatalErr, true) + case m.state == stateShowDocument: + content = m.pager.View() + default: + content = m.stash.view() } - switch m.state { //nolint:exhaustive - case stateShowDocument: - return m.pager.View() - default: - return m.stash.view() + v := tea.NewView(content) + v.AltScreen = true + if m.common.cfg.EnableMouse { + v.MouseMode = tea.MouseModeCellMotion } + return v } -func errorView(err error, fatal bool) string { +func errorView(styles Styles, err error, fatal bool) string { exitMsg := "press any key to " if fatal { exitMsg += "exit" @@ -345,9 +329,9 @@ exitMsg += "return" } s := fmt.Sprintf("%s\n\n%v\n\n%s", - errorTitleStyle.Render("ERROR"), + styles.errorTitleStyle.Render("ERROR"), err, - subtleStyle.Render(exitMsg), + styles.subtleStyle.Render(exitMsg), ) return "\n" + indent(s, 3) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glow-2.1.2/utils/utils.go new/glow-3.0.0/utils/utils.go --- old/glow-2.1.2/utils/utils.go 2026-04-09 22:25:27.000000000 +0200 +++ new/glow-3.0.0/utils/utils.go 2026-08-11 19:45:40.000000000 +0200 @@ -7,10 +7,10 @@ "regexp" "strings" - "github.com/charmbracelet/glamour" - "github.com/charmbracelet/glamour/ansi" - "github.com/charmbracelet/glamour/styles" - "github.com/charmbracelet/lipgloss" + "charm.land/glamour/v2" + "charm.land/glamour/v2/ansi" + "charm.land/glamour/v2/styles" + "charm.land/lipgloss/v2" "github.com/mitchellh/go-homedir" ) @@ -72,8 +72,8 @@ // GlamourStyle returns a glamour.TermRendererOption based on the given style. func GlamourStyle(style string, isCode bool) glamour.TermRendererOption { if !isCode { - if style == styles.AutoStyle { - return glamour.WithAutoStyle() + if style == "auto" { + return glamour.WithStandardStyle("dark") } return glamour.WithStylePath(style) } @@ -84,8 +84,8 @@ var styleConfig ansi.StyleConfig switch style { - case styles.AutoStyle: - if lipgloss.HasDarkBackground() { + case "auto": + if lipgloss.HasDarkBackground(os.Stdin, os.Stdout) { styleConfig = styles.DarkStyleConfig } else { styleConfig = styles.LightStyleConfig ++++++ vendor.tar.zst ++++++ ++++ 146711 lines of diff (skipped)
