djinni 1.3.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d6bdde61547d555da94f76c9d3bdb07673cb4e2
4
- data.tar.gz: 5c911b3278fd04e20803e01f1bcdb9bfbd7809b9
3
+ metadata.gz: b0c26461a62d30afb00ae7a1cb72b76f0ef55b9e
4
+ data.tar.gz: 7dbdea06e28da92e6511031b88a3d286c7eb2481
5
5
  SHA512:
6
- metadata.gz: c684bdacedecc922a6853c6624c8bd47ccf8da7daf3af9e76048ae8917f22129cfb3d15d5efe530d16f3a054e8b529eaf02fbb745413314650962a770282075c
7
- data.tar.gz: b1709e68b1205931c8c254af7fe6bede4614062c832188ac322808a5592293016e91220e08d76e17c947e382d1716cc4d816303dbcfa3c55dead8faa16842c62
6
+ metadata.gz: fc6041f1be04c2b4644eb3efea8dd137d207a843ab10aa65aa98b8e3d4dfc2e13df984056eaa4a59d76a692907a0ca87928378128aaf219fb98214db6b9b23e4
7
+ data.tar.gz: dcc88eb053727c0f5e4b4a2d28b40c76a5bc3df4779fac764a7b9e1c606d916a9d3f306e2bf4ad1f19371aff71ab0101b0834c82e7dbda018a8cc6e6ce39df40
@@ -1,6 +1,6 @@
1
1
  class Djinni::Wish::Clear < Djinni::Wish
2
2
  def aliases
3
- return [ "clear", "cls" ]
3
+ return ["clear", "cls"]
4
4
  end
5
5
 
6
6
  def description
@@ -8,15 +8,12 @@ class Djinni::Wish::Clear < Djinni::Wish
8
8
  end
9
9
 
10
10
  def execute(args, djinni_env = {})
11
- if (args.nil? || args.empty?)
12
- system("clear")
13
- else
14
- usage
15
- end
11
+ system("clear") if (args.empty?)
12
+ usage if (!args.empty?)
16
13
  end
17
14
 
18
15
  def usage
19
16
  puts aliases.join(", ")
20
- puts "\t#{description}."
17
+ puts " #{description}."
21
18
  end
22
19
  end
@@ -1,6 +1,6 @@
1
1
  class Djinni::Wish::Help < Djinni::Wish
2
2
  def aliases
3
- return [ "?", "help" ]
3
+ return ["?", "help"]
4
4
  end
5
5
 
6
6
  def description
@@ -8,27 +8,22 @@ class Djinni::Wish::Help < Djinni::Wish
8
8
  end
9
9
 
10
10
  def execute(args, djinni_env = {})
11
- wishes = djinni_env["djinni_wishes"].sort
12
- if (args.nil? || args.empty?)
13
- cmd_col_width = 0
14
- wishes.map do |aliaz, wish|
15
- if (aliaz.length > cmd_col_width)
16
- cmd_col_width = aliaz.length
17
- end
18
- end
19
-
20
- filler = Array.new(cmd_col_width - 7 + 4, " ").join
21
- puts "COMMAND#{filler}DESCRIPTION"
22
- puts "-------#{filler}-----------"
23
- wishes.map do |aliaz, wish|
24
- filler = Array.new(
25
- cmd_col_width - aliaz.length + 4,
26
- " "
27
- ).join
28
- puts "#{aliaz}#{filler}#{wish.description}"
11
+ wishes = djinni_env["djinni_wishes"]
12
+ max = wishes.keys.max_by(&:length).length
13
+ if (args.empty?)
14
+ fill = Array.new(max - 7 + 4, " ").join
15
+ puts "COMMAND#{fill}DESCRIPTION"
16
+ puts "-------#{fill}-----------"
17
+ wishes.sort do |a, b|
18
+ a.first.downcase <=> b.first.downcase
19
+ end.each do |aliaz, wish|
20
+ fill = Array.new(max - aliaz.length + 4, " ").join
21
+ puts "#{aliaz}#{fill}#{wish.description}"
29
22
  end
30
23
  elsif (args.split(" ").length == 1)
31
- wishes.map do |aliaz, wish|
24
+ wishes.sort do |a, b|
25
+ a.first.downcase <=> b.first.downcase
26
+ end.each do |aliaz, wish|
32
27
  if (aliaz == args)
33
28
  wish.usage
34
29
  return
@@ -41,13 +36,23 @@ class Djinni::Wish::Help < Djinni::Wish
41
36
  end
42
37
 
43
38
  def tab_complete(input, djinni_env = {})
44
- # TODO
45
- return input
39
+ return [{}, "", " "] if (input.include?(" "))
40
+
41
+ completions = Hash.new
42
+ djinni_env["djinni_wishes"].select do |aliaz, wish|
43
+ aliaz.downcase.start_with?(input.downcase)
44
+ end.sort do |a, b|
45
+ a.first.downcase <=> b.first.downcase
46
+ end.each do |aliaz, wish|
47
+ completions[aliaz] = wish.description
48
+ end
49
+
50
+ return [completions, input, " "]
46
51
  end
47
52
 
48
53
  def usage
49
54
  puts "help [command]"
50
- puts "\tPrint usage for specified command. If no command is"
51
- puts "\tspecified, print description of all commands."
55
+ puts " Print usage for specified command. If no command is"
56
+ puts " specified, print description of all commands."
52
57
  end
53
58
  end
@@ -1,6 +1,8 @@
1
+ require "string"
2
+
1
3
  class Djinni::Wish::History < Djinni::Wish
2
4
  def aliases
3
- return [ "hist", "history" ]
5
+ return ["hist", "history"]
4
6
  end
5
7
 
6
8
  def description
@@ -11,56 +13,69 @@ class Djinni::Wish::History < Djinni::Wish
11
13
  djinni = djinni_env["djinni"]
12
14
  history = djinni_env["djinni_history"]
13
15
 
14
- case args
15
- when nil, ""
16
- history.each_index do |index|
17
- puts "#{index}:\t#{history[index]}"
16
+ if (args.empty?)
17
+ history.each_with_index do |hist, index|
18
+ puts "#{index}: #{hist}"
18
19
  end
19
- when "clear"
20
- history.clear
21
- when %r{^[0-9]+( [0-9]+)*$}
22
- args.split(" ").each do |arg|
20
+ return
21
+ end
22
+
23
+ args.split(" ").each do |arg|
24
+ case arg
25
+ when "clear"
26
+ # Do nothing
27
+ when /^[0-9]+$/
23
28
  index = arg.to_i
24
- if ((index >= 0) && (index < history.length))
25
- djinni.grant_wish(
26
- "#{history[index]}\n",
27
- djinni_env
28
- )
29
- else
30
- puts "Index out of bounds"
29
+ if ((index < 0) || (index >= history.length))
30
+ puts "Index out of bounds; #{index}"
31
31
  end
32
+ else
33
+ usage
34
+ return
35
+ end
36
+ end
37
+
38
+ args.split(" ").each do |arg|
39
+ case arg
40
+ when "clear"
41
+ history.clear
42
+ when /^[0-9]+$/
43
+ index = arg.to_i
44
+ print "\e[F"
45
+ djinni.grant_wish("#{history[index]}\n", djinni_env)
32
46
  end
33
- else
34
- usage
35
47
  end
36
48
  end
37
49
 
38
50
  def tab_complete(input, djinni_env = {})
39
51
  history = djinni_env["djinni_history"]
40
-
52
+ input, last = input.rsplit(" ")
41
53
  included = input.split(" ")
42
- completions = (0...history.length).to_a
43
54
 
44
- included.each do |item|
45
- completions.delete(item.to_i)
55
+ completions = Hash.new
56
+ (0...history.length).each do |i|
57
+ completions[i.to_s] = history[i]
58
+ end
59
+ completions["clear"] = "Clear history"
60
+
61
+ completions.keep_if do |item, desc|
62
+ !included.include?(item)
46
63
  end
47
64
 
48
- if (input.empty? || input.end_with?(" "))
49
- puts
50
- completions.sort.each do |index|
51
- puts "#{index}:\t#{history[index]}"
65
+ if (last && !last.empty?)
66
+ completions.keep_if do |item, desc|
67
+ item.downcase.start_with?(last.downcase)
52
68
  end
53
- return input
54
69
  end
55
70
 
56
- return "#{input} "
71
+ return [completions, last, " "]
57
72
  end
58
73
 
59
74
  def usage
60
75
  puts "history [option]"
61
- puts "\t#{description}."
62
- puts "\tOPTIONS"
63
- puts "\t\t[0-9]+\tExecute command from history"
64
- puts "\t\tclear\tClear history"
76
+ puts " #{description}."
77
+ puts " OPTIONS"
78
+ puts " [0-9]+ Execute command from history"
79
+ puts " clear Clear history"
65
80
  end
66
81
  end
@@ -1,6 +1,6 @@
1
1
  class Djinni::Wish::Quit < Djinni::Wish
2
2
  def aliases
3
- return [ "bye", "exit", "q", "quit" ]
3
+ return ["bye", "exit", "q", "quit"]
4
4
  end
5
5
 
6
6
  def description
@@ -13,6 +13,6 @@ class Djinni::Wish::Quit < Djinni::Wish
13
13
 
14
14
  def usage
15
15
  puts aliases.join(", ")
16
- puts "\t#{description}."
16
+ puts " #{description}."
17
17
  end
18
18
  end
data/lib/djinni/wish.rb CHANGED
@@ -21,7 +21,7 @@ class Djinni::Wish
21
21
  end
22
22
 
23
23
  def tab_complete(input, djinni_env = {})
24
- return input
24
+ return [{}, "", ""]
25
25
  end
26
26
 
27
27
  def usage
data/lib/djinni.rb CHANGED
@@ -27,47 +27,120 @@ class Djinni
27
27
  name, args = input.split(" ", 2)
28
28
  return input if (!@wishes.has_key?(name))
29
29
 
30
- wish = @wishes[name]
31
- complete = ""
32
30
  begin
33
- djinni_env["djinni_input"] = input
34
- complete = wish.tab_complete(args, djinni_env)
31
+ wish = @wishes[name]
32
+ djinni_env["djinni_input"] = name
33
+ completions, replace, append = wish.tab_complete(
34
+ args,
35
+ djinni_env
36
+ )
35
37
  rescue SystemExit => e
36
38
  raise e
37
39
  rescue Exception => e
38
40
  puts
39
41
  puts e.message
42
+ ensure
43
+ append ||= " "
44
+ completions ||= Hash.new
45
+ replace ||= ""
40
46
  end
41
- return "#{name} #{complete}"
47
+
48
+ return input if (completions.empty?)
49
+
50
+ if (completions.length == 1)
51
+ return input.gsub(
52
+ /#{replace}$/,
53
+ "#{completions.first.first}#{append}"
54
+ )
55
+ end
56
+
57
+ puts
58
+ max = completions.keys.max_by(&:length).length
59
+ completions.each do |item, desc|
60
+ fill = Array.new(max + 4 - item.length, " ").join
61
+ nlfill = Array.new(max + 4, " ").join
62
+ lines = desc.word_wrap(80 - (max + 4)).split("\n")
63
+
64
+ if (lines.empty?)
65
+ puts "#{item}"
66
+ else
67
+ start = lines.delete_at(0)
68
+ puts "#{item}#{fill}#{start}"
69
+ lines.each do |line|
70
+ puts "#{nlfill}#{line}"
71
+ end
72
+ end
73
+ end
74
+
75
+ return input.gsub(
76
+ /#{replace}$/,
77
+ longest_common_substring(completions.keys)
78
+ )
42
79
  else
43
- wishes = @wishes.keys
44
- wishes.sort.each do |wish|
45
- if (wish.start_with?(input))
46
- return "#{wish} "
80
+ wishes = @wishes.select do |aliaz, w|
81
+ aliaz.start_with?(input)
82
+ end
83
+
84
+ return input if (wishes.empty?)
85
+
86
+ if (wishes.length == 1)
87
+ return "#{wishes.first.first} "
88
+ end
89
+
90
+ puts
91
+ max = wishes.keys.max_by(&:length).length
92
+ wishes.sort do |a, b|
93
+ a.first.downcase <=> b.first.downcase
94
+ end.each do |aliaz, w|
95
+ fill = Array.new(max + 4 - aliaz.length, " ").join
96
+ nlfill = Array.new(max + 4, " ").join
97
+ lines = w.description.word_wrap(
98
+ 80 - (max + 4)
99
+ ).split("\n")
100
+
101
+ if (lines.empty?)
102
+ puts "#{aliaz}"
103
+ else
104
+ start = lines.delete_at(0)
105
+ puts "#{aliaz}#{fill}#{start}"
106
+ lines.each do |line|
107
+ puts "#{nlfill}#{line}"
108
+ end
47
109
  end
48
110
  end
49
- return input
111
+
112
+ return longest_common_substring(wishes.keys)
50
113
  end
51
114
  when /\r|\n/ # Enter
52
115
  input.strip!
53
116
  puts if (@interactive)
54
117
  return "" if (input.empty?)
55
118
 
119
+ # "".split(" ", 2) => [] aka [nil, nil]
120
+ # " ".split(" ", 2) => [""] aka ["", nil]
121
+ # The above 2 would return before getting here
122
+ # "string".split(" ", 2) => ["string"] aka ["string", nil]
123
+ # "string ".split(" ", 2) => ["string", ""]
56
124
  name, args = input.split(" ", 2)
125
+ args ||= ""
57
126
 
58
- @wishes.sort.map do |aliaz, wish|
59
- if (aliaz == name)
60
- begin
61
- djinni_env["djinni_input"] = input
62
- wish.execute(args, djinni_env)
63
- rescue SystemExit => e
64
- raise e
65
- rescue Exception => e
66
- puts e.message
67
- end
127
+ @wishes.select do |aliaz, w|
128
+ aliaz == name
129
+ end.each do |aliaz, w|
130
+ begin
131
+ djinni_env["djinni_input"] = name
132
+ w.execute(args, djinni_env)
133
+ rescue SystemExit => e
134
+ raise e
135
+ rescue Exception => e
136
+ puts e.message
137
+ end
138
+
139
+ if (w.class.to_s != "Djinni::Wish::History")
68
140
  store_history(input)
69
- return ""
70
141
  end
142
+
143
+ return ""
71
144
  end
72
145
  store_history(input)
73
146
  return nil
@@ -140,6 +213,20 @@ class Djinni
140
213
  @loaded_from.push(dir)
141
214
  end
142
215
 
216
+ def longest_common_substring(array)
217
+ compare = array.min_by(&:length)
218
+ loop do
219
+ break if (compare.empty?)
220
+ all = array.all? do |item|
221
+ item.downcase.start_with?(compare.downcase)
222
+ end
223
+ compare = compare[0..-2] if (!all)
224
+ break if (all)
225
+ end
226
+ return compare
227
+ end
228
+ private :longest_common_substring
229
+
143
230
  def prompt(djinni_env = {}, djinni_prompt = "$ ")
144
231
  @interactive = true
145
232
 
data/lib/string.rb ADDED
@@ -0,0 +1,12 @@
1
+ # Modify String class to allow for rsplit and word wrap
2
+ class String
3
+ def rsplit(pattern)
4
+ ret = rpartition(pattern)
5
+ ret.delete_at(1)
6
+ return ret
7
+ end
8
+
9
+ def word_wrap(width = 80)
10
+ return scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/).join("\n")
11
+ end
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: djinni
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Whittaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-21 00:00:00.000000000 Z
11
+ date: 2016-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -106,6 +106,7 @@ files:
106
106
  - lib/djinni/wish/help.rb
107
107
  - lib/djinni/wish/history.rb
108
108
  - lib/djinni/wish/quit.rb
109
+ - lib/string.rb
109
110
  homepage: https://mjwhitta.github.io/djinni
110
111
  licenses:
111
112
  - GPL-3.0