>From 4d66998bff5de197e097870c30cc0b533bc134ac Mon Sep 17 00:00:00 2001 From: Amin Bandali Date: Sun, 9 Jun 2019 02:29:52 -0400 Subject: [PATCH] Implement XDG Base Directory specification for user-emacs-directory * lisp/startup.el (command-line): Use user-emacs-directory instead of hard-coding "~/.emacs.d". * lisp/subr.el (user-emacs-directory): Use "$XDG_CONFIG_HOME/emacs/" if XDG_CONFIG_HOME is set and has an "emacs/" subdirectory. Otherwise, try "~/.config/emacs/" before falling back to "~/.emacs.d/". --- doc/emacs/custom.texi | 72 +++++++++++++++++++++++-------------------- etc/NEWS | 6 ++++ lisp/startup.el | 19 +++--------- lisp/subr.el | 6 +++- 4 files changed, 54 insertions(+), 49 deletions(-) diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 982cea1f21..b582601cae 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -380,7 +380,7 @@ Saving Customizations file. For example: @example -(setq custom-file "~/.config/emacs-custom.el") +(setq custom-file "~/.config/emacs/custom.el") (load custom-file) @end example @@ -390,14 +390,14 @@ Saving Customizations @example (cond ((< emacs-major-version 22) ;; @r{Emacs 21 customization.} - (setq custom-file "~/.config/custom-21.el")) + (setq custom-file "~/.config/emacs/custom-21.el")) ((and (= emacs-major-version 22) (< emacs-minor-version 3)) ;; @r{Emacs 22 customization, before version 22.3.} - (setq custom-file "~/.config/custom-22.el")) + (setq custom-file "~/.config/emacs/custom-22.el")) (t ;; @r{Emacs version 22.3 or later.} - (setq custom-file "~/.config/emacs-custom.el"))) + (setq custom-file "~/.config/emacs/custom.el"))) (load custom-file) @end example @@ -2215,28 +2215,30 @@ Init File @cindex init file @cindex .emacs file @cindex ~/.emacs file -@cindex ~/.config/emacs file +@cindex ~/.config/emacs/init.el file @cindex Emacs initialization file @cindex startup (init file) When Emacs is started, it normally tries to load a Lisp program from an @dfn{initialization file}, or @dfn{init file} for short. This file, if it exists, specifies how to initialize Emacs for you. Emacs -looks for your init file using the filenames -@file{~/.config/emacs},. @file{~/.emacs}, @file{~/.config/emacs.el}, -@file{~/.emacs.el}, @file{~/.config/emacs.d/init.el} or -@file{~/.emacs.d/init.el}; you can choose to use any one of these -names (@pxref{Find Init}). Here, @file{~/} stands for your home -directory. +looks for your init file using the filenames @file{~/.emacs} or +@file{~/.emacs.el}. Here, @file{~/} stands for your home directory. +Alternatively, you may wish to group all things Emacs-related in one +place in the Emacs configuration directory. Emacs looks for +@file{$XDG_CONFIG_HOME/emacs/init.el}, using @file{~/.config} for +@env{XDG_CONFIG_HOME} if it's not set. If +@file{$XDG_CONFIG_HOME/emacs/} doesn't exist, Emacs will fall back to +@file{~/.emacs.d/} and look for @file{~/.emacs.d/init.el} instead +(@pxref{Find Init}). While the @file{~/.emacs} and @file{~/.emacs.d/init.el} locations are backward-compatible to older Emacs versions, and the rest of this -chapter will use them to name your initialization file, it is better practice -to group all of your dotfiles under @file{.config} so that if you have -to troubleshoot a problem that might be due to a bad init file, or -archive a collection of them, it can be done by renaming or -copying that directory. Note that the @file{.config} versions -don't have a leading dot on the basename part of the file. +chapter will use them to name your initialization file, it is better +practice to group all of your dotfiles under @file{~/.config} so that +if you have to troubleshoot a problem that might be due to a bad init +file, or archive a collection of them, it can be done by renaming or +copying that directory. You can use the command line switch @samp{-q} to prevent loading your init file, and @samp{-u} (or @samp{--user}) to specify a @@ -2642,13 +2644,14 @@ Terminal Init @node Find Init @subsection How Emacs Finds Your Init File - Normally Emacs uses your home directory to find -@file{~/.config/emacs} or @file{~/.emacs}; that's what @samp{~} means -in a file name. @xref{General Variables, HOME}. If none of -@file{~/.config/emacs}, @file{~/.emacs}, @file{~/.config/emacs.el} nor + Normally Emacs uses your home directory to find @file{~/.emacs} +(@samp{~} refers to the user's home directory in a file name). +@xref{General Variables, HOME}. If neither @file{~/.emacs} nor @file{~/.emacs.el} is found, Emacs looks for -@file{~/.config/emacs.d/init.el} or @file{~/.emacs.d/init.el} (these, -like @file{~/.emacs.el}, can be byte-compiled). +@file{$XDG_CONFIG_HOME/emacs/init.el}, substituting @file{~/.config} +for @env{XDG_CONFIG_HOME} if it's not set. If neither of these exist, +Emacs will look for @file{~/.emacs.d/init.el}. These, like +@file{~/.emacs.el}, can be byte-compiled. However, if you run Emacs from a shell started by @code{su}, Emacs tries to find your own initialization files, not that of the user you are @@ -2702,16 +2705,19 @@ Early Init File @cindex early init file Most customizations for Emacs should be put in the normal init file, -@file{.config/emacs} or @file{~/.config/emacs.d/init.el}. However, it is sometimes desirable -to have customizations that take effect during Emacs startup earlier than the -normal init file is processed. Such customizations can be put in the early -init file, @file{~/.config/emacs.d/early-init.el} or @file{~/.emacs.d/early-init.el}. This file is loaded before the -package system and GUI is initialized, so in it you can customize variables -that affect frame appearance as well as the package initialization process, -such as @code{package-enable-at-startup}, @code{package-load-list}, and -@code{package-user-dir}. Note that variables like @code{package-archives} -which only affect the installation of new packages, and not the process of -making already-installed packages available, may be customized in the regular +@file{~/.emacs} or @file{$XDG_CONFIG_HOME/emacs/init.el}. However, it +is sometimes desirable to have customizations that take effect during +Emacs startup earlier than the normal init file is processed. Such +customizations can be put in the early init file, +@file{$XDG_CONFIG_HOME/emacs/early-init.el} or +@file{~/.emacs.d/early-init.el}. This file is loaded before the +package system and GUI is initialized, so in it you can customize +variables that affect frame appearance as well as the package +initialization process, such as @code{package-enable-at-startup}, +@code{package-load-list}, and @code{package-user-dir}. Note that +variables like @code{package-archives} which only affect the +installation of new packages, and not the process of making +already-installed packages available, may be customized in the regular init file. @xref{Package Installation}. We do not recommend that you move into @file{early-init.el} diff --git a/etc/NEWS b/etc/NEWS index f358a211a5..09a5e7a8aa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -24,6 +24,12 @@ When you add a new item, use the appropriate mark if you are sure it applies, * Installation Changes in Emacs 27.1 +** Emacs now supports XDG Base Directory specification +Emacs now uses "$XDG_CONFIG_HOME/emacs/" for 'user-emacs-directory' if +it exists, including for the init and early init files. If +"$XDG_CONFIG_HOME" is not set, Emacs will use "~/.config/emacs/" if it +exists, and will otherwise fall back to "~/.emacs.d/". + ** Emacs now uses GMP, the GNU Multiple Precision library. By default, if 'configure' does not find a suitable libgmp, it arranges for the included mini-gmp library to be built and used. diff --git a/lisp/startup.el b/lisp/startup.el index 90046389d1..49b44fbae3 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1,4 +1,4 @@ -;; startup.el --- process Emacs shell arguments -*- lexical-binding: t -*- +;;; startup.el --- process Emacs shell arguments -*- lexical-binding: t -*- ;; Copyright (C) 1985-1986, 1992, 1994-2019 Free Software Foundation, ;; Inc. @@ -971,15 +971,6 @@ startup--load-user-init-file (when debug-on-error-should-be-set (setq debug-on-error debug-on-error-from-init-file)))) -(defun find-init-path (fn) - "Look in ~/.config/FOO or ~/.FOO for the dotfile or dot directory FOO. -It is expected that the output will undergo ~ expansion. Implements the -XDG convention for dotfiles." - (let* ((xdg-path (concat "~" init-file-user "/.config/" fn)) - (oldstyle-path (concat "~" init-file-user "/." fn)) - (found-path (if (file-exists-p xdg-path) xdg-path oldstyle-path))) - found-path)) - (defun command-line () "A subroutine of `normal-top-level'. Amongst another things, it parses the command-line arguments." @@ -1180,8 +1171,7 @@ command-line ;; with the .el extension, if the file doesn't exist, not just ;; "early-init" without an extension, as it does for ".emacs". "early-init.el" - (file-name-as-directory - (find-init-path "emacs.d"))))) + (file-name-as-directory user-emacs-directory)))) (setq early-init-file user-init-file) ;; If any package directory exists, initialize the package system. @@ -1322,7 +1312,7 @@ command-line ((eq system-type 'ms-dos) (concat "~" init-file-user "/_emacs")) ((not (eq system-type 'windows-nt)) - (find-init-path "emacs")) + (concat "~" init-file-user "/.emacs")) ;; Else deal with the Windows situation. ((directory-files "~" nil "^\\.emacs\\(\\.elc?\\)?$") ;; Prefer .emacs on Windows. @@ -1339,8 +1329,7 @@ command-line (lambda () (expand-file-name "init" - (file-name-as-directory - (find-init-path "emacs.d")))) + (file-name-as-directory user-emacs-directory))) (not inhibit-default-init)) (when (and deactivate-mark transient-mark-mode) diff --git a/lisp/subr.el b/lisp/subr.el index 73031a2a9f..dc2a4d8373 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2924,7 +2924,11 @@ user-emacs-directory (if (eq system-type 'ms-dos) ;; MS-DOS cannot have initial dot. "~/_emacs.d/" - "~/.emacs.d/") + (let ((config-dir (or (getenv "XDG_CONFIG_HOME") + (concat "~" init-file-user "/.config")))) + (if (file-exists-p config-dir) + (concat config-dir "/emacs/") + (concat "~" init-file-user "/.emacs.d/")))) "Directory beneath which additional per-user Emacs-specific files are placed. Various programs in Emacs store information in this directory. Note that this should end with a directory separator. -- 2.21.0