Emacs Workspace
在使用 doom emacs 的时候 workspace
是我们经常使用到的功能.那么如何在进行buffer切换时找到自己想要的空间呢?比如快速找vterm这个空间, 或者说http这个空间呢?
痛点
在使用 doom emacs 的时候 workspace
是我们经常使用到的功能. 但是默认的workspace在设置workspace的名称的时候使用了编号(#No.)进行命名,没有实际的上下文含义.
我经常开多个workspace, 频繁的在多个workspace中切换. 一般在做后端java开发的时候,我习惯至少要开四个workspace, 工作中往往需要再给空间另外命名. 但每次关闭又需要重新命名操作, 非常的麻烦.
- lsp-java 代码工程空间
- ejcsql 数据库空间
- rest-client 作为测试接口的空间
- org-mode 文档空间
那么如何在进行buffer切换时找到自己想要的空间呢?比如快速找vterm这个空间, 或者说http这个空间呢?
解决
其实最终期望的效果是释放手动设置workspace的名称这个动作, 尝试用elisp来帮我们实现利用当前buffer的名称作为workspace的名称.
可以利用 pre-command-hook 钩子在每次执行命令的时候对 workspace 的名称进行一次设置. 为了提升效率, 当判定出buffer-name与workspace-name相同时, 则不需要再次设置workspace的名称. 此外在进行recentf、fzf等操作的时候 workspace 名称无需跟随改变. 则有了下面的代码.
需要注意的是workspace要求名称唯一,因此如果我们在2个buffer中打开了同一个文件此时又将workspace的名称设置成了buffer的名称则workspace会提示异常(名称未发生改变).
到这里猛然发现想要的不就是 tab 标签栏的效果吗?Anyway 就是习惯了看 workspace ~ happy.
(add-hook 'pre-command-hook (lambda ()
(if (or (eq (buffer-name) (+workspace-current-name))
(string-match "*Minibuf" (buffer-name)) )
nil (+workspace:rename (buffer-name)))))
eslip代码学习
需要注意的是, string-match 这个函数当不匹配的时候就返回nil,匹配的时候返回数字. 其实它的结果可直接被if语句用于判断条件的.无需再进行转换了.另外pre-command-hook和post-command-hook这两个hook都可以实现本次的功能, 但post-command-hook时而会出现一些异常的情况.这个与两个hook的执行时间有关系, pre-command-hook 是在comman执行之前就先执行hook, post-command-hook是在command执行之后才执行的hook.实践证明hook应该要放在执行前还是执行后并无实际的影响.
铵键配置
同时也分享下neo-emacs中对于workspace快捷键的设置. 最常用的就是左右切换workspace了, 因此设置了K、J来进行切换.
还有对workspace进行位置的移动,这其实是一个低频的功能.因此设置在了 command+k
、 command+j
来分别左移和右移.
(map! :n "K" '+workspace/switch-right )
(map! :n "J" '+workspace/switch-left )
(map! :n "s-k" '+workspace/swap-right )
(map! :n "s-j" '+workspace/swap-left )
其他问题
- 如果buffer的名称过长了会占用底部太多的空间. 这个还比较好优化
- 每次 workspace-rename 以后,该 workspace 的排序被移动到了最右边. workspace 位置产生移动会打乱我们对空间顺序的固有思维. 暂时无解答
- 如果在2个不同的workspace中打开相同的文件, 程序会自动设置workspacename为文件名, 但是workspace不允许设置为相同,因此会出现buffer切换了但是workspacename没更改的情况,也算是一种错乱.