修改 ~/.bashrc 后有没有办法让 emacs 不重启也能同步 ~/.bashrc 的修改?

原来的动机是我添加了一个 shell 函数比如叫 func, 希望 emacs 能 :!func 这样执行. 后来我发现是我想多了, emacs 本来也不支持执行写在配置文件的 shell 函数. 我本来以为 emacs 其实有个内在的 shell, 现在我猜测应该没有, 每次执行 shell command 都是开了一个新的 shell 去执行的. 因此我怀疑此问题无解.

假设:

$ tail ~/.bashrc
function foo() {
    echo "foo"
}
export -f foo
$ foo
foo

在 Emacs 中可以通过 setenv 把函数写入到 process-environment

(setenv "BASH_FUNC_foo%%" "() { echo \"foo\"; }")

设置前:

M-! foo
;; => "/bin/bash: foo: command not found"

设置后:

M-! foo
;; => "foo"
4 个赞

写了一个函数用来重新加载 bash functions,新增/修改立即生效:

(defun reload-bash-functions ()
  "Reload bash function.

Make new and updated functions in files such as .bashrc and .profile take effect."
  (interactive)
  (mapc
   (lambda (decl)
     (when (string-match " (" decl)
       (let ((pos (match-beginning 0)))
         (setenv (concat "BASH_FUNC_" (substring decl 0 pos) "%%")
                 (replace-regexp-in-string "^()\s*\n" "() " (substring decl (1+ pos)))))))
   (let ((output (generate-new-buffer " *declares*" t))
         (shell-command-switch "-lc")
         (case-fold-search nil))
     (with-current-buffer output
       (call-process-shell-command "echo __DeClArEs__; declare -fx" nil output)
       (goto-char (point-min))
       (re-search-forward "^__DeClArEs__\n" nil t)
       (split-string (buffer-substring (point) (point-max)) "declare -fx .*\n")))))
1 个赞