package app import ( "os" "strings" "git.sr.ht/~rockorager/vaxis" "git.sr.ht/~rockorager/vaxis/widgets/textinput" "git.tilde.town/nbsp/directory/ui" ) type App struct { allUsers []string users ui.List filter textinput.Model searching bool } func New() *App { users := []string{"(home)"} userDirs, _ := os.ReadDir("/home") for _, user := range userDirs { if user.IsDir() { users = append(users, "~"+user.Name()) } } return &App{users: ui.NewList(users, 0), allUsers: users} } func (app *App) Event(state *ui.State, event vaxis.Event) { if key, ok := event.(vaxis.Key); ok && key.EventType == vaxis.EventPress { other := false switch key.String() { case "Ctrl+c", "Ctrl+d": close(ui.Quit) case "Down", "Ctrl+n": app.users.Down() case "Up", "Ctrl+p": app.users.Up() case "End": app.users.End() case "Home": app.users.Home() case "Escape": app.searching = false default: other = true } if other { if !app.searching { switch key.String() { case "q": close(ui.Quit) case "j": app.users.Down() case "k": app.users.Up() case "g": app.users.Home() case "Shift+g": app.users.End() case "/": app.searching = true app.filter.SetContent("") } } else { app.filter.Update(event) app.users.SetItems(filter(app.allUsers, app.filter.String())) } } } win := state.Window() w, h := win.Size() if len(app.users.Items()) > 0 { app.users.Draw(win.New(0, 0, 20, h-1)) } for x := 0; x < w; x++ { setCell(win, x, h-2, '─', vaxis.Style{}) } if app.searching { app.filter.Draw(win.New(0, h-1, w, 1)) } else { win.New(0, h-1, w, 1).Print(vaxis.Segment{Text: "press / to search users", Style: vaxis.Style{Foreground: vaxis.IndexColor(8)}}) } } func setCell(win vaxis.Window, x int, y int, r rune, st vaxis.Style) { win.SetCell(x, y, vaxis.Cell{ Character: vaxis.Character{ Grapheme: string([]rune{r}), }, Style: st, }) } func filter(users []string, query string) []string { var filtered []string for _, s := range users { if strings.Contains(s, query) { filtered = append(filtered, s) } } return filtered }