aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2012-11-24 11:46:29 +0800
committerChong Yidong2012-11-24 11:46:29 +0800
commit0917cc542f31c47ee6cc4ecff85dc2a698d98873 (patch)
tree7aee8454c1f0ae1a44659870f0fc123056220391
parentd125ca15f3751f36a1ec49e3d9f9de1735b43698 (diff)
downloademacs-0917cc542f31c47ee6cc4ecff85dc2a698d98873.tar.gz
emacs-0917cc542f31c47ee6cc4ecff85dc2a698d98873.zip
Fix dependency sorting in custom-theme-set-variables.
* lisp/custom.el (custom-theme-set-variables): Use a topological sort for ordering by custom dependencies. (custom--sort-vars, custom--sort-vars-1): New functions. Fixes: debbugs:12952
-rw-r--r--lisp/ChangeLog6
-rw-r--r--lisp/custom.el79
2 files changed, 61 insertions, 24 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c127bfd42e6..75004181ee1 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
12012-11-24 Chong Yidong <cyd@gnu.org>
2
3 * custom.el (custom-theme-set-variables): Use a topological sort
4 for ordering by custom dependencies (Bug#12952).
5 (custom--sort-vars, custom--sort-vars-1): New functions.
6
12012-11-24 Stefan Monnier <monnier@iro.umontreal.ca> 72012-11-24 Stefan Monnier <monnier@iro.umontreal.ca>
2 8
3 * emacs-lisp/bytecomp.el (byte-compile-file): Setup default value for 9 * emacs-lisp/bytecomp.el (byte-compile-file): Setup default value for
diff --git a/lisp/custom.el b/lisp/custom.el
index dc810e3c97d..8dfcf4bc14c 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -948,7 +948,6 @@ prior to evaluating EXP).
948 948
949COMMENT is a comment string about SYMBOL." 949COMMENT is a comment string about SYMBOL."
950 (custom-check-theme theme) 950 (custom-check-theme theme)
951
952 ;; Process all the needed autoloads before anything else, so that the 951 ;; Process all the needed autoloads before anything else, so that the
953 ;; subsequent code has all the info it needs (e.g. which var corresponds 952 ;; subsequent code has all the info it needs (e.g. which var corresponds
954 ;; to a minor mode), regardless of the ordering of the variables. 953 ;; to a minor mode), regardless of the ordering of the variables.
@@ -958,29 +957,7 @@ COMMENT is a comment string about SYMBOL."
958 (memq (get symbol 'custom-autoload) '(nil noset))) 957 (memq (get symbol 'custom-autoload) '(nil noset)))
959 ;; This symbol needs to be autoloaded, even just for a `set'. 958 ;; This symbol needs to be autoloaded, even just for a `set'.
960 (custom-load-symbol symbol)))) 959 (custom-load-symbol symbol))))
961 960 (setq args (custom--sort-vars args))
962 ;; Move minor modes and variables with explicit requires to the end.
963 (setq args
964 (sort args
965 (lambda (a1 a2)
966 (let* ((sym1 (car a1))
967 (sym2 (car a2))
968 (1-then-2 (memq sym1 (get sym2 'custom-dependencies)))
969 (2-then-1 (memq sym2 (get sym1 'custom-dependencies))))
970 (cond ((and 1-then-2 2-then-1)
971 (error "Circular custom dependency between `%s' and `%s'"
972 sym1 sym2))
973 (2-then-1 nil)
974 ;; 1 is a dependency of 2, so needs to be set first.
975 (1-then-2)
976 ;; Put minor modes and symbols with :require last.
977 ;; Putting minor modes last ensures that the mode
978 ;; function will see other customized values rather
979 ;; than default values.
980 (t (or (nth 3 a2)
981 (eq (get sym2 'custom-set)
982 'custom-set-minor-mode))))))))
983
984 (dolist (entry args) 961 (dolist (entry args)
985 (unless (listp entry) 962 (unless (listp entry)
986 (error "Incompatible Custom theme spec")) 963 (error "Incompatible Custom theme spec"))
@@ -1014,6 +991,60 @@ COMMENT is a comment string about SYMBOL."
1014 (and (or now (default-boundp symbol)) 991 (and (or now (default-boundp symbol))
1015 (put symbol 'variable-comment comment))))))) 992 (put symbol 'variable-comment comment)))))))
1016 993
994(defvar custom--sort-vars-table)
995(defvar custom--sort-vars-result)
996
997(defun custom--sort-vars (vars)
998 "Sort VARS based on custom dependencies.
999VARS is a list whose elements have the same form as the ARGS
1000arguments to `custom-theme-set-variables'. Return the sorted
1001list, in which A occurs before B if B was defined with a
1002`:set-after' keyword specifying A (see `defcustom')."
1003 (let ((custom--sort-vars-table (make-hash-table))
1004 (dependants (make-hash-table))
1005 (custom--sort-vars-result nil)
1006 last)
1007 ;; Construct a pair of tables keyed with the symbols of VARS.
1008 (dolist (var vars)
1009 (puthash (car var) (cons t var) custom--sort-vars-table)
1010 (puthash (car var) var dependants))
1011 ;; From the second table, remove symbols that are depended-on.
1012 (dolist (var vars)
1013 (dolist (dep (get (car var) 'custom-dependencies))
1014 (remhash dep dependants)))
1015 ;; If a variable is "stand-alone", put it last if it's a minor
1016 ;; mode or has a :require flag. This is not really necessary, but
1017 ;; putting minor modes last helps ensure that the mode function
1018 ;; sees other customized values rather than default values.
1019 (maphash (lambda (sym var)
1020 (when (and (null (get sym 'custom-dependencies))
1021 (or (nth 3 var)
1022 (eq (get sym 'custom-set)
1023 'custom-set-minor-mode)))
1024 (remhash sym dependants)
1025 (push var last)))
1026 dependants)
1027 ;; The remaining symbols depend on others but are not
1028 ;; depended-upon. Do a depth-first topological sort.
1029 (maphash #'custom--sort-vars-1 dependants)
1030 (nreverse (append last custom--sort-vars-result))))
1031
1032(defun custom--sort-vars-1 (sym &optional _ignored)
1033 (let ((elt (gethash sym custom--sort-vars-table)))
1034 ;; The car of the hash table value is nil if the variable has
1035 ;; already been processed, `dependant' if it is a dependant in the
1036 ;; current graph descent, and t otherwise.
1037 (when elt
1038 (cond
1039 ((eq (car elt) 'dependant)
1040 (error "Circular custom dependency on `%s'" sym))
1041 ((car elt)
1042 (setcar elt 'dependant)
1043 (dolist (dep (get sym 'custom-dependencies))
1044 (custom--sort-vars-1 dep))
1045 (setcar elt nil)
1046 (push (cdr elt) custom--sort-vars-result))))))
1047
1017 1048
1018;;; Defining themes. 1049;;; Defining themes.
1019 1050