lib/sup/textfield.rb in sup-0.1 vs lib/sup/textfield.rb in sup-0.2

- old
+ new

@@ -1,17 +1,19 @@ -require 'curses' - module Redwood ## 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 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?). +## 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. class TextField def initialize window, y, x, width @@ -25,34 +27,29 @@ end bool_reader :new_completions, :roll_completions attr_reader :completions - ## when the user presses enter, we store the value in @value and - ## clean up all the ncurses cruft. before @value is set, we can - ## get the current value from ncurses. - def value; @field ? get_cur_value : @value end + def value; @value || get_cursed_value end def activate question, default=nil, &block @question = question - @value = nil @completion_block = block @field = Ncurses::Form.new_field 1, @width - question.length, @y, @x + question.length, 0, 0 @form = Ncurses::Form.new_form [@field] - - @history[@i = @history.size] = default || "" + @value = default Ncurses::Form.post_form @form - set_cur_value @history[@i] + set_cursed_value default if default end 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 @history[@i] =~ / $/ # fucking RETARDED!!!! + Ncurses::Form.form_driver @form, Ncurses::Form::REQ_NEXT_CHAR if @value && @value =~ / $/ # fucking RETARDED!!!! end def deactivate reset_completion_state @form.unpost_form @@ -64,24 +61,25 @@ def handle_input c ## short-circuit exit paths case c when Ncurses::KEY_ENTER # submit! - @value = @history[@i] = get_cur_value + @value = get_cursed_value + @history.push @value return false when Ncurses::KEY_CANCEL # cancel - @history.delete_at @i - @i = @history.empty? ? nil : (@i - 1) % @history.size @value = nil return false when Ncurses::KEY_TAB # completion return true unless @completion_block if @completions.empty? - v = get_cur_value + v = get_cursed_value c = @completion_block.call v if c.size > 0 - set_cur_value c.map { |full, short| full }.shared_prefix + @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 @@ -92,31 +90,38 @@ 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_BACKSPACE Ncurses::Form::REQ_DEL_PREV - when ?\001 + when 1 #ctrl-a Ncurses::Form::REQ_BEG_FIELD - when ?\005 + when 5 #ctrl-e Ncurses::Form::REQ_END_FIELD + when 11 # ctrl-k + Ncurses::Form::REQ_CLR_EOF when Ncurses::KEY_UP - @history[@i] = @field.field_buffer 0 + @i ||= @history.size + @history[@i] = get_cursed_value @i = (@i - 1) % @history.size - set_cur_value @history[@i] + @value = @history[@i] + set_cursed_value @value when Ncurses::KEY_DOWN - @history[@i] = @field.field_buffer 0 + @i ||= @history.size + @history[@i] = get_cursed_value @i = (@i + 1) % @history.size - set_cur_value @history[@i] + @value = @history[@i] + set_cursed_value @value else c end Ncurses::Form.form_driver @form, d @@ -129,18 +134,27 @@ @completions = [] @new_completions = @roll_completions = @clear_completions = false end ## ncurses inanity wrapper - def get_cur_value + ## + ## DO NOT READ THIS CODE. YOU WILL GO MAD. + def get_cursed_value + return nil unless @field + + x = Ncurses.curx Ncurses::Form.form_driver @form, Ncurses::Form::REQ_VALIDATION - @field.field_buffer(0).gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ") + v = @field.field_buffer(0).gsub(/^\s+|\s+$/, "") + + ## cursor <= end of text + if x - @question.length - v.length <= 0 + v + else # trailing spaces + v + (" " * (x - @question.length - v.length)) + end end - - ## ncurses inanity wrapper - def set_cur_value v + + def set_cursed_value v @field.set_field_buffer 0, v - Ncurses::Form.form_driver @form, Ncurses::Form::REQ_END_FIELD end - end end