def ask domain, question, default=nil, &block
    raise "impossible!" if @asking
    raise "Question too long" if Ncurses.cols <= question.length
    @asking = true

    @textfields[domain] ||= TextField.new
    tf = @textfields[domain]
    completion_buf = nil

    status, title = get_status_and_title @focus_buf

    Ncurses.sync do
      tf.activate Ncurses.stdscr, Ncurses.rows - 1, 0, Ncurses.cols, question, default, &block
      @dirty = true # for some reason that blanks the whole fucking screen
      draw_screen :sync => false, :status => status, :title => title
      tf.position_cursor
      Ncurses.refresh
    end

    while true
      c = Ncurses::CharCode.get
      next unless c.present? # getch timeout
      break unless tf.handle_input c # process keystroke

      if tf.new_completions?
        kill_buffer completion_buf if completion_buf

        shorts = tf.completions.map { |full, short| short }
        prefix_len = shorts.shared_prefix(caseless=true).length

        mode = CompletionMode.new shorts, :header => "Possible completions for \"#{tf.value}\": ", :prefix_len => prefix_len
        completion_buf = spawn "<completions>", mode, :height => 10

        draw_screen :skip_minibuf => true
        tf.position_cursor
      elsif tf.roll_completions?
        completion_buf.mode.roll
        draw_screen :skip_minibuf => true
        tf.position_cursor
      end

      Ncurses.sync { Ncurses.refresh }
    end

    kill_buffer completion_buf if completion_buf

    @dirty = true
    @asking = false
    Ncurses.sync do
      tf.deactivate
      draw_screen :sync => false, :status => status, :title => title
    end
    tf.value.tap { |x| x }
  end
def ask domain, question, default=nil, &block
    raise "impossible!" if @asking
    raise "Question too long" if Ncurses.cols <= question.length
    @asking = true

    @textfields[domain] ||= TextField.new
    tf = @textfields[domain]
    completion_buf = nil

    status, title = get_status_and_title @focus_buf

    Ncurses.sync do
      tf.activate Ncurses.stdscr, Ncurses.rows - 1, 0, Ncurses.cols, question, default, &block
      @dirty = true # for some reason that blanks the whole fucking screen
      draw_screen :sync => false, :status => status, :title => title
      tf.position_cursor
      Ncurses.refresh
    end

    while true
      c = Ncurses::CharCode.get
      next unless c.present? # getch timeout
      break unless tf.handle_input c # process keystroke

      if tf.new_completions?
        kill_buffer completion_buf if completion_buf

        shorts = tf.completions.map { |full, short| short }
        prefix_len = shorts.shared_prefix(caseless=true).length

        mode = CompletionMode.new shorts, :header => "Possible completions for \"#{tf.value}\": ", :prefix_len => prefix_len
        completion_buf = spawn "<completions>", mode, :height => 10

        draw_screen :skip_minibuf => true
        tf.position_cursor
      elsif tf.roll_completions?
        completion_buf.mode.roll
        draw_screen :skip_minibuf => true
        tf.position_cursor
      end

      Ncurses.sync { Ncurses.refresh }
    end

    kill_buffer completion_buf if completion_buf

    @dirty = true
    @asking = false
    Ncurses.sync do
      tf.deactivate
      draw_screen :sync => false, :status => status, :title => title
    end
    tf.value.tap { |x| x }
  end
def ask domain , question , default = nil , & block raise "impossible!" if @asking raise "Question too long" if Ncurses . cols <= question . length @asking = true @textfields [ domain ] ||= TextField . new tf = @textfields [ domain ] completion_buf = nil status , title = get_status_and_title @focus_buf Ncurses . sync do tf . activate Ncurses . stdscr , Ncurses . rows - 1 , 0 , Ncurses . cols , question , default , block @dirty = true # for some reason that blanks the whole fucking screen draw_screen :sync => false , :status => status , :title => title tf . position_cursor Ncurses . refresh end while true c = Ncurses :: CharCode . get next unless c . present? # getch timeout break unless tf . handle_input c # process keystroke if tf . new_completions? kill_buffer completion_buf if completion_buf shorts = tf . completions . map { | full , short | short } prefix_len = shorts . shared_prefix ( caseless = true ) . length mode = CompletionMode . new shorts , :header => "Possible completions for \"#{tf.value}\": " , :prefix_len => prefix_len completion_buf = spawn "<completions>" , mode , :height => 10 draw_screen :skip_minibuf => true tf . position_cursor elsif tf . roll_completions? completion_buf . mode . roll draw_screen :skip_minibuf => true tf . position_cursor end Ncurses . sync { Ncurses . refresh } end kill_buffer completion_buf if completion_buf @dirty = true @asking = false Ncurses . sync do tf . deactivate draw_screen :sync => false , :status => status , :title => title end tf . value . tap { | x | x } end
for simplicitly, we always place the question at the very bottom of the
 screen
for simplicitly we always place the question at the very bottom of the screen