少 --quit-if-one-screen 没有 --no-init

Thi*_*ter 42 less

我在一个支持备用屏幕的终端上,less、vim 等使用它来在退出后恢复以前的显示。这是一个很好的功能,但它确实打破了--quit-if-one-screen切换,less因为在这种情况下,较少切换到备用屏幕,显示其数据,确定只有一个屏幕,然后退出,同时带走备用屏幕的内容。

通常建议的解决方法是使用--no-init开关来避免完全使用备用屏幕。但是,这有点难看,因为我确实想使用它以防万一实际上用作寻呼机。因此,我正在寻找一种解决方案,仅当 less 不会自动终止时才使用备用屏幕。

我将主要使用它作为 Git 的寻呼机,因此如果有足够的输出,只运行较少的包装 shell 脚本也可以。至少如果没有一个就没有办法做到这一点。

Gil*_*il' 24

由于少于 530(于 2017 年 12 月发布),less --quit-if-one-screen如果读取少于一屏,则不会切换到备用屏幕。因此,如果您的 less 版本足够新,则不会遇到此问题。

在早期版本中,less 必须在启动时决定是否使用备用屏幕。您不能将该选择推迟到它终止时。

您可以调用 less,让它使用备用屏幕,如果 less 自动终止,则将内容放到主屏幕上。但是我不知道检测自动终止的方法。

另一方面,对于短输入调用 cat 并为较大输入调用 less 并不困难,甚至可以保留缓冲,这样您就不必等待整个输入开始以更少的方式查看内容(缓冲区可能是稍大一点——在你有至少一屏数据之前你不会看到任何东西——但不会更多)。

#!/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
Run Code Online (Sandbox Code Playgroud)

您可能更喜欢在主屏幕上看到这些行,如果这些行会导致滚动,则切换到备用屏幕。

#!/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
Run Code Online (Sandbox Code Playgroud)

  • “Less 不必在启动时决定是否使用备用屏幕。你不能将这个选择推迟到它终止时。” - 虽然它显然没有这样做,但它不能简单地推迟任何输出(例如终端初始化命令或实际数据),直到它收到 X 行。如果在 X<TERMINAL_LINES 时 stdin 耗尽,它将简单地将所有内容转储到 stdout 并退出,否则它将初始化备用屏幕并执行它应该执行的操作 (5认同)
  • 我真的很喜欢这个想法,并进一步开发了它(具有更多功能):https://github.com/stefanheule/smartless (3认同)

小智 12

GNU less v. 530 合并了@paul-antoine-arras 引用的 Fedora 补丁,并且在--quit-if-one-screen使用时不再输出终端初始化序列并且输入适合一个屏幕。

  • Mac OS 上的 Homebrew 用户可以通过运行 `brew install less` 并确保 `$LESS` 具有 F 并省略 X 来立即获得此行为。 (10认同)

Joh*_*lor 5

对于慢速输入,例如git log -Gregex,您想要:

A) 行出现在主屏幕上,然后在需要滚动时切换到备用屏幕(因此第一个$LINES输出将始终出现在您的回滚中);如果是这样,请使用Gilles 的第二个答案

B) 出现在备用屏幕上的行,但如果不需要滚动,则退出备用屏幕并将行打印到主屏幕(因此,如果需要滚动,则回滚中不会出现任何输出);如果是这样,请使用以下脚本:

tee是临时文件的输入,如果它包含的行数少于屏幕高度,则一旦less退出它cat就是临时文件:

#!/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"
Run Code Online (Sandbox Code Playgroud)

export PAGER='/path/to/script'. 这应该足以git使用它,除非您已经覆盖了core.pager.

对于可能的增强,另请参阅我在此脚本中稍微充实的版本:https : //github.com/johnmellor/scripts/blob/master/bin/least