intar 2.3 → 2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README +15 -0
- data/lib/intar/prompt.rb +15 -4
- data/lib/intar/redirect.rb +15 -11
- data/lib/intar/version.rb +1 -1
- data/lib/intar.rb +129 -80
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cad6272b3ab1559bdebde9d6c9979fe065d4bf7bc57c49c85a0d6abf10071b0b
|
4
|
+
data.tar.gz: 3babbed5bbeab2e9f1b7da52ff16aec85f16f13da414f20fe3fdfac995ec0776
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3757b39f033d37efb3b0c36b547e788da344f084160b3f4cea112c6d23b9249db7bc0a766df605cf546f592810f1da2290e1bcf949f9179a0ed573f425b52ba
|
7
|
+
data.tar.gz: 8309a03d4e9a40a604829eaa70d18ed54db2d09d698a5d13474526e5a7cdf6a64bb1109c6fb8ab2c62443d5f97ec06225097408f206e8a3b527102f77e1558b2
|
data/README
CHANGED
@@ -18,6 +18,21 @@ Yet, Intar is more robust. Try this in Irb and in Intar:
|
|
18
18
|
|
19
19
|
|
20
20
|
|
21
|
+
== Usage
|
22
|
+
|
23
|
+
=== Subcommands
|
24
|
+
|
25
|
+
obj.method & enter a sub-Intar
|
26
|
+
obj.each & enter multiple sub-Intars
|
27
|
+
|
28
|
+
\q exit from the innermost sub-Intar
|
29
|
+
\q! exit from the innermost sub-Intar loop
|
30
|
+
\q!! exit from all levels
|
31
|
+
|
32
|
+
\h get a list of all subcommands
|
33
|
+
|
34
|
+
|
35
|
+
|
21
36
|
== Author
|
22
37
|
|
23
38
|
Bertram Scharpf <software@bertram-scharpf.de>
|
data/lib/intar/prompt.rb
CHANGED
@@ -16,8 +16,20 @@ class Intar
|
|
16
16
|
@new = 0
|
17
17
|
end
|
18
18
|
|
19
|
+
def push text
|
20
|
+
Readline.pre_input_hook = proc {
|
21
|
+
Readline.insert_text text
|
22
|
+
Readline.redisplay
|
23
|
+
}
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
19
27
|
def ask prompt
|
20
|
-
|
28
|
+
begin
|
29
|
+
Readline.readline prompt
|
30
|
+
ensure
|
31
|
+
Readline.pre_input_hook = nil
|
32
|
+
end
|
21
33
|
rescue Interrupt
|
22
34
|
puts
|
23
35
|
retry
|
@@ -34,12 +46,11 @@ class Intar
|
|
34
46
|
i = Readline::HISTORY.length
|
35
47
|
while i > 0 do
|
36
48
|
i -= 1
|
37
|
-
|
38
|
-
yield l
|
49
|
+
yield Readline::HISTORY[i]
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
|
-
def
|
53
|
+
def push_history item
|
43
54
|
item.empty? and return
|
44
55
|
last != item or return
|
45
56
|
Readline::HISTORY.push item
|
data/lib/intar/redirect.rb
CHANGED
@@ -16,22 +16,24 @@ class Intar
|
|
16
16
|
class Redirect
|
17
17
|
def redirect_output
|
18
18
|
out = outfile
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
begin
|
20
|
+
stdin, stdout = $stdin.dup, $stdout.dup
|
21
|
+
$stdin .reopen "/dev/null"
|
22
|
+
$stdout.reopen out
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
$stdin .reopen stdin
|
26
|
+
$stdout.reopen stdout
|
27
|
+
out.close
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
32
|
class RedirectPipe < Redirect
|
31
33
|
class <<self
|
32
34
|
def detect line, pager
|
33
|
-
if line.slice! /\s
|
34
|
-
new pager
|
35
|
+
if line.slice! /\s+\|(\b[^|&;{}()\[\]]*)?\z/ then
|
36
|
+
new $1||pager
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
@@ -39,7 +41,9 @@ class Intar
|
|
39
41
|
@pager = pager||ENV[ "PAGER"]||"more"
|
40
42
|
end
|
41
43
|
def outfile
|
42
|
-
IO.popen @pager.to_s, "w"
|
44
|
+
IO.popen @pager.to_s, "w"
|
45
|
+
rescue Errno::ENOENT
|
46
|
+
raise Failed, "Pipe error: #$!"
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
data/lib/intar/version.rb
CHANGED
data/lib/intar.rb
CHANGED
@@ -63,7 +63,7 @@ class Intar
|
|
63
63
|
|
64
64
|
|
65
65
|
DEFAULTS = {
|
66
|
-
prompt: "%(32)c%
|
66
|
+
prompt: "%(32)c%16i%c:%1c%d:%3n%c%> ",
|
67
67
|
color: true,
|
68
68
|
show: 1,
|
69
69
|
shownil: false,
|
@@ -74,56 +74,66 @@ class Intar
|
|
74
74
|
histmax: 500,
|
75
75
|
}
|
76
76
|
|
77
|
+
@@current = nil
|
78
|
+
|
79
|
+
attr_reader :params, :prompt, :depth, :n
|
77
80
|
def initialize obj = nil, **params
|
78
81
|
@obj = obj.nil? ? (eval "self", TOPLEVEL_BINDING) : obj
|
79
|
-
|
80
|
-
|
82
|
+
if @@current then
|
83
|
+
@params = @@current.params
|
84
|
+
@prompt = @@current.prompt
|
85
|
+
@depth = @@current.depth + 1
|
86
|
+
else
|
87
|
+
@params = DEFAULTS.dup.update params
|
88
|
+
@prompt = Prompt.new
|
89
|
+
@depth = 0
|
90
|
+
end
|
81
91
|
@n = 1
|
82
|
-
|
92
|
+
|
93
|
+
@binding = @obj.intar_binding
|
83
94
|
end
|
84
95
|
|
85
96
|
|
86
97
|
class Quit < Exception ; end
|
87
|
-
class
|
98
|
+
class Bye < Quit ; end
|
99
|
+
class Break < Bye ; end
|
100
|
+
class Failed < StandardError ; end
|
88
101
|
|
89
102
|
def run
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
+
handle_history do
|
104
|
+
set_current do
|
105
|
+
oldset = eval OLDSET, @binding
|
106
|
+
loop do
|
107
|
+
l = readline
|
108
|
+
l or break
|
109
|
+
@redir = find_redirect l
|
110
|
+
r = begin
|
111
|
+
if l =~ /\A\\(\w+|.)\s*(.*?)\s*\Z/ then
|
112
|
+
send (get_metacommand $1).method, (eval_param $2)
|
113
|
+
else
|
114
|
+
l.sub! %r/\s*&\s*\z/, SUB
|
115
|
+
@redir.redirect_output do eval l, @binding, @file end
|
116
|
+
end
|
117
|
+
rescue Bye
|
118
|
+
raise if @depth.nonzero?
|
119
|
+
break
|
120
|
+
rescue Quit
|
121
|
+
break
|
103
122
|
rescue SyntaxError
|
104
123
|
raise if l.end_with? $/
|
105
124
|
@previous = l
|
106
125
|
next
|
126
|
+
rescue Exception
|
127
|
+
break if SystemExit === $! and not @params[ :catch_exit]
|
128
|
+
show_exception
|
129
|
+
$!
|
107
130
|
end
|
131
|
+
display r
|
132
|
+
oldset.call r, @n
|
133
|
+
@n += 1
|
108
134
|
end
|
109
|
-
rescue Quit
|
110
|
-
break
|
111
|
-
rescue Failed
|
112
|
-
switchcolor 31, 1
|
113
|
-
puts $!
|
114
|
-
switchcolor
|
115
|
-
r = $!
|
116
|
-
rescue Exception
|
117
|
-
break if SystemExit === $! and not @params[ :catch_exit]
|
118
|
-
show_exception
|
119
|
-
r = $!
|
120
|
-
else
|
121
|
-
display r
|
122
135
|
end
|
123
|
-
oldset.call r, @n
|
124
|
-
@n += 1
|
125
136
|
end
|
126
|
-
prompt_save_history
|
127
137
|
end
|
128
138
|
|
129
139
|
def execute code
|
@@ -133,6 +143,26 @@ class Intar
|
|
133
143
|
|
134
144
|
private
|
135
145
|
|
146
|
+
def handle_history
|
147
|
+
unless @depth.nonzero? then
|
148
|
+
begin
|
149
|
+
prompt_load_history
|
150
|
+
yield
|
151
|
+
ensure
|
152
|
+
prompt_save_history
|
153
|
+
end
|
154
|
+
else
|
155
|
+
yield
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def set_current
|
160
|
+
old, @@current = @@current, self
|
161
|
+
yield
|
162
|
+
ensure
|
163
|
+
@@current = old
|
164
|
+
end
|
165
|
+
|
136
166
|
def find_redirect line
|
137
167
|
RedirectPipe.detect line, @params[ :pager] or
|
138
168
|
RedirectFile.detect line, @params[ :output] or
|
@@ -140,6 +170,14 @@ class Intar
|
|
140
170
|
end
|
141
171
|
|
142
172
|
|
173
|
+
SUB = <<~EOT
|
174
|
+
\ do |obj|
|
175
|
+
Intar.run obj
|
176
|
+
rescue Intar::Break
|
177
|
+
break
|
178
|
+
end
|
179
|
+
EOT
|
180
|
+
|
143
181
|
OLDSET = <<~EOT
|
144
182
|
_, __, ___ = nil, nil, nil
|
145
183
|
proc { |r,n|
|
@@ -158,44 +196,56 @@ class Intar
|
|
158
196
|
|
159
197
|
def cur_prompt prev
|
160
198
|
p = @params[ :prompt].to_s
|
161
|
-
p.gsub /%
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
case $
|
167
|
-
when "s" then @obj.to_s
|
168
|
-
when "i" then $1 ? (@obj.send
|
169
|
-
when "
|
170
|
-
when "
|
171
|
-
when "
|
172
|
-
when "
|
173
|
-
when "
|
174
|
-
when "
|
175
|
-
when "
|
199
|
+
p.gsub /%
|
200
|
+
(\d+)?
|
201
|
+
(?:\(([^)]*)\)|\{([^}]*)\})?
|
202
|
+
(.)/nx do
|
203
|
+
sub = $2||$3
|
204
|
+
case $4
|
205
|
+
when "s" then str_axe $1, @obj.to_s
|
206
|
+
when "i" then str_axe $1, (sub ? (@obj.send sub) : @obj.inspect)
|
207
|
+
when "C" then str_axe $1, @obj.class.name
|
208
|
+
when "n" then "%0#$1d" % @n
|
209
|
+
when "d" then "%0#$1d" % @depth
|
210
|
+
when "t" then str_axe $1, (Time.now.strftime sub||"%X")
|
211
|
+
when "u" then str_axe $1, Etc.getpwuid.name
|
212
|
+
when "h" then str_axe $1, Socket.gethostname
|
213
|
+
when "w" then str_axe $1, cwd_short
|
214
|
+
when "W" then str_axe $1, (File.basename cwd_short)
|
215
|
+
when "c" then color [$1,sub].compact.map { |c| c.scan %r/\d+/ }.flatten
|
176
216
|
when ">" then prev ? "." : Process.uid == 0 ? "#" : ">"
|
177
|
-
when "%" then $
|
217
|
+
when "%" then $4
|
178
218
|
else $&
|
179
219
|
end
|
180
220
|
end
|
181
221
|
end
|
182
222
|
|
183
|
-
def
|
223
|
+
def str_axe len, str
|
224
|
+
if len then
|
225
|
+
str.axe len.to_i
|
226
|
+
else
|
227
|
+
str
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def color codes
|
184
232
|
if @params[ :color] then
|
185
|
-
|
186
|
-
"\e[#{s}m"
|
233
|
+
"\e[#{codes.join ';'}m"
|
187
234
|
end
|
188
235
|
end
|
189
236
|
|
190
237
|
def switchcolor *c
|
191
|
-
s = color
|
238
|
+
s = color c
|
192
239
|
print s
|
193
240
|
end
|
194
241
|
|
195
242
|
def cwd_short
|
196
243
|
r = Dir.pwd
|
197
244
|
h = Etc.getpwuid.dir
|
198
|
-
r[ 0, h.length] == h
|
245
|
+
if r[ 0, h.length] == h then
|
246
|
+
n = r[ h.length]
|
247
|
+
r[ 0, h.length] = "~" if !n || n == "/"
|
248
|
+
end
|
199
249
|
r
|
200
250
|
end
|
201
251
|
|
@@ -205,7 +255,7 @@ class Intar
|
|
205
255
|
cp = cur_prompt r
|
206
256
|
l = @prompt.ask cp
|
207
257
|
return if l.nil?
|
208
|
-
@prompt.
|
258
|
+
@prompt.push_history l unless !r and @params[ :histhid] and l =~ /\A[ \t]+/
|
209
259
|
if r then
|
210
260
|
r << $/ << l
|
211
261
|
else
|
@@ -246,11 +296,11 @@ class Intar
|
|
246
296
|
|
247
297
|
def show_exception
|
248
298
|
unless $!.to_s.empty? then
|
249
|
-
switchcolor
|
299
|
+
switchcolor 1, 31
|
250
300
|
print $!
|
251
301
|
print " " unless $!.to_s =~ /\s\z/
|
252
302
|
end
|
253
|
-
switchcolor
|
303
|
+
switchcolor 22, 31
|
254
304
|
puts "(#{$!.class})"
|
255
305
|
switchcolor 33
|
256
306
|
$@.each { |b|
|
@@ -351,36 +401,36 @@ class Intar
|
|
351
401
|
Leave Intar.
|
352
402
|
EOT
|
353
403
|
def cmd_quit x
|
354
|
-
|
404
|
+
lx = $&.length.nonzero? if x =~ /!*/
|
405
|
+
raise lx ? (lx > 1 ? Bye : Break) : Quit
|
355
406
|
end
|
356
407
|
|
357
408
|
metacmd %w(cd), "Change directory", <<~EOT
|
358
409
|
Switch to a different working directory.
|
359
|
-
Former directories will be
|
410
|
+
Former directories will be pushed to a stack.
|
360
411
|
|
361
|
-
|
362
|
-
|
363
|
-
|
412
|
+
N|PATH|% change directory and push
|
413
|
+
-N|PATH|% drop stack item
|
414
|
+
=N|PATH|% change directory but do not push
|
364
415
|
|
365
|
-
Default N is 1.
|
416
|
+
Default N or % is 1.
|
366
417
|
EOT
|
367
418
|
def cmd_cd x
|
368
419
|
@wds ||= []
|
369
420
|
y = Dir.getwd
|
370
|
-
if x =~ /\A([%=-])?(\d+)?\z/ then
|
371
|
-
x = $2 ? (@wds.delete_at -$2.to_i) : @wds.pop
|
372
|
-
x or raise Failed, ($2 ? "No directory ##$2." : "No last directory.")
|
373
|
-
case $1
|
374
|
-
when "-" then x = nil
|
375
|
-
when "=" then y = nil
|
376
|
-
end
|
377
|
-
end
|
378
421
|
if x then
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
422
|
+
cmd = x.slice! /\A[=-]/
|
423
|
+
x = case x
|
424
|
+
when /\A\d+\z/ then @wds[ -x.to_i] or raise Failed, "No directory ##{x}."
|
425
|
+
when /\A%?\z/ then @wds.last or raise Failed, "No last directory."
|
426
|
+
else File.expand_path x
|
427
|
+
end
|
428
|
+
@wds.delete x
|
429
|
+
if cmd != "-" then
|
430
|
+
Dir.chdir x
|
431
|
+
@wds.push y if cmd != "="
|
432
|
+
y = x
|
433
|
+
end
|
384
434
|
end
|
385
435
|
@redir.redirect_output do
|
386
436
|
i = @wds.length
|
@@ -467,7 +517,7 @@ class Intar
|
|
467
517
|
EOT
|
468
518
|
def cmd_input x
|
469
519
|
x or raise Failed, "No input file given."
|
470
|
-
l = File.read x
|
520
|
+
l = File.read x
|
471
521
|
@redir.redirect_output do
|
472
522
|
eval l, @binding, x
|
473
523
|
end
|
@@ -478,7 +528,7 @@ class Intar
|
|
478
528
|
EOT
|
479
529
|
def cmd_output x
|
480
530
|
if x then
|
481
|
-
File.open x, "w" do end
|
531
|
+
File.open x, "w" do end
|
482
532
|
end
|
483
533
|
@params[ :output] = x
|
484
534
|
end
|
@@ -498,7 +548,6 @@ class Intar
|
|
498
548
|
p = File.read fn
|
499
549
|
p.strip!
|
500
550
|
@prompt.push p
|
501
|
-
@redir.redirect_output do eval p, @binding, @file end
|
502
551
|
ensure
|
503
552
|
File.unlink fn
|
504
553
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: intar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '2.
|
4
|
+
version: '2.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bertram Scharpf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appl
|