emacs 有没有包能支持 per tab working-directory?

tab-mode 是我一直在用的, 只要用 emacs 我就会用 tab-mode. 我理解的是, 每一个 buffer 有一个 default-directory. 但 emacs 好像不像 vim 那样支持每一个 tab 都有一个 working directory. 比如它做不到这样一件事, 在两个不同的 tab 打开的是同一个文件, 但当前目录不同. 请问 emacs 有办法做到以 tab 为单位的 working directory 么? 比如我希望:

  • 同一个 tab 下的不同 window 打开的是不同的文件, 然而它们的 working directory 相同
  • 不同 tab 下的 window 都打开了同一个文件, 但它们的 working directory 不同

虽然但是,Vim 所有的 tab 都是共享一个目录的。

并不是。vim 的 working directory 是 per tab 的。

你可以自己维护一个 per tab 的 working directory 的变量,然后给你想要调用的感兴趣的函数加一个 advice 临时修改他们的值,比如这样

(advice-add #'find-file :around
(defun set-default-directory-per-tab (origin-fun &rest args) 

(let ((default-directory (get-working-directory-of-current-tab))
(apply origin-fun args)))

)

暂时解决了这个问题, 我之前苦于如何设置 tab-local variables, 然后发现 htab.el 可以. 基于此, 我为 cd 命令添加了 embark action 就是设置 tab-local 的 default-directory. 然后改写了新的 find-file 和 consult-ripgrep 的命令.

我把代码列在这里了, 也希望有经验的道友能给我的代码提意见, 让我能采用更好的写法或者风格.

为 cd 添加 new embark action

(defvar-keymap my/embark-file-map
  :doc "Keymap for Embark file actions."
  :parent embark-file-map
  "t" 'embark-set-tab-local-default-directory
"i" 'embark-print-info
  )

(defun embark-set-tab-local-default-directory (target)
(htab-local-set 'default-directory target)
  )

(add-to-list 'embark-keymap-alist '(file . my/embark-file-map))

修改 find-file 与 consult-ripgrep 的命令

(require 'htab)

(defun my/get-tab-local-default-directory()
(htab-local-get 'default-directory)
  )

(defun my/echo-tab-local-default-directory()
(interactive)
(message "%s" (my/get-tab-local-default-directory))
)

(defun find-file-in-local-tab-directory ()
"find-file in local-tab variable default-directory"
  (interactive)
  (let* ((ffip-project-root (ffip-parent-directory 0 (or (my/get-tab-local-default-directory) default-directory))))
    (find-file-in-project nil))
  )

(defun consult-ripgrep-in-local-tab-directory()
"consult-ripgrep in local-tab variable default-directory"
(interactive)
(consult-ripgrep (my/get-tab-local-default-directory))
    )