Class: VER::MiniBuffer

Inherits:
Tk::Text
  • Object
show all
Includes:
Keymapped
Defined in:
lib/ver/minibuffer.rb

Instance Attribute Summary collapse

Attributes included from Keymapped

#major_mode

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Keymapped

#minor_mode, #minor_mode?

Constructor Details

#initialize(*args) ⇒ MiniBuffer

Returns a new instance of MiniBuffer.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/ver/minibuffer.rb', line 7

def initialize(*args)
  super

  font = VER.options.font
  configure(
    font: font,
    wrap: :none,
    undo: true,
    borderwidth: 0,
    exportselection: true,
    insertofftime: 0,
    setgrid: false, # wtf?
    autoseparators: true,
    blockcursor: false,
    background: '#000',
    foreground: '#fff',
    insertbackground: '#fff'
  )

  self.major_mode = :MiniBuffer
  self.messages_expire = false
  self.messages_pending = 0
  self.char_width = font.measure('0')

  tag_configure 'info', foreground: '#fff'
  tag_configure 'warn', foreground: '#f00'
  tag_configure 'highlight', background: '#330'

  bind('<Configure>'){ adjust_size }
end

Instance Attribute Details

#char_widthObject

Returns the value of attribute char_width.



5
6
7
# File 'lib/ver/minibuffer.rb', line 5

def char_width
  @char_width
end

#messages_expireObject

Returns the value of attribute messages_expire.



5
6
7
# File 'lib/ver/minibuffer.rb', line 5

def messages_expire
  @messages_expire
end

#messages_pendingObject

Returns the value of attribute messages_pending.



5
6
7
# File 'lib/ver/minibuffer.rb', line 5

def messages_pending
  @messages_pending
end

Class Method Details

.answer_from(text) ⇒ Object



157
158
159
160
161
162
# File 'lib/ver/minibuffer.rb', line 157

def self.answer_from(text)
  line = text.get('current linestart', 'current lineend')
  minibuf = VER.minibuf
  minibuf.answer = line
  minibuf.complete_small
end

Instance Method Details

#abort(event = nil) ⇒ Object



144
145
146
147
148
149
150
151
# File 'lib/ver/minibuffer.rb', line 144

def abort(event = nil)
  self.answer = ''
  self.prompt = ''
  bind('<FocusOut>'){ }
  self.messages_expire = false
  Buffer[:Completions].hide
  @caller.focus
end

#adjust_sizeObject



38
39
40
41
42
43
# File 'lib/ver/minibuffer.rb', line 38

def adjust_size
  configure(
    width: (tk_parent.winfo_width / char_width.to_f).floor,
    height: count('1.0', 'end', :lines)
  )
end

#answerObject



65
66
67
68
69
# File 'lib/ver/minibuffer.rb', line 65

def answer
  get('answer.first', 'answer.last')
rescue
  ''
end

#answer=(answer) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/ver/minibuffer.rb', line 57

def answer=(answer)
  replace 'answer.first', 'answer.last', answer, 'answer'
rescue
  insert 'prompt.last', answer, 'answer'
rescue
  insert 'end', answer, 'answer'
end

#ask(prompt, options = {}, &action) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ver/minibuffer.rb', line 130

def ask(prompt, options = {}, &action)
  @action = action || options[:action]
  @caller = options.fetch(:caller)

  self.prompt = prompt
  self.answer = options[:value].to_s

  message ''
  warn ''
  self.messages_expire = true
  bind('<FocusOut>'){ focus }
  focus
end

#attempt(event = nil) ⇒ Object



153
154
155
# File 'lib/ver/minibuffer.rb', line 153

def attempt(event = nil)
  invoke(:attempt)
end

#complete_large(event = nil) ⇒ Object



183
184
185
186
187
188
189
190
191
# File 'lib/ver/minibuffer.rb', line 183

def complete_large(event = nil)
  if choices = invoke(:complete)
    if choices.size == 1
      self.answer = choices.first
    elsif choices.size > 1
      show_completions(choices)
    end
  end
end

#complete_small(event = nil) ⇒ Object



175
176
177
178
179
180
181
# File 'lib/ver/minibuffer.rb', line 175

def complete_small(event = nil)
  if choices = invoke(:complete)
    if choices.size == 1
      self.answer = choices.first
    end
  end
end

#end_of_line(event = nil) ⇒ Object



223
224
225
226
227
# File 'lib/ver/minibuffer.rb', line 223

def end_of_line(event = nil)
  return if tag_ranges('answer').empty?
  mark_set('insert', 'answer.last')
  invoke(:movement)
end

#insert_selection(event = nil) ⇒ Object



213
214
215
216
# File 'lib/ver/minibuffer.rb', line 213

def insert_selection(event = nil)
  insert(:insert, Tk::Selection.get, 'answer')
  invoke(:modified)
end

#insert_string(event) ⇒ Object



203
204
205
206
207
208
209
210
211
# File 'lib/ver/minibuffer.rb', line 203

def insert_string(event)
  case string = event.unicode
  when /^([[:word:][:ascii:]]| )+$/
    insert(:insert, string, 'answer')
    invoke(:modified)
  else
    p string
  end
end

#insert_tab(event = nil) ⇒ Object



218
219
220
221
# File 'lib/ver/minibuffer.rb', line 218

def insert_tab(event = nil)
  insert(:insert, "\t", 'answer')
  invoke(:modified)
end

#invoke(action, *args) ⇒ Object



193
194
195
196
197
198
199
200
201
# File 'lib/ver/minibuffer.rb', line 193

def invoke(action, *args)
  Tk::Event.generate(self, "<<#{action.capitalize}>>")
  case result = @action.call(answer, action, *args)
  when :abort
    abort
  else
    result
  end
end

#kill_end_of_line(event = nil) ⇒ Object



229
230
231
232
233
# File 'lib/ver/minibuffer.rb', line 229

def kill_end_of_line(event = nil)
  return if tag_ranges('answer').empty?
  delete('insert', 'answer.last')
  invoke(:modified)
end

#kill_next_char(event = nil) ⇒ Object



235
236
237
238
239
# File 'lib/ver/minibuffer.rb', line 235

def kill_next_char(event = nil)
  return if tag_ranges('answer').empty?
  delete('insert')
  invoke(:modified)
end

#kill_next_word(event = nil) ⇒ Object



241
242
243
244
245
246
247
# File 'lib/ver/minibuffer.rb', line 241

def kill_next_word(event = nil)
  return if tag_ranges('answer').empty?
  line = get('insert', 'answer.last')
  return unless word = line[/^\s*(?:\w+|[^\w\s]+)\s*/]
  delete('insert', "insert + #{word.size} chars")
  invoke(:modified)
end

#kill_prev_char(event = nil) ⇒ Object



249
250
251
252
253
# File 'lib/ver/minibuffer.rb', line 249

def kill_prev_char(event = nil)
  return if tag_ranges('answer').empty?
  delete('insert - 1 chars')
  invoke(:modified)
end

#kill_prev_word(event = nil) ⇒ Object



255
256
257
258
259
260
261
# File 'lib/ver/minibuffer.rb', line 255

def kill_prev_word(event = nil)
  return if tag_ranges('answer').empty?
  line = get('answer.first', 'insert').reverse
  return unless word = line[/^\s*(?:\w+|[^\w\s]+)\s*/]
  delete("insert - #{word.size} chars", 'insert')
  invoke(:modified)
end

#message(string, tag = 'info') ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ver/minibuffer.rb', line 71

def message(string, tag = 'info')
  Tk::After.idle do
    insert = index('insert')

    begin
      replace "#{tag}.first", "#{tag}.last", " #{string}", tag
    rescue
      insert '1.0 lineend', " #{string}", tag
    end

    mark_set('insert', insert)
    see "#{tag}.first"

    message_expire(tag) #  if messages_expire
    message_notify(tag)
    message_buffer_insert(string, tag)
  end
end

#message_buffer_insert(string, tag) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/ver/minibuffer.rb', line 90

def message_buffer_insert(string, tag)
  string = "#{string}\n" unless string.end_with?("\n")
  buffer = Buffer[:Messages]
  buffer.text.execute(:insert, :end, string, tag)

  last_focus = Tk::Focus.focus # for some reason
  buffer.text.see(:end)        # this changes focus to the text
  Tk::Focus.focus(last_focus)  # so we restore it here
end

#message_expire(tag, timeout = 3000) ⇒ Object



108
109
110
111
112
113
114
115
116
117
# File 'lib/ver/minibuffer.rb', line 108

def message_expire(tag, timeout = 3000)
  self.messages_pending += 1

  Tk::After.ms timeout.to_int do
    self.messages_pending -= 1
    if messages_pending == 0
      delete("#{tag}.first", "#{tag}.last") rescue nil
    end
  end
end

#message_notify(tag, timeout = 500) ⇒ Object



100
101
102
103
104
105
106
# File 'lib/ver/minibuffer.rb', line 100

def message_notify(tag, timeout = 500)
  tag_add('highlight', "#{tag}.first", "#{tag}.last")

  Tk::After.ms timeout.to_int do
    tag_remove('highlight', "#{tag}.first", "#{tag}.last")
  end
end

#next_char(event = nil) ⇒ Object



263
264
265
266
267
268
# File 'lib/ver/minibuffer.rb', line 263

def next_char(event = nil)
  return if tag_ranges('answer').empty?
  return if compare('insert', '>=', 'answer.last')
  mark_set('insert', 'insert + 1 chars')
  invoke(:movement)
end

#prev_char(event = nil) ⇒ Object



270
271
272
273
274
275
# File 'lib/ver/minibuffer.rb', line 270

def prev_char(event = nil)
  return if tag_ranges('answer').empty?
  return if compare('insert', '<=', 'answer.first')
  mark_set('insert', 'insert - 1 chars')
  invoke(:movement)
end

#promptObject



51
52
53
54
55
# File 'lib/ver/minibuffer.rb', line 51

def prompt
  get('prompt.first', 'prompt.last')
rescue
  ''
end

#prompt=(prompt) ⇒ Object



45
46
47
48
49
# File 'lib/ver/minibuffer.rb', line 45

def prompt=(prompt)
  replace 'prompt.first', 'prompt.last', prompt, 'prompt'
rescue
  insert '1.0 linestart', prompt, 'prompt'
end

#show_completions(completions) ⇒ Object



164
165
166
167
168
169
170
171
172
173
# File 'lib/ver/minibuffer.rb', line 164

def show_completions(completions)
  buffer = Buffer[:Completions]
  text = buffer.text
  text.delete('1.0', 'end')
  completions.each do |completion|
    text.insert('end', completion, 'ver.minibuf.completion')
    text.insert('end', "\n")
  end
  buffer.show
end

#start_of_line(event = nil) ⇒ Object



277
278
279
280
281
# File 'lib/ver/minibuffer.rb', line 277

def start_of_line(event = nil)
  return if tag_ranges('answer').empty?
  mark_set('insert', 'answer.first')
  invoke(:movement)
end

#transpose_chars(event = nil) ⇒ Object



283
284
285
286
287
288
289
290
291
# File 'lib/ver/minibuffer.rb', line 283

def transpose_chars(event = nil)
  return if tag_ranges('answer').empty?
  insert = index('insert')
  line = get('insert', 'answer.last')
  line[0, 2] = line[0, 2].reverse
  replace('insert', 'answer.last', line, 'answer')
  mark_set('insert', insert)
  invoke(:modified)
end

#warn(object) ⇒ Object



119
120
121
122
123
124
125
126
127
128
# File 'lib/ver/minibuffer.rb', line 119

def warn(object)
  case object
  when Exception
    message("#{object.class}: #{object}", 'warn')
  when Symbol, String
    message(object.to_s, 'warn')
  else
    message(object.to_str, 'warn')
  end
end