终端应用作为窗口应用

Table of Contents

将终端应用像窗口一样使用,是我快捷使用tui程序的一种方式。至于什么是像窗口应用一样来使用?这句话听着会有点奇怪,举个例子来讲,经常使用终端应用的开发者们应该都用过vim这种典型tui程序。

通常使用vim的流程就是切换到终端窗口页面,然后输入vim xxx 就可以打开一个文件开始编辑了。这样一套操作,其实使用起来已经非常快速了。但vim这种终端应用本身就是启动修改完毕后就关闭掉的一次性应用,除非像ide一样用它,一般人是没有需要常驻在后台的需求。

而有的tui程序,比如有名的邮件客户端mutt或者irc客户端weechat这类应用,就需要长期在后台运行,保持网络连接和数据更新。

jobs fg bg & tmux

终端应用作为窗口应用.org_20240817_120426_KrD4lP.png

有的人喜欢用jobs、fg、bg的方式,通过ctrl+z将应用放到后台,然后要使用的时候再fg [job number]切换回前台来使用。这样可以方便得在不同应用之间切换,而不需要在使用其它程序的时候就关闭当前应用。但是这样有一个缺点就是当前终端会话退出之后,所有在后台的job都会被kill掉。

所以有的人更喜欢把这类常驻后台的应用放在终端复用器tmux中,然后通过对tmux里的window切换来使用不同的程序。就算要退出之后让使其在后台跑,只需要通过deattach tmux session的这种方式。

不过不管是jobs的或者tmux的方式也好,每次使用其它应用都需要在终端中输入一些命令或者快捷键来进行切换。而且很多时候,开发者日常使用过程中,不会全程都在终端里。

比如在浏览器中浏览网页时,需要使用newsboat去看看rss里的订阅,就需要先切换到终端窗口然后用快捷键切换tmux的不同window再使用。这中间就多了一个切换到终端窗口的步骤,而且还要每次都输入命令或者快捷键来切换,非常麻烦。

alacritty + wcsharp

我期望的操作方式是,只要按一下快捷键就跳出一个终端窗口并聚焦就可以开始操作了。 所谓的终端应用像窗口一样使用,就是给每一个tui应用都分配一个terminal窗口。多个tui程序就是多个窗口程序

在这个基础上,把一些快捷键映射到高频率应用来触发窗口。这样一来我就可以迅速切换使用终端应用,再也不需要频繁得切换窗口然后再用命令或者应用的快捷键进行终端的上下文切换。

基础的流程想通之后就可以开始实现了,我选择的终端模拟器是alacritty,它是一个跨平台的应用,而且可定制性不错。但是alacritty没有自带全局快捷键触发窗口的功能,所以还需要一套窗口管理的套件来达到触发的效果。

我目前主要使用的系统是win,所以针对的窗口管理也主要是windows平台。对于全局按键的触发需要常驻后台这种需求,需要一些编译好的二进制程序,我就参考了以前写的一些管理窗口的powershell脚本,用c#写了一套窗口管理的工具叫wcsharp。这样一来就可以通过alacritty和wcsharp构建自己的工作流了。

例子

下面就是一个我针对weechat的启动脚本:

$title="irc"
$c=@"
pwsh -C w weechat
"@
$a="/C ""start /b  alacritty.exe --working-directory . --option window.position.y=100 window.position.x=100  window.dimensions.columns=180 window.dimensions.lines=50 window.decorations=""""""full"""""" --title $title -e $c"""

Start-Process -FilePath "cmd.exe" -ArgumentList "$a" -WindowStyle Hidden
sleep 1
wcs-hide-altab $title
Start-Process -FilePath "wcs-tray.exe" -ArgumentList "$title", '"ctrl+alt+i"' -WindowStyle Hidden

这里用的几个变量,title表示要终端模拟器的窗口的标题,c表示alacritty启动之后执行的command,a表示cmd的启动参数。通过start-process运行之后,就会启动一个带有rss标题的alacritty窗口,并且在其中运行了weechat这个irc客户端。

然后再sleep 1秒等待窗口出现,再用wcs-hide-altab把窗口在任务栏和alt+tab/win+tab的快捷键中隐藏掉,最后用wcs-tray来设置快捷键触发窗口。

这样一来整个alacritty窗口就能通过托盘图标或者快捷键来进行显示隐藏使用了,就像这个例子里我通过ctrl+alt+i这个快捷键,来触发标题为irc的终端窗口,以此来达到快捷访问的目的。