From 3a28393a23055f45c0396c55e6e03e6570a54e2a Mon Sep 17 00:00:00 2001 From: Eivind Fonn Date: Tue, 30 Aug 2016 11:26:38 +0200 Subject: [PATCH] Implement :enabled-for layer keyword --- core/core-configuration-layer.el | 30 ++++++++-- doc/DOCUMENTATION.org | 25 +++++++- tests/core/core-configuration-layer-utest.el | 60 ++++++++++++++++++++ 3 files changed, 108 insertions(+), 7 deletions(-) diff --git a/core/core-configuration-layer.el b/core/core-configuration-layer.el index 917c22f2d..015cf265e 100644 --- a/core/core-configuration-layer.el +++ b/core/core-configuration-layer.el @@ -97,7 +97,12 @@ ROOT is returned." (disabled :initarg :disabled-for :initform nil :type list - :documentation "A list of layer where this layer is disabled.")) + :documentation "A list of layers where this layer is disabled.") + (enabled :initarg :enabled-for + :initform 'unspecified + :type (satisfies (lambda (x) (or (listp x) (eq 'unspecified x)))) + :documentation (concat "A list of layers where this layer is enabled. " + "(Takes precedence over `:disabled-for'.)"))) "A configuration layer.") (defmethod cfgl-layer-owned-packages ((layer cfgl-layer)) @@ -504,6 +509,10 @@ indexed layers for the path." (let* ((dir (file-name-as-directory dir)) (disabled (when (listp layer-specs) (spacemacs/mplist-get layer-specs :disabled-for))) + (enabled (if (and (listp layer-specs) + (memq :enabled-for layer-specs)) + (spacemacs/mplist-get layer-specs :enabled-for) + 'unspecified)) (variables (when (listp layer-specs) (spacemacs/mplist-get layer-specs :variables))) (packages-file (concat dir "packages.el")) @@ -522,6 +531,7 @@ indexed layers for the path." (oset obj :dir dir) (when usedp (oset obj :disabled-for disabled) + (oset obj :enabled-for enabled) (oset obj :variables variables)) (when packages (oset obj :packages packages) @@ -1491,18 +1501,26 @@ wether the declared layer is an used one or not." (t (configuration-layer//configure-package pkg)))))))) +(defun configuration-layer//package-enabled-p (pkg layer) + "Returns true if PKG should be configured for LAYER. +LAYER must not be the owner of PKG." + (let* ((owner (configuration-layer/get-layer (car (oref pkg :owners)))) + (disabled (oref owner :disabled-for)) + (enabled (oref owner :enabled-for))) + (if (not (eq 'unspecified enabled)) + (memq layer enabled) + (not (memq layer disabled))))) + (defun configuration-layer//configure-package (pkg) "Configure PKG object." (let* ((pkg-name (oref pkg :name)) - (owner (car (oref pkg :owners))) - (owner-layer (configuration-layer/get-layer owner)) - (disabled-for-layers (oref owner-layer :disabled-for))) + (owner (car (oref pkg :owners)))) (spacemacs-buffer/message (format "Configuring %S..." pkg-name)) ;; pre-init (mapc (lambda (layer) (when (configuration-layer/layer-usedp layer) - (if (memq layer disabled-for-layers) + (if (not (configuration-layer//package-enabled-p pkg layer)) (spacemacs-buffer/message (format " -> ignored pre-init (%S)..." layer)) (spacemacs-buffer/message @@ -1524,7 +1542,7 @@ wether the declared layer is an used one or not." (mapc (lambda (layer) (when (configuration-layer/layer-usedp layer) - (if (memq layer disabled-for-layers) + (if (not (configuration-layer//package-enabled-p pkg layer)) (spacemacs-buffer/message (format " -> ignored post-init (%S)..." layer)) (spacemacs-buffer/message diff --git a/doc/DOCUMENTATION.org b/doc/DOCUMENTATION.org index 96b0971a2..1318f3c6e 100644 --- a/doc/DOCUMENTATION.org +++ b/doc/DOCUMENTATION.org @@ -628,10 +628,33 @@ you can do it with the following layer declaration. (defun dotspacemacs/layers () ;; List of configuration layers to load. (setq-default dotspacemacs-configuration-layers - '(org + '(org git (auto-completion :disabled-for org git)))) #+END_SRC +You can also use the =:enabled-for= construct to disable it for /all/ layers +/except/ those explicitly identified. + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(java python c-c++ + (auto-completion :enabled-for java python)))) +#+END_SRC + +Note that =:enabled-for= may be an empty list. + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(java python c-c++ + (auto-completion :enabled-for)))) +#+END_SRC + +=:enabled-for= takes precedence over =:disabled-for= if both are present. + *** Selecting/Ignoring packages of a layer By default a declared layer installs/configures all its associated packages. You may want to select only some of them or ignoring some of them. This is possible diff --git a/tests/core/core-configuration-layer-utest.el b/tests/core/core-configuration-layer-utest.el index c25423214..38054d5df 100644 --- a/tests/core/core-configuration-layer-utest.el +++ b/tests/core/core-configuration-layer-utest.el @@ -1328,6 +1328,66 @@ (configuration-layer//configure-package pkg) (should (equal '(init) witness))))) +(ert-deftest test-configure-package--enabled-for-unspecified-does-call-pre-post-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :enabled-for 'unspecified) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(post-init init pre-init) witness))))) + +(ert-deftest test-configure-package--enabled-for-nil-does-not-call-pre-post-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :enabled-for nil) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init) witness))))) + +(ert-deftest test-configure-package--enabled-for-partial () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :enabled-for '(layer2)) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init pre-init) witness))))) + ;; --------------------------------------------------------------------------- ;; configuration-layer//configure-packages-2 ;; ---------------------------------------------------------------------------