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