ruby-shell 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/bin/rsh +81 -67
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a90c70f4301d27cd625341258f896e214b489b7bc7f94df209696970f00d44e9
|
4
|
+
data.tar.gz: 769a76676650f1bc307c22dcc4f6b2198196673b7c70acead191d6a08c802e30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78db98d6b5f0925ad5460985479480e95f03faa42ec8a4d136ad63962d956b41aab7df0077131a05546fd3d05329023242e848f138ffa87ccc0ba138f9a07d24
|
7
|
+
data.tar.gz: 306debaadf9e812c4cb6ee47e153964a2c00c866ec4208e8b5ea04b645b571004136c081e6529f54a3696515e6446bb206d9c0cfee653a24bce6e69bf3ae975a
|
data/README.md
CHANGED
@@ -29,7 +29,9 @@ 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
37
|
rsh is integrated with the [rtfm file manager](https://github.com/isene/RTFM) and with [fzf](https://github.com/junegunn/fzf). 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. 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.
|
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:"
|
@@ -489,20 +501,22 @@ loop do
|
|
489
501
|
@cmd.sub!(/^cd (\S*).*/, '\1')
|
490
502
|
@cmd = Dir.home if @cmd == "~"
|
491
503
|
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))
|
504
|
+
if Dir.exists?(dir)
|
505
|
+
Dir.chdir(dir)
|
501
506
|
else
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
507
|
+
ca = @nick.transform_keys {|k| /((^\K\s*\K)|(\|\K\s*\K))\b(?<!-)#{Regexp.escape k}\b/}
|
508
|
+
@cmd = @cmd.gsub(Regexp.union(ca.keys), @nick)
|
509
|
+
ga = @gnick.transform_keys {|k| /\b#{Regexp.escape k}\b/}
|
510
|
+
@cmd = @cmd.gsub(Regexp.union(ga.keys), @gnick)
|
511
|
+
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
512
|
+
if @cmd == "fzf" # fzf integration (https://github.com/junegunn/fzf)
|
513
|
+
res = `#{@cmd}`.chomp
|
514
|
+
Dir.chdir(File.dirname(res))
|
515
|
+
else
|
516
|
+
if File.exist?(@cmd) then system("#{ENV['EDITOR']} #{@cmd}") # Try open with user's editor
|
517
|
+
elsif system(@cmd) # Try execute the command
|
518
|
+
else puts "No such command: #{@cmd}"
|
519
|
+
end
|
506
520
|
end
|
507
521
|
end
|
508
522
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
@@ -11,8 +11,9 @@ cert_chain: []
|
|
11
11
|
date: 2023-05-26 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.6: Included history search with Shift-TAB + general improvements (thanks to folks
|
16
|
+
at #ruby at Libera.Chat).'
|
16
17
|
email: g@isene.com
|
17
18
|
executables:
|
18
19
|
- rsh
|