]> git.eshelyaron.com Git - emacs.git/commitdiff
update bind-chords to use of eval-after-load when maps declared
authorJustin Talbott <justin@waymondo.com>
Thu, 20 Jun 2019 15:27:46 +0000 (11:27 -0400)
committerJustin Talbott <justin@waymondo.com>
Thu, 20 Jun 2019 15:48:55 +0000 (11:48 -0400)
also improve :chord keyword syntax processing to more closely mimic bind-keys since the same binding
normalizer is used.

also add tests for use-package-chords to cover these test cases

lisp/use-package/bind-chord.el
lisp/use-package/use-package-chords.el
test/lisp/use-package/use-package-chords-tests.el [new file with mode: 0644]

index e5184bff60efd45cb3a498a3a087838a5d3a1780..f009b2b8b29f6538f313ceee44145c0d476e679e 100644 (file)
@@ -1,11 +1,11 @@
 ;;; bind-chord.el --- key-chord binding helper for use-package-chords
 
-;; Copyright (C) 2015-2017 Justin Talbott
+;; Copyright (C) 2015-2019 Justin Talbott
 
 ;; Author: Justin Talbott <justin@waymondo.com>
 ;; Keywords: convenience, tools, extensions
-;; URL: https://github.com/waymondo/use-package-chords
-;; Version: 0.2
+;; URL: https://github.com/jwiegley/use-package
+;; Version: 0.2.1
 ;; Package-Requires: ((bind-key "1.0") (key-chord "0.6"))
 ;; Filename: bind-chord.el
 ;; License: GNU General Public License version 3, or (at your option) any later version
          (bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap)
          (bind-key (vector 'key-chord ,key2 ,key1) ,command ,keymap)))))
 
+(defun bind-chords-form (args keymap)
+  "Bind multiple chords at once.
+
+Accepts keyword arguments:
+:map MAP               - a keymap into which the keybindings should be
+                         added
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+  (let (map pkg)
+    (let ((cont t))
+      (while (and cont args)
+        (if (cond ((eq :map (car args))
+                   (setq map (cadr args)))
+                  ((eq :package (car args))
+                   (setq pkg (cadr args))))
+            (setq args (cddr args))
+          (setq cont nil))))
+
+    (unless map (setq map keymap))
+
+    (let (first next)
+      (while args
+        (if (keywordp (car args))
+            (progn
+              (setq next args)
+              (setq args nil))
+          (if first
+              (nconc first (list (car args)))
+            (setq first (list (car args))))
+          (setq args (cdr args))))
+
+      (cl-flet
+          ((wrap (map bindings)
+                 (if (and map pkg (not (memq map '(global-map
+                                                   override-global-map))))
+                     `((if (boundp ',map)
+                           ,(macroexp-progn bindings)
+                         (eval-after-load
+                             ,(if (symbolp pkg) `',pkg pkg)
+                           ',(macroexp-progn bindings))))
+                   bindings)))
+
+        (append
+         (wrap map
+               (cl-mapcan
+                (lambda (form)
+                  (let ((fun (and (cdr form) (list 'function (cdr form)))))
+                    (if (and map (not (eq map 'global-map)))
+                        `((bind-chord ,(car form) ,fun ,map))
+                      `((bind-chord ,(car form) ,fun nil)))))
+                first))
+         (when next
+           (bind-chords-form (if pkg
+                            (cons :package (cons pkg next))
+                          next) map)))))))
+
 ;;;###autoload
 (defmacro bind-chords (&rest args)
   "Bind multiple chords at once.
@@ -39,23 +96,7 @@ Accepts keyword argument:
 
 The rest of the arguments are conses of keybinding string and a
 function symbol (unquoted)."
-  (let* ((map (plist-get args :map))
-         (maps (if (listp map) map (list map)))
-         (key-bindings (progn
-                         (while (keywordp (car args))
-                           (pop args)
-                           (pop args))
-                         args)))
-    (macroexp-progn
-     (apply
-      #'nconc
-      (mapcar (lambda (form)
-                (if maps
-                    (mapcar
-                     #'(lambda (m)
-                         `(bind-chord ,(car form) ',(cdr form) ,m)) maps)
-                  `((bind-chord ,(car form) ',(cdr form)))))
-              key-bindings)))))
+  (macroexp-progn (bind-chords-form args nil)))
 
 (provide 'bind-chord)
 
index 547adc27427b1167f58c1f98edb2d8d4646d9628..cf390dbe59375ee005d32c45dddefee632a77edc 100644 (file)
@@ -1,11 +1,11 @@
 ;;; use-package-chords.el --- key-chord keyword for use-package  -*- lexical-binding: t; -*-
 
-;; Copyright (C) 2015-2017 Justin Talbott
+;; Copyright (C) 2015-2019 Justin Talbott
 
 ;; Author: Justin Talbott <justin@waymondo.com>
 ;; Keywords: convenience, tools, extensions
-;; URL: https://github.com/waymondo/use-package-chords
-;; Version: 0.2
+;; URL: https://github.com/jwiegley/use-package
+;; Version: 0.2.1
 ;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6"))
 ;; Filename: use-package-chords.el
 ;; License: GNU General Public License version 3, or (at your option) any later version
diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el
new file mode 100644 (file)
index 0000000..3c3dc4b
--- /dev/null
@@ -0,0 +1,161 @@
+;;; use-package-chords-tests.el --- Tests for use-package-chords.el  -*- lexical-binding: t; -*-
+
+;; 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, 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+\f
+;;; Commentary:
+
+;;
+
+\f
+;;; Code:
+
+(require 'use-package)
+(require 'use-package-tests)
+(require 'use-package-chords)
+
+(defmacro match-expansion (form &rest value)
+  `(should (pcase (expand-minimally ,form)
+             ,@(mapcar #'(lambda (x) (list x t)) value))))
+
+(defun use-package-test-normalize-chord (&rest args)
+  (apply #'use-package-normalize-binder 'foo :chords args))
+
+(ert-deftest use-package-test-normalize/:chords-1 ()
+  (should (equal (use-package-test-normalize-chord
+                  '(("C-a" . alpha)))
+                 '(("C-a" . alpha)))))
+
+(ert-deftest use-package-test-normalize/:chords-2 ()
+  (should (equal (use-package-test-normalize-chord
+                  '(("C-a" . alpha)
+                    :map foo-map
+                    ("C-b" . beta)))
+                 '(("C-a" . alpha)
+                   :map foo-map
+                   ("C-b" . beta)))))
+
+(ert-deftest use-package-test-normalize/:chords-3 ()
+  (should (equal (use-package-test-normalize-chord
+                  '(:map foo-map
+                         ("C-a" . alpha)
+                         ("C-b" . beta)))
+                 '(:map foo-map
+                        ("C-a" . alpha)
+                        ("C-b" . beta)))))
+
+(ert-deftest use-package-test/:chords-1 ()
+  (match-expansion
+   (use-package foo :chords ("C-k" . key1) ("C-u" . key2))
+   `(progn
+      (unless
+          (fboundp 'key1)
+        (autoload #'key1 "foo" nil t))
+      (unless
+          (fboundp 'key2)
+        (autoload #'key2 "foo" nil t))
+      (bind-chord "C-k" #'key1 nil)
+      (bind-chord "C-u" #'key2 nil))))
+
+(ert-deftest use-package-test/:chords-2 ()
+  (match-expansion
+   (use-package foo :chords (("C-k" . key1) ("C-u" . key2)))
+   `(progn
+      (unless (fboundp 'key1)
+        (autoload #'key1 "foo" nil t))
+      (unless (fboundp 'key2)
+        (autoload #'key2 "foo" nil t))
+      (bind-chord "C-k" #'key1 nil)
+      (bind-chord "C-u" #'key2 nil))))
+
+(ert-deftest use-package-test/:chords-3 ()
+  (match-expansion
+   (use-package foo :chords (:map my-map ("C-k" . key1) ("C-u" . key2)))
+   `(progn
+      (unless
+          (fboundp 'key1)
+        (autoload #'key1 "foo" nil t))
+      (unless
+          (fboundp 'key2)
+        (autoload #'key2 "foo" nil t))
+      (if
+          (boundp 'my-map)
+          (progn
+            (bind-chord "C-k" #'key1 my-map)
+            (bind-chord "C-u" #'key2 my-map))
+        (eval-after-load 'foo
+          '(progn
+             (bind-chord "C-k" #'key1 my-map)
+             (bind-chord "C-u" #'key2 my-map)))))))
+
+(ert-deftest use-package-test/:chords-4 ()
+  (should-error
+   (match-expansion
+    (use-package foo :chords :map my-map ("C-k" . key1) ("C-u" . key2))
+    `(bind-chords :package foo))))
+
+(ert-deftest use-package-test/:chords-5 ()
+  (match-expansion
+   (use-package foo :chords ("C-k" . key1) (:map my-map ("C-u" . key2)))
+   `(progn
+      (unless (fboundp 'key1)
+        (autoload #'key1 "foo" nil t))
+      (unless (fboundp 'key2)
+        (autoload #'key2 "foo" nil t))
+      (progn
+        (bind-chord "C-k" #'key1 nil)
+        (if
+            (boundp 'my-map)
+            (bind-chord "C-u" #'key2 my-map)
+          (eval-after-load 'foo
+            '(bind-chord "C-u" #'key2 my-map)))))))
+
+(ert-deftest use-package-test/:chords-6 ()
+  (match-expansion
+   (use-package foo
+     :chords
+     ("C-k" . key1)
+     (:map my-map ("C-u" . key2))
+     (:map my-map2 ("C-u" . key3)))
+   `(progn
+      (unless
+          (fboundp 'key1)
+        (autoload #'key1 "foo" nil t))
+      (unless
+          (fboundp 'key2)
+        (autoload #'key2 "foo" nil t))
+      (unless
+          (fboundp 'key3)
+        (autoload #'key3 "foo" nil t))
+      (progn
+        (bind-chord "C-k" #'key1 nil)
+        (if
+            (boundp 'my-map)
+            (bind-chord "C-u" #'key2 my-map)
+          (eval-after-load 'foo
+            '(bind-chord "C-u" #'key2 my-map)))
+        (if
+            (boundp 'my-map2)
+            (bind-chord "C-u" #'key3 my-map2)
+          (eval-after-load 'foo
+            '(bind-chord "C-u" #'key3 my-map2)))))))
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+
+;;; use-package-tests.el ends here