如何在Nim中读取上次调用函数后所有按键且无需按回车
Nim 实现非阻塞无回车读取按键序列
默认情况下,终端处于规范模式,会缓冲输入直到按下回车才传递给程序,这就是你之前的代码需要回车才触发的原因。要实现无回车的非阻塞读取,需要修改终端模式,同时用非阻塞方式读取输入。
实现代码
import os, strutils, terminal proc getPendingKeys(): seq[char] = result = newSeq[char]() # 保存当前终端状态,切换到原始模式(关闭行缓冲与回显) var termState: TerminalState if not getTerminalState(stdin, termState): return result setTerminalState(stdin, terminalStateRaw) try: # 将stdin设置为非阻塞模式 setFileFlags(stdin, fmNonBlocking) var buf = newString(1) # 循环读取所有待处理的按键 while true: let bytesRead = readBuffer(stdin, buf, 1) if bytesRead <= 0: break result.add(buf[0]) finally: # 无论是否出错,都恢复终端原始状态 setTerminalState(stdin, termState) when isMainModule: while true: let keys = getPendingKeys() if keys.len > 0: echo "收到按键序列: ", keys sleep(100) # 降低循环CPU占用
关键说明
- 终端模式切换:
terminalStateRaw模式下,输入会立即传递给程序,不再等待回车触发,同时关闭默认的按键回显。 - 非阻塞读取:
fmNonBlocking标志让readBuffer在无输入时直接返回,不会阻塞程序执行。 - 状态恢复:
finally块确保程序退出或异常时,终端能恢复到原来的工作模式,避免后续终端操作异常。 - 特殊按键处理:方向键、功能键这类特殊按键会生成多字节转义序列,若需要识别这类按键,需额外解析对应的转义码。
内容的提问来源于stack exchange,提问作者Bobson Tobson
相关产品推荐
相关产品推荐

