yap-shell 0.4.11 → 0.5.1
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 +3 -2
- data/addons/history_search/history_search.rb +193 -0
- data/addons/keyboard_macros/keyboard_macros.rb +3 -3
- data/addons/prompt/right_prompt.rb +9 -7
- data/addons/prompt_updates/prompt_updates.rb +25 -24
- data/bin/yap +22 -15
- data/lib/tasks/addons.rake +46 -0
- data/lib/yap/shell/evaluation.rb +1 -0
- data/lib/yap/shell/execution/file_system_command_execution.rb +10 -0
- data/lib/yap/shell/execution/shell_command_execution.rb +5 -3
- data/lib/yap/shell/repl.rb +0 -1
- data/lib/yap/shell/version.rb +1 -1
- data/lib/yap/world/addons.rb +2 -2
- data/lib/yap/world.rb +14 -1
- data/rcfiles/yaprc +4 -0
- data/yap-shell.gemspec +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dd93a58914bed99609652e05c82c3f90fb11af3
|
4
|
+
data.tar.gz: 685276b3f2f829e8252c82490c30cb443bde61b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 580220fe950fbc8cb393f1b783315a2af677177907951851b0d9c44ef7d9e7dd05f6dc0fea2aec3b436e2f187d0e27ca96a3b28449781c99a92689d405b90108
|
7
|
+
data.tar.gz: d037e820050e596a596891133b1bf18736ea9953850978d736505f6f32eee67e1b6e017d529a2dd9860ca69373b7b4006faa09aa953c18fd72816a4d80b4265e
|
data/Gemfile
CHANGED
@@ -2,7 +2,8 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in yap.gemspec
|
4
4
|
gemspec
|
5
|
+
# gem 'terminal-layout', path: "../terminal-layout"
|
5
6
|
# gem 'yap-shell-parser', path: "../yap-shell-parser"
|
6
7
|
# gem 'yap-shell-parser', git: 'git@github.com:zdennis/yap-shell-parser.git'
|
7
|
-
# gem "rawline",
|
8
|
-
# gem "
|
8
|
+
# gem "yap-rawline", path: '/Users/zdennis/source/opensource_projects/rawline'
|
9
|
+
# gem "terminal-layout", path: '/Users/zdennis/source/playground/terminal-layout'
|
@@ -0,0 +1,193 @@
|
|
1
|
+
class HistorySearch < Addon
|
2
|
+
attr_reader :editor
|
3
|
+
|
4
|
+
def initialize_world(world)
|
5
|
+
@editor = world.editor
|
6
|
+
end
|
7
|
+
|
8
|
+
def prompt_user_to_search
|
9
|
+
label_text = "(reverse-search): "
|
10
|
+
search_label = ::TerminalLayout::Box.new(
|
11
|
+
content: label_text,
|
12
|
+
style: {
|
13
|
+
display: :inline,
|
14
|
+
height: 1
|
15
|
+
}
|
16
|
+
)
|
17
|
+
search_box = ::TerminalLayout::InputBox.new(
|
18
|
+
content: "",
|
19
|
+
style: {
|
20
|
+
display: :inline,
|
21
|
+
height: 1
|
22
|
+
}
|
23
|
+
)
|
24
|
+
search_box.name = "focused-input-box"
|
25
|
+
|
26
|
+
Treefell['shell'].puts "editor.content_box.children: #{editor.content_box.children.inspect}"
|
27
|
+
history_search_env = editor.new_env
|
28
|
+
history_search = Search.new(editor.history,
|
29
|
+
line: ::RawLine::LineEditor.new(::RawLine::Line.new, sync_with: -> { search_box }),
|
30
|
+
keys: history_search_env.keys,
|
31
|
+
search: -> (term:, result:){
|
32
|
+
# when there is no match, result will be nil, #to_s clears out the content
|
33
|
+
editor.input_box.content = result.to_s
|
34
|
+
},
|
35
|
+
done: -> (execute:, result:){
|
36
|
+
editor.content_box.children = []
|
37
|
+
editor.pop_env
|
38
|
+
editor.focus_input_box(editor.input_box)
|
39
|
+
editor.overwrite_line(result.to_s)
|
40
|
+
editor.process_line if execute
|
41
|
+
}
|
42
|
+
)
|
43
|
+
|
44
|
+
editor.push_env history_search_env
|
45
|
+
editor.push_keyboard_input_processor(history_search)
|
46
|
+
|
47
|
+
editor.content_box.children = [search_label, search_box]
|
48
|
+
editor.focus_input_box(search_box)
|
49
|
+
end
|
50
|
+
|
51
|
+
class Search
|
52
|
+
attr_reader :keys
|
53
|
+
|
54
|
+
def initialize(history, keys:, line:, search:, done:)
|
55
|
+
@history = history
|
56
|
+
@keys = keys
|
57
|
+
@line = line
|
58
|
+
@search_proc = search || -> {}
|
59
|
+
@done_proc = done || -> {}
|
60
|
+
|
61
|
+
initialize_key_bindings
|
62
|
+
end
|
63
|
+
|
64
|
+
def initialize_key_bindings
|
65
|
+
@keys.bind(:return){ execute }
|
66
|
+
@keys.bind(:ctrl_j){ accept }
|
67
|
+
@keys.bind(:ctrl_r){ search_again_backward }
|
68
|
+
@keys.bind(:ctrl_n){ search_again_forward }
|
69
|
+
@keys.bind(:ctrl_a){ @line.move_to_beginning_of_input }
|
70
|
+
@keys.bind(:ctrl_e){ @line.move_to_end_of_input }
|
71
|
+
@keys.bind(:backspace) do
|
72
|
+
@line.delete_left_character
|
73
|
+
perform_search(type: @last_search_was)
|
74
|
+
end
|
75
|
+
@keys.bind(:escape){ cancel }
|
76
|
+
@keys.bind(:ctrl_c){ cancel }
|
77
|
+
end
|
78
|
+
|
79
|
+
def read_bytes(bytes)
|
80
|
+
if bytes.any?
|
81
|
+
Treefell['shell'].puts "history search found bytes: #{bytes.inspect}"
|
82
|
+
|
83
|
+
# [1,2,3] => try 1,2,3 first ,then 1,2, then 1, then move on
|
84
|
+
nbytes = bytes.dup
|
85
|
+
search_bytes = []
|
86
|
+
loop do
|
87
|
+
if nbytes.empty?
|
88
|
+
break
|
89
|
+
elsif @keys[nbytes]
|
90
|
+
Treefell['shell'].puts "history search found key-binding for bytes=#{nbytes.inspect}"
|
91
|
+
@keys[nbytes].call
|
92
|
+
nbytes = search_bytes
|
93
|
+
search_bytes = []
|
94
|
+
else
|
95
|
+
search_bytes.unshift nbytes[-1]
|
96
|
+
nbytes = nbytes[0..-2]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
if search_bytes.any?
|
101
|
+
Treefell['shell'].puts "history searching with bytes=#{bytes.inspect}"
|
102
|
+
search_with_bytes(bytes)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def accept
|
110
|
+
@done_proc.call(execute: false, result: result)
|
111
|
+
end
|
112
|
+
|
113
|
+
def cancel
|
114
|
+
@done_proc.call(execute: false, result: result)
|
115
|
+
end
|
116
|
+
|
117
|
+
def execute
|
118
|
+
@done_proc.call(execute: true, result: result)
|
119
|
+
end
|
120
|
+
|
121
|
+
def found_match(result:)
|
122
|
+
@search_proc.call(term: @line.text, result: result)
|
123
|
+
end
|
124
|
+
|
125
|
+
def no_match_found
|
126
|
+
@last_match_index = nil
|
127
|
+
@search_proc.call(term: @line.text, result: result)
|
128
|
+
end
|
129
|
+
|
130
|
+
def result
|
131
|
+
@history2search[@last_match_index] if @last_match_index
|
132
|
+
end
|
133
|
+
|
134
|
+
def search_again_backward
|
135
|
+
Treefell['shell'].puts "history searching again backward"
|
136
|
+
if @last_search_was == :forward
|
137
|
+
@last_match_index = @history.length - @last_match_index - 1
|
138
|
+
@history2search = @history.reverse
|
139
|
+
end
|
140
|
+
perform_search(starting_index: @last_match_index, type: :backward)
|
141
|
+
end
|
142
|
+
|
143
|
+
def search_again_forward
|
144
|
+
Treefell['shell'].puts "history searching again forward"
|
145
|
+
if @last_search_was == :backward
|
146
|
+
@last_match_index = @history.length - @last_match_index - 1
|
147
|
+
@history2search = @history
|
148
|
+
end
|
149
|
+
perform_search(starting_index: @last_match_index, type: :forward)
|
150
|
+
end
|
151
|
+
|
152
|
+
def search_with_bytes(bytes)
|
153
|
+
part = bytes.map(&:chr).join
|
154
|
+
@line.write(part.scan(/[[:print:]]/).join)
|
155
|
+
@history2search = @history.reverse
|
156
|
+
perform_search(type: :backward)
|
157
|
+
end
|
158
|
+
|
159
|
+
def perform_search(starting_index: -1, type:)
|
160
|
+
if @line.text.empty?
|
161
|
+
no_match_found
|
162
|
+
return
|
163
|
+
end
|
164
|
+
|
165
|
+
# fuzzy search
|
166
|
+
characters = @line.text.split('').map { |ch| Regexp.escape(ch) }
|
167
|
+
fuzzy_search_regex = /#{characters.join('.*?')}/
|
168
|
+
|
169
|
+
# non-fuzzy-search
|
170
|
+
# fuzzy_search_regex = /#{Regexp.escape(@line.text)}/
|
171
|
+
|
172
|
+
Treefell['shell'].puts "history search matching on regex=#{fuzzy_search_regex.inspect} starting_index=#{starting_index}"
|
173
|
+
@last_search_was = type
|
174
|
+
|
175
|
+
match = @history2search.detect.with_index do |item, i|
|
176
|
+
next if i <= starting_index
|
177
|
+
|
178
|
+
# Treefell['shell'].puts "history search matching #{(item + @line.text).inspect} =~ #{fuzzy_search_regex}"
|
179
|
+
md = (item + @line.text).match(fuzzy_search_regex)
|
180
|
+
if md && md.end(0) <= item.length
|
181
|
+
# Treefell['shell'].puts "history search match #{item} at #{i}"
|
182
|
+
@last_match_index = i
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
if match
|
187
|
+
found_match(result: match)
|
188
|
+
else
|
189
|
+
no_match_found
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -89,7 +89,7 @@ class KeyboardMacros < Addon
|
|
89
89
|
configuration.start.call if configuration.start
|
90
90
|
|
91
91
|
debug_log "taking over keyboard input processing from editor"
|
92
|
-
world.editor.
|
92
|
+
world.editor.push_keyboard_input_processor(self)
|
93
93
|
|
94
94
|
wait_timeout_in_seconds = 0.1
|
95
95
|
world.editor.input.wait_timeout_in_seconds = wait_timeout_in_seconds
|
@@ -195,9 +195,9 @@ class KeyboardMacros < Addon
|
|
195
195
|
definition.configuration.stop.call if definition.configuration.stop
|
196
196
|
end
|
197
197
|
@stack.clear
|
198
|
-
if world.editor.
|
198
|
+
if world.editor.keyboard_input_processor == self
|
199
199
|
debug_log "giving keyboard input processing control back"
|
200
|
-
world.editor.
|
200
|
+
world.editor.pop_keyboard_input_processor
|
201
201
|
|
202
202
|
debug_log "restoring default editor input timeout"
|
203
203
|
world.editor.input.restore_default_timeout
|
@@ -6,12 +6,14 @@ class RightPrompt < Addon
|
|
6
6
|
def initialize_world(world)
|
7
7
|
@world = world
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
@world.subscribe(:refresh_right_prompt) do |event|
|
10
|
+
@world.right_prompt_text = Time.now.strftime("%H:%M:%S")
|
11
|
+
end
|
12
|
+
|
13
|
+
@world.events.recur(
|
14
|
+
name: "refresh_right_prompt",
|
15
|
+
interval_in_ms: 1_000,
|
16
|
+
source: self
|
17
|
+
)
|
16
18
|
end
|
17
19
|
end
|
@@ -1,28 +1,29 @@
|
|
1
|
-
class PromptUpdates < Addon
|
2
|
-
attr_reader :world
|
3
|
-
|
4
|
-
def initialize_world(world)
|
5
|
-
current_branch = determine_branch
|
6
|
-
|
7
|
-
@world = world
|
8
|
-
@world.events.recur(
|
9
|
-
name: 'prompt_updates',
|
10
|
-
source: self,
|
11
|
-
interval_in_ms: 100
|
12
|
-
) do
|
13
|
-
new_branch = determine_branch
|
14
|
-
if current_branch != new_branch
|
15
|
-
current_branch = new_branch
|
16
|
-
@world.refresh_prompt
|
17
|
-
end
|
18
|
-
end
|
19
1
|
|
20
|
-
end
|
21
2
|
|
22
|
-
|
3
|
+
class PromptUpdates < Addon
|
4
|
+
def initialize_world(world)
|
5
|
+
@world = world
|
6
|
+
|
7
|
+
current_branch = determine_branch
|
23
8
|
|
24
|
-
|
25
|
-
|
26
|
-
|
9
|
+
@world.events.recur(
|
10
|
+
name: 'prompt_updates',
|
11
|
+
source: self,
|
12
|
+
interval_in_ms: 100
|
13
|
+
) do
|
14
|
+
new_branch = determine_branch
|
15
|
+
if current_branch != new_branch
|
16
|
+
current_branch = new_branch
|
17
|
+
@world.refresh_prompt
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
27
22
|
|
28
|
-
|
23
|
+
private
|
24
|
+
|
25
|
+
def determine_branch
|
26
|
+
`git branch 2>/dev/null`.scan(/\*\s*(.*)$/).flatten.first
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/bin/yap
CHANGED
@@ -1,20 +1,35 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
if ENV[
|
3
|
+
if ENV['YAP_SHELL'] != 'active'
|
4
4
|
# Start YAP with a pristine environment
|
5
5
|
env2keep = {
|
6
|
-
|
6
|
+
# DISPLAY needs to be inherited in order to launch GUI apps
|
7
|
+
'DISPLAY' => ENV['DISPLAY'],
|
7
8
|
'HOME' => ENV['HOME'],
|
9
|
+
'PATH' => ENV['PATH'],
|
10
|
+
|
11
|
+
# For Yap's sanity
|
8
12
|
'RUBYOPT' => '-rubygems -EUTF-8',
|
9
|
-
'
|
13
|
+
'YAP_SHELL' => 'active',
|
14
|
+
|
15
|
+
# Inherit the user's preferred shell
|
16
|
+
'SHELL' => ENV['SHELL'],
|
17
|
+
|
18
|
+
# Necessary for ssh-agent
|
19
|
+
'SSH_AUTH_SOCK' => ENV['SSH_AUTH_SOCK'],
|
20
|
+
|
21
|
+
# DEBUG/TREEFELL_OUT are for debuging yap itself
|
10
22
|
'DEBUG' => ENV['DEBUG'],
|
11
|
-
'
|
23
|
+
'TREEFELL_OUT' => ENV['TREEFELL_OUT']
|
12
24
|
}
|
25
|
+
|
26
|
+
ENV.clear
|
13
27
|
env_params = env2keep.each_with_object([]) do |(key,value),arr|
|
14
28
|
next if value.nil?
|
15
29
|
arr << %|#{key}="#{value}"|
|
16
30
|
end.join(' ')
|
17
|
-
|
31
|
+
|
32
|
+
cmd = %|env -i #{env_params} #{File.expand_path(__FILE__)}|
|
18
33
|
exec cmd
|
19
34
|
else
|
20
35
|
file = __FILE__
|
@@ -30,18 +45,10 @@ else
|
|
30
45
|
$LOAD_PATH.unshift File.dirname(file) + '/../lib'
|
31
46
|
|
32
47
|
ENV['TERM'] ||= 'linux'
|
33
|
-
|
34
|
-
# Delete all RBENV/RVM environment variables
|
35
|
-
# Once we're booted, we don't want them being inherited
|
36
|
-
# by other child processes since those children cannot
|
37
|
-
# modify Yap's ENV, only their own child env.
|
38
|
-
ENV.keys.each do |key|
|
39
|
-
if key =~ /^(rbenv_|rvm_)/i
|
40
|
-
ENV.delete(key)
|
41
|
-
end
|
42
|
-
end
|
48
|
+
ENV['YAP_SHELL'] = 'active'
|
43
49
|
|
44
50
|
require "term/ansicolor"
|
51
|
+
require "tins"
|
45
52
|
require "byebug"
|
46
53
|
require "pry"
|
47
54
|
require "yap"
|
data/lib/tasks/addons.rake
CHANGED
@@ -1,4 +1,50 @@
|
|
1
1
|
namespace :addons do
|
2
|
+
task :new do
|
3
|
+
require 'highline'
|
4
|
+
require 'term/ansicolor'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
extend Term::ANSIColor
|
8
|
+
|
9
|
+
yap_path = Pathname.new(File.dirname(__FILE__)).join('../..')
|
10
|
+
yap_lib_path = yap_path.join('lib')
|
11
|
+
yap_addons_path = yap_path.join('addons')
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift yap_lib_path
|
14
|
+
require 'yap'
|
15
|
+
|
16
|
+
cli = HighLine.new
|
17
|
+
answer = cli.ask("Name for the addon? ")
|
18
|
+
|
19
|
+
addon_name = answer.downcase.gsub(/\W+/, '_')
|
20
|
+
addon_class_name = addon_name.split('_').map(&:capitalize).join
|
21
|
+
addon_path = yap_addons_path.join(addon_name)
|
22
|
+
|
23
|
+
loop do
|
24
|
+
answer = cli.ask("Create #{addon_class_name} addon in #{addon_path}? [Yn] ")
|
25
|
+
break if answer =~ /y/i
|
26
|
+
exit 1 if answer =~ /n/i
|
27
|
+
end
|
28
|
+
puts "Generating #{addon_class_name}"
|
29
|
+
puts
|
30
|
+
|
31
|
+
print " Creating #{addon_path} "
|
32
|
+
FileUtils.mkdir_p addon_path
|
33
|
+
puts green('done')
|
34
|
+
|
35
|
+
addon_file = addon_path.join("#{addon_name}.rb")
|
36
|
+
print " Creating #{addon_file} "
|
37
|
+
File.write addon_file, <<-FILE.gsub(/^\s*\|/, '')
|
38
|
+
|class #{addon_class_name} < Addon
|
39
|
+
| def initialize_world(world)
|
40
|
+
| # initialization code here
|
41
|
+
| end
|
42
|
+
|end
|
43
|
+
FILE
|
44
|
+
puts green('done')
|
45
|
+
puts
|
46
|
+
end
|
47
|
+
|
2
48
|
namespace :update do
|
3
49
|
desc "Update the gemspec based on add-on specific dependnecies"
|
4
50
|
task :gemspec do
|
data/lib/yap/shell/evaluation.rb
CHANGED
@@ -44,6 +44,16 @@ module Yap::Shell::Execution
|
|
44
44
|
begin
|
45
45
|
before = ENV.to_h.dup
|
46
46
|
ENV.replace(@world.env)
|
47
|
+
Treefell['shell'].puts <<-MSG.gsub(/^\s*\|/, '')
|
48
|
+
|forked child process
|
49
|
+
| pid=#{Process.pid} #{command.to_executable_str}
|
50
|
+
| stdin=#{stdin.inspect}
|
51
|
+
| stdout=#{stdout.inspect}
|
52
|
+
| stderr=#{stderr.inspect}
|
53
|
+
| $stdin=#{$stdin.inspect}
|
54
|
+
| $stdout=#{$stdout.inspect}
|
55
|
+
| $stderr=#{$stderr.inspect}
|
56
|
+
MSG
|
47
57
|
Kernel.exec command.to_executable_str
|
48
58
|
ensure
|
49
59
|
ENV.replace(before)
|
@@ -6,7 +6,7 @@ module Yap::Shell::Execution
|
|
6
6
|
possible_parameters = {
|
7
7
|
command: command.str,
|
8
8
|
args: command.args,
|
9
|
-
stdin: @stdin,
|
9
|
+
stdin: (@stdin != $stdin ? @stdin : StringIO.new),
|
10
10
|
stdout: @stdout,
|
11
11
|
stderr: @stderr,
|
12
12
|
world: @world,
|
@@ -19,10 +19,12 @@ module Yap::Shell::Execution
|
|
19
19
|
h
|
20
20
|
end
|
21
21
|
|
22
|
-
Treefell['shell'].puts "shell command executing with params: #{params.inspect}"
|
23
|
-
|
22
|
+
Treefell['shell'].puts "shell command executing with params: #{params.inspect} $stdout=#{$stdout.inspect} $stderr=#{$stderr.inspect}"
|
23
|
+
func.call(**params)
|
24
|
+
|
24
25
|
@stdout.close if @stdout != $stdout && !@stdout.closed?
|
25
26
|
@stderr.close if @stderr != $stderr && !@stderr.closed?
|
27
|
+
@stdin.close if @stdin != $stdin && !@stdin.closed?
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
data/lib/yap/shell/repl.rb
CHANGED
@@ -30,7 +30,6 @@ module Yap::Shell
|
|
30
30
|
line = line_read << "\n"
|
31
31
|
begin
|
32
32
|
@blk.call(line)
|
33
|
-
@world.editor.redraw_prompt
|
34
33
|
rescue Yap::Shell::Parser::Lexer::NonterminatedString,
|
35
34
|
Yap::Shell::Parser::Lexer::LineContinuationFound => ex
|
36
35
|
Treefell['shell'].puts "rescued #{ex}, asking user for more input"
|
data/lib/yap/shell/version.rb
CHANGED
data/lib/yap/world/addons.rb
CHANGED
@@ -98,12 +98,12 @@ module Yap
|
|
98
98
|
attr_reader :file
|
99
99
|
|
100
100
|
def initialize(file)
|
101
|
-
@file = file
|
101
|
+
@file = File.expand_path(file)
|
102
102
|
end
|
103
103
|
|
104
104
|
def initialize_world(world)
|
105
105
|
Treefell['shell'].puts "initializing rcfile: #{file}"
|
106
|
-
world.instance_eval File.read(@file)
|
106
|
+
world.instance_eval File.read(@file), @file
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
data/lib/yap/world.rb
CHANGED
@@ -129,7 +129,17 @@ module Yap
|
|
129
129
|
evaluation.evaluate(statement) do |command, stdin, stdout, stderr, wait|
|
130
130
|
context.clear_commands
|
131
131
|
context.add_command_to_run command, stdin:stdin, stdout:stdout, stderr:stderr, wait:wait
|
132
|
-
@last_result = context.execute(world:self)
|
132
|
+
@last_result = context.execute(world:self) || 0
|
133
|
+
if @last_result.is_a?(Integer)
|
134
|
+
Yap::Shell::Execution::Result.new(
|
135
|
+
status_code: @last_result,
|
136
|
+
directory: Dir.pwd,
|
137
|
+
n: 1,
|
138
|
+
of: 1
|
139
|
+
)
|
140
|
+
else
|
141
|
+
@last_result
|
142
|
+
end
|
133
143
|
end
|
134
144
|
end
|
135
145
|
|
@@ -224,6 +234,9 @@ module Yap
|
|
224
234
|
dom.prompt_box = @prompt_box
|
225
235
|
dom.input_box = @input_box
|
226
236
|
dom.content_box = @content_box
|
237
|
+
@prompt_box.name = "prompt-box"
|
238
|
+
@input_box.name = "input-box"
|
239
|
+
@content_box.name = "content-box"
|
227
240
|
end
|
228
241
|
end
|
229
242
|
end
|
data/rcfiles/yaprc
CHANGED
@@ -155,6 +155,10 @@ world.editor.bind(:alt_down_arrow) do
|
|
155
155
|
keyboard_macros.cycle(:recent_git_branches).previous
|
156
156
|
end
|
157
157
|
|
158
|
+
world.editor.bind(:ctrl_r) do
|
159
|
+
world.addons[:history_search].prompt_user_to_search
|
160
|
+
end
|
161
|
+
|
158
162
|
# Or, you can set the trigger key for a particular set of macros
|
159
163
|
# by specifying it when you call .configure(...).
|
160
164
|
world.addons[:keyboard_macros].configure(trigger_key: ?\C-g) do |macro|
|
data/yap-shell.gemspec
CHANGED
@@ -65,11 +65,11 @@ Gem::Specification.new do |spec|
|
|
65
65
|
spec.require_paths = ["lib"]
|
66
66
|
|
67
67
|
spec.add_dependency "pry-byebug", "~> 3.3.0"
|
68
|
-
spec.add_dependency "yap-shell-parser", "~> 0.6.
|
68
|
+
spec.add_dependency "yap-shell-parser", "~> 0.6.2"
|
69
69
|
spec.add_dependency "term-ansicolor", "~> 1.3"
|
70
70
|
spec.add_dependency "ruby-termios", "~> 0.9.6"
|
71
71
|
spec.add_dependency "ruby-terminfo", "~> 0.1.1"
|
72
|
-
spec.add_dependency "yap-rawline", "~> 0.
|
72
|
+
spec.add_dependency "yap-rawline", "~> 0.4.0"
|
73
73
|
spec.add_dependency "treefell", "~> 0.2.3"
|
74
74
|
|
75
75
|
spec.add_development_dependency "bundler", "~> 1.6"
|
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.5.1
|
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-05-
|
11
|
+
date: 2016-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry-byebug
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.6.
|
33
|
+
version: 0.6.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.6.
|
40
|
+
version: 0.6.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: term-ansicolor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.4.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.4.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: treefell
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,6 +169,7 @@ files:
|
|
169
169
|
- WISHLIST.md
|
170
170
|
- addons/history/README.md
|
171
171
|
- addons/history/history.rb
|
172
|
+
- addons/history_search/history_search.rb
|
172
173
|
- addons/keyboard_macros/keyboard_macros.rb
|
173
174
|
- addons/keyboard_macros/lib/keyboard_macros/cycle.rb
|
174
175
|
- addons/prompt/Gemfile
|