mini_readline 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +68 -20
- data/bin/sire +218 -0
- data/lib/mini_readline/version.rb +1 -1
- metadata +4 -3
- data/sire.rb +0 -145
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63c0d0b393fbbae9881b657135bd97f34befd2ed
|
4
|
+
data.tar.gz: cba975451eecdd8e3a960bf176326dd64fa0a092
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b363e4ff27560dd63ffdcc77311f9c0ad564fa89f030bf0d393304f8bf5fb05d8e3d796fffbfcf1e71879e86c0090df4fbd6234d8aa31c5ea3dc26a3811b4ab
|
7
|
+
data.tar.gz: eefdd7034858baef7e5306947e31a627adc96925a6e1ba40d7bfa72d80a9051aa8277eeb3fe4e5275541edbaa5bb2af3fd1ef2ffade686d324f7fcdb741dc7b5
|
data/README.md
CHANGED
@@ -77,6 +77,8 @@ replaced by Escape followed by the appropriate letter.
|
|
77
77
|
* References to Pad keys under Windows assume that Num Lock is not engaged.
|
78
78
|
* Support for End of Input is controlled by the eoi_detect option. See options
|
79
79
|
below.
|
80
|
+
* These keyboard mappings are the standard ones included with mini_readline.
|
81
|
+
See the section Adding Custom Key Maps below for more info.
|
80
82
|
|
81
83
|
## Usage
|
82
84
|
|
@@ -367,7 +369,55 @@ statement to permit the use of clearer, easier to read access to regular
|
|
367
369
|
expression results.
|
368
370
|
|
369
371
|
<br> An example of a custom auto-complete facility may be found in the mysh
|
370
|
-
gem located at: https://github.com/PeterCamilleri/mysh/blob/master/lib/mysh/
|
372
|
+
gem located at: https://github.com/PeterCamilleri/mysh/blob/master/lib/mysh/sources/smart_auto_complete.rb
|
373
|
+
|
374
|
+
### Adding Custom Key Maps
|
375
|
+
It is possible to override the default keyboard maps used by the mini_readline
|
376
|
+
gem. The following shows the installation of a retro, WordStar(TM) inspired
|
377
|
+
keyboard mapping for a Windows system:
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
MiniTerm.add_map(:windows) do |map|
|
381
|
+
map[" ".."~"] = :insert_text
|
382
|
+
|
383
|
+
#Left Arrows
|
384
|
+
map["\x13"] = :go_left
|
385
|
+
map["\x01"] = :word_left
|
386
|
+
|
387
|
+
#Right Arrows
|
388
|
+
map["\x04"] = :go_right
|
389
|
+
map["\x06"] = :word_right
|
390
|
+
|
391
|
+
#Up Arrows
|
392
|
+
map["\x05"] = :previous_history
|
393
|
+
|
394
|
+
#Down Arrows
|
395
|
+
map["\x18"] = :next_history
|
396
|
+
|
397
|
+
#The Home and End keys
|
398
|
+
map["\x17"] = :go_home
|
399
|
+
map["\x12"] = :go_end
|
400
|
+
|
401
|
+
#The Backspace and Delete keys
|
402
|
+
map["\x08"] = :delete_left
|
403
|
+
map["\x7F"] = :delete_right
|
404
|
+
map["\x11\x13"] = :delete_all_left
|
405
|
+
map["\x11\x04"] = :delete_all_right
|
406
|
+
|
407
|
+
#Auto-completion.
|
408
|
+
map["\t"] = :auto_complete
|
409
|
+
|
410
|
+
#The Enter key
|
411
|
+
map["\x0D"] = :enter
|
412
|
+
|
413
|
+
#The Escape key
|
414
|
+
map["\e"] = :cancel
|
415
|
+
|
416
|
+
#End of Input
|
417
|
+
map["\x1A"] = :end_of_input
|
418
|
+
end
|
419
|
+
```
|
420
|
+
|
371
421
|
|
372
422
|
### Important Security Note
|
373
423
|
|
@@ -378,24 +428,25 @@ command line itself. Untrusted users should **never** be given such access!
|
|
378
428
|
|
379
429
|
## Demo
|
380
430
|
A simple demo of mini_readline in action is available. To access this demo use
|
381
|
-
the following
|
431
|
+
the following:
|
382
432
|
|
383
|
-
$
|
433
|
+
$ sire
|
384
434
|
|
385
435
|
This will launch SIRE, a Simple Interactive Ruby Environment, a sort of
|
386
|
-
simple minded irb knock-off.
|
387
|
-
|
388
|
-
if all fails, it will load the "classic" Readline gem. Here is a typical run:
|
436
|
+
simple minded irb knock-off. The utility supports a number of options that
|
437
|
+
allow the behaviour of the gem to be explored. These are:
|
389
438
|
|
390
|
-
|
439
|
+
Option | Effect
|
440
|
+
-------|-------
|
441
|
+
local | Use the mini_readline in the lib folder. For testing.
|
442
|
+
gem | Use the mini_readline installed as a gem. The default.
|
443
|
+
old | Use the old readline facility.
|
444
|
+
map1 | Install a Wordstar keyboard map.
|
445
|
+
help | Display usage info and exit.
|
446
|
+
-? | Same thing.
|
391
447
|
|
448
|
+
#### Testing Shell Out Bugs
|
392
449
|
|
393
|
-
Loaded mini_readline from the local code folder.
|
394
|
-
|
395
|
-
Welcome to a Simple Interactive Ruby Environment
|
396
|
-
Use the command 'quit' to exit.
|
397
|
-
|
398
|
-
SIRE>
|
399
450
|
Of note, the run method can be used to test for the shell process bug. For
|
400
451
|
example:
|
401
452
|
|
@@ -412,15 +463,12 @@ example:
|
|
412
463
|
"sire.rb",
|
413
464
|
"tests"]
|
414
465
|
SIRE>
|
466
|
+
|
415
467
|
After this command is run, the program should continue to operate correctly
|
416
|
-
and not go bannanas. To test the behavior of the
|
417
|
-
|
418
|
-
$ ruby sire.rb old
|
419
|
-
|
420
|
-
To test the local copy of mini_readline in the lib folder instead of the
|
421
|
-
system gem, use this:
|
468
|
+
and not go bannanas. To test the behavior of the (currently broken) standard
|
469
|
+
readline library, use:
|
422
470
|
|
423
|
-
$
|
471
|
+
$ sire.rb old
|
424
472
|
|
425
473
|
## Cross Platform Portability Progress
|
426
474
|
|
data/bin/sire
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# A Simple Interactive Ruby Environment
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
# Capture a binding for code evaluation.
|
9
|
+
sire_binding = binding
|
10
|
+
|
11
|
+
# Process command line arguments.
|
12
|
+
valid_options = {'local' => :reader,
|
13
|
+
'gem' => :reader,
|
14
|
+
'old' => :reader,
|
15
|
+
'map1' => :map,
|
16
|
+
'help' => :help,
|
17
|
+
'?' => :help}
|
18
|
+
|
19
|
+
options = {reader: 'gem'}
|
20
|
+
|
21
|
+
# Display help for SIRE and exit.
|
22
|
+
def display_help(error=nil)
|
23
|
+
puts "SIRE: a Simple Interactive Ruby Environment\n"
|
24
|
+
|
25
|
+
if error
|
26
|
+
puts "Invalid option: #{error}"
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "", "Usage: sire <options>"
|
30
|
+
puts " local Use the local mini_readline code."
|
31
|
+
puts " gem Use the mini_readline installed gem."
|
32
|
+
puts " old Use the standard readline gem."
|
33
|
+
puts " map1 Use the alternate key mapping in Windows."
|
34
|
+
puts " help -? Display this help and exit."
|
35
|
+
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
|
39
|
+
ARGV.each do |arg|
|
40
|
+
key = valid_options[arg]
|
41
|
+
display_help(arg) unless key
|
42
|
+
options[key] = arg
|
43
|
+
end
|
44
|
+
|
45
|
+
display_help if options[:help]
|
46
|
+
|
47
|
+
case options[:reader]
|
48
|
+
when 'local'
|
49
|
+
require_relative '../lib/mini_readline'
|
50
|
+
puts "", "Option(local). Loaded mini_readline from the local code folder. Version #{MiniReadline::VERSION}"
|
51
|
+
when 'gem'
|
52
|
+
require 'mini_readline'
|
53
|
+
puts "", "Loaded mini_readline from the system gem. Version #{MiniReadline::VERSION}"
|
54
|
+
when 'old'
|
55
|
+
require 'readline'
|
56
|
+
class MiniReadlineEOI < StandardError; end #Compatibility stub.
|
57
|
+
puts "", "Loaded the standard readline gem. Version #{Readline::VERSION}"
|
58
|
+
end
|
59
|
+
|
60
|
+
MiniReadline = Readline unless defined?(MiniReadline)
|
61
|
+
|
62
|
+
class Object
|
63
|
+
# Generate the class lineage of the object.
|
64
|
+
def classes
|
65
|
+
begin
|
66
|
+
result = ""
|
67
|
+
klass = self.instance_of?(Class) ? self : self.class
|
68
|
+
|
69
|
+
begin
|
70
|
+
result << klass.to_s
|
71
|
+
klass = klass.superclass
|
72
|
+
result << " < " if klass
|
73
|
+
end while klass
|
74
|
+
|
75
|
+
result
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# Quit the interactive session.
|
82
|
+
def quit
|
83
|
+
puts "Quit command.", ""
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get a mapped keystroke.
|
88
|
+
def get_mapped
|
89
|
+
if old?
|
90
|
+
puts 'Not supported by old readline.'
|
91
|
+
else
|
92
|
+
print 'Press a key: '
|
93
|
+
MiniTerm.get_mapped_char
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Test spawning a process. This breaks the regular readline gem.
|
98
|
+
def run(command)
|
99
|
+
IO.popen(command, "r+") do |io|
|
100
|
+
io.close_write
|
101
|
+
return io.read
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def old?
|
106
|
+
defined?(Readline)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
if options[:map] == 'map1'
|
112
|
+
if old?
|
113
|
+
puts 'An option is not supported by old readline.'
|
114
|
+
exit
|
115
|
+
end
|
116
|
+
|
117
|
+
[:windows, :ansi].each do |target|
|
118
|
+
MiniTerm.add_map(target) do |map|
|
119
|
+
map[" ".."~"] = :insert_text
|
120
|
+
|
121
|
+
#Left Arrows
|
122
|
+
map["\x13"] = :go_left
|
123
|
+
map["\x01"] = :word_left
|
124
|
+
|
125
|
+
#Right Arrows
|
126
|
+
map["\x04"] = :go_right
|
127
|
+
map["\x06"] = :word_right
|
128
|
+
|
129
|
+
#Up Arrows
|
130
|
+
map["\x05"] = :previous_history
|
131
|
+
|
132
|
+
#Down Arrows
|
133
|
+
map["\x18"] = :next_history
|
134
|
+
|
135
|
+
#The Home and End keys
|
136
|
+
map["\x17"] = :go_home
|
137
|
+
map["\x12"] = :go_end
|
138
|
+
|
139
|
+
#The Backspace and Delete keys
|
140
|
+
map["\x08"] = :delete_left
|
141
|
+
map["\x7F"] = :delete_right
|
142
|
+
map["\x11\x13"] = :delete_all_left
|
143
|
+
map["\x11\x04"] = :delete_all_right
|
144
|
+
|
145
|
+
#Auto-completion.
|
146
|
+
map["\t"] = :auto_complete
|
147
|
+
|
148
|
+
#The Enter key
|
149
|
+
map["\x0D"] = :enter
|
150
|
+
|
151
|
+
#The Escape key
|
152
|
+
map["\e"] = :cancel
|
153
|
+
|
154
|
+
#End of Input
|
155
|
+
map["\x1A"] = :end_of_input
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
#The SIRE module contains a simplistic R.E.P.L. to test out mini_readline.
|
161
|
+
module SIRE
|
162
|
+
|
163
|
+
# Run the interactive session.
|
164
|
+
def self.run_sire(evaluator)
|
165
|
+
@evaluator = evaluator
|
166
|
+
|
167
|
+
unless old?
|
168
|
+
MiniReadline::BASE_OPTIONS[:auto_complete] = true
|
169
|
+
MiniReadline::BASE_OPTIONS[:eoi_detect] = true
|
170
|
+
end
|
171
|
+
|
172
|
+
puts
|
173
|
+
puts "Welcome to a Simple Interactive Ruby Environment\n"
|
174
|
+
puts "Use the command 'quit' to exit.\n\n"
|
175
|
+
|
176
|
+
loop do
|
177
|
+
exec_line(get_line)
|
178
|
+
end
|
179
|
+
|
180
|
+
puts "\n\n"
|
181
|
+
|
182
|
+
rescue MiniReadlineEOI, Interrupt => e
|
183
|
+
puts "\n"
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
# Get a line of input from the user.
|
189
|
+
def self.get_line
|
190
|
+
initial_input = MiniReadline.readline("SIRE>", true)
|
191
|
+
get_extra_input(initial_input)
|
192
|
+
end
|
193
|
+
|
194
|
+
# Get any continuations of the inputs
|
195
|
+
def self.get_extra_input(str)
|
196
|
+
if /\\\s*$/ =~ str
|
197
|
+
get_extra_input($PREMATCH + "\n" + MiniReadline.readline("SIRE\\", true))
|
198
|
+
else
|
199
|
+
str
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# Execute a single line.
|
204
|
+
def self.exec_line(line)
|
205
|
+
result = @evaluator.eval(line)
|
206
|
+
pp result unless line.length == 0
|
207
|
+
|
208
|
+
rescue Interrupt => e
|
209
|
+
puts "", "Execution Interrupted!"
|
210
|
+
puts "", "#{e.class} detected: #{e}", ""
|
211
|
+
|
212
|
+
rescue StandardError, ScriptError => e
|
213
|
+
puts "", "#{e.class} detected: #{e}", ""
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
SIRE.run_sire(sire_binding)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Version info for the gem.
|
4
4
|
module MiniReadline
|
5
5
|
#The current version of the mini_readline gem.
|
6
|
-
VERSION = "0.9.
|
6
|
+
VERSION = "0.9.2".freeze
|
7
7
|
|
8
8
|
# A brief description.
|
9
9
|
DESCRIPTION = "mini_readline: Get console input with edit, history, and auto-complete.".freeze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_readline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mini_term
|
@@ -102,6 +102,7 @@ email:
|
|
102
102
|
- peter.c.camilleri@gmail.com
|
103
103
|
executables:
|
104
104
|
- irbm
|
105
|
+
- sire
|
105
106
|
extensions: []
|
106
107
|
extra_rdoc_files: []
|
107
108
|
files:
|
@@ -112,6 +113,7 @@ files:
|
|
112
113
|
- LICENSE.txt
|
113
114
|
- README.md
|
114
115
|
- bin/irbm
|
116
|
+
- bin/sire
|
115
117
|
- irbt.rb
|
116
118
|
- lib/mini_readline.rb
|
117
119
|
- lib/mini_readline/exceptions.rb
|
@@ -152,7 +154,6 @@ files:
|
|
152
154
|
- mini_readline.gemspec
|
153
155
|
- rakefile.rb
|
154
156
|
- reek.txt
|
155
|
-
- sire.rb
|
156
157
|
- tests/history_tests.rb
|
157
158
|
- tests/mini_readline_tests.rb
|
158
159
|
homepage: https://github.com/PeterCamilleri/mini_readline
|
data/sire.rb
DELETED
@@ -1,145 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# A Simple Interactive Ruby Environment
|
3
|
-
|
4
|
-
require 'pp'
|
5
|
-
|
6
|
-
#Some SIRE control variables.
|
7
|
-
$sire_done = false
|
8
|
-
$sire_binding = binding
|
9
|
-
$sire_old = (ARGV[0] == 'old') || defined?(Readline)
|
10
|
-
|
11
|
-
if $sire_old
|
12
|
-
require 'readline'
|
13
|
-
class MiniReadlineEOI < StandardError; end #Compatibility stub.
|
14
|
-
puts "\nLoaded the standard readline gem. Version #{Readline::VERSION}"
|
15
|
-
elsif ARGV[0] == 'local'
|
16
|
-
require './lib/mini_readline'
|
17
|
-
puts "\nOption(local). Loaded mini_readline from the local code folder. Version #{MiniReadline::VERSION}"
|
18
|
-
elsif defined?(MiniReadline)
|
19
|
-
puts "\nThe mini_readline gem is already loaded. Version #{MiniReadline::VERSION}"
|
20
|
-
else
|
21
|
-
begin
|
22
|
-
require 'mini_readline'
|
23
|
-
puts "\nLoaded mini_readline from the system gem. Version #{MiniReadline::VERSION}"
|
24
|
-
rescue LoadError
|
25
|
-
begin
|
26
|
-
require './lib/mini_readline'
|
27
|
-
puts "\nLoaded mini_readline from the local code folder. Version #{MiniReadline::VERSION}"
|
28
|
-
rescue LoadError
|
29
|
-
require 'readline'
|
30
|
-
puts "\nLoaded the standard readline gem. Version #{Readline::VERSION}"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
Readline = MiniReadline unless defined?(Readline)
|
36
|
-
|
37
|
-
class Object
|
38
|
-
#Generate the class lineage of the object.
|
39
|
-
def classes
|
40
|
-
begin
|
41
|
-
result = ""
|
42
|
-
klass = self.instance_of?(Class) ? self : self.class
|
43
|
-
|
44
|
-
begin
|
45
|
-
result << klass.to_s
|
46
|
-
klass = klass.superclass
|
47
|
-
result << " < " if klass
|
48
|
-
end while klass
|
49
|
-
|
50
|
-
result
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
#Quit the interactive session.
|
57
|
-
def quit
|
58
|
-
$sire_done = true
|
59
|
-
puts
|
60
|
-
"Quit command."
|
61
|
-
end
|
62
|
-
|
63
|
-
#Get a mapped keystroke.
|
64
|
-
def get_mapped
|
65
|
-
if $sire_old
|
66
|
-
puts 'Not supported by old readline.'
|
67
|
-
else
|
68
|
-
print 'Press a key:'
|
69
|
-
MiniTerm.get_mapped_char
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
#Test spawning a process. This breaks the regular readline gem.
|
74
|
-
def run(command)
|
75
|
-
IO.popen(command, "r+") do |io|
|
76
|
-
io.close_write
|
77
|
-
return io.read
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
#The SIRE class contains the simplistic R.E.P.L.
|
84
|
-
class SIRE
|
85
|
-
|
86
|
-
#Run the interactive session.
|
87
|
-
def run_sire
|
88
|
-
unless $sire_old
|
89
|
-
MiniReadline::BASE_OPTIONS[:auto_complete] = true
|
90
|
-
MiniReadline::BASE_OPTIONS[:eoi_detect] = true
|
91
|
-
end
|
92
|
-
|
93
|
-
puts
|
94
|
-
puts "Welcome to a Simple Interactive Ruby Environment\n"
|
95
|
-
puts "Use the command 'quit' to exit.\n\n"
|
96
|
-
|
97
|
-
until $sire_done
|
98
|
-
exec_line(get_line)
|
99
|
-
end
|
100
|
-
|
101
|
-
puts "\n\n"
|
102
|
-
|
103
|
-
rescue MiniReadlineEOI, Interrupt => e
|
104
|
-
puts "\n"
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
#Get a line of input from the user.
|
110
|
-
def get_line
|
111
|
-
initial_input = Readline.readline("SIRE>", true)
|
112
|
-
get_extra_input(initial_input)
|
113
|
-
end
|
114
|
-
|
115
|
-
#Get any continuations of the inputs
|
116
|
-
def get_extra_input(str)
|
117
|
-
if /\\\s*$/ =~ str
|
118
|
-
get_extra_input($PREMATCH + "\n" + Readline.readline("SIRE\\", true))
|
119
|
-
else
|
120
|
-
str
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
#Execute a single line.
|
125
|
-
def exec_line(line)
|
126
|
-
result = $sire_binding.eval(line)
|
127
|
-
pp result unless line.length == 0
|
128
|
-
|
129
|
-
rescue Interrupt => e
|
130
|
-
puts "\nExecution Interrupted!"
|
131
|
-
puts "\n#{e.class} detected: #{e}\n"
|
132
|
-
puts e.backtrace
|
133
|
-
puts "\n"
|
134
|
-
|
135
|
-
rescue Exception => e
|
136
|
-
puts "\n#{e.class} detected: #{e}\n"
|
137
|
-
puts e.backtrace
|
138
|
-
puts
|
139
|
-
end
|
140
|
-
|
141
|
-
end
|
142
|
-
|
143
|
-
if __FILE__ == $0
|
144
|
-
SIRE.new.run_sire
|
145
|
-
end
|