menos --quit-if-one-screen sin --no-init


31

Estoy en un terminal que admite la pantalla alternativa que es utilizada por less, vim, etc. para restaurar la pantalla anterior después de salir. Esa es una buena característica, pero realmente rompe el --quit-if-one-screencambio lessya que en ese caso menos cambia a la pantalla alternativa, muestra sus datos, descubre que solo hay una pantalla y sale, llevándose el contenido de la pantalla alternativa.

La solución alternativa comúnmente sugerida es usar el --no-initinterruptor para evitar usar la pantalla alternativa por completo. Sin embargo, esto es algo feo, ya que no quiero usarlo en caso menos en realidad actúa como un localizador. Por lo tanto, estoy buscando una solución para usar la pantalla alternativa solo si menos no termina automáticamente.

Lo usaré principalmente como el buscapersonas de Git, por lo que un script de shell de envoltura que solo se ejecuta menos en caso de que haya suficiente salida también estaría bien. Al menos si no hay forma de hacerlo sin uno.


@thieMaster en este caso, ¿cómo define la pantalla alternativa? Intento limpiar algunas etiquetas y realmente no entiendo el significado aquí
Kiwy

Respuestas:


14

Dado que menos de 530 (lanzado en diciembre de 2017), less --quit-if-one-screenno cambia a la pantalla alternativa si lee menos de una pantalla completa. Por lo tanto, no tendrá este problema si su versión de less es lo suficientemente reciente.

En versiones anteriores, menos tiene que decidir si usar la pantalla alternativa cuando se inicia. No puede diferir esa elección cuando termine.

Podría llamar menos, dejar que use la pantalla alternativa y colocar el contenido en la pantalla principal si menos termina automáticamente. Sin embargo, no conozco una forma de detectar la terminación automática.

Por otro lado, no es tan difícil llamar a cat para entradas cortas y menos para entradas más grandes, incluso preservando el almacenamiento en búfer para que no tenga que esperar a que toda la entrada comience a ver cosas en menos (el búfer puede ser un poco más grande, no verá nada hasta que tenga al menos una pantalla llena de datos, pero no mucho más).

#!/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

Es posible que prefiera ver las líneas en la pantalla principal a medida que entran y cambiar a la pantalla alternativa si las líneas causan desplazamiento.

#!/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

55
"Less tiene que decidir si usar la pantalla alternativa cuando se inicia. No puede diferir esa opción cuando finalice". - aunque aparentemente no lo hace, pero no podría simplemente diferir cualquier salida (como comandos de inicialización de terminal o datos reales) hasta que haya recibido X líneas. Si stdin se agota mientras X <TERMINAL_LINES simplemente volcaría todo en stdout y saldría, de lo contrario inicializaría la pantalla alternativa y haría lo que se supone que debe hacer
ThiefMaster

1
Terminé usando una versión modificada de su primer ejemplo de código: gist.github.com/ThiefMaster/8331024 ($ LINES estaba vacío cuando se lo llamó como git-pager y creo que olvidó incrementar $n)
ThiefMaster

@ThiefMaster Gracias por los comentarios. Tenga en cuenta que debe colocar #!/bin/bashsu script ya que está utilizando una construcción específica de bash, ya que es su script que no funcionará en sistemas (como Ubuntu) donde /bin/shno es bash.
Gilles 'SO- deja de ser malvado'

3
Realmente me gustó esta idea, y la desarrollé un poco más (con más funciones): github.com/stefanheule/smartless
stefan

1
@ThiefMaster: lesstambién podría (pero no tiene) una forma opcional de salir donde imprime el contenido actual de la pantalla después de enviar la cadena un-init. Por lo tanto, podría tener el beneficio de que la pantalla alternativa no satura el desplazamiento hacia atrás, pero aún así deja la parte relevante de la página de manual o lo que sea en el terminal después de salir.
Peter Cordes

9

GNU less v. 530 incorpora el parche Fedora al que hace referencia @ paul-antoine-arras y ya no generará la secuencia de inicialización del terminal cuando --quit-if-one-screense usa y la entrada cabe en una pantalla.


44
Los usuarios de Homebrew en Mac OS pueden obtener este comportamiento de inmediato al ejecutar brew install lessy asegurarse de que $LESStiene F y omite X.
Ryan Patterson

Esta es mi respuesta favorita. Inmediatamente descargué Less 5.3.0 de GNU y lo compilé yo mismo. Gran sugerencia!
iBug

5

Para entradas lentas, como git log -Gregex, ¿quieres:

A) las líneas que aparecen en la pantalla principal a medida que entran, luego cambian a la pantalla alternativa una vez que se necesita desplazamiento (por lo que el primero $LINESde la salida siempre aparecerá en su desplazamiento hacia atrás); Si es así, vaya con la segunda de las respuestas de Gilles .

B) aparecerán líneas en la pantalla alternativa, pero salga de la pantalla alternativa e imprima las líneas en la pantalla principal si el desplazamiento resulta innecesario (por lo que no aparecerá ningún resultado en su desplazamiento hacia atrás si fuera necesario); Si es así, utilice el siguiente script:

Es teela entrada a un archivo temporal, luego, una vez que lesssale, cates el archivo temporal si contiene menos líneas que la altura de la pantalla:

#!/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"

Úselo con export PAGER='/path/to/script'. Eso debería ser suficiente para gitusarlo, a menos que ya lo haya anulado core.pager.

Para posibles mejoras, vea también mi versión un poco más carnosa de este script en: https://github.com/johnmellor/scripts/blob/master/bin/least


3

Esto se ha resuelto durante mucho tiempo en distribuciones basadas en Red Hat modificando el comportamiento de la opción -F en el lesscódigo fuente: vea este parche del Proyecto Fedora, cuya primera versión se remonta a 2008. La idea es simplemente obtener la altura de la terminal (es decir, el número máximo de líneas que se pueden mostrar a la vez) y para omitir las secuencias de inicialización y desinicialización cuando el archivo cabe en una pantalla. Por lo tanto, no es necesario utilizar la opción -X y -F se puede usar de forma coherente independientemente de la longitud del archivo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.