ubuntuusers.de

Problem mit Cursor-Handling im Terminal

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Hallo,

via tput lassen sich bekanntlich die in terminfo gepeicherten Capnames benutzen, welche die jeweils für das Terminal geltenden Steuersequenzen abstrahieren. In meinem Fall geht es darum, mehrzeiligen Text zu updaten, indem immer wieder mit dem Cursor zurück an den Anfang des Textes gesprungen wird. Dafür nutze ich die Capnames sc zum Speichern der Position, bevor ich mit dem Schreiben anfange und danach rc zum Wiederherstellen der Position, damit neuer Text drübergeklatscht werden kann. Das ganze sieht beispielhaft so aus:

1
2
3
4
urx@murx:~$ echo -e "$(tput sc)aaaaaa\nbbbbbb\ncccccc $(tput rc)111\n222"
111aaa
222bbb
urx@murx:~$ 

Es werden also zunächst die 3 Zeilen mit je 6 Buchstaben geschrieben. Dann wird zurückgesprungen und über 2 Zeilen die jeweils ersten 3 Zeichen mit Zahlen überschrieben. Die letzte Zeile mit den "c"'s überschreibt natürlich der Prompt.

Das alles ist schön und funktioniert wie gewünscht. Das Problem tritt erst in dem Moment auf, in dem man das Ende des Emulator-Fensters erreicht hat und der Inhalt entsprechend gescrollt wird, um Platz für eine neue Zeile zu schaffen. Die Ausgabe sieht dann so aus:

1
2
3
4
5
6
urx@murx:~$ echo -e "$(tput sc)aaaaaa\nbbbbbb\ncccccc $(tput rc)111\n222"
aaaaaa
bbbbbb
111ccc 
222
urx@murx:~$ 

Der Cursor springt also wieder 2 Zeilen nach oben zur alten Position und überschreibt den Text von da aus. Dumm nur, dass an dieser Stelle jetzt nicht mehr die erwarteten "a"'s , sondern eben die hochgerutschten "c"'s stehen. Ich hoffe, die Problematik ist damit klar geworden.

Meine Frage an euch ist nun, ob ihr irgendeine Möglichkeit kennt, genau dies zu verhindern. Der Cursor soll also nicht bezogen auf den sichtbaren Bereich hochspringen, sondern bezogen auf den vorher geschriebenen Text.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Hi snafu,

das Problem kenne ich auch. (ich verwende in der Regel direkt die ANSI-Steuerzeichen, aber das kommt am Ende aufs selbe hinaus.)

Eine grundsätzliche Lösung kenne ich nicht, sondern ich löse das pragmatisch, indem ich mit Leerzeilen zuerst die volle Zeilenzahl auf den Schirm bringe, und erst dann per Steuercode verspringe.

Alternativ könntest Du auch vorher den Schirm löschen (dann fängt er oben an), oder wenn Du definitiv mehr Zeilen brauchst als auf den Schirm passen, dann kannst Du gezielt scrollen (den Offset musst Du allerdings selber verwalten).

- ok, das ist etwas aufwändiger, aber mit sauber gebauten Funktionen geht das einigermaßen übersichtlich zu machen.

track

edit: mal meine "Menümaschine" als Beispiel angehängt.

menu_2 (1.8 KiB)
Download menu_2

snafu1

(Themenstarter)
Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Ich hatte jetzt zumindest gehofft, dass es ein Signal zum Lauschen gibt, welches beim Scrollen gesendet wird. Also ähnlich wie das von Terminals gesendete Signal SIGWINCH bei einer Größenveränderung des Emulator-Fensters. Nun ja, der Workaround mit den leeren Zeilen, die überschrieben werden, ist vermutlich noch die beste Idee.

snafu1

(Themenstarter)
Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Nur mal für mich als Memo und natürlich auch für andere Interessierte:

Die Position des Cursors ist leider nicht so ohne Weiteres herauszubekommen. Ich bin zwischenzeitlich auf einen Beitrag gestoßen, der besagt, dass die aktuelle Spalte mittels u7 herausbekommen werden kann. Das habe ich bisher zwar nirgendwo dokumentiert gefunden, aber es funktioniert offenbar (zumindest in einer xterm-basierten Emulation). Man muss es nur noch ein bißchen zurechtparsen.

Ich mache mich jetzt noch auf die Suche nach dem Capname zur aktuellen Zeile. Gern nehme ich natürlich Lösungen dafür an. Und vielleicht geht ja auch das mit der Spalte viel einfacher als von mir beschrieben. ☺

UPDATE


Bin jetzt endlich auf passende Dokumentation gestoßen und fündig geworden:

The VT100's cursor location can be read with the DSR (Device Status Report) control

Esc [ 6 n

The VT100 reports by transmitting the CPR sequence

Esc [ Pl ; Pc R

where Pl is the line number and Pc is the column number (in decimal).

Die fish-Shell zeigt entsprechend an:

1
2
3
urx@murx ~> echo -e "\033[6n"

urx@murx ~> [24;1R

Die bash gibt anscheinend nur die Spalte aus:

1
2
3
urx@murx:~$ echo -e "\033[6n"

urx@murx:~$ ;1R

Naja, aber das bekomme ich schon noch irgendwie hin. Für mich ist der Thread erstmal gelöst.

EDIT: Hier gibt es eine eine Komplettlösung zum Parsen in der Bash.

Antworten |