You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 06:12:06