カスタムuser-emacs-directoryでemacsを起動する方法


58

私は、自分の将来の構成のベースラインとして使用するgitリポジトリとして、友人と共有したいカスタムの小さなEmacs構成に取り組んでいます。

そのためには、構成をテストするいくつかの方法が必要です。考えられる最も簡単な解決策は次のようなものです。

$ emacs --eval "(setq user-emacs-directory \"~/Code/my_custom_emacs.d/\")"

しかし、私はそれを機能させることができないようです。

助けていただければ幸いです。


3
付録C Emacs呼び出しのコマンドライン引数を読みましたが.emacs.d、HOMEを変更しない限り、カスタムディレクトリでEmacsを起動する簡単なコマンドラインオプションが見つかりませんでした。人々は以下の回避策を提供しましたが、私には、これはEmacs自体に対する非常に合理的な機能要求のように聞こえます。
デビッドJ.


5
@DavidJamesそのとおりです。実際には、これに関するウィッシュリスト項目がEmacsのバグトラッカーにあります。
ffevotte

2
更新:この機能はEmacs開発者にはあまり関心がないようです。リクエストはタグ付けwontfixされ、バグトラッカーで閉じられました。
-ffevotte

@Francesco:私はユーザーEmacsディレクトリを「〜」の外に置くことができる動的なアプローチを試みています。試してみるかもしれません。
アントニオ

回答:


39

私がこれに使用する基本的なアプローチは$HOME、次を実行して変更することです:

env HOME=/path/to/dir emacs

次に使用します /path/to/dir/.emacs.d

Emacsがそれらを見ることができるように、この偽のホームディレクトリ内の重要なファイルまたはディレクトリを実際のものにシンボリックリンクすることもできます。


2
これは完璧に動作します!
マティアスベンツソン

8
よると、Emacsの起動のための付録Cコマンドライン引数- -環境変数- EMACマニュアル一般的な変数、HOMEセット「ディレクトリツリー内のファイルの場所;。チルダ(〜)で始まるファイル名の拡張のために使用されます」HOMEを変更することは、後で実際のホームフォルダーからファイルをすばやく移動したり検索したりするときに、トラブルのレシピのように聞こえます。
デビッドJ.

2
デビッド・ジェームス:はい、それはこのアプローチに対する小さな迷惑です。前述のとおり、EmacsがHOMEの下に表示するのに必要なものをコピーまたはシンボリックリンクし、実際のホームディレクトリにアクセスする場合は、絶対パスを使用する必要があります(またはシンボリックリンクを追加することもできます) )。
phils

3
また、初期化中にEmacs内で元のHOMEを復元することもできます。私はそれを試したことはありませんが、検討する価値があるようです。
phils

1
@phils:あなたが提案したことを試しました。
アントニオ

39

複数の.emacs.dディレクトリを並行して維持するために使用する方法は次のとおりです。

  1. emacsは次のように開始されます。

    alias emacs='emacs -q --load "/path/to/init.el"'
    
  2. init.elファイルは次のように始まりuser-init-fileuser-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だけで、デフォルトのシステム設定ではなく、独自のinitファイルをロードするのに必要な時間を報告しています。初期化時間のベンチマークに興味がある場合は、別の方法で行う必要があります(たとえば、elispコードのパフォーマンスを測定するにはどうすればよいですか?を参照)。

  • 通常のスタートアップとは異なり、いくつかの特定の点に注意する必要があります。特に:

    • after-init-hookinitファイルがロードされる前に実行されます。
    • *scratch*バッファが作成される前に、 initファイルがロードされています。(を使用する代わりにinitial-major-mode)モードを明示的に変更する必要があります。
    • 明示的に呼び出す必要がありますpackage-initialize; 自動的には行われません
  • へのパスinit.elは任意に選択できます。特に、存在するディレクトリにinit.el名前を付ける必要はありません.emacs.d。私は例を持っているためにこれを使用する.emacs.d.23と一緒に.emacs.d.24(仕事で私が使用しているシステムはまずまず古くなっている、と私は、私が使用するすべてのマシン上のEmacs 24をインストールすることはできません)のEmacsの異なるバージョンを切り替えることができるようにするために。

  • このワークフローでは、環境(特にHOMEenvvar)を変更する必要はありません。これは、変更された環境の影響を受ける可能性のあるemacs内からプログラムを実行する場合に望ましい場合があります。


1
--loadedファイルをinitファイルと見なしている場合、これは(実際には)通常の実行順序を変更します。まず第一に、通常の(デフォルトの)パッケージ初期化は行われないように見え、(偽の)initファイルが評価される前after-init-hookに実行されます。これらは回避できますが、指定されたパスをinitファイルとして使用するEmacsとはまったく同じではないことに注意してください。
フィル14

2
@philsはい、あなたは正しいです。これは実際に通常の実行順序を変更するものであり、通常の初期化ファイルを使用することとは異なります。あなたの意見を反映するために答えを編集しましたafter-init-hook。しかし、私は常にこの手法を使用after-init-hookしていますが、問題は発生していません(ただし、明示的には使用せず、使用しているパッケージがそれに依存しないのは幸運です) 。「通常の(デフォルト)パッケージの初期化が行われない」とはどういう意味ですか?
ffevotte 14

1
つまり、そのような状況でcommand-lineは呼び出しませんpackage-initialize。偽のinitファイルで手動で呼び出す必要があります。
phils 14

1
@philsありがとう。これを回答に追加し、最初のメジャーモードも特に注意する必要があると述べました。
ffevotte 14

これは完璧に機能しました。ありがとうございます!!!
ストライカー

15

シンボリックリンク できます~/.emacs.d、これが私がやることです

  1. emacsの構成を維持するようにしてください。~/.emacs.dつまり、すべてのemacs関連の構成ファイルがそのフォルダーに存在する必要があります。

  2. 次に~/.emacs_configs、すべての構成フォルダー(基本的init.elには構成の残りのフォルダー)が存在するフォルダーがあるため、個人の構成フォルダーはになり~/emacs_configs/iqbal、プレリュードの配布は~/emacs_configs/prelude

  3. 私の個人的なemacs設定の非常に早い段階でuser-emacs-directory、次を使用して設定へのフルパスを設定しました

    (setq user-emacs-directory (file-truename "~/.emacs.d/"))
    
  4. 最後に~/.emacs.d、実際に使用したい設定にシンボリックリンクします。私の設定を使用するには、私が行いますln -s ~/emacs_configs/iqbal .emacs.d。設定を試してみたい場合は、設定フォルダをコピーし~/emacs_configs/whatever_nameてシンボリックリンクを変更してください

3番目のステップの利点は、個人用構成で開始されたemacsが実行.emacs.d中にsymlink を変更しても、影響を受けずに実行できることです。

別の利点は、HOME変更されないため、emacsが対話する必要のある外部プログラムは影響を受けません


1
これは、すべての個別のemacs構成を微調整して、(setq user-emacs-directory (file-truename "~/.emacs.d/"))すべてが同時に影響を受けずに実行できることを意味しますか?
user1011471

1
理論上はそうですが、実際には~/.emacs.dを使用するのではなく、パスをハードコードするライブラリが存在する場合がありますuser-emacs-directory。私は少なくともそのような図書館に出くわしましたが、残念ながらその名前を思い出すことができません。
イクバルアンサリ


5

私はEmacsWikiからこのきちんとした解決策を見つけました:

emacs -q -l ~/my-init-file.el

(正確にはカスタムディレクトリを使用していませんが、とにかく単一のエントリファイルを持っている可能性が高いため、うまく機能します)


参考までに、これは2年前の@Francescoのコメントで冗長です。
ブライス

4

「EMACS_USER_DIRECTORY」環境変数を使用して.emacs.dの場所を指定できるパッチは、https: //debbugs.gnu.org/cgi/bugreport.cgi?bug = 15539にありますが、まだマージされていません。


3

initファイルをロードする前に変数を設定します。

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

非常にエレガントで、私のお気に入りのシステムです。すべてがそのままEmacsのドメインに残っているためです。ありがとうございました。
gsl

1

@philsからの回答を拡張し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

1

HOME環境変数を変更し、Emacs内でそれを復元することについての@Philの回答とコメントに基づいた小さなスクリプトを次に示します。

#!/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 "$@"

1

ユースケースが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 /」ディレクトリを持ちますが、一時ファイルの保存にのみ使用されますが、パッケージおよびその他の構成は共有構成ディレクトリからロードされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.