manifoldco / promptui

Interactive prompt for command-line applications
https://www.manifold.co
BSD 3-Clause "New" or "Revised" License
6.03k stars 333 forks source link

Default searcher implemetation #212

Open migueleliasweb opened 1 year ago

migueleliasweb commented 1 year ago

Hi, firstly thanks for the code. It's great.

I've had a bit of problem using the search feature but after digging a little bit, I've found my way.

Have said that, I reckon it would be awesome if there was some kind of default simple implementation of the searcher someone could use that could fit a lot of differet usecases.

This implementation doesn't add any dependencies since it only uses the std library.

Here's the idea:

package main

import (
    "fmt"
    "regexp"

    "github.com/manifoldco/promptui"
)

func SimpleRegexSearcher(items []string) func(input string, index int) bool {
    return func(input string, index int) bool {
        reg, _ := regexp.Compile(fmt.Sprintf("(?i).*%s.*", input))

        return reg.MatchString(items[index])
    }
}

func main() {
    items := []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
    prompt := promptui.Select{
        StartInSearchMode: true,
        Label:             "Select Day",
        Items:             items,
        Searcher:          SimpleRegexSearcher(items),
    }

    _, result, err := prompt.Run()

    if err != nil {
        fmt.Printf("Prompt failed %v\n", err)
        return
    }

    fmt.Printf("You choose %q\n", result)
}

Let me know if you think this is a good idea so I can make a PR :)

migueleliasweb commented 1 year ago

The idea is not make the simpleRegexSearcher the default implementation per say. But instead allow users to easily use it as it would be implemented in the same package as the select package.

So the final code would look something like this:

func main() {
    items := []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
    prompt := promptui.Select{
        StartInSearchMode: true,
        Label:             "Select Day",
        Items:             items,
        Searcher:          promptui.SimpleRegexSearcher(items),
    }

    _, result, err := prompt.Run()

    if err != nil {
        fmt.Printf("Prompt failed %v\n", err)
        return
    }

    fmt.Printf("You choose %q\n", result)
}
TrayserCassa commented 1 year ago

In case of speed and also error checking I would not use regex for this, just a strings.Contains() I think is the better way. But that's just my opinion.

migueleliasweb commented 1 year ago

Fair point. Yeah we could change it to use that instead.

migueleliasweb commented 1 year ago

Oh, actually... I think I did try this and it turns out you can't make it so it's case insensitive. That was the reason I used regex. =/

migueleliasweb commented 1 year ago

Ping @jbowes 🔔 .

Hi, James. Do you still support this repo or is it already considered stable (no further changes)?