@@ -17,8 +17,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
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 v1.0.0 h1:yjRSILSEUSIhuRcyOJ55tbSKtvBLmJDgbPErH8pXcxM=
-github.com/aymanbagabas/go-osc52 v1.0.0/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
github.com/aymanbagabas/go-osc52 v1.0.1 h1:juDXgeKhMfVnylcoA4S7p9E4q+9DErUZGkX8t2ZR2j8=
github.com/aymanbagabas/go-osc52 v1.0.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
@@ -16,20 +16,26 @@ import (
// Item represents a single item in the selector.
type Item struct {
- Title string
- Name string
- Description string
- LastUpdate time.Time
- URL *yankable.Yankable
+ name string
+ repo string
+ desc string
+ lastUpdate time.Time
+ url *yankable.Yankable
}
// ID implements selector.IdentifiableItem.
func (i Item) ID() string {
- return i.Name
+ return i.repo
}
+// Title returns the item title. Implements list.DefaultItem.
+func (i Item) Title() string { return i.name }
+
+// Description returns the item description. Implements list.DefaultItem.
+func (i Item) Description() string { return i.desc }
+
// FilterValue implements list.Item.
-func (i Item) FilterValue() string { return i.Title }
+func (i Item) FilterValue() string { return i.name }
// ItemDelegate is the delegate for the item.
type ItemDelegate struct {
@@ -77,8 +83,8 @@ func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
continue
}
}
- y, cmd := itm.URL.Update(msg)
- itm.URL = y.(*yankable.Yankable)
+ y, cmd := itm.url.Update(msg)
+ itm.url = y.(*yankable.Yankable)
if cmd != nil {
cmds = append(cmds, cmd)
}
@@ -90,29 +96,50 @@ func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
func (d ItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
i := listItem.(Item)
s := strings.Builder{}
- style := d.styles.MenuItem.Copy()
- if index == m.Index() {
- style = style.BorderForeground(d.styles.ActiveBorderColor)
+ var matchedRunes []int
+
+ // Conditions
+ var (
+ isSelected = index == m.Index()
+ // emptyFilter = m.FilterState() == list.Filtering && m.FilterValue() == ""
+ isFiltered = m.FilterState() == list.Filtering || m.FilterState() == list.FilterApplied
+ )
+
+ itemStyle := d.styles.MenuItem.Copy()
+ if isSelected {
+ itemStyle = itemStyle.BorderForeground(d.styles.ActiveBorderColor)
if d.activeBox != nil && *d.activeBox == readmeBox {
// TODO make this into its own color
- style = style.BorderForeground(lipgloss.Color("15"))
+ itemStyle = itemStyle.BorderForeground(lipgloss.Color("15"))
}
}
- titleStr := i.Title
- updatedStr := fmt.Sprintf(" Updated %s", humanize.Time(i.LastUpdate))
+
+ title := i.name
+ updatedStr := fmt.Sprintf(" Updated %s", humanize.Time(i.lastUpdate))
updated := d.styles.MenuLastUpdate.
Copy().
- Width(m.Width() - style.GetHorizontalFrameSize() - lipgloss.Width(titleStr)).
+ Width(m.Width() - itemStyle.GetHorizontalFrameSize() - lipgloss.Width(title)).
Render(updatedStr)
- title := lipgloss.NewStyle().
+ titleStyle := lipgloss.NewStyle().
Align(lipgloss.Left).
- Width(m.Width() - style.GetHorizontalFrameSize() - lipgloss.Width(updated)).
- Render(titleStr)
+ Width(m.Width() - itemStyle.GetHorizontalFrameSize() - lipgloss.Width(updated))
+
+ if isFiltered && index < len(m.VisibleItems()) {
+ // Get indices of matched characters
+ matchedRunes = m.MatchesForItem(index)
+ }
+
+ if isFiltered {
+ unmatched := lipgloss.NewStyle().Inline(true)
+ matched := unmatched.Copy().Underline(true)
+ title = lipgloss.StyleRunes(title, matchedRunes, matched, unmatched)
+ }
+ title = titleStyle.Render(title)
s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, updated))
s.WriteString("\n")
- s.WriteString(i.Description)
+ s.WriteString(i.desc)
s.WriteString("\n\n")
- s.WriteString(i.URL.View())
- w.Write([]byte(style.Render(s.String())))
+ s.WriteString(i.url.View())
+ w.Write([]byte(itemStyle.Render(s.String())))
}
@@ -140,29 +140,29 @@ func (s *Selection) Init() tea.Cmd {
// Put configured repos first
for _, r := range cfg.Repos {
items = append(items, Item{
- Title: r.Name,
- Name: r.Repo,
- Description: r.Note,
- LastUpdate: time.Now(),
- URL: yank(repoUrl(cfg, r.Repo)),
+ name: r.Name,
+ repo: r.Repo,
+ desc: r.Note,
+ lastUpdate: time.Now(), // TODO get repo last update
+ url: yank(repoUrl(cfg, r.Repo)),
})
}
for _, r := range cfg.Source.AllRepos() {
exists := false
for _, item := range items {
item := item.(Item)
- if item.Name == r.Name() {
+ if item.repo == r.Name() {
exists = true
break
}
}
if !exists {
items = append(items, Item{
- Title: r.Name(),
- Name: r.Name(),
- Description: "",
- LastUpdate: time.Now(),
- URL: yank(repoUrl(cfg, r.Name())),
+ name: r.Name(),
+ repo: r.Name(),
+ desc: "",
+ lastUpdate: time.Now(), // TODO get repo last update
+ url: yank(repoUrl(cfg, r.Name())),
})
}
}