Giter Site home page Giter Site logo

Using an enumerator for choices about tty-prompt HOT 3 CLOSED

sled avatar sled commented on June 9, 2024
Using an enumerator for choices

from tty-prompt.

Comments (3)

sled avatar sled commented on June 9, 2024

I managed to get it working by manually creating a TTY::Prompt::List:

prompt = TTY::Prompt.new
letters = ["A", "B", "C", "D", "E"].to_enum

list = TTY::Prompt::List.new(prompt, per_page: 2)
list.call("Choose a letter", letters)

but TTY::Prompt::List seems to iterate all elements, defeating the purpose of having a paged enumerator, e.g:

numbers = Enumerator.new do |yielder|
  count = 1
  loop do
    puts "yield!"
    yielder << count
    count += 1
    break if count > 5
  end
end

list = TTY::Prompt::List.new(prompt, per_page: 2)
list.call("Choose a number", numbers)

will result in:

yield!
yield!
yield!
yield!
yield!
Choose a number (Press ↑/↓/←/→ arrow to move and Enter to select)
‣ 1
  2

this is especially a problem if you have an "infinite" list of things, like a fibonacci sequence. This will block forever:

fib = Enumerator.new do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, a + b
  end
end

list = TTY::Prompt::List.new(prompt, per_page: 10)
list.call("Choose your favorite fibonacci number", fib)

Question
Do you think it's possible to adapt TTY::Prompt::List so that it does not iterate all elements beforehand but rather uses Enumerator#peek to check if there are more elements to paginate?

A possible solution could be to use a different paginator if choices.size returns nil

from tty-prompt.

sled avatar sled commented on June 9, 2024

Found a way to achieve this, but it's a bit messy because it checks if the cursor is at the end of the list by accessing an instance variable.

fib = Enumerator.new do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, a + b
  end
end

prompt = TTY::Prompt.new
list = TTY::Prompt::List.new(prompt)

prompt.on(:keydown) do |event|
  if list.instance_variable_get(:@active) == list.choices.length
    # end of list reached, load more
    list.choice(fib.next)
  end
end

# start with 5 numbers in the list
result = list.call("Select a number: ", 5.times.map { fib.next })

puts "You chose: #{result}"

from tty-prompt.

piotrmurach avatar piotrmurach commented on June 9, 2024

Hi Simon 👋

Thanks for using tty-prompt and submitting this issue.

When I read this issue I got confused by this sentence:

When supplying an enumerator as choices to a select menu, the menu breaks.

Would you mind explaining where did the documentation/examples lead you to believe that enumerators are supported? I'd like to remedy this as this gem has never supported such a use case and I don't wish to confuse anyone going forward.

Supporting enumerators is not a trivial matter due to all the options currently supported. Let's take the :filter option that searches all the choices for a match. It's not straightforward to make it work with an infinite stream as it needs to search through all the choices at once. In other words, what you're suggesting is vastly incompatible with how the select prompt works. The only way I see this being a viable solution is if it was added as an additional prompt type. However, I wonder how common such a need is.

from tty-prompt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.