少-如果没有--no-init的单屏退出


31

我在支持备用屏幕的终端上,该屏幕由less,vim等用于退出后恢复以前的显示。这是一个很好的功能,但是它确实中断了--quit-if-one-screen切换,less因为在这种情况下,切换到备用屏幕的次数减少了,显示其数据,只找出一个屏幕,然后退出,并带走了备用屏幕的内容。

通常建议的解决方法是使用--no-init开关以避免完全使用备用屏幕。但是,这有点丑陋,因为我确实希望在不太实际用作寻呼机的情况下使用它。因此,我正在寻找一种解决方案,以仅在备用屏幕不会自动终止时才使用备用屏幕。

我将主要使用它作为Git的寻呼机,因此仅在有足够输出的情况下运行较少的包装Shell脚本也可以。至少如果没有一种方法无法做到这一点。


在这种情况下,@ thieMaster如何定义备用屏幕?我尝试清洁一些标签,但我的意思确实不明白
Kiwy 2014年

Answers:


14

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

在早期版本中,更少的时间决定启动备用屏幕时是否使用备用屏幕。您不能将选择推迟到终止时。

您可以减少呼叫,让其使用备用屏幕,如果较少自动终止,则将内容显示在主屏幕上。但是我不知道检测自动终止的方法。

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

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

您可能希望在进入时在主屏幕上看到这些行,如果这些行会引起滚动,请切换到备用屏幕。

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

5
“很少需要决定在启动备用屏幕时是否使用它。您不能将选择推迟到终止时使用。” -尽管它显然不这样做,但不能简单地将任何输出(例如终端初始化命令或实际数据)推迟到收到X行之前。如果在X <TERMINAL_LINES时用尽了stdin,它只会将所有内容都转储到stdout并退出,否则它将初始化备用屏幕并执行应做的事情
ThiefMaster 2014年

1
我最终使用了第一个代码示例的修改版本:gist.github.com/ThiefMaster/8331024($git在称为git-pager时为空,我认为您忘记了递增$n
ThiefMaster 2014年

@ThiefMaster感谢您的反馈。请注意,#!/bin/bash由于使用的是bash特定的构造,因此应放入脚本,因为这是您的脚本在/bin/sh非bash的系统(例如Ubuntu)上无法使用的原因。
吉尔(Gilles)'所以

3
我真的很喜欢这个想法,并进一步发展了它(具有更多功能):github.com/stefanheule/smartless
stefan

1
@ThiefMaster:less还可以(但没有)有一种可选的方式来退出,该方式发送uninit字符串后将其打印屏幕的当前内容。因此,您可以获得备用屏幕的好处,即不会使回滚混乱,但退出后仍保留手册页的相关部分或终端上的任何内容。
彼得·科德斯

9

GNU less v。530包含@ paul-antoine-arras所指的Fedora修补程序,--quit-if-one-screen使用时不再输出终端初始化序列,并且输入适合在一个屏幕上显示。


4
在Mac OS家酿用户可以通过运行立即得到这个行为brew install less,并确保$LESS有F和遗漏X.
瑞安帕特森

这是我最喜欢的答案。我立即从GNU下载了Less 5.3.0,并自己进行了编译。很好的提示!
iBug

5

对于慢速输入(如)git log -Gregex,您是否想要:

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

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"

与结合使用export PAGER='/path/to/script'git除非您已经覆盖,否则应该足以使用它core.pager

有关可能的增强功能,另请参见我对此脚本更为充实的版本:https : //github.com/johnmellor/scripts/blob/master/bin/least


3

长期以来,通过修改less源代码中-F选项的行为,在基于Red Hat的发行版中已解决了该问题:请参阅Fedora Project的此补丁程序,其第一个版本可以追溯到2008年。终端(即一次可以显示的最大行数),并在文件适合一个屏幕时省略初始化和取消初始化序列。因此,无论文件长度如何,都可以始终使用-X选项和-F。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.