yap-shell 0.4.11 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|