(分享)Emacs 中的工作区、tab 和窗口管理

整理了一下最近总结的一套项目管理和窗口管理流程,分享一下


首先需要说明的是,在 Emacs 中,有两个「tab」

  • tab-line:是 window-local 的,类似 VS Code 里面的 tab 栏,可以更改一个 window 里所显示的 buffer
  • tab-bar:是全局的(或者说 frame-local),贴近于一个窗口布局(window-configuration)的管理工具

我的工作流分成了三层:persp-mode > tab-bar > window

  • persp 对应工作区的概念,我一般习惯一个项目放在一个工作区中。工作区中所打开的 buffer,设置的 tabs,窗口布局信息都可以保存和恢复,方便继续工作;
    • 例如我将 .emacs.d 配置放在一个工作区里,这个工作区还有 help 信息,list colors 的 buffer 等;
    • 我也将 elfeed 放在一个单独的工作区,包括它打开的 eww 等,放置污染其他工作区
    • 此外,Git 仓库/笔记/博客我也会设置单独的工作区
    • 工作区的列表显示在 tab-bar 上,用 C-c p n/C-c p p 或者 persp-switch 切换
    • 平时用 persp-switch-to-buffer 切换
  • tab 对应窗口布局,一般应对这样的场景:开两三个窗口编辑文件的时候,突然想看另一个文件的信息,但是不想打乱当前的布局,就新开一个 tab,对应一组新的 window-configuration
    • 类似在一个项目中的多个工作模式
    • tab 上标注数字,方便用 super(cmd) + <digit> 切换
  • window 这里值得一说的是我习惯用 popper 这个包控制那些临时 buffer,使用下面这个 hack 可以在弹出这些临时 buffers 的时候用 C-g 直接关掉
    • 我在窗口的 mode-line 上面放置了数字,可以用 meta(alt, options) + <digit> 切换
  ;; HACK: close popper window with `C-g'
  (defun +popper-close-window-hack (&rest _)
    "Close popper window via `C-g'."
    (when (and (called-interactively-p 'interactive)
               (not (region-active-p))
               popper-open-popup-alist)
      (let ((window (caar popper-open-popup-alist)))
        (when (window-live-p window)
          (delete-window window)))))
  (advice-add #'keyboard-quit :before #'+popper-close-window-hack)

由于 tab-barmode-line 都是高度可定制的,因此我把一些信息直接放上面了:


当然,让 persp-modetab-bar 协同工作需要一些 hack,感兴趣的话可以看我的具体的配置(给 doom-emacs 交过 hack 的 PR,doom 用户不需要考虑)

17 个赞

我使用 doom emacs 里面的 persp,也想基于工作区显示 tab 但是搞不定。。

C-x b 用户飘过~~

1 个赞

是的,copy当前layout,捣鼓一阵然后kill掉回到之前的layout继续。(我是eyebrowse党)


偏题一下,buffer也有同样的思路,copy内容到一个非file的buffer,随便改,捣鼓完了回来:

代码
(defun jester/scratch-from-current-buffer ()
  "Copy current buffer content, make a new buffer to fiddle with. If region active, only copy region."
  (interactive)
  (let ((mode major-mode)
        (text (if (region-active-p)
                  (prog1 (buffer-substring (region-beginning) (region-end))
                    (deactivate-mark))
                (buffer-substring (point-min) (point-max)))))
    (switch-to-buffer (generate-new-buffer (format "fiddling: %s" (buffer-name))))
    (insert text)
    (funcall mode)))
1 个赞

这个代码中使用的虚线是什么工具?

indent bars

1 个赞

总感觉persp-mode和tab-bar的功能重复了

1 个赞

你是什么版本的emacs?我在我的mac上使用安装包了完全不显示,我的emacs-mac通过如下方式安装的: brew tap railwaycat/emacsmacport brew install emacs-mac

有按照他的说明进行配置吗,macport 应该是可以用的

就是这个包说明文件里面默认的配置,配置如下:

dent-bars
  :load-path "~/.emacs.d/packages/indent-bars"
  :hook ((python-mode yaml-mode) . indent-bars-mode)) ; or whichever modes you prefer

我在emacs中执行M-x emacs-version 显示的信息是:

GNU Emacs 29.1 (build 1, aarch64-apple-darwin21.6.0, NS appkit-2113.60 Version 12.6.6 (Build 21G646)) of 2023-08-17

这个包的作者在说明文档中说应该提示是Carbon,而不是NS

你的应该是 ns-port,不是 Mac-port 吧😂不过就算是 ns-port 应该也有 fallback 的

Emacs For Mac OS X: Releases, Pretests & Nightlies 中这里下载的二进制文件直接使用的。

有其他类似的indent bar插件吗?

highlight indentation guides 也可以 你试试