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