如何在Ruby终端输入提示符中捕获特殊按键(其余按键正常响应)
这个需求得靠切换终端的输入模式来实现——默认情况下终端是「规范模式」,会把输入攒到回车才交给程序,而且方向键发送的是转义序列(比如^[[A),自然会显示成乱码。咱们用Ruby自带的io/console库就能搞定,它能让咱们直接捕获单个按键,还能安全切换终端模式。
先给你一段完整的实现代码,我会逐段解释:
require 'io/console' def arrow_pressed puts "\narrows totally pressed!" # 加换行避免和输入内容混在一起 end # 保存终端原始设置,块结束后自动恢复(防止退出后终端乱掉) STDIN.raw(false) do |stdin| input_buffer = "" # 用来存储用户输入的普通字符,模拟gets的行输入 loop do char = stdin.getch # 捕获单个按键,无回显 case char when "\e" # 方向键的转义序列以ESC开头(\e就是ESC字符) # 读取后续两个字符,组成完整的方向键序列 seq = char + stdin.getch + stdin.getch # 匹配常见的上下左右箭头序列 if ["\e[A", "\e[B", "\e[C", "\e[D"].include?(seq) arrow_pressed else # 其他以ESC开头的序列(比如F1-F12),按需处理或直接输出 print seq end when "\r", "\n" # 回车键,结束当前输入行 puts "\n你输入的内容是:#{input_buffer}" break when "\u0003" # Ctrl+C,强制终止程序 puts "\n程序已终止" break else # 普通字符,直接回显并加入输入缓冲区 print char input_buffer << char end end end
关键细节说明:
- 终端模式切换:
STDIN.raw(false)会把终端切换到「原始模式」——不缓冲输入、不自动回显字符,而且块执行完毕后会自动恢复终端的原始设置,不用担心退出后终端变乱。 - 方向键处理:方向键发送的是3字符的转义序列(ESC + [ + 字母),所以先捕获ESC,再读取后续两个字符判断是否是方向键,匹配到就直接调用
arrow_pressed。 - 模拟原生gets行为:用
input_buffer存储普通字符,用户按回车时输出内容,和原来的gets逻辑一致。 - 异常退出处理:加入了Ctrl+C的捕获,确保程序能正常终止。
小提示:
不同终端的方向键转义序列可能略有差异(比如部分终端会发送\eOA而非\e[A),如果遇到匹配不上的情况,可以先临时加一行p seq打印捕获到的序列,再调整case里的判断条件。
内容的提问来源于stack exchange,提问作者PlacateTheCattin
相关产品推荐
相关产品推荐

