ruby-shell 0.5 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -2
  3. data/bin/rsh +82 -67
  4. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43147c77abd46c4331dc8cf1c7ed4902f2849c7d11a67f00309ac45da5211c55
4
- data.tar.gz: 99926b773d53e5b7302a954d62eb3f766ef6caf0c6837cfd77dbdabe4f6a7132
3
+ metadata.gz: 800a622da17daf070678be93473db6ebebbc8a2387230d1344941136914b43f5
4
+ data.tar.gz: 3eb5c0b1067ed677d7215ac83e6d5ee2dc20075487bb3a090feb2614b5ab1220
5
5
  SHA512:
6
- metadata.gz: f53b1c639d01623da942f8255bbfe3b32a53b95faf693c18a4520ac5541c3937a073e67cdd0cee5c2b3b24d71805ca412a45293cd85311bc90c1499af11ba271
7
- data.tar.gz: a7c9b7d2255c62169b6cbf3b019f49a61843e3b0051836863c495278b69ce121b99b57208aea75e35a6d5d2b33085cd770644383d7505f3361501e6941aebed2
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) 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.
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.5"
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 << "\e[6n"
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
- @tabstr = @history_copy[@stk][0...@pos]
248
- @tabend = @history_copy[@stk][@pos..]
249
- elements = @tabstr.split(" ")
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 tab_switch(str) # TAB completion for command switches (TAB after "-")
284
- begin
285
- hlp = `#{str} --help`
286
- hlp = hlp.split("\n").grep(/^\s*-{1,2}[^-]/)
287
- hlp = hlp.map {|h| h.sub(/^\s*/, '')}
288
- switch = tabselect(hlp)
289
- switch = switch.sub(/ .*/, '').sub(/,/, '')
290
- @tabsearch.chop!
291
- @tabsearch += switch
292
- @pos = @tabstr.length + @tabsearch.length
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 = exe.select {|s| s =~ Regexp.new("^" + str)}
306
- fdir = str
307
- fdir += "/" if Dir.exist?(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 = tabselect(compl) unless compl.empty?
311
- @tabsearch = match if match
312
- @pos = @tabstr.length + @tabsearch.length if match
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 tabselect(ary) # Let user select from the incoming array
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
- sel0 = " " + ary[i][0...tl]
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
- opt0 = " " + ary[i+x][0...tl]
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.exists?(el.sub(/^~/, "/home/#{@user}"))
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
- Dir.chdir(dir) if Dir.exists?(dir)
493
- ca = @nick.transform_keys {|k| /((^\K\s*\K)|(\|\K\s*\K))\b(?<!-)#{Regexp.escape k}\b/}
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
- if File.exist?(@cmd) # Try to open file with user's editor
503
- system("#{ENV['EDITOR']} #{@cmd}")
504
- elsif system(@cmd) # Try execute the command
505
- else puts "No such command: #{@cmd}"
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.5'
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-26 00:00:00.000000000 Z
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 theming. New in 0.5: Code clean-up. Even better
15
- tab completion.'
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