less --quit-if-one-screen sem --no-init

27

Eu estou em um terminal que suporta a tela alternativa que é usada por menos, vim, etc. para restaurar a exibição anterior depois de sair. Esse é um bom recurso, mas realmente quebra a opção --quit-if-one-screen de less , já que nesse caso menos alterna para a tela alternativa, exibe seus dados, descobre que há apenas uma tela e sai, levando o conteúdo da alternativa tela com ele.

A solução normalmente sugerida é usar a opção --no-init para evitar o uso da tela alternativa. No entanto, isso é um pouco feio porque eu quero usá-lo no caso de menos atuar como um pager. Portanto, estou procurando uma solução para usar a tela alternativa apenas se menos não terminar automaticamente.

Eu vou usar isso principalmente como pager do Git, então um script de shell que só roda menos no caso de haver saída suficiente também seria bom. Pelo menos se não há como fazer isso sem um.

    
por ThiefMaster 31.12.2013 / 19:24

4 respostas

12

Desde menos 530 (lançado em dezembro de 2017), less --quit-if-one-screen não alterna para a tela alternativa se ler menos de uma tela inteira. Então você não terá esse problema se a sua versão de menos for recente o suficiente.

Em versões anteriores, menos é necessário decidir se deve usar a tela alternativa quando ela for iniciada. Você não pode adiar essa escolha para quando terminar.

Você pode chamar menos, usar a tela alternativa e enviar o conteúdo para a tela principal, se menos terminar automaticamente. No entanto, não conheço uma maneira de detectar a terminação automática.

Por outro lado, não é tão difícil chamar o cat para entradas curtas e menos para entradas maiores, mesmo preservando o buffer para que você não precise esperar que toda a entrada comece a ver o material em menos (o O buffer pode ser um pouco maior - você não verá nada até que tenha pelo menos uma tela cheia de dados - mas não muito mais).

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

Você pode preferir ver as linhas na tela principal conforme elas entram e alternar para a tela alternativa se as linhas causarem a rolagem.

#!/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
    
por 01.01.2014 / 01:00
8

GNU less v. 530 incorpora o patch do Fedora referido por @ paul-antoine-arras e não emitirá mais a seqüência de inicialização do terminal quando --quit-if-one-screen for usado e a entrada couber em um tela.

    
por 20.03.2018 / 09:19
5

Para entradas lentas, como git log -Gregex , você quer:

A) Linhas a aparecer no ecrã principal à medida que entram e, em seguida, mudar para o ecrã alternativo, uma vez que é necessário efectuar a rolagem (para que o primeiro $LINES da saída apareça sempre no seu deslocamento); se assim for, vá com o segundo de as respostas de Gilles .

B) linhas para aparecer na tela alternativa, mas saia da tela alternativa e imprima as linhas na tela principal se a rolagem for desnecessária (assim nenhuma saída aparecerá na sua rolagem se a rolagem for necessária); Em caso afirmativo, use o script abaixo:

É tee s a entrada para um arquivo temporário, então, uma vez less sai cat s do arquivo temporário se ele contiver menos linhas que a altura da tela:

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

Use com export PAGER='/path/to/script' . Isso deve ser o suficiente para tornar git usá-lo, a menos que você já tenha substituído core.pager .

Para possíveis melhorias, veja também minha versão um pouco mais elaborada deste script em: link

    
por 23.05.2015 / 20:55
3

Isso tem sido resolvido em distros baseadas no Red Hat, modificando o comportamento da opção -F em less source code: veja este patch do Projeto Fedora, cuja primeira versão data de 2008. A idéia é simplesmente obter a altura do terminal (ou seja, o número máximo de linhas que podem ser exibidas de uma só vez) e omitir as seqüências de inicialização e de inicialização quando o arquivo se encaixa em uma tela. Assim, nenhuma necessidade para a opção -X e -F pode ser usada consistentemente em qualquer tamanho de arquivo.

    
por 16.03.2017 / 17:34

Tags