workaround to avoid suspending rb-readline by 'Ctrl-Y'. https://arika.org/2017/11/10/rb-readline-and-ctrl-y/
# macOSでのrb-readline使用時の"\C-y"サスペンド問題の回避 | |
if defined?(::RbReadline) && $".grep(/\/rbreadline.rb\z/) | |
stty = `stty -a` | |
stty_ccs = { 'dsusp' => '^Y', 'lnext' => '^V' } | |
stty_ccs.delete_if {|cc, key| /\b#{Regexp.quote("#{cc} = #{key}")};/ !~ stty } | |
unless stty_ccs.empty? | |
system('stty', *stty_ccs.keys.inject([]) {|opts, cc| opts << cc << 'undef' }) | |
IRB.conf[:AT_EXIT] << proc do | |
system('stty', *stty_ccs.to_a.flatten) | |
end | |
end | |
end |
# macOSでのrb-readline使用時の"\C-y"サスペンド問題の回避 | |
stty_ccs = {} | |
nest_level = -1 | |
Pry.hooks.add_hook(:when_started, 'avoid dsusp') do | |
if defined?(::RbReadline) && $".grep(/\/rbreadline.rb\z/) | |
stty = `stty -a` | |
stty_ccs = { 'dsusp' => '^Y', 'lnext' => '^V' } | |
stty_ccs.delete_if {|cc, key| /\b#{Regexp.quote("#{cc} = #{key}")};/ !~ stty } | |
end | |
end | |
Pry.hooks.add_hook(:before_session, 'count nest level') do | |
nest_level += 1 | |
end | |
Pry.hooks.add_hook(:before_session, 'avoid dsusp') do |_, _, pry| | |
system('stty', *stty_ccs.keys.inject([]) {|opts, cc| opts << cc << 'undef' }) if nest_level.zero? && !stty_ccs.empty? | |
end | |
Pry.hooks.add_hook(:after_session, 'avoid dsusp') do |_, _, pry| | |
system('stty', *stty_ccs.to_a.flatten) if nest_level.zero? && !stty_ccs.empty? | |
end | |
Pry.hooks.add_hook(:after_session, 'count nest level') do | |
nest_level -= 1 | |
end |
require 'pty' | |
require 'timeout' | |
irb_start = [ | |
'gem "rb-readline"', # rb-readlineを使用しない場合はコメントアウト | |
'require "irb"', | |
'IRB.start', | |
].join('; ') | |
timeout = 5 | |
bash_prompt = /bash-[.\d]+\$ \z/ | |
irb_prompt = />> \z/ | |
ios = [ | |
bash_prompt, | |
"echo cat test\n", | |
bash_prompt, | |
"cat\n", | |
"aaa\n", | |
"bbb\n", | |
"\C-d", | |
bash_prompt, | |
"echo readline test\n", | |
bash_prompt, | |
"ruby -e '#{irb_start}' -- -f --prompt-mode=simple\n", | |
irb_prompt, | |
":ccc\n", | |
irb_prompt, | |
":ddd", "\C-a", "\C-k", "eee = ", "\C-y", "\n", | |
irb_prompt, | |
":fff\n", | |
irb_prompt, | |
"quit\n", | |
bash_prompt, | |
"echo done.\n", | |
bash_prompt, | |
"exit\n", | |
] | |
result = 'OK' | |
wait = nil | |
buf = '' | |
PTY.spawn('bash --norc') do |r, w, _p| | |
w.sync = true | |
begin | |
Timeout.timeout(timeout) do | |
ios.each do |obj| | |
if obj.is_a?(String) | |
w.write obj | |
$stderr.write '+' | |
next | |
end | |
wait = obj | |
loop do | |
buf << r.readpartial(1024) | |
break if wait.match(buf) | |
$stderr.write '-' | |
sleep 0.1 | |
end | |
$stderr.write '.' | |
end | |
end | |
buf << r.readpartial(1024) | |
rescue Timeout::Error | |
result = "ERROR: couldn't get #{wait.inspect}" | |
ensure | |
w.close | |
r.close | |
end | |
end | |
$stderr.write "\n#{'-' * 78}\n" | |
print "RESULT = #{result}\n\n#{buf}" |
$ ruby test.rb | |
-.+-.++++-.+-.+--.+-.++++++--- | |
------------------------------------------------------------------------------ | |
RESULT = ERROR: couldn't get />> \z/ | |
bash-3.2$ echo cat test | |
cat test | |
bash-3.2$ cat | |
aaa | |
bbb | |
aaa | |
bbb | |
bash-3.2$ echo readline test | |
readline test | |
ode=simpleruby -e 'gem "rb-readline"; require "irb"; IRB.start' -- -f --prompt-m | |
>> :ccc | |
=> :ccc | |
>> eee = | |
[1]+ Stopped ruby -e 'gem "rb-readline"; require "irb"; IRB.start' -- -f --prompt-mode=simple | |
bash-3.2$ |
$ ruby test.rb | |
.+-.++++-.+-.+--.+--.++++++---.+--.+-.+-.+ | |
------------------------------------------------------------------------------ | |
RESULT = OK | |
bash-3.2$ echo cat test | |
cat test | |
bash-3.2$ cat | |
aaa | |
bbb | |
aaa | |
bbb | |
bash-3.2$ echo readline test | |
readline test | |
bash-3.2$ ruby -e 'require "irb"; IRB.start' -- -f --prompt-mode=simple | |
>> :ccc | |
=> :ccc | |
>> eee = :ddd | |
=> :ddd | |
>> :fff | |
=> :fff | |
>> quit | |
bash-3.2$ echo done. | |
done. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment