rdp-rb-readline 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/readline.rb ADDED
@@ -0,0 +1,502 @@
1
+ # readline.rb -- GNU Readline module
2
+ # Copyright (C) 1997-2001 Shugo Maed
3
+ #
4
+ # Ruby translation by Park Heesob phasis@gmail.com
5
+
6
+ module Readline
7
+
8
+ require 'rbreadline'
9
+ include RbReadline
10
+
11
+ @completion_proc = nil
12
+ @completion_case_fold = false
13
+
14
+ # Begins an interactive terminal process using +prompt+ as the command
15
+ # prompt that users see when they type commands. The method returns the
16
+ # line entered whenever a carriage return is encountered.
17
+ #
18
+ # If an +add_history+ argument is provided, commands entered by users are
19
+ # stored in a history buffer that can be recalled for later use.
20
+ #
21
+ # Note that this method depends on $stdin and $stdout both being open.
22
+ # Because this is meant as an interactive console interface, they should
23
+ # generally not be redirected.
24
+ #
25
+ # Example:
26
+ #
27
+ # loop{ Readline.readline('> ') }
28
+ #
29
+ def readline(prompt, add_history=nil)
30
+ if $stdin.closed?
31
+ raise IOError, "stdin closed"
32
+ end
33
+
34
+ RbReadline.rl_instream = $stdin
35
+ RbReadline.rl_outstream = $stdout
36
+
37
+ status = 0
38
+
39
+ begin
40
+ buff = RbReadline.readline(prompt)
41
+ rescue Exception => e
42
+ buff = nil
43
+ RbReadline.rl_cleanup_after_signal()
44
+ RbReadline.rl_deprep_terminal()
45
+ raise e
46
+ end
47
+
48
+ if add_history && buff
49
+ RbReadline.add_history(buff)
50
+ end
51
+
52
+ return buff ? buff.dup : nil
53
+ end
54
+
55
+ # Sets the input stream (an IO object) for readline interaction. The
56
+ # default is <tt>$stdin</tt>.
57
+ #
58
+ def self.input=(input)
59
+ RbReadline.rl_instream = input
60
+ end
61
+
62
+ # Sets the output stream (an IO object) for readline interaction. The
63
+ # default is <tt>$stdout</tt>.
64
+ #
65
+ def self.output=(output)
66
+ RbReadline.rl_outstream = output
67
+ end
68
+
69
+ # Sets the auto-completion procedure (i.e. tab auto-complete).
70
+ #
71
+ # The +proc+ argument is typically a Proc object. It must respond to
72
+ # <tt>.call</tt>, take a single String argument and return an Array of
73
+ # candidates for completion.
74
+ #
75
+ # Example:
76
+ #
77
+ # list = ['search', 'next', 'clear']
78
+ # Readline.completion_proc = proc{ |s| list.grep( /^#{Regexp.escape(s)}/) }
79
+ #
80
+ def self.completion_proc=(proc)
81
+ unless defined? proc.call
82
+ raise ArgumentError,"argument must respond to `call'"
83
+ end
84
+ @completion_proc = proc
85
+ end
86
+
87
+ # Returns the current auto-completion procedure.
88
+ #
89
+ def self.completion_proc()
90
+ @completion_proc
91
+ end
92
+
93
+ # Sets whether or not the completion proc should ignore case sensitivity.
94
+ # The default is false, i.e. completion procs are case sensitive.
95
+ #
96
+ def self.completion_case_fold=(bool)
97
+ @completion_case_fold = bool
98
+ end
99
+
100
+ # Returns whether or not the completion proc is case sensitive. The
101
+ # default is false, i.e. completion procs are case sensitive.
102
+ #
103
+ def self.completion_case_fold()
104
+ @completion_case_fold
105
+ end
106
+
107
+ def self.readline_attempted_completion_function(text,start,_end)
108
+ proc = @completion_proc
109
+ return nil if proc.nil?
110
+
111
+ RbReadline.rl_attempted_completion_over = true
112
+
113
+ case_fold = @completion_case_fold
114
+ ary = proc.call(text)
115
+ if ary.class != Array
116
+ ary = Array(ary)
117
+ else
118
+ ary.compact!
119
+ end
120
+
121
+ matches = ary.length
122
+ return nil if (matches == 0)
123
+ result = Array.new(matches+2)
124
+ for i in 0 ... matches
125
+ result[i+1] = ary[i].dup
126
+ end
127
+ result[matches+1] = nil
128
+
129
+ if(matches==1)
130
+ result[0] = result[1].dup
131
+ else
132
+ i = 1
133
+ low = 100000
134
+
135
+ while (i < matches)
136
+ if (case_fold)
137
+ si = 0
138
+ while ((c1 = result[i][si,1].downcase) &&
139
+ (c2 = result[i + 1][si,1].downcase))
140
+ break if (c1 != c2)
141
+ si += 1
142
+ end
143
+ else
144
+ si = 0
145
+ while ((c1 = result[i][si,1]) &&
146
+ (c2 = result[i + 1][si,1]))
147
+ break if (c1 != c2)
148
+ si += 1
149
+ end
150
+ end
151
+ if (low > si)
152
+ low = si
153
+ end
154
+ i+=1
155
+ end
156
+ result[0] = result[1][0,low]
157
+ end
158
+
159
+ result
160
+ end
161
+
162
+ # Sets vi editing mode.
163
+ #
164
+ def self.vi_editing_mode()
165
+ RbReadline.rl_vi_editing_mode(1,0)
166
+ nil
167
+ end
168
+
169
+ # Sets emacs editing mode
170
+ #
171
+ def self.emacs_editing_mode()
172
+ RbReadline.rl_emacs_editing_mode(1,0)
173
+ nil
174
+ end
175
+
176
+ # Sets the character that is automatically appended after the
177
+ # Readline.completion_proc method is called.
178
+ #
179
+ # If +char+ is nil or empty, then a null character is used.
180
+ #
181
+ def self.completion_append_character=(char)
182
+ if char.nil?
183
+ RbReadline.rl_completion_append_character = ?\0
184
+ elsif char.length==0
185
+ RbReadline.rl_completion_append_character = ?\0
186
+ else
187
+ RbReadline.rl_completion_append_character = char[0]
188
+ end
189
+ end
190
+
191
+ # Returns the character that is automatically appended after the
192
+ # Readline.completion_proc method is called.
193
+ #
194
+ def self.completion_append_character()
195
+ if RbReadline.rl_completion_append_character == ?\0
196
+ nil
197
+ end
198
+ return RbReadline.rl_completion_append_character
199
+ end
200
+
201
+ # Sets the character string that signal a break between words for the
202
+ # completion proc.
203
+ #
204
+ def self.basic_word_break_characters=(str)
205
+ RbReadline.rl_basic_word_break_characters = str.dup
206
+ end
207
+
208
+ # Returns the character string that signal a break between words for the
209
+ # completion proc. The default is " \t\n\"\\'`@$><=|&{(".
210
+ #
211
+ def self.basic_word_break_characters()
212
+ if RbReadline.rl_basic_word_break_characters.nil?
213
+ nil
214
+ else
215
+ RbReadline.rl_basic_word_break_characters.dup
216
+ end
217
+ end
218
+
219
+ # Sets the character string that signal the start or end of a word for
220
+ # the completion proc.
221
+ #
222
+ def self.completer_word_break_characters=(str)
223
+ RbReadline.rl_completer_word_break_characters = str.dup
224
+ end
225
+
226
+ # Returns the character string that signal the start or end of a word for
227
+ # the completion proc.
228
+ #
229
+ def self.completer_word_break_characters()
230
+ if RbReadline.rl_completer_word_break_characters.nil?
231
+ nil
232
+ else
233
+ RbReadline.rl_completer_word_break_characters.dup
234
+ end
235
+ end
236
+
237
+ # Sets the list of quote characters that can cause a word break.
238
+ #
239
+ def self.basic_quote_characters=(str)
240
+ RbReadline.rl_basic_quote_characters = str.dup
241
+ end
242
+
243
+ # Returns the list of quote characters that can cause a word break.
244
+ # The default is "'\"" (single and double quote characters).
245
+ #
246
+ def self.basic_quote_characters()
247
+ if RbReadline.rl_basic_quote_characters.nil?
248
+ nil
249
+ else
250
+ RbReadline.rl_basic_quote_characters.dup
251
+ end
252
+ end
253
+
254
+ # Sets the list of characters that can be used to quote a substring of
255
+ # the line, i.e. a group of characters within quotes.
256
+ #
257
+ def self.completer_quote_characters=(str)
258
+ RbReadline.rl_completer_quote_characters = str.dup
259
+ end
260
+
261
+ # Returns the list of characters that can be used to quote a substring
262
+ # of the line, i.e. a group of characters inside quotes.
263
+ #
264
+ def self.completer_quote_characters()
265
+ if RbReadline.rl_completer_quote_characters.nil?
266
+ nil
267
+ else
268
+ RbReadline.rl_completer_quote_characters.dup
269
+ end
270
+ end
271
+
272
+ # Sets the character string of one or more characters that indicate quotes
273
+ # for the filename completion of user input.
274
+ #
275
+ def self.filename_quote_characters=(str)
276
+ RbReadline.rl_filename_quote_characters = str.dup
277
+ end
278
+
279
+ # Returns the character string used to indicate quotes for the filename
280
+ # completion of user input.
281
+ #
282
+ def self.filename_quote_characters()
283
+ if RbReadline.rl_filename_quote_characters.nil?
284
+ nil
285
+ else
286
+ RbReadline.rl_filename_quote_characters.dup
287
+ end
288
+ end
289
+
290
+ # The History class encapsulates a history of all commands entered by
291
+ # users at the prompt, providing an interface for inspection and retrieval
292
+ # of all commands.
293
+ class History
294
+ extend Enumerable
295
+
296
+ # The History class, stringified in all caps.
297
+ #--
298
+ # Why?
299
+ #
300
+ def self.to_s
301
+ "HISTORY"
302
+ end
303
+
304
+ # Returns the command that was entered at the specified +index+
305
+ # in the history buffer.
306
+ #
307
+ # Raises an IndexError if the entry is nil.
308
+ #
309
+ def self.[](index)
310
+ if index < 0
311
+ index += RbReadline.history_length
312
+ end
313
+ entry = RbReadline.history_get(RbReadline.history_base+index)
314
+ if entry.nil?
315
+ raise IndexError,"invalid index"
316
+ end
317
+ entry.line.dup
318
+ end
319
+
320
+ # Sets the command +str+ at the given index in the history buffer.
321
+ #
322
+ # You can only replace an existing entry. Attempting to create a new
323
+ # entry will result in an IndexError.
324
+ #
325
+ def self.[]=(index,str)
326
+ if index<0
327
+ index += RbReadline.history_length
328
+ end
329
+ entry = RbReadline.replace_history_entry(index,str,nil)
330
+ if entry.nil?
331
+ raise IndexError,"invalid index"
332
+ end
333
+ str
334
+ end
335
+
336
+ # Synonym for Readline.add_history.
337
+ #
338
+ def self.<<(str)
339
+ RbReadline.add_history(str)
340
+ end
341
+
342
+ # Pushes a list of +args+ onto the history buffer.
343
+ #
344
+ def self.push(*args)
345
+ args.each do |str|
346
+ RbReadline.add_history(str)
347
+ end
348
+ end
349
+
350
+ # Internal function that removes the item at +index+ from the history
351
+ # buffer, performing necessary duplication in the process.
352
+ #--
353
+ # TODO: mark private?
354
+ #
355
+ def self.rb_remove_history(index)
356
+ entry = RbReadline.remove_history(index)
357
+ if (entry)
358
+ val = entry.line.dup
359
+ entry = nil
360
+ return val
361
+ end
362
+ nil
363
+ end
364
+
365
+ # Removes and returns the last element from the history buffer.
366
+ #
367
+ def self.pop()
368
+ if RbReadline.history_length>0
369
+ rb_remove_history(RbReadline.history_length-1)
370
+ else
371
+ nil
372
+ end
373
+ end
374
+
375
+ # Removes and returns the first element from the history buffer.
376
+ #
377
+ def self.shift()
378
+ if RbReadline.history_length>0
379
+ rb_remove_history(0)
380
+ else
381
+ nil
382
+ end
383
+ end
384
+
385
+ # Iterates over each entry in the history buffer.
386
+ #
387
+ def self.each()
388
+ for i in 0 ... RbReadline.history_length
389
+ entry = RbReadline.history_get(RbReadline.history_base + i)
390
+ break if entry.nil?
391
+ yield entry.line.dup
392
+ end
393
+ self
394
+ end
395
+
396
+ # Returns the length of the history buffer.
397
+ #
398
+ def self.length()
399
+ RbReadline.history_length
400
+ end
401
+
402
+ # Synonym for Readline.length.
403
+ #
404
+ def self.size()
405
+ RbReadline.history_length
406
+ end
407
+
408
+ # Returns a bolean value indicating whether or not the history buffer
409
+ # is empty.
410
+ #
411
+ def self.empty?()
412
+ RbReadline.history_length == 0
413
+ end
414
+
415
+ # Deletes an entry from the histoyr buffer at the specified +index+.
416
+ #
417
+ def self.delete_at(index)
418
+ if index < 0
419
+ i += RbReadline.history_length
420
+ end
421
+ if index < 0 || index > RbReadline.history_length - 1
422
+ raise IndexError, "invalid index"
423
+ end
424
+ rb_remove_history(index)
425
+ end
426
+
427
+ end
428
+
429
+ HISTORY = History
430
+
431
+ # The Fcomp class provided to encapsulate typical filename completion
432
+ # procedure. You will not typically use this directly, but will instead
433
+ # use the Readline::FILENAME_COMPLETION_PROC.
434
+ #
435
+ class Fcomp
436
+ def self.call(str)
437
+ matches = RbReadline.rl_completion_matches(str,
438
+ :rl_filename_completion_function)
439
+ if (matches)
440
+ result = []
441
+ i = 0
442
+ while(matches[i])
443
+ result << matches[i].dup
444
+ matches[i] = nil
445
+ i += 1
446
+ end
447
+ matches = nil
448
+ if (result.length >= 2)
449
+ result.shift
450
+ end
451
+ else
452
+ result = nil
453
+ end
454
+ return result
455
+ end
456
+ end
457
+
458
+ FILENAME_COMPLETION_PROC = Fcomp
459
+
460
+ # The Ucomp class provided to encapsulate typical filename completion
461
+ # procedure. You will not typically use this directly, but will instead
462
+ # use the Readline::USERNAME_COMPLETION_PROC.
463
+ #
464
+ # Note that this feature currently only works on Unix systems since it
465
+ # ultimately uses the Etc module to iterate over a list of users.
466
+ #
467
+ class Ucomp
468
+ def self.call(str)
469
+ matches = RbReadline.rl_completion_matches(str,
470
+ :rl_username_completion_function)
471
+ if (matches)
472
+ result = []
473
+ i = 0
474
+ while(matches[i])
475
+ result << matches[i].dup
476
+ matches[i] = nil
477
+ i += 1
478
+ end
479
+ matches = nil
480
+ if (result.length >= 2)
481
+ result.shift
482
+ end
483
+ else
484
+ result = nil
485
+ end
486
+ return result
487
+ end
488
+ end
489
+
490
+ USERNAME_COMPLETION_PROC = Ucomp
491
+
492
+ RbReadline.rl_readline_name = "Ruby"
493
+
494
+ RbReadline.using_history()
495
+
496
+ VERSION = RbReadline.rl_library_version
497
+
498
+ module_function :readline
499
+
500
+ RbReadline.rl_attempted_completion_function = :readline_attempted_completion_function
501
+
502
+ end