Я пытаюсь создать базовый 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 полезны и для потомков.
Сноска: Да, мне известны такие вещи, как ncurses, которые обрабатывают все это для меня. Я хотел бы сделать это без использования таких библиотек, чтобы улучшить мое понимание терминальной среды.
Это цель TERM
переменная окружения. Вы используете (низкоуровневые) библиотеки, такие как TERMINFO понять (значение) ценности TERM
хотя признать в Emacs значение «тупой» достаточно просто.
Других решений пока нет …