原来的动机是我添加了一个 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 个赞