Skip to content

Commit

Permalink
core: wrap Emacs custom in a dotfile new function
Browse files Browse the repository at this point in the history
New function `dotspacmacs/emacs-custom-settings` wrapping Emacs
custom settings sexps.
`dotspacemacs/emacs-custom-settings` is called just after the user
configuration (`dotspacemacs/user-config`)

Customize cannot write its auto-generated sexps inside a function, to
accomplish this we trick Emacs by setting the custom file to a file
in `.cache` directory, the path to this file is defined by the variable
`spacemacs--custom-file`. At the startup of Emacs we read this file
to insert its content inside the function
`dotspacemacs/emacs-custom-settings` in the dotfile, this is done in the
function `spacemacs/write-custom-settings-to-dotfile`.

I don't think we need to write the custom settings to the dotfile when
exiting Emacs as well, since we do it at startup at the very beginning
(i.e. before actually loading the dotfile) we should be OK.

Fixes syl20bnr#5170
  • Loading branch information
syl20bnr authored and CodingSolo committed Oct 29, 2018
1 parent b9eaca0 commit 68ff7c6
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 5 deletions.
95 changes: 95 additions & 0 deletions core/core-custom-settings.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
;;; core-custom-settings.el --- Spacemacs Core File
;;
;; Copyright (c) 2012-2016 Sylvain Benner & Contributors
;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3
(require 'core-dotspacemacs)

(defvar spacemacs--custom-file (concat spacemacs-cache-directory
".custom-settings"))
(setq custom-file spacemacs--custom-file)

(defun spacemacs//initialize-custom-file ()
"Initialize the custom file."
(unless (file-exists-p spacemacs--custom-file)
(with-temp-file spacemacs--custom-file
(let ((standard-output (current-buffer)))
(princ ";; -*- mode: emacs-lisp -*-\n")
(princ ";; This file is where Emacs writes custom variables.
;; Spacemacs will copy its content to your dotfile automatically in the
;; function `dotspacemacs/emacs-custom-settings'.
;; Do not alter this file, use Emacs customize interface instead.\n\n")))))

(defun spacemacs//delete-emacs-custom-settings ()
"Delete function `dotspacemacs/emacs-custom-settings' from dotfile.
Leave point at the old location of the defun, or (if there were none) at the
end of the buffer.
This function does not save the buffer."
(goto-char (point-min))
;; Skip all whitespace and comments.
(while (forward-comment 1))
(let (first)
(catch 'found
(while t ;; We exit this loop only via throw.
;; Skip all whitespace and comments.
(while (forward-comment 1))
(let ((start (point))
(sexp (condition-case nil
(read (current-buffer))
(end-of-file (throw 'found nil)))))
(when (and (listp sexp)
(eq (car sexp) 'defun)
(eq (cadr sexp) 'dotspacemacs/emacs-custom-settings))
(delete-region start (point))
(unless first
(setq first (point)))))))
(if first
(goto-char first)
;; Move in front of local variables, otherwise long Custom
;; entries would make them ineffective.
(let ((pos (point-max))
(case-fold-search t))
(save-excursion
(goto-char (point-max))
(search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
'move)
(when (search-forward "Local Variables:" nil t)
(setq pos (line-beginning-position))))
(goto-char pos)))))

(defun spacemacs//get-custom-settings-from-cache ()
"Returns the custom settings from `spacemacs--custom-file'."
(with-current-buffer (let ((find-file-visit-truename t)
(delay-mode-hooks t))
(find-file-noselect spacemacs--custom-file))
(goto-char (point-min))
;; Skip all whitespace and comments.
(while (forward-comment 1))
(buffer-substring-no-properties (point) (point-max))))

(defun spacemacs/write-custom-settings-to-dotfile ()
"Write `dotspacemacs/emacs-custom-settings' function in the dotfile"
(message "Writing Emacs custom settings to dotfile...")
(spacemacs//initialize-custom-file)
(with-current-buffer (let ((find-file-visit-truename t)
(delay-mode-hooks t))
(find-file-noselect (dotspacemacs/location)))
(spacemacs//delete-emacs-custom-settings)
(let ((standard-output (current-buffer)))
(princ "(defun dotspacemacs/emacs-custom-settings ()\n")
(princ " \"Emacs custom settings.
This is an auto-generated function, do not modify its content directly, use
Emacs customize menu instead.
This function is called at the very end of Spacemacs initialization.\"\n")
(princ (spacemacs//get-custom-settings-from-cache))
(princ ")")
(save-buffer)
(kill-buffer (current-buffer)))))

(provide 'core-custom-settings)
4 changes: 2 additions & 2 deletions core/core-dotspacemacs.el
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@ List sizes may be nil, in which case

(defmacro dotspacemacs|call-func (func &optional msg)
"Call the function from the dotfile only if it is bound.
If MSG is not nil then display a message in `*Messages'. Errors
are caught and signalled to user in spacemacs buffer."
If MSG is not nil then display a message in `*Messages*'. Errors
are caught and signaled to user in spacemacs buffer."
`(progn
(when ,msg (spacemacs-buffer/message ,msg))
(when (fboundp ',func)
Expand Down
4 changes: 4 additions & 0 deletions core/core-spacemacs.el
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
(require 'core-debug)
(require 'core-command-line)
(require 'core-dotspacemacs)
(require 'core-custom-settings)
(require 'core-release-management)
(require 'core-auto-completion)
(require 'core-jump)
Expand Down Expand Up @@ -78,6 +79,7 @@ the final step of executing code in `emacs-startup-hook'.")
;; overlapped in terminal mode. The GUI specific `<C-i>' is used
;; instead.
evil-want-C-i-jump nil)
(spacemacs/write-custom-settings-to-dotfile)
(dotspacemacs/load-file)
(require 'core-configuration-layer)
(dotspacemacs|call-func dotspacemacs/init "Calling dotfile init...")
Expand Down Expand Up @@ -209,6 +211,8 @@ defer call using `spacemacs-post-user-config-hook'."
;; them in his/her ~/.spacemacs file
(dotspacemacs|call-func dotspacemacs/user-config
"Calling dotfile user config...")
(dotspacemacs|call-func dotspacemacs/emacs-custom-settings
"Calling dotfile Emacs custom settings...")
(run-hooks 'spacemacs-post-user-config-hook)
(setq spacemacs-post-user-config-hook-run t)
(when (fboundp dotspacemacs-scratch-mode)
Expand Down
3 changes: 0 additions & 3 deletions layers/+distributions/spacemacs-base/config.el
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,6 @@ It runs `tabulated-list-revert-hook', then calls `tabulated-list-print'."
;; Session
;; ---------------------------------------------------------------------------

;; save custom variables in ~/.spacemacs
(unless (bound-and-true-p custom-file)
(setq custom-file (dotspacemacs/location)))
;; scratch buffer empty
(setq initial-scratch-message nil)
;; don't create backup~ files
Expand Down

0 comments on commit 68ff7c6

Please sign in to comment.