1
20
2015
10

恢复 tmux 窗口名称的自动设置

tmux 我已经用了好几年了,然而从未使用得多么深入,偶尔有些小不满也一直没有去研究看看能不能解决,其中就包括这么一项:tmux 窗口名称(就是显示在状态栏上的那个)默认会随着前台所运行的命令的不同而自动变化。但是,如果窗口名称被设置过之后,不管是通过prefix A设置的,还是通过终端转义序列设置的,之后它就再也不会自动变化了。

本来这也不是多大的事。偶尔会因为不小心往终端输出了些二进制数据弄乱终端标题,我要么是把它重新设置成「zsh」,要么直接关掉再开一个窗口,反正是很容器的事情。可是呢,公司服务器的 zsh 会把终端标题设置成当前的工作目录,ssh 退出时也不会清除。本来呢,我是专门再开一个终端来跑,完事之后再关掉。可是,习惯的力量是巨大的,我还是会时不时地在 tmux 窗口里 ssh 连过去,然后 tmux 窗口名称就坏掉了。

今天我终于决定把此事查个水落石出。既然主动设置之后就不再变化,那么 tmux 肯定用某种方法把「主动设置过窗口名称」这个信息给记录了下来。然后我就去 tmux 源码里找啊找,结果很意外地看到一个叫「automatic-rename」选项!敢情 tmux 早知道有人会对此不爽,专门弄了个选项呀。然后直接在1500行的 man 文档里搜索这个选项名称就可以了。

默认,tmux 的「automatic-rename」选项的全局值为「on」,也就是根据正在前台运行的命令自动设置。一旦窗口获得了一个用户或者程序指定的标题,不管是创建窗口时指定的,还是后来通过「rename-window」改的,又或者是通过终端转义序列改的,窗口局部的「automatic-rename」值就会被设置为「off」,也就是不会再自动变化了。所以,想要恢复 tmux 窗口的这个行为,只要把这个选项再次打开即可:

tmux setw automatic-rename on

或者,取消设置此窗口的局部值,这样 tmux 会使用全局值:

tmux setw -u automatic-rename

终于又解决了一个困扰已久的小麻烦~话说,直接去源码里寻找,远比在比 wget 手册还要长的 manpage 里乱逛要高效呢=w=

Category: Linux | Tags: tmux
8
24
2011
22

改变终端下的光标颜色,包括 screen 和 tmux!

曾经在Ubuntu中文论坛里看到一个改变光标颜色的方法,用光标颜色来指示是在 Vim 的普通模式还是插入模式下(因为 gnome-terminal 不支持使用转义序列改变光标形状)。Vim Wiki 上的 tip

if &term =~ "xterm\|rxvt"
  silent !echo -ne "\e]12;HotPink\007"
  let &t_SI="\e]12;RoyalBlue1\007"
  let &t_EI="\e]12;HotPink\007"
  autocmd VimLeave * :!echo -ne "\e]12;green\007"
endif

可惜它不适用于当时我正在使用的 screen。现在我改用 tmux 了,偶然改变TERM变量测试的时候,发现光标颜色竟然改变了——虽然还附带一些“不良反应”。我想到:一定有办法来正确地改变光标颜色的!

于是求助于 Google,很快找到了这个,有了用于 screen 的转义序列。不过依旧不适用于 tmux。把“tmux”也加到关键词里再搜,终于找到了这个。根据这个帖子,screen 和 tmux 比 xterm 多出来的那些字符序列是告诉 screen 或者 tmux 把其中的字符序列直接发送到终端模拟器处理。

于是,我的 vimrc 又可以更新了:

let color_normal = 'HotPink'
let color_insert = 'RoyalBlue1'
let color_exit = 'green'
if &term =~ 'xterm\|rxvt'
  exe 'silent !echo -ne "\e]12;"' . shellescape(color_normal, 1) . '"\007"'
  let &t_SI="\e]12;" . color_insert . "\007"
  let &t_EI="\e]12;" . color_normal . "\007"
  exe 'autocmd VimLeave * :!echo -ne "\e]12;"' . shellescape(color_exit, 1) . '"\007"'
elseif &term =~ "screen"
  if !exists('$SUDO_UID')
    if exists('$TMUX')
      exe 'silent !echo -ne "\033Ptmux;\033\e]12;"' . shellescape(color_normal, 1) . '"\007\033\\"'
      let &t_SI="\033Ptmux;\033\e]12;" . color_insert . "\007\033\\"
      let &t_EI="\033Ptmux;\033\e]12;" . color_normal . "\007\033\\"
      exe 'autocmd VimLeave * :!echo -ne "\033Ptmux;\033\e]12;"' . shellescape(color_exit, 1) . '"\007\033\\"'
    else
      exe 'silent !echo -ne "\033P\e]12;"' . shellescape(color_normal, 1) . '"\007\033\\"'
      let &t_SI="\033P\e]12;" . color_insert . "\007\033\\"
      let &t_EI="\033P\e]12;" . color_normal . "\007\033\\"
      exe 'autocmd VimLeave * :!echo -ne "\033P\e]12;"' . shellescape(color_exit, 1) . '"\007\033\\"'
    endif
  endif
endif
unlet color_normal
unlet color_insert
unlet color_exit

因为 tmux 的TERM变量和 screen 的一致,所以得使用TMUX变量来判断是在 tmux 里还是在 screen 里。

最后,说下指定颜色的方法。可以使用和 HTML 中一样的#rrggbb甚至简写#rgb,也可以使用颜色名。这里有个 xterm 的颜色名表。

2011年8月25日更新:

写了个 zsh 函数:

if [[ $TERM == xterm* ]] || [[ $TERM == *rxvt* ]]; then # {{{2 设置光标颜色
  cursorcolor () { echo -ne "\e]12;$*\007" }
elif [[ $TERM == screen* ]]; then
  if [[ -n "$TMUX" ]]; then
    cursorcolor () { echo -ne "\ePtmux;\e\e]12;$*\007\e\\" }
  else
    cursorcolor () { echo -ne "\eP\e]12;$*\007\e\\" }
  fi
fi
Category: Linux | Tags: vim 终端 screen zsh tmux
5
6
2011
6

login shell 和 non-login shell 不同造成的问题

上篇说到,我在Arch下的tmux的部分环境变量有问题。于是接下来我开始调查原因。最后终于真相大白。不过在揭露真相前,先详细说说问题是什么。

自从使用zsh以后,我在Ubuntu下发现我在~/.profile中设置PATH变量的代码在tty下没有起作用。但在~/.zshrc中设置又不行,因为图形界面登录时不会读取~/.zshrc。source 它也不行,因为可能导致双重设置(在一段时间里,我总是很奇怪地发现命令补全时某些命令会出现两次。。。)。于是,最后我的方案是这样的(箭头表示 source):

.profile --> .zsh/zshrc.env   <-+
.zshrc --> ZSHRC_ENV set? --No--+

这个方案在Ubuntu下一直工作良好。但在Arch+tmux下就出问题了。在tmux中的zsh启动前,ZSHRC_ENV已经设置,于是~/.zsh/zshrc.env没有被 source,于是$PATH设置得不对了。。。

在查阅tmux N次之后,我想,可能是某个启动文件覆盖了我自己的 PATH 变量的设置。于是打开 zsh 的文档,翻到这里:

5.1 Startup/Shutdown Files

Commands are first read from /etc/zsh/zshenv; this cannot be overridden. Subsequent be- haviour is modified by the RCS and GLOBAL_RCS options; the former affects all startup files, while the second only affects global startup files (those shown here with an path starting with a /). If one of the options is unset at any point, any subsequent startup file(s) of the corresponding type will not be read. It is also possible for a file in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and GLOBAL_RCS are set by default.

Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login shell, commands are read from /etc/zsh/zprofile and then $ZDOTDIR/.zprofile. Then, if the shell is interactive, commands are read from /etc/zsh/zshrc and then $ZDOTDIR/.zshrc. Finally, if the shell is a login shell, /etc/zsh/zlogin and $ZDOTDIR/.zlogin are read.

于是发现这一切的根源在于tmux里启动的是login shell!Arch的/etc/profile中重置了$PATH/etc/profile.d/locale.sh中重置了$LANG,所以造成我的tmux下的zsh环境变量不对的问题。于是我把设置移回了~/.profile中,然后将软链接~/.zprofile指向它。locale.shpacman不知道是什么包的,所以我就把它改成了:

[ -z "$LANG" ] && export LANG=en_US.UTF-8

至此,tmux部分的问题终于解决了!

Category: Linux | Tags: arch linux zsh tmux

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com