yap-shell 0.3.1 → 0.4.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/Gemfile +1 -1
- data/addons/history/README.md +16 -0
- data/addons/history/history.rb +31 -77
- data/addons/keyboard_macros/keyboard_macros.rb +115 -43
- data/addons/keyboard_macros/lib/keyboard_macros/cycle.rb +38 -0
- data/addons/prompt_updates/prompt_updates.rb +1 -1
- data/addons/tab_completion/lib/tab_completion/basic_completion.rb +151 -0
- data/addons/tab_completion/tab_completion.rb +11 -7
- data/bin/yap +1 -12
- data/bin/yap-dev +12 -0
- data/lib/yap/configuration.rb +33 -0
- data/lib/yap/shell/aliases.rb +5 -1
- data/lib/yap/shell/builtins/alias.rb +2 -1
- data/lib/yap/shell/builtins.rb +2 -2
- data/lib/yap/shell/commands.rb +4 -4
- data/lib/yap/shell/evaluation.rb +22 -11
- data/lib/yap/shell/execution/builtin_command_execution.rb +2 -2
- data/lib/yap/shell/execution/file_system_command_execution.rb +2 -1
- data/lib/yap/shell/execution.rb +8 -8
- data/lib/yap/shell/repl.rb +13 -2
- data/lib/yap/shell/version.rb +1 -1
- data/lib/yap/shell.rb +3 -2
- data/lib/yap/world.rb +30 -5
- data/lib/yap.rb +9 -7
- data/rcfiles/.yaprc +42 -10
- data/yap-shell.gemspec +44 -4
- metadata +27 -51
- data/addons/history/Gemfile +0 -2
- data/addons/history/lib/history/buffer.rb +0 -204
- data/addons/history/lib/history/events.rb +0 -13
- data/addons/tab_completion/lib/tab_completion/file_completion.rb +0 -75
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yap-shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Dennis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yap-shell-parser
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.5.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.5.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: term-ansicolor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,40 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.1.1
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: activesupport
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '4.2'
|
76
|
-
- - ">="
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version: 4.2.4
|
79
|
-
type: :runtime
|
80
|
-
prerelease: false
|
81
|
-
version_requirements: !ruby/object:Gem::Requirement
|
82
|
-
requirements:
|
83
|
-
- - "~>"
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '4.2'
|
86
|
-
- - ">="
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: 4.2.4
|
89
69
|
- !ruby/object:Gem::Dependency
|
90
70
|
name: yap-rawline
|
91
71
|
requirement: !ruby/object:Gem::Requirement
|
92
72
|
requirements:
|
93
73
|
- - "~>"
|
94
74
|
- !ruby/object:Gem::Version
|
95
|
-
version: 0.
|
75
|
+
version: 0.3.1
|
96
76
|
type: :runtime
|
97
77
|
prerelease: false
|
98
78
|
version_requirements: !ruby/object:Gem::Requirement
|
99
79
|
requirements:
|
100
80
|
- - "~>"
|
101
81
|
- !ruby/object:Gem::Version
|
102
|
-
version: 0.
|
82
|
+
version: 0.3.1
|
103
83
|
- !ruby/object:Gem::Dependency
|
104
84
|
name: bundler
|
105
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,26 +108,6 @@ dependencies:
|
|
128
108
|
- - "~>"
|
129
109
|
- !ruby/object:Gem::Version
|
130
110
|
version: '10'
|
131
|
-
- !ruby/object:Gem::Dependency
|
132
|
-
name: pry-byebug
|
133
|
-
requirement: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - "~>"
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: '3.3'
|
138
|
-
- - ">="
|
139
|
-
- !ruby/object:Gem::Version
|
140
|
-
version: 3.3.0
|
141
|
-
type: :development
|
142
|
-
prerelease: false
|
143
|
-
version_requirements: !ruby/object:Gem::Requirement
|
144
|
-
requirements:
|
145
|
-
- - "~>"
|
146
|
-
- !ruby/object:Gem::Version
|
147
|
-
version: '3.3'
|
148
|
-
- - ">="
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
version: 3.3.0
|
151
111
|
- !ruby/object:Gem::Dependency
|
152
112
|
name: chronic
|
153
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,6 +127,7 @@ email:
|
|
167
127
|
- zach.dennis@gmail.com
|
168
128
|
executables:
|
169
129
|
- yap
|
130
|
+
- yap-dev
|
170
131
|
extensions: []
|
171
132
|
extra_rdoc_files: []
|
172
133
|
files:
|
@@ -178,24 +139,25 @@ files:
|
|
178
139
|
- README.md
|
179
140
|
- Rakefile
|
180
141
|
- WISHLIST.md
|
181
|
-
- addons/history/
|
142
|
+
- addons/history/README.md
|
182
143
|
- addons/history/history.rb
|
183
|
-
- addons/history/lib/history/buffer.rb
|
184
|
-
- addons/history/lib/history/events.rb
|
185
144
|
- addons/keyboard_macros/keyboard_macros.rb
|
145
|
+
- addons/keyboard_macros/lib/keyboard_macros/cycle.rb
|
186
146
|
- addons/prompt/Gemfile
|
187
147
|
- addons/prompt/right_prompt.rb
|
188
148
|
- addons/prompt_updates/prompt_updates.rb
|
189
149
|
- addons/tab_completion/Gemfile
|
150
|
+
- addons/tab_completion/lib/tab_completion/basic_completion.rb
|
190
151
|
- addons/tab_completion/lib/tab_completion/completer.rb
|
191
152
|
- addons/tab_completion/lib/tab_completion/custom_completion.rb
|
192
153
|
- addons/tab_completion/lib/tab_completion/dsl_methods.rb
|
193
|
-
- addons/tab_completion/lib/tab_completion/file_completion.rb
|
194
154
|
- addons/tab_completion/tab_completion.rb
|
195
155
|
- bin/yap
|
156
|
+
- bin/yap-dev
|
196
157
|
- lib/tasks/addons.rake
|
197
158
|
- lib/tasks/gem.rake
|
198
159
|
- lib/yap.rb
|
160
|
+
- lib/yap/configuration.rb
|
199
161
|
- lib/yap/shell.rb
|
200
162
|
- lib/yap/shell/aliases.rb
|
201
163
|
- lib/yap/shell/builtins.rb
|
@@ -236,7 +198,21 @@ homepage: https://github.com/zdennis/yap-shell
|
|
236
198
|
licenses:
|
237
199
|
- MIT
|
238
200
|
metadata: {}
|
239
|
-
post_install_message:
|
201
|
+
post_install_message: "\nGreetings forward-thinking traveler!\n\nLet's waste no time
|
202
|
+
and get right to it.\n\n\e[033mFirstly\e[0m, thank you for installing the yap shell!\n\n\e[033mSecondly\e[0m,
|
203
|
+
this is my beta's beta. Yap has many cool ideas. I dare\nsay some of those made
|
204
|
+
it into this very release.\n\n\e[033mLastly\e[0m, create an alias to the yap executable
|
205
|
+
using the ruby version\nyou just installed it for. For example, with rbenv I use
|
206
|
+
the below\nalias in my ~/.profile file:\n\n alias yap='~/.rbenv/versions/2.2.3/bin/ruby
|
207
|
+
~/.rbenv/shims/yap'\n\nThen, `source ~/.profile` or reload your shell. Now you can
|
208
|
+
finally run:\n\n yap\n\nYou know your tooling better than me. If you need things
|
209
|
+
to go a little\ndifferently than above you go right ahead. If any questions arise
|
210
|
+
don't\nhesitate to holler over at Github. I may not always be home, but there will\nalways
|
211
|
+
be a cozy textarea with dozens of emoji friends waiting to hear your\nthoughts.
|
212
|
+
All day. All night.\n\nUntil the next update: Happy coding!\n\nSincerely,\n\n \e[51mThe
|
213
|
+
Lagniappe (Yap) Shell\e[0m\n\n\e[033mP.S.\e[0m If you have ideas for loading other
|
214
|
+
than the hard-coded\nalias, do tell, right over here:\n\n \e[1mhttp://github.com/zdennis/yap-shell/issues\e[0m\n\n\e[033mP.P.S.\e[0m
|
215
|
+
OSX support? YES! Linux? I assume YES! Windows? Um...\n\n"
|
240
216
|
rdoc_options: []
|
241
217
|
require_paths:
|
242
218
|
- lib
|
data/addons/history/Gemfile
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
class History
|
2
|
-
class Buffer < Array
|
3
|
-
attr_reader :position, :size
|
4
|
-
attr_accessor :duplicates, :exclude, :cycle
|
5
|
-
|
6
|
-
#
|
7
|
-
# Create an instance of History::Buffer.
|
8
|
-
# This method takes an optional block used to override the
|
9
|
-
# following instance attributes:
|
10
|
-
# * <tt>@duplicates</tt> - whether or not duplicate items will be stored in the buffer.
|
11
|
-
# * <tt>@exclude</tt> - a Proc object defining exclusion rules to prevent items from being added to the buffer.
|
12
|
-
# * <tt>@cycle</tt> - Whether or not the buffer is cyclic.
|
13
|
-
#
|
14
|
-
def initialize(size)
|
15
|
-
@duplicates = true
|
16
|
-
@exclude = lambda{|a|}
|
17
|
-
@cycle = false
|
18
|
-
yield self if block_given?
|
19
|
-
@size = size
|
20
|
-
@position = nil
|
21
|
-
end
|
22
|
-
|
23
|
-
def supports_partial_text_matching?
|
24
|
-
true
|
25
|
-
end
|
26
|
-
|
27
|
-
def supports_matching_text?
|
28
|
-
true
|
29
|
-
end
|
30
|
-
|
31
|
-
#
|
32
|
-
# Clears the current position on the history object. Useful when deciding
|
33
|
-
# to cancel/reset history navigation.
|
34
|
-
#
|
35
|
-
def clear_position
|
36
|
-
@position = nil
|
37
|
-
end
|
38
|
-
|
39
|
-
def searching?
|
40
|
-
!!@position
|
41
|
-
end
|
42
|
-
|
43
|
-
#
|
44
|
-
# Resize the buffer, resetting <tt>@position</tt> to nil.
|
45
|
-
#
|
46
|
-
def resize(new_size)
|
47
|
-
if new_size < @size
|
48
|
-
@size-new_size.times { pop }
|
49
|
-
end
|
50
|
-
@size = new_size
|
51
|
-
@position = nil
|
52
|
-
end
|
53
|
-
|
54
|
-
#
|
55
|
-
# Clear the content of the buffer and reset <tt>@position</tt> to nil.
|
56
|
-
#
|
57
|
-
def empty
|
58
|
-
@position = nil
|
59
|
-
clear
|
60
|
-
end
|
61
|
-
|
62
|
-
#
|
63
|
-
# Retrieve a copy of the element at <tt>@position</tt>.
|
64
|
-
#
|
65
|
-
def get
|
66
|
-
return nil unless length > 0
|
67
|
-
return nil unless @position
|
68
|
-
at(@position).dup
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
# Return true if <tt>@position</tt> is at the end of the buffer.
|
73
|
-
#
|
74
|
-
def end?
|
75
|
-
@position == length-1
|
76
|
-
end
|
77
|
-
|
78
|
-
#
|
79
|
-
# Return true if <tt>@position</tt> is at the start of the buffer.
|
80
|
-
#
|
81
|
-
def start?
|
82
|
-
@position == 0
|
83
|
-
end
|
84
|
-
|
85
|
-
#
|
86
|
-
# Decrement <tt>@position</tt>. By default the history will become
|
87
|
-
# positioned at the previous item.
|
88
|
-
#
|
89
|
-
def back(matching_text: nil)
|
90
|
-
return nil unless length > 0
|
91
|
-
@position = search_back(matching_text: matching_text) || @position
|
92
|
-
end
|
93
|
-
|
94
|
-
#
|
95
|
-
# Increment <tt>@position</tt>. By default the history will become
|
96
|
-
# positioned at the next item.
|
97
|
-
#
|
98
|
-
def forward(matching_text: nil)
|
99
|
-
return nil unless length > 0
|
100
|
-
@position = search_forward(matching_text: matching_text) || @position
|
101
|
-
end
|
102
|
-
|
103
|
-
#
|
104
|
-
# Add a new item to the buffer.
|
105
|
-
#
|
106
|
-
def push(item)
|
107
|
-
item = item.without_ansi if item.respond_to?(:without_ansi)
|
108
|
-
|
109
|
-
if !@duplicates && self[-1] == item
|
110
|
-
# skip adding this line
|
111
|
-
return
|
112
|
-
end
|
113
|
-
|
114
|
-
unless @exclude.call(item)
|
115
|
-
# Remove the oldest element if size is exceeded
|
116
|
-
if @size <= length
|
117
|
-
reverse!.pop
|
118
|
-
reverse!
|
119
|
-
end
|
120
|
-
# Add the new item and reset the position
|
121
|
-
super(item)
|
122
|
-
@position = nil
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
alias << push
|
127
|
-
|
128
|
-
def to_yaml(range=(0..-1))
|
129
|
-
self[range].map do |element|
|
130
|
-
element.kind_of?(String) ? element : element.to_h
|
131
|
-
end.to_yaml
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def search_back(matching_text:)
|
137
|
-
if !matching_text
|
138
|
-
matching_text = ""
|
139
|
-
elsif matching_text.respond_to?(:without_ansi)
|
140
|
-
matching_text = matching_text.without_ansi
|
141
|
-
end
|
142
|
-
|
143
|
-
command_history = self
|
144
|
-
upto_index = (position || length) - 1
|
145
|
-
current = get
|
146
|
-
|
147
|
-
# $z.puts
|
148
|
-
# $z.puts <<-EOS.gsub(/^\s*\|/, '')
|
149
|
-
# |Search backward:
|
150
|
-
# | current:#{current.inspect}
|
151
|
-
# | history: #{command_history.inspect}
|
152
|
-
# | history position: #{position}
|
153
|
-
# | matching_text: #{matching_text.inspect}
|
154
|
-
# | upto_index: #{upto_index}
|
155
|
-
# | snapshot: #{command_history[0..upto_index].reverse.inspect}
|
156
|
-
# EOS
|
157
|
-
|
158
|
-
return position unless upto_index >= 0
|
159
|
-
|
160
|
-
snapshot = command_history[0..upto_index].reverse
|
161
|
-
no_match = nil
|
162
|
-
|
163
|
-
position = snapshot.each_with_index.reduce(no_match) do |no_match, (text, i)|
|
164
|
-
# $z.print " - matching #{text.inspect} =~ /^#{matching_text.to_s}/ && #{current} != #{text} : "
|
165
|
-
if text =~ /^#{Regexp.escape(matching_text)}/ && current != text
|
166
|
-
# $z.puts " match #{i}, returning position #{snapshot.length - (i + 1)}"
|
167
|
-
|
168
|
-
# convert to non-reversed indexing
|
169
|
-
position = snapshot.length - (i + 1)
|
170
|
-
break position
|
171
|
-
else
|
172
|
-
# $z.puts " no match."
|
173
|
-
no_match
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def search_forward(matching_text:)
|
179
|
-
if !matching_text
|
180
|
-
matching_text = ""
|
181
|
-
elsif matching_text.respond_to?(:without_ansi)
|
182
|
-
matching_text = matching_text.without_ansi
|
183
|
-
end
|
184
|
-
|
185
|
-
command_history = self
|
186
|
-
return nil unless position
|
187
|
-
|
188
|
-
start_index = position + 1
|
189
|
-
snapshot = command_history[start_index..-1].dup
|
190
|
-
no_match = nil
|
191
|
-
current = get
|
192
|
-
|
193
|
-
position = snapshot.each_with_index.reduce(no_match) do |no_match, (text, i)|
|
194
|
-
if text =~ /^#{Regexp.escape(matching_text.to_s)}/ && current != text
|
195
|
-
position = start_index + i
|
196
|
-
break position
|
197
|
-
else
|
198
|
-
no_match
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
Yap::Shell::Execution::Context.on(:before_statements_execute) do |world|
|
2
|
-
end
|
3
|
-
|
4
|
-
Yap::Shell::Execution::Context.on(:after_statements_execute) do |world|
|
5
|
-
end
|
6
|
-
|
7
|
-
Yap::Shell::Execution::Context.on(:before_execute) do |world, command:|
|
8
|
-
# world[:history].executing command:command.str, started_at:Time.now
|
9
|
-
end
|
10
|
-
|
11
|
-
Yap::Shell::Execution::Context.on(:after_execute) do |world, command:, result:|
|
12
|
-
# world[:history].executed command:command.str, stopped_at:Time.now
|
13
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
class TabCompletion
|
2
|
-
class FileCompletion
|
3
|
-
class << self
|
4
|
-
attr_accessor :priority
|
5
|
-
end
|
6
|
-
self.priority = 1
|
7
|
-
|
8
|
-
attr_reader :world
|
9
|
-
|
10
|
-
def initialize(world:, word_break_characters:, path:nil)
|
11
|
-
@world = world
|
12
|
-
@word_break_characters = word_break_characters
|
13
|
-
path ||= @world.env["PATH"]
|
14
|
-
@paths = path.split(":")
|
15
|
-
end
|
16
|
-
|
17
|
-
def completions_for(word, line)
|
18
|
-
completions = []
|
19
|
-
if looking_for_command?
|
20
|
-
completions.concat command_completion_matches_for(word, line)
|
21
|
-
end
|
22
|
-
completions.concat filename_completion_matches_for(word, line)
|
23
|
-
completions
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def looking_for_command?
|
29
|
-
# TODO
|
30
|
-
false
|
31
|
-
end
|
32
|
-
|
33
|
-
def command_completion_matches_for(word, line)
|
34
|
-
matches = @paths.inject([]) do |matches, path|
|
35
|
-
glob = "#{path}*"
|
36
|
-
arr = Dir[glob].select { |path| File.executable?(path) && File.file?(path) }
|
37
|
-
arr.each { |path| matches << path }
|
38
|
-
matches
|
39
|
-
end
|
40
|
-
|
41
|
-
matches.map { |path| File.basename(path) }.sort.uniq.map do |command|
|
42
|
-
CompletionResult.new(type: :command, text:command)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def filename_completion_matches_for(word, line)
|
47
|
-
glob = "#{word}*"
|
48
|
-
glob.gsub!("~", world.env["HOME"])
|
49
|
-
Dir.glob(glob, File::FNM_CASEFOLD).map do |path|
|
50
|
-
text = path.gsub(filtered_work_break_characters_rgx, '\\\\\1')
|
51
|
-
descriptive_text = File.basename(text)
|
52
|
-
if File.directory?(path)
|
53
|
-
CompletionResult.new(type: :directory, text: text, descriptive_text: descriptive_text)
|
54
|
-
elsif File.symlink?(path)
|
55
|
-
CompletionResult.new(type: :symlink, text: text, descriptive_text: descriptive_text)
|
56
|
-
elsif File.file?(path) && File.executable?(path)
|
57
|
-
CompletionResult.new(type: :command, text: text, descriptive_text: descriptive_text)
|
58
|
-
else
|
59
|
-
CompletionResult.new(type: :file, text: text, descriptive_text: descriptive_text)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Remove file separator and the back-slash from word break characters when determining
|
65
|
-
# the pre-word-context
|
66
|
-
def filtered_word_break_characters
|
67
|
-
@word_break_characters.sub(File::Separator, "").sub('\\', '')
|
68
|
-
end
|
69
|
-
|
70
|
-
def filtered_work_break_characters_rgx
|
71
|
-
/([#{Regexp.escape(filtered_word_break_characters)}])/
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|