Làm thế nào để bắt đầu emacs với một thư mục tùy chỉnh người dùng-emacs


58

Tôi đang làm việc với một cấu hình Emacs tùy chỉnh và nhỏ mà tôi muốn chia sẻ với một số người bạn làm kho lưu trữ git để họ sử dụng làm đường cơ sở cho các cấu hình tương lai của riêng họ.

Đối với điều này, tôi cần một số cách để kiểm tra cấu hình của mình và giải pháp đơn giản nhất tôi có thể đưa ra là:

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

Nhưng tôi dường như không thể làm cho nó hoạt động.

Bất kỳ trợ giúp nhiều đánh giá cao.


3
Tôi đã đọc qua Phụ lục C Đối số dòng lệnh cho Yêu cầu Emacs nhưng tôi không tìm thấy tùy chọn dòng lệnh đơn giản để bắt đầu Emacs với một .emacs.dthư mục tùy chỉnh trừ khi bạn thay đổi HOME, điều này có vẻ có vấn đề với tôi. Mọi người đã cung cấp cách giải quyết bên dưới, nhưng, với tôi, điều này nghe có vẻ như là một yêu cầu tính năng rất hợp lý cho chính Emacs.
David J.


5
@DavidJames Bạn nói đúng: thực sự có một mục danh sách mong muốn về điều này trong trình theo dõi lỗi của Emacs.
ffevotte

2
Cập nhật: có vẻ như tính năng này không được các nhà phát triển Emacs quan tâm nhiều: yêu cầu đã được gắn thẻ wontfixvà đóng trong trình theo dõi lỗi.
ffevotte

@Francesco: Tôi thử một cách tiếp cận động cho phép đặt thư mục Emacs của người dùng bên ngoài "~". Có thể là bạn sẽ cho một thử.
antonio

Câu trả lời:


39

Cách tiếp cận cơ bản tôi sử dụng cho việc này là sửa đổi $HOME, bằng cách chạy:

env HOME=/path/to/dir emacs

Sau đó bạn sử dụng /path/to/dir/.emacs.d

Bạn cũng có thể muốn liên kết bất kỳ tệp hoặc thư mục quan trọng nào trong thư mục giả mạo này trở lại tệp thực, để Emacs sẽ nhìn thấy chúng.


2
Điều này làm việc hoàn hảo!
Mattias Bengtsson

8
Theo Hướng dẫn sử dụng Emac - Phụ lục C Đối số dòng lệnh cho lệnh gọi Emacs - Biến môi trường - Biến chung , HOME đặt "Vị trí tệp của bạn trong cây thư mục; được sử dụng để mở rộng tên tệp bắt đầu bằng dấu ngã (~)." Thay đổi HOME có vẻ như là một công thức cho rắc rối sau này khi bạn muốn nhanh chóng điều hướng hoặc tìm tệp từ thư mục nhà thực sự của bạn .
David J.

2
David James: Vâng, đó là một phiền toái nhỏ với phương pháp này. Như đã đề cập, bạn sẽ muốn sao chép hoặc liên kết những thứ mà bạn cần Emacs để xem trong HOME và nếu bạn muốn truy cập thư mục nhà thực sự của mình thì bạn cũng cần sử dụng đường dẫn tuyệt đối (hoặc bạn cũng có thể thêm một liên kết tượng trưng vào đó ).
phils

3
Bạn cũng có thể thử nghiệm khôi phục HOME gốc trong Emacs trong quá trình khởi tạo. Tôi đã không thử điều đó, nhưng nó có vẻ đáng để xem xét.
phils

1
@phils: Tôi đã thử những gì bạn đề nghị.
antonio

39

Cách tôi sử dụng để duy trì .emacs.dsong song một số thư mục như sau.

  1. emacs được bắt đầu như thế này:

    alias emacs='emacs -q --load "/path/to/init.el"'
    
  2. Mỗi init.eltệp bắt đầu như thế này, để thiết lập chính xác user-init-fileuser-emacs-directorycác biến:

    (setq user-init-file (or load-file-name (buffer-file-name)))
    (setq user-emacs-directory (file-name-directory user-init-file))
    

Tôi đã tìm thấy điều này để làm việc rất đáng tin cậy trong những tháng qua. Dưới đây là một vài nhận xét:

  • nó bị hỏng emacs-init-time, chỉ báo cáo thời gian cần thiết để tải cấu hình hệ thống mặc định, nhưng không phải là tệp init của riêng bạn. Nếu bạn quan tâm đến việc đo điểm chuẩn thời gian khởi động của mình, bạn sẽ phải thực hiện theo cách khác (xem ví dụ: Làm thế nào để tôi đo lường hiệu suất của mã elisp? ).

  • nó không tương đương với một khởi động bình thường và bạn sẽ cần quan tâm đến một vài điểm cụ thể. Đặc biệt:

    • after-init-hookđược chạy trước khi tập tin init được tải.
    • Bộ *scratch*đệm được tạo trước khi tập tin init được tải. Bạn sẽ phải thay đổi chế độ của nó một cách rõ ràng (thay vì sử dụng initial-major-mode).
    • Bạn sẽ cần phải gọi một cách rõ ràng package-initialize; nó sẽ không được thực hiện tự động
  • con đường để init.elcó thể được lựa chọn tùy ý; đặc biệt, thư mục init.elcư trú không cần phải được đặt tên .emacs.d. Tôi sử dụng điều này để có ví dụ .emacs.d.23bên cạnh .emacs.d.24để có thể chuyển đổi giữa các phiên bản khác nhau của emacs (hệ thống tôi đang sử dụng tại nơi làm việc đã lỗi thời và tôi không thể cài đặt emacs 24 trên tất cả các máy tôi sử dụng).

  • quy trình công việc này không yêu cầu sửa đổi môi trường (và đặc biệt là HOMEenvvar), điều này có thể được mong muốn nếu bạn chạy các chương trình từ bên trong emacs, có thể bị ảnh hưởng bởi môi trường đã sửa đổi).


1
Điều này không (có hiệu lực) thay đổi thứ tự thực hiện thông thường, nếu bạn đang xem --loadtệp ed là tệp init. Đối với người mới bắt đầu, tôi thấy như thể khởi tạo gói (mặc định) bình thường sẽ không xảy ra và after-init-hooksẽ chạy trước khi tệp init (giả) được đánh giá. Đây là những thứ mà bạn có thể làm việc xung quanh, chắc chắn, nhưng lưu ý rằng nó không hoàn toàn giống với Emacs sử dụng đường dẫn được chỉ định làm tệp init.
phils

2
@phils vâng, bạn nói đúng. Điều này thực sự thay đổi thứ tự thực hiện thông thường và không tương đương với việc sử dụng tệp init thông thường. Tôi chỉnh sửa câu trả lời của tôi để phản ánh quan điểm của bạn trên after-init-hook. Nhưng tôi phải nói rằng mặc dù tôi sử dụng kỹ thuật này mọi lúc, tôi không bao giờ gặp phải bất kỳ vấn đề nào với after-init-hook(nhưng tôi không sử dụng nó một cách rõ ràng và có lẽ tôi chỉ may mắn là các gói tôi sử dụng không dựa vào nó) . Ý bạn là gì khi "khởi tạo gói thông thường (mặc định) sẽ không xảy ra"?
ffevotte

1
Tôi có nghĩa là command-linesẽ không gọi package-initializetrong tình huống đó. Bạn sẽ cần phải gọi nó bằng tay trong tệp init giả.
phils

1
@phils cảm ơn. Tôi đã thêm điều này vào câu trả lời, cùng với một đề cập rằng chế độ chính ban đầu cũng phải được quan tâm cụ thể.
ffevotte

Điều này làm việc hoàn hảo .. Cảm ơn bạn !!!
Stryker

15

Bạn có thể symlink ~/.emacs.d , đây là những gì tôi làm

  1. Cố gắng giữ cấu hình emacs của tôi ~/.emacs.dtheo định hướng, tức là tất cả các tệp cấu hình liên quan đến emacs sẽ nằm trong thư mục đó

  2. Sau đó, tôi có một ~/.emacs_configsthư mục chứa tất cả các thư mục cấu hình (về cơ bản là một thư mục có init.elphần còn lại của cấu hình), vì vậy thư mục cấu hình cá nhân của tôi sẽ có ~/emacs_configs/iqbal, một bản phân phối mở đầu sẽ ở trong~/emacs_configs/prelude

  3. Rất sớm trong cấu hình emacs cá nhân của tôi, tôi đặt user-emacs-directoryđường dẫn đầy đủ đến cấu hình của mình bằng cách sử dụng như sau

    (setq user-emacs-directory (file-truename "~/.emacs.d/"))
    
  4. Sau đó, cuối cùng tôi symlink ~/.emacs.dđến cấu hình tôi thực sự muốn sử dụng, ví dụ. để sử dụng cấu hình của tôi, tôi sẽ làm ln -s ~/emacs_configs/iqbal .emacs.d. Nếu bạn muốn thử một số cấu hình, chỉ cần sao chép thư mục cấu hình vào ~/emacs_configs/whatever_namevà thay đổi liên kết tượng trưng

Ưu điểm của bước thứ 3 là emacs bắt đầu với cấu hình cá nhân của tôi có thể chạy không bị ảnh hưởng ngay cả khi tôi thay đổi .emacs.dliên kết tượng trưng trong khi emacs nó đang chạy.

Một lợi thế khác là do các HOMEchương trình bên ngoài không thay đổi, các emacs có thể cần phải tương tác với không bị ảnh hưởng


1
Điều này có nghĩa là chúng ta có thể điều chỉnh tất cả các cấu hình emacs riêng biệt để (setq user-emacs-directory (file-truename "~/.emacs.d/"))tất cả chúng có thể chạy không bị ảnh hưởng đồng thời?
user1011471

1
Về lý thuyết thì có, nhưng trong thực tế có thể có một số thư viện mã hóa đường dẫn đến ~/.emacs.dthay vì sử dụng user-emacs-directory. Tôi đã đi qua ít nhất một thư viện như vậy nhưng tiếc là không thể nhớ tên.
Iqbal Ansari

7

HOMEthể tìm thấy cấu hình không thay đổi hoặc hoạt động với symlink trong câu trả lời của tôi https://emacs.stackexchange.com/a/20508/934 . Với cấu hình này, bạn có thể thay đổi user-emacs-directorybằng cách đặt biến môi trường:

EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs

và điều này thậm chí hoạt động với daemon.


5

Tôi tìm thấy giải pháp gọn gàng này từ EmacsWiki :

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

(không chính xác bằng cách sử dụng một thư mục tùy chỉnh, nhưng hoạt động độc đáo vì rất có thể bạn có một tệp nhập duy nhất)


FYI, điều này là dư thừa với một nhận xét của @Francesco từ 2 năm trước.
Bryce


3

Đặt var của bạn trước khi tải tập tin init của bạn:

emacs -q --eval '(setq alt-conf t)' --load ~/.emacs

Sau đó, trong tệp init của bạn (trong trường hợp này ~/.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"))

Rất thanh lịch, hệ thống yêu thích của tôi, vì mọi thứ vẫn thuộc về miền của Emacs. Cảm ơn bạn.
gsl

1

Mở rộng câu trả lời từ @phils Tôi đã tạo tập lệnh shell nhỏ này (được gọi testrun.sh) để thử nghiệm cấu hình emacs mới của tôi. Điều này cũng có thể có ý nghĩa trong các trường hợp khác (ví dụ: khi thử nghiệm thay đổi đối với init.el của bạn có thể phá vỡ emacs).

#!/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

Đây là một đoạn script nhỏ dựa trên câu trả lời và nhận xét của @ Phil về việc thay đổi HOMEbiến môi trường, sau đó khôi phục nó trong 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 "$@"

1

Nếu trường hợp sử dụng được chia sẻ emacs đơn cấu hình ".emacs.d" thư mục trên tất cả các người dùng của một máy Linux thì giải pháp này https://emacs.stackexchange.com/a/4258/5488 sẽ làm việc trong hầu hết các trường hợp, nhưng trong một số trường hợp emacs cố gắng ghi các tệp tạm thời vào thư mục người dùng-emacs (chẳng hạn như tệp .ido.last). Trong những trường hợp như vậy nếu thư mục config được chia sẻ có quyền ghi cho tất cả người dùng thì nó sẽ hoạt động nhưng có thể không phải là giải pháp mong muốn vì mỗi người dùng hệ thống có thể không muốn chia sẻ cùng một thư mục để lưu trữ tệp tạm thời. Trong trường hợp như vậy, giải pháp sau đây sẽ là lựa chọn tốt hơn.

Tệp cấu hình được chia sẻ chung .emacs.d / init.el sẽ bắt đầu bằng

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

Làm cho cấu hình được chia sẻ .emacs.d có quyền đọc cho tất cả người dùng (không cần có quyền ghi)

another_user $ emacs -q --load /path/to/shared/config/.emacs.d/init.el

Mỗi người dùng sẽ có thư mục "~ / .emacs.d /" của riêng mình nhưng chỉ được sử dụng để lưu các tệp tạm thời nhưng các gói và cấu hình khác được tải từ thư mục cấu hình chung.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.