mirror of
https://github.com/zoriya/bubbles.git
synced 2026-08-16 01:43:21 +00:00
Merge branch 'master' into beta
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -16,6 +16,7 @@ linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- exportloopref
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gosec
|
||||
- nilerr
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user