ruby-shell 0.5 → 0.6

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 +3 -1
  3. data/bin/rsh +81 -67
  4. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43147c77abd46c4331dc8cf1c7ed4902f2849c7d11a67f00309ac45da5211c55
4
- data.tar.gz: 99926b773d53e5b7302a954d62eb3f766ef6caf0c6837cfd77dbdabe4f6a7132
3
+ metadata.gz: a90c70f4301d27cd625341258f896e214b489b7bc7f94df209696970f00d44e9
4
+ data.tar.gz: 769a76676650f1bc307c22dcc4f6b2198196673b7c70acead191d6a08c802e30
5
5
  SHA512:
6
- metadata.gz: f53b1c639d01623da942f8255bbfe3b32a53b95faf693c18a4520ac5541c3937a073e67cdd0cee5c2b3b24d71805ca412a45293cd85311bc90c1499af11ba271
7
- data.tar.gz: a7c9b7d2255c62169b6cbf3b019f49a61843e3b0051836863c495278b69ce121b99b57208aea75e35a6d5d2b33085cd770644383d7505f3361501e6941aebed2
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.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:"
@@ -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
- 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))
504
+ if Dir.exists?(dir)
505
+ Dir.chdir(dir)
501
506
  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}"
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.5'
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 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.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