quelpa-use-package.el 4.19 KB
Newer Older
steckerhalter's avatar
steckerhalter committed
1 2 3 4 5
;;; quelpa-use-package.el --- quelpa handler for use-package

;; Copyright 2015, Steckerhalter

;; Author: steckerhalter
steckerhalter's avatar
steckerhalter committed
6
;; URL: https://framagit.org/steckerhalter/quelpa-use-package
steckerhalter's avatar
steckerhalter committed
7
;; Version: 0.0.1
steckerhalter's avatar
steckerhalter committed
8
;; Package-Requires: ((emacs "24.3") (quelpa "0") (use-package "2"))
steckerhalter's avatar
steckerhalter committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
;; Keywords: package management elpa use-package

;; This file is not part of GNU Emacs.

;; This file 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 file 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.

;;; Commentary:

;; quelpa handler for `use-package'
;; See the the repo website for more info:
steckerhalter's avatar
steckerhalter committed
32
;; https://framagit.org/steckerhalter/quelpa-use-package
steckerhalter's avatar
steckerhalter committed
33 34 35

;;; Requirements:

steckerhalter's avatar
steckerhalter committed
36
;; Emacs 24.3, `quelpa' and `use-package'
steckerhalter's avatar
steckerhalter committed
37 38 39

;;; Code:

40 41 42 43 44
(defvar quelpa-use-package-inhibit-loading-quelpa nil
  "If non-nil, `quelpa-use-package' will do its best to avoid
loading `quelpa' unless necessary. This improves performance, but
can prevent packages from being updated automatically.")

steckerhalter's avatar
steckerhalter committed
45
(require 'cl-lib)
46 47
(unless quelpa-use-package-inhibit-loading-quelpa
  (require 'quelpa))
48
(require 'use-package-core)
steckerhalter's avatar
steckerhalter committed
49 50 51

(defvar quelpa-use-package-keyword :quelpa)

52
;; insert `:quelpa' keyword after `:unless' so that quelpa only runs
53
;; if either `:if', `:when', `:unless' or `:requires' are satisfied
steckerhalter's avatar
steckerhalter committed
54 55 56
(defun quelpa-use-package-set-keyword ()
  (unless (member quelpa-use-package-keyword use-package-keywords)
    (setq use-package-keywords
57
          (let* ((pos (cl-position :unless use-package-keywords))
steckerhalter's avatar
steckerhalter committed
58 59 60 61 62 63 64 65 66 67 68 69
                 (head (cl-subseq use-package-keywords 0 (+ 1 pos)))
                 (tail (nthcdr (+ 1 pos) use-package-keywords)))
            (append head (list quelpa-use-package-keyword) tail)))))

(defun use-package-normalize/:quelpa (name-symbol keyword args)
  (let ((arg (car args)))
    (pcase arg
      ((or `nil `t) (list name-symbol))
      ((pred symbolp) args)
      ((pred listp) (cond
                     ((listp (car arg)) arg)
                     ((string-match "^:" (symbol-name (car arg))) (cons name-symbol arg))
Syohei YOSHIDA's avatar
Syohei YOSHIDA committed
70
                     ((symbolp (car arg)) args)))
steckerhalter's avatar
steckerhalter committed
71 72 73 74 75 76
      (_ nil))))

(defun use-package-handler/:quelpa (name-symbol keyword args rest state)
  (let ((body (use-package-process-keywords name-symbol rest state)))
    ;; This happens at macro expansion time, not when the expanded code is
    ;; compiled or evaluated.
77 78
    (if args
        (use-package-concat
79
         `((unless (and quelpa-use-package-inhibit-loading-quelpa
80
                        (package-installed-p ',(pcase (car args)
tsuucat's avatar
tsuucat committed
81 82
                                                 ((pred symbolp) (car args))
                                                 ((pred listp) (car (car args))))))
83
             (apply 'quelpa ',args)))
84 85
         body)
      body)))
steckerhalter's avatar
steckerhalter committed
86

87 88 89 90 91 92
(defun quelpa-use-package-override-:ensure (func name-symbol keyword ensure rest state)
  (let ((ensure (if (plist-member rest :quelpa)
                    nil
                  ensure)))
    (funcall func name-symbol keyword ensure rest state)))

steckerhalter's avatar
steckerhalter committed
93 94 95 96
(defadvice use-package-handler/:ensure (before quelpa-use-package/:ensure)
  (when (plist-member rest :quelpa)
    (ad-set-arg 2 nil)))

97
(defun quelpa-use-package-activate-advice ()
steckerhalter's avatar
steckerhalter committed
98 99 100 101 102 103
  (if (version< emacs-version "24.4")
      (ad-activate 'use-package-handler/:ensure t)
    (advice-add
     'use-package-handler/:ensure
     :around
     'quelpa-use-package-override-:ensure)))
104 105

(defun quelpa-use-package-deactivate-advice ()
steckerhalter's avatar
steckerhalter committed
106 107 108 109 110
  (if (version< emacs-version "24.4")
      (ad-deactivate 'use-package-handler/:ensure)
    (advice-remove
     'use-package-handler/:ensure
     'quelpa-use-package-override-:ensure)))
111

steckerhalter's avatar
steckerhalter committed
112 113 114 115 116 117
;; register keyword on require
(quelpa-use-package-set-keyword)

(provide 'quelpa-use-package)

;;; quelpa-use-package.el ends here