rdp-rb-readline 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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