Module: Reline

Extended by:
Reline
Included in:
Reline
Defined in:
lib/reline.rb,
lib/reline/version.rb

Defined Under Namespace

Modules: KeyActor Classes: ANSI, Config, CursorPos, GeneralIO, History, Key, KeyStroke, KillRing, LineEditor, Unicode, Windows

Constant Summary collapse

FILENAME_COMPLETION_PROC =
nil
USERNAME_COMPLETION_PROC =
nil
IS_WINDOWS =
false
HISTORY =
History.new(@@config)
IOGate =
Reline::ANSI
VERSION =
'0.0.1'
@@config =
Reline::Config.new
@@key_stroke =
Reline::KeyStroke.new(@@config)
@@line_editor =
Reline::LineEditor.new(@@config)
@@ambiguous_width =
nil
@@completion_append_character =
nil
@@basic_word_break_characters =
" \t\n`><=;|&{("
@@completer_word_break_characters =
@@basic_word_break_characters.dup
@@basic_quote_characters =
'"\''
@@completer_quote_characters =
'"\''
@@filename_quote_characters =
''
@@special_prefixes =
''
@@completion_case_fold =
nil
@@completion_proc =
nil
@@output_modifier_proc =
nil
@@prompt_proc =
nil
@@auto_indent_proc =
nil
@@pre_input_hook =
nil
@@dig_perfect_match_proc =
nil
@@output =
STDOUT

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ambiguous_widthObject



403
404
405
# File 'lib/reline.rb', line 403

def self.ambiguous_width
  @@ambiguous_width
end

.auto_indent_procObject



132
133
134
# File 'lib/reline.rb', line 132

def self.auto_indent_proc
  @@auto_indent_proc
end

.auto_indent_proc=(p) ⇒ Object

Raises:

  • (ArgumentError)


135
136
137
138
# File 'lib/reline.rb', line 135

def self.auto_indent_proc=(p)
  raise ArgumentError unless p.is_a?(Proc)
  @@auto_indent_proc = p
end

.basic_quote_charactersObject



65
66
67
# File 'lib/reline.rb', line 65

def self.basic_quote_characters
  @@basic_quote_characters
end

.basic_quote_characters=(v) ⇒ Object



68
69
70
# File 'lib/reline.rb', line 68

def self.basic_quote_characters=(v)
  @@basic_quote_characters = v.encode(Encoding::default_external)
end

.basic_word_break_charactersObject



49
50
51
# File 'lib/reline.rb', line 49

def self.basic_word_break_characters
  @@basic_word_break_characters
end

.basic_word_break_characters=(v) ⇒ Object



52
53
54
# File 'lib/reline.rb', line 52

def self.basic_word_break_characters=(v)
  @@basic_word_break_characters = v.encode(Encoding::default_external)
end

.completer_quote_charactersObject



73
74
75
# File 'lib/reline.rb', line 73

def self.completer_quote_characters
  @@completer_quote_characters
end

.completer_quote_characters=(v) ⇒ Object



76
77
78
# File 'lib/reline.rb', line 76

def self.completer_quote_characters=(v)
  @@completer_quote_characters = v.encode(Encoding::default_external)
end

.completer_word_break_charactersObject



57
58
59
# File 'lib/reline.rb', line 57

def self.completer_word_break_characters
  @@completer_word_break_characters
end

.completer_word_break_characters=(v) ⇒ Object



60
61
62
# File 'lib/reline.rb', line 60

def self.completer_word_break_characters=(v)
  @@completer_word_break_characters = v.encode(Encoding::default_external)
end

.completion_append_characterObject



33
34
35
# File 'lib/reline.rb', line 33

def self.completion_append_character
  @@completion_append_character
end

.completion_append_character=(val) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/reline.rb', line 36

def self.completion_append_character=(val)
  if val.nil?
    @@completion_append_character = nil
  elsif val.size == 1
    @@completion_append_character = val.encode(Encoding::default_external)
  elsif val.size > 1
    @@completion_append_character = val[0].encode(Encoding::default_external)
  else
    @@completion_append_character = nil
  end
end

.completion_case_foldObject



97
98
99
# File 'lib/reline.rb', line 97

def self.completion_case_fold
  @@completion_case_fold
end

.completion_case_fold=(v) ⇒ Object



100
101
102
# File 'lib/reline.rb', line 100

def self.completion_case_fold=(v)
  @@completion_case_fold = v
end

.completion_procObject



105
106
107
# File 'lib/reline.rb', line 105

def self.completion_proc
  @@completion_proc
end

.completion_proc=(p) ⇒ Object

Raises:

  • (ArgumentError)


108
109
110
111
# File 'lib/reline.rb', line 108

def self.completion_proc=(p)
  raise ArgumentError unless p.is_a?(Proc)
  @@completion_proc = p
end

.delete_text(start = nil, length = nil) ⇒ Object



178
179
180
# File 'lib/reline.rb', line 178

def self.delete_text(start = nil, length = nil)
  @@line_editor&.delete_text(start, length)
end

.dig_perfect_match_procObject



149
150
151
# File 'lib/reline.rb', line 149

def self.dig_perfect_match_proc
  @@dig_perfect_match_proc
end

.dig_perfect_match_proc=(p) ⇒ Object

Raises:

  • (ArgumentError)


152
153
154
155
# File 'lib/reline.rb', line 152

def self.dig_perfect_match_proc=(p)
  raise ArgumentError unless p.is_a?(Proc)
  @@dig_perfect_match_proc = p
end

.emacs_editing_modeObject



214
215
216
217
# File 'lib/reline.rb', line 214

def self.emacs_editing_mode
  @@config.editing_mode = :emacs
  nil
end

.emacs_editing_mode?Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/reline.rb', line 223

def self.emacs_editing_mode?
  @@config.editing_mode_is?(:emacs)
end

.filename_quote_charactersObject



81
82
83
# File 'lib/reline.rb', line 81

def self.filename_quote_characters
  @@filename_quote_characters
end

.filename_quote_characters=(v) ⇒ Object



84
85
86
# File 'lib/reline.rb', line 84

def self.filename_quote_characters=(v)
  @@filename_quote_characters = v.encode(Encoding::default_external)
end

.get_screen_sizeObject



227
228
229
# File 'lib/reline.rb', line 227

def self.get_screen_size
  Reline::IOGate.get_screen_size
end

.input=(val) ⇒ Object

Raises:

  • (TypeError)


189
190
191
192
193
194
195
196
197
198
# File 'lib/reline.rb', line 189

def self.input=(val)
  raise TypeError unless val.respond_to?(:getc) or val.nil?
  if val.respond_to?(:getc)
    if defined?(Reline::ANSI) and IOGate == Reline::ANSI
      Reline::ANSI.input = val
    elsif IOGate == Reline::GeneralIO
      Reline::GeneralIO.input = val
    end
  end
end

.insert_text(text) ⇒ Object



157
158
159
160
# File 'lib/reline.rb', line 157

def self.insert_text(text)
  @@line_editor&.insert_text(text)
  self
end

.line_bufferObject



166
167
168
# File 'lib/reline.rb', line 166

def self.line_buffer
  @@line_editor&.line
end

.output=(val) ⇒ Object

Raises:

  • (TypeError)


201
202
203
204
205
206
207
# File 'lib/reline.rb', line 201

def self.output=(val)
  raise TypeError unless val.respond_to?(:write) or val.nil?
  @@output = val
  if defined?(Reline::ANSI) and IOGate == Reline::ANSI
    Reline::ANSI.output = val
  end
end

.output_modifier_procObject



114
115
116
# File 'lib/reline.rb', line 114

def self.output_modifier_proc
  @@output_modifier_proc
end

.output_modifier_proc=(p) ⇒ Object

Raises:

  • (ArgumentError)


117
118
119
120
# File 'lib/reline.rb', line 117

def self.output_modifier_proc=(p)
  raise ArgumentError unless p.is_a?(Proc)
  @@output_modifier_proc = p
end

.pointObject



170
171
172
# File 'lib/reline.rb', line 170

def self.point
  @@line_editor ? @@line_editor.byte_pointer : 0
end

.point=(val) ⇒ Object



174
175
176
# File 'lib/reline.rb', line 174

def self.point=(val)
  @@line_editor.byte_pointer = val
end

.pre_input_hookObject



141
142
143
# File 'lib/reline.rb', line 141

def self.pre_input_hook
  @@pre_input_hook
end

.pre_input_hook=(p) ⇒ Object



144
145
146
# File 'lib/reline.rb', line 144

def self.pre_input_hook=(p)
  @@pre_input_hook = p
end

.prompt_procObject



123
124
125
# File 'lib/reline.rb', line 123

def self.prompt_proc
  @@prompt_proc
end

.prompt_proc=(p) ⇒ Object

Raises:

  • (ArgumentError)


126
127
128
129
# File 'lib/reline.rb', line 126

def self.prompt_proc=(p)
  raise ArgumentError unless p.is_a?(Proc)
  @@prompt_proc = p
end

.redisplayObject



162
163
164
# File 'lib/reline.rb', line 162

def self.redisplay
  @@line_editor&.rerender
end

.special_prefixesObject



89
90
91
# File 'lib/reline.rb', line 89

def self.special_prefixes
  @@special_prefixes
end

.special_prefixes=(v) ⇒ Object



92
93
94
# File 'lib/reline.rb', line 92

def self.special_prefixes=(v)
  @@special_prefixes = v.encode(Encoding::default_external)
end

.vi_editing_modeObject



209
210
211
212
# File 'lib/reline.rb', line 209

def self.vi_editing_mode
  @@config.editing_mode = :vi_insert
  nil
end

.vi_editing_mode?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'lib/reline.rb', line 219

def self.vi_editing_mode?
  @@config.editing_mode_is?(:vi_insert, :vi_command)
end

Instance Method Details

#eof?Boolean

Returns:

  • (Boolean)


231
232
233
# File 'lib/reline.rb', line 231

def eof?
  @@line_editor.eof?
end

#inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination) ⇒ Object



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/reline.rb', line 264

def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
  if ENV['RELINE_STDERR_TTY']
    $stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
    $stderr.sync = true
    $stderr.puts "Reline is used by #{Process.pid}"
  end
  otio = Reline::IOGate.prep

  may_req_ambiguous_char_width
  @@line_editor.reset(prompt)
  if multiline
    @@line_editor.multiline_on
    if block_given?
      @@line_editor.confirm_multiline_termination_proc = confirm_multiline_termination
    end
  else
    @@line_editor.multiline_off
  end
  @@line_editor.output = @@output
  @@line_editor.completion_proc = @@completion_proc
  @@line_editor.output_modifier_proc = @@output_modifier_proc
  @@line_editor.prompt_proc = @@prompt_proc
  @@line_editor.auto_indent_proc = @@auto_indent_proc
  @@line_editor.dig_perfect_match_proc = @@dig_perfect_match_proc
  @@line_editor.pre_input_hook = @@pre_input_hook
  @@line_editor.rerender

  unless @@config.test_mode
    @@config.read
    @@config.reset_default_key_bindings
    Reline::IOGate::RAW_KEYSTROKE_CONFIG.each_pair do |key, func|
      @@config.add_default_key_binding(key, func)
    end
  end

  begin
    loop do
      read_io(@@config.keyseq_timeout) { |inputs|
        inputs.each { |c|
          @@line_editor.input_key(c)
          @@line_editor.rerender
        }
      }
      break if @@line_editor.finished?
    end
    Reline::IOGate.move_cursor_column(0)
  rescue StandardError => e
    @@line_editor.finalize
    Reline::IOGate.deprep(otio)
    raise e
  end

  @@line_editor.finalize
  Reline::IOGate.deprep(otio)
end

#may_req_ambiguous_char_widthObject



393
394
395
396
397
398
399
400
401
# File 'lib/reline.rb', line 393

def may_req_ambiguous_char_width
  @@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
  return if @@ambiguous_width
  Reline::IOGate.move_cursor_column(0)
  print "\u{25bd}"
  @@ambiguous_width = Reline::IOGate.cursor_pos.x
  Reline::IOGate.move_cursor_column(0)
  Reline::IOGate.erase_after_cursor
end

#read_escaped_key(keyseq_timeout, buffer, block) ⇒ Object



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/reline.rb', line 372

def read_escaped_key(keyseq_timeout, buffer, block)
  begin
    escaped_c = nil
    Timeout.timeout(keyseq_timeout / 1000.0) {
      escaped_c = Reline::IOGate.getc
    }
  rescue Timeout::Error # independent ESC
    block.([Reline::Key.new(c, c, false)])
  else
    if escaped_c.nil?
      block.([Reline::Key.new(c, c, false)])
    elsif escaped_c >= 128 # maybe, first byte of multi byte
      block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
    elsif escaped_c == "\e".ord # escape twice
      block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
    else
      block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
    end
  end
end

#read_io(keyseq_timeout, &block) ⇒ Object

Keystrokes of GNU Readline will timeout it with the specification of “keyseq-timeout” when waiting for the 2nd character after the 1st one. If the 2nd character comes after 1st ESC without timeout it has a meta-property of meta-key to discriminate modified key with meta-key from multibyte characters that come with 8th bit on.

GNU Readline will wait for the 2nd character with “keyseq-timeout” milli-seconds but wait forever after 3rd characters.



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/reline.rb', line 328

def read_io(keyseq_timeout, &block)
  buffer = []
  loop do
    c = Reline::IOGate.getc
    buffer << c
    result = @@key_stroke.match_status(buffer)
    case result
    when :matched
      block.(@@key_stroke.expand(buffer).map{ |c| Reline::Key.new(c, c, false) })
      break
    when :matching
      if buffer.size == 1
        begin
          succ_c = nil
          Timeout.timeout(keyseq_timeout / 1000.0) {
            succ_c = Reline::IOGate.getc
          }
        rescue Timeout::Error # cancel matching only when first byte
          block.([Reline::Key.new(c, c, false)])
          break
        else
          if @@key_stroke.match_status(buffer.dup.push(succ_c)) == :unmatched
            if c == "\e".ord
              block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
            else
              block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
            end
            break
          else
            Reline::IOGate.ungetc(succ_c)
          end
        end
      end
    when :unmatched
      if buffer.size == 1 and c == "\e".ord
        read_escaped_key(keyseq_timeout, buffer, block)
      else
        block.(buffer.map{ |c| Reline::Key.new(c, c, false) })
      end
      break
    end
  end
end

#readline(prompt = '', add_hist = false) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/reline.rb', line 251

def readline(prompt = '', add_hist = false)
  inner_readline(prompt, add_hist, false)

  line = @@line_editor.line.dup
  line.taint
  if add_hist and line and line.chomp.size > 0
    Reline::HISTORY << line.chomp
  end

  @@line_editor.reset_line if @@line_editor.line.nil?
  line
end

#readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/reline.rb', line 235

def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
  unless confirm_multiline_termination
    raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
  end
  inner_readline(prompt, add_hist, true, &confirm_multiline_termination)

  whole_buffer = @@line_editor.whole_buffer.dup
  whole_buffer.taint
  if add_hist and whole_buffer and whole_buffer.chomp.size > 0
    Reline::HISTORY << whole_buffer
  end

  @@line_editor.reset_line if @@line_editor.whole_buffer.nil?
  whole_buffer
end