Nachgestellte Leerzeichen beim Kopieren von der Konsole

9

Es ist dieses nervige Verhalten, das ich hier und da gelegentlich erlebt habe: Wenn Sie Text mit der Maus in der Konsole auswählen (dh kopieren), einfügen und feststellen, dass am Ende jeder Zeile zusätzliche Leerzeichen stehen. Das ist,

line 1                                                                          
line 2                                                                          

anstatt

line 1
line 2

Also nicht nur ein Leerzeichen am Ende jeder Zeile.

Ich konnte das Problem nicht zuverlässig reproduzieren und fand keine Antwort. Ich glaube, mit etwas Software manifestiert es sich erst nach einer Weile.

Aber ich habe gerade bemerkt, dass es im vimersten tmuxFall gut funktioniert , wenn ich dieselbe Datei erst direkt von der Konsole aus und dann von dort aus öffne . Und nicht in letzterem. Betrachtet man TERM=xterm-256colorin der Konsole, und TERM=screen-256colorin tmux, meine Vermutung ist , dass es mit Terminal zu tun hat , nicht richtig zu tun, oder nicht - Anwendungen ermöglicht es richtig zu machen. Eine vage Vermutung, nehme ich an. Die erste Frage lautet also: "Was genau verursacht es?"

Und der andere ist: "Wie gehe ich vor?" Der schlimmste Fall ist, wenn sich die Datei remote befindet. Ich habe es in geditletzter Zeit lokal kopiert und geöffnet . Jetzt habe ich angeblich die Möglichkeit, es in einer neuen Konsole zu öffnen (da ich hauptsächlich in tmuxSitzungen arbeite ) und von dort zu kopieren. Könnte dies einfacher gemacht werden?

Wenn ich laufen vimaus tmuxmit TERM=xterm-256color vim, verhält es sich seltsam an . Als würde man keinen Hintergrund zeichnen, wo es keinen Text gibt. Und es scheint mir nicht in Ordnung zu sein, eine TERMVariable zu ändern (was die Software glauben lässt, dass es sich um ein anderes Terminal handelt).

Wenn ich lokale Dateien bearbeite, mache ich das normalerweise :!gedit %.

x-yuri
quelle

Antworten:

3

Beim Auswählen und Kopieren vom Terminal werden am Ende der Zeile Leerzeichen angezeigt, wenn die Anwendung an dieser Stelle Leerzeichen anzeigt. Anwendungen können Leerzeichen anzeigen, um das zu löschen, was zuvor vorhanden war. Terminals verfügen über Befehle zum Löschen einer ganzen Zeile oder zum Löschen von Zeichen rechts vom Cursor. Anwendungen wählen zwischen dieser und der Anzeige von Räumen basierend auf dem, was sie für am effizientesten halten. Wenn Sie beispielsweise an einer Eingabeaufforderung etwas eingeben und dann die Rücktaste drücken, überschreibt die Anwendung (z. B. die Shell) wahrscheinlich das letzte Zeichen mit einem Leerzeichen.

Wenn Sie eine X11-Verbindung haben, können Sie eine Datei verwenden xseloder xclipin die lokale Zwischenablage kopieren.

Experimentell scheint Vim Mühe zu haben, keine Zeilen anzuzeigen, die mit Leerzeichen enden (selbst wenn der Puffer eine Zeile enthält, die mit Leerzeichen endet). Das Kopieren davon ist daher eine Option, wenn Sie keine X11-Verbindung haben.

Eine Alternative wäre die Nachbearbeitung nach dem Kopieren:

xsel | sed 's/  *$//' | xsel
Gilles 'SO - hör auf böse zu sein'
quelle
So copying from that is an option if you don't have an X11 connection.Nicht mit screenähnlichen Terminalemulatoren, AFAICT ( TERM=screen*). Apropos xsel, guter Punkt, ich denke jetzt darüber nach, einen vimBefehl zu erstellen , der einen Shell-Befehl ausgibt, der lokal ausgegeben werden soll, wie :XSelCommand %-> ssh server cat path/to/file | xsel. Das scheint besser zu sein, als entfernte Dateisysteme zu mounten oder Dateien lokal zu kopieren.
X-Yuri
Mit einem Befehl wie diesem: command! XSelCommand echo 'ssh ' . system('hostname')[:-2] . ' ' . shellescape('sh -c ''cat "$1"'' -- ' . shellescape(expand('%'))) . ' | xsel'oder wie diesem: command! -range=% RXSelCommand echo 'ssh ' . system('hostname')[:-2] . ' ' . shellescape('sh -c ''cat "$1" | sed -n "<line1>,<line2>p"'' -- ' . shellescape(expand('%'))) . ' | xsel'kann man den Inhalt von Dateien kopieren, nicht das, was ausgegeben wurde. Die einfachere Option wäre jedoch, die Datei lokal vimüber ssh zu öffnen und zu tun :%!xsel. Oder noch :r!ssh HOST CMDeinmal :%!xsel.
X-Yuri
Ich habe es bisher geschafft, auf zwei Probleme zu xselstoßen: 1) :%!xselfunktioniert nicht, funktioniert vimaber :%!xsel -i, angeblich weil vimWeiterleitungen stdoutsowie stdin; Eine weitere Option ist :w !xsel: 2) Das Kopieren von Dateien über 4000 Byte funktioniert nicht beim Einfügen in chrome's textarea, funktioniert aber für gedit; Der Tab hängt ungefähr 10 Sekunden lang, aber danach wird nichts mehr eingefügt. Weißt du zufällig, was für eine magische Zahl das ist?
X-Yuri
... und nichts dergleichen passiert beim Kopieren von geditnach chromemit der mittleren Maustaste.
X-Yuri
@ x-yuri Ich weiß nicht, warum es eine Größenbeschränkung geben würde. Versuchen Sie, die xsel/ mittlere Maustaste auf xsel -b/ Strg + V zu ändern , wobei ein etwas anderer Auswahlmechanismus verwendet wird, der möglicherweise anders fehlerhaft ist.
Gilles 'SO - hör auf böse zu sein'
3

Das sind eigentlich mehrere Fragen, und keine der Antworten überfliegt die interessanten Teile:

  • Wenn Sie Text mit der Maus in der Konsole auswählen (dh kopieren), fügen Sie ihn ein und stellen Sie fest, dass am Ende jeder Zeile zusätzliche Leerzeichen stehen.
  • Wenn ich vim von tmux mit TERM = xterm-256color vim ausführe, verhält es sich seltsam.

Die meisten Terminals (wie xterm) speichern die Daten, die Sie auf dem Bildschirm auswählen können. Dahinter befindet sich kein versteckter Teil, der dem Terminal mitteilt, dass die Anwendung einen Hintergrund ausfüllen soll.

Anwendungen aktualisieren den Bildschirm durch den Cursor zu bewegen, das Schreiben von Text (die tatsächlichen Räume umfassen kann - oder Laschen , die das Endgerät rendert als Räume) und Teile des Bildschirms zu löschen.

Das Löschen ist ein besonderes Problem (beim Auswählen / Einfügen), da viele Terminals (z. B. xterm) den gelöschten Bereich des Bildschirms mit der aktuellen Farbe füllen ( die Funktion zum Löschen der hinteren Farbe (bce) in der Terminalbeschreibung). Gleichzeitig werden in gelöschten Bereichen keine Zeichen mehr an diesen Positionen des Bildschirms gespeichert. Mit Terminals, die die Bildschirmdarstellung verwenden, können Sie alles außer dem gelöschten Bereich auswählen. (Als Sonderfall könnte Ihr Terminal Bereiche gelöscht haben, die von Text umgeben sind, und so tun, als wären sie Leerzeichen für die Auswahl).

All dies ist ein Ärgernis, und vor langer Zeit bot xterm eine Funktion zum Ignorieren der nachgestellten Leerzeichen. Die meisten anderen Terminals bieten dies nicht an. Und da dies eine Option ist, kann sie möglicherweise nicht aktiviert werden, wenn Sie xterm ausgeführt haben. Die meisten Terminalentwickler, die die Funktionen von xterm kopieren, kopieren die Optionen nicht.

Zu tmux gehen: Die bce-Funktion wird nicht unterstützt. Die Entwickler entschieden sich dagegen. Normale Anwendungen, die unter tmux ausgeführt werden, erzeugen also nachgestellte Leerzeichen. Wenn Sie die Terminalbeschreibung überschreiben, wird tmux verwirrt, da nicht bekannt ist, dass vim wirklich davon ausgeht, dass der Hintergrund mit der aktuellen Farbe gelöscht wird . Sie bekommen nur die Löschung. Keine Farbe.

Auf der anderen Seite haben die Entwickler des GNU-Bildschirms vor einiger Zeit beschlossen, die Funktion zu unterstützen. Es ist optional ...

Weiterführende Literatur:

  • Unterstützung für das Löschen von Hintergrundfarben (bce) [war: Vim Copy & Paste Trailing Space Problem] # 109 (tmux-Fehlerbericht)
  • Mein Terminal zeigt einige ungefärbte Leerzeichen (ncurses FAQ)
  • Das Problem mit Terminals (nützliche Diskussion zum Thema)
  • highlightSelection (xterm Handbuch)
  • trimSelection (xterm Handbuch)

    Wenn Sie HighlightSelection festlegen, wird der ausgewählte Text einschließlich aller nachgestellten Leerzeichen angezeigt. Durch Löschen des Bildschirms (oder einer Zeile) wird dieser in einen Zustand ohne Leerzeichen zurückgesetzt. Einige Zeilen können nachgestellte Leerzeichen enthalten, wenn eine Anwendung sie auf den Bildschirm schreibt. Möglicherweise möchten Sie jedoch keine Zeilen mit nachgestellten Leerzeichen einfügen. Wenn diese Ressource wahr ist, schneidet xterm nachgestellte Leerzeichen aus dem ausgewählten Text ab. Leerzeichen, die zu einer umbrochenen Zeile führen, werden nicht beeinflusst, und die nachfolgende neue Zeile wird nicht aus Ihrer Auswahl entfernt. Der Standardwert ist "false".

  • Patch Nr. 105 - 05.06.1999 - XFree86 3.9Pp (xterm Changelog)

    Implementieren Sie eine neue Ressource trimSelection, mit der xterm nachgestellte Leerzeichen aus ausgewählten Zeilen entfernen kann. Dies hat keinen Einfluss auf die Hervorhebung.

  • Patch Nr. 27 - 21.08.1996 - XFree86 3.1.2Ek (xterm Changelog bezieht sich auf highlightSelection)

    Dieser Patch behebt einen meiner langfristigen Probleme: Die Auswahl von xterm zeigt nicht klar an, was ausgewählt wird (gemäß Davids Anfrage wird er von einer Ressource gesteuert, die standardmäßig das ältere Verhalten verwendet).

Thomas Dickey
quelle
Die allgemeine Idee scheint klar zu sein, aber ich verstehe möglicherweise nicht die Einzelheiten einiger Aussagen oder bin mir nicht sicher, ob ich dies tue, wie ... Terminals which use the on-screen representationWas sind andere Arten von Terminals? Sind sie in Ihrer Antwort enthalten? As a special case, your terminal could have erased regions surrounded by text, which it will pretend are spaces for selectionHier meinst du wahrscheinlich "als gelöscht markiert". Und was für Regionen sind das? Leerzeichen in der Mitte der Linie? Leere Zeilen, umgeben von Text? Dies sind wahrscheinlich die am wenigsten klaren.
X-Yuri
Andere Typen: Anwendungen (wie Flüche), die auf höheren Ebenen "wissen", ob sie den gesamten Bildschirm löschen oder eine Zeile neu streichen und über die Daten verfügen, um Dinge auf mehr als eine Weise zu rekonstruieren. "Als gelöscht markiert": Beispielsweise zeigt xterm möglicherweise ein Leerzeichen für gelöschte Bereiche an, hat jedoch keinen Charakter.
Thomas Dickey
fwiw, "screen" und "tmux" sind gängige Beispiele für Anwendungen, die das Terminal so manipulieren können, dass sich die Auswahl anders verhält.
Thomas Dickey
2

In vielen modernen Terminalanwendungen gibt es Einstellungen wie "Nachgestellte Leerzeichen kürzen" in den Maus- / Kopieroptionen. Diese sind für Konsole (KDE) & Yakuake vorhanden.

Aram
quelle
2

Das Kopieren und Einfügen von einem Terminalbildschirm wird niemals vollständig zuverlässig sein, da es sich um die Bildschirmausgabe anstelle des Originalquellmaterials handelt. Wenn einige Anwendungen auf ungewöhnliche Weise Text an das Terminal zurückgeben und das Terminal nicht in der Lage ist, den ursprünglichen Text zu erraten, können Sie oder das Terminal wahrscheinlich nicht viel dagegen tun.

Viele Informationen über den Originaltext gehen möglicherweise verloren, wenn er auf einem Terminal gerendert wird: Zum Beispiel, ob ein Leerraum durch eine Registerkarte oder eine Reihe von Leerzeichen erzeugt wurde oder ob zwei Textzeilen ursprünglich eine lange waren Zeile, die umbrochen wurde oder zwei separate Zeilen.

Das Terminal versucht sein Bestes, damit Sie den Originaltext kopieren und einfügen können, der auf dem Terminal wiedergegeben wurde, kann es jedoch nicht immer wissen.

Versuchen Sie als Experiment Folgendes:

  • Verwenden Sie lessdiese Option , um eine Datei anzuzeigen, die sehr lange Zeilen enthält, die sich über mehrere Terminalzeilen erstrecken.
  • Dreifachklick auf eine dieser Zeilen (für die Auswahl der gesamten Zeile). lessWählen Sie die gesamte logische Zeile aus, die mehrere physische Zeilen umfasst. Wenn Sie sie an einer anderen Stelle einfügen, wird sie als eine lange Zeile beibehalten.
  • Drücken Sie jeinige Zeilen, damit ein Teil dieser langen Zeile oben auf dem Bildschirm verschwindet.
  • Drücken Sie kein oder mehrere Male, um die gesamte logische Zeile wieder anzuzeigen.
  • Klicken Sie erneut dreimal auf die logische Zeile. Diesmal ist nur eine physikalische Leitung ausgewählt. Dies liegt daran, dass lessdie physische Leitung des Bildschirms Zeile für Zeile neu gestrichen wurde und das Terminal nicht mehr wissen kann, dass die physischen Leitungen miteinander verbunden waren.
  • Wenn Sie nun die gesamte logische Zeile manuell per Drag & Drop auswählen und an einer anderen Stelle einfügen, werden Sie feststellen, dass darin Zeilenumbrüche eingebettet sind.

YMMV bei diesem Experiment, weil Ihr Terminal (oder Ihre Version von less) möglicherweise mehr oder weniger clever ist als meins.

Je dümmer die Software ist, die die Ausgabe erstellt hat, desto besser sind im Allgemeinen Ihre Chancen, genau das Originalmaterial kopieren und einfügen zu können. catZum einen ist es so dumm wie es nur geht. (Sie verstehen natürlich, dass "dumm" ein Kompliment ist!)

Wenn Sie am Ende einer Zeile darunter ein zusätzliches Leerzeichen erhalten tmux, liegt dies wahrscheinlich daran, tmuxdass dieses Zeichen tatsächlich wiedergegeben wird. Denken Sie daran, dass tmuxdies eine eigene Terminalemulation durchführt und dann neue Terminalsequenzen erneut ausgibt, um sie auf dem zugrunde liegenden Terminal zu rendern. Vielleicht spiegelt es dieses Leerzeichen wider, weil es glaubt, dass es in einigen Fällen notwendig sein könnte, ein anderes Zeichen zu überschreiben, von dem es glaubt, dass es dort ist. Was auch immer der Grund sein mag, das Terminal hat wahrscheinlich keine Möglichkeit zu wissen, dass das Leerzeichen nicht wirklich Teil des ursprünglichen Inhalts ist.

Celada
quelle
Sie haben mich dazu gebracht, eine Problemumgehung zu finden: cateine Datei und die Ausgabe von zu kopieren cat. Zumindest in meinem speziellen Fall funktioniert es. Danke :) Aber wenn es eine lange Datei ist ... Nun, ich habe darüber nachgedacht, das Remote-Dateisystem ( sshfs) zu mounten , dann kann ich eine Datei geditzum Beispiel so bearbeiten, als wäre es eine lokale.
X-Yuri
Wenn Daten , die Sie kopieren möchten in der Datei ist, können Sie xsel -bi < filenamesicher alle daraus kopieren ... Verwenden Sie aktuelle Version von xsel , obwohl
Matija Nalis
1

Unter Verwendung von Fedora 17 Linux und des Konsolenterminalfensters öffne ich vim mit dem syntastischen vim-Add-On. Ich konnte diesen Fehler konsistent reproduzieren. Ich habe diese drei Python-Zeilen in vim eingefügt:

a = "generic assignment"
b = "cursor is on this line"
c = "generic assignment"

Dann wähle ich diese Linien visuell aus und füge sie hier ein:

a = "generic assignment"
b = "cursor is on this line"                                                                                     
c = "generic assignment"

Beachten Sie, wie in der zweiten Zeile Tonnen von Leerzeichen kopiert werden. Das wird sicher nervig.

Die Zeilen 1 und 3 werden wie erwartet kopiert, aber die zweite Zeile kopiert Leerzeichen bis zur äußersten rechten Stelle des Terminalfensters.

Umgehungslösung:

Bewegen Sie die markierte Linie (den Vim-Cursor) von den zu kopierenden Linien weg, bevor Sie sie mit der Maus auswählen. Dann erscheinen die zusätzlichen Leerzeichen nicht in dieser einen Zeile.

Ich vermute, es sind die Syntax- und Farbhervorhebungs-Add-Ons, die diese Probleme verursachen.

Eric Leschinski
quelle
Ich habe Zeile 1 auch mit Leerzeichen aufgefüllt.
X-Yuri
0

Ich habe auch xterm-256colordie nachgestellten Leerzeichen beim Kopieren zwischen Terminals verwendet und mochte sie immer nicht, zum Beispiel beim Kopieren einer ganzen Datei zwischen zwei Remote-Servern. Am einfachsten finde ich es, die gesamte Datei zu kopieren und dann im Ziellauf auszuführen:

:%s/\s\+$//g

Dadurch werden alle nachfolgenden Leerzeichen aus der gesamten Datei entfernt. Es ist schnell und einfach.

Kamil
quelle
Gelegentlich bekomme ich weniger Zeilen als im Original (Zeilenumbrüche verbreiten sich nicht immer). Möglicherweise möchten Sie dies nach dem Ersetzen überprüfen.
X-Yuri
-1

xterm-256colorscheint jetzt richtig zu funktionieren (Vollfarben und keine Probleme beim Zeichnen im Hintergrund) und verfügt über die BCE-Funktion (Back Color Erase). Sie können es in tmux aktivieren, indem Sie dies in Folgendes einfügen ~/.tmux.conf:

set -g default-terminal "xterm-256color"

user48052
quelle