diff options
| author | Justin Talbott | 2019-06-20 11:27:46 -0400 |
|---|---|---|
| committer | Justin Talbott | 2019-06-20 11:48:55 -0400 |
| commit | 0d720a0f618fe2edfd7e7c547f422ae1d8b831c7 (patch) | |
| tree | 0d663aa9d3bc78482b9f9c96c5b5d5ab58b1ccc2 | |
| parent | 97f0287e1968d3ccd802fe52a4dbca707babd7fa (diff) | |
| download | emacs-0d720a0f618fe2edfd7e7c547f422ae1d8b831c7.tar.gz emacs-0d720a0f618fe2edfd7e7c547f422ae1d8b831c7.zip | |
update bind-chords to use of eval-after-load when maps declared
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
| -rw-r--r-- | lisp/use-package/bind-chord.el | 81 | ||||
| -rw-r--r-- | lisp/use-package/use-package-chords.el | 6 | ||||
| -rw-r--r-- | test/lisp/use-package/use-package-chords-tests.el | 161 |
3 files changed, 225 insertions, 23 deletions
diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index e5184bff60e..f009b2b8b29 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | ;;; bind-chord.el --- key-chord binding helper for use-package-chords | 1 | ;;; bind-chord.el --- key-chord binding helper for use-package-chords |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2015-2017 Justin Talbott | 3 | ;; Copyright (C) 2015-2019 Justin Talbott |
| 4 | 4 | ||
| 5 | ;; Author: Justin Talbott <justin@waymondo.com> | 5 | ;; Author: Justin Talbott <justin@waymondo.com> |
| 6 | ;; Keywords: convenience, tools, extensions | 6 | ;; Keywords: convenience, tools, extensions |
| 7 | ;; URL: https://github.com/waymondo/use-package-chords | 7 | ;; URL: https://github.com/jwiegley/use-package |
| 8 | ;; Version: 0.2 | 8 | ;; Version: 0.2.1 |
| 9 | ;; Package-Requires: ((bind-key "1.0") (key-chord "0.6")) | 9 | ;; Package-Requires: ((bind-key "1.0") (key-chord "0.6")) |
| 10 | ;; Filename: bind-chord.el | 10 | ;; Filename: bind-chord.el |
| 11 | ;; License: GNU General Public License version 3, or (at your option) any later version | 11 | ;; License: GNU General Public License version 3, or (at your option) any later version |
| @@ -30,6 +30,63 @@ | |||
| 30 | (bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap) | 30 | (bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap) |
| 31 | (bind-key (vector 'key-chord ,key2 ,key1) ,command ,keymap))))) | 31 | (bind-key (vector 'key-chord ,key2 ,key1) ,command ,keymap))))) |
| 32 | 32 | ||
| 33 | (defun bind-chords-form (args keymap) | ||
| 34 | "Bind multiple chords at once. | ||
| 35 | |||
| 36 | Accepts keyword arguments: | ||
| 37 | :map MAP - a keymap into which the keybindings should be | ||
| 38 | added | ||
| 39 | |||
| 40 | The rest of the arguments are conses of keybinding string and a | ||
| 41 | function symbol (unquoted)." | ||
| 42 | (let (map pkg) | ||
| 43 | (let ((cont t)) | ||
| 44 | (while (and cont args) | ||
| 45 | (if (cond ((eq :map (car args)) | ||
| 46 | (setq map (cadr args))) | ||
| 47 | ((eq :package (car args)) | ||
| 48 | (setq pkg (cadr args)))) | ||
| 49 | (setq args (cddr args)) | ||
| 50 | (setq cont nil)))) | ||
| 51 | |||
| 52 | (unless map (setq map keymap)) | ||
| 53 | |||
| 54 | (let (first next) | ||
| 55 | (while args | ||
| 56 | (if (keywordp (car args)) | ||
| 57 | (progn | ||
| 58 | (setq next args) | ||
| 59 | (setq args nil)) | ||
| 60 | (if first | ||
| 61 | (nconc first (list (car args))) | ||
| 62 | (setq first (list (car args)))) | ||
| 63 | (setq args (cdr args)))) | ||
| 64 | |||
| 65 | (cl-flet | ||
| 66 | ((wrap (map bindings) | ||
| 67 | (if (and map pkg (not (memq map '(global-map | ||
| 68 | override-global-map)))) | ||
| 69 | `((if (boundp ',map) | ||
| 70 | ,(macroexp-progn bindings) | ||
| 71 | (eval-after-load | ||
| 72 | ,(if (symbolp pkg) `',pkg pkg) | ||
| 73 | ',(macroexp-progn bindings)))) | ||
| 74 | bindings))) | ||
| 75 | |||
| 76 | (append | ||
| 77 | (wrap map | ||
| 78 | (cl-mapcan | ||
| 79 | (lambda (form) | ||
| 80 | (let ((fun (and (cdr form) (list 'function (cdr form))))) | ||
| 81 | (if (and map (not (eq map 'global-map))) | ||
| 82 | `((bind-chord ,(car form) ,fun ,map)) | ||
| 83 | `((bind-chord ,(car form) ,fun nil))))) | ||
| 84 | first)) | ||
| 85 | (when next | ||
| 86 | (bind-chords-form (if pkg | ||
| 87 | (cons :package (cons pkg next)) | ||
| 88 | next) map))))))) | ||
| 89 | |||
| 33 | ;;;###autoload | 90 | ;;;###autoload |
| 34 | (defmacro bind-chords (&rest args) | 91 | (defmacro bind-chords (&rest args) |
| 35 | "Bind multiple chords at once. | 92 | "Bind multiple chords at once. |
| @@ -39,23 +96,7 @@ Accepts keyword argument: | |||
| 39 | 96 | ||
| 40 | The rest of the arguments are conses of keybinding string and a | 97 | The rest of the arguments are conses of keybinding string and a |
| 41 | function symbol (unquoted)." | 98 | function symbol (unquoted)." |
| 42 | (let* ((map (plist-get args :map)) | 99 | (macroexp-progn (bind-chords-form args nil))) |
| 43 | (maps (if (listp map) map (list map))) | ||
| 44 | (key-bindings (progn | ||
| 45 | (while (keywordp (car args)) | ||
| 46 | (pop args) | ||
| 47 | (pop args)) | ||
| 48 | args))) | ||
| 49 | (macroexp-progn | ||
| 50 | (apply | ||
| 51 | #'nconc | ||
| 52 | (mapcar (lambda (form) | ||
| 53 | (if maps | ||
| 54 | (mapcar | ||
| 55 | #'(lambda (m) | ||
| 56 | `(bind-chord ,(car form) ',(cdr form) ,m)) maps) | ||
| 57 | `((bind-chord ,(car form) ',(cdr form))))) | ||
| 58 | key-bindings))))) | ||
| 59 | 100 | ||
| 60 | (provide 'bind-chord) | 101 | (provide 'bind-chord) |
| 61 | 102 | ||
diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 547adc27427..cf390dbe593 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | ;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- | 1 | ;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2015-2017 Justin Talbott | 3 | ;; Copyright (C) 2015-2019 Justin Talbott |
| 4 | 4 | ||
| 5 | ;; Author: Justin Talbott <justin@waymondo.com> | 5 | ;; Author: Justin Talbott <justin@waymondo.com> |
| 6 | ;; Keywords: convenience, tools, extensions | 6 | ;; Keywords: convenience, tools, extensions |
| 7 | ;; URL: https://github.com/waymondo/use-package-chords | 7 | ;; URL: https://github.com/jwiegley/use-package |
| 8 | ;; Version: 0.2 | 8 | ;; Version: 0.2.1 |
| 9 | ;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6")) | 9 | ;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6")) |
| 10 | ;; Filename: use-package-chords.el | 10 | ;; Filename: use-package-chords.el |
| 11 | ;; License: GNU General Public License version 3, or (at your option) any later version | 11 | ;; 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 index 00000000000..3c3dc4b4fe0 --- /dev/null +++ b/test/lisp/use-package/use-package-chords-tests.el | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | ;;; use-package-chords-tests.el --- Tests for use-package-chords.el -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; This program is free software; you can redistribute it and/or | ||
| 4 | ;; modify it under the terms of the GNU General Public License as | ||
| 5 | ;; published by the Free Software Foundation; either version 3, or (at | ||
| 6 | ;; your option) any later version. | ||
| 7 | |||
| 8 | ;; This program is distributed in the hope that it will be useful, but | ||
| 9 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | ;; General Public License for more details. | ||
| 12 | |||
| 13 | ;; You should have received a copy of the GNU General Public License | ||
| 14 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | ||
| 15 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 16 | ;; Boston, MA 02111-1307, USA. | ||
| 17 | |||
| 18 | ;;; Commentary: | ||
| 19 | |||
| 20 | ;; | ||
| 21 | |||
| 22 | |||
| 23 | ;;; Code: | ||
| 24 | |||
| 25 | (require 'use-package) | ||
| 26 | (require 'use-package-tests) | ||
| 27 | (require 'use-package-chords) | ||
| 28 | |||
| 29 | (defmacro match-expansion (form &rest value) | ||
| 30 | `(should (pcase (expand-minimally ,form) | ||
| 31 | ,@(mapcar #'(lambda (x) (list x t)) value)))) | ||
| 32 | |||
| 33 | (defun use-package-test-normalize-chord (&rest args) | ||
| 34 | (apply #'use-package-normalize-binder 'foo :chords args)) | ||
| 35 | |||
| 36 | (ert-deftest use-package-test-normalize/:chords-1 () | ||
| 37 | (should (equal (use-package-test-normalize-chord | ||
| 38 | '(("C-a" . alpha))) | ||
| 39 | '(("C-a" . alpha))))) | ||
| 40 | |||
| 41 | (ert-deftest use-package-test-normalize/:chords-2 () | ||
| 42 | (should (equal (use-package-test-normalize-chord | ||
| 43 | '(("C-a" . alpha) | ||
| 44 | :map foo-map | ||
| 45 | ("C-b" . beta))) | ||
| 46 | '(("C-a" . alpha) | ||
| 47 | :map foo-map | ||
| 48 | ("C-b" . beta))))) | ||
| 49 | |||
| 50 | (ert-deftest use-package-test-normalize/:chords-3 () | ||
| 51 | (should (equal (use-package-test-normalize-chord | ||
| 52 | '(:map foo-map | ||
| 53 | ("C-a" . alpha) | ||
| 54 | ("C-b" . beta))) | ||
| 55 | '(:map foo-map | ||
| 56 | ("C-a" . alpha) | ||
| 57 | ("C-b" . beta))))) | ||
| 58 | |||
| 59 | (ert-deftest use-package-test/:chords-1 () | ||
| 60 | (match-expansion | ||
| 61 | (use-package foo :chords ("C-k" . key1) ("C-u" . key2)) | ||
| 62 | `(progn | ||
| 63 | (unless | ||
| 64 | (fboundp 'key1) | ||
| 65 | (autoload #'key1 "foo" nil t)) | ||
| 66 | (unless | ||
| 67 | (fboundp 'key2) | ||
| 68 | (autoload #'key2 "foo" nil t)) | ||
| 69 | (bind-chord "C-k" #'key1 nil) | ||
| 70 | (bind-chord "C-u" #'key2 nil)))) | ||
| 71 | |||
| 72 | (ert-deftest use-package-test/:chords-2 () | ||
| 73 | (match-expansion | ||
| 74 | (use-package foo :chords (("C-k" . key1) ("C-u" . key2))) | ||
| 75 | `(progn | ||
| 76 | (unless (fboundp 'key1) | ||
| 77 | (autoload #'key1 "foo" nil t)) | ||
| 78 | (unless (fboundp 'key2) | ||
| 79 | (autoload #'key2 "foo" nil t)) | ||
| 80 | (bind-chord "C-k" #'key1 nil) | ||
| 81 | (bind-chord "C-u" #'key2 nil)))) | ||
| 82 | |||
| 83 | (ert-deftest use-package-test/:chords-3 () | ||
| 84 | (match-expansion | ||
| 85 | (use-package foo :chords (:map my-map ("C-k" . key1) ("C-u" . key2))) | ||
| 86 | `(progn | ||
| 87 | (unless | ||
| 88 | (fboundp 'key1) | ||
| 89 | (autoload #'key1 "foo" nil t)) | ||
| 90 | (unless | ||
| 91 | (fboundp 'key2) | ||
| 92 | (autoload #'key2 "foo" nil t)) | ||
| 93 | (if | ||
| 94 | (boundp 'my-map) | ||
| 95 | (progn | ||
| 96 | (bind-chord "C-k" #'key1 my-map) | ||
| 97 | (bind-chord "C-u" #'key2 my-map)) | ||
| 98 | (eval-after-load 'foo | ||
| 99 | '(progn | ||
| 100 | (bind-chord "C-k" #'key1 my-map) | ||
| 101 | (bind-chord "C-u" #'key2 my-map))))))) | ||
| 102 | |||
| 103 | (ert-deftest use-package-test/:chords-4 () | ||
| 104 | (should-error | ||
| 105 | (match-expansion | ||
| 106 | (use-package foo :chords :map my-map ("C-k" . key1) ("C-u" . key2)) | ||
| 107 | `(bind-chords :package foo)))) | ||
| 108 | |||
| 109 | (ert-deftest use-package-test/:chords-5 () | ||
| 110 | (match-expansion | ||
| 111 | (use-package foo :chords ("C-k" . key1) (:map my-map ("C-u" . key2))) | ||
| 112 | `(progn | ||
| 113 | (unless (fboundp 'key1) | ||
| 114 | (autoload #'key1 "foo" nil t)) | ||
| 115 | (unless (fboundp 'key2) | ||
| 116 | (autoload #'key2 "foo" nil t)) | ||
| 117 | (progn | ||
| 118 | (bind-chord "C-k" #'key1 nil) | ||
| 119 | (if | ||
| 120 | (boundp 'my-map) | ||
| 121 | (bind-chord "C-u" #'key2 my-map) | ||
| 122 | (eval-after-load 'foo | ||
| 123 | '(bind-chord "C-u" #'key2 my-map))))))) | ||
| 124 | |||
| 125 | (ert-deftest use-package-test/:chords-6 () | ||
| 126 | (match-expansion | ||
| 127 | (use-package foo | ||
| 128 | :chords | ||
| 129 | ("C-k" . key1) | ||
| 130 | (:map my-map ("C-u" . key2)) | ||
| 131 | (:map my-map2 ("C-u" . key3))) | ||
| 132 | `(progn | ||
| 133 | (unless | ||
| 134 | (fboundp 'key1) | ||
| 135 | (autoload #'key1 "foo" nil t)) | ||
| 136 | (unless | ||
| 137 | (fboundp 'key2) | ||
| 138 | (autoload #'key2 "foo" nil t)) | ||
| 139 | (unless | ||
| 140 | (fboundp 'key3) | ||
| 141 | (autoload #'key3 "foo" nil t)) | ||
| 142 | (progn | ||
| 143 | (bind-chord "C-k" #'key1 nil) | ||
| 144 | (if | ||
| 145 | (boundp 'my-map) | ||
| 146 | (bind-chord "C-u" #'key2 my-map) | ||
| 147 | (eval-after-load 'foo | ||
| 148 | '(bind-chord "C-u" #'key2 my-map))) | ||
| 149 | (if | ||
| 150 | (boundp 'my-map2) | ||
| 151 | (bind-chord "C-u" #'key3 my-map2) | ||
| 152 | (eval-after-load 'foo | ||
| 153 | '(bind-chord "C-u" #'key3 my-map2))))))) | ||
| 154 | |||
| 155 | ;; Local Variables: | ||
| 156 | ;; indent-tabs-mode: nil | ||
| 157 | ;; no-byte-compile: t | ||
| 158 | ;; no-update-autoloads: t | ||
| 159 | ;; End: | ||
| 160 | |||
| 161 | ;;; use-package-tests.el ends here | ||