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 +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
|