231 lines
7.7 KiB
EmacsLisp
231 lines
7.7 KiB
EmacsLisp
|
;;; xdg-paths.el --- XDG Base Directory Specification paths for emacs.
|
||
|
;;;
|
||
|
;;;
|
||
|
;;; Copyright ©2011 Francisco Miguel Colaço <francisco.colaco@gmail.com>
|
||
|
;;; All rights reserved.
|
||
|
;;;
|
||
|
;;; This library is free software; you can redistribute it and/or
|
||
|
;;; modify it under the terms of the GNU Lesser General Public
|
||
|
;;; License as published by the Free Software Foundation; either
|
||
|
;;; version 3 of the License, or (at your option) any later version.
|
||
|
;;;
|
||
|
;;; This library is distributed in the hope that it will be useful,
|
||
|
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
;;; Lesser General Public License for more details.
|
||
|
;;;
|
||
|
;;; You should have received a copy of the GNU Lesser General Public
|
||
|
;;; License along with this library; if not, write to the
|
||
|
;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||
|
;;; Boston, MA 02111-1307, USA.
|
||
|
;;;
|
||
|
;;;
|
||
|
;;; Commentary:
|
||
|
;;;
|
||
|
;;; This package sets the directory according to the XDG Base
|
||
|
;;; Directory Specification. The directories are given by the
|
||
|
;;; environment variables, falling back to the defaults enumerated
|
||
|
;;; in the standard.
|
||
|
;;;
|
||
|
;;; The $XDG_RUNTIME_DIR was not contemplated here, since we found
|
||
|
;;; no practical use for it.
|
||
|
;;;
|
||
|
;;; The defaults (or generated values) are:
|
||
|
;;;
|
||
|
;;; Symbol Default
|
||
|
;;; user-emacs-data-directory ~/.local/share/emacs/
|
||
|
;;; user-emacs-config-directory ~/.config/emacs/
|
||
|
;;; user-emacs-cache-directory ~/.cache/emacs/
|
||
|
;;; user-emacs-lisp-directory `user-emacs-data-directory`/lisp
|
||
|
;;; user-documents-directory ~/Documents
|
||
|
;;;
|
||
|
;;; Some convenience functions are defined to locate files in these
|
||
|
;;; directories and to add user lisp to load-path.
|
||
|
;;;
|
||
|
;;; Some advantages are:
|
||
|
;;;
|
||
|
;;; Installation:
|
||
|
;;;
|
||
|
;;; 1. put xdg-paths in your own path.
|
||
|
;;; 2. Start your .emacs with (load-library 'xdg-paths) or,
|
||
|
;;; write (load-library 'xdg-paths) in site-start.el
|
||
|
;;;
|
||
|
;;; Use cases:
|
||
|
;;;
|
||
|
;;; In my .emacs, I simply load a configuration hub file within
|
||
|
;;; user-emacs-config-directory with:
|
||
|
;;;
|
||
|
;;; (load (locate-user-config-file "conf-init"))
|
||
|
;;;
|
||
|
;;; Within conf-init.el file, all other files are loaded with:
|
||
|
;;;
|
||
|
;;; (dolist (module (list
|
||
|
;;; "edit" "frame" "programming" "tex" "xml"
|
||
|
;;; (concat "emacs-version-" (int-to-string emacs-major-version))
|
||
|
;;; (concat "window-system-" (symbol-name window-system))
|
||
|
;;; (concat "system-type-" (subst-char-in-string ?/ ?- (symbol-name system-type)))
|
||
|
;;; (concat "host-" (system-name))))
|
||
|
;;; (load (locate-user-config-file (concat "conf-" module)) t))
|
||
|
;;;
|
||
|
;;; Adding to path from the user library just becomes:
|
||
|
;;;
|
||
|
;;; (add-user-lisp-to-path "yasnippet")
|
||
|
;;;
|
||
|
;;; The user documents directory can be made the initial buffer in case
|
||
|
;;; no command line arguments are passed in:
|
||
|
;;;
|
||
|
;;; (if (eql (length command-line-args) 1)
|
||
|
;;; ;; No files were passed in the command line.
|
||
|
;;; (setq initial-buffer-choice user-documents-directory))
|
||
|
;;;
|
||
|
;;;
|
||
|
;;; Caveat Emptor:
|
||
|
;;;
|
||
|
;;; Variable setting and directory initialization were not properly tested.
|
||
|
;;; I have never tested setting previously the directories because the
|
||
|
;;; default results are satisfactory.
|
||
|
;;;
|
||
|
;;;
|
||
|
;;; History:
|
||
|
;;;
|
||
|
;;; 0.1.2: Tom Prince <tom.prince@ualberta.net>
|
||
|
;;; Require cl properly.
|
||
|
;;; Fix some typos and dead code.
|
||
|
;;; 0.1.1: Francisco Miguel Colaço <francisco.col...@gmail.com>
|
||
|
;;; Removed stale code;
|
||
|
;;; Replaced eq by zerop in xdg-user-dir.
|
||
|
;;; 0.1: Francisco Miguel Colaço <francisco.col...@gmail.com>
|
||
|
;;; Directory variables;
|
||
|
;;; Functions to locate files;
|
||
|
;;; add-to-path and add-user-lisp-to-path;
|
||
|
;;; xdg-user-dir (depends on xdg-user-dir existing).
|
||
|
;;;
|
||
|
;;;
|
||
|
;;; Future work:
|
||
|
;;;
|
||
|
;;; 1. Make better docstrings (I may have assumed too much).
|
||
|
;;; 3. Add customize support.
|
||
|
;;; 3. Add more functions to cover the full standard.
|
||
|
;;; 4. Add more convenience functions (as needed by others).
|
||
|
;;; 5. Refactor the initialization of the variables.
|
||
|
;;; 6. Make it within the default emacs distribution.
|
||
|
;;;
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(eval-when-compile
|
||
|
(require 'cl))
|
||
|
|
||
|
;;; Directories definition.
|
||
|
(defvar user-emacs-config-directory nil
|
||
|
"The directory where the emacs user configuration files are stored at.")
|
||
|
|
||
|
|
||
|
(defvar user-emacs-data-directory nil
|
||
|
"The directory where the emacs user data and lisp files are stored at.
|
||
|
|
||
|
\\[user-emacs-directory] is set to this directory.")
|
||
|
|
||
|
|
||
|
(defvar user-emacs-cache-directory nil
|
||
|
"The directory where the emacs user expendable files are stored at.
|
||
|
|
||
|
Files stored here should not be missed when deleted, apart a
|
||
|
temporary loss in speed.")
|
||
|
|
||
|
|
||
|
(defvar user-emacs-lisp-directory nil
|
||
|
"The directory where the user lisp packages are stored at.
|
||
|
|
||
|
This directory is added to \\[load-path].")
|
||
|
|
||
|
|
||
|
(defvar user-documents-directory nil
|
||
|
"The directory where the user stores his documents.")
|
||
|
|
||
|
|
||
|
|
||
|
(defun xdg-user-dir (dirname)
|
||
|
"Given NAME, run 'xdg-user-dir NAME' and return the result in a string.
|
||
|
|
||
|
If the command fails, return NIL."
|
||
|
(let ((command (concat "xdg-user-dir " dirname)))
|
||
|
(if (zerop (shell-command command))
|
||
|
(substring (shell-command-to-string command) 0 -1)
|
||
|
nil)))
|
||
|
|
||
|
|
||
|
(defun locate-user-file (filename &optional type)
|
||
|
"Given a file, locate it in the user files.
|
||
|
|
||
|
If TYPE is NIL or 'data, the file will be located in user-emacs-data-directory.
|
||
|
|
||
|
If 'config, it will be located in user-emacs-config-directory.
|
||
|
|
||
|
If 'cache, it will be located in user-emacs-cache-directory.
|
||
|
|
||
|
If 'lisp, it will be located in user-emacs-lisp-directory.
|
||
|
|
||
|
If 'documents, it will be located in user-documents-directory.
|
||
|
|
||
|
If the category is wrong, an error will be signaled.
|
||
|
"
|
||
|
(expand-file-name filename
|
||
|
(case type
|
||
|
((nil data) user-emacs-data-directory)
|
||
|
('config user-emacs-config-directory)
|
||
|
('lisp user-emacs-lisp-directory)
|
||
|
('cache user-emacs-cache-directory)
|
||
|
('documents user-documents-directory)
|
||
|
(t (error "The category %s is not valid" type)))))
|
||
|
|
||
|
|
||
|
(defun locate-user-config-file (filename)
|
||
|
"Given a file, locate it in `user-emacs-config-directory`."
|
||
|
(locate-user-file filename 'config))
|
||
|
|
||
|
|
||
|
(defun locate-user-lisp (filename)
|
||
|
"Given a file, locate it in `user-emacs-lisp-directory`."
|
||
|
(locate-user-file filename 'lisp))
|
||
|
|
||
|
|
||
|
(defun add-to-path (directory &optional append)
|
||
|
"Given DIRECTORY, it it exists and is indeed a directory, add
|
||
|
it to `load-path`."
|
||
|
(interactive "D")
|
||
|
(if (file-directory-p directory)
|
||
|
(add-to-list 'load-path directory append)
|
||
|
(error "The directory \"%s\" does not exist or isn't a directory." directory)))
|
||
|
|
||
|
|
||
|
(defun add-user-lisp-to-path (directory &optional append)
|
||
|
"Given DIRECTORY, it it exists and is indeed a directory, add
|
||
|
it to `load-path`."
|
||
|
(interactive "D")
|
||
|
(add-to-path (locate-user-lisp directory) append))
|
||
|
|
||
|
|
||
|
;; Set the default variables if they have no name.
|
||
|
(macrolet ((setq-if-null (variable value)
|
||
|
`(if (null ,variable)
|
||
|
(setf ,variable ,value)))
|
||
|
(getdir (variable fallback)
|
||
|
`(expand-file-name "emacs/" (or (getenv ,variable) ,fallback))))
|
||
|
(setq-if-null user-emacs-config-directory (getdir "XDG_CONFIG_HOME" "~/.config/"))
|
||
|
(setq-if-null user-emacs-data-directory (getdir "XDG_DATA_HOME" "~/.local/share/"))
|
||
|
(setq-if-null user-emacs-cache-directory (getdir "XDG_CACHE_HOME" "~/.cache/"))
|
||
|
(setq-if-null user-emacs-lisp-directory (expand-file-name "lisp" user-emacs-data-directory))
|
||
|
(setq-if-null user-documents-directory (or (xdg-user-dir "DOCUMENTS") "~/Documents")))
|
||
|
|
||
|
|
||
|
;; Set the user-emacs-directory to user-emacs-data-directory.
|
||
|
;(setf user-emacs-directory user-emacs-data-directory)
|
||
|
|
||
|
|
||
|
;; Add the user lisp directory to path.
|
||
|
(add-to-list 'load-path user-emacs-lisp-directory)
|
||
|
|
||
|
|
||
|
(provide 'xdg-paths)
|