używam GNU readline w modzie „Wybierz”, rejestrując funkcję zwrotną tak:GNU Readline: jak wyczyścić linię wejściową?
rl_callback_handler_install("", on_readline_input);
a następnie podpinania rl_callback_read_char
jako zwrotnego dla mojego select()
pętli dla STDIN_FILENO
. To wszystko jest dość standardowe i działa dobrze.
Teraz mój program asynchronicznie drukuje wiadomości na ekranie, czasami przeplatany danymi wejściowymi od użytkownika. "Czysta" sesja wyglądałaby następująco:
user input
SERVER OUTPUT
SERVER OUTPUT
user input
SERVER OUTPUT
Ale co, jeśli użytkownik jest w połowie linii, gdy przychodzi odpowiedź serwera? Potem robi się brzydkie:
user input
SERVER OUTPUT
user inSERVER OUTPUT
put
SERVER OUTPUT
Naprawiłem to po prostu drukując przełamane przed wyjściem serwera, jeśli użytkownik wpisał coś (to łatwo stwierdzić sprawdzając rl_line_buffer
), a następnie robi rl_forced_update_display()
po wydrukowaniu wyjście serwera . Teraz wygląda to tak:
user input
SERVER OUTPUT
user in
SERVER OUTPUT
user input
SERVER OUTPUT
To jest lepsze, ale wciąż nie jest doskonałe. Problem pojawia się, gdy użytkownik wpisze całą linię, ale jeszcze nie nacisnąć Enter - wtedy wygląda to tak:
user input
SERVER OUTPUT
user input
SERVER OUTPUT
user input
SERVER OUTPUT
To jest złe, ponieważ wydaje się, że użytkownik wpisał trzy polecenia (trzy odpowiedzi dla trzy wejścia są tak samo możliwe, jak trzy odpowiedzi na dwa wejścia, co tak naprawdę się wydarzyło).
Paskudny Hack (które działa) jest, aby to zrobić:
user input
SERVER OUTPUT
user input - INCOMPLETE
SERVER OUTPUT
user input
SERVER OUTPUT
Pomyślałem mogę poprawić to poprzez drukowanie znaków zamiast " - INCOMPLETE"
Backspace ('\ b'), ale nie wydaje się rób cokolwiek w moim terminalu (gnome-terminal na Ubuntu Hardy). printf("ABC\b");
po prostu drukuje ABC
, bez względu na przyczynę.
Jak mogę usunąć niekompletną linię wejściową? Albo przez drukowanie tylnych przestrzeni w jakiś sposób (mogę dowiedzieć się, ile do wydrukowania - to jest strlen(rl_line_buffer)
), lub za pomocą jakiejś funkcji Readline, o której jeszcze nie wiem?
Niektóre terminale/emulatory terminali mają różne zachowanie dla charakteru Backspace. pmg ma dobry pomysł. –
To działa w moim terminalu. Ale bez lepszego zrozumienia, dlaczego to działa i jak (nie) jest to przenośne, wybrałem użycie '\ r' zamiast tego (jak zasugerowano w innej odpowiedzi). –
Zmieniono zdanie po użyciu kodu '\ r' na chwilę ... Naprawdę to lubię, ponieważ nie wymaga nadpisywania spacji na końcu (wolę nadpisywać przed wyjściem serwera, więc to rozwiązanie najlepiej mi odpowiada, nie wspominając już o tym, że jest to najbardziej bezpośrednia odpowiedź na moje oryginalne pytanie). –