;;; leaf-tests.el --- -*- lexical-binding: t; -*- ;; Copyright (C) 2018-2020 Free Software Foundation, Inc. ;; Author: Naoya Yamashita ;; Maintainer: Naoya Yamashita ;; URL: https://github.com/conao3/leaf.el ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program 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 General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; ;;; Code: (load "cort-test") (require 'leaf) ;;;; General polyfill (when (not (fboundp 'autoload-do-load)) (defun autoload-do-load (fundef &optional funname macro-only) (if (or (not (consp fundef)) (not (eql 'autoload (car fundef)))) fundef (let ((kind (nth 4 fundef))) (if (and (eql macro-only 'macro) (not (or (eql kind t) (eql kind 'macro)))) fundef) (if purify-flag (error "Attempt to autoload %s while preparing to dump" (symbol-name funnname))) (unwind-protect (let ((ignore-errors (if (or (eql kind t) (eql kind 'macro)) nil macro_only))) (load (cadr fundef) ignore-errors t nil t)) ;; FIXME: revert partially performed defuns ()) (if (or (not funname) ignore-errors) nil (let ((fun (indirect-function funname, nil))) (if (equal fun fundef) (error "Autoloading file %s failed to define function %s" (caar load-history) (symbol-name funname)) fun))))))) (when (not (fboundp 'macroexpand-1)) (defun macroexpand-1 (form &optional environment) "Perform (at most) one step of macroexpansion." (cond ((consp form) (let* ((head (car form)) (env-expander (assq head environment))) (if env-expander (if (cdr env-expander) (apply (cdr env-expander) (cdr form)) form) (if (not (and (symbolp head) (fboundp head))) form (let ((def (autoload-do-load (symbol-function head) head 'macro))) (cond ;; Follow alias, but only for macros, otherwise we may end up ;; skipping an important compiler-macro (e.g. cl--block-wrapper). ((and (symbolp def) (macrop def)) (cons def (cdr form))) ((not (consp def)) form) (t (if (eq 'macro (car def)) (apply (cdr def) (cdr form)) form)))))))) (t form)))) ;;;; support macros for test definition (defmacro cort-deftest-with-equal (name form) "Return `cort-deftest' compare by `equal' for NAME, FORM. Example: (p (cort-deftest-with-equal leaf/disabled '((asdf asdf-fn) (uiop uiop-fn)))) => (cort-deftest leaf/disabled '((:equal 'asdf asdf-fn) (:equal 'uiop uiop-fn)))" (declare (indent 1)) `(cort-deftest ,name ',(mapcar (lambda (elm) `(:equal ,(cadr elm) ,(car elm))) (cadr form)))) (defmacro cort-deftest-with-macroexpand (name form) "Return `cort-deftest' compare by `equal' for NAME, FORM. Example: (p (cort-deftest-with-equal leaf/disabled '((asdf asdf) (uiop uiop)))) => (cort-deftest leaf/disabled '((:equal 'asdf (macroexpand-1 'asdf)) (:equal 'uiop (macroexpand-1 'uiop))))" (declare (indent 1)) `(cort-deftest ,name ',(mapcar (lambda (elm) `(:equal ',(cadr elm) (macroexpand-1 ',(car elm)))) (cadr form)))) (defmacro cort-deftest-with-macroexpand-let (name letform form) "Return `cort-deftest' compare by `equal' for NAME, LETFORM FORM. Example: (p (cort-deftest-with-macroexpand-let leaf/leaf ((leaf-expand-leaf-protect t)) '(((leaf leaf :config (leaf-init)) (prog1 'leaf (leaf-handler-leaf-protect leaf (leaf-init))))))) => (cort-deftest leaf/leaf '((:equal '(prog1 'leaf (leaf-handler-leaf-protect leaf (leaf-init))) (let ((leaf-expand-leaf-protect t)) (macroexpand-1 '(leaf leaf :config (leaf-init)))))))" (declare (indent 2)) `(cort-deftest ,name ',(mapcar (lambda (elm) `(:equal ',(cadr elm) (let ,letform (macroexpand-1 ',(car elm))))) (cadr form)))) ;;;; test definition (setq leaf-expand-leaf-protect nil) (setq leaf-expand-leaf-defun nil) (setq leaf-expand-leaf-defvar nil) (setq leaf-expand-leaf-path nil) (cort-deftest-with-macroexpand leaf/none '(((leaf leaf) (prog1 'leaf)))) (cort-deftest-with-macroexpand leaf/disabled '(((leaf leaf :disabled t :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled t t :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled t nil :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled nil t :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled t :disabled t :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled t :disabled nil :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled t :disabled t t :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled t :disabled t nil :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled t :disabled nil t :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled t :disabled nil nil :config (leaf-init)) (prog1 'leaf)) ((leaf leaf :disabled nil :disabled t :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled t t :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled t nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled nil t :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled nil nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled t :disabled t :config (leaf-init) :disabled t) (prog1 'leaf)) ((leaf leaf :disabled t :disabled nil :config (leaf-init) :disabled nil) (prog1 'leaf)) ((leaf leaf :disabled t :disabled t t :config (leaf-init) :disabled t t) (prog1 'leaf)) ((leaf leaf :disabled t :disabled t nil :config (leaf-init) :disabled t nil) (prog1 'leaf)) ((leaf leaf :disabled t :disabled nil t :config (leaf-init) :disabled nil t) (prog1 'leaf)) ((leaf leaf :disabled t :disabled nil nil :config (leaf-init) :disabled nil nil) (prog1 'leaf)) ((leaf leaf :disabled nil :disabled t :config (leaf-init) :disabled t) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled nil :config (leaf-init) :disabled nil) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled t t :config (leaf-init) :disabled t t) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled t nil :config (leaf-init) :disabled t nil) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled nil t :config (leaf-init) :disabled nil t) (prog1 'leaf (leaf-init))) ((leaf leaf :disabled nil :disabled nil nil :config (leaf-init) :disabled nil nil) (prog1 'leaf (leaf-init))))) (cort-deftest-with-macroexpand leaf/ensure '( ;; 't will be converted leaf--name ((leaf leaf :ensure t :config (leaf-init)) (prog1 'leaf (leaf-handler-package leaf leaf nil) (leaf-init))) ;; multi symbols will be accepted ((leaf leaf :ensure t leaf-browser :config (leaf-init)) (prog1 'leaf (leaf-handler-package leaf leaf nil) (leaf-handler-package leaf leaf-browser nil) (leaf-init))) ;; multi symbols in list will be accepted ((leaf leaf :ensure (feather leaf-key leaf-browser) :config (leaf-init)) (prog1 'leaf (leaf-handler-package leaf feather nil) (leaf-handler-package leaf leaf-key nil) (leaf-handler-package leaf leaf-browser nil) (leaf-init))) ;; ensure from pin ((leaf leaf :ensure (t . pin)) (prog1 'leaf (leaf-handler-package leaf leaf pin))))) (cort-deftest-with-macroexpand leaf/package '(((leaf leaf :package t :config (leaf-init)) (prog1 'leaf (leaf-handler-package leaf leaf nil) (leaf-init))) ((leaf leaf :package t leaf-browser :config (leaf-init)) (prog1 'leaf (leaf-handler-package leaf leaf nil) (leaf-handler-package leaf leaf-browser nil) (leaf-init))) ((leaf leaf :package feather leaf-key leaf-browser :config (leaf-init)) (prog1 'leaf (leaf-handler-package leaf feather nil) (leaf-handler-package leaf leaf-key nil) (leaf-handler-package leaf leaf-browser nil) (leaf-init))) ((leaf leaf :package nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :package nil leaf :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :package (t . pin)) (prog1 'leaf (leaf-handler-package leaf leaf pin))))) (cort-deftest-with-macroexpand leaf/doc '( ;; any sexp will be ignored ((leaf leaf :doc "Symplify init.el configuration" :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :file "~/.emacs.d/elpa/leaf.el/leaf.el" :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :url "https://github.com/conao3/leaf.el" :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :doc "Symplify init.el configuration" :file "~/.emacs.d/elpa/leaf.el/leaf.el" :url "https://github.com/conao3/leaf.el" :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :doc "Symplify init.el configuration" " (leaf leaf :doc \"Symplify init.el configuration\" :config (leaf-init)) => (progn (leaf-init))" " (leaf leaf :disabled nil :config (leaf-init)) => (progn (leaf-init))" :file "~/.emacs.d/elpa/leaf.el/leaf.el" :url "https://github.com/conao3/leaf.el" :config (leaf-init)) (prog1 'leaf (leaf-init))))) (cort-deftest-with-macroexpand leaf/load-path '( ;; string will be accepted ((leaf leaf :load-path "~/.emacs.d/elpa-archive/leaf.el/" :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (require 'leaf) (leaf-init))) ;; multi strings will be accepted ((leaf leaf :load-path "~/.emacs.d/elpa-archive/leaf.el/" "~/.emacs.d/elpa-archive/leaf-browser.el/" :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf-browser.el/") (require 'leaf) (leaf-init))) ;; multi strings in list will be accepted ((leaf leaf :load-path ("~/.emacs.d/elpa-archive/leaf.el/" "~/.emacs.d/elpa-archive/leaf-browser.el/") :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf-browser.el/") (require 'leaf) (leaf-init))) ;; nested strings is supported ((leaf leaf :load-path ("~/.emacs.d/elpa-archive/leaf.el/" ("~/.emacs.d/elpa-archive/leaf.el/" "~/.emacs.d/elpa-archive/leaf-browser.el/")) :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf-browser.el/") (require 'leaf) (leaf-init))) ;; duplicated value is ignored ((leaf leaf :load-path ("~/.emacs.d/elpa-archive/leaf.el/" ("~/.emacs.d/elpa-archive/leaf.el/" ("~/.emacs.d/elpa-archive/leaf.el/" ("~/.emacs.d/elpa-archive/leaf.el/" ("~/.emacs.d/elpa-archive/leaf.el/"))))) :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (require 'leaf) (leaf-init))) ;; use backquote and comma to configure with result of sexp ((leaf leaf :load-path ("~/.emacs.d/elpa-archive/leaf.el/") :load-path `(,(mapcar (lambda (elm) (concat "~/.emacs.d/elpa-archive/" elm "/")) '("leaf.el" "leaf-broser.el" "orglyth.el"))) :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf-broser.el/") (add-to-list 'load-path "~/.emacs.d/elpa-archive/orglyth.el/") (require 'leaf) (leaf-init))))) (cort-deftest-with-macroexpand-let leaf/load-path* ((user-emacs-directory "~/.emacs.d")) '( ;; string will be accepted ((leaf leaf :load-path* "leaf.el" :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path (locate-user-emacs-file "leaf.el")) (require 'leaf) (leaf-init))) ;; multi strings will be accepted ((leaf leaf :load-path* "leaf.el" "leaf-browser.el" :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path (locate-user-emacs-file "leaf.el")) (add-to-list 'load-path (locate-user-emacs-file "leaf-browser.el")) (require 'leaf) (leaf-init))) ;; multi strings in list will be accepted ((leaf leaf :load-path* ("leaf.el" "leaf-browser.el") :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path (locate-user-emacs-file "leaf.el")) (add-to-list 'load-path (locate-user-emacs-file "leaf-browser.el")) (require 'leaf) (leaf-init))) ;; nested strings is supported ((leaf leaf :load-path* ("leaf.el" ("leaf.el" "leaf-browser.el")) :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path (locate-user-emacs-file "leaf.el")) (add-to-list 'load-path (locate-user-emacs-file "leaf-browser.el")) (require 'leaf) (leaf-init))) ;; duplicated value is ignored ((leaf leaf :load-path* ("leaf.el" ("leaf.el" ("leaf.el" ("leaf.el" ("leaf.el"))))) :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path (locate-user-emacs-file "leaf.el")) (require 'leaf) (leaf-init))))) (cort-deftest-with-macroexpand leaf/defun '( ;; symbol will be accepted and use leaf--name ((leaf leaf :defun leaf) (prog1 'leaf (declare-function leaf "leaf"))) ;; multi symbols will be accepted ((leaf leaf :defun leaf leaf-normalize-plist leaf-merge-dupkey-values-plist) (prog1 'leaf (declare-function leaf "leaf") (declare-function leaf-normalize-plist "leaf") (declare-function leaf-merge-dupkey-values-plist "leaf"))) ;; multi symbols in list will be accepted ((leaf leaf :defun (leaf leaf-normalize-plist leaf-merge-dupkey-values-plist)) (prog1 'leaf (declare-function leaf "leaf") (declare-function leaf-normalize-plist "leaf") (declare-function leaf-merge-dupkey-values-plist "leaf"))) ;; cons-cell will be accepted ((leaf leaf :defun (lbrowser-open . leaf-browser)) (prog1 'leaf (declare-function lbrowser-open "leaf-browser"))) ;; distribution feature is supported ((leaf leaf :defun ((lbrowser-open lbrowser-close) . leaf-browser)) (prog1 'leaf (declare-function lbrowser-open "leaf-browser") (declare-function lbrowser-close "leaf-browser"))))) (cort-deftest-with-macroexpand leaf/defvar '( ;; symbol will be accepted ((leaf leaf :defvar leaf-var) (prog1 'leaf (defvar leaf-var))) ;; multi symbols will be accepted ((leaf leaf :defvar leaf-var1 leaf-var2 leaf-var3) (prog1 'leaf (defvar leaf-var1) (defvar leaf-var2) (defvar leaf-var3))) ;; multi symbols in list will be accepted ((leaf leaf :defvar (leaf-var1 leaf-var2 leaf-var3)) (prog1 'leaf (defvar leaf-var1) (defvar leaf-var2) (defvar leaf-var3))) ;; nested list will be accepted ;; duplicated values will be ignored ((leaf leaf :defvar (leaf-var1 (leaf-var1 leaf-var2 leaf-var3))) (prog1 'leaf (defvar leaf-var1) (defvar leaf-var2) (defvar leaf-var3))))) (cort-deftest-with-macroexpand leaf/preface '( ;; sexp will be expanded in order of :preface, :when, :require, :init, :config. ((leaf leaf :require t :preface (preface-init) :when (some-condition) :init (package-preconfig) :config (package-init)) (prog1 'leaf (preface-init) (when (some-condition) (package-preconfig) (require 'leaf) (package-init)))) ;; multi sexp will be accepted ((leaf leaf :preface (leaf-pre-init) (leaf-pre-init-after) :when (some-condition) :require t :init (package-preconfig) :config (package-init)) (prog1 'leaf (leaf-pre-init) (leaf-pre-init-after) (when (some-condition) (package-preconfig) (require 'leaf) (package-init)))) ;; you can use `progn' if you prefer it ((leaf leaf :preface (progn (leaf-pre-init) (leaf-pre-init-after)) :when (some-condition) :require t :init (package-preconfig) :config (package-init)) (prog1 'leaf (progn (leaf-pre-init) (leaf-pre-init-after)) (when (some-condition) (package-preconfig) (require 'leaf) (package-init)))))) (cort-deftest-with-macroexpand leaf/if '( ;; single xexp will accepted ((leaf leaf :if leafp :require t :config (leaf-init)) (prog1 'leaf (if leafp (progn (require 'leaf) (leaf-init))))) ;; multi sexp will accepted and eval them in `and' ((leaf leaf :if leafp leaf-avairablep (window-system) :require t :config (leaf-init)) (prog1 'leaf (if (and leafp leaf-avairablep (window-system)) (progn (require 'leaf) (leaf-init))))) ;; you can use other condition keywords same time ((leaf leaf :if leafp leaf-avairablep (window-system) :when leaf-browserp :require t :config (leaf-init)) (prog1 'leaf (when leaf-browserp (if (and leafp leaf-avairablep (window-system)) (progn (require 'leaf) (leaf-init)))))) ;; you want eval sexp before any conditions, you can use :preface ((leaf leaf :if leafp leaf-avairablep (window-system) :when leaf-browserp :load-path "~/.emacs.d/elpa-archive/leaf.el/" :preface (leaf-load) :require t :config (leaf-init)) (prog1 'leaf (add-to-list 'load-path "~/.emacs.d/elpa-archive/leaf.el/") (leaf-load) (when leaf-browserp (if (and leafp leaf-avairablep (window-system)) (progn (require 'leaf) (leaf-init)))))))) (cort-deftest-with-macroexpand leaf/when '( ;; same as :if ((leaf leaf :when leafp :require t :config (leaf-init)) (prog1 'leaf (when leafp (require 'leaf) (leaf-init)))) ((leaf leaf :when leafp leaf-avairablep (window-system) :require t :config (leaf-init)) (prog1 'leaf (when (and leafp leaf-avairablep (window-system)) (require 'leaf) (leaf-init)))))) (cort-deftest-with-macroexpand leaf/unless '( ;; same as :if ((leaf leaf :unless leafp :require t :config (leaf-init)) (prog1 'leaf (unless leafp (require 'leaf) (leaf-init)))) ((leaf leaf :unless leafp leaf-avairablep (window-system) :require t :config (leaf-init)) (prog1 'leaf (unless (and leafp leaf-avairablep (window-system)) (require 'leaf) (leaf-init)))))) (cort-deftest-with-macroexpand leaf/emacs< '( ;; string will be accepted ((leaf leaf-keywords :emacs> "24.4" :config (leaf-keywords-init)) (prog1 'leaf-keywords (when (version< "24.4" emacs-version) (leaf-keywords-init)))) ;; number will be accepted ((leaf leaf-keywords :emacs> 24.4 :config (leaf-keywords-init)) (prog1 'leaf-keywords (when (version< "24.4" emacs-version) (leaf-keywords-init)))) ;; quoted number will be accepted ((leaf leaf-keywords :emacs> '24.4 :config (leaf-keywords-init)) (prog1 'leaf-keywords (when (version< "24.4" emacs-version) (leaf-keywords-init)))) ;; quoted string will be accepted ((leaf leaf-keywords :emacs> '"24.4" :config (leaf-keywords-init)) (prog1 'leaf-keywords (when (version< "24.4" emacs-version) (leaf-keywords-init)))) ;; one argument list will be accepted ((leaf leaf-keywords :emacs> ("24.4") :config (leaf-keywords-init)) (prog1 'leaf-keywords (when (version< "24.4" emacs-version) (leaf-keywords-init)))) ;; one argument list will be accepted ((leaf leaf-keywords :emacs> ('"24.4") :config (leaf-keywords-init)) (prog1 'leaf-keywords (when (version< "24.4" emacs-version) (leaf-keywords-init)))))) (cort-deftest-with-macroexpand leaf/after '( ;; 't will be converted leaf--name ((leaf leaf-browser :after leaf :require t :config (leaf-browser-init)) (prog1 'leaf-browser (eval-after-load 'leaf '(progn (require 'leaf-browser) (leaf-browser-init))))) ;; multi symbols will be accepted ((leaf leaf-browser :after leaf org orglyth :require t :config (leaf-browser-init)) (prog1 'leaf-browser (eval-after-load 'orglyth '(eval-after-load 'org '(eval-after-load 'leaf '(progn (require 'leaf-browser) (leaf-browser-init))))))) ;; multi symbols in list will be accepted ((leaf leaf-browser :after leaf (org orglyth) :require t :config (leaf-browser-init)) (prog1 'leaf-browser (eval-after-load 'orglyth '(eval-after-load 'org '(eval-after-load 'leaf '(progn (require 'leaf-browser) (leaf-browser-init))))))) ;; duplicated symbol will be ignored ((leaf leaf-browser :after leaf (org orglyth) org org :require t :config (leaf-browser-init)) (prog1 'leaf-browser (eval-after-load 'orglyth '(eval-after-load 'org '(eval-after-load 'leaf '(progn (require 'leaf-browser) (leaf-browser-init))))))) ;; if specified t, assume leaf--name specified ((leaf leaf-browser :after t :require t :config (leaf-browser-init)) (prog1 'leaf-browser (eval-after-load 'leaf-browser '(progn (require 'leaf-browser) (leaf-browser-init))))))) (cort-deftest-with-macroexpand leaf/custom '( ;; multi cons-cell will be accepted ((leaf foo-package :custom (foo-package-to-enable . t) (foo-package-to-disable . nil) (foo-package-to-symbol . 'symbol) (foo-package-to-function . #'ignore) (foo-package-to-lambda . (lambda (elm) (message elm)))) (prog1 'foo-package (customize-set-variable 'foo-package-to-enable t "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-disable nil "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-symbol 'symbol "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-function #'ignore "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-lambda (lambda (elm) (message elm)) "Customized with leaf in `foo-package' block"))) ;; multi cons-cell in list will be accepted ((leaf foo-package :custom ((foo-package-to-enable . t) (foo-package-to-disable . nil) (foo-package-to-symbol . 'symbol) (foo-package-to-function . #'ignore) (foo-package-to-lambda . (lambda (elm) (message elm))))) (prog1 'foo-package (customize-set-variable 'foo-package-to-enable t "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-disable nil "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-symbol 'symbol "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-function #'ignore "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-lambda (lambda (elm) (message elm)) "Customized with leaf in `foo-package' block"))) ;; distribution feature is supported ((leaf foo-package :custom (((to-enable1 to-enable2 to-enable3) . t) ((to-disable1 to-disable2 to-disable3) . nil))) (prog1 'foo-package (customize-set-variable 'to-enable1 t "Customized with leaf in `foo-package' block") (customize-set-variable 'to-enable2 t "Customized with leaf in `foo-package' block") (customize-set-variable 'to-enable3 t "Customized with leaf in `foo-package' block") (customize-set-variable 'to-disable1 nil "Customized with leaf in `foo-package' block") (customize-set-variable 'to-disable2 nil "Customized with leaf in `foo-package' block") (customize-set-variable 'to-disable3 nil "Customized with leaf in `foo-package' block"))) ;; and mix specification is accepted ((leaf foo-package :custom (foo-package-to-function . #'ignore) ((to-symbol1 to-symbol2) . 'baz) (((to-enable1 to-enable2 to-enable3) . t) ((to-disable1 to-disable2 to-disable3) . nil))) (prog1 'foo-package (customize-set-variable 'foo-package-to-function #'ignore "Customized with leaf in `foo-package' block") (customize-set-variable 'to-symbol1 'baz "Customized with leaf in `foo-package' block") (customize-set-variable 'to-symbol2 'baz "Customized with leaf in `foo-package' block") (customize-set-variable 'to-enable1 t "Customized with leaf in `foo-package' block") (customize-set-variable 'to-enable2 t "Customized with leaf in `foo-package' block") (customize-set-variable 'to-enable3 t "Customized with leaf in `foo-package' block") (customize-set-variable 'to-disable1 nil "Customized with leaf in `foo-package' block") (customize-set-variable 'to-disable2 nil "Customized with leaf in `foo-package' block") (customize-set-variable 'to-disable3 nil "Customized with leaf in `foo-package' block"))))) (cort-deftest-with-macroexpand leaf/custom* '( ;; multi cons-cell will be accepted ;; ((leaf foo-package ;; :custom* ;; (foo-package-to-enable t) ;; (foo-package-to-disable nil) ;; (foo-package-to-symbol 'symbol) ;; (foo-package-to-function #'ignore) ;; (foo-package-to-lambda (lambda (elm) (message elm)))) ;; (prog1 'foo-package ;; (customize-set-variable 'foo-package-to-enable t "Customized with leaf in foo-package block") ;; (customize-set-variable 'foo-package-to-disable nil "Customized with leaf in foo-package block") ;; (customize-set-variable 'foo-package-to-symbol 'symbol "Customized with leaf in foo-package block") ;; (customize-set-variable 'foo-package-to-function #'ignore "Customized with leaf in foo-package block") ;; (customize-set-variable 'foo-package-to-lambda (lambda (elm) (message elm)) "Customized with leaf in foo-package block"))) ;; multi cons-cell in list will be accepted ((leaf foo-package :custom* ((foo-package-to-enable t) (foo-package-to-disable nil) (foo-package-to-symbol 'symbol) (foo-package-to-function #'ignore) (foo-package-to-lambda (lambda (elm) (message elm))))) (prog1 'foo-package (customize-set-variable 'foo-package-to-enable t "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-disable nil "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-symbol 'symbol "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-function #'ignore "Customized with leaf in `foo-package' block") (customize-set-variable 'foo-package-to-lambda (lambda (elm) (message elm)) "Customized with leaf in `foo-package' block"))) ;; distribution feature is supported ;; ((leaf foo-package ;; :custom (((to-enable1 to-enable2 to-enable3) . t) ;; ((to-disable1 to-disable2 to-disable3) . nil))) ;; (prog1 'foo-package ;; (customize-set-variable 'to-enable1 t "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-enable2 t "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-enable3 t "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-disable1 nil "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-disable2 nil "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-disable3 nil "Customized with leaf in foo-package block"))) ;; and mix specification is accepted ;; ((leaf foo-package ;; :custom ;; (foo-package-to-function . #'ignore) ;; ((to-symbol1 to-symbol2) . 'baz) ;; (((to-enable1 to-enable2 to-enable3) . t) ;; ((to-disable1 to-disable2 to-disable3) . nil))) ;; (prog1 'foo-package ;; (customize-set-variable 'foo-package-to-function #'ignore "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-symbol1 'baz "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-symbol2 'baz "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-enable1 t "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-enable2 t "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-enable3 t "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-disable1 nil "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-disable2 nil "Customized with leaf in foo-package block") ;; (customize-set-variable 'to-disable3 nil "Customized with leaf in foo-package block"))) )) (cort-deftest-with-macroexpand leaf/custom-face '( ;; cons-cell will be accepted ((leaf eruby-mode :custom-face (eruby-standard-face . '((t (:slant italic))))) (prog1 'eruby-mode (custom-set-faces '(eruby-standard-face ((t (:slant italic))) nil "Customized with leaf in `eruby-mode' block")))) ;; distribution feature is supported ((leaf eruby-mode :custom-face ((default eruby-standard-face) . '((t (:slant italic))))) (prog1 'eruby-mode (custom-set-faces '(default ((t (:slant italic))) nil "Customized with leaf in `eruby-mode' block") '(eruby-standard-face ((t (:slant italic))) nil "Customized with leaf in `eruby-mode' block")))))) (cort-deftest-with-macroexpand leaf/pl-custom '( ;; Emulate customizing `sql-connection-alist' with value taken from `some-plstore'. ((leaf sql :pl-custom (sql-connection-alist . some-plstore)) (prog1 'sql (customize-set-variable 'sql-connection-alist (leaf-handler-auth sql sql-connection-alist some-plstore) "Customized with leaf in `sql' block using `some-plstore' plstore"))) ;; Emulate customizing `erc-password' and `erc-nickserv-passwords' ;; with values taken from `some-plstore', and `erc-user-full-name' ;; and `erc-nick' with values taken from `another-plstore'. ((leaf erc :pl-custom ((erc-password erc-nickserv-passwords) . some-plstore) ((erc-user-full-name erc-nick) . another-plstore)) (prog1 'erc (customize-set-variable 'erc-password (leaf-handler-auth erc erc-password some-plstore) "Customized with leaf in `erc' block using `some-plstore' plstore") (customize-set-variable 'erc-nickserv-passwords (leaf-handler-auth erc erc-nickserv-passwords some-plstore) "Customized with leaf in `erc' block using `some-plstore' plstore") (customize-set-variable 'erc-user-full-name (leaf-handler-auth erc erc-user-full-name another-plstore) "Customized with leaf in `erc' block using `another-plstore' plstore") (customize-set-variable 'erc-nick (leaf-handler-auth erc erc-nick another-plstore) "Customized with leaf in `erc' block using `another-plstore' plstore"))) ;; you can use symbol to configure with `leaf-default-plstore'. ((leaf erc :pl-custom erc-nick erc-password) (prog1 'erc (customize-set-variable 'erc-nick (leaf-handler-auth erc erc-nick leaf-default-plstore) "Customized with leaf in `erc' block using `leaf-default-plstore' plstore") (customize-set-variable 'erc-password (leaf-handler-auth erc erc-password leaf-default-plstore) "Customized with leaf in `erc' block using `leaf-default-plstore' plstore"))))) (cort-deftest-with-macroexpand leaf/bind '( ;; cons-cell will be accepted ((leaf macrostep :ensure t :bind ("C-c e" . macrostep-expand)) (prog1 'macrostep (unless (fboundp 'macrostep-expand) (autoload #'macrostep-expand "macrostep" nil t)) (leaf-handler-package macrostep macrostep nil) (leaf-keys (("C-c e" . macrostep-expand))))) ;; multi cons-cell will be accepted ((leaf color-moccur :bind ("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))))) ;; multi cons-cell in list will be accepted ((leaf color-moccur :bind (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))))) ;; bind to nil to unbind shortcut ((leaf color-moccur :bind (("M-s" . nil) ("M-s o" . isearch-moccur) ("M-s i" . isearch-moccur-all))) (prog1 'color-moccur (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s") ("M-s o" . isearch-moccur) ("M-s i" . isearch-moccur-all))))) ;; nested cons-cell list will be accepted ((leaf color-moccur :bind (("M-s O" . moccur) (("M-o" . isearch-moccur) (("M-O" . isearch-moccur-all)) ("M-s" . isearch-moccur-some)))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-some) (autoload #'isearch-moccur-some "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all) ("M-s" . isearch-moccur-some))))) ;; use keyword at first element to bind specific map ((leaf color-moccur :bind (("M-s O" . moccur) (:isearch-mode-map ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) (isearch-mode-map :package color-moccur ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))))) ;; specific map at top-level will be accepted ((leaf color-moccur :bind ("M-s O" . moccur) (:isearch-mode-map ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) (isearch-mode-map :package color-moccur ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))))) ;; use :package to deffering :iserch-mode-map declared ((leaf color-moccur :bind (("M-s O" . moccur) (:isearch-mode-map :package isearch ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) (isearch-mode-map :package isearch ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))))) ;; you can use symbol instead of keyword to specify map ((leaf color-moccur :bind (("M-s O" . moccur) (isearch-mode-map :package isearch ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys (("M-s O" . moccur) (isearch-mode-map :package isearch ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)))))) ;; you can use vectors to remap etc ((leaf swiper :ensure t :bind (([remap isearch-forward] . swiper))) (prog1 'swiper (unless (fboundp 'swiper) (autoload #'swiper "swiper" nil t)) (leaf-handler-package swiper swiper nil) (leaf-keys (([remap isearch-forward] . swiper))))) ((leaf files :bind (([(control ?x) (control ?f)] . find-file))) (prog1 'files (unless (fboundp 'find-file) (autoload #'find-file "files" nil t)) (leaf-keys (([(control ?x) (control ?f)] . find-file))))))) (cort-deftest-with-macroexpand leaf/bind* '( ;; bind* to bind override any key-bind map ((leaf color-moccur :bind* ("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys* (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))))) ((leaf color-moccur :bind* (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys* (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))))) ((leaf color-moccur :bind* (("M-s O" . moccur) (("M-o" . isearch-moccur) (("M-O" . isearch-moccur-all))))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (leaf-keys* (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all))))) ((leaf color-moccur :bind* (("M-s O" . moccur) (("M-o" . isearch-moccur) (("M-O" . isearch-moccur-all)) ("M-s" . isearch-moccur-some)))) (prog1 'color-moccur (unless (fboundp 'moccur) (autoload #'moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur) (autoload #'isearch-moccur "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-all) (autoload #'isearch-moccur-all "color-moccur" nil t)) (unless (fboundp 'isearch-moccur-some) (autoload #'isearch-moccur-some "color-moccur" nil t)) (leaf-keys* (("M-s O" . moccur) ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all) ("M-s" . isearch-moccur-some))))))) (cort-deftest-with-macroexpand leaf/bind-keymap '( ;; cons-cell will be accepted ((leaf projectile :ensure t :bind-keymap ("C-c p" . projectile-command-map)) (prog1 'projectile (leaf-handler-package projectile projectile nil) (leaf-keys-bind-keymap (("C-c p" . projectile-command-map)) nil 'projectile))) ;; multi cons-cell will be accepted ((leaf projectile :bind-keymap ("C-c p" . projectile-command-map) ("C-%" . ctl-x-5-map)) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) ("C-%" . ctl-x-5-map)) nil 'projectile))) ;; multi cons-cell in list will be accepted ((leaf projectile :bind-keymap (("C-c p" . projectile-command-map) ("C-%" . ctl-x-5-map))) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) ("C-%" . ctl-x-5-map)) nil 'projectile))) ;; nested cons-cell list will be accepted ((leaf projectile :bind-keymap (("C-c p" . projectile-command-map) (("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map)))) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map)) nil 'projectile))) ;; use keyword at first element to bind specific map ((leaf projectile :bind-keymap (("C-c p" . projectile-command-map) (:projectile-mode-map ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map)))) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) (projectile-mode-map :package projectile ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map))) nil 'projectile))) ;; specific map at top-level will be accepted ((leaf projectile :bind-keymap ("C-c p" . projectile-command-map) (:projectile-mode-map ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map))) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) (projectile-mode-map :package projectile ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map))) nil 'projectile))) ;; use :package to deffering :iserch-mode-map declared ((leaf projectile :bind-keymap (("C-c p" . projectile-command-map) (:isearch-mode-map :package isearch ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map)))) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) (isearch-mode-map :package isearch ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map))) nil 'projectile))) ;; you can use symbol instead of keyword to specify map ((leaf projectile :bind-keymap (("C-c p" . projectile-command-map) (isearch-mode-map :package isearch ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map)))) (prog1 'projectile (leaf-keys-bind-keymap (("C-c p" . projectile-command-map) (isearch-mode-map :package isearch ("C-^" . ctl-x-4-map) ("C-%" . ctl-x-5-map))) nil 'projectile))) ;; you can use vectors to remap etc ((leaf projectile :ensure t :bind-keymap (([remap isearch-forward] . projectile-command-map))) (prog1 'projectile (leaf-handler-package projectile projectile nil) (leaf-keys-bind-keymap (([remap isearch-forward] . projectile-command-map)) nil 'projectile))))) (cort-deftest-with-macroexpand leaf/global-minor-mode '( ;; symbol will be accepted ((leaf autorevert :global-minor-mode global-auto-revert-mode) (prog1 'autorevert (unless (fboundp 'global-auto-revert-mode) (autoload #'global-auto-revert-mode "autorevert" nil t)) (global-auto-revert-mode 1))) ;; multi strings will be accepted ((leaf autorevert :global-minor-mode global-auto-revert-mode show-paren-mode) (prog1 'autorevert (unless (fboundp 'global-auto-revert-mode) (autoload #'global-auto-revert-mode "autorevert" nil t)) (unless (fboundp 'show-paren-mode) (autoload #'show-paren-mode "autorevert" nil t)) (global-auto-revert-mode 1) (show-paren-mode 1))) ;; multi strings in list will be accepted ((leaf autorevert :global-minor-mode (global-auto-revert-mode show-paren-mode)) (prog1 'autorevert (unless (fboundp 'global-auto-revert-mode) (autoload #'global-auto-revert-mode "autorevert" nil t)) (unless (fboundp 'show-paren-mode) (autoload #'show-paren-mode "autorevert" nil t)) (global-auto-revert-mode 1) (show-paren-mode 1))) ;; cons-cell used to controll autoload package ((leaf autorevert :global-minor-mode ((global-auto-revert-mode . autorevert) (show-paren-mode . paren))) (prog1 'autorevert (unless (fboundp 'global-auto-revert-mode) (autoload #'global-auto-revert-mode "autorevert" nil t)) (unless (fboundp 'show-paren-mode) (autoload #'show-paren-mode "paren" nil t)) (global-auto-revert-mode 1) (show-paren-mode 1))) ;; distribution feature is supported ((leaf simple :global-minor-mode ((line-number-mode column-number-mode) . simple)) (prog1 'simple (unless (fboundp 'line-number-mode) (autoload #'line-number-mode "simple" nil t)) (unless (fboundp 'column-number-mode) (autoload #'column-number-mode "simple" nil t)) (line-number-mode 1) (column-number-mode 1))) ;; mix specification will be accepted ((leaf autoinsert :global-minor-mode (auto-insert-mode ((line-number-mode column-number-mode) . simple))) (prog1 'autoinsert (unless (fboundp 'auto-insert-mode) (autoload #'auto-insert-mode "autoinsert" nil t)) (unless (fboundp 'line-number-mode) (autoload #'line-number-mode "simple" nil t)) (unless (fboundp 'column-number-mode) (autoload #'column-number-mode "simple" nil t)) (auto-insert-mode 1) (line-number-mode 1) (column-number-mode 1))) ;; t will convert leaf--name, and suffix 'mode' ((leaf autorevert :global-minor-mode t) (prog1 'autorevert (unless (fboundp 'autorevert-mode) (autoload #'autorevert-mode "autorevert" nil t)) (autorevert-mode 1))) ;; symbol not suffix 'mode', add 'mode' suffix ((leaf autorevert :global-minor-mode autorevert) (prog1 'autorevert (unless (fboundp 'autorevert-mode) (autoload #'autorevert-mode "autorevert" nil t)) (autorevert-mode 1))))) (cort-deftest-with-macroexpand leaf/mode '( ;; string will be accepted and use leaf--name ((leaf web-mode :mode "\\.js\\'") (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode)))) ;; multi strings will be accepted ((leaf web-mode :mode "\\.js\\'" "\\.p?html?\\'") (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.p?html?\\'" . web-mode)))) ;; multi strings in list will be accepted ((leaf web-mode :mode ("\\.js\\'" "\\.p?html?\\'")) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.p?html?\\'" . web-mode)))) ;; cons-cell will be accepted ((leaf web-mode :mode ("\\.js\\'" . web-strict-mode)) (prog1 'web-mode (unless (fboundp 'web-strict-mode) (autoload #'web-strict-mode "web-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.js\\'" . web-strict-mode)))) ;; distribution feature is supported ((leaf web-mode :mode (("\\.js\\'" "\\.p?html?\\'") . web-strict-mode)) (prog1 'web-mode (unless (fboundp 'web-strict-mode) (autoload #'web-strict-mode "web-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.js\\'" . web-strict-mode)) (add-to-list 'auto-mode-alist '("\\.p?html?\\'" . web-strict-mode)))) ;; mix specification will be accepted ((leaf web-mode :mode ("\\.html\\'" (("\\.js\\'" "\\.p?html?\\'") . web-strict-mode))) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (unless (fboundp 'web-strict-mode) (autoload #'web-strict-mode "web-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.js\\'" . web-strict-mode)) (add-to-list 'auto-mode-alist '("\\.p?html?\\'" . web-strict-mode)))) ;; if package symbol suffix doesn't suffix '-mode', add '-mode' ((leaf gnuplot :mode "\\.gp$") (prog1 'gnuplot (unless (fboundp 'gnuplot-mode) (autoload #'gnuplot-mode "gnuplot" nil t)) (add-to-list 'auto-mode-alist '("\\.gp$" . gnuplot-mode)))))) (cort-deftest-with-macroexpand leaf/interpreter '( ;; same as :mode ((leaf ruby-mode :mode "\\.rb\\'" "\\.rb2\\'" ("\\.rbg\\'" . rb-mode) :interpreter "ruby") (prog1 'ruby-mode (unless (fboundp 'ruby-mode) (autoload #'ruby-mode "ruby-mode" nil t)) (unless (fboundp 'rb-mode) (autoload #'rb-mode "ruby-mode" nil t)) (add-to-list 'auto-mode-alist '("\\.rb\\'" . ruby-mode)) (add-to-list 'auto-mode-alist '("\\.rb2\\'" . ruby-mode)) (add-to-list 'auto-mode-alist '("\\.rbg\\'" . rb-mode)) (add-to-list 'interpreter-mode-alist '("ruby" . ruby-mode)))) ((leaf web-mode :interpreter "js" "p?html?") (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'interpreter-mode-alist '("js" . web-mode)) (add-to-list 'interpreter-mode-alist '("p?html?" . web-mode)))) ((leaf web-mode :interpreter ("js" "p?html?")) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'interpreter-mode-alist '("js" . web-mode)) (add-to-list 'interpreter-mode-alist '("p?html?" . web-mode)))) ((leaf web-mode :interpreter (("js" "p?html?") . web-mode)) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'interpreter-mode-alist '("js" . web-mode)) (add-to-list 'interpreter-mode-alist '("p?html?" . web-mode)))))) (cort-deftest-with-macroexpand leaf/magic '( ;; same as :mode ((leaf pdf-tools :magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install)) (prog1 'pdf-tools (unless (fboundp 'pdf-view-mode) (autoload #'pdf-view-mode "pdf-tools" nil t)) (add-to-list 'magic-mode-alist '("%PDF" . pdf-view-mode)) (eval-after-load 'pdf-tools '(progn (pdf-tools-install))))) ((leaf web-mode :magic "js" "p?html?") (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'magic-mode-alist '("js" . web-mode)) (add-to-list 'magic-mode-alist '("p?html?" . web-mode)))) ((leaf web-mode :magic ("js" "p?html?")) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'magic-mode-alist '("js" . web-mode)) (add-to-list 'magic-mode-alist '("p?html?" . web-mode)))) ((leaf web-mode :magic (("js" "p?html?") . web-mode)) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'magic-mode-alist '("js" . web-mode)) (add-to-list 'magic-mode-alist '("p?html?" . web-mode)))))) (cort-deftest-with-macroexpand leaf/magic-fallback '( ;; same as :mode ((leaf pdf-tools :magic-fallback ("%PDF" . pdf-view-mode) :config (pdf-tools-install)) (prog1 'pdf-tools (unless (fboundp 'pdf-view-mode) (autoload #'pdf-view-mode "pdf-tools" nil t)) (add-to-list 'magic-fallback-mode-alist '("%PDF" . pdf-view-mode)) (eval-after-load 'pdf-tools '(progn (pdf-tools-install))))) ((leaf web-mode :magic-fallback "js" "p?html?") (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'magic-fallback-mode-alist '("js" . web-mode)) (add-to-list 'magic-fallback-mode-alist '("p?html?" . web-mode)))) ((leaf web-mode :magic-fallback ("js" "p?html?")) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'magic-fallback-mode-alist '("js" . web-mode)) (add-to-list 'magic-fallback-mode-alist '("p?html?" . web-mode)))) ((leaf web-mode :magic-fallback (("js" "p?html?") . web-mode)) (prog1 'web-mode (unless (fboundp 'web-mode) (autoload #'web-mode "web-mode" nil t)) (add-to-list 'magic-fallback-mode-alist '("js" . web-mode)) (add-to-list 'magic-fallback-mode-alist '("p?html?" . web-mode)))))) (cort-deftest-with-macroexpand leaf/hook '( ;; symbol will be accepted ((leaf ace-jump-mode :hook cc-mode-hook :config (ace-jump-mode)) (prog1 'ace-jump-mode (unless (fboundp 'ace-jump-mode) (autoload #'ace-jump-mode "ace-jump-mode" nil t)) (add-hook 'cc-mode-hook #'ace-jump-mode) (eval-after-load 'ace-jump-mode '(progn (ace-jump-mode))))) ;; multi symbols will be accepted ((leaf ace-jump-mode :hook cc-mode-hook prog-mode-hook) (prog1 'ace-jump-mode (unless (fboundp 'ace-jump-mode) (autoload #'ace-jump-mode "ace-jump-mode" nil t)) (add-hook 'cc-mode-hook #'ace-jump-mode) (add-hook 'prog-mode-hook #'ace-jump-mode))) ;; cons-cell will be accepted ((leaf ace-jump-mode :hook (prog-mode-hook . my-ace-jump-mode)) (prog1 'ace-jump-mode (unless (fboundp 'my-ace-jump-mode) (autoload #'my-ace-jump-mode "ace-jump-mode" nil t)) (add-hook 'prog-mode-hook #'my-ace-jump-mode))) ;; distribution feature is supported ((leaf ace-jump-mode :hook ((cc-mode-hook prog-mode-hook) . my-ace-jump-mode)) (prog1 'ace-jump-mode (unless (fboundp 'my-ace-jump-mode) (autoload #'my-ace-jump-mode "ace-jump-mode" nil t)) (add-hook 'cc-mode-hook #'my-ace-jump-mode) (add-hook 'prog-mode-hook #'my-ace-jump-mode))) ;; guess leaf--name is mode ((leaf dired-filter :hook dired-mode-hook) (prog1 'dired-filter (unless (fboundp 'dired-filter-mode) (autoload #'dired-filter-mode "dired-filter" nil t)) (add-hook 'dired-mode-hook #'dired-filter-mode))) ;; lambda sexp is supported ((leaf hook :hook (foo-hook . (lambda () (foo)))) (prog1 'hook (add-hook 'foo-hook #'(lambda nil (foo))))) ;; lambda sexp with many sexps ((leaf hook :hook (foo-hook . (lambda () (foo) (bar) (baz)))) (prog1 'hook (add-hook 'foo-hook #'(lambda nil (foo) (bar) (baz))))))) (cort-deftest-with-macroexpand leaf/advice '( ;; define advice function(s) in :preface ;; list like ({{place}} {{adviced-function}} {{advice-function}}) will be accepted ((leaf leaf :preface (defun matu (x) (princ (format ">>%s<<" x)) nil) (defun matu-around0 (f &rest args) (prog2 (princ "around0 ==>") (apply f args) (princ "around0 <=="))) (defun matu-before0 (&rest args) (princ "before0:")) :advice (:around matu matu-around0) (:before matu matu-before0)) (prog1 'leaf (unless (fboundp 'matu-around0) (autoload #'matu-around0 "leaf" nil t)) (unless (fboundp 'matu-before0) (autoload #'matu-before0 "leaf" nil t)) (defun matu (x) (princ (format ">>%s<<" x)) nil) (defun matu-around0 (f &rest args) (prog2 (princ "around0 ==>") (apply f args) (princ "around0 <=="))) (defun matu-before0 (&rest args) (princ "before0:")) (advice-add 'matu :around #'matu-around0) (advice-add 'matu :before #'matu-before0))) ;; multi lists like ({{place}} {{adviced-function}} {{advice-function}}) in list is accepted ((leaf leaf :preface (defun matu (x) (princ (format ">>%s<<" x)) nil) (defun matu-around0 (f &rest args) (prog2 (princ "around0 ==>") (apply f args) (princ "around0 <=="))) (defun matu-before0 (&rest args) (princ "before0:")) :advice ((:around matu matu-around0) (:before matu matu-before0))) (prog1 'leaf (unless (fboundp 'matu-around0) (autoload #'matu-around0 "leaf" nil t)) (unless (fboundp 'matu-before0) (autoload #'matu-before0 "leaf" nil t)) (defun matu (x) (princ (format ">>%s<<" x)) nil) (defun matu-around0 (f &rest args) (prog2 (princ "around0 ==>") (apply f args) (princ "around0 <=="))) (defun matu-before0 (&rest args) (princ "before0:")) (advice-add 'matu :around #'matu-around0) (advice-add 'matu :before #'matu-before0))) ;; you can use `lambda' in {{function}} place ((leaf leaf :preface (defun matu (x) (princ (format ">>%s<<" x)) nil) (defun matu-around0 (f &rest args) (prog2 (princ "around0 ==>") (apply f args) (princ "around0 <=="))) (defun matu-before0 (&rest args) (princ "before0:")) :advice ((:around matu matu-around0) (:before matu matu-before0) (:around matu (lambda (f &rest args) (prog2 (princ "around1 ==>") (apply f args) (princ "around1 <==")))))) (prog1 'leaf (unless (fboundp 'matu-around0) (autoload #'matu-around0 "leaf" nil t)) (unless (fboundp 'matu-before0) (autoload #'matu-before0 "leaf" nil t)) (defun matu (x) (princ (format ">>%s<<" x)) nil) (defun matu-around0 (f &rest args) (prog2 (princ "around0 ==>") (apply f args) (princ "around0 <=="))) (defun matu-before0 (&rest args) (princ "before0:")) (advice-add 'matu :around #'matu-around0) (advice-add 'matu :before #'matu-before0) (advice-add 'matu :around #'(lambda (f &rest args) (prog2 (princ "around1 ==>") (apply f args) (princ "around1 <==")))))))) (cort-deftest-with-macroexpand leaf/advice-remove '( ;; list like ({{adviced-function}} {{advice-function}}) will be accepted ((leaf leaf :advice-remove (matu matu-around0) (matu matu-before0)) (prog1 'leaf (unless (fboundp 'matu-before0) (autoload #'matu-before0 "leaf" nil t)) (unless (fboundp 'matu-around0) (autoload #'matu-around0 "leaf" nil t)) (advice-remove 'matu #'matu-around0) (advice-remove 'matu #'matu-before0))) ;; multi lists like ({{adviced-function}} {{advice-function}}) in list will be accepted ((leaf leaf :advice-remove ((matu matu-around0) (matu matu-before0))) (prog1 'leaf (unless (fboundp 'matu-before0) (autoload #'matu-before0 "leaf" nil t)) (unless (fboundp 'matu-around0) (autoload #'matu-around0 "leaf" nil t)) (advice-remove 'matu #'matu-around0) (advice-remove 'matu #'matu-before0))))) (cort-deftest-with-macroexpand leaf/commands '( ;; specify a symbol to set to autoload function ((leaf leaf :commands leaf :config (leaf-init)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (eval-after-load 'leaf '(progn (leaf-init))))) ;; multi symbols will be accepted ((leaf leaf :commands leaf leaf-pairp leaf-plist-get) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (unless (fboundp 'leaf-pairp) (autoload #'leaf-pairp "leaf" nil t)) (unless (fboundp 'leaf-plist-get) (autoload #'leaf-plist-get "leaf" nil t)))) ;; multi symbols in list will be accepted ((leaf leaf :commands (leaf leaf-pairp leaf-plist-get)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (unless (fboundp 'leaf-pairp) (autoload #'leaf-pairp "leaf" nil t)) (unless (fboundp 'leaf-plist-get) (autoload #'leaf-plist-get "leaf" nil t)))) ;; It is accepted even if you specify symbol and list at the same time ((leaf leaf :commands leaf (leaf-pairp leaf-plist-get (leaf-insert-list-after))) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (unless (fboundp 'leaf-pairp) (autoload #'leaf-pairp "leaf" nil t)) (unless (fboundp 'leaf-plist-get) (autoload #'leaf-plist-get "leaf" nil t)) (unless (fboundp 'leaf-insert-list-after) (autoload #'leaf-insert-list-after "leaf" nil t)))))) (cort-deftest-with-macroexpand leaf/pre-setq '( ;; :pre-setq setq before `require' ((leaf alloc :pre-setq `((gc-cons-threshold . ,(* 512 1024 1024)) (garbage-collection-messages . t)) :require t) (prog1 'alloc (setq gc-cons-threshold 536870912) (setq garbage-collection-messages t) (require 'alloc))) ((leaf alloc :pre-setq ((gc-cons-threshold . 536870912) (garbage-collection-messages . t)) :require t) (prog1 'alloc (setq gc-cons-threshold 536870912) (setq garbage-collection-messages t) (require 'alloc))) ((leaf leaf :pre-setq (leaf-backend-bind . 'bind-key) (leaf-backend-bind* . 'bind-key) :require t) (prog1 'leaf (setq leaf-backend-bind 'bind-key) (setq leaf-backend-bind* 'bind-key) (require 'leaf))) ((leaf leaf :pre-setq ((leaf-backend-bind leaf-backend-bind*) . 'bind-key) :require t) (prog1 'leaf (setq leaf-backend-bind 'bind-key) (setq leaf-backend-bind* 'bind-key) (require 'leaf))) ((leaf lsp-mode :pre-setq ((lsp-print-io lsp-trace lsp-print-performance) . nil) :require t) (prog1 'lsp-mode (setq lsp-print-io nil) (setq lsp-trace nil) (setq lsp-print-performance nil) (require 'lsp-mode))) ((leaf lsp-mode :pre-setq ((lsp-use-native-json . t) ((lsp-enable-folding lsp-enable-snippet) . t) ((lsp-print-io lsp-trace lsp-print-performance) . nil)) :require t) (prog1 'lsp-mode (setq lsp-use-native-json t) (setq lsp-enable-folding t) (setq lsp-enable-snippet t) (setq lsp-print-io nil) (setq lsp-trace nil) (setq lsp-print-performance nil) (require 'lsp-mode))))) (cort-deftest-with-macroexpand leaf/init '(((leaf leaf :init (leaf-pre-init) :require t :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (require 'leaf) (leaf-init))) ((leaf leaf :init (progn (leaf-pre-init) (leaf-pre-init-after)) :require t :config (leaf-init)) (prog1 'leaf (progn (leaf-pre-init) (leaf-pre-init-after)) (require 'leaf) (leaf-init))) ((leaf leaf :init (leaf-pre-init) (leaf-pre-init-after) :require t :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (leaf-pre-init-after) (require 'leaf) (leaf-init))))) (cort-deftest-with-macroexpand leaf/require '( ;; 't will be converted leaf--name ((leaf leaf :init (leaf-pre-init) :when leaf-workable-p :require t :config (leaf-init)) (prog1 'leaf (when leaf-workable-p (leaf-pre-init) (require 'leaf) (leaf-init)))) ;; 'nil will be just ignored it ((leaf leaf :init (leaf-pre-init) :require nil :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (leaf-init))) ;; multi symbols will be accepted ((leaf leaf :init (leaf-pre-init) :require leaf leaf-polyfill :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (require 'leaf) (require 'leaf-polyfill) (leaf-init))) ;; multi keywords will be accepted ((leaf leaf :init (leaf-pre-init) :require t :require leaf-polyfill :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (require 'leaf) (require 'leaf-polyfill) (leaf-init))) ;; multi symbols in list will be accepted ((leaf leaf :init (leaf-pre-init) :require (leaf leaf-polyfill leaf-sub leaf-subsub) :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (require 'leaf) (require 'leaf-polyfill) (require 'leaf-sub) (require 'leaf-subsub) (leaf-init))))) (cort-deftest-with-macroexpand leaf/setq '( ;; cons-cell will be accepted ((leaf alloc :setq (gc-cons-threshold . 536870912) :require t) (prog1 'alloc (require 'alloc) (setq gc-cons-threshold 536870912))) ;; multi cons-cell will be accepted ((leaf alloc :setq (gc-cons-threshold . 536870912) (garbage-collection-messages . t) :require t) (prog1 'alloc (require 'alloc) (setq gc-cons-threshold 536870912) (setq garbage-collection-messages t))) ;; multi cons-cell in list will be accepted ((leaf alloc :setq ((gc-cons-threshold . 536870912) (garbage-collection-messages . t)) :require t) (prog1 'alloc (require 'alloc) (setq gc-cons-threshold 536870912) (setq garbage-collection-messages t))) ;; use backquote and comma to set result of sexp ((leaf alloc :setq `((gc-cons-threshold . ,(* 512 1024 1024)) (garbage-collection-messages . t)) :require t) (prog1 'alloc (require 'alloc) (setq gc-cons-threshold 536870912) (setq garbage-collection-messages t))) ;; distribution feature is supported ((leaf leaf :setq ((leaf-backend-bind leaf-backend-bind*) . 'bind-key) :require t) (prog1 'leaf (require 'leaf) (setq leaf-backend-bind 'bind-key) (setq leaf-backend-bind* 'bind-key))))) (cort-deftest-with-macroexpand leaf/setf '( ;; :setf require cons-cell list ONLY. ((leaf alloc :setf ((gc-cons-threshold . 536870912) (garbage-collection-messages . t)) :require t) (prog1 'alloc (require 'alloc) (setf gc-cons-threshold 536870912) (setf garbage-collection-messages t))) ;; left value could generalized variable (alist-get, plist-get...) ;; note that it is specified as the car of the cons list. ((leaf emacs :setf (((alist-get "gnu" package-archives) . "http://elpa.gnu.org/packages/") ((alist-get 'vertical-scroll-bars default-frame-alist) . nil))) (prog1 'emacs (setf (alist-get "gnu" package-archives) "http://elpa.gnu.org/packages/") (setf (alist-get 'vertical-scroll-bars default-frame-alist) nil))))) (cort-deftest-with-macroexpand leaf/push '( ;; :setf require cons-cell list ONLY. ((leaf emacs :push ((package-archives . '("melpa" . "https://melpa.org/packages/")) (auto-mode-alist . '("\\.jpe?g\\'" . image-mode)))) (prog1 'emacs (push '("melpa" . "https://melpa.org/packages/") package-archives) (push '("\\.jpe?g\\'" . image-mode) auto-mode-alist))))) (cort-deftest-with-macroexpand leaf/pl-setq '( ;; Emulate setting `sql-connection-alist' with value taken from `some-plstore'. ((leaf sql :pl-setq (sql-connection-alist . some-plstore)) (prog1 'sql (setq sql-connection-alist (leaf-handler-auth sql sql-connection-alist some-plstore)))) ;; Emulate setting `erc-password' and `erc-nickserv-passwords' ;; with values taken from `some-plstore', and `erc-user-full-name' ;; and `erc-nick' with values taken from `another-plstore'. ((leaf erc :pl-setq ((erc-password erc-nickserv-passwords) . some-plstore) ((erc-user-full-name erc-nick) . another-plstore)) (prog1 'erc (setq erc-password (leaf-handler-auth erc erc-password some-plstore)) (setq erc-nickserv-passwords (leaf-handler-auth erc erc-nickserv-passwords some-plstore)) (setq erc-user-full-name (leaf-handler-auth erc erc-user-full-name another-plstore)) (setq erc-nick (leaf-handler-auth erc erc-nick another-plstore)))))) (cort-deftest-with-macroexpand leaf/setq-default '( ;; :setq-default to `setq-default' ((leaf alloc :setq-default `((gc-cons-threshold . ,(* 512 1024 1024)) (garbage-collection-messages . t)) :require t) (prog1 'alloc (require 'alloc) (setq-default gc-cons-threshold 536870912) (setq-default garbage-collection-messages t))) ((leaf alloc :setq-default ((gc-cons-threshold . 536870912) (garbage-collection-messages . t)) :require t) (prog1 'alloc (require 'alloc) (setq-default gc-cons-threshold 536870912) (setq-default garbage-collection-messages t))) ((leaf leaf :setq-default (leaf-backend-bind . 'bind-key) (leaf-backend-bind* . 'bind-key) :require t) (prog1 'leaf (require 'leaf) (setq-default leaf-backend-bind 'bind-key) (setq-default leaf-backend-bind* 'bind-key))) ((leaf leaf :setq-default ((leaf-backend-bind leaf-backend-bind*) . 'bind-key) :require t) (prog1 'leaf (require 'leaf) (setq-default leaf-backend-bind 'bind-key) (setq-default leaf-backend-bind* 'bind-key))))) (cort-deftest-with-macroexpand leaf/pl-setq-default ;; Emulate setting `indent-tabs-mode' with a default value taken ;; from `some-plstore'. '(((leaf indent :pl-setq-default (indent-tabs-mode . some-plstore)) (prog1 'indent (setq-default indent-tabs-mode (leaf-handler-auth indent indent-tabs-mode some-plstore)))))) (cort-deftest-with-macroexpand leaf/pl-pre-setq ;; Emulate setting `indent-tabs-mode' with a default value taken ;; from `some-plstore'. '(((leaf indent :pl-pre-setq (indent-tabs-mode . some-plstore) :require t) (prog1 'indent (setq indent-tabs-mode (leaf-handler-auth indent indent-tabs-mode some-plstore)) (require 'indent))))) (cort-deftest-with-macroexpand leaf/config '(((leaf leaf :init (leaf-pre-init) :require t :config (leaf-init)) (prog1 'leaf (leaf-pre-init) (require 'leaf) (leaf-init))) ((leaf leaf :init (leaf-init) :require t :config (progn (leaf-pre-init) (leaf-pre-init-after))) (prog1 'leaf (leaf-init) (require 'leaf) (progn (leaf-pre-init) (leaf-pre-init-after)))) ((leaf leaf :init (leaf-init) :require t :config (leaf-pre-init) (leaf-pre-init-after)) (prog1 'leaf (leaf-init) (require 'leaf) (leaf-pre-init) (leaf-pre-init-after))))) (cort-deftest-with-macroexpand leaf/defer-config '(((leaf leaf :init (leaf-pre-init) :defer-config (leaf-init)) (prog1 'leaf (leaf-pre-init) (eval-after-load 'leaf '(progn (leaf-init))))) ((leaf leaf :init (leaf-init) :defer-config (leaf-pre-init) (leaf-pre-init-after)) (prog1 'leaf (leaf-init) (eval-after-load 'leaf '(progn (leaf-pre-init) (leaf-pre-init-after))))))) (cort-deftest-with-macroexpand leaf/auth-custom '( ;; Emulate customizing `sql-connection-alist' with value taken from `some-plstore'. ((leaf sql :auth-custom (sql-connection-alist . some-plstore)) (prog1 'sql (customize-set-variable 'sql-connection-alist (leaf-handler-auth sql sql-connection-alist some-plstore) "Customized with leaf in `sql' block using `some-plstore' plstore"))) ;; Emulate customizing `erc-password' and `erc-nickserv-passwords' ;; with values taken from `some-plstore', and `erc-user-full-name' ;; and `erc-nick' with values taken from `another-plstore'. ((leaf erc :auth-custom ((erc-password erc-nickserv-passwords) . some-plstore) ((erc-user-full-name erc-nick) . another-plstore)) (prog1 'erc (customize-set-variable 'erc-password (leaf-handler-auth erc erc-password some-plstore) "Customized with leaf in `erc' block using `some-plstore' plstore") (customize-set-variable 'erc-nickserv-passwords (leaf-handler-auth erc erc-nickserv-passwords some-plstore) "Customized with leaf in `erc' block using `some-plstore' plstore") (customize-set-variable 'erc-user-full-name (leaf-handler-auth erc erc-user-full-name another-plstore) "Customized with leaf in `erc' block using `another-plstore' plstore") (customize-set-variable 'erc-nick (leaf-handler-auth erc erc-nick another-plstore) "Customized with leaf in `erc' block using `another-plstore' plstore"))) ;; you can use symbol to configure with `leaf-default-plstore'. ((leaf erc :auth-custom erc-nick erc-password) (prog1 'erc (customize-set-variable 'erc-nick (leaf-handler-auth erc erc-nick leaf-default-plstore) "Customized with leaf in `erc' block using `leaf-default-plstore' plstore") (customize-set-variable 'erc-password (leaf-handler-auth erc erc-password leaf-default-plstore) "Customized with leaf in `erc' block using `leaf-default-plstore' plstore"))))) (cort-deftest-with-macroexpand leaf/auth-setq '( ;; Emulate setting `sql-connection-alist' with value taken from `some-plstore'. ((leaf sql :auth-setq (sql-connection-alist . some-plstore)) (prog1 'sql (setq sql-connection-alist (leaf-handler-auth sql sql-connection-alist some-plstore)))) ;; Emulate setting `erc-password' and `erc-nickserv-passwords' ;; with values taken from `some-plstore', and `erc-user-full-name' ;; and `erc-nick' with values taken from `another-plstore'. ((leaf erc :auth-setq ((erc-password erc-nickserv-passwords) . some-plstore) ((erc-user-full-name erc-nick) . another-plstore)) (prog1 'erc (setq erc-password (leaf-handler-auth erc erc-password some-plstore)) (setq erc-nickserv-passwords (leaf-handler-auth erc erc-nickserv-passwords some-plstore)) (setq erc-user-full-name (leaf-handler-auth erc erc-user-full-name another-plstore)) (setq erc-nick (leaf-handler-auth erc erc-nick another-plstore)))))) (cort-deftest-with-macroexpand leaf/auth-setq-default ;; Emulate setting `indent-tabs-mode' with a default value taken ;; from `some-plstore'. '(((leaf indent :auth-setq-default (indent-tabs-mode . some-plstore)) (prog1 'indent (setq-default indent-tabs-mode (leaf-handler-auth indent indent-tabs-mode some-plstore)))))) (cort-deftest-with-macroexpand leaf/auth-pre-setq ;; Emulate setting `indent-tabs-mode' with a default value taken ;; from `some-plstore'. '(((leaf indent :auth-pre-setq (indent-tabs-mode . some-plstore) :require t) (prog1 'indent (setq indent-tabs-mode (leaf-handler-auth indent indent-tabs-mode some-plstore)) (require 'indent))))) ;;;; System keywords (cort-deftest-with-macroexpand-let leaf/leaf-expand-minimally ((leaf-expand-minimally t)) '(((leaf leaf :config (leaf-init)) (prog1 'leaf (leaf-init))))) (cort-deftest-with-macroexpand leaf/leaf-autoload '(((leaf leaf :commands leaf :config (leaf-init)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (eval-after-load 'leaf '(progn (leaf-init))))) ((leaf leaf :leaf-autoload nil :commands leaf :config (leaf-init)) (prog1 'leaf (eval-after-load 'leaf '(progn (leaf-init))))))) (cort-deftest-with-macroexpand leaf/leaf-defer '(((leaf leaf :commands leaf :config (leaf-init)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (eval-after-load 'leaf '(progn (leaf-init))))) ((leaf leaf :leaf-defer nil :commands leaf :config (leaf-init)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (leaf-init))))) (cort-deftest-with-macroexpand-let leaf/leaf-protect ((leaf-expand-leaf-protect t)) '(((leaf leaf :config (leaf-init)) (prog1 'leaf (leaf-handler-leaf-protect leaf (leaf-init)))) ((leaf leaf :leaf-protect nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :leaf-protect t nil :config (leaf-init)) (prog1 'leaf (leaf-handler-leaf-protect leaf (leaf-init)))) ((leaf-handler-leaf-protect leaf (leaf-load) (leaf-init)) (condition-case err (progn (leaf-load) (leaf-init)) (error (display-warning 'leaf (format "Error in `leaf' block. Error msg: %s" (error-message-string err)))))))) (cort-deftest-with-macroexpand-let leaf/leaf-path ((leaf-expand-leaf-path t)) '(((leaf leaf :config (leaf-init)) (prog1 'leaf (leaf-handler-leaf-path leaf) (leaf-init))) ((leaf leaf :leaf-path nil :config (leaf-init)) (prog1 'leaf (leaf-init))) ((leaf leaf :leaf-path t nil :config (leaf-init)) (prog1 'leaf (leaf-handler-leaf-path leaf) (leaf-init))) ((leaf-handler-leaf-path leaf) (let ((file (leaf-this-file))) (unless (boundp 'leaf--paths) (defvar leaf--paths nil)) (when file (add-to-list 'leaf--paths (cons 'leaf file))))))) (cort-deftest-with-macroexpand leaf/leaf-defun '(((leaf annotate :commands annotate-mode :bind (("C-c a a" . annotate-annotate) ("C-c a ]" . annotate-next-annotation) ("C-c a [" . annotate-previous-anotation))) (prog1 'annotate (unless (fboundp 'annotate-annotate) (autoload #'annotate-annotate "annotate" nil t)) (unless (fboundp 'annotate-next-annotation) (autoload #'annotate-next-annotation "annotate" nil t)) (unless (fboundp 'annotate-previous-anotation) (autoload #'annotate-previous-anotation "annotate" nil t)) (unless (fboundp 'annotate-mode) (autoload #'annotate-mode "annotate" nil t)) (leaf-keys (("C-c a a" . annotate-annotate) ("C-c a ]" . annotate-next-annotation) ("C-c a [" . annotate-previous-anotation))))) ((leaf annotate :leaf-autoload nil :leaf-defun nil :commands annotate-mode :bind (("C-c a a" . annotate-annotate) ("C-c a ]" . annotate-next-annotation) ("C-c a [" . annotate-previous-anotation))) (prog1 'annotate (leaf-keys (("C-c a a" . annotate-annotate) ("C-c a ]" . annotate-next-annotation) ("C-c a [" . annotate-previous-anotation))))))) ;;;; Support leaf macros (cort-deftest-with-macroexpand leaf/handler-package '( ;; simple :ensure expandion example ((leaf macrostep :ensure t) (prog1 'macrostep (leaf-handler-package macrostep macrostep nil))) ;; `leaf-handler-package' expandion example. ;; If `macrostep' isn't installed, try to install. ;; If fail install, update local cache and retry to install. ((leaf-handler-package macrostep macrostep nil) (unless (package-installed-p 'macrostep) (unless (assoc 'macrostep package-archive-contents) (package-refresh-contents)) (condition-case _err (package-install 'macrostep) (error (condition-case err (progn (package-refresh-contents) (package-install 'macrostep)) (error (display-warning 'leaf (format "In `macrostep' block, failed to :package of `macrostep'. Error msg: %s" (error-message-string err))))))))))) (when (version< "24.0" emacs-version) (cort-deftest-with-macroexpand leaf/leaf-key '(((leaf-key "C-M-i" 'flyspell-correct-wrapper) (let* ((old (lookup-key global-map (kbd "C-M-i"))) (value `(global-map "C-M-i" flyspell-correct-wrapper ,(and old (not (numberp old)) old) nil))) (leaf-safe-push value leaf-key-bindlist) (define-key global-map (kbd "C-M-i") 'flyspell-correct-wrapper))) ((leaf-key [remap backward-sentence] 'sh-beginning-of-command) (let* ((old (lookup-key global-map [remap backward-sentence])) (value `(global-map " " sh-beginning-of-command ,(and old (not (numberp old)) old) nil))) (leaf-safe-push value leaf-key-bindlist) (define-key global-map [remap backward-sentence] 'sh-beginning-of-command))) ((leaf-key "C-M-i" 'flyspell-correct-wrapper 'c-mode-map) (let* ((old (lookup-key c-mode-map (kbd "C-M-i"))) (value `(c-mode-map "C-M-i" flyspell-correct-wrapper ,(and old (not (numberp old)) old) nil))) (leaf-safe-push value leaf-key-bindlist) (define-key c-mode-map (kbd "C-M-i") 'flyspell-correct-wrapper))) ((leaf-key [remap backward-sentence] 'sh-beginning-of-command 'shell-mode-map) (let* ((old (lookup-key shell-mode-map [remap backward-sentence])) (value `(shell-mode-map " " sh-beginning-of-command ,(and old (not (numberp old)) old) nil))) (leaf-safe-push value leaf-key-bindlist) (define-key shell-mode-map [remap backward-sentence] 'sh-beginning-of-command))) ((leaf-key (vector 'key-chord ?i ?j) 'undo nil) (let* ((old (lookup-key global-map [key-chord 105 106])) (value `(global-map " i j" undo ,(and old (not (numberp old)) old) nil))) (leaf-safe-push value leaf-key-bindlist) (define-key global-map [key-chord 105 106] 'undo))) ((leaf-key [(control ?x) (control ?f)] 'undo) (let* ((old (lookup-key global-map [(control 120) (control 102)])) (value `(global-map "C-x C-f" undo ,(and old (not (numberp old)) old) nil))) (leaf-safe-push value leaf-key-bindlist) (define-key global-map [(control 120) (control 102)] 'undo)))))) (when (version< "24.0" emacs-version) (cort-deftest-with-macroexpand leaf/leaf-key-bind-keymap '(((leaf-key-bind-keymap "C-c p" projectile-command-map) (progn nil (leaf-key "C-c p" projectile-command-map nil))) ((leaf-key-bind-keymap "C-c p" projectile-command-map 'c-mode-map) (progn nil (leaf-key "C-c p" projectile-command-map 'c-mode-map))) ((leaf-key-bind-keymap "C-c p" projectile-command-map 'c-mode-map 'projectile) (progn (require 'projectile) (leaf-key "C-c p" projectile-command-map 'c-mode-map))) ((leaf-key-bind-keymap [remap backward-sentence] projectile-command-map 'shell-mode-map) (progn nil (leaf-key [remap backward-sentence] projectile-command-map 'shell-mode-map)))))) ;; required `tabulated-list' ;; there are only tested running (leaf-key-describe-bindings) with no error (when (version<= "24.4" emacs-version) (cort-deftest leaf/leaf-key-describe '((:equal (leaf-key-describe-bindings) (leaf-key-describe-bindings))))) (cort-deftest-with-macroexpand leaf/leaf-key* '(((leaf-key* "C-M-i" 'flyspell-correct-wrapper) (leaf-key "C-M-i" 'flyspell-correct-wrapper 'leaf-key-override-global-map)) ((leaf-key* [remap backward-sentence] 'sh-beginning-of-command) (leaf-key [remap backward-sentence] 'sh-beginning-of-command 'leaf-key-override-global-map)))) (cort-deftest-with-macroexpand leaf/leaf-keys '(((leaf-keys ("C-M-i" . flyspell-correct-wrapper)) (leaf-key "C-M-i" #'flyspell-correct-wrapper)) ((leaf-keys (("C-M-i" . flyspell-correct-wrapper))) (leaf-key "C-M-i" #'flyspell-correct-wrapper)) ((leaf-keys (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (progn (leaf-key "C-c C-n" #'go-run) (leaf-key "C-c ." #'go-test-current-test))) ((leaf-keys (:go-mode-map ("C-M-i" . flyspell-correct-wrapper))) (progn (leaf-key "C-M-i" #'flyspell-correct-wrapper 'go-mode-map))) ((leaf-keys (:go-mode-map ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map))) ((leaf-keys (:go-mode-map (("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))) (progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map))) ((leaf-keys (:go-mode-map :package go-mode ("C-M-i" . flyspell-correct-wrapper))) (eval-after-load 'go-mode '(progn (leaf-key "C-M-i" #'flyspell-correct-wrapper 'go-mode-map)))) ((leaf-keys (:go-mode-map :package go-mode (("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))) (eval-after-load 'go-mode '(progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map)))) ((leaf-keys (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))) (eval-after-load 'go-mode '(eval-after-load 'cc-mode '(progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map))))) ((leaf-keys (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))) (eval-after-load 'go-mode '(eval-after-load 'cc-mode '(progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map))))) ((leaf-keys ((:isearch-mode-map ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))))) (progn (progn (leaf-key "M-o" #'isearch-moccur 'isearch-mode-map) (leaf-key "M-O" #'isearch-moccur-all 'isearch-mode-map)) (eval-after-load 'go-mode '(eval-after-load 'cc-mode '(progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map)))))) ((leaf-keys (("C-c C-n" . go-run) ("C-c ." . go-test-current-test) (:isearch-mode-map ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))))) (progn (leaf-key "C-c C-n" #'go-run) (leaf-key "C-c ." #'go-test-current-test) (progn (leaf-key "M-o" #'isearch-moccur 'isearch-mode-map) (leaf-key "M-O" #'isearch-moccur-all 'isearch-mode-map)) (eval-after-load 'go-mode '(eval-after-load 'cc-mode '(progn (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map)))))) ((leaf-keys (([remap compile] . go-run) ("C-c ." . go-test-current-test))) (progn (leaf-key [remap compile] #'go-run) (leaf-key "C-c ." #'go-test-current-test))) ((leaf-keys (((vector 'key-chord ?i ?j) . undo) ([remap compile] . go-run) ("C-c ." . go-test-current-test))) (progn (leaf-key (vector 'key-chord 105 106) #'undo) (leaf-key [remap compile] #'go-run) (leaf-key "C-c ." #'go-test-current-test))) ((leaf-keys (:go-mode-map :package go-mode (((vector 'key-chord ?i ?j) . undo) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))) (eval-after-load 'go-mode '(progn (leaf-key (vector 'key-chord 105 106) #'undo 'go-mode-map) (leaf-key "C-c C-n" #'go-run 'go-mode-map) (leaf-key "C-c ." #'go-test-current-test 'go-mode-map)))))) (cort-deftest-with-equal leaf/leaf-keys-dryrun '(((leaf-keys ("C-M-i" . flyspell-correct-wrapper) flyspell) '((("C-M-i" . flyspell-correct-wrapper)) (flyspell-correct-wrapper))) ((leaf-keys (("C-M-i" . flyspell-correct-wrapper)) flyspell) '((("C-M-i" . flyspell-correct-wrapper)) (flyspell-correct-wrapper))) ((leaf-keys (("C-c C-n" . go-run) ("C-c ." . go-test-current-test)) go-mode) '((("C-c C-n" . go-run) ("C-c ." . go-test-current-test)) (go-run go-test-current-test))) ((leaf-keys (:go-mode-map ("C-M-i" . flyspell-correct-wrapper)) go-mode) '(((go-mode-map :package go-mode ("C-M-i" . flyspell-correct-wrapper))) (flyspell-correct-wrapper))) ((leaf-keys (:go-mode-map ("C-c C-n" . go-run) ("C-c ." . go-test-current-test)) go-mode) '(((go-mode-map :package go-mode ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (go-run go-test-current-test))) ((leaf-keys (:go-mode-map :package go-mode ("C-M-i" . flyspell-correct-wrapper)) go-mode) '(((go-mode-map :package go-mode ("C-M-i" . flyspell-correct-wrapper))) (flyspell-correct-wrapper))) ((leaf-keys (:go-mode-map :package go-mode (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) go-mode) '(((go-mode-map :package go-mode ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (go-run go-test-current-test))) ((leaf-keys (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) go-mode) '(((go-mode-map :package (cc-mode go-mode) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (go-run go-test-current-test))) ((leaf-keys (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) go-mode) '(((go-mode-map :package (cc-mode go-mode) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (go-run go-test-current-test))) ((leaf-keys ((:isearch-mode-map ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (:go-mode-map :package (cc-mode go-mode) (("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))) go-mode) '(((isearch-mode-map :package go-mode ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (go-mode-map :package (cc-mode go-mode) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (isearch-moccur isearch-moccur-all go-run go-test-current-test))) ((leaf-keys (("C-c C-n" . go-run) ("C-c ." . go-test-current-test) (:isearch-mode-map ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (:go-mode-map :package (cc-mode go-mode) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) go-mode) '((("C-c C-n" . go-run) ("C-c ." . go-test-current-test) (isearch-mode-map :package go-mode ("M-o" . isearch-moccur) ("M-O" . isearch-moccur-all)) (go-mode-map :package (cc-mode go-mode) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (go-run go-test-current-test isearch-moccur isearch-moccur-all go-run go-test-current-test))) ((leaf-keys (([remap compile] . go-run) ("C-c ." . go-test-current-test)) go-mode) '((([remap compile] . go-run) ("C-c ." . go-test-current-test)) (go-run go-test-current-test))) ((leaf-keys (((vector 'key-chord ?i ?j) . undo) ([remap compile] . go-run) ("C-c ." . go-test-current-test)) go-mode) '((((vector 'key-chord 105 106) . undo) ([remap compile] . go-run) ("C-c ." . go-test-current-test)) (undo go-run go-test-current-test))) ((leaf-keys (:go-mode-map :package go-mode (((vector 'key-chord ?i ?j) . undo) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) go-mode) '(((go-mode-map :package go-mode ((vector 'key-chord 105 106) . undo) ("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (undo go-run go-test-current-test))))) (cort-deftest-with-macroexpand leaf/leaf-keys* '(((leaf-keys* ("C-M-i" . flyspell-correct-wrapper)) (leaf-keys (:leaf-key-override-global-map ("C-M-i" . flyspell-correct-wrapper)))) ((leaf-keys* (("C-c C-n" . go-run) ("C-c ." . go-test-current-test))) (leaf-keys (:leaf-key-override-global-map ("C-c C-n" . go-run) ("C-c ." . go-test-current-test)))))) (cort-deftest-with-macroexpand-let leaf/alias ((leaf-alias-keyword-alist '((:defer . :leaf-defer)))) '(((leaf leaf :commands leaf :config (leaf-init)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (eval-after-load 'leaf '(progn (leaf-init))))) ((leaf leaf :defer nil :commands leaf :config (leaf-init)) (prog1 'leaf (unless (fboundp 'leaf) (autoload #'leaf "leaf" nil t)) (leaf-init))))) (cort-deftest-with-macroexpand-let leaf/no-leaf-defaults ((leaf-defaults '())) '(((leaf leaf :config (leaf leaf-keywords :config (leaf-keywords-init)) (leaf leaf-tree :config (leaf-tree-init))) (prog1 'leaf (leaf leaf-keywords :config (leaf-keywords-init)) (leaf leaf-tree :config (leaf-tree-init)))))) (cort-deftest-with-macroexpand-let leaf/leaf-defaults ((leaf-defaults '(:ensure t))) '(((leaf leaf :config (leaf leaf-keywords :config (leaf-keywords-init)) (leaf leaf-tree :config (leaf-tree-init))) (prog1 'leaf (leaf-handler-package leaf leaf nil) (leaf leaf-keywords :config (leaf-keywords-init)) (leaf leaf-tree :config (leaf-tree-init)))))) ;;;; Misc functions (cort-deftest-with-equal leaf/pairp '(((leaf-pairp nil) nil) ((leaf-pairp t) nil) ((leaf-pairp 'a) nil) ((leaf-pairp '(nil . nil)) nil) ((leaf-pairp '(a . nil)) nil) ((leaf-pairp '(a . t)) t) ((leaf-pairp '(a . 'b)) t) ((leaf-pairp '(a . `b)) t) ((leaf-pairp '(a . #'b)) t) ((leaf-pairp '(a . (lambda (elm) elm))) t))) (cort-deftest-with-equal leaf/pairp-allow-nil '(((leaf-pairp nil 'allow-nil) t) ((leaf-pairp t 'allow-nil) nil) ((leaf-pairp 'a 'allow-nil) nil) ((leaf-pairp '(nil . nil) 'allow-nil) t) ((leaf-pairp '(a . nil) 'allow-nil) t) ((leaf-pairp '(a . t) 'allow-nil) t) ((leaf-pairp '(a . 'b) 'allow-nil) t) ((leaf-pairp '(a . `b) 'allow-nil) t) ((leaf-pairp '(a . #'b) 'allow-nil) t) ((leaf-pairp '(a . (lambda (elm) elm))) t))) (cort-deftest-with-equal leaf/normalize-list-in-list--normal '(((leaf-normalize-list-in-list 'a) '(a)) ((leaf-normalize-list-in-list '(a b c)) '(a b c)) ((leaf-normalize-list-in-list '(a . b)) '(a . b)) ((leaf-normalize-list-in-list '(a . nil)) '(a . nil)) ((leaf-normalize-list-in-list '(a . 'b)) '(a . 'b)) ((leaf-normalize-list-in-list '(a . 'nil)) '(a . 'nil)) ((leaf-normalize-list-in-list '(a)) '(a . nil)) ((leaf-normalize-list-in-list '((a . b) (c . d))) '((a . b) (c . d))) ((leaf-normalize-list-in-list '((a . 'b) (c . 'd))) '((a . 'b) (c . 'd))) ((leaf-normalize-list-in-list '((a) (b) (c))) '((a) (b) (c))) ((leaf-normalize-list-in-list '((a b c) . d)) '((a b c) . d)) ((leaf-normalize-list-in-list '((a b c) . 'd)) '((a b c) . 'd)))) (cort-deftest-with-equal normalize-list-in-list--distribute '(((leaf-normalize-list-in-list 'a 'dotlist) '((a))) ((leaf-normalize-list-in-list '(a) 'dotlist) '((a . nil))) ((leaf-normalize-list-in-list '(a b c) 'dotlist) '((a . nil) (b . nil) (c . nil))) ((leaf-normalize-list-in-list '(a . b) 'dotlist) '((a . b))) ((leaf-normalize-list-in-list '(a . nil) 'dotlist) '((a . nil))) ((leaf-normalize-list-in-list '(a . 'nil) 'dotlist) '((a . 'nil))) ((leaf-normalize-list-in-list '(a . 'b) 'dotlist) '((a . 'b))) ((leaf-normalize-list-in-list '(a . `b) 'dotlist) '((a . `b))) ((leaf-normalize-list-in-list '(a . #'b) 'dotlist) '((a . #'b))) ((leaf-normalize-list-in-list '(a . '(b c)) 'dotlist) '((a . '(b c)))) ((leaf-normalize-list-in-list '(a . `(b ,c)) 'dotlist) '((a . `(b ,c)))) ((leaf-normalize-list-in-list '(a . (lambda (v) v)) 'dotlist) '((a . (lambda (v) v)))) ((leaf-normalize-list-in-list '(a . '(lambda (v) v)) 'dotlist) '((a . '(lambda (v) v)))) ((leaf-normalize-list-in-list '(a . #'(lambda (v) v)) 'dotlist) '((a . #'(lambda (v) v)))) ((leaf-normalize-list-in-list '(a z . b) 'dotlist) '((a . b) (z . b))) ((leaf-normalize-list-in-list '(a z . nil) 'dotlist) '((a . nil) (z . nil))) ((leaf-normalize-list-in-list '(a z . 'nil) 'dotlist) '((a . 'nil) (z . 'nil))) ((leaf-normalize-list-in-list '(a z . 'b) 'dotlist) '((a . 'b) (z . 'b))) ((leaf-normalize-list-in-list '(a z . `b) 'dotlist) '((a . `b) (z . `b))) ((leaf-normalize-list-in-list '(a z . #'b) 'dotlist) '((a . #'b) (z . #'b))) ((leaf-normalize-list-in-list '(a z . '(b c)) 'dotlist) '((a . '(b c)) (z . '(b c)))) ((leaf-normalize-list-in-list '(a z . `(b ,c)) 'dotlist) '((a . `(b ,c)) (z . `(b ,c)))) ((leaf-normalize-list-in-list '(a z . (lambda (v) v)) 'dotlist) '((a . (lambda (v) v)) (z . (lambda (v) v)))) ((leaf-normalize-list-in-list '(a z . '(lambda (v) v)) 'dotlist) '((a . '(lambda (v) v)) (z . '(lambda (v) v)))) ((leaf-normalize-list-in-list '(a z . #'(lambda (v) v)) 'dotlist) '((a . #'(lambda (v) v)) (z . #'(lambda (v) v)))) ((leaf-normalize-list-in-list '((a) (b)) 'dotlist) '((a . nil) (b . nil))) ((leaf-normalize-list-in-list '((a . b) (c . nil)) 'dotlist) '((a . b) (c . nil))) ((leaf-normalize-list-in-list '((a . b) (c . d)) 'dotlist) '((a . b) (c . d))) ((leaf-normalize-list-in-list '((a . 'b) (c . 'd)) 'dotlist) '((a . 'b) (c . 'd))) ((leaf-normalize-list-in-list '((a . 'b) (c . #'d)) 'dotlist) '((a . 'b) (c . #'d))) ((leaf-normalize-list-in-list '((a . 'b) (c . '(d e))) 'dotlist) '((a . 'b) (c . '(d e)))) ((leaf-normalize-list-in-list '((a . 'b) (c . `(d ,e))) 'dotlist) '((a . 'b) (c . `(d ,e)))) ((leaf-normalize-list-in-list '((a . 'b) (c . (lambda (v) v))) 'dotlist) '((a . 'b) (c . (lambda (v) v)))) ((leaf-normalize-list-in-list '((a . 'b) (c . '(lambda (v) v))) 'dotlist) '((a . 'b) (c . '(lambda (v) v)))) ((leaf-normalize-list-in-list '((a . 'b) (c . #'(lambda (v) v))) 'dotlist) '((a . 'b) (c . #'(lambda (v) v)))) ((leaf-normalize-list-in-list '((a) (b z)) 'dotlist) '((a . nil) (b . nil) (z . nil))) ((leaf-normalize-list-in-list '((a . b) (c z . nil)) 'dotlist) '((a . b) (c . nil) (z . nil))) ((leaf-normalize-list-in-list '((a . b) (c z . d)) 'dotlist) '((a . b) (c . d) (z . d))) ((leaf-normalize-list-in-list '((a . 'b) (c z . 'd)) 'dotlist) '((a . 'b) (c . 'd) (z . 'd))) ((leaf-normalize-list-in-list '((a . 'b) (c z . #'d)) 'dotlist) '((a . 'b) (c . #'d) (z . #'d))) ((leaf-normalize-list-in-list '((a . 'b) (c z . '(d e))) 'dotlist) '((a . 'b) (c . '(d e)) (z . '(d e)))) ((leaf-normalize-list-in-list '((a . 'b) (c z . `(d ,e))) 'dotlist) '((a . 'b) (c . `(d ,e)) (z . `(d ,e)))) ((leaf-normalize-list-in-list '((a . 'b) (c z . (lambda (v) v))) 'dotlist) '((a . 'b) (c . (lambda (v) v)) (z . (lambda (v) v)))) ((leaf-normalize-list-in-list '((a . 'b) (c z . '(lambda (v) v))) 'dotlist) '((a . 'b) (c . '(lambda (v) v)) (z . '(lambda (v) v)))) ((leaf-normalize-list-in-list '((a . 'b) (c z . #'(lambda (v) v))) 'dotlist) '((a . 'b) (c . #'(lambda (v) v)) (z . #'(lambda (v) v)))) ((leaf-normalize-list-in-list '((a b c) . nil) 'dotlist) '((a . nil) (b . nil) (c . nil))) ((leaf-normalize-list-in-list '((a b c) . d) 'dotlist) '((a . d) (b . d) (c . d))) ((leaf-normalize-list-in-list '((a b c) . 'd) 'dotlist) '((a . 'd) (b . 'd) (c . 'd))) ((leaf-normalize-list-in-list '((a b c) . #'d) 'dotlist) '((a . #'d) (b . #'d) (c . #'d))) ((leaf-normalize-list-in-list '((a b c) . (lambda (v) v)) 'dotlist) '((a . (lambda (v) v)) (b . (lambda (v) v)) (c . (lambda (v) v)))) ((leaf-normalize-list-in-list '((x . 'y) ((a b c) . nil)) 'dotlist) '((x . 'y) (a . nil) (b . nil) (c . nil))) ((leaf-normalize-list-in-list '((x . 'y) ((a b c) . d)) 'dotlist) '((x . 'y) (a . d) (b . d) (c . d))) ((leaf-normalize-list-in-list '((x . 'y) ((a b c) . 'd)) 'dotlist) '((x . 'y) (a . 'd) (b . 'd) (c . 'd))) ((leaf-normalize-list-in-list '((x . 'y) ((a b c) . #'d)) 'dotlist) '((x . 'y) (a . #'d) (b . #'d) (c . #'d))) ((leaf-normalize-list-in-list '((x . 'y) ((a b c) . (lambda (v) v))) 'dotlist) '((x . 'y) (a . (lambda (v) v)) (b . (lambda (v) v)) (c . (lambda (v) v)))))) (cort-deftest-with-equal leaf/leaf-form-regexp '(((with-temp-buffer (require 'imenu) (emacs-lisp-mode) (insert (pp-to-string '(leaf package-foo))) (mapcar 'car (cdr (assoc "Leaf" (funcall imenu-create-index-function))))) '("package-foo")) ((with-temp-buffer (require 'imenu) (emacs-lisp-mode) (insert (pp-to-string '(leaf package-foo :config (leaf-init)))) (mapcar 'car (cdr (assoc "Leaf" (funcall imenu-create-index-function))))) '("package-foo")) ((with-temp-buffer (require 'imenu) (emacs-lisp-mode) (insert (pp-to-string '(leaf package-foo :custom (foo-package-to-enable . t) (foo-package-to-disable . nil) (foo-package-to-symbol . 'symbol) (foo-package-to-function . #'ignore) (foo-package-to-lambda . (lambda (elm) (message elm)))))) (mapcar 'car (cdr (assoc "Leaf" (funcall imenu-create-index-function))))) '("package-foo")) ((with-temp-buffer (require 'imenu) (emacs-lisp-mode) (insert (pp-to-string '(leaf package-foo :custom (foo-package-to-enable . t) (foo-package-to-disable . nil) (foo-package-to-symbol . 'symbol) (foo-package-to-function . #'ignore) (foo-package-to-lambda . (lambda (elm) (message elm))) :config (leaf package-bar :init (leaf package-baz))))) (mapcar 'car (cdr (assoc "Leaf" (funcall imenu-create-index-function))))) '("package-foo" "package-bar" "package-baz")) ((with-temp-buffer (require 'imenu) (emacs-lisp-mode) (insert "\ (leaf scala-mode :ensure t :after t :init (defun lsp-format-before-save () (add-hook 'before-save-hook 'lsp-format-buffer nil t)) :hook (scala-mode-hook . lsp-format-before-save) :config (leaf lsp-metals :ensure t :require t) (leaf *scala-flycheck-integration))") (mapcar 'car (cdr (assoc "Leaf" (funcall imenu-create-index-function))))) '("scala-mode" "lsp-metals" "*scala-flycheck-integration")))) (when (version<= "24.3" emacs-version) (require 'cl-lib) (cort-deftest-with-equal leaf/leaf-plist-get '(((let ((target '(:a "a" :b "b" :c "c"))) (setf (leaf-plist-get :b target) "modify") target) '(:a "a" :b "modify" :c "c")) ((let ((target '(:a "a" :b "b" :c "c"))) (cl-rotatef (leaf-plist-get :b target) (leaf-plist-get :c target)) target) '(:a "a" :b "c" :c "b")) ((let ((target '(:a "a" :b "b" :c "c"))) (setf (leaf-plist-get :d target) "modify") target) '(:d "modify" :a "a" :b "b" :c "c")) ((let ((target '(:a "a" :b "b" :c "c"))) (cl-rotatef (leaf-plist-get :b target) (leaf-plist-get :d target)) target) '(:d "b" :a "a" :b nil :c "c"))))) ;; (provide 'leaf-tests) ;; Local Variables: ;; indent-tabs-mode: nil ;; End: ;;; leaf-tests.el ends here