我刚刚意识到,使用终端时我经常弯腰驼背,因为提示符总是位于垂直最大化的终端窗口的底部。
我希望提示位于窗口的垂直中间(或者位于我眼睛指向的附近的点)。
您可能会说我可以调整窗口大小并实现这一点,但有时我喜欢垂直空间(例如运行时ls -la
)。因此,理想情况下,我可以在某个点和窗口底部之间切换提示的位置。
(我在 MacOS 下使用带有 zsh 的 iTerm,但我对一种不可知/通用的方法感兴趣)
答案1
以下代码(使用 zsh 功能,但该原理也可以用于其他 shell)定义了两个 shell 函数,prompt_middle
和prompt_restore
。
第一个函数通过强制在提示符下方留出适当数量的空行,使提示符始终位于终端中间上方。后一个函数恢复正常行为。
您可以将这些功能分配给一些快捷方式或使用一些逻辑在这两种模式之间切换。
# load terminfo modules to make the associative array $terminfo available
zmodload zsh/terminfo
# save current prompt to parameter PS1o
PS1o="$PS1"
# calculate how many lines one half of the terminal's height has
halfpage=$((LINES/2))
# construct parameter to go down/up $halfpage lines via termcap
halfpage_down=""
for i in {1..$halfpage}; do
halfpage_down="$halfpage_down$terminfo[cud1]"
done
halfpage_up=""
for i in {1..$halfpage}; do
halfpage_up="$halfpage_up$terminfo[cuu1]"
done
# define functions
function prompt_middle() {
# print $halfpage_down
PS1="%{${halfpage_down}${halfpage_up}%}$PS1o"
}
function prompt_restore() {
PS1="$PS1o"
}
$halfpage_up/down
就我个人而言,我不会在两种模式之间切换,而是使用一种更简单的方法(您需要上面的定义):
magic-enter () {
if [[ -z $BUFFER ]]
then
print ${halfpage_down}${halfpage_up}$terminfo[cuu1]
zle reset-prompt
else
zle accept-line
fi
}
zle -N magic-enter
bindkey "^M" magic-enter
这将检查当前命令行是否为空(请参阅我的其他答案),如果是,则将提示移至终端中间。现在,您可以再按一下键来快进提示ENTER
(或者您可能想称之为双击类似于双击)。
答案2
我用tput cup
将以下内容添加到.zshrc
alias ptop='tput cup $((LINES/4)) 0' # Clear quarter
alias pmid='tput cup $((LINES/2)) 0' # Clear half
alias pdown='tput cup $((3*LINES/4)) 0' # Clear 3/4th
笔记:这种方法的问题是——屏幕内容被删除。
但是,如果您有兴趣保留屏幕内容,请使用下面的方法
# Get ceiling eg: 7/2 = 4
ceiling_divide() {
ceiling_result=$((($1+$2-1)/$2))
}
clear_rows() {
POS=$1
# Insert Empty Rows to push & preserve the content of screen
for i in {1..$((LINES-POS-1))}; echo
# Move to POS, after clearing content from POS to end of screen
tput cup $((POS-1)) 0
}
# Clear quarter
alias ptop='ceiling_divide $LINES 4; clear_rows $ceiling_result'
# Clear half
alias pmid='ceiling_divide $LINES 2; clear_rows $ceiling_result'
# Clear 3/4th
alias pdown='ceiling_divide $((3*LINES)) 4; clear_rows $ceiling_result'