XDG Compliant init directory.
authorSteve Youngs <steve@sxemacs.org>
Sat, 2 May 2015 15:56:21 +0000 (01:56 +1000)
committerSteve Youngs <steve@sxemacs.org>
Sat, 2 May 2015 15:56:21 +0000 (01:56 +1000)
This changeset moves the init directory from ~/.sxemacs to
$XDG_CONFIG_HOME/sxemacs, falling back to ~/.config/sxemacs when
$XDG_CONFIG_HOME isn't set.

SXEmacs will continue to use ~/.sxemacs if that directory exists, unless
the XDG-based directory also exists.  In that case, the XDG-based directory
will take precedence, unless the user has set $SXE_USE_LEGACY in their
environment.

If no init directories exist, use the XDG-based directory, unless
$SXE_USE_LEGACY has been set.

If multiple init directories exist a warning is displayed to the user
showing the directories found, and which is the one in use.  This warning
can be suppressed by adding the symbol `multi-initd' to
`display-warning-suppressed-classes'

* lisp/startup.el (find-user-init-directory): New.
(user-init-directory): Set to empty string.
(user-init-directory-base): Removed.
(command-line-do-help): Warn that using -user may not be the
wisest of choices.
(command-line-early): When using -user set user-init-directory to
~user/.config/sxemacs, or ~user/.sxemacs if that doesn't exist.
(site-start-file): Doc fix.

* lisp/site-start.el: New.  Deals with the consequences of
computing a user-init-directory at run-time.

* lisp/Makefile.am (corelispels): Add site-start.el.

Signed-off-by: Steve Youngs <steve@sxemacs.org>
lisp/Makefile.am
lisp/site-start.el [new file with mode: 0644]
lisp/startup.el

index e3a3bbd..3276074 100644 (file)
@@ -96,13 +96,14 @@ corelispels =                                                               \
        page.el paragraphs.el paths.el picture.el printer.el            \
        process.el rect.el regexp-opt.el register.el replace.el         \
        resize-minibuffer.el scrollbar.el select.el shadow.el simple.el \
-       sound.el specifier.el subr.el symbol-syntax.el symbols.el       \
-       syntax.el text-mode.el text-props.el toolbar-items.el           \
-       toolbar.el tty-init.el undo-stack.el userlock.el version.el     \
-       view-less.el wid-browse.el wid-edit.el widget.el                \
-       window-xemacs.el window.el x-color.el x-compose.el x-faces.el   \
-       x-font-menu.el x-init.el x-iso8859-1.el x-misc.el x-mouse.el    \
-       x-scrollbar.el x-select.el x-win-sun.el x-win-xfree86.el
+       site-start.el sound.el specifier.el subr.el symbol-syntax.el    \
+        symbols.el syntax.el text-mode.el text-props.el                 \
+       toolbar-items.el toolbar.el tty-init.el undo-stack.el           \
+       userlock.el version.el view-less.el wid-browse.el wid-edit.el   \
+       widget.el window-xemacs.el window.el x-color.el x-compose.el    \
+       x-faces.el x-font-menu.el x-init.el x-iso8859-1.el x-misc.el    \
+       x-mouse.el x-scrollbar.el x-select.el x-win-sun.el              \
+       x-win-xfree86.el
 
 ffilispels =                                                           \
        ffi/ffi-curl.el ffi/ffi-gcrypt.el ffi/ffi-libc.el               \
diff --git a/lisp/site-start.el b/lisp/site-start.el
new file mode 100644 (file)
index 0000000..c8955a6
--- /dev/null
@@ -0,0 +1,58 @@
+;;; site-start.el --- Site-wide customisations
+;;                    that must be loaded before the user's init files
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Up until now (May, 2015), user-init-directory had always been
+;; hard-coded to ~/.sxemacs.  Today we take a more "dynamic"
+;; approach and support $XDG_CONFIG_HOME as well.  Unfortunately,
+;; that flexibility has consequences.  This snippet deals with
+;; those consequences. --SY
+(when (zerop (length user-init-directory))
+
+  ;; Compute the init directory location
+  (setq user-init-directory (find-user-init-directory))
+
+  ;; Make sure the load-path includes any packages the user may have
+  ;; in their local setup.
+  (unless inhibit-early-packages
+    (startup-setup-paths emacs-roots user-init-directory))
+
+  ;; There could possibly now be some more auto-autoloads to load from
+  ;; the user's local packages.
+  (unless inhibit-autoloads
+    (unless inhibit-early-packages
+      (packages-load-package-auto-autoloads early-package-load-path)))
+
+  ;; emodules ?
+
+  ;; Reset the lisp init.d directory
+  (setq lisp-initd-dir
+       (file-name-as-directory
+        (paths-construct-path (list user-init-directory
+                                    lisp-initd-basename))))
+
+  ;; Lastly, warn the user if multiple candidates for user-init-directory
+  ;; were found.
+  (let* ((legacy (expand-file-name "~/.sxemacs"))
+        (xdg (expand-file-name "sxemacs"
+                               (getenv "XDG_CONFIG_HOME")))
+        (fback (paths-construct-path
+                (list (user-home-directory) ".config" "sxemacs")))
+        (dirs (remove-duplicates
+               (list legacy xdg fback) :test #'string=))
+        (ndirs (count-if #'file-directory-p dirs)))
+    (when (> ndirs 1)
+      (lwarn 'multi-initd nil
+       "Multiple init directories found:
+%S
+
+Currently using: %s
+
+See `display-warning-suppressed-classes' to suppress this warning"
+       dirs user-init-directory))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Site-specific additions go here.
+
+
+;;; End site-start.el
index 1004d5f..81e668d 100644 (file)
@@ -3,7 +3,7 @@
 ;; Copyright (C) 1985-1986, 1990, 1992-1997 Free Software Foundation, Inc.
 ;; Copyright (c) 1993, 1994 Sun Microsystems, Inc.
 ;; Copyright (C) 1995 Board of Trustees, University of Illinois
-;; Copyright (C) 2004 - 2012 Steve Youngs
+;; Copyright (C) 2004 - 2015 Steve Youngs
 
 ;; Maintainer: SXEmacs Development Team
 ;; Keywords: internal, dumped
@@ -92,17 +92,41 @@ the user's init file.")
 (defvar emacs-roots nil
   "List of plausible roots of the SXEmacs hierarchy.")
 
-(defvar user-init-directory-base ".sxemacs"
-  "Base of directory where user-installed init files may go.")
-
-(defvar user-init-directory
-  (file-name-as-directory
-   (paths-construct-path (list "~" user-init-directory-base)))
+(defun find-user-init-directory ()
+  "Find the user's init directory.
+
+If no init directory currently exists, this will return:
+\"$XDG_CONFIG_HOME/sxemacs\", which falls back to
+\"~/.config/sxemacs\" if $XDG_CONFIG_HOME is not set in the user's
+environment.
+
+If the legacy init directory, \"~/.sxemacs\" exists, return that.
+
+If both the legacy directory and the XDG-based directory exist, return
+the XDG-based directory unless $SXE_USE_LEGACY is set in the user's
+environment."
+  (let* ((legacy (getenv "SXE_USE_LEGACY"))
+        (xdg (getenv "XDG_CONFIG_HOME"))
+        (xdgdir (or (and xdg
+                         (paths-construct-path
+                          (list xdg "sxemacs")))
+                    (paths-construct-path
+                     (list (user-home-directory) ".config" "sxemacs"))))
+        (legacydir (paths-construct-path
+                    (list (user-home-directory) ".sxemacs")))
+        (locations (list xdgdir legacydir)))
+    (if legacy
+       (file-name-as-directory legacydir)
+      (catch 'found
+       (dolist (dir locations)
+         (and (paths-file-readable-directory-p dir)
+              (throw 'found (file-name-as-directory dir))))
+       (file-name-as-directory xdgdir)))))
+
+(defvar user-init-directory ""
   "Directory where user-installed init files may go.
 
-This defaults to \"~/.sxemacs\".  Old XEmacs users can get up and
-running quickly by symlinking \"~/.sxemacs\" to their existing
-\"~/.xemacs\" directory.")
+See: `find-user-init-directory'.")
 
 (defvar user-init-file-base-list '("init.elc" "init.el")
   "List of allowed init files in the user's init directory.
@@ -115,13 +139,13 @@ The first one found takes precedence.")
 
 (defvar site-start-file "site-start"
   "File containing site-wide run-time initializations.
-This file is loaded at run-time before `~/.sxemacs/init.el'.  It
+This file is loaded at run-time before `user-init-file'.  It
 contains inits that need to be in place for the entire site, but
 which, due to their higher incidence of change, don't make sense to
 load into SXEmacs' dumped image.  Thus, the run-time load order is:
 
   1. file described in this variable, if non-nil;
-  2. `~/.sxemacs/init.el';
+  2. `user-init-file';
   3. `/path/to/sxemacs/lisp/default.el'.
 
 Don't use the `site-start.el' file for things some users may not like.
@@ -224,6 +248,7 @@ In addition, the")
   -user-init-file <file> Use <file> as init file.
   -user-init-directory <directory> Use <directory> as init directory.
   -user <user>          Load user's init file instead of your own.
+                        Probably not a wise thing to do.
   -u <user>             Same as -user.\n")
    (let ((l command-switch-alist)
          (insert (lambda (&rest x)
@@ -498,10 +523,14 @@ Type ^H^H^H (Control-h Control-h Control-h) to get more help options.\n")
        ((or (string= arg "-u")
            (string= arg "-user"))
        (let* ((user (pop args))
-              (home-user (concat "~" user)))
-         (setq user-init-directory (file-name-as-directory
-                                    (paths-construct-path
-                                     (list home-user user-init-directory-base))))
+              (home-user (concat "~" user))
+              (xdgdir (paths-construct-path
+                       (list home-user ".config" "sxemacs")))
+              (legacydir (paths-construct-path (list home-user ".sxemacs")))
+              (dir-user (or (and (file-directory-p xdgdir)
+                                 (file-name-as-directory xdgdir))
+                            (file-name-as-directory legacydir))))
+         (setq user-init-directory dir-user)
          (setq user-init-file
                (find-user-init-file user-init-directory))
          (setq custom-file