5 ## a fully-functional text field supporting completions, expansions,
6 ## history--everything!
8 ## writing this fucking sucked. if you thought ncurses was some 1970s
9 ## before-people-knew-how-to-program bullshit, wait till you see
12 ## completion comments: completion is done emacs-style, and mostly
13 ## depends on outside support, as we merely signal the existence of a
14 ## new set of completions to show (#new_completions?) or that the
15 ## current list of completions should be rolled if they're too large
16 ## to fill the screen (#roll_completions?).
18 ## in sup, completion support is implemented through BufferManager#ask
19 ## and CompletionMode.
21 def initialize window, y, x, width
22 @w, @x, @y = window, x, y
27 @completion_block = nil
28 reset_completion_state
31 bool_reader :new_completions, :roll_completions
32 attr_reader :completions
34 def value; @value || get_cursed_value end
36 def activate question, default=nil, &block
38 @completion_block = block
39 @field = Ncurses::Form.new_field 1, @width - question.length,
40 @y, @x + question.length, 0, 0
41 @form = Ncurses::Form.new_form [@field]
42 Ncurses::Form.post_form @form
43 set_cursed_value default if default
47 @w.attrset Colormap.color_for(:none)
48 @w.mvaddstr @y, 0, @question
50 Ncurses::Form.form_driver @form, Ncurses::Form::REQ_END_FIELD
51 Ncurses::Form.form_driver @form, Ncurses::Form::REQ_NEXT_CHAR if @value && @value =~ / $/ # fucking RETARDED!!!!
55 reset_completion_state
64 ## short-circuit exit paths
66 when Ncurses::KEY_ENTER # submit!
67 @value = get_cursed_value
70 when Ncurses::KEY_CANCEL # cancel
73 when Ncurses::KEY_TAB # completion
74 return true unless @completion_block
75 if @completions.empty?
77 c = @completion_block.call v
79 @value = c.map { |full, short| full }.shared_prefix(true)
80 set_cursed_value @value
85 @new_completions = true
86 @roll_completions = false
89 @new_completions = false
90 @roll_completions = true
95 reset_completion_state
100 when Ncurses::KEY_LEFT
101 Ncurses::Form::REQ_PREV_CHAR
102 when Ncurses::KEY_RIGHT
103 Ncurses::Form::REQ_NEXT_CHAR
104 when Ncurses::KEY_BACKSPACE
105 Ncurses::Form::REQ_DEL_PREV
107 Ncurses::Form::REQ_BEG_FIELD
109 Ncurses::Form::REQ_END_FIELD
111 Ncurses::Form::REQ_CLR_EOF
114 @history[@i] = get_cursed_value
115 @i = (@i - 1) % @history.size
116 @value = @history[@i]
117 set_cursed_value @value
118 when Ncurses::KEY_DOWN
120 @history[@i] = get_cursed_value
121 @i = (@i + 1) % @history.size
122 @value = @history[@i]
123 set_cursed_value @value
128 Ncurses::Form.form_driver @form, d
134 def reset_completion_state
136 @new_completions = @roll_completions = @clear_completions = false
139 ## ncurses inanity wrapper
141 ## DO NOT READ THIS CODE. YOU WILL GO MAD.
143 return nil unless @field
146 Ncurses::Form.form_driver @form, Ncurses::Form::REQ_VALIDATION
147 v = @field.field_buffer(0).gsub(/^\s+|\s+$/, "")
149 ## cursor <= end of text
150 if x - @question.length - v.length <= 0
152 else # trailing spaces
153 v + (" " * (x - @question.length - v.length))
157 def set_cursed_value v
158 @field.set_field_buffer 0, v