Class: Redwood::TextField

Inherits:
Object show all
Defined in:
lib/sup/textfield.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(window, y, x, width) ⇒ TextField

Returns a new instance of TextField.



19
20
21
22
23
24
25
26
27
# File 'lib/sup/textfield.rb', line 19

def initialize window, y, x, width
  @w, @x, @y = window, x, y
  @width = width
  @i = nil
  @history = []

  @completion_block = nil
  reset_completion_state
end

Instance Attribute Details

#completionsObject (readonly)

Returns the value of attribute completions.



30
31
32
# File 'lib/sup/textfield.rb', line 30

def completions
  @completions
end

Instance Method Details

#activate(question, default = nil, &block) ⇒ Object



34
35
36
37
38
39
40
41
42
43
# File 'lib/sup/textfield.rb', line 34

def activate question, default=nil, &block
  @question = question
  @completion_block = block
  @field = Ncurses::Form.new_field 1, @width - question.length,
                                   @y, @x + question.length, 0, 0
  @form = Ncurses::Form.new_form [@field]
  @value = default
  Ncurses::Form.post_form @form
  set_cursed_value default if default
end

#deactivateObject



53
54
55
56
57
58
59
60
# File 'lib/sup/textfield.rb', line 53

def deactivate
  reset_completion_state
  @form.unpost_form
  @form.free_form
  @field.free_field
  @field = nil
  Ncurses.curs_set 0
end

#handle_input(c) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/sup/textfield.rb', line 62

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_BACKSPACE
      Ncurses::Form::REQ_DEL_PREV
    when 1 #ctrl-a
      Ncurses::Form::REQ_BEG_FIELD
    when 5 #ctrl-e
      Ncurses::Form::REQ_END_FIELD
    when 11 # ctrl-k
      Ncurses::Form::REQ_CLR_EOF
    when Ncurses::KEY_UP, Ncurses::KEY_DOWN
      unless @history.empty?
        value = get_cursed_value
        @i ||= @history.size
        #Redwood::log "history before #{@history.inspect}"
        @history[@i] = value #unless value =~ /^\s*$/
        @i = (@i + (c == Ncurses::KEY_UP ? -1 : 1)) % @history.size
        @value = @history[@i]
        #Redwood::log "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

#position_cursorObject



45
46
47
48
49
50
51
# File 'lib/sup/textfield.rb', line 45

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

#valueObject



32
# File 'lib/sup/textfield.rb', line 32

def value; @value || get_cursed_value end