djinni 1.3.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/djinni/wish/clear.rb +4 -7
- data/lib/djinni/wish/help.rb +29 -24
- data/lib/djinni/wish/history.rb +47 -32
- data/lib/djinni/wish/quit.rb +2 -2
- data/lib/djinni/wish.rb +1 -1
- data/lib/djinni.rb +108 -21
- data/lib/string.rb +12 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0c26461a62d30afb00ae7a1cb72b76f0ef55b9e
|
4
|
+
data.tar.gz: 7dbdea06e28da92e6511031b88a3d286c7eb2481
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc6041f1be04c2b4644eb3efea8dd137d207a843ab10aa65aa98b8e3d4dfc2e13df984056eaa4a59d76a692907a0ca87928378128aaf219fb98214db6b9b23e4
|
7
|
+
data.tar.gz: dcc88eb053727c0f5e4b4a2d28b40c76a5bc3df4779fac764a7b9e1c606d916a9d3f306e2bf4ad1f19371aff71ab0101b0834c82e7dbda018a8cc6e6ce39df40
|
data/lib/djinni/wish/clear.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Djinni::Wish::Clear < Djinni::Wish
|
2
2
|
def aliases
|
3
|
-
return [
|
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.
|
12
|
-
|
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 "
|
17
|
+
puts " #{description}."
|
21
18
|
end
|
22
19
|
end
|
data/lib/djinni/wish/help.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Djinni::Wish::Help < Djinni::Wish
|
2
2
|
def aliases
|
3
|
-
return [
|
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"]
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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.
|
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
|
-
|
45
|
-
|
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 "
|
51
|
-
puts "
|
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
|
data/lib/djinni/wish/history.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require "string"
|
2
|
+
|
1
3
|
class Djinni::Wish::History < Djinni::Wish
|
2
4
|
def aliases
|
3
|
-
return [
|
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
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
25
|
-
|
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
|
-
|
45
|
-
|
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 (
|
49
|
-
|
50
|
-
|
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 "
|
71
|
+
return [completions, last, " "]
|
57
72
|
end
|
58
73
|
|
59
74
|
def usage
|
60
75
|
puts "history [option]"
|
61
|
-
puts "
|
62
|
-
puts "
|
63
|
-
puts "
|
64
|
-
puts "
|
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
|
data/lib/djinni/wish/quit.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Djinni::Wish::Quit < Djinni::Wish
|
2
2
|
def aliases
|
3
|
-
return [
|
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 "
|
16
|
+
puts " #{description}."
|
17
17
|
end
|
18
18
|
end
|
data/lib/djinni/wish.rb
CHANGED
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
|
-
|
34
|
-
|
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
|
-
|
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.
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
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.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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:
|
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-
|
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
|