]> git.eshelyaron.com Git - emacs.git/commitdiff
Add `use-package-chords` and `use-package-ensure-system-package`
authorJustin Talbott <justin@waymondo.com>
Mon, 4 Dec 2017 15:57:23 +0000 (10:57 -0500)
committerJustin Talbott <justin@waymondo.com>
Mon, 4 Dec 2017 15:57:23 +0000 (10:57 -0500)
Also update docs on usage

connect to https://github.com/jwiegley/use-package/issues/516

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

diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el
new file mode 100644 (file)
index 0000000..e0827a4
--- /dev/null
@@ -0,0 +1,61 @@
+;;; bind-chord.el --- key-chord binding helper for use-package-chords
+
+;; Copyright (C) 2015-2017 Justin Talbott
+
+;; Author: Justin Talbott <justin@waymondo.com>
+;; Keywords: convenience, tools, extensions
+;; URL: https://github.com/waymondo/use-package-chords
+;; Version: 0.2
+;; 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
+;;
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'bind-key)
+(require 'key-chord)
+
+;;;###autoload
+(defmacro bind-chord (chord command &optional keymap)
+  "Bind CHORD to COMMAND in KEYMAP (`global-map' if not passed)."
+  (let ((key1 (logand 255 (aref chord 0)))
+        (key2 (logand 255 (aref chord 1))))
+    (if (eq key1 key2)
+        `(bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap)
+      `(progn
+         (bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap)
+         (bind-key (vector 'key-chord ,key2 ,key1) ,command ,keymap)))))
+
+;;;###autoload
+(defmacro bind-chords (&rest args)
+  "Bind multiple chords at once.
+
+Accepts keyword argument:
+: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 (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)))))
+
+(provide 'bind-chord)
+;;; bind-chord.el ends here
diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el
new file mode 100644 (file)
index 0000000..f3e85b4
--- /dev/null
@@ -0,0 +1,48 @@
+;;; use-package-chords.el --- key-chord keyword for use-package
+
+;; Copyright (C) 2015-2017 Justin Talbott
+
+;; Author: Justin Talbott <justin@waymondo.com>
+;; Keywords: convenience, tools, extensions
+;; URL: https://github.com/waymondo/use-package-chords
+;; Version: 0.2
+;; 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
+;;
+
+;;; Commentary:
+;;
+;; The `:chords' keyword allows you to define `key-chord' bindings for
+;; `use-package' declarations in the same manner as the `:bind'
+;; keyword.
+;;
+
+;;; Code:
+
+(require 'use-package)
+(require 'bind-chord)
+
+(add-to-list 'use-package-keywords :chords t)
+
+(defalias 'use-package-normalize/:chords 'use-package-normalize-binder)
+
+(defun use-package-handler/:chords (name keyword arg rest state)
+  "Handler for `:chords' keyword in `use-package'."
+  (let* ((commands (remq nil (mapcar #'(lambda (arg)
+                                         (if (listp arg)
+                                             (cdr arg)
+                                           nil)) arg)))
+         (chord-binder
+          (use-package-concat
+           (use-package-process-keywords name
+             (use-package-sort-keywords
+              (use-package-plist-maybe-put rest :defer t))
+             (use-package-plist-append state :commands commands))
+           `((ignore
+              ,(macroexpand
+                `(bind-chords :package ,name ,@arg)))))))
+    (use-package-handler/:preface name keyword chord-binder rest state)))
+
+(provide 'use-package-chords)
+;;; use-package-chords.el ends here
diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el
new file mode 100644 (file)
index 0000000..e34bb16
--- /dev/null
@@ -0,0 +1,70 @@
+;;; use-package-ensure-system-package.el --- auto install system packages
+
+;; Copyright (C) 2017 Justin Talbott
+
+;; Author: Justin Talbott <justin@waymondo.com>
+;; Keywords: convenience, tools, extensions
+;; URL: https://github.com/waymondo/use-package-ensure-system-package
+;; Version: 0.1
+;; Package-Requires: ((use-package "2.1") (system-packages "0.1"))
+;; Filename: use-package-ensure-system-package.el
+;; License: GNU General Public License version 3, or (at your option) any later version
+;;
+
+;;; Commentary:
+;;
+;; The `:ensure-system-package` keyword allows you to ensure system
+;; binaries exist alongside your `use-package` declarations.
+;;
+
+;;; Code:
+
+(require 'use-package)
+(require 'system-packages)
+
+(add-to-list 'use-package-keywords :ensure-system-package t)
+
+(defun use-package-ensure-system-package-install-command (pack)
+  "Return the default install command for `pack'."
+  (let ((command
+         (cdr (assoc 'install (cdr (assoc system-packages-packagemanager
+                                          system-packages-supported-package-managers))))))
+    (unless command
+      (error (format "%S not supported in %S" 'install system-packages-packagemanager)))
+    (unless (listp command)
+      (setq command (list command)))
+    (when system-packages-usesudo
+      (setq command (mapcar (lambda (part) (concat "sudo " part)) command)))
+    (setq command (mapconcat 'identity command " && "))
+    (mapconcat 'identity (list command pack) " ")))
+
+(defun use-package-ensure-system-package-consify (arg)
+  "Turn `arg' into a cons of (`package-name' . `install-command')."
+  (cond
+   ((stringp arg)
+    (cons arg (use-package-ensure-system-package-install-command arg)))
+   ((symbolp arg)
+    (cons arg (use-package-ensure-system-package-install-command (symbol-name arg))))
+   ((consp arg) arg)))
+
+(defun use-package-normalize/:ensure-system-package (name-symbol keyword args)
+  "Turn `arg' into a list of cons-es of (`package-name' . `install-command')."
+  (use-package-only-one (symbol-name keyword) args
+    (lambda (label arg)
+      (cond
+       ((and (listp arg) (listp (cdr arg)))
+        (mapcar #'use-package-ensure-system-package-consify arg))
+       (t
+        (list (use-package-ensure-system-package-consify arg)))))))
+
+(defun use-package-handler/:ensure-system-package (name keyword arg rest state)
+  "Execute the handler for `:ensure-system-package' keyword in `use-package'."
+  (let ((body (use-package-process-keywords name rest state)))
+    (use-package-concat
+     (mapcar #'(lambda (cons)
+                 `(unless (executable-find (symbol-name ',(car cons)))
+                    (async-shell-command ,(cdr cons)))) arg)
+     body)))
+
+(provide 'use-package-ensure-system-package)
+;;; use-package-ensure-system-package.el ends here