gpt4 book ai didi

swift - 如何在 Swift 中读取 ANSI Escape 代码响应值?

转载 作者:行者123 更新时间:2023-11-28 07:34:29 25 4
gpt4 key购买 nike

我正在使用 Swift 作为控制台应用程序来处理 ANSI 代码(ESC 序列)。发送 ESC 命令很简单,例如设置文本颜色。但是,从 ESC 命令读取响应值具有挑战性。这是一个简单的测试程序:

print("Get cursor position:", "\u{1b}[6n", terminator: "")
let s = readLine()!
print(s)

程序发送<ESC>[6n获取当前光标位置,控制台将返回 <ESC>[<line>;<column>R字符串。以下是问题:

  1. readLine()一直等待输入,直到用户按下 Return 或 Enter 键。我认为一旦输入缓冲区变空它就会自动停止读取。
  2. readLine()奇怪的是似乎没有从控制台读取响应值,尽管它清楚地打印在屏幕上。发生什么事了?
  3. 响应值打印在控制台上。我想静静地拥有它,就像这样print()打印 ESC 命令。有没有办法临时将标准输入重定向到变量?

系统:
• MacOS Mojave
• X代码10
• swift 4.2
• 在终端应用程序上运行

我一直在查看 GitHub 和 Google 以找到一些答案,但我没有运气。那么,这里有人会提示我从哪里开始解决这个问题吗?谢谢。

问候,

~蜜蜂

最佳答案

终端默认处于“规范输入处理”模式,这意味着在输入和处理整行之前不会返回读取请求。 tcsetattr() 函数用于同时禁用输入处理和回显,参见示例

以及 tcsetattr(3)termios(4) 手册页。

这是一个 Swift 中的简单示例,灵感来自上述问答中的 C 代码,以及 Xcode Swift Command Line Tool reads 1 char from keyboard without echo or need to press return :

#if os(Linux)
import Glibc
#else
import Darwin
#endif

// Write escape sequence:
write(STDOUT_FILENO, "\u{1b}[6n", 4)

// Save terminal attributes:
var oldt = termios()
tcgetattr(STDIN_FILENO, &oldt)

// Disable canonical input processing and echo:
var newt = oldt
newt.c_lflag &= ~tcflag_t(ICANON)
newt.c_lflag &= ~tcflag_t(ECHO)
tcsetattr(STDIN_FILENO, TCSANOW, &newt)

// Read response:
var response: [UInt8] = []
var c: UInt8 = 0
repeat {
read(STDIN_FILENO, &c, 1)
response.append(c)
} while c != UInt8(ascii: "R")

// Restore original terminal attributes:
tcsetattr(STDIN_FILENO, TCSANOW, &oldt)

print(response) // [27, 91, 52, 59, 49, 82] == ESC[4;1R

请注意,这仅在终端窗口中运行时有效,而不是在 Xcode 中运行。

关于swift - 如何在 Swift 中读取 ANSI Escape 代码响应值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53587666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com