使用tmux执行Emacs中的当前行
我认为,如果一个操作每天重复太多,就得想办法让它自动化。
我在工作的时候,常常都是一边开terminal一边开emacs。有这样一个操作每天都在重复:在Emacs中copy一行,到terminal中粘贴执行。
注意这个操作和在Emacs中直接执行shell是不同的。因为,很多时候这一行不是shell脚本,对我来说,可能是交换机的命令,我需要放到串口去执行。 也可能,terminal是登陆到remote的,这时候直接在Emacs中执行shell脚本也达不到要求。
因为我的terminal中一定是在运行tmux的,tmux又可以借助xsel把系统clipboard中的内容放入当前的buffer中。实现自动化的方法就变得很简单了。
- 在Emacs中拷贝当前行,注意在结尾加一个回车。
- 调用shell把系统clipboard中的内容放入tmux的当前buffer中。这点我搞了一个shell脚本来做,该脚本就是把当前系统clipboard中的内容放入当前tmux的buffer中:
#!/bin/bash xsel -ob | tmux load-buffer - ; tmux paste-buffer exit 0
- 如果有需要,使用wmctrl切换到对应的窗口中。
关于最后一点,是否切换到terminal窗口,我使用行尾空格来判断(反正行尾空格基本没什么用)。 如果行尾有空格,才切换到terminal,否则移动到下一行。Emacs可以开启行尾空格显示:
(setq show-trailing-whitespace t)
我是在ubuntu下,terminal使用的是 lilyterm 。 需要安装的软件如下:
apt-get install wmctrl xsel
其中xsel可以提取系统clipboard内容,wmctrl可以用来进行窗口切换。
最后函数如下:
(defun peng-lilyterm-tmux-run-current-line () "Run current line in tmux. If line is end up with space, switch to lilyterm. Else, just move to next line in Emacs." (interactive) (let* ((origin-line (thing-at-point 'line)) (switch-to (equal (s-right 1 (s-chomp (thing-at-point 'line))) " ")) (line (concat origin-line "\n"))) (kill-new line) (start-process "paste" nil "bash" "/home/pengpengxp/bin/p_paste_to_tmux.sh") (if switch-to (shell-command "wmctrl -xa lilyterm.Lilyterm") (next-line))))
- 函数中的脚本文件 /home/pengpengxp/bin/p_paste_to_tmux.sh 里就是 上文 提到的。
- 如果你的terminal不是lilyterm,就改一下最后的 lilyterm.Lilyterm 就可以了。
可以使用
wmctrl -xl
命令来查当前打开的所有的窗口。
如果你觉得本文不错,欢迎 donate