将c中的read()函数与stdin中的剪贴板事件区分开来



我正在开发基于终端的文本编辑器,我需要区分read((函数的输入文本是剪贴板粘贴文本还是键盘文本输入。

#include <unistd.h>
char read_key_input() {
char ch;
int read_count;
while ((read_count = read(STDIN_FILENO, &ch, 1)) != 1)
{
// Handle error if any
}

return ch;
}
...

编辑:这是我最后做的事情。

void read_key_input(void (*callback)(int)) {
char* text = malloc(UINT8_MAX);
int read_count;
while ((read_count = read(STDIN_FILENO, text, UINT8_MAX)) == -1)
{
// Handle error if any
}
// Handle escape sequences if found and return early
...
if (read_count > 1) {
// It's probably a clipboard text. So change the editor mode to input and loop through all the characters one by one.
else {
// It's a user keyboard text input
}
// Revert back to the original editor mode if changed
}

我更新了代码,一次检索多个字节(如@AnttiHaapala所建议的(,并处理每个字节。现在看来已经足够满足我的文本编辑器的需要了。如果我更新,会发回来。

通常,您可以通过快速连续计数收到的字符数来区分这一点。因此,如果你的按键速度比每分钟1000个字符更快,那么这很可能是剪贴板粘贴。。。或者胡说八道。

此外,如果您已将终端设置为原始模式,则可以轻松监控各个按键。同时使read一次接受多于一个字节的,而read是在可用的情况下接收的最大字节数。


这种交互式终端程序的一个例子是IPython——这里有两行分别键入:

In [1]: print("Hello")
Hello
In [2]: print("World")
World

这里一次性粘贴:

In [3]: print("Hello")
...: print("World")
...:
Hello
World

请注意提示是如何不同的,并且程序只有在经过一小段延迟后单独按下Enter键后才运行。

AFAIK,你不能(可靠地(做你想做的事。

剪贴板(通常(与某些显示服务器相关,例如Xorg或Wayland服务器(Weston(。X11可能有远程客户端(因此,如果跨越一些海洋,剪贴板操作可能会很慢(。

一些Linux机器(可能是Stackoverflow的web服务器(不运行任何显示服务器。

您可以对GUI应用程序进行编码,例如使用GTK或Qt。

您可以测试您的标准输入是具有termios(3(功能的终端还是isatty(3((即标准输出为isatty(STDIN_FILENO)isatty(STDOUT_FILENO)(

如果您的程序在crontab(1(作业或unix管道中运行,则标准输入不会是终端,甚至可能没有任何显示服务器在运行。

您可以从GNUemacs的源代码中获得灵感,它可以检测显示服务器何时可用(可能使用environ(7(,例如"DISPLAY"的getenv(3(…(

在Linux上,您可以打开(2(/dev/tty(参见tty(4((来访问您的终端。在某些情况下,它并不存在。

Hey@jiten不确定你是否检查了其按键输入检测并逐个检查其输入是否为按键或其即时批量输入。

最新更新