ruby-shell 0.5 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -2
- data/bin/rsh +82 -67
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 800a622da17daf070678be93473db6ebebbc8a2387230d1344941136914b43f5
|
4
|
+
data.tar.gz: 3eb5c0b1067ed677d7215ac83e6d5ee2dc20075487bb3a090feb2614b5ab1220
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6a32929246f8af6064bec27ab4428c4bb82d850eb893d81ae00fe127390280b43e942cfb3d5e084d1e3bd9137f587d5c642b9a92df018aafa37f8d83805c063
|
7
|
+
data.tar.gz: 4a8099fd7aa338d1f80845165b10cf7f225bf674951d3439feb719a6c7e2ccb520a45266e151357c3214f73b74951c8e6cc3fdfeff468ba32ed14b3ba16479eb
|
data/README.md
CHANGED
@@ -29,10 +29,18 @@ Or simply `gem install ruby-shell`.
|
|
29
29
|
Add command nicks (aliases) with `:nick "some_nick = some_command"`, e.g. `:nick "ls = ls --color"`. Add general nicks that will substitute anything on a command line (not just commands) like this `:gnick "some_gnick = some_command"`, e.g. `:gnick "x = /home/user/somewhere"`. List (g)nicks with `:nick?`. Remove a nick with `:nick "-some_command"`, e.g. `:nick "-ls"` to remove an `ls` nick. Same for gnicks.
|
30
30
|
|
31
31
|
## Tab completion
|
32
|
-
You can tab complete almost anything. Hitting `TAB` will try to complete in this priority: nicks, gnicks, commands, dirs/files. Hitting `TAB`after a `-` will list the command switches for the preceding command with a short explanation (from the command's --help), like this `ls -`(`TAB`) will list all the switches/options for the `ls` command.
|
32
|
+
You can tab complete almost anything. Hitting `TAB` will try to complete in this priority: nicks, gnicks, commands, dirs/files. Hitting `TAB`after a `-` will list the command switches for the preceding command with a short explanation (from the command's --help), like this `ls -`(`TAB`) will list all the switches/options for the `ls` command. You can add to (or subtract from) the search criteria while selecting possible matches - hit any letter to specify the search, while backspace removes a letter from the search criteria.
|
33
|
+
|
34
|
+
Hitting Shift-TAB will do a similar search through the command history - but with a general match of the search criteria (not only matching at the start).
|
33
35
|
|
34
36
|
## Integrations
|
35
|
-
rsh is integrated with the [rtfm file manager](https://github.com/isene/RTFM)
|
37
|
+
rsh is integrated with the [rtfm file manager](https://github.com/isene/RTFM), with [fzf](https://github.com/junegunn/fzf) and with the programming language [XRPN](https://github.com/isene/xrpn).
|
38
|
+
|
39
|
+
Just enter the command `r` and rtfm will be launched - and when you quit the file manager, you will drop back into rsh in the directory you where you exited rtfm.
|
40
|
+
|
41
|
+
Enter the command `fzf` to launch the fuzzy finder - select the directory/file you want, press `ENTER` and you will find yourself in the directory where that item resides.
|
42
|
+
|
43
|
+
If you start a line with "=", the rest of the line will be interpreted as an XRPN program. This gives you the full power of XRPN right at your fingertips. You can do simple stuff like this: `=13,23,*,x^2` and the answer to `(13 * 23)^2` will be given (89401) in the format that you have set in your `.xrpn/conf`. Or you can do more elaborate stuff like `=fix 6,5,sto c,time,'Time now is: ',atime,aview,pse,fix 0,lbl a,rcl c,prx,dse c,gto a`. Go crazy. Use single-quotes for any Alpha entry.
|
36
44
|
|
37
45
|
## Syntax highlighting
|
38
46
|
rsh will highlight nicks, gnicks, commands and dirs/files as they are written on the command line.
|
data/bin/rsh
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
# for any damages resulting from its use. Further, I am under no
|
15
15
|
# obligation to maintain or extend this software. It is provided
|
16
16
|
# on an 'as is' basis without any expressed or implied warranty.
|
17
|
-
@version = "0.
|
17
|
+
@version = "0.6"
|
18
18
|
|
19
19
|
# MODULES, CLASSES AND EXTENSIONS
|
20
20
|
class String # Add coloring to strings (with escaping for Readline)
|
@@ -38,7 +38,7 @@ module Cursor # Terminal cursor movement ANSI codes (thanks to https://github.co
|
|
38
38
|
def pos # Query cursor current position
|
39
39
|
res = ''
|
40
40
|
$stdin.raw do |stdin|
|
41
|
-
$stdout <<
|
41
|
+
$stdout << CSI + '6n' # Tha actual ANSI get-position
|
42
42
|
$stdout.flush
|
43
43
|
while (c = stdin.getc) != 'R'
|
44
44
|
res << c if c
|
@@ -93,6 +93,7 @@ module Cursor # Terminal cursor movement ANSI codes (thanks to https://github.co
|
|
93
93
|
print(CSI + 'J')
|
94
94
|
end
|
95
95
|
end
|
96
|
+
|
96
97
|
# INITIALIZATION
|
97
98
|
begin # Requires
|
98
99
|
require 'etc'
|
@@ -127,6 +128,7 @@ begin # Initialization
|
|
127
128
|
# Variable initializations
|
128
129
|
@cmd = "" # Initiate variable @cmd
|
129
130
|
end
|
131
|
+
|
130
132
|
# GENERIC FUNCTIONS
|
131
133
|
def getchr # Process key presses
|
132
134
|
c = STDIN.getch
|
@@ -244,29 +246,9 @@ def getstr # A custom Readline-like function
|
|
244
246
|
@history_copy[@stk] = ""
|
245
247
|
@pos = 0
|
246
248
|
when 'TAB' # Tab completion of dirs and files
|
247
|
-
@
|
248
|
-
|
249
|
-
|
250
|
-
if @tabstr.match(" $")
|
251
|
-
elements.append("")
|
252
|
-
@tabsearch = ""
|
253
|
-
else
|
254
|
-
@tabsearch = elements.last.to_s
|
255
|
-
@tabstr = @tabstr[0...-@tabsearch.length]
|
256
|
-
end
|
257
|
-
i = elements.length - 1
|
258
|
-
if @tabsearch =~ /^-/
|
259
|
-
until i == 0
|
260
|
-
i -= 1
|
261
|
-
if elements[i] !~ /^-/
|
262
|
-
tab_switch(elements[i])
|
263
|
-
break
|
264
|
-
end
|
265
|
-
end
|
266
|
-
else
|
267
|
-
tab_all(@tabsearch)
|
268
|
-
end
|
269
|
-
@history_copy[@stk] = @tabstr.to_s + @tabsearch.to_s + @tabend.to_s
|
249
|
+
@tabsearch =~ /^-/ ? tabbing("switch") : tabbing("all")
|
250
|
+
when 'S-TAB'
|
251
|
+
tabbing("hist")
|
270
252
|
when /^.$/
|
271
253
|
@history_copy[@stk].insert(@pos,chr)
|
272
254
|
@pos += 1
|
@@ -280,18 +262,32 @@ def getstr # A custom Readline-like function
|
|
280
262
|
@history.insert(0, @history_copy[@stk])
|
281
263
|
@history[0]
|
282
264
|
end
|
283
|
-
def
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
@tabsearch
|
292
|
-
@
|
293
|
-
rescue
|
265
|
+
def tabbing(type)
|
266
|
+
@tabstr = @history_copy[@stk][0...@pos]
|
267
|
+
@tabend = @history_copy[@stk][@pos..]
|
268
|
+
elements = @tabstr.split(" ")
|
269
|
+
if @tabstr.match(" $")
|
270
|
+
elements.append("")
|
271
|
+
@tabsearch = ""
|
272
|
+
else
|
273
|
+
@tabsearch = elements.last.to_s
|
274
|
+
@tabstr = @tabstr[0...-@tabsearch.length]
|
294
275
|
end
|
276
|
+
i = elements.length - 1
|
277
|
+
if @tabsearch =~ /^-/
|
278
|
+
until i == 0
|
279
|
+
i -= 1
|
280
|
+
if elements[i] !~ /^-/
|
281
|
+
tab_switch(elements[i])
|
282
|
+
break
|
283
|
+
end
|
284
|
+
end
|
285
|
+
elsif type == 'all'
|
286
|
+
tab_all(@tabsearch)
|
287
|
+
elsif type == 'hist'
|
288
|
+
tab_hist(@tabsearch)
|
289
|
+
end
|
290
|
+
@history_copy[@stk] = @tabstr.to_s + @tabsearch.to_s + @tabend.to_s
|
295
291
|
end
|
296
292
|
def tab_all(str) # TAB completion for Dirs/files, nicks and commands
|
297
293
|
exe = []
|
@@ -302,22 +298,41 @@ def tab_all(str) # TAB completion for Dirs/files, nicks and commands
|
|
302
298
|
end
|
303
299
|
exe.prepend(*@nick.keys)
|
304
300
|
exe.prepend(*@gnick.keys)
|
305
|
-
compl
|
306
|
-
fdir
|
307
|
-
fdir
|
308
|
-
fdir
|
301
|
+
compl = exe.select {|s| s =~ Regexp.new("^" + str)}
|
302
|
+
fdir = str
|
303
|
+
fdir += "/" if Dir.exist?(fdir)
|
304
|
+
fdir += "*"
|
309
305
|
compl.prepend(*Dir.glob(fdir))
|
310
|
-
match
|
311
|
-
@tabsearch
|
312
|
-
@pos
|
306
|
+
match = tabselect(compl) unless compl.empty?
|
307
|
+
@tabsearch = match if match
|
308
|
+
@pos = @tabstr.length + @tabsearch.length if match
|
313
309
|
end
|
314
|
-
def
|
310
|
+
def tab_switch(str) # TAB completion for command switches (TAB after "-")
|
311
|
+
begin
|
312
|
+
hlp = `#{str} --help`
|
313
|
+
hlp = hlp.split("\n").grep(/^\s*-{1,2}[^-]/)
|
314
|
+
hlp = hlp.map {|h| h.sub(/^\s*/, '')}
|
315
|
+
switch = tabselect(hlp)
|
316
|
+
switch = switch.sub(/ .*/, '').sub(/,/, '')
|
317
|
+
@tabsearch = switch if switch
|
318
|
+
@pos = @tabstr.length + @tabsearch.length
|
319
|
+
rescue
|
320
|
+
end
|
321
|
+
end
|
322
|
+
def tab_hist(str)
|
323
|
+
sel = @history.select {|el| el =~ /#{str}/}
|
324
|
+
hist = tabselect(sel, true)
|
325
|
+
@tabsearch = hist if hist
|
326
|
+
@pos = @tabstr.length + @tabsearch.length if hist
|
327
|
+
end
|
328
|
+
def tabselect(ary, hist=false) # Let user select from the incoming array
|
329
|
+
ary.uniq!
|
315
330
|
@c_row, @c_col = @c.pos
|
316
331
|
chr = ""
|
317
332
|
i = 0
|
318
|
-
ary.length - i < 5 ? l = ary.length - i : l = 5
|
319
333
|
while chr != "ENTER"
|
320
334
|
@c.clear_screen_down
|
335
|
+
ary.length - i < 5 ? l = ary.length - i : l = 5
|
321
336
|
l.times do |x|
|
322
337
|
tl = @tabsearch.length
|
323
338
|
if x == 0
|
@@ -327,14 +342,10 @@ def tabselect(ary) # Let user select from the incoming array
|
|
327
342
|
print tabline # Full command line
|
328
343
|
@c_col = @pos0 + @tabstr.length + tabchoice.length
|
329
344
|
nextline
|
330
|
-
|
331
|
-
sel1 = ary[i][tl...].c(@c_tabselect)
|
332
|
-
print sel0 + sel1 # Top option selected
|
345
|
+
print " " + ary[i].sub(/(.*?)#{@tabsearch}(.*)/, '\1'.c(@c_tabselect) + @tabsearch + '\2'.c(@c_tabselect))
|
333
346
|
else
|
334
347
|
begin
|
335
|
-
|
336
|
-
opt1 = ary[i+x][tl...].c(@c_taboption)
|
337
|
-
print opt0 + opt1 # Next option unselected
|
348
|
+
print " " + ary[i+x].sub(/(.*?)#{@tabsearch}(.*)/, '\1'.c(@c_taboption) + @tabsearch + '\2'.c(@c_taboption))
|
338
349
|
rescue
|
339
350
|
end
|
340
351
|
end
|
@@ -355,11 +366,11 @@ def tabselect(ary) # Let user select from the incoming array
|
|
355
366
|
chr = "ENTER"
|
356
367
|
when 'BACK'
|
357
368
|
@tabsearch.chop! unless @tabsearch == ''
|
358
|
-
tab_all(@tabsearch)
|
369
|
+
hist ? tab_hist(@tabsearch) : tab_all(@tabsearch)
|
359
370
|
return @tabsearch
|
360
371
|
when /^[[:print:]]$/
|
361
372
|
@tabsearch += chr
|
362
|
-
tab_all(@tabsearch)
|
373
|
+
hist ? tab_hist(@tabsearch) : tab_all(@tabsearch)
|
363
374
|
return @tabsearch
|
364
375
|
end
|
365
376
|
end
|
@@ -387,7 +398,7 @@ def cmd_check(str) # Check if each element on the readline matches commands, nic
|
|
387
398
|
el.c(@c_nick)
|
388
399
|
elsif @gnick.include?(el)
|
389
400
|
el.c(@c_gnick)
|
390
|
-
elsif File.
|
401
|
+
elsif File.exist?(el.sub(/^~/, "/home/#{@user}"))
|
391
402
|
el.c(@c_path)
|
392
403
|
elsif system "which #{el}", %i[out err] => File::NULL
|
393
404
|
el.c(@c_cmd)
|
@@ -414,6 +425,7 @@ def rshrc # Write updates to .rshrc
|
|
414
425
|
File.write(Dir.home+'/.rshrc', conf)
|
415
426
|
puts "\n .rshrc updated"
|
416
427
|
end
|
428
|
+
|
417
429
|
# RSH FUNCTIONS
|
418
430
|
def history # Show history
|
419
431
|
puts "History:"
|
@@ -482,6 +494,7 @@ loop do
|
|
482
494
|
Dir.chdir(File.read("/tmp/.rshpwd"))
|
483
495
|
next
|
484
496
|
end
|
497
|
+
@cmd = "echo \"#{@cmd[1...]},prx,off\" | xrpn" if @cmd =~ /^\=/ # Integration with xrpn (https://github.com/isene/xrpn)
|
485
498
|
begin
|
486
499
|
if @cmd.match(/^\s*:/) # Ruby commands are prefixed with ":"
|
487
500
|
eval(@cmd[1..-1])
|
@@ -489,20 +502,22 @@ loop do
|
|
489
502
|
@cmd.sub!(/^cd (\S*).*/, '\1')
|
490
503
|
@cmd = Dir.home if @cmd == "~"
|
491
504
|
dir = @cmd.strip.sub(/~/, Dir.home)
|
492
|
-
|
493
|
-
|
494
|
-
@cmd = @cmd.gsub(Regexp.union(ca.keys), @nick)
|
495
|
-
ga = @gnick.transform_keys {|k| /\b#{Regexp.escape k}\b/}
|
496
|
-
@cmd = @cmd.gsub(Regexp.union(ga.keys), @gnick)
|
497
|
-
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
498
|
-
if @cmd == "fzf" # fzf integration (https://github.com/junegunn/fzf)
|
499
|
-
res = `#{@cmd}`.chomp
|
500
|
-
Dir.chdir(File.dirname(res))
|
505
|
+
if Dir.exists?(dir)
|
506
|
+
Dir.chdir(dir)
|
501
507
|
else
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
508
|
+
ca = @nick.transform_keys {|k| /((^\K\s*\K)|(\|\K\s*\K))\b(?<!-)#{Regexp.escape k}\b/}
|
509
|
+
@cmd = @cmd.gsub(Regexp.union(ca.keys), @nick)
|
510
|
+
ga = @gnick.transform_keys {|k| /\b#{Regexp.escape k}\b/}
|
511
|
+
@cmd = @cmd.gsub(Regexp.union(ga.keys), @gnick)
|
512
|
+
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
513
|
+
if @cmd == "fzf" # fzf integration (https://github.com/junegunn/fzf)
|
514
|
+
res = `#{@cmd}`.chomp
|
515
|
+
Dir.chdir(File.dirname(res))
|
516
|
+
else
|
517
|
+
if File.exist?(@cmd) then system("#{ENV['EDITOR']} #{@cmd}") # Try open with user's editor
|
518
|
+
elsif system(@cmd) # Try execute the command
|
519
|
+
else puts "No such command: #{@cmd}"
|
520
|
+
end
|
506
521
|
end
|
507
522
|
end
|
508
523
|
end
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'A shell written in Ruby with extensive tab completions, aliases/nicks,
|
14
|
-
history, syntax highlighting and
|
15
|
-
|
14
|
+
history, syntax highlighting, theming and more. In continual development. New in
|
15
|
+
0.7: Added XRPN integration :).'
|
16
16
|
email: g@isene.com
|
17
17
|
executables:
|
18
18
|
- rsh
|