fish shell:仅当先前的输出存在时才在提示前添加换行符
fish shell: add newline before prompt only when previous output exists
(免责声明:我使用的是鱼,但这同样适用于 bash)
我当前的 shell 在提示符之前打印一个换行符,因此我可以在命令输出之间轻松找到它。
# [...]
echo # newline before prompt
echo -s $arrow ' ' $cwd $git_info
echo -n -s '❯ '
但是,当没有先前的输出时,也会打印换行符,例如使用 printf "3c"
清除终端后(或首次打开终端时):
<--- bad newline: no previous output
➜ /some/dir
❯ command1
output...
<--- good newline
➜ /some/dir
❯ command2
问题:有什么办法可以摆脱这个审美上的小烦恼吗?
编辑 #1:
澄清一下:“没有以前的输出”是指我的控制台的内容是空的,即在(重新)初始化终端之后(因为 that's all printf "3c"
does)。
编辑:post 编辑得更便携。
这是我在 bash 中的做法:
__PROMPT_NEWLINE=$'\nVVV '
__set_missing_newline_fix()
{
local CURPOS
echo -en "3[6n" # ANSI DSR
read -s -d R CURPOS
CURPOS=${CURPOS#*;}
if [ $CURPOS -eq 1 ]; then
__MISSING_NEWLINE_FIX=""
else
__MISSING_NEWLINE_FIX="$__PROMPT_NEWLINE"
fi
}
PROMPT_COMMAND=__set_missing_newline_fix
PS1="${__MISSING_NEWLINE_FIX}\w > "
请注意,它配置为在我的提示符前加上 VVV
前缀,让我知道最后一条命令没有以换行符结尾。
演示:
$ source bashrc.sh
/tmp/so/newline > echo hello
hello
/tmp/so/newline > echo -n hello
hello
VVV /tmp/so/newline >
小丑:
ANSI DSR 将导致终端将其当前光标位置写为输入。由于我们是交互式 shell,该输入可用于 shell 的标准输入,所以我们只是 read -s
它(没有回显)。
在上面的 link 中,您会看到响应的格式为 CSI Pl; Pc R
,因此我们告诉 read
阅读并包括 R
-d R
.
然后我们使用 bash'“删除匹配前缀”语法 ${CURPOS#*;}
提取 Pc
部分,该语法删除包括分号 ;
在内的所有内容。
然后,如果光标位置不为1,即我们不在换行符的开头,我们手动在提示中添加一个换行符。
ANSI DSR 应该适用于每个与 ANSI 兼容的终端,但如果您遵循 link,您会发现它并没有字面上说 3[6n
,而是 CSI 6 n
. CSI is the beginning of an escape sequence。转义序列以 ASCII 27 ESC 字符(八进制 033)开头。
在我最初的回答中,我使用了 \E
,其中 bash' 内置 echo -e
命令解析与 3
相同,因此上面的编辑。
Stock fish 已经处理了这个(并且已经处理了很多年),不需要提示来做。
当输出未以换行符结尾时,您会看到“缺少换行符”,如“¶”或“⏎”,后跟一个换行符,然后才是您的提示。
exec 事件在几年前合并到 fish-shell 中。我想你可以在这里使用这些。它们的工作方式类似于其他语言中的事件生命周期挂钩。 https://github.com/fish-shell/fish-shell/pull/1666
作为测试,我创建了一个名为 postexec-newline.fish 的文件,其中包含以下内容:
function postexec_test --on-event fish_postexec
echo
end
发出 source postexec-newline.fish
后,您描述的行为已被观察到。当使用 C-l 清除屏幕时,换行符也不可见,我认为这就是这种功能的表现方式。
如果您希望永久更改,此功能可以存在于 config.fish 中。
(免责声明:我使用的是鱼,但这同样适用于 bash)
我当前的 shell 在提示符之前打印一个换行符,因此我可以在命令输出之间轻松找到它。
# [...]
echo # newline before prompt
echo -s $arrow ' ' $cwd $git_info
echo -n -s '❯ '
但是,当没有先前的输出时,也会打印换行符,例如使用 printf "3c"
清除终端后(或首次打开终端时):
<--- bad newline: no previous output
➜ /some/dir
❯ command1
output...
<--- good newline
➜ /some/dir
❯ command2
问题:有什么办法可以摆脱这个审美上的小烦恼吗?
编辑 #1:
澄清一下:“没有以前的输出”是指我的控制台的内容是空的,即在(重新)初始化终端之后(因为 that's all printf "3c"
does)。
编辑:post 编辑得更便携。
这是我在 bash 中的做法:
__PROMPT_NEWLINE=$'\nVVV '
__set_missing_newline_fix()
{
local CURPOS
echo -en "3[6n" # ANSI DSR
read -s -d R CURPOS
CURPOS=${CURPOS#*;}
if [ $CURPOS -eq 1 ]; then
__MISSING_NEWLINE_FIX=""
else
__MISSING_NEWLINE_FIX="$__PROMPT_NEWLINE"
fi
}
PROMPT_COMMAND=__set_missing_newline_fix
PS1="${__MISSING_NEWLINE_FIX}\w > "
请注意,它配置为在我的提示符前加上 VVV
前缀,让我知道最后一条命令没有以换行符结尾。
演示:
$ source bashrc.sh
/tmp/so/newline > echo hello
hello
/tmp/so/newline > echo -n hello
hello
VVV /tmp/so/newline >
小丑:
ANSI DSR 将导致终端将其当前光标位置写为输入。由于我们是交互式 shell,该输入可用于 shell 的标准输入,所以我们只是 read -s
它(没有回显)。
在上面的 link 中,您会看到响应的格式为 CSI Pl; Pc R
,因此我们告诉 read
阅读并包括 R
-d R
.
然后我们使用 bash'“删除匹配前缀”语法 ${CURPOS#*;}
提取 Pc
部分,该语法删除包括分号 ;
在内的所有内容。
然后,如果光标位置不为1,即我们不在换行符的开头,我们手动在提示中添加一个换行符。
ANSI DSR 应该适用于每个与 ANSI 兼容的终端,但如果您遵循 link,您会发现它并没有字面上说 3[6n
,而是 CSI 6 n
. CSI is the beginning of an escape sequence。转义序列以 ASCII 27 ESC 字符(八进制 033)开头。
在我最初的回答中,我使用了 \E
,其中 bash' 内置 echo -e
命令解析与 3
相同,因此上面的编辑。
Stock fish 已经处理了这个(并且已经处理了很多年),不需要提示来做。
当输出未以换行符结尾时,您会看到“缺少换行符”,如“¶”或“⏎”,后跟一个换行符,然后才是您的提示。
exec 事件在几年前合并到 fish-shell 中。我想你可以在这里使用这些。它们的工作方式类似于其他语言中的事件生命周期挂钩。 https://github.com/fish-shell/fish-shell/pull/1666
作为测试,我创建了一个名为 postexec-newline.fish 的文件,其中包含以下内容:
function postexec_test --on-event fish_postexec
echo
end
发出 source postexec-newline.fish
后,您描述的行为已被观察到。当使用 C-l 清除屏幕时,换行符也不可见,我认为这就是这种功能的表现方式。
如果您希望永久更改,此功能可以存在于 config.fish 中。