appl 1.9 → 1.14
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.
- checksums.yaml +4 -4
- data/lib/appl.rb +30 -9
- data/lib/applfan.rb +4 -9
- metadata +7 -10
- data/bin/intar +0 -136
- data/lib/intar.rb +0 -447
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45ad7f9759023d5910cca734d856a368baf06770ad4e193b6dee940e7b417beb
|
4
|
+
data.tar.gz: 55bc842b3ac4fced98fc3c9574bf6a048e838590d26e709b8f4cd3d38cdeab4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7a30d4159280cef5ca6692decc3f561fd2073bcac52f45234936c75f4aa32e20175ba41bc1495aed79383e69cc9ac84410d9b72c89fcdf0d8043e2b12245a7b
|
7
|
+
data.tar.gz: 82e73a96e8e23b880feeeb783d491b52d0d5c2ae29f368ac2d86c26875b5d86fb39a1c6c244c4b38881423ba171d502e034e51e63354727045f37fce529c2256
|
data/lib/appl.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
class Application
|
7
7
|
|
8
|
-
APPL_VERSION = "1.
|
8
|
+
APPL_VERSION = "1.14".freeze
|
9
9
|
|
10
10
|
OPTIONS_ENV = nil
|
11
11
|
|
@@ -13,14 +13,16 @@ class Application
|
|
13
13
|
UNKNOWN = "Unknown option: `%s'."
|
14
14
|
UNPROCA = "Warning: unprocessed arguments: %s"
|
15
15
|
|
16
|
+
ALIASES = [].freeze
|
17
|
+
|
16
18
|
W_OPTS = 10
|
17
19
|
W_ARGS = 16
|
18
20
|
|
19
21
|
class OptionError < StandardError ; end
|
20
22
|
class Done < Exception ; end
|
21
23
|
|
22
|
-
def initialize args = nil
|
23
|
-
@args = args
|
24
|
+
def initialize name = nil, args = nil
|
25
|
+
@name, @args = name, args
|
24
26
|
self.class.each_option { |opt,desc,arg,dfl,act|
|
25
27
|
begin
|
26
28
|
send act, dfl if dfl
|
@@ -92,7 +94,8 @@ class Application
|
|
92
94
|
private
|
93
95
|
|
94
96
|
def execute args = nil
|
95
|
-
|
97
|
+
n = File.basename $0
|
98
|
+
i = new n, args||cmdline_arguments
|
96
99
|
i.execute
|
97
100
|
rescue Done
|
98
101
|
0
|
@@ -214,14 +217,32 @@ class Application
|
|
214
217
|
self
|
215
218
|
end
|
216
219
|
|
217
|
-
def
|
218
|
-
self::NAME
|
220
|
+
def all_names
|
221
|
+
[ self::NAME, *self::ALIASES].join "|"
|
222
|
+
end
|
223
|
+
|
224
|
+
def full_name
|
225
|
+
n = []
|
226
|
+
s = self
|
227
|
+
loop do
|
228
|
+
l = s.all_names
|
229
|
+
n.unshift l
|
230
|
+
break if s == root
|
231
|
+
s = s.root
|
232
|
+
end
|
233
|
+
n.join ' '
|
219
234
|
end
|
220
235
|
|
221
236
|
def help
|
222
|
-
|
237
|
+
fn = full_name
|
238
|
+
puts "#{fn} -- #{self::SUMMARY}"
|
223
239
|
puts
|
224
|
-
|
240
|
+
d = self::DESCRIPTION.gsub /#(\w+?)?#/ do
|
241
|
+
case $1
|
242
|
+
when "NAME" then fn
|
243
|
+
end
|
244
|
+
end
|
245
|
+
puts d
|
225
246
|
puts
|
226
247
|
show_options
|
227
248
|
if block_given? then
|
@@ -231,7 +252,7 @@ class Application
|
|
231
252
|
end
|
232
253
|
|
233
254
|
def version
|
234
|
-
puts "#{
|
255
|
+
puts "#{self::NAME} #{self::VERSION} -- #{self::SUMMARY}"
|
235
256
|
puts self::COPYRIGHT if const_defined? :COPYRIGHT
|
236
257
|
puts "License: #{self::LICENSE}" if const_defined? :LICENSE
|
237
258
|
a = []
|
data/lib/applfan.rb
CHANGED
@@ -5,9 +5,7 @@
|
|
5
5
|
require "appl"
|
6
6
|
|
7
7
|
|
8
|
-
ApplicationFan
|
9
|
-
|
10
|
-
class ApplicationFan
|
8
|
+
class ApplicationFan < Application
|
11
9
|
|
12
10
|
AVAILCMDS = "Available commands (say -h after one for help)"
|
13
11
|
NOCOMMAND = "No command given. Say -h for a list."
|
@@ -22,7 +20,7 @@ class ApplicationFan
|
|
22
20
|
attr_accessor :commands
|
23
21
|
|
24
22
|
def find_command name
|
25
|
-
@commands.find { |c| c::NAME == name }
|
23
|
+
@commands.find { |c| c::NAME == name or c::ALIASES.include? name }
|
26
24
|
end
|
27
25
|
|
28
26
|
|
@@ -35,7 +33,7 @@ class ApplicationFan
|
|
35
33
|
puts self::AVAILCMDS
|
36
34
|
puts
|
37
35
|
@commands.each { |c|
|
38
|
-
puts " %-*s %s" % [ self::W_CMDS, c
|
36
|
+
puts " %-*s %s" % [ self::W_CMDS, c.all_names, c::SUMMARY]
|
39
37
|
}
|
40
38
|
end
|
41
39
|
end
|
@@ -54,9 +52,6 @@ class ApplicationFan
|
|
54
52
|
define_singleton_method :root do
|
55
53
|
sub
|
56
54
|
end
|
57
|
-
define_singleton_method :applname do
|
58
|
-
"#{root::NAME} #{self::NAME}"
|
59
|
-
end
|
60
55
|
end
|
61
56
|
)
|
62
57
|
end
|
@@ -70,7 +65,7 @@ class ApplicationFan
|
|
70
65
|
c or raise CommandError, self.class::NOCOMMAND
|
71
66
|
cmd = self.class.find_command c
|
72
67
|
cmd or raise CommandError, self.class::UNKNWNCMD % c
|
73
|
-
sub = cmd.new @args.slice! 0, @args.length
|
68
|
+
sub = cmd.new c, (@args.slice! 0, @args.length)
|
74
69
|
yield sub if block_given?
|
75
70
|
sub.execute
|
76
71
|
end
|
metadata
CHANGED
@@ -1,35 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.14'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bertram Scharpf
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
A base class for command line applications doing options parsing
|
15
15
|
and generating exit codes.
|
16
16
|
email: "<software@bertram-scharpf.de>"
|
17
|
-
executables:
|
18
|
-
- intar
|
17
|
+
executables: []
|
19
18
|
extensions: []
|
20
19
|
extra_rdoc_files: []
|
21
20
|
files:
|
22
|
-
- bin/intar
|
23
21
|
- doc/demoappl
|
24
22
|
- doc/demofan
|
25
23
|
- lib/appl.rb
|
26
24
|
- lib/applfan.rb
|
27
|
-
- lib/intar.rb
|
28
25
|
homepage: http://www.bertram-scharpf.de/software/appl
|
29
26
|
licenses:
|
30
27
|
- BSD-2-Clause
|
31
28
|
metadata: {}
|
32
|
-
post_install_message:
|
29
|
+
post_install_message:
|
33
30
|
rdoc_options: []
|
34
31
|
require_paths:
|
35
32
|
- lib
|
@@ -45,8 +42,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
42
|
version: '0'
|
46
43
|
requirements:
|
47
44
|
- Just Ruby
|
48
|
-
rubygems_version: 3.0.
|
49
|
-
signing_key:
|
45
|
+
rubygems_version: 3.0.8
|
46
|
+
signing_key:
|
50
47
|
specification_version: 4
|
51
48
|
summary: Easy option parsing
|
52
49
|
test_files: []
|
data/bin/intar
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
#!/usr/local/bin/ruby
|
2
|
-
|
3
|
-
#
|
4
|
-
# intar -- Interactive Ruby evaluation
|
5
|
-
#
|
6
|
-
|
7
|
-
require "intar"
|
8
|
-
require "appl"
|
9
|
-
|
10
|
-
|
11
|
-
class IntarApp < Application
|
12
|
-
|
13
|
-
NAME = "intar"
|
14
|
-
VERSION = APPL_VERSION
|
15
|
-
SUMMARY = "Interactive Ruby"
|
16
|
-
COPYRIGHT = "(C) 2008-2016 Bertram Scharpf <software@bertram-scharpf.de>"
|
17
|
-
LICENSE = "BSD"
|
18
|
-
AUTHOR = "Bertram Scharpf <software@bertram-scharpf.de>"
|
19
|
-
|
20
|
-
DESCRIPTION = <<~EOT
|
21
|
-
Prompt for Ruby statements, evaluate them. This is a replacement
|
22
|
-
for "irb". The underlying library may be entered from inside any
|
23
|
-
Ruby program.
|
24
|
-
|
25
|
-
Example:
|
26
|
-
|
27
|
-
$ intar -p '%(33 1)c%t%c%> '
|
28
|
-
|
29
|
-
EOT
|
30
|
-
|
31
|
-
attr_writer :show, :prompt, :histmax
|
32
|
-
def histfile= f ; @histfile = nil_if_none f ; end
|
33
|
-
def configfile= f ; @configfile = nil_if_none f ; end
|
34
|
-
attr_bang :quiet, :bw, :catch_exit, :histall
|
35
|
-
|
36
|
-
define_option "p", :prompt=, "STR",
|
37
|
-
"prompt - see source code for % escapes"
|
38
|
-
alias_option "p", "prompt"
|
39
|
-
|
40
|
-
define_option "q", :quiet!, "don't show results"
|
41
|
-
alias_option "q", "quiet"
|
42
|
-
|
43
|
-
define_option "s", :show=, "N", "show result line limit (0=all)"
|
44
|
-
alias_option "s", "show"
|
45
|
-
|
46
|
-
define_option "r", :require, "FILE", "Ruby require"
|
47
|
-
alias_option "r", "require"
|
48
|
-
|
49
|
-
define_option "bw", :bw!, "black & white"
|
50
|
-
|
51
|
-
define_option "c", :configfile=, "FILE", ".intarrc",
|
52
|
-
"config file, NONE means none"
|
53
|
-
alias_option "c", "configfile"
|
54
|
-
|
55
|
-
define_option "H", :histfile=, "FILE", ".intar_history",
|
56
|
-
"history file, NONE means none"
|
57
|
-
alias_option "H", "histfile"
|
58
|
-
|
59
|
-
define_option "m", :histmax=, "NUM",
|
60
|
-
"maximum history entries to save"
|
61
|
-
alias_option "m", "histmax"
|
62
|
-
|
63
|
-
define_option "A", :histall!,
|
64
|
-
"pass lines starting with blanks to history"
|
65
|
-
alias_option "A", "histall"
|
66
|
-
|
67
|
-
define_option "E", :encoding=, "ENC", "set encoding (like ruby -E)"
|
68
|
-
alias_option "E", "encoding"
|
69
|
-
|
70
|
-
define_option "x", :catch_exit!,
|
71
|
-
"On exit exception: Wait 3 seconds for interrupt"
|
72
|
-
alias_option "x", "catchexit"
|
73
|
-
alias_option "x", "catch-exit"
|
74
|
-
|
75
|
-
define_option "h", :help, "show options"
|
76
|
-
alias_option "h", "help"
|
77
|
-
define_option "V", :version, "show version"
|
78
|
-
alias_option "V", "version"
|
79
|
-
|
80
|
-
def run
|
81
|
-
# @debug = true # Only development.
|
82
|
-
read_cfg
|
83
|
-
if @quiet then
|
84
|
-
Intar.show = 0
|
85
|
-
elsif @show then
|
86
|
-
Intar.show = Integer @show
|
87
|
-
end
|
88
|
-
Intar.prompt = @prompt if @prompt
|
89
|
-
Intar.colour = false if @bw
|
90
|
-
Intar.catch_exit = (Intar.catch_exit||0) + 3 if @catch_exit
|
91
|
-
Intar.histhid = false if @histall
|
92
|
-
Intar.histfile = @histfile if @histfile
|
93
|
-
Intar.histmax = Integer @histmax if @histmax
|
94
|
-
|
95
|
-
main = eval "self", TOPLEVEL_BINDING
|
96
|
-
Intar.open main do |i|
|
97
|
-
i.run *(@args.shift @args.length)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
|
103
|
-
def encoding= ei
|
104
|
-
e, i = ei.split ":"
|
105
|
-
Encoding.default_external = e if e and not e.empty?
|
106
|
-
Encoding.default_internal = i if i and not i.empty?
|
107
|
-
[ $stdin, $stdout, $stderr].each do |io|
|
108
|
-
io.set_encoding e, i
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def read_cfg
|
113
|
-
return unless @configfile
|
114
|
-
h = "~" unless @configfile[ File::SEPARATOR]
|
115
|
-
c = File.expand_path @configfile, h
|
116
|
-
return unless File.exists? c
|
117
|
-
load c
|
118
|
-
rescue Exception
|
119
|
-
$@.pop 2
|
120
|
-
e = $@.shift
|
121
|
-
puts "#{e}: #$! (#{$!.class})"
|
122
|
-
$@.each { |l| puts "\t#{l}" }
|
123
|
-
raise "Error in config file #{c}"
|
124
|
-
end
|
125
|
-
|
126
|
-
def nil_if_none var
|
127
|
-
case var
|
128
|
-
when "", "NONE" then nil
|
129
|
-
else var
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
|
-
IntarApp.run
|
136
|
-
|
data/lib/intar.rb
DELETED
@@ -1,447 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# intar.rb -- Interactive Ruby evaluation
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
=begin rdoc
|
7
|
-
|
8
|
-
This could be opened not only by the Intar executable but also
|
9
|
-
everywhere inside your Ruby program.
|
10
|
-
|
11
|
-
= Example 1
|
12
|
-
|
13
|
-
require "intar"
|
14
|
-
|
15
|
-
Intar.prompt = "str(%(length)i):%03n%> "
|
16
|
-
a = "hello"
|
17
|
-
Intar.run a
|
18
|
-
|
19
|
-
|
20
|
-
= Example 2
|
21
|
-
|
22
|
-
require "intar"
|
23
|
-
|
24
|
-
class C
|
25
|
-
end
|
26
|
-
|
27
|
-
class IntarC < Intar
|
28
|
-
@show = 3
|
29
|
-
@prompt = "%(33 1)c%t%c%> "
|
30
|
-
@histfile = ".intarc_history"
|
31
|
-
|
32
|
-
class <<self
|
33
|
-
def open
|
34
|
-
super C.new
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
IntarC.open do |ia| ia.run end
|
40
|
-
|
41
|
-
=end
|
42
|
-
|
43
|
-
|
44
|
-
require "readline"
|
45
|
-
require "supplement"
|
46
|
-
require "supplement/terminal"
|
47
|
-
|
48
|
-
|
49
|
-
class Object
|
50
|
-
def intar_binding
|
51
|
-
binding
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class Intar
|
56
|
-
|
57
|
-
class History
|
58
|
-
|
59
|
-
IND = " "
|
60
|
-
IND_RE = /^#{IND}/
|
61
|
-
|
62
|
-
def initialize filename
|
63
|
-
@filename = filename
|
64
|
-
return unless @filename
|
65
|
-
h = "~" unless @filename[ File::SEPARATOR]
|
66
|
-
@filename = File.expand_path @filename, h
|
67
|
-
File.exists? @filename and File.open @filename do |h|
|
68
|
-
c = []
|
69
|
-
h.each { |l|
|
70
|
-
case l
|
71
|
-
when IND_RE then c.push $'
|
72
|
-
else push c.join.chomp ; c.clear
|
73
|
-
end
|
74
|
-
}
|
75
|
-
push c.join.chomp
|
76
|
-
end
|
77
|
-
@num = Readline::HISTORY.length
|
78
|
-
end
|
79
|
-
|
80
|
-
def finish max
|
81
|
-
return unless @filename
|
82
|
-
@num.times { Readline::HISTORY.shift }
|
83
|
-
File.open @filename, "a" do |h|
|
84
|
-
a = []
|
85
|
-
while (c = Readline::HISTORY.shift) do a.push c end
|
86
|
-
if a.any? then
|
87
|
-
h.puts "# #{Time.now}"
|
88
|
-
a.each { |c|
|
89
|
-
c.each_line { |l| h.puts IND + l }
|
90
|
-
h.puts "-"
|
91
|
-
}
|
92
|
-
i = a.length
|
93
|
-
h.puts "# #{i} #{entry_str i} added"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
n = File.open @filename do |h|
|
97
|
-
h.inject 0 do |i,l| i += 1 if l =~ IND_RE ; i end
|
98
|
-
end
|
99
|
-
i = max - n
|
100
|
-
if i < 0 then
|
101
|
-
f = nil
|
102
|
-
File.open @filename do |h|
|
103
|
-
h.each_line { |l|
|
104
|
-
f.push l if f
|
105
|
-
case l
|
106
|
-
when IND_RE then i += 1
|
107
|
-
else f ||= [] if i >= 0
|
108
|
-
end
|
109
|
-
}
|
110
|
-
end
|
111
|
-
f and File.open @filename, "w" do |h| h.puts f end
|
112
|
-
end
|
113
|
-
rescue Errno
|
114
|
-
# Forget it if there isn't enough disk space.
|
115
|
-
end
|
116
|
-
|
117
|
-
def push l
|
118
|
-
Readline::HISTORY.push l unless l.empty?
|
119
|
-
end
|
120
|
-
|
121
|
-
private
|
122
|
-
|
123
|
-
def entry_str i
|
124
|
-
i == 1 ? "entry" : "entries"
|
125
|
-
end
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
class <<self
|
130
|
-
|
131
|
-
attr_accessor :prompt, :show, :shownil, :colour
|
132
|
-
|
133
|
-
attr_reader :histfile
|
134
|
-
def histfile= hf
|
135
|
-
@histfile = hf
|
136
|
-
if @history then
|
137
|
-
@history.finish @histmax
|
138
|
-
@history = History.new @histfile
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# Maximum number of history entries.
|
143
|
-
attr_accessor :histmax
|
144
|
-
|
145
|
-
# Whether to hide entries starting with whitespace.
|
146
|
-
attr_accessor :histhid
|
147
|
-
|
148
|
-
# Shell prefix and Pipe suffix
|
149
|
-
attr_accessor :sh_pref, :pi_suff
|
150
|
-
|
151
|
-
# Whether <code>Kernel#exit</code> should be caught.
|
152
|
-
attr_accessor :catch_exit
|
153
|
-
|
154
|
-
private
|
155
|
-
|
156
|
-
def inherited sub
|
157
|
-
sub.class_eval {
|
158
|
-
s = superclass
|
159
|
-
@prompt = s.prompt
|
160
|
-
@show = s.show
|
161
|
-
@shownil = s.shownil
|
162
|
-
@colour = s.colour
|
163
|
-
@histfile = s.histfile
|
164
|
-
@histmax = s.histmax
|
165
|
-
@histhid = s.histhid
|
166
|
-
@sh_pref = s.sh_pref
|
167
|
-
@pi_suff = s.pi_suff
|
168
|
-
@catch_exit = s.catch_exit
|
169
|
-
}
|
170
|
-
end
|
171
|
-
|
172
|
-
def history_file
|
173
|
-
if @history then
|
174
|
-
yield
|
175
|
-
else
|
176
|
-
@history = History.new @histfile
|
177
|
-
begin
|
178
|
-
yield
|
179
|
-
ensure
|
180
|
-
@history.finish @histmax
|
181
|
-
@history = nil
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
public
|
187
|
-
|
188
|
-
private :new
|
189
|
-
def open obj
|
190
|
-
history_file do
|
191
|
-
i = new obj
|
192
|
-
yield i
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
def run obj
|
197
|
-
open obj do |i| i.run end
|
198
|
-
end
|
199
|
-
|
200
|
-
def hist_add l
|
201
|
-
return if @histhid and l == /\A[ \t]+/
|
202
|
-
lst = Readline::HISTORY[-1] if Readline::HISTORY.length > 0
|
203
|
-
@history.push l unless l == lst
|
204
|
-
end
|
205
|
-
|
206
|
-
end
|
207
|
-
|
208
|
-
self.prompt = "%(32)c%i%c:%1c%03n%c%> "
|
209
|
-
self.show = 1
|
210
|
-
self.shownil = false
|
211
|
-
self.colour = true
|
212
|
-
self.histfile = nil
|
213
|
-
self.histmax = 500
|
214
|
-
self.histhid = true
|
215
|
-
self.sh_pref = "."
|
216
|
-
self.pi_suff = " |"
|
217
|
-
self.catch_exit = nil
|
218
|
-
|
219
|
-
private
|
220
|
-
|
221
|
-
def initialize obj
|
222
|
-
@obj = obj
|
223
|
-
@n = 0
|
224
|
-
end
|
225
|
-
|
226
|
-
OLDSET = <<~EOT
|
227
|
-
_, __, ___ = nil, nil, nil
|
228
|
-
proc { |r,n|
|
229
|
-
Array === __ or __ = []
|
230
|
-
Hash === ___ or ___ = {}
|
231
|
-
unless r.nil? or r.equal? __ or r.equal? ___ then
|
232
|
-
_ = r
|
233
|
-
__.delete r rescue nil
|
234
|
-
__.unshift r
|
235
|
-
___[ n] = r
|
236
|
-
end
|
237
|
-
}
|
238
|
-
EOT
|
239
|
-
|
240
|
-
autoload :Etc, "etc"
|
241
|
-
autoload :Socket, "socket"
|
242
|
-
|
243
|
-
def cur_prompt prev
|
244
|
-
t = Time.now
|
245
|
-
self.class.prompt.gsub /%(?:
|
246
|
-
\(([^\)]+)?\)
|
247
|
-
|
|
248
|
-
([+-]?[0-9]+(?:\.[0-9]+)?)
|
249
|
-
)?(.)/nx do
|
250
|
-
case $3
|
251
|
-
when "s" then @obj.to_s
|
252
|
-
when "i" then $1 ? (@obj.send $1) : @obj.inspect
|
253
|
-
when "n" then "%#$2d" % @n
|
254
|
-
when "t" then t.strftime $1||"%X"
|
255
|
-
when "u" then Etc.getpwuid.name
|
256
|
-
when "h" then Socket.gethostname
|
257
|
-
when "w" then cwd_short
|
258
|
-
when "W" then File.basename cwd_short
|
259
|
-
when "c" then (colour *($1 || $2 || "").split.map { |x| x.to_i }).to_s
|
260
|
-
when ">" then prev ? "." : Process.uid == 0 ? "#" : ">"
|
261
|
-
when "%" then $3
|
262
|
-
else $&
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def colour *c
|
268
|
-
if self.class.colour then
|
269
|
-
s = c.map { |i| "%d" % i }.join ";"
|
270
|
-
"\e[#{s}m"
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def switchcolour *c
|
275
|
-
s = colour *c
|
276
|
-
print s if s
|
277
|
-
end
|
278
|
-
|
279
|
-
def cwd_short
|
280
|
-
r = Dir.pwd
|
281
|
-
h = Etc.getpwuid.dir
|
282
|
-
r[ 0, h.length] == h and r[ 0, h.length] = "~"
|
283
|
-
r
|
284
|
-
end
|
285
|
-
|
286
|
-
def readline
|
287
|
-
r, @previous = @previous, nil
|
288
|
-
r or @n += 1
|
289
|
-
begin
|
290
|
-
cp = cur_prompt r
|
291
|
-
begin
|
292
|
-
l = Readline.readline cp
|
293
|
-
rescue Interrupt
|
294
|
-
puts "^C -- #{$!.inspect}"
|
295
|
-
retry
|
296
|
-
end
|
297
|
-
return if l.nil?
|
298
|
-
if r then
|
299
|
-
r << $/ << l
|
300
|
-
else
|
301
|
-
r = l unless l.empty?
|
302
|
-
end
|
303
|
-
self.class.hist_add l
|
304
|
-
cp.strip!
|
305
|
-
cp.gsub! /\e\[[0-9]*(;[0-9]*)*m/, ""
|
306
|
-
@file = "#{self.class}/#{cp}"
|
307
|
-
end until r
|
308
|
-
r
|
309
|
-
end
|
310
|
-
|
311
|
-
# :stopdoc:
|
312
|
-
ARROW = "=> "
|
313
|
-
ELLIPSIS = "..."
|
314
|
-
# :startdoc:
|
315
|
-
|
316
|
-
def display r
|
317
|
-
return if r.nil? and not self.class.shownil
|
318
|
-
show = (self.class.show or return)
|
319
|
-
i = ARROW.dup
|
320
|
-
i << r.inspect
|
321
|
-
if show > 0 then
|
322
|
-
siz, = $stdout.winsize
|
323
|
-
siz *= show
|
324
|
-
if i.length > siz then
|
325
|
-
i.cut! siz-ELLIPSIS.length
|
326
|
-
i << ELLIPSIS
|
327
|
-
end
|
328
|
-
end
|
329
|
-
puts i
|
330
|
-
end
|
331
|
-
|
332
|
-
def pager doit
|
333
|
-
if doit then
|
334
|
-
IO.popen ENV[ "PAGER"]||"more", "w" do |pg|
|
335
|
-
begin
|
336
|
-
stdout = $stdout.dup
|
337
|
-
$stdout.reopen pg
|
338
|
-
yield
|
339
|
-
ensure
|
340
|
-
$stdout.reopen stdout
|
341
|
-
end
|
342
|
-
end
|
343
|
-
else
|
344
|
-
yield
|
345
|
-
end
|
346
|
-
end
|
347
|
-
|
348
|
-
public
|
349
|
-
|
350
|
-
class Exit < Exception ; end
|
351
|
-
class CmdFailed < Exception ; end
|
352
|
-
|
353
|
-
def run *precmds
|
354
|
-
bind = @obj.intar_binding
|
355
|
-
precmds.each { |l| eval l, bind }
|
356
|
-
oldset = eval OLDSET, bind
|
357
|
-
@cl = (eval "caller.length", bind) + 2 # 2 = eval + run()
|
358
|
-
while l = readline do
|
359
|
-
re_sh_pref = /\A#{Regexp.quote self.class.sh_pref}/
|
360
|
-
re_pi_suff = /#{Regexp.quote self.class.pi_suff}\z/
|
361
|
-
switchcolour
|
362
|
-
begin
|
363
|
-
pg = l.slice! re_pi_suff
|
364
|
-
r = pager pg do
|
365
|
-
unless l =~ re_sh_pref then
|
366
|
-
eval l, bind, @file
|
367
|
-
else
|
368
|
-
call_system $', bind
|
369
|
-
end
|
370
|
-
end
|
371
|
-
oldset.call r, @n
|
372
|
-
display r
|
373
|
-
rescue Exit
|
374
|
-
wait_exit and break
|
375
|
-
rescue CmdFailed
|
376
|
-
oldset.call $?, @n
|
377
|
-
switchcolour 33
|
378
|
-
puts "Exit code: #{$?.exitstatus}"
|
379
|
-
rescue LoadError
|
380
|
-
oldset.call $!, @n
|
381
|
-
show_exception
|
382
|
-
rescue SyntaxError
|
383
|
-
if l.end_with? $/ then
|
384
|
-
switchcolour 33
|
385
|
-
puts $!
|
386
|
-
else
|
387
|
-
@previous = l
|
388
|
-
end
|
389
|
-
rescue SystemExit
|
390
|
-
break if wait_exit
|
391
|
-
oldset.call $!, @n
|
392
|
-
show_exception
|
393
|
-
rescue Exception
|
394
|
-
oldset.call $!, @n
|
395
|
-
show_exception
|
396
|
-
ensure
|
397
|
-
switchcolour
|
398
|
-
end
|
399
|
-
end
|
400
|
-
puts
|
401
|
-
ensure
|
402
|
-
done
|
403
|
-
end
|
404
|
-
|
405
|
-
protected
|
406
|
-
|
407
|
-
def done
|
408
|
-
end
|
409
|
-
|
410
|
-
private
|
411
|
-
|
412
|
-
def wait_exit
|
413
|
-
c = self.class.catch_exit
|
414
|
-
c and c.times { print "." ; $stdout.flush ; sleep 1 }
|
415
|
-
true
|
416
|
-
rescue Interrupt
|
417
|
-
puts
|
418
|
-
end
|
419
|
-
|
420
|
-
def show_exception
|
421
|
-
unless $!.to_s.empty? then
|
422
|
-
switchcolour 31, 1
|
423
|
-
print $!
|
424
|
-
print " " unless $!.to_s =~ /\s\z/
|
425
|
-
end
|
426
|
-
switchcolour 31, 22
|
427
|
-
puts "(#{$!.class})"
|
428
|
-
switchcolour 33
|
429
|
-
bt = $@.dup
|
430
|
-
if bt.length > @cl then
|
431
|
-
bt.pop @cl
|
432
|
-
end
|
433
|
-
puts bt
|
434
|
-
end
|
435
|
-
|
436
|
-
def call_system l, bind
|
437
|
-
l.strip!
|
438
|
-
raise Exit if l.empty?
|
439
|
-
eot = "EOT0001"
|
440
|
-
eot.succ! while l[ eot]
|
441
|
-
l = eval "<<#{eot}\n#{l}\n#{eot}", bind, @file
|
442
|
-
system l or raise CmdFailed
|
443
|
-
nil
|
444
|
-
end
|
445
|
-
|
446
|
-
end
|
447
|
-
|