Skip to content

Commit

Permalink
- add fuzzy usability improvements
Browse files Browse the repository at this point in the history
- bump go version to 1.23
  • Loading branch information
prnvbn committed Sep 14, 2024
1 parent 7fa59a8 commit fb7e55f
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 10 deletions.
9 changes: 7 additions & 2 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ import (

// addCmd represents the add command
var addCmd = &cobra.Command{
Use: "add",
Use: "add [FUZZY_COUNTRY_NAME?]",
Short: "Add one or more clock",
PostRunE: saveConfig,
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
oldNumClocks := len(cfg.ClockCfgs)
clockCfgs := ui.SelectClocks()
searchTerm := ""
if len(args) >= 1 {
searchTerm = args[0]
}
clockCfgs := ui.SelectClocks(searchTerm)
cfg.ClockCfgs.Add(clockCfgs...)

newNumClocks := len(cfg.ClockCfgs)
Expand Down
36 changes: 34 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ var (

cfg ui.AppConfig
rootCmd = &cobra.Command{
Use: "clocks",
Use: "clocks [FUZZY_CLOCK_NAME?]",
Short: "A tool to display time across multiple timezones.",
PersistentPreRunE: loadConfig,
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
if clocksAbsent() {
return
Expand All @@ -52,6 +53,38 @@ var (
if twelveHr {
cfg.TwelveHour = true
}

if len(args) >= 1 {
// when a @search term is passed, set layout to horizontal
// so that all clocks are displayed in one row
// clocks are filtered by the search term
// fuzzy search is used to match the search term
searchTerm := args[0]
cfg.Layout.LayoutType = ui.Horizontal

n := 0
cfg.ClockCfgs, n = cfg.ClockCfgs.Filter(searchTerm)
if n == 0 {
pterm.FgYellow.Println("No clocks match the search term:", searchTerm)
return
}
}

if len(args) >= 1 {
// when a @search term is passed, set layout to horizontal
// so that all clocks are displayed in one row
// clocks are filtered by the search term
// fuzzy search is used to match the search term
searchTerm := args[0]
cfg.Layout.LayoutType = ui.Horizontal

n := 0
cfg.ClockCfgs, n = cfg.ClockCfgs.Filter(searchTerm)
if n == 0 {
pterm.FgYellow.Println("No clocks match the search term:", searchTerm)
return
}
}

ui.ShowClocks(cfg)
},
Expand Down Expand Up @@ -152,7 +185,6 @@ func addFlags(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&live, "live", "l", false, "keeps clocks on screen")
cmd.Flags().BoolVarP(&seconds, "seconds", "s", false, "shows seconds as well")
cmd.Flags().BoolVar(&twelveHr, "t12", false, "print dates in 12 hour format")

}

func fatal(err error, fmt string, args ...any) {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module github.com/prnvbn/clocks

go 1.21.3
go 1.23.1

require (
github.com/adrg/xdg v0.4.0
github.com/lithammer/fuzzysearch v1.1.8
github.com/pkg/errors v0.9.1
github.com/pterm/pterm v0.12.75
github.com/rs/zerolog v1.31.0
Expand All @@ -21,7 +22,6 @@ require (
github.com/gookit/color v1.5.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
Expand Down
11 changes: 11 additions & 0 deletions internal/match/fuzzy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package match

import (
"strings"

"github.com/lithammer/fuzzysearch/fuzzy"
)

func Fuzzy(searchTerm string, toMatch string) bool {
return fuzzy.Match(strings.ToLower(searchTerm), strings.ToLower(toMatch))
}
20 changes: 20 additions & 0 deletions internal/tmz/filtered.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package tmz

import (
"iter"

"github.com/prnvbn/clocks/internal/match"
)

func FilteredCountries(searchTerm string) iter.Seq[string] {
return func(yield func(string) bool) {
for cntry := range CountryZonesMap {
if match.Fuzzy(searchTerm, cntry) {
if !yield(cntry) {
return
}
}
}
}

}
1 change: 0 additions & 1 deletion internal/ui/clocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ func ShowClocks(appCfg AppConfig) {
}

time.Sleep(time.Second)

}
}

Expand Down
21 changes: 21 additions & 0 deletions internal/ui/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package ui
import (
"encoding/json"
"fmt"
"iter"
"slices"
"strings"

"github.com/prnvbn/clocks/internal/match"
"github.com/prnvbn/clocks/internal/tmz"
)

Expand Down Expand Up @@ -93,3 +96,21 @@ func (s *SortedClockConfigs) Remove(toRemove ...ClockConfig) {
return slices.Contains(toRemove, cfg)
})
}

func (s SortedClockConfigs) Filter(searchTerm string) (filtered SortedClockConfigs, n int) {
filtered = slices.Collect(s.fuzzyFiltered(searchTerm))
n = len(filtered)
return
}

func (s SortedClockConfigs) fuzzyFiltered(searchTerm string) iter.Seq[ClockConfig] {
return func(yield func(ClockConfig) bool) {
for _, clockCfg := range s {
if match.Fuzzy(strings.ToLower(searchTerm), strings.ToLower(clockCfg.Heading)) {
if !yield(clockCfg) {
return
}
}
}
}
}
6 changes: 3 additions & 3 deletions internal/ui/select_clocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import (

"github.com/prnvbn/clocks/internal/tmz"
"github.com/pterm/pterm"
"golang.org/x/exp/maps"
"golang.org/x/term"
)

const (
minMaxHeight = 5
)

func SelectClocks() []ClockConfig {
cntries := maps.Keys(tmz.CountryZonesMap)
func SelectClocks(searchTerm string) []ClockConfig {
cntries := slices.Collect(tmz.FilteredCountries(searchTerm))

slices.Sort(cntries)

cntryMenuHeading := pterm.ThemeDefault.PrimaryStyle.Sprint("Please select countries; you can select the timezones after this ") + pterm.ThemeDefault.SecondaryStyle.Sprint("[type to search]")
Expand Down

0 comments on commit fb7e55f

Please sign in to comment.