Merge branch 'master' into beta

This commit is contained in:
Ayman Bagabas
2024-06-05 11:53:51 -04:00
12 changed files with 591 additions and 226 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v4
- name: golangci-lint
uses: golangci/golangci-lint-action@v5
uses: golangci/golangci-lint-action@v6
with:
# Optional: golangci-lint command line arguments.
args: --config .golangci-soft.yml --issues-exit-code=0
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v4
- name: golangci-lint
uses: golangci/golangci-lint-action@v5
uses: golangci/golangci-lint-action@v6
with:
# Optional: golangci-lint command line arguments.
#args:
+1
View File
@@ -16,6 +16,7 @@ linters:
enable:
- bodyclose
- exportloopref
- gofumpt
- goimports
- gosec
- nilerr
+4 -6
View File
@@ -4,15 +4,14 @@ go 1.18
require (
github.com/MakeNowJust/heredoc v1.0.0
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/atotto/clipboard v0.1.4
github.com/charmbracelet/bubbletea v0.26.3-0.20240528172931-7581b6a46c83
github.com/charmbracelet/bubbletea v0.26.5-0.20240605151746-bca513b1982b
github.com/charmbracelet/harmonica v0.2.0
github.com/charmbracelet/lipgloss v0.10.1-0.20240528172826-972c013da128
github.com/charmbracelet/lipgloss v0.11.1-0.20240605151253-a724723338e3
github.com/charmbracelet/x/ansi v0.1.1
github.com/dustin/go-humanize v1.0.1
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mattn/go-runewidth v0.0.15
github.com/muesli/reflow v0.3.0
github.com/muesli/termenv v0.15.2
github.com/rivo/uniseg v0.4.7
github.com/sahilm/fuzzy v0.1.1
@@ -20,13 +19,12 @@ require (
require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/x/ansi v0.1.1 // indirect
github.com/charmbracelet/x/input v0.1.0 // indirect
github.com/charmbracelet/x/term v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.1.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
+6 -40
View File
@@ -1,45 +1,15 @@
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
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/charmbracelet/bubbletea v0.26.3-0.20240510203954-a434f25ff7d3 h1:Bg0eRBAgsWh84rpAq5X+e52TMAfloxoWeSJkYp9Pyw0=
github.com/charmbracelet/bubbletea v0.26.3-0.20240510203954-a434f25ff7d3/go.mod h1:jxN9TKmttdNsUKWSjjQQonHIY4nCuTBNdkDn3/Bpf7A=
github.com/charmbracelet/bubbletea v0.26.3-0.20240513205551-cf6db9e1506a h1:9p5KZLIfqlGIvR0VvCslSTQHMePwKJ7mRESH2FqvWR4=
github.com/charmbracelet/bubbletea v0.26.3-0.20240513205551-cf6db9e1506a/go.mod h1:K3huPnfaiCxjWojAg1QijEVeqHYY9LO4cAPC12KmpLQ=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514165352-43ffb64832ac h1:oU2Kc74rwT2tmvtVSOK5IQVHkgD7SiIxdICGu3zQ2uI=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514165352-43ffb64832ac/go.mod h1:1dQnHpcm7F+IxzjVZELAgjNMsg8MeTRa2oZefBe/giM=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514171728-e310dbefd4d7 h1:Az6OJpSeWBh/MsWMylnovPv6m1W1bzCYn65vRjXEtuU=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514171728-e310dbefd4d7/go.mod h1:1dQnHpcm7F+IxzjVZELAgjNMsg8MeTRa2oZefBe/giM=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514172205-72ce959b78e3 h1:GugYAtdwJBA1e8+y/diVe41cPS8dgdML7+atTeLS4R8=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514172205-72ce959b78e3/go.mod h1:FixrOn+mReyxbVP0qZcyDsHLKeaZbMHf3wZOxLm8wj4=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514172421-c69b27d7eeb8 h1:uq7c8wSq2/wK/KyvQ3KMQGZp0LFrKhOTAnHK6rNSMG0=
github.com/charmbracelet/bubbletea v0.26.3-0.20240514172421-c69b27d7eeb8/go.mod h1:69vZAJlmlVOxh7Y/Ndvr0csqEP2coOgZolwXx6qvPCk=
github.com/charmbracelet/bubbletea v0.26.3-0.20240515201852-5648cc2d9070 h1:fQQA/hv45Y7AhZH1l0p1WMfmkQ6CwexJEQ0/U+j0TGM=
github.com/charmbracelet/bubbletea v0.26.3-0.20240515201852-5648cc2d9070/go.mod h1:XggZds/FnG8qLKTAc4DRzqooDc72f94hdsj1Qb2cWfM=
github.com/charmbracelet/bubbletea v0.26.3-0.20240528172931-7581b6a46c83 h1:3+xEsSiI+qhBURG8641j/4jz83ECgWhhNtDr8RsEQGQ=
github.com/charmbracelet/bubbletea v0.26.3-0.20240528172931-7581b6a46c83/go.mod h1:g/d1WUOwmXQpbQtzRoTYJ9Dzjait158UnUAOGdcb8R0=
github.com/charmbracelet/bubbletea v0.26.5-0.20240605151746-bca513b1982b h1:IqnzS1grN+x+JrAxhBdZ+9dXffMA5r9E/10OC5sgPxE=
github.com/charmbracelet/bubbletea v0.26.5-0.20240605151746-bca513b1982b/go.mod h1:n5kk+aidUsbwmVVdIlFPfwHB44/aKFGZk4AKVxWWi90=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v0.10.1-0.20240510203806-a6dc2ab509a8 h1:aOfL0f8fhgqKe+iOIQYAIazSwTO4J0axB5ztPxw5JHY=
github.com/charmbracelet/lipgloss v0.10.1-0.20240510203806-a6dc2ab509a8/go.mod h1:axBjGt1mTZwwTM0kfcq8fPWFzNPj+ZAOjfLCr7JW9fk=
github.com/charmbracelet/lipgloss v0.10.1-0.20240513205513-d059cfa7d6f0 h1:CWvUdfXeiDgBM0PZ9Mix19P7JB1tzaCDUy9F1JiuQ5M=
github.com/charmbracelet/lipgloss v0.10.1-0.20240513205513-d059cfa7d6f0/go.mod h1:axBjGt1mTZwwTM0kfcq8fPWFzNPj+ZAOjfLCr7JW9fk=
github.com/charmbracelet/lipgloss v0.10.1-0.20240514163550-4de43222e210 h1:Q7gfEmAUFJL0n8IgXUs7m/SgjfRASClC6Mu+JpanJu8=
github.com/charmbracelet/lipgloss v0.10.1-0.20240514163550-4de43222e210/go.mod h1:/WJOlugg8bddqSP52FFiGXWVIfXsO+/+KzOGAT7opnw=
github.com/charmbracelet/lipgloss v0.10.1-0.20240514172133-9a1d854f90dd h1:y23y/2Sa7Wa3nseIm0KTP1R0BA44QyFhRB/rvJKOyjI=
github.com/charmbracelet/lipgloss v0.10.1-0.20240514172133-9a1d854f90dd/go.mod h1:/WJOlugg8bddqSP52FFiGXWVIfXsO+/+KzOGAT7opnw=
github.com/charmbracelet/lipgloss v0.10.1-0.20240514172355-88ecbb398449 h1:jy8zvXRALm2v8aK4ivo4m1+/E1/p8nejp5hWRudx2VA=
github.com/charmbracelet/lipgloss v0.10.1-0.20240514172355-88ecbb398449/go.mod h1:/WJOlugg8bddqSP52FFiGXWVIfXsO+/+KzOGAT7opnw=
github.com/charmbracelet/lipgloss v0.10.1-0.20240515201529-1969fb54fefe h1:2SKkDenRBzWlqbqnk7cseOretWPktJNddvQkvORQxWo=
github.com/charmbracelet/lipgloss v0.10.1-0.20240515201529-1969fb54fefe/go.mod h1:/WJOlugg8bddqSP52FFiGXWVIfXsO+/+KzOGAT7opnw=
github.com/charmbracelet/lipgloss v0.10.1-0.20240528172826-972c013da128 h1:/I9AeUxL+sekKPqe9LgQP8WesLt8Zo40WwcZmozjk1g=
github.com/charmbracelet/lipgloss v0.10.1-0.20240528172826-972c013da128/go.mod h1:/WJOlugg8bddqSP52FFiGXWVIfXsO+/+KzOGAT7opnw=
github.com/charmbracelet/x/ansi v0.1.0 h1:o4NbQQCoVgbLpD5RC1cI687baoLwrLZyCOTGlF0gne4=
github.com/charmbracelet/x/ansi v0.1.0/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/lipgloss v0.11.1-0.20240605151253-a724723338e3 h1:mr/tgxpMK+EUnQguGGByux9bxLQMG3at24Xs+07BBYY=
github.com/charmbracelet/lipgloss v0.11.1-0.20240605151253-a724723338e3/go.mod h1:aA4Y43qJqCRSpm/LoDYWDsLFP9U/Z6h0O99AIjiwThc=
github.com/charmbracelet/x/ansi v0.1.1 h1:CGAduulr6egay/YVbGc8Hsu8deMg1xZ/bkaXTPi1JDk=
github.com/charmbracelet/x/ansi v0.1.1/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ=
@@ -56,20 +26,16 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
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/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
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-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
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/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+5 -6
View File
@@ -81,10 +81,10 @@ func New(ctx tea.Context) Model {
ShortKey: keyStyle,
ShortDesc: descStyle,
ShortSeparator: sepStyle,
Ellipsis: sepStyle.Copy(),
FullKey: keyStyle.Copy(),
FullDesc: descStyle.Copy(),
FullSeparator: sepStyle.Copy(),
Ellipsis: sepStyle,
FullKey: keyStyle,
FullDesc: descStyle,
FullSeparator: sepStyle,
},
}
}
@@ -214,9 +214,8 @@ func (m Model) FullHelpView(groups [][]key.Binding) string {
if m.Width > 0 && totalWidth > m.Width {
break
}
out = append(out, sep)
}
out = append(out, sep)
}
return lipgloss.JoinHorizontal(lipgloss.Top, out...)
+11 -11
View File
@@ -8,7 +8,7 @@ import (
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/reflow/truncate"
"github.com/charmbracelet/x/ansi"
)
// DefaultItemStyles defines styling for a default list item.
@@ -37,7 +37,7 @@ func NewDefaultItemStyles(ctx tea.Context) (s DefaultItemStyles) {
Foreground(lipgloss.AdaptiveColor{Light: "#1a1a1a", Dark: "#dddddd"}).
Padding(0, 0, 0, 2)
s.NormalDesc = s.NormalTitle.Copy().
s.NormalDesc = s.NormalTitle.
Foreground(lipgloss.AdaptiveColor{Light: "#A49FA5", Dark: "#777777"})
s.SelectedTitle = ctx.NewStyle().
@@ -46,14 +46,14 @@ func NewDefaultItemStyles(ctx tea.Context) (s DefaultItemStyles) {
Foreground(lipgloss.AdaptiveColor{Light: "#EE6FF8", Dark: "#EE6FF8"}).
Padding(0, 0, 0, 1)
s.SelectedDesc = s.SelectedTitle.Copy().
s.SelectedDesc = s.SelectedTitle.
Foreground(lipgloss.AdaptiveColor{Light: "#F793FF", Dark: "#AD58B4"})
s.DimmedTitle = ctx.NewStyle().
Foreground(lipgloss.AdaptiveColor{Light: "#A49FA5", Dark: "#777777"}).
Padding(0, 0, 0, 2)
s.DimmedDesc = s.DimmedTitle.Copy().
s.DimmedDesc = s.DimmedTitle.
Foreground(lipgloss.AdaptiveColor{Light: "#C2B8C2", Dark: "#4D4D4D"})
s.FilterMatch = ctx.NewStyle().Underline(true)
@@ -155,15 +155,15 @@ func (d DefaultDelegate) Render(w io.Writer, m Model, index int, item Item) {
}
// Prevent text from exceeding list width
textwidth := uint(m.width - s.NormalTitle.GetPaddingLeft() - s.NormalTitle.GetPaddingRight())
title = truncate.StringWithTail(title, textwidth, ellipsis)
textwidth := m.width - s.NormalTitle.GetPaddingLeft() - s.NormalTitle.GetPaddingRight()
title = ansi.Truncate(title, textwidth, ellipsis)
if d.ShowDescription {
var lines []string
for i, line := range strings.Split(desc, "\n") {
if i >= d.height-1 {
break
}
lines = append(lines, truncate.StringWithTail(line, textwidth, ellipsis))
lines = append(lines, ansi.Truncate(line, textwidth, ellipsis))
}
desc = strings.Join(lines, "\n")
}
@@ -187,7 +187,7 @@ func (d DefaultDelegate) Render(w io.Writer, m Model, index int, item Item) {
if isFiltered {
// Highlight matches
unmatched := s.SelectedTitle.Inline(true)
matched := unmatched.Copy().Inherit(s.FilterMatch)
matched := unmatched.Inherit(s.FilterMatch)
title = lipgloss.StyleRunes(title, matchedRunes, matched, unmatched)
}
title = s.SelectedTitle.Render(title)
@@ -196,7 +196,7 @@ func (d DefaultDelegate) Render(w io.Writer, m Model, index int, item Item) {
if isFiltered {
// Highlight matches
unmatched := s.NormalTitle.Inline(true)
matched := unmatched.Copy().Inherit(s.FilterMatch)
matched := unmatched.Inherit(s.FilterMatch)
title = lipgloss.StyleRunes(title, matchedRunes, matched, unmatched)
}
title = s.NormalTitle.Render(title)
@@ -204,10 +204,10 @@ func (d DefaultDelegate) Render(w io.Writer, m Model, index int, item Item) {
}
if d.ShowDescription {
fmt.Fprintf(w, "%s\n%s", title, desc)
fmt.Fprintf(w, "%s\n%s", title, desc) //nolint: errcheck
return
}
fmt.Fprintf(w, "%s", title)
fmt.Fprintf(w, "%s", title) //nolint: errcheck
}
// ShortHelp returns the delegate's short help.
+6 -7
View File
@@ -17,8 +17,7 @@ import (
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/reflow/ansi"
"github.com/muesli/reflow/truncate"
"github.com/charmbracelet/x/ansi"
"github.com/sahilm/fuzzy"
)
@@ -1053,7 +1052,7 @@ func (m Model) View(ctx tea.Context) string {
func (m Model) titleView() string {
var (
view string
titleBarStyle = m.Styles.TitleBar.Copy()
titleBarStyle = m.Styles.TitleBar
// We need to account for the size of the spinner, even if we don't
// render it, to reserve some space for it should we turn it on later.
@@ -1078,7 +1077,7 @@ func (m Model) titleView() string {
// Status message
if m.filterState != Filtering {
view += " " + m.statusMessage
view = truncate.StringWithTail(view, uint(m.width-spinnerWidth), ellipsis)
view = ansi.Truncate(view, m.width-spinnerWidth, ellipsis)
}
}
@@ -1129,7 +1128,7 @@ func (m Model) statusView() string {
if filtered {
f := strings.TrimSpace(m.FilterInput.Value())
f = truncate.StringWithTail(f, 10, "…")
f = ansi.Truncate(f, 10, "…")
status += fmt.Sprintf("“%s” ", f)
}
@@ -1154,14 +1153,14 @@ func (m Model) paginationView() string {
// If the dot pagination is wider than the width of the window
// use the arabic paginator.
if ansi.PrintableRuneWidth(s) > m.width {
if ansi.StringWidth(s) > m.width {
m.Paginator.Type = paginator.Arabic
s = m.Styles.ArabicPagination.Render(m.Paginator.View(m.ctx))
}
style := m.Styles.PaginationStyle
if m.delegate.Spacing() == 0 && style.GetMarginTop() == 0 {
style = style.Copy().MarginTop(1)
style = style.MarginTop(1)
}
return style.Render(s)
+3 -3
View File
@@ -10,8 +10,8 @@ import (
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/harmonica"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/x/ansi"
"github.com/lucasb-eyer/go-colorful"
"github.com/muesli/reflow/ansi"
)
// Internal ID management. Used during animating to assure that frame messages
@@ -271,7 +271,7 @@ func (m Model) View(ctx tea.Context) string {
func (m Model) ViewAs(ctx tea.Context, percent float64) string {
b := strings.Builder{}
percentView := m.percentageView(percent)
m.barView(ctx, &b, percent, ansi.PrintableRuneWidth(percentView))
m.barView(ctx, &b, percent, ansi.StringWidth(percentView))
b.WriteString(percentView)
return b.String()
}
@@ -297,7 +297,7 @@ func (m Model) barView(ctx tea.Context, b *strings.Builder, percent float64, tex
if fw == 1 {
// this is up for debate: in a gradient of width=1, should the
// single character rendered be the first color, the last color
// or exactly 50% inbetween? I opted for 50%
// or exactly 50% in between? I opted for 50%
p = 0.5
} else if m.scaleRamp {
p = float64(i) / float64(fw-1)
+1 -1
View File
@@ -261,7 +261,7 @@ func New(ctx tea.Context) Model {
FocusedStyle: focusedStyle,
BlurredStyle: blurredStyle,
cache: memoization.NewMemoCache[line, [][]rune](defaultMaxHeight),
EndOfBufferCharacter: '~',
EndOfBufferCharacter: ' ',
ShowLineNumbers: true,
Cursor: cur,
KeyMap: DefaultKeyMap,
+551 -149
View File
@@ -6,9 +6,9 @@ import (
"unicode"
"github.com/MakeNowJust/heredoc"
"github.com/acarl005/stripansi"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/x/ansi"
)
func TestVerticalScrolling(t *testing.T) {
@@ -326,6 +326,8 @@ func TestVerticalNavigationShouldRememberPositionWhileTraversing(t *testing.T) {
}
func TestView(t *testing.T) {
t.Parallel()
type want struct {
view string
cursorRow int
@@ -342,11 +344,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 Hello, World!
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
},
},
@@ -360,11 +362,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 the first line
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 14,
@@ -382,9 +384,9 @@ func TestView(t *testing.T) {
> 1 the first line
> 2 the second line
> 3 the third line
> ~
> ~
> ~
>
>
>
`),
cursorRow: 2,
cursorCol: 14,
@@ -401,11 +403,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> the first line
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 14,
@@ -424,9 +426,9 @@ func TestView(t *testing.T) {
> the first line
> the second line
> the third line
> ~
> ~
> ~
>
>
>
`),
cursorRow: 2,
cursorCol: 14,
@@ -529,11 +531,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
* 1 the first line
* ~
* ~
* ~
* ~
* ~
*
*
*
*
*
`),
cursorRow: 0,
cursorCol: 14,
@@ -552,9 +554,9 @@ func TestView(t *testing.T) {
* 1 the first line
* 2 the second line
* 3 the third line
* ~
* ~
* ~
*
*
*
`),
cursorRow: 2,
cursorCol: 14,
@@ -571,11 +573,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 foo
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 3,
@@ -594,9 +596,9 @@ func TestView(t *testing.T) {
> 1 foo
> 2 bar
> 3 baz
> ~
> ~
> ~
>
>
>
`),
cursorRow: 2,
cursorCol: 3,
@@ -619,9 +621,9 @@ func TestView(t *testing.T) {
foo
bar
baz
~
~
~
`),
cursorRow: 2,
cursorCol: 3,
@@ -640,11 +642,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 foo bar
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 7,
@@ -664,10 +666,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 foo bar baz
> 2 foo bar
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 7,
@@ -686,11 +688,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 12
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 2,
@@ -709,11 +711,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 123
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 3,
@@ -733,10 +735,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 1234
>
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 0,
@@ -756,10 +758,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 1234
> 5
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 1,
@@ -779,11 +781,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 1 123
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 3,
@@ -804,10 +806,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 1234
>
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 0,
@@ -828,10 +830,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 1234
> 5
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 1,
@@ -853,8 +855,8 @@ func TestView(t *testing.T) {
> 2
> 3
>
> ~
> ~
>
>
`),
cursorRow: 3,
cursorCol: 0,
@@ -876,8 +878,8 @@ func TestView(t *testing.T) {
> 2
> 3
>
> ~
> ~
>
>
`),
cursorRow: 3,
cursorCol: 0,
@@ -900,8 +902,8 @@ func TestView(t *testing.T) {
> 2
> 3
>
> ~
> ~
>
>
`),
cursorRow: 3,
cursorCol: 0,
@@ -925,8 +927,8 @@ func TestView(t *testing.T) {
2
3
~
~
`),
cursorRow: 3,
cursorCol: 0,
@@ -946,10 +948,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 12
> 3
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 1,
@@ -969,11 +971,11 @@ func TestView(t *testing.T) {
want: want{
view: heredoc.Doc(`
> 123
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
cursorCol: 3,
@@ -994,10 +996,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1234
>
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 0,
@@ -1018,10 +1020,10 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1234
> 5
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
cursorCol: 1,
@@ -1044,11 +1046,11 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 1
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
@@ -1072,11 +1074,11 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1 123
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
@@ -1101,10 +1103,10 @@ func TestView(t *testing.T) {
> 1 1234
>
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
@@ -1129,10 +1131,10 @@ func TestView(t *testing.T) {
> 1 1234
> 5
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
@@ -1157,11 +1159,11 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 123456
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
@@ -1186,11 +1188,11 @@ func TestView(t *testing.T) {
view: heredoc.Doc(`
> 1234567
> ~
> ~
> ~
> ~
> ~
>
>
>
>
>
`),
cursorRow: 0,
@@ -1216,10 +1218,10 @@ func TestView(t *testing.T) {
> 12345678
>
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
@@ -1245,10 +1247,10 @@ func TestView(t *testing.T) {
> 12345678
> 9
> ~
> ~
> ~
> ~
>
>
>
>
`),
cursorRow: 1,
@@ -1264,19 +1266,419 @@ func TestView(t *testing.T) {
},
want: want{
view: heredoc.Doc(`
> 1 .
> ~
> ~
> ~
> ~
> ~
> 1 H
> e
> l
> l
> o
> ,
`),
},
},
{
name: "placeholder single line",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line"
m.ShowLineNumbers = false
return m
},
want: want{
view: heredoc.Doc(`
> placeholder the first line
>
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line\nplaceholder the second line\nplaceholder the third line"
m.ShowLineNumbers = false
return m
},
want: want{
view: heredoc.Doc(`
> placeholder the first line
> placeholder the second line
> placeholder the third line
>
>
>
`),
},
},
{
name: "placeholder single line with line numbers",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line"
m.ShowLineNumbers = true
return m
},
want: want{
view: heredoc.Doc(`
> 1 placeholder the first line
>
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines with line numbers",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line\nplaceholder the second line\nplaceholder the third line"
m.ShowLineNumbers = true
return m
},
want: want{
view: heredoc.Doc(`
> 1 placeholder the first line
> placeholder the second line
> placeholder the third line
>
>
>
`),
},
},
{
name: "placeholder single line with end of buffer character",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line"
m.ShowLineNumbers = false
m.EndOfBufferCharacter = '*'
return m
},
want: want{
view: heredoc.Doc(`
> placeholder the first line
> *
> *
> *
> *
> *
`),
},
},
{
name: "placeholder multiple lines with with end of buffer character",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line\nplaceholder the second line\nplaceholder the third line"
m.ShowLineNumbers = false
m.EndOfBufferCharacter = '*'
return m
},
want: want{
view: heredoc.Doc(`
> placeholder the first line
> placeholder the second line
> placeholder the third line
> *
> *
> *
`),
},
},
{
name: "placeholder single line with line numbers and end of buffer character",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line"
m.ShowLineNumbers = true
m.EndOfBufferCharacter = '*'
return m
},
want: want{
view: heredoc.Doc(`
> 1 placeholder the first line
> *
> *
> *
> *
> *
`),
},
},
{
name: "placeholder multiple lines with line numbers and end of buffer character",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line\nplaceholder the second line\nplaceholder the third line"
m.ShowLineNumbers = true
m.EndOfBufferCharacter = '*'
return m
},
want: want{
view: heredoc.Doc(`
> 1 placeholder the first line
> placeholder the second line
> placeholder the third line
> *
> *
> *
`),
},
},
{
name: "placeholder single line that is longer than max width",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line that is longer than the max width"
m.SetWidth(40)
m.ShowLineNumbers = false
return m
},
want: want{
view: heredoc.Doc(`
> placeholder the first line that is
> longer than the max width
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines that are longer than max width",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line that is longer than the max width\nplaceholder the second line that is longer than the max width"
m.ShowLineNumbers = false
m.SetWidth(40)
return m
},
want: want{
view: heredoc.Doc(`
> placeholder the first line that is
> longer than the max width
> placeholder the second line that is
> longer than the max width
>
>
`),
},
},
{
name: "placeholder single line that is longer than max width with line numbers",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line that is longer than the max width"
m.ShowLineNumbers = true
m.SetWidth(40)
return m
},
want: want{
view: heredoc.Doc(`
> 1 placeholder the first line that is
> longer than the max width
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines that are longer than max width with line numbers",
modelFunc: func(m Model) Model {
m.Placeholder = "placeholder the first line that is longer than the max width\nplaceholder the second line that is longer than the max width"
m.ShowLineNumbers = true
m.SetWidth(40)
return m
},
want: want{
view: heredoc.Doc(`
> 1 placeholder the first line that is
> longer than the max width
> placeholder the second line that
> is longer than the max width
>
>
`),
},
},
{
name: "placeholder single line that is longer than max width at limit",
modelFunc: func(m Model) Model {
m.Placeholder = "123456789012345678"
m.ShowLineNumbers = false
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 123456789012345678
>
>
>
>
>
`),
},
},
{
name: "placeholder single line that is longer than max width at limit plus one",
modelFunc: func(m Model) Model {
m.Placeholder = "1234567890123456789"
m.ShowLineNumbers = false
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 123456789012345678
> 9
>
>
>
>
`),
},
},
{
name: "placeholder single line that is longer than max width with line numbers at limit",
modelFunc: func(m Model) Model {
m.Placeholder = "12345678901234"
m.ShowLineNumbers = true
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 1 12345678901234
>
>
>
>
>
`),
},
},
{
name: "placeholder single line that is longer than max width with line numbers at limit plus one",
modelFunc: func(m Model) Model {
m.Placeholder = "123456789012345"
m.ShowLineNumbers = true
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 1 12345678901234
> 5
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines that are longer than max width at limit",
modelFunc: func(m Model) Model {
m.Placeholder = "123456789012345678\n123456789012345678"
m.ShowLineNumbers = false
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 123456789012345678
> 123456789012345678
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines that are longer than max width at limit plus one",
modelFunc: func(m Model) Model {
m.Placeholder = "1234567890123456789\n1234567890123456789"
m.ShowLineNumbers = false
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 123456789012345678
> 9
> 123456789012345678
> 9
>
>
`),
},
},
{
name: "placeholder multiple lines that are longer than max width with line numbers at limit",
modelFunc: func(m Model) Model {
m.Placeholder = "12345678901234\n12345678901234"
m.ShowLineNumbers = true
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 1 12345678901234
> 12345678901234
>
>
>
>
`),
},
},
{
name: "placeholder multiple lines that are longer than max width with line numbers at limit plus one",
modelFunc: func(m Model) Model {
m.Placeholder = "123456789012345\n123456789012345"
m.ShowLineNumbers = true
m.SetWidth(20)
return m
},
want: want{
view: heredoc.Doc(`
> 1 12345678901234
> 5
> 12345678901234
> 5
>
>
`),
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
textarea := newTextArea()
if tt.modelFunc != nil {
@@ -1326,7 +1728,7 @@ func sendString(m Model, str string) Model {
}
func stripString(str string) string {
s := stripansi.Strip(str)
s := ansi.Strip(str)
ss := strings.Split(s, "\n")
var lines []string
+1 -1
View File
@@ -378,7 +378,7 @@ func (m Model) View(ctx tea.Context) string {
MaxHeight(contentHeight). // truncate height if taller.
MaxWidth(contentWidth). // truncate width if wider.
Render(strings.Join(m.visibleLines(), "\n"))
return m.Style.Copy().
return m.Style.
UnsetWidth().UnsetHeight(). // Style size already applied in contents.
Render(contents)
}