Add use-package-chords and use-package-ensure-system-package

Also update docs on usage

connect to https://github.com/jwiegley/use-package/issues/516
This commit is contained in:
Justin Talbott 2017-12-04 10:57:23 -05:00
parent 05dfea96e5
commit 5d9c854a6c
3 changed files with 179 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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