weniger --quit-if-one-screen ohne --no-init

31

Ich befinde mich in einem Terminal, das den alternativen Bildschirm unterstützt, der von less, vim usw. verwendet wird, um die vorherige Anzeige nach dem Beenden wiederherzustellen. Das ist eine nette Funktion, aber sie unterbricht die --quit-if-one-screenUmschaltung wirklich , lessda in diesem Fall weniger zum alternativen Bildschirm wechselt, dessen Daten anzeigt, herausfindet, dass es nur einen Bildschirm gibt, und beendet sich und nimmt den Inhalt des alternativen Bildschirms mit.

Die häufig vorgeschlagene Problemumgehung besteht darin, die --no-initOption zu verwenden, um die Verwendung des alternativen Bildschirms insgesamt zu vermeiden. Dies ist jedoch etwas hässlich, da ich es verwenden möchte, falls weniger tatsächlich als Pager fungiert. Aus diesem Grund suche ich nach einer Lösung, um den alternativen Bildschirm nur zu verwenden, wenn weniger nicht automatisch beendet wird.

Ich verwende dies meistens als Git-Pager, daher ist ein Wrapper-Shell-Skript, das nur dann weniger ausführt, wenn genügend Ausgabe vorhanden ist, auch in Ordnung. Zumindest wenn es keine Möglichkeit gibt, es ohne eine zu schaffen.

Diebesmeister
quelle
@thieMaster in diesem Fall, wie definieren Sie alternative Bildschirm? Ich versuche einige Tags zu säubern und verstehe die Bedeutung hier wirklich nicht
Kiwy

Antworten:

14

Seit weniger als 530 (im Dezember 2017 veröffentlicht) less --quit-if-one-screenwird nicht zum alternativen Bildschirm gewechselt, wenn weniger als ein Bildschirm angezeigt wird. Sie werden dieses Problem also nicht haben, wenn Ihre Version von less aktuell genug ist.

In früheren Versionen muss weniger entscheiden, ob der alternative Bildschirm beim Start verwendet werden soll. Sie können diese Auswahl nicht auf einen Zeitpunkt verschieben, an dem sie endet.

Sie können auch weniger anrufen, den alternativen Bildschirm verwenden und den Inhalt auf den primären Bildschirm übertragen, wenn weniger automatisch beendet wird. Ich kenne jedoch keine Möglichkeit, eine automatische Beendigung zu erkennen.

Andererseits ist es nicht so schwierig, cat für kurze Eingaben und less für größere Eingaben aufzurufen, auch wenn die Pufferung erhalten bleibt, sodass Sie nicht warten müssen, bis die gesamte Eingabe anfängt, Inhalte in less zu sehen (der Puffer kann es sein) etwas größer - Sie werden nichts sehen, bis Sie mindestens einen Bildschirm voller Daten haben - aber nicht viel mehr).

#!/bin/sh
n=3  # number of screen lines that should remain visible in addition to the content
lines=
newline='
'
case $LINES in
  ''|*[!0-9]*) exec less;;
esac
while [ $n -lt $LINES ] && IFS= read -r line; do
  lines="$lines$newline$line"
done
if [ $n -eq $LINES ]; then
  { printf %s "$lines"; exec cat; } | exec less
else
  printf %s "$lines"
fi

Möglicherweise möchten Sie lieber die Zeilen auf dem Hauptbildschirm sehen, wenn sie eingehen, und zum alternativen Bildschirm wechseln, wenn die Zeilen einen Bildlauf verursachen würden.

#!/bin/sh
n=3  # number of screen lines that should remain visible in addition to the content
beginning=
newline='
'
# If we can't determine the terminal height, execute less directly
[ -n "$LINES" ] || LINES=$(tput lines) 2>/dev/null
case $LINES in
  ''|*[!0-9]*) exec less "$@";;
esac
# Read and display enough lines to fill most of the terminal
while [ $n -lt $LINES ] && IFS= read -r line; do
  beginning="$beginning$newline$line"
  printf '%s\n' -- "$line"
  n=$((n + 1))
done
# If the input is longer, run the pager
if [ $n -eq $LINES ]; then
  { printf %s "$beginning"; exec cat; } | exec less "$@"
fi
Gilles 'SO - hör auf böse zu sein'
quelle
5
"Weniger muss entscheiden, ob der alternative Bildschirm beim Start verwendet werden soll. Sie können diese Auswahl nicht auf den Zeitpunkt verschieben, an dem sie beendet wird." - obwohl es es anscheinend nicht tut, aber es konnte einfach keine Ausgabe (wie Terminalinitialisierungsbefehle oder tatsächliche Daten) aufschieben, bis es X Zeilen empfangen hat. Wenn stdin erschöpft ist, während X <TERMINAL_LINES ist, wird einfach alles auf stdout und exit
ausgegeben
1
Am Ende habe ich eine modifizierte Version Ihres ersten Codebeispiels verwendet: gist.github.com/ThiefMaster/8331024 ($ LINES war leer, als es als Git-Pager aufgerufen wurde, und ich glaube, Sie haben das Inkrementieren vergessen $n)
ThiefMaster
@ThiefMaster Danke für das Feedback. Beachten Sie, dass Sie #!/bin/bashIhr Skript einfügen sollten, da Sie ein bash-spezifisches Konstrukt verwenden, da Ihr Skript auf Systemen (wie Ubuntu) /bin/shohne bash nicht funktioniert .
Gilles 'SO- hör auf böse zu sein'
3
Diese Idee hat mir sehr gut gefallen und ich habe sie weiterentwickelt (mit mehr Funktionen): github.com/stefanheule/smartless
stefan
1
@ThiefMaster: Kann lessoptional auch beenden, wo der aktuelle Inhalt des Bildschirms nach dem Senden der un-init-Zeichenfolge gedruckt wird (aber nicht) . Sie könnten also den Vorteil haben, dass der alternative Bildschirm den Bildlauf nicht überfüllt, sondern den relevanten Teil der Manpage oder was auch immer nach dem Beenden auf dem Terminal belässt.
Peter Cordes
9

GNU less v. 530 enthält den Fedora-Patch, auf den @ paul-antoine-arras verweist, und gibt die Terminal-Initialisierungssequenz nicht mehr aus, wenn er --quit-if-one-screenverwendet wird und die Eingabe auf einen Bildschirm passt.

eigengrau82
quelle
4
Homebrew-Benutzer unter Mac OS können dieses Verhalten sofort erzielen brew install less, indem $LESSsie F ausführen und sicherstellen, dass X weggelassen wird.
Ryan Patterson
Das ist meine Lieblingsantwort. Ich habe Less 5.3.0 sofort von GNU heruntergeladen und selbst kompiliert. Toller Tipp!
iBug
5

Möchtest git log -Gregexdu für langsame Eingaben :

A) Zeilen, die auf dem Hauptbildschirm angezeigt werden, sobald sie eingehen, und dann zum alternativen Bildschirm wechseln, sobald ein Bildlauf erforderlich ist (sodass die erste $LINESAusgabe immer in Ihrem Bildlauffeld angezeigt wird); Wenn ja, fahren Sie mit der zweiten Antwort von Gilles fort .

B) Zeilen, die auf dem alternativen Bildschirm angezeigt werden sollen, aber beenden Sie den alternativen Bildschirm, und drucken Sie die Zeilen auf dem Hauptbildschirm aus, wenn sich herausstellt, dass kein Bildlauf erforderlich ist (daher wird in Ihrem Bildlauf keine Ausgabe angezeigt, wenn ein Bildlauf erforderlich war). Verwenden Sie in diesem Fall das folgende Skript:

Es tees die Eingabe in eine temporäre Datei, dann einmal lessverlässt er catdie temporäre Datei s , wenn es weniger Zeilen als die Bildschirmhöhe enthält:

#!/bin/bash

# Needed so less doesn't prevent trap from working.
set -m
# Keeps this script alive when Ctrl+C is pressed in less,
# so we still cat and rm $TMPFILE afterwards.
trap '' EXIT

TXTFILE=$(mktemp 2>/dev/null || mktemp -t 'tmp')

tee "$TXTFILE" | LESS=-FR command less "$@"

[[ -n $LINES ]] || LINES=$(tput lines)
[[ -n $COLUMNS ]] || COLUMNS=$(tput cols)
# Wrap lines before counting, unless you pass --chop-long-lines to less
# (the perl regex strips ANSI escapes).
if (( $(perl -pe 's/\e\[?.*?[\@-~]//g' "$TXTFILE" | fold -w "$COLUMNS" | wc -l) < $LINES )); then
    cat "$TXTFILE"
fi

rm "$TXTFILE"

Verwenden Sie es mit export PAGER='/path/to/script'. Das sollte ausreichen, um gites zu nutzen, es sei denn, Sie haben es bereits überschrieben core.pager.

Informationen zu möglichen Verbesserungen finden Sie auch in meiner etwas umfangreicheren Version dieses Skripts unter: https://github.com/johnmellor/scripts/blob/master/bin/least

John Mellor
quelle
3

Dieses Problem wurde in Red Hat-basierten Distributionen seit langem behoben, indem das Verhalten der Option -F im lessQuellcode geändert wurde : Sehen Sie sich diesen Patch aus dem Fedora-Projekt an, dessen erste Version aus dem Jahr 2008 stammt terminal (dh die maximale Anzahl von Zeilen, die gleichzeitig angezeigt werden können) und um die Initialisierungs- und Deinitialisierungssequenzen wegzulassen, wenn die Datei in einen Bildschirm passt. Somit können die Optionen -X und -F unabhängig von der Dateilänge konsistent verwendet werden.

parras
quelle