在 GNU 屏幕上显示完整命令,标题中包含 bash,并与 Vim 缓冲区正确交互

在 GNU 屏幕上显示完整命令,标题中包含 bash,并与 Vim 缓冲区正确交互

网络上有很多关于此问题的问题,但我发现有两个共同点之一:

  • 他们给出了手动解决方案,仅打印当前正在运行的程序(不带参数)
  • 使用 zsh preexec 功能(尽管我不确定它如何与屏幕交互)。我正在寻找 Bash 解决方案。

如何让屏幕标题显示整个命令运行,例如,如果我运行 3 个长时间运行的 Python 脚本,我也可以在标题中看到脚本名称?为了奖励积分,如果我能让它继续显示最后运行的命令那就更好了。

我当前的设置:

  • 出口PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"'
  • PS1以。。结束>
  • shelltitle ">|bash"

我试过:

  • \033k在and之间添加内容\033- 与${BASH_COMMAND}
  • 使用陷阱调试设置外部附加标题,因为对于没有屏幕的 XTERM,我知道解决方案。这与PS1.

以及上述内容的变体。我想要一个通过屏幕的解决方案,因此窗口标题和屏幕窗口列表都显示完整的命令。

作为奖励,如果 Screen 与 Vim 能够很好地交互,我真的很喜欢它,因此可以更改缓冲区/打开新文件/等等。将在屏幕标题中动态更新。

答案1

一年后,这是我使用陷阱的解决方案。这将显示主机名、当前信息PWD和命令(如果在屏幕上,还显示屏幕内容)。这可以在set_screen_window下面轻松定制。所有东西都应该放在你的.bashrc.

首先使用一些辅助函数来检查我是否打开screen

export PROMPT_COMMAND=''
if [[ "$TERM" == "screen"* ]]; then
    screen_title_slicer() { echo "${1:0:40}"; } # Arbitrary cut off. use echo $1 for full.
    screen_title_format='\ek%s\e\\'
else
    screen_title_slicer() { echo "${1//[^[:print:]]/}"; }
    screen_title_format='\033]0;%s\007'
fi

构建命令的核心依赖于有用的BASH_COMMAND.我做了一些自定义的事情fg(例如显示原始命令)和cd(获取真实的目录):

ready="Ready!"

set_screen_window() {
    title_string=$1
    [ -z "$title_string" ] && title_string=$(screen_title_slicer "$BASH_COMMAND")
    [ "$title_string" = "fg" ] && read -ra job < <( jobs %% 2> /dev/null )
    [ "$title_string" = "fg " ] && read -ra job < <(jobs "${title_string:3} 2> /dev/null")
    if [ ${#job[@]} -gt 0 ]; then
        title_string=$(screen_title_slicer "${job[2]}")
    fi
    cwd=$PWD
    if [ "${title_string::3}" = "cd " ]; then
        cwd=$(  eval cd "$(awk '{print $2}' <<< "$BASH_COMMAND")" &> /dev/null && pwd)
        [ -z "$cwd" ] && cwd=$PWD
        title_string="$ready"
    fi
    [ "$title_string" = "cd" ] && title_string=$ready && cwd=$HOME
    printf "$screen_title_format" "$HOSTNAME -- ${cwd//$HOME/\~}> $title_string" > "$(tty)"
    unset job
    unset title_string
}

现在用我的字符串初始化终端头ready,并捕获错误和调试以更新终端窗口:

set_screen_window "$ready"
trap "set_screen_window $ready" ERR
trap set_screen_window DEBUG

最后,.vimrc我们有vim具体的内容:

function! Filename()
    if @% == ""
        return "noname"
    endif
    let is_tracked=system("git ls-files " . expand("%"))
    if is_tracked == ""
        return expand("%:t")
    endif
    return gitbranch#name() . "/" . expand("%:t")
endfunction

let &titlestring = hostname() . " -- vim " . Filename()
if &term[:5] == "screen"
  set t_ts=^[k
  set t_fs=^[\
  set title
endif
autocmd TabEnter,WinEnter,BufReadPost,FileReadPost,BufNewFile * silent execute '!printf "\033]0;'.hostname().' -- vim '.Filename().'\007"'
autocmd TabEnter,WinEnter,BufReadPost,FileReadPost,BufNewFile * let &titlestring = hostname() . ' -- vim ' . Filename()

在这里Filename可以定制以获得您自己的标题风格。autocmd确保在缓冲区、窗口等之间移动时重新加载内容。gitbranch在我的示例中,有一个插件可用于git在编辑存储库中的文件时生成(如您所期望的)分支名称。

答案2

PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"'in一起使用对我来说效果很好。使用这个特定的东西会以某种方式破坏我的 PS1,所以我还添加了以下内容:.bashrcshelltitle '$ |bash'.screenrcPROMPT_COMMAND.bashrc

case "$TERM" in
    screen*) PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"';;
esac

附加示例图像 - 在窗口 0 中运行 sleep,在窗口 1 中运行 find,在窗口 2 中运行 watch,在窗口 3 中运行 ping,在窗口 4 中运行 bash。 在此输入图像描述

相关内容