Обнаружение, могу ли я захватить клавиши со стрелками через стандартный ввод - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь создать базовый REPL. Если моя программа запускается в терминале, который может ее поддерживать, я использую termios getchar, чтобы прочитать ввод за символом и ответить на специальные клавиши, такие как клавиши со стрелками. Однако, если запустить в терминале, для которого это не имеет смысла, я бы хотел переключиться на старый добрый cin.getline.

Проблема в том, чтобы определить, обладает ли терминал возможностями, которые я ищу. Первоначально я думал, что isatty сделает свое дело.

#include <cstdio>
#include <iostream>
#include <unistd.h>

int main() {
  bool tty = isatty(fileno(stdin));
  std::cout << "You are using a TTY: " << std::boolalpha << tty << std::endl;
  return 0;
}

Это правильно идентифицирует случаи, когда stdin - это труба или что-то в этом роде. Однако, если я запускаю подоболочку внутри Emacs (в частности, M-x shell), он все равно идентифицируется как TTY, даже если Emacs захватывает клавиши со стрелками и другие специальные символы и выполняет с ними свои функции. Какие функции C ++ или POSIX я могу использовать, чтобы правильно различать подоболочку, запускаемую в Emacs, и оболочку, запускаемую с полным контролем внутри «обычного» терминала?

В первую очередь я ищу решения POSIX, но ответы только для Windows полезны и для потомков.


Сноска: Да, я знаю о вещах, подобных няням, которые справляются со всем этим для меня. Я хотел бы сделать это без использования таких библиотек, чтобы улучшить мое понимание терминальной среды.

1 Ответ

0 голосов
/ 11 мая 2018

Это цель переменной среды TERM . Вы используете (низкоуровневые) библиотеки, такие как terminfo , чтобы понять (значение) значения TERM, хотя распознать значение Emacs «тупой» достаточно просто.

...