152 lines
5.8 KiB
EmacsLisp
152 lines
5.8 KiB
EmacsLisp
;;; system.el --- System-specific configuration -*- lexical-binding: t; -*-
|
|
|
|
;;; Commentary:
|
|
|
|
;; When using Emacs on separate computers, some variables need different
|
|
;; settings. This library contains functions and variables to work with
|
|
;; different system configurations for Emacs.
|
|
|
|
;;; Code:
|
|
|
|
(require 'cl-lib)
|
|
|
|
(defgroup system nil
|
|
"System-specific configurations."
|
|
:group 'emacs
|
|
:prefix "system-")
|
|
|
|
;;; Variables
|
|
|
|
(defcustom system-load-alist '((system-microsoft-p . windows)
|
|
(system-linux-p . linux))
|
|
"Alist describing which system Emacs is on.
|
|
Each cell is of the form (PREDICATE . SYSTEM), where PREDICATE is
|
|
a function of no arguments and SYSTEM is a string or symbol that
|
|
will be passed to `system-settings-load'.
|
|
|
|
This list need not be exhaustive; see `system-settings-load' for
|
|
more details on what happens if this alist is exhausted."
|
|
:type '(alist :key-type function :value-type (choice string symbol)))
|
|
|
|
(defcustom system-load-directory (locate-user-emacs-file "systems")
|
|
"The directory from which to load system-specific configurations."
|
|
:type 'file)
|
|
|
|
;; `defcustoms' defined here are best-guess defaults.
|
|
|
|
(defcustom system-default-font (pcase system-type
|
|
((or 'ms-dos 'windows-nt)
|
|
"Consolas")
|
|
(_ "monospace"))
|
|
"The font used for the `default' face."
|
|
:type 'string)
|
|
|
|
(defcustom system-default-height 100
|
|
"The height used for the `default' face."
|
|
:type 'number)
|
|
|
|
(defcustom system-variable-pitch-font (pcase system-type
|
|
((or 'ms-dos 'windows-nt)
|
|
"Arial")
|
|
(_ "sans-serif"))
|
|
"The font used for the `variable-pitch' face."
|
|
:type 'string)
|
|
|
|
(defcustom system-variable-pitch-height 1.0
|
|
"The height used for the `variable-pitch' face.
|
|
A floating-point number is recommended, since that makes it
|
|
relative to the `default' face height."
|
|
:type 'number)
|
|
|
|
(defvar system-file nil
|
|
"The current system's file for system-specific configuration.
|
|
Do not edit this by hand. Instead, call `system-system-file'.")
|
|
|
|
;;; Functions
|
|
|
|
;; Convenience functions for systems
|
|
(defun system-microsoft-p ()
|
|
"Return non-nil if running in a Microsoft system."
|
|
(memq system-type '(ms-dos windows-nt)))
|
|
|
|
(defun system-linux-p ()
|
|
"Return non-nil if running on a Linux system."
|
|
(memq system-type '(gnu/linux)))
|
|
|
|
(defun system-warn (message &rest args)
|
|
"Display a wraning message made from (format-message MESSAGE ARGS...).
|
|
This function is like `warn', except it uses the `system' type."
|
|
(display-warning 'system (apply #'format-message message args)))
|
|
|
|
(defun system-system-file (&optional system refresh-cache set-system-file-p)
|
|
"Determine the current system's system-specific file.
|
|
The current system's file will be returned, and the value of
|
|
`system-file' set /unless/ the parameter SYSTEM was passed to
|
|
this function and SET-SYSTEM-FILE-P is nil. If both SYSTEM and
|
|
SET-SYSTEM-FILE-P are non-nil, this function will still set
|
|
`system-file'.
|
|
|
|
If SYSTEM is not passed, and `system-file' is set, simply return
|
|
its value /unless/ REFRESH-CACHE is non-nil, in which case
|
|
`system-load-alist' will be looped through to find the
|
|
appropriate system by testing the car of each cell there. When
|
|
one matches, use the cdr of that cell as SYSTEM. If none
|
|
matches, return nil.
|
|
|
|
This function will only look for system-specific files in
|
|
`system-load-directory'."
|
|
(let* ((system* (or system
|
|
(and system-file (not refresh-cache))
|
|
(cl-loop for (p . s) in system-load-alist
|
|
if (funcall p) return s)))
|
|
(file (expand-file-name (format "%s" system*) system-load-directory)))
|
|
(when (or (not system)
|
|
(and system set-system-file-p))
|
|
(setq system-file file))
|
|
file))
|
|
|
|
;;;###autoload
|
|
(defun system-settings-load (&optional system error nomessage)
|
|
"Load system settings.
|
|
Load settings from `system-file', or the `system-file' as
|
|
determined by SYSTEM, if passed. See `system-system-file' for
|
|
details on how the `system-file' is determined.
|
|
|
|
ERROR determines how to deal with errors: if nil, warn the user
|
|
when `system-file' can't be found or when the system being used
|
|
can't be determined. If t, those are elevated to errors. If any
|
|
other value, the errors are completely ignored.
|
|
|
|
NOMESSAGE is passed directly to `load'."
|
|
(let ((file (system-system-file system)))
|
|
(if file
|
|
(condition-case e
|
|
(load file nil nomessage)
|
|
(t (cond ((eq error t) (signal (car e) (cdr e)))
|
|
((null error) (system-warn "Couldn't find file `%s'."
|
|
file)))))
|
|
(funcall (cond ((eq error t) #'error)
|
|
((null error) #'system-warn)
|
|
(t #'ignore))
|
|
"Could not determine the system being used."))))
|
|
|
|
;;;###autoload
|
|
(defun system-find-system-file (&optional system)
|
|
"Find the current system's system-file."
|
|
(interactive (list (completing-read "System file: "
|
|
(mapcar (lambda (a) (format "%s" (cdr a)))
|
|
system-load-alist)
|
|
nil t nil nil
|
|
(cl-loop for (p . s) in system-load-alist
|
|
if (funcall p)
|
|
return (format "%s" s)))))
|
|
(find-file (cl-loop with file = (system-system-file system)
|
|
for cand in (list file
|
|
(concat file ".el"))
|
|
if (file-exists-p cand)
|
|
return cand
|
|
finally return cand)))
|
|
|
|
(provide 'system)
|
|
;;; system.el ends here
|