a fully-functional text field supporting completions, expansions, history--everything!
writing this fucking sucked. if you thought ncurses was some 1970s before-people-knew-how-to-program bullshit, wait till you see ncurses forms.
completion comments: completion is done emacs-style, and mostly depends on outside support, as we merely signal the existence of a new set of completions to show (new_completions?) or that the current list of completions should be rolled if they're too large to fill the screen (roll_completions?).
in sup, completion support is implemented through BufferManager#ask and CompletionMode.
# File lib/sup/textfield.rb, line 32 def activate window, y, x, width, question, default=nil, &block @w, @y, @x, @width = window, y, x, width @question = question @completion_block = block @field = Ncurses::Form.new_field 1, @width - question.length, @y, @x + question.length, 256, 0 @form = Ncurses::Form.new_form [@field] @value = default || '' Ncurses::Form.post_form @form set_cursed_value @value end
# File lib/sup/textfield.rb, line 51 def deactivate reset_completion_state @form.unpost_form @form.free_form @field.free_field @field = nil Ncurses.curs_set 0 end
# File lib/sup/textfield.rb, line 60 def handle_input c ## short-circuit exit paths case c when Ncurses::KEY_ENTER # submit! @value = get_cursed_value @history.push @value unless @value =~ /^\s*$/ return false when Ncurses::KEY_CANCEL # cancel @value = nil return false when Ncurses::KEY_TAB # completion return true unless @completion_block if @completions.empty? v = get_cursed_value c = @completion_block.call v if c.size > 0 @value = c.map { |full, short| full }.shared_prefix(true) set_cursed_value @value position_cursor end if c.size > 1 @completions = c @new_completions = true @roll_completions = false end else @new_completions = false @roll_completions = true end return true end reset_completion_state @value = nil d = case c when Ncurses::KEY_LEFT Ncurses::Form::REQ_PREV_CHAR when Ncurses::KEY_RIGHT Ncurses::Form::REQ_NEXT_CHAR when Ncurses::KEY_DC Ncurses::Form::REQ_DEL_CHAR when Ncurses::KEY_BACKSPACE, 127 # 127 is also a backspace keysym Ncurses::Form::REQ_DEL_PREV when \C\ nop Ncurses::Form::REQ_BEG_FIELD when \C\ Ncurses::Form::REQ_END_FIELD when \C\ Ncurses::Form::REQ_CLR_EOF when \C\ set_cursed_value cursed_value_after_point Ncurses::Form.form_driver @form, Ncurses::Form::REQ_END_FIELD nop Ncurses::Form::REQ_BEG_FIELD when \C\ Ncurses::Form.form_driver @form, Ncurses::Form::REQ_PREV_CHAR Ncurses::Form.form_driver @form, Ncurses::Form::REQ_DEL_WORD when Ncurses::KEY_UP, Ncurses::KEY_DOWN unless @history.empty? value = get_cursed_value @i ||= @history.size #debug "history before #{@history.inspect}" @history[@i] = value #unless value =~ /^\s*$/ @i = (@i + (c == Ncurses::KEY_UP ? -1 : 1)) % @history.size @value = @history[@i] #debug "history after #{@history.inspect}" set_cursed_value @value Ncurses::Form::REQ_END_FIELD end else c end Ncurses::Form.form_driver @form, d if d true end
# File lib/sup/textfield.rb, line 43 def position_cursor @w.attrset Colormap.color_for(:none) @w.mvaddstr @y, 0, @question Ncurses.curs_set 1 Ncurses::Form.form_driver @form, Ncurses::Form::REQ_END_FIELD Ncurses::Form.form_driver @form, Ncurses::Form::REQ_NEXT_CHAR if @value && @value =~ / $/ # fucking RETARDED end
Generated with the Darkfish Rdoc Generator 2.