我正在开发一个自定义的小型Emacs配置,我想与一些朋友分享为git存储库,以供他们用作自己未来配置的基准。
为此,我需要某种方法来测试我的配置,而我能想到的最简单的解决方案是:
$ emacs --eval "(setq user-emacs-directory \"~/Code/my_custom_emacs.d/\")"
但是我似乎无法使其正常工作。
任何帮助,不胜感激。
wontfix
并在错误跟踪器中关闭。
我正在开发一个自定义的小型Emacs配置,我想与一些朋友分享为git存储库,以供他们用作自己未来配置的基准。
为此,我需要某种方法来测试我的配置,而我能想到的最简单的解决方案是:
$ emacs --eval "(setq user-emacs-directory \"~/Code/my_custom_emacs.d/\")"
但是我似乎无法使其正常工作。
任何帮助,不胜感激。
wontfix
并在错误跟踪器中关闭。
Answers:
我使用的基本方法是$HOME
通过运行来修改:
env HOME=/path/to/dir emacs
然后,您使用 /path/to/dir/.emacs.d
您可能还希望将该虚假主目录中的重要文件或目录符号链接回真实文件或目录,以便Emacs可以看到它们。
下面是我用来.emacs.d
并行维护多个目录的方法。
emacs是这样启动的:
alias emacs='emacs -q --load "/path/to/init.el"'
每个init.el
文件都是这样开始的,以正确设置user-init-file
和user-emacs-directory
变量:
(setq user-init-file (or load-file-name (buffer-file-name)))
(setq user-emacs-directory (file-name-directory user-init-file))
我发现这在过去几个月中非常可靠地工作。这里有几点评论:
它会中断emacs-init-time
,它仅报告加载默认系统配置所需的时间,而不报告您自己的初始化文件。如果您有兴趣对基准时间进行基准测试,则必须采用另一种方式(例如,请参见如何测量elisp代码的性能?)。
它不等同于正常的启动,您需要注意一些特定的问题。尤其是:
after-init-hook
在加载初始化文件之前运行。*scratch*
创建缓冲区之前加载init文件。您必须显式更改其模式(而不是使用initial-major-mode
)。package-initialize
;它不会自动完成init.el
可以任意选择的路径;特别是,init.el
不必将其所在的目录命名为.emacs.d
。例如,我可以使用它.emacs.d.23
并排使用.emacs.d.24
,以便能够在不同版本的emacs之间切换(我正在使用的系统已经过时,并且我无法在使用的所有计算机上安装emacs 24)。
此工作流程不需要修改环境(尤其是HOME
envvar),如果您从emacs中运行程序(可能会受到修改后的环境的影响),则可能需要这样做。
--load
ed文件视为初始化文件,则(实际上)会更改正常的执行顺序。对于初学者来说,在我看来,将不会发生正常的(默认)软件包初始化,并且after-init-hook
它将在评估(伪)初始化文件之前运行。当然,可以解决这些问题,但是请注意,使用指定的路径作为init文件,这与Emacs并不完全相同。
after-init-hook
。但是我不得不说,尽管我一直在使用这种技术,但是我从来没有遇到任何问题after-init-hook
(但是我没有明确使用它,也许我很幸运我使用的软件包不依赖它) 。“正常(默认)包初始化不会发生”是什么意思?
command-line
不会打电话package-initialize
。您需要在伪造的init文件中手动调用它。
你可以符号链接 ~/.emacs.d
,这就是我所做的
尝试保持我的emacs配置~/.emacs.d
为导向,即所有与emacs相关的配置文件应位于该文件夹中
然后,我有一个~/.emacs_configs
文件夹,其中所有配置文件夹(基本上是一个带有init.el
其余配置的文件夹)都存在,因此我的个人配置文件夹将为~/emacs_configs/iqbal
,一个前奏分发将位于~/emacs_configs/prelude
在我的个人emacs配置很早的时候,我user-emacs-directory
使用以下命令将设置为配置的完整路径
(setq user-emacs-directory (file-truename "~/.emacs.d/"))
最后,我将符号链接~/.emacs.d
到我实际要使用的配置,例如。使用我的配置我会做的ln -s ~/emacs_configs/iqbal .emacs.d
。如果要尝试一些配置,只需将配置文件夹复制到~/emacs_configs/whatever_name
并更改符号链接
第三步的优点是,即使我.emacs.d
在emacs运行时更改了符号链接,以我的个人配置启动的emacs也不会受到影响。
另一个优点是,由于HOME
emacs可能需要与之交互的外部程序未更改,因此不受影响
(setq user-emacs-directory (file-truename "~/.emacs.d/"))
使它们都可以不受影响地同时运行?
~/.emacs.d
而不是使用user-emacs-directory
。我遇到过至少一个这样的库,但是不幸的是忘记了这个名字。
HOME
可以在我的答案https://emacs.stackexchange.com/a/20508/934中找到不会更改或无法使用符号链接的配置。使用此配置,您可以user-emacs-directory
通过设置环境变量来更改:
EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs
甚至可以与守护程序一起使用。
该修补程序可通过https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15539提供通过EMACS_USER_DIRECTORY环境变量指定.emacs.d位置的信息,但尚未合并。
在加载初始化文件之前设置var :
emacs -q --eval '(setq alt-conf t)' --load ~/.emacs
然后,在您的init文件中(在本例中为~/.emacs
):
(defvar alt-conf nil)
(if alt-conf
(let ((default-directory "~/src/elisp-test/"))
(normal-top-level-add-subdirs-to-load-path)
(various-alt-config-stuff)
(message "Alternate conf"))
(message "Regular conf"))
通过扩展@phils的答案,我制作了这个小shell脚本(称为testrun.sh
)来测试我的新emacs配置。在其他情况下也可以这样做(例如,在测试可能会破坏emacs的init.el更改时)。
#!/bin/bash
cd $(dirname "${BASH_SOURCE[0]}")
[ -d .testrun ] || mkdir .testrun
cd .testrun
[ -h .emacs.d ] || ln -s .. .emacs.d
env HOME=`pwd` emacs
rm .emacs.d
cd ..
rm -rf .testrun
这是一个基于@Phil的答案和注释的小脚本,有关更改HOME
环境变量,然后在Emacs中恢复它。
#!/bin/bash
# Use it like this:
# /path/to/this/script EMACS_USER_DIRECTORY [OTHER EMACS ARGS]
# You can never be too careful
set -e
# First arg = emacs user directory
# (get a canonical, absolute path)
EMACS_USER_DIRECTORY=$(readlink -f "$1")
shift
if [ ! -d "${EMACS_USER_DIRECTORY}" ]; then
echo "Non-existent directory: '${EMACS_USER_DIRECTORY}'"
exit 1
fi
# Bootstrap directory
BOOTSTRAP=$(mktemp --directory --tmpdir .emacs-bootstrap.XXXXXX)
mkdir "${BOOTSTRAP}/.emacs.d"
# Bootstrap init file
cat >"${BOOTSTRAP}/.emacs.d/init.el" <<EOF
;; # Correctly set-up emacs-user-directory
(setq user-emacs-directory "${EMACS_USER_DIRECTORY}/")
(setq user-init-file (concat user-emacs-directory "init.el"))
;; # Reset the HOME environment variable
(setenv "HOME" "${HOME}")
;; # Load the real init file and clean-up afterwards
(unwind-protect (load user-init-file)
(delete-directory "${BOOTSTRAP}" :recursive))
EOF
# Forward remaining arguments to emacs
exec env HOME="${BOOTSTRAP}" emacs "$@"
如果用例是在Linux计算机的所有用户之间共享单个emacs配置“ .emacs.d”目录,则此解决方案https://emacs.stackexchange.com/a/4258/5488在大多数情况下都可以使用,但是在某些情况下在emacs尝试将临时文件写入到user-emacs-directory的情况下(例如.ido.last文件)。在这种情况下,如果共享配置目录对所有用户都具有写许可权,则它将起作用,但可能不是理想的解决方案,因为每个系统用户可能不想共享同一目录来存储临时文件。在这种情况下,以下解决方案将是更好的选择。
通用共享配置文件.emacs.d / init.el应该以
;; should come before calling package-initialize as it will populate
;; everything under common config "~/.emacs.d/elpa"
(setq user-init-file (or load-file-name (buffer-file-name)))
(setq package-user-dir (concat (file-name-directory user-init-file) "elpa"))
(package-initialize)
使共享的配置.emacs.d具有对所有用户的读取权限(不需要写入权限)
another_user $ emacs -q --load /path/to/shared/config/.emacs.d/init.el
每个用户都有自己的“〜/ .emacs.d /”目录,但仅用于保存临时文件,但软件包和其他配置是从共享config目录中加载的。
.emacs.d
除非找到HOME,否则我找不到用于启动带有自定义目录的Emacs的简单命令行选项,这对我来说似乎很麻烦。人们在下面提供了解决方法,但对我来说,这听起来像是对Emacs本身非常合理的功能要求。