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))
)