This commit is contained in:
Marcus Kammer 2020-04-14 08:05:43 +02:00
commit c37364d527
227 changed files with 9465 additions and 146 deletions

View file

@ -69,7 +69,7 @@
'(package-enable-at-startup t)
'(package-selected-packages
(quote
(ivy elpy olivetti ace-window graphviz-dot-mode dot-mode plantuml-mode elisp-format elisp-lint flymake-racket google-translate org-pomodoro elm-mode dashboard pickle poet-theme flymake-eslint json-mode darkroom dockerfile-mode ein spacemacs-theme flucui-themes leuven-theme htmlize scss-mode berrys-theme web-mode python-docstring sphinx-doc sphinx-frontend sphinx-mode ox-nikola racket-mode slime gherkin-mode powershell typescript-mode ob-http ob-ipython ob-restclient nord-theme restclient request restclient-test yaml-mode magit)))
(projectile python-django ivy elpy olivetti ace-window graphviz-dot-mode dot-mode plantuml-mode elisp-format elisp-lint flymake-racket google-translate org-pomodoro elm-mode dashboard pickle poet-theme flymake-eslint json-mode darkroom dockerfile-mode ein spacemacs-theme flucui-themes leuven-theme htmlize scss-mode berrys-theme web-mode python-docstring sphinx-doc sphinx-frontend sphinx-mode ox-nikola racket-mode slime gherkin-mode powershell typescript-mode ob-http ob-ipython ob-restclient nord-theme restclient request restclient-test yaml-mode magit)))
'(python-shell-interpreter "python3")
'(register-preview-delay 2)
'(register-separator 43)

View file

@ -1465,7 +1465,7 @@
("Ian Dunn" . "dunni@gnu.org"))
(:keywords "convenience" "text" "org"))])
(orgalist .
[(1 11)
[(1 12)
((emacs
(24 4)))
"Manage Org-like lists in non-Org buffers" single
@ -1549,7 +1549,7 @@
("Phillip Lord" . "phillip.lord@russet.org.uk"))
(:url . "http://elpa.gnu.org/packages/persist.html"))])
(phps-mode .
[(0 3 38)
[(0 3 39)
((emacs
(26)))
"Major mode for PHP with Semantic integration" tar
@ -1812,6 +1812,18 @@
(:authors
("Jan Moringen" . "scymtym@users.sourceforge.net"))
(:keywords "rudel" "collaboration"))])
(scanner .
[(0 1)
((emacs
(25 1))
(dash
(2 12 0)))
"Scan documents and images" tar
((:url . "https://gitlab.com/rstocker/scanner.git")
(:maintainer "Raffael Stocker" . "r.stocker@mnet-mail.de")
(:authors
("Raffael Stocker" . "r.stocker@mnet-mail.de"))
(:keywords "hardware" "multimedia"))])
(scroll-restore .
[(1 0)
nil "restore original position after scrolling" single

View file

@ -1 +1 @@
Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2020-04-08T23:05:02+0200 using RSA
Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2020-04-13T11:05:02+0200 using RSA

View file

@ -349,6 +349,8 @@ server command."
;; `ein:notebooklist-sentinel' frequently does not trigger
(ein:notebooklist-list-remove url-or-port)
(kill-buffer (ein:notebooklist-get-buffer url-or-port))
(when (ein:shared-output-healthy-p)
(kill-buffer (ein:shared-output-buffer)))
(when log
(with-current-buffer *ein:jupyter-server-buffer-name*
(write-region (point-min) (point-max) log)))))

View file

@ -33,8 +33,6 @@
;;; Code:
(require 'company nil t)
(require 'eldoc nil t)
(require 'ein-node)
(require 'ein-file)
(require 'ein-notebooklist)
@ -1284,14 +1282,6 @@ Tried add-function: the &rest from :around is an emacs-25 compilation issue."
'(("Open scratch sheet" ein:notebook-scratchsheet-open)))))
map)
(defcustom ein:enable-eldoc-support nil
"Enable experimental support for eldoc in notebook buffers.
Disabled by default, but if you want to help debug this feature set it to T and
watch the fireworks!"
:type 'boolean
:group 'ein)
(define-minor-mode ein:notebook-mode
"A mode for jupyter notebooks.

View file

@ -1,4 +1,4 @@
(define-package "ein" "20200328.2131" "Emacs IPython Notebook"
(define-package "ein" "20200410.1735" "Emacs IPython Notebook"
'((emacs "25")
(websocket "20190620.338")
(anaphora "20180618")

View file

@ -26,8 +26,6 @@
;; is needed. This module buffer containing one special cell for that
;; purpose.
;; TODO - Undo accounting is almost certainly broken by this module
;;; Code:
(require 'eieio)
@ -38,7 +36,8 @@
((cell-type :initarg :cell-type :initform "shared-output")
;; (element-names :initform (:prompt :output :footer))
(callback :initarg :callback :initform #'ignore :type function)
(callback-called :initarg :callback-called :initform nil :type boolean))
(clear :initarg :clear :initform #'ignore :type function)
(results-inserted :initarg :results-inserted :initform nil :type boolean))
"A singleton cell to show output from non-notebook buffers.")
(defclass ein:shared-output ()
@ -66,15 +65,17 @@ Called from ewoc pretty printer via `ein:cell-pp'."
(setf (slot-value cell 'kernel) kernel)
(apply #'ein:cell-execute-internal cell kernel code args))
(cl-defmethod ein:cell-append-display-data ((_cell ein:shared-output-cell) _json)
"Do not display the plot in the shared output context.")
(cl-defmethod ein:cell--handle-output ((cell ein:shared-output-cell)
msg-type _content _metadata)
(ein:log 'debug
"ein:cell--handle-output (cell ein:shared-output-cell): %s" msg-type)
(cl-call-next-method)
(aif (ein:oref-safe cell 'callback)
(progn
(funcall it cell)
(setf (slot-value cell 'callback-called) t))))
(awhen (ein:oref-safe cell 'callback)
(when (funcall it cell)
(setf (slot-value cell 'results-inserted) t))))
(cl-defmethod ein:cell--handle-execute-reply ((cell ein:shared-output-cell)
content _metadata)
@ -82,21 +83,20 @@ Called from ewoc pretty printer via `ein:cell-pp'."
"ein:cell--handle-execute-reply (cell ein:shared-output-cell): %s"
content)
(cl-call-next-method)
(aif (ein:oref-safe cell 'callback)
;; clear the way for waiting block in `ob-ein--execute-async'
;; but only after 2 seconds to allow for handle-output stragglers
;; TODO avoid this hack
(progn
(unless (ein:oref-safe cell 'callback-called)
(funcall it cell)
(setf (slot-value cell 'callback-called) t))
(run-at-time 2 nil (lambda ()
(ein:log 'debug "Clearing callback shared output cell")
(setf (slot-value cell 'callback) #'ignore)
(setf (slot-value cell 'callback-called) nil))))))
;;; Main
(awhen (ein:oref-safe cell 'callback)
(when (funcall it cell)
(setf (slot-value cell 'results-inserted) t)))
(unless (slot-value cell 'results-inserted)
(awhen (ein:oref-safe cell 'clear)
(funcall it)))
;; clear the way for waiting block in `ob-ein--execute-async'
;; but only after 2 seconds to allow for handle-output stragglers
;; TODO avoid this hack
(run-at-time 2 nil (lambda ()
(ein:log 'debug "Clearing callback shared output cell")
(setf (slot-value cell 'callback) #'ignore)
(setf (slot-value cell 'clear) #'ignore)
(setf (slot-value cell 'results-inserted) nil))))
(defun ein:shared-output-create-buffer ()
"Get or create the shared output buffer."
@ -212,9 +212,6 @@ See also `ein:cell-max-num-outputs'."
(defun ein:get-traceback-data--shared-output ()
(ein:aand (ein:get-cell-at-point--shared-output) (ein:cell-get-tb-data it)))
;;; ein:shared-output-mode
(defvar ein:shared-output-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-c\C-x" 'ein:tb-show)

View file

@ -117,6 +117,7 @@
(base64-decode-region (point-min) (point-max)))))
(defun ob-ein--proxy-images (json explicit-file)
(declare (indent defun))
(let (result)
(ein:output-area-case-type
json
@ -129,12 +130,22 @@
(setq result value))))
result))
(defun ob-ein--process-outputs (outputs params)
(let ((file (cdr (assoc :image params))))
(ein:join-str "\n"
(cl-loop for o in outputs
collecting (ob-ein--proxy-images o file)))))
(defun ob-ein--process-outputs (result-type cell params)
(let* ((render (let ((stdout-p
(lambda (out)
(and (equal "stream" (plist-get out :output_type))
(equal "stdout" (plist-get out :name))))))
(if (eq result-type 'output)
(lambda (out)
(and (funcall stdout-p out) (plist-get out :text)))
(lambda (out)
(and (not (funcall stdout-p out))
(ob-ein--proxy-images
out (cdr (assoc :image params))))))))
(outputs (cl-loop for out in (ein:oref-safe cell 'outputs)
collect (funcall render out))))
(when outputs
(ein:join-str "\n" outputs))))
(defun ob-ein--get-name-create (src-block-info)
"Get the name of a src block or add a uuid as the name."
@ -177,7 +188,8 @@ e.g., ob-c++ is not ob-C.el."
(defun ob-ein--execute-body (body params)
(let* ((buffer (current-buffer))
(processed-params (org-babel-process-params params))
(result-params (cdr (assq :result-params params)))
(result-type (cdr (assq :result-type params)))
(result-params (cdr (assq :result-params params)))
(session (or (ein:aand (cdr (assoc :session processed-params))
(unless (string= "none" it)
(format "%s" it)))
@ -195,6 +207,7 @@ e.g., ob-c++ is not ob-C.el."
body
(ein:$notebook-kernel notebook)
processed-params
result-type
result-params
name))))
(save-excursion
@ -218,44 +231,64 @@ e.g., ob-c++ is not ob-C.el."
(if pending
(prog1 ""
(ein:log 'error "ob-ein--execute-body: %s timed out" name))
(ob-ein--process-outputs
(ein:oref-safe (ein:shared-output-get-cell) 'outputs)
processed-params))))
(ob-ein--process-outputs result-type
(ein:shared-output-get-cell)
processed-params))))
(org-babel-remove-result)
*ob-ein-sentinel*)))
(defsubst ob-ein--execute-async-callback (buffer params result-params name)
"Callback of 1-arity (the shared output cell) to update org buffer when
`ein:shared-output-eval-string' completes."
(apply-partially
(lambda (buffer* params* result-params* name* cell)
(let* ((raw (aif (ein:oref-safe cell 'traceback)
(ansi-color-apply (ein:join-str "\n" it))
(ob-ein--process-outputs
(ein:oref-safe cell 'outputs) params*)))
(result
(let ((tmp-file (org-babel-temp-file "ein-")))
(with-temp-file tmp-file raw)
(org-babel-result-cond result-params*
raw (org-babel-import-elisp-from-file tmp-file '(16)))))
(info (org-babel-get-src-block-info 'light)))
(ein:log 'debug "ob-ein--execute-async-callback %s \"%s\" %s" name* result buffer*)
(save-excursion
(save-restriction
(with-current-buffer buffer*
(unless (stringp (org-babel-goto-named-src-block name*)) ;; stringp=error
(when info ;; kill #+RESULTS: (no-name)
(setf (nth 4 info) nil)
(org-babel-remove-result info))
(org-babel-remove-result) ;; kill #+RESULTS: name
(org-babel-insert-result
result
(cdr (assoc :result-params
(third (org-babel-get-src-block-info)))))
(org-redisplay-inline-images)))))))
buffer params result-params name))
(defun ob-ein--execute-async-callback (buffer params result-type result-params name)
"Return callback of 1-arity (the shared output cell) to update org buffer when
`ein:shared-output-eval-string' completes.
(defun ob-ein--execute-async (buffer body kernel params result-params name)
The callback returns t if results containt RESULT-TYPE outputs, nil otherwise."
(apply-partially
(lambda (buffer* params* result-type* result-params* name* cell)
(when-let ((raw (aif (ein:oref-safe cell 'traceback)
(ansi-color-apply (ein:join-str "\n" it))
(ob-ein--process-outputs result-type* cell params*))))
(prog1 t
(let ((result
(let ((tmp-file (org-babel-temp-file "ein-")))
(with-temp-file tmp-file raw)
(org-babel-result-cond result-params*
raw (org-babel-import-elisp-from-file tmp-file '(16)))))
(info (org-babel-get-src-block-info 'light)))
(ein:log 'debug "ob-ein--execute-async-callback %s \"%s\" %s"
name* result buffer*)
(save-excursion
(save-restriction
(with-current-buffer buffer*
(unless (stringp (org-babel-goto-named-src-block name*)) ;; stringp=error
(when info ;; kill #+RESULTS: (no-name)
(setf (nth 4 info) nil)
(org-babel-remove-result info))
(org-babel-remove-result) ;; kill #+RESULTS: name
(org-babel-insert-result
result
(cdr (assoc :result-params
(third (org-babel-get-src-block-info)))))
(org-redisplay-inline-images)))))))))
buffer params result-type result-params name))
(defun ob-ein--execute-async-clear (buffer result-params name)
"Return function of 0-arity to clear *ob-ein-sentinel*."
(apply-partially
(lambda (buffer* result-params* name*)
(let ((info (org-babel-get-src-block-info 'light)))
(save-excursion
(save-restriction
(with-current-buffer buffer*
(unless (stringp (org-babel-goto-named-src-block name*)) ;; stringp=error
(when info ;; kill #+RESULTS: (no-name)
(setf (nth 4 info) nil)
(org-babel-remove-result info))
(org-babel-remove-result) ;; kill #+RESULTS: name
(org-babel-insert-result "" result-params*)
(org-redisplay-inline-images)))))))
buffer result-params name))
(defun ob-ein--execute-async (buffer body kernel params result-type result-params name)
"As `ein:shared-output-get-cell' is a singleton, ob-ein can only execute blocks
one at a time. Further, we do not order the queued up blocks!"
(deferred:$
@ -263,10 +296,12 @@ one at a time. Further, we do not order the queued up blocks!"
(deferred:lambda ()
(let ((cell (ein:shared-output-get-cell)))
(if (eq (slot-value cell 'callback) #'ignore)
(let ((callback
(ob-ein--execute-async-callback buffer params
result-params name)))
(setf (slot-value cell 'callback) callback))
(let ((callback (ob-ein--execute-async-callback
buffer params result-type
result-params name))
(clear (ob-ein--execute-async-clear buffer result-params name)))
(setf (slot-value cell 'callback) callback)
(setf (slot-value cell 'clear) clear))
;; still pending previous callback
(deferred:nextc (deferred:wait 1200) self)))))
(deferred:nextc it

View file

@ -0,0 +1,22 @@
;;; epl-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path (directory-file-name
(or (file-name-directory #$) (car load-path))))
;;;### (autoloads nil "epl" "epl.el" (0 0 0 0))
;;; Generated autoloads from epl.el
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "epl" '("epl-")))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; epl-autoloads.el ends here

View file

@ -0,0 +1,2 @@
;;; -*- no-byte-compile: t -*-
(define-package "epl" "20180205.2049" "Emacs Package Library" '((cl-lib "0.3")) :commit "78ab7a85c08222cd15582a298a364774e3282ce6" :keywords '("convenience") :authors '(("Sebastian Wiesner" . "swiesner@lunaryorn.com")) :maintainer '("Johan Andersson" . "johan.rejeep@gmail.com") :url "http://github.com/cask/epl")

View file

@ -0,0 +1,711 @@
;;; epl.el --- Emacs Package Library -*- lexical-binding: t; -*-
;; Copyright (C) 2013-2015 Sebastian Wiesner
;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2015 Free Software
;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
;; Sebastian Wiesner <swiesner@lunaryorn.com>
;; Version: 0.10-cvs
;; Package-Version: 20180205.2049
;; Package-Requires: ((cl-lib "0.3"))
;; Keywords: convenience
;; URL: http://github.com/cask/epl
;; This file is NOT part of GNU Emacs.
;; 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 of the License, 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; A package management library for Emacs, based on package.el.
;; The purpose of this library is to wrap all the quirks and hassle of
;; package.el into a sane API.
;; The following functions comprise the public interface of this library:
;;; Package directory selection
;; `epl-package-dir' gets the directory of packages.
;; `epl-default-package-dir' gets the default package directory.
;; `epl-change-package-dir' changes the directory of packages.
;;; Package system management
;; `epl-initialize' initializes the package system and activates all
;; packages.
;; `epl-reset' resets the package system.
;; `epl-refresh' refreshes all package archives.
;; `epl-add-archive' adds a new package archive.
;;; Package objects
;; Struct `epl-requirement' describes a requirement of a package with `name' and
;; `version' slots.
;; `epl-requirement-version-string' gets a requirement version as string.
;; Struct `epl-package' describes an installed or installable package with a
;; `name' and some internal `description'.
;; `epl-package-version' gets the version of a package.
;; `epl-package-version-string' gets the version of a package as string.
;; `epl-package-summary' gets the summary of a package.
;; `epl-package-requirements' gets the requirements of a package.
;; `epl-package-directory' gets the installation directory of a package.
;; `epl-package-from-buffer' creates a package object for the package contained
;; in the current buffer.
;; `epl-package-from-file' creates a package object for a package file, either
;; plain lisp or tarball.
;; `epl-package-from-descriptor-file' creates a package object for a package
;; description (i.e. *-pkg.el) file.
;;; Package database access
;; `epl-package-installed-p' determines whether a package is installed, either
;; built-in or explicitly installed.
;; `epl-package-outdated-p' determines whether a package is outdated, that is,
;; whether a package with a higher version number is available.
;; `epl-built-in-packages', `epl-installed-packages', `epl-outdated-packages'
;; and `epl-available-packages' get all packages built-in, installed, outdated,
;; or available for installation respectively.
;; `epl-find-built-in-package', `epl-find-installed-packages' and
;; `epl-find-available-packages' find built-in, installed and available packages
;; by name.
;; `epl-find-upgrades' finds all upgradable packages.
;; `epl-built-in-p' return true if package is built-in to Emacs.
;;; Package operations
;; `epl-install-file' installs a package file.
;; `epl-package-install' installs a package.
;; `epl-package-delete' deletes a package.
;; `epl-upgrade' upgrades packages.
;;; Code:
(require 'cl-lib)
(require 'package)
(unless (fboundp #'define-error)
;; `define-error' for 24.3 and earlier, copied from subr.el
(defun define-error (name message &optional parent)
"Define NAME as a new error signal.
MESSAGE is a string that will be output to the echo area if such an error
is signaled without being caught by a `condition-case'.
PARENT is either a signal or a list of signals from which it inherits.
Defaults to `error'."
(unless parent (setq parent 'error))
(let ((conditions
(if (consp parent)
(apply #'append
(mapcar (lambda (parent)
(cons parent
(or (get parent 'error-conditions)
(error "Unknown signal `%s'" parent))))
parent))
(cons parent (get parent 'error-conditions)))))
(put name 'error-conditions
(delete-dups (copy-sequence (cons name conditions))))
(when message (put name 'error-message message)))))
(defsubst epl--package-desc-p (package)
"Whether PACKAGE is a `package-desc' object.
Like `package-desc-p', but return nil, if `package-desc-p' is not
defined as function."
(and (fboundp 'package-desc-p) (package-desc-p package)))
;;; EPL errors
(define-error 'epl-error "EPL error")
(define-error 'epl-invalid-package "Invalid EPL package" 'epl-error)
(define-error 'epl-invalid-package-file "Invalid EPL package file"
'epl-invalid-package)
;;; Package directory
(defun epl-package-dir ()
"Get the directory of packages."
package-user-dir)
(defun epl-default-package-dir ()
"Get the default directory of packages."
(eval (car (get 'package-user-dir 'standard-value))))
(defun epl-change-package-dir (directory)
"Change the directory of packages to DIRECTORY."
(setq package-user-dir directory)
(epl-initialize))
;;; Package system management
(defvar epl--load-path-before-initialize nil
"Remember the load path for `epl-reset'.")
(defun epl-initialize (&optional no-activate)
"Load Emacs Lisp packages and activate them.
With NO-ACTIVATE non-nil, do not activate packages."
(setq epl--load-path-before-initialize load-path)
(package-initialize no-activate))
(defalias 'epl-refresh 'package-refresh-contents)
(defun epl-add-archive (name url)
"Add a package archive with NAME and URL."
(add-to-list 'package-archives (cons name url)))
(defun epl-reset ()
"Reset the package system.
Clear the list of installed and available packages, the list of
package archives and reset the package directory."
(setq package-alist nil
package-archives nil
package-archive-contents nil
load-path epl--load-path-before-initialize)
(when (boundp 'package-obsolete-alist) ; Legacy package.el
(setq package-obsolete-alist nil))
(epl-change-package-dir (epl-default-package-dir)))
;;; Package structures
(cl-defstruct (epl-requirement
(:constructor epl-requirement-create))
"Structure describing a requirement.
Slots:
`name' The name of the required package, as symbol.
`version' The version of the required package, as version list."
name
version)
(defun epl-requirement-version-string (requirement)
"The version of a REQUIREMENT, as string."
(package-version-join (epl-requirement-version requirement)))
(cl-defstruct (epl-package (:constructor epl-package-create))
"Structure representing a package.
Slots:
`name' The package name, as symbol.
`description' The package description.
The format package description varies between package.el
variants. For `package-desc' variants, it is simply the
corresponding `package-desc' object. For legacy variants, it is
a vector `[VERSION REQS DOCSTRING]'.
Do not access `description' directly, but instead use the
`epl-package' accessors."
name
description)
(defmacro epl-package-as-description (var &rest body)
"Cast VAR to a package description in BODY.
VAR is a symbol, bound to an `epl-package' object. This macro
casts this object to the `description' object, and binds the
description to VAR in BODY."
(declare (indent 1))
(unless (symbolp var)
(signal 'wrong-type-argument (list #'symbolp var)))
`(if (epl-package-p ,var)
(let ((,var (epl-package-description ,var)))
,@body)
(signal 'wrong-type-argument (list #'epl-package-p ,var))))
(defsubst epl-package--package-desc-p (package)
"Whether the description of PACKAGE is a `package-desc'."
(epl--package-desc-p (epl-package-description package)))
(defun epl-package-version (package)
"Get the version of PACKAGE, as version list."
(epl-package-as-description package
(cond
((fboundp 'package-desc-version) (package-desc-version package))
;; Legacy
((fboundp 'package-desc-vers)
(let ((version (package-desc-vers package)))
(if (listp version) version (version-to-list version))))
(:else (error "Cannot get version from %S" package)))))
(defun epl-package-version-string (package)
"Get the version from a PACKAGE, as string."
(package-version-join (epl-package-version package)))
(defun epl-package-summary (package)
"Get the summary of PACKAGE, as string."
(epl-package-as-description package
(cond
((fboundp 'package-desc-summary) (package-desc-summary package))
((fboundp 'package-desc-doc) (package-desc-doc package)) ; Legacy
(:else (error "Cannot get summary from %S" package)))))
(defsubst epl-requirement--from-req (req)
"Create a `epl-requirement' from a `package-desc' REQ."
(let ((version (cadr req)))
(epl-requirement-create :name (car req)
:version (if (listp version) version
(version-to-list version)))))
(defun epl-package-requirements (package)
"Get the requirements of PACKAGE.
The requirements are a list of `epl-requirement' objects."
(epl-package-as-description package
(mapcar #'epl-requirement--from-req (package-desc-reqs package))))
(defun epl-package-directory (package)
"Get the directory PACKAGE is installed to.
Return the absolute path of the installation directory of
PACKAGE, or nil, if PACKAGE is not installed."
(cond
((fboundp 'package-desc-dir)
(package-desc-dir (epl-package-description package)))
((fboundp 'package--dir)
(package--dir (symbol-name (epl-package-name package))
(epl-package-version-string package)))
(:else (error "Cannot get package directory from %S" package))))
(defun epl-package-->= (pkg1 pkg2)
"Determine whether PKG1 is before PKG2 by version."
(not (version-list-< (epl-package-version pkg1)
(epl-package-version pkg2))))
(defun epl-package--from-package-desc (package-desc)
"Create an `epl-package' from a PACKAGE-DESC.
PACKAGE-DESC is a `package-desc' object, from recent package.el
variants."
(if (and (fboundp 'package-desc-name)
(epl--package-desc-p package-desc))
(epl-package-create :name (package-desc-name package-desc)
:description package-desc)
(signal 'wrong-type-argument (list 'epl--package-desc-p package-desc))))
(defun epl-package--parse-info (info)
"Parse a package.el INFO."
(if (epl--package-desc-p info)
(epl-package--from-package-desc info)
;; For legacy package.el, info is a vector [NAME REQUIRES DESCRIPTION
;; VERSION COMMENTARY]. We need to re-shape this vector into the
;; `package-alist' format [VERSION REQUIRES DESCRIPTION] to attach it to the
;; new `epl-package'.
(let ((name (intern (aref info 0)))
(info (vector (aref info 3) (aref info 1) (aref info 2))))
(epl-package-create :name name :description info))))
(defun epl-package-from-buffer (&optional buffer)
"Create an `epl-package' object from BUFFER.
BUFFER defaults to the current buffer.
Signal `epl-invalid-package' if the buffer does not contain a
valid package file."
(let ((info (with-current-buffer (or buffer (current-buffer))
(condition-case err
(package-buffer-info)
(error (signal 'epl-invalid-package (cdr err)))))))
(epl-package--parse-info info)))
(defun epl-package-from-lisp-file (file-name)
"Parse the package headers the file at FILE-NAME.
Return an `epl-package' object with the header metadata."
(with-temp-buffer
(insert-file-contents file-name)
(condition-case err
(epl-package-from-buffer (current-buffer))
;; Attach file names to invalid package errors
(epl-invalid-package
(signal 'epl-invalid-package-file (cons file-name (cdr err))))
;; Forward other errors
(error (signal (car err) (cdr err))))))
(defun epl-package-from-tar-file (file-name)
"Parse the package tarball at FILE-NAME.
Return a `epl-package' object with the meta data of the tarball
package in FILE-NAME."
(condition-case nil
;; In legacy package.el, `package-tar-file-info' takes the name of the tar
;; file to parse as argument. In modern package.el, it has no arguments
;; and works on the current buffer. Hence, we just try to call the legacy
;; version, and if that fails because of a mismatch between formal and
;; actual arguments, we use the modern approach. To avoid spurious
;; signature warnings by the byte compiler, we suppress warnings when
;; calling the function.
(epl-package--parse-info (with-no-warnings
(package-tar-file-info file-name)))
(wrong-number-of-arguments
(with-temp-buffer
(insert-file-contents-literally file-name)
;; Switch to `tar-mode' to enable extraction of the file. Modern
;; `package-tar-file-info' relies on `tar-mode', and signals an error if
;; called in a buffer with a different mode.
(tar-mode)
(epl-package--parse-info (with-no-warnings
(package-tar-file-info)))))))
(defun epl-package-from-file (file-name)
"Parse the package at FILE-NAME.
Return an `epl-package' object with the meta data of the package
at FILE-NAME."
(if (string-match-p (rx ".tar" string-end) file-name)
(epl-package-from-tar-file file-name)
(epl-package-from-lisp-file file-name)))
(defun epl-package--parse-descriptor-requirement (requirement)
"Parse a REQUIREMENT in a package descriptor."
;; This function is only called on legacy package.el. On package-desc
;; package.el, we just let package.el do the work.
(cl-destructuring-bind (name version-string) requirement
(list name (version-to-list version-string))))
(defun epl-package-from-descriptor-file (descriptor-file)
"Load a `epl-package' from a package DESCRIPTOR-FILE.
A package descriptor is a file defining a new package. Its name
typically ends with -pkg.el."
(with-temp-buffer
(insert-file-contents descriptor-file)
(goto-char (point-min))
(let ((sexp (read (current-buffer))))
(unless (eq (car sexp) 'define-package)
(error "%S is no valid package descriptor" descriptor-file))
(if (and (fboundp 'package-desc-from-define)
(fboundp 'package-desc-name))
;; In Emacs snapshot, we can conveniently call a function to parse the
;; descriptor
(let ((desc (apply #'package-desc-from-define (cdr sexp))))
(epl-package-create :name (package-desc-name desc)
:description desc))
;; In legacy package.el, we must manually deconstruct the descriptor,
;; because the load function has eval's the descriptor and has a lot of
;; global side-effects.
(cl-destructuring-bind
(name version-string summary requirements) (cdr sexp)
(epl-package-create
:name (intern name)
:description
(vector (version-to-list version-string)
(mapcar #'epl-package--parse-descriptor-requirement
;; Strip the leading `quote' from the package list
(cadr requirements))
summary)))))))
;;; Package database access
(defun epl-package-installed-p (package &optional min-version)
"Determine whether a PACKAGE, of MIN-VERSION or newer, is installed.
PACKAGE is either a package name as symbol, or a package object.
When a explicit MIN-VERSION is provided it overwrites the version of the PACKAGE object."
(let ((name (if (epl-package-p package)
(epl-package-name package)
package))
(min-version (or min-version (and (epl-package-p package)
(epl-package-version package)))))
(package-installed-p name min-version)))
(defun epl--parse-built-in-entry (entry)
"Parse an ENTRY from the list of built-in packages.
Return the corresponding `epl-package' object."
(if (fboundp 'package--from-builtin)
;; In package-desc package.el, convert the built-in package to a
;; `package-desc' and convert that to an `epl-package'
(epl-package--from-package-desc (package--from-builtin entry))
(epl-package-create :name (car entry) :description (cdr entry))))
(defun epl-built-in-packages ()
"Get all built-in packages.
Return a list of `epl-package' objects."
;; This looks mighty strange, but it's the only way to force package.el to
;; build the list of built-in packages. Without this, `package--builtins'
;; might be empty.
(package-built-in-p 'foo)
(mapcar #'epl--parse-built-in-entry package--builtins))
(defun epl-find-built-in-package (name)
"Find a built-in package with NAME.
NAME is a package name, as symbol.
Return the built-in package as `epl-package' object, or nil if
there is no built-in package with NAME."
(when (package-built-in-p name)
;; We must call `package-built-in-p' *before* inspecting
;; `package--builtins', because otherwise `package--builtins' might be
;; empty.
(epl--parse-built-in-entry (assq name package--builtins))))
(defun epl-package-outdated-p (package)
"Determine whether a PACKAGE is outdated.
A package is outdated, if there is an available package with a
higher version.
PACKAGE is either a package name as symbol, or a package object.
In the former case, test the installed or built-in package with
the highest version number, in the later case, test the package
object itself.
Return t, if the package is outdated, or nil otherwise."
(let* ((package (if (epl-package-p package)
package
(or (car (epl-find-installed-packages package))
(epl-find-built-in-package package))))
(available (car (epl-find-available-packages
(epl-package-name package)))))
(and package available (version-list-< (epl-package-version package)
(epl-package-version available)))))
(defun epl--parse-package-list-entry (entry)
"Parse a list of packages from ENTRY.
ENTRY is a single entry in a package list, e.g. `package-alist',
`package-archive-contents', etc. Typically it is a cons cell,
but the exact format varies between package.el versions. This
function tries to parse all known variants.
Return a list of `epl-package' objects parsed from ENTRY."
(let ((descriptions (cdr entry)))
(cond
((listp descriptions)
(sort (mapcar #'epl-package--from-package-desc descriptions)
#'epl-package-->=))
;; Legacy package.el has just a single package in an entry, which is a
;; standard description vector
((vectorp descriptions)
(list (epl-package-create :name (car entry)
:description descriptions)))
(:else (error "Cannot parse entry %S" entry)))))
(defun epl-installed-packages ()
"Get all installed packages.
Return a list of package objects."
(apply #'append (mapcar #'epl--parse-package-list-entry package-alist)))
(defsubst epl--filter-outdated-packages (packages)
"Filter outdated packages from PACKAGES."
(let (res)
(dolist (package packages)
(when (epl-package-outdated-p package)
(push package res)))
(nreverse res)))
(defun epl-outdated-packages ()
"Get all outdated packages, as in `epl-package-outdated-p'.
Return a list of package objects."
(epl--filter-outdated-packages (epl-installed-packages)))
(defsubst epl--find-package-in-list (name list)
"Find a package by NAME in a package LIST.
Return a list of corresponding `epl-package' objects."
(let ((entry (assq name list)))
(when entry
(epl--parse-package-list-entry entry))))
(defun epl-find-installed-package (name)
"Find the latest installed package by NAME.
NAME is a package name, as symbol.
Return the installed package with the highest version number as
`epl-package' object, or nil, if no package with NAME is
installed."
(car (epl-find-installed-packages name)))
(make-obsolete 'epl-find-installed-package 'epl-find-installed-packages "0.7")
(defun epl-find-installed-packages (name)
"Find all installed packages by NAME.
NAME is a package name, as symbol.
Return a list of all installed packages with NAME, sorted by
version number in descending order. Return nil, if there are no
packages with NAME."
(epl--find-package-in-list name package-alist))
(defun epl-available-packages ()
"Get all packages available for installation.
Return a list of package objects."
(apply #'append (mapcar #'epl--parse-package-list-entry
package-archive-contents)))
(defun epl-find-available-packages (name)
"Find available packages for NAME.
NAME is a package name, as symbol.
Return a list of available packages for NAME, sorted by version
number in descending order. Return nil, if there are no packages
for NAME."
(epl--find-package-in-list name package-archive-contents))
(cl-defstruct (epl-upgrade
(:constructor epl-upgrade-create))
"Structure describing an upgradable package.
Slots:
`installed' The installed package
`available' The package available for installation."
installed
available)
(defun epl-find-upgrades (&optional packages)
"Find all upgradable PACKAGES.
PACKAGES is a list of package objects to upgrade, defaulting to
all installed packages.
Return a list of `epl-upgrade' objects describing all upgradable
packages."
(let ((packages (or packages (epl-installed-packages)))
upgrades)
(dolist (pkg packages)
(let* ((version (epl-package-version pkg))
(name (epl-package-name pkg))
;; Find the latest available package for NAME
(available-pkg (car (epl-find-available-packages name)))
(available-version (when available-pkg
(epl-package-version available-pkg))))
(when (and available-version (version-list-< version available-version))
(push (epl-upgrade-create :installed pkg
:available available-pkg)
upgrades))))
(nreverse upgrades)))
(defalias 'epl-built-in-p 'package-built-in-p)
;;; Package operations
(defun epl-install-file (file)
"Install a package from FILE, like `package-install-file'."
(interactive (advice-eval-interactive-spec
(cadr (interactive-form #'package-install-file))))
(apply #'package-install-file (list file))
(let ((package (epl-package-from-file file)))
(unless (epl-package--package-desc-p package)
(epl--kill-autoload-buffer package))))
(defun epl--kill-autoload-buffer (package)
"Kill the buffer associated with autoloads for PACKAGE."
(let* ((auto-name (format "%s-autoloads.el" (epl-package-name package)))
(generated-autoload-file (expand-file-name auto-name (epl-package-directory package)))
(buf (find-buffer-visiting generated-autoload-file)))
(when buf (kill-buffer buf))))
(defun epl-package-install (package &optional force)
"Install a PACKAGE.
PACKAGE is a `epl-package' object. If FORCE is given and
non-nil, install PACKAGE, even if it is already installed."
(when (or force (not (epl-package-installed-p package)))
(if (epl-package--package-desc-p package)
(package-install (epl-package-description package))
;; The legacy API installs by name. We have no control over versioning,
;; etc.
(package-install (epl-package-name package))
(epl--kill-autoload-buffer package))))
(defun epl-package-delete (package)
"Delete a PACKAGE.
PACKAGE is a `epl-package' object to delete."
;; package-delete allows for packages being trashed instead of fully deleted.
;; Let's prevent his silly behavior
(let ((delete-by-moving-to-trash nil))
;; The byte compiler will warn us that we are calling `package-delete' with
;; the wrong number of arguments, since it can't infer that we guarantee to
;; always call the correct version. Thus we suppress all warnings when
;; calling `package-delete'. I wish there was a more granular way to
;; disable just that specific warning, but it is what it is.
(if (epl-package--package-desc-p package)
(with-no-warnings
(package-delete (epl-package-description package)))
;; The legacy API deletes by name (as string!) and version instead by
;; descriptor. Hence `package-delete' takes two arguments. For some
;; insane reason, the arguments are strings here!
(let ((name (symbol-name (epl-package-name package)))
(version (epl-package-version-string package)))
(with-no-warnings
(package-delete name version))
;; Legacy package.el does not remove the deleted package
;; from the `package-alist', so we do it manually here.
(let ((pkg (assq (epl-package-name package) package-alist)))
(when pkg
(setq package-alist (delq pkg package-alist))))))))
(defun epl-upgrade (&optional packages preserve-obsolete)
"Upgrade PACKAGES.
PACKAGES is a list of package objects to upgrade, defaulting to
all installed packages.
The old versions of the updated packages are deleted, unless
PRESERVE-OBSOLETE is non-nil.
Return a list of all performed upgrades, as a list of
`epl-upgrade' objects."
(let ((upgrades (epl-find-upgrades packages)))
(dolist (upgrade upgrades)
(epl-package-install (epl-upgrade-available upgrade) 'force)
(unless preserve-obsolete
(epl-package-delete (epl-upgrade-installed upgrade))))
upgrades))
(provide 'epl)
;;; epl.el ends here

Binary file not shown.

View file

@ -0,0 +1,127 @@
;;; pkg-info-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path (directory-file-name
(or (file-name-directory #$) (car load-path))))
;;;### (autoloads nil "pkg-info" "pkg-info.el" (0 0 0 0))
;;; Generated autoloads from pkg-info.el
(autoload 'pkg-info-library-original-version "pkg-info" "\
Get the original version in the header of LIBRARY.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no X-Original-Version
header.
See Info node `(elisp)Library Headers' for more information
about library headers.
\(fn LIBRARY &optional SHOW)" t nil)
(autoload 'pkg-info-library-version "pkg-info" "\
Get the version in the header of LIBRARY.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no proper header.
See Info node `(elisp)Library Headers' for more information
about library headers.
\(fn LIBRARY &optional SHOW)" t nil)
(autoload 'pkg-info-defining-library-original-version "pkg-info" "\
Get the original version of the library defining FUNCTION.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header.
\(fn FUNCTION &optional SHOW)" t nil)
(autoload 'pkg-info-defining-library-version "pkg-info" "\
Get the version of the library defining FUNCTION.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header.
\(fn FUNCTION &optional SHOW)" t nil)
(autoload 'pkg-info-package-version "pkg-info" "\
Get the version of an installed PACKAGE.
If SHOW is non-nil, show the version in the minibuffer.
Return the version as list, or nil if PACKAGE is not installed.
\(fn PACKAGE &optional SHOW)" t nil)
(autoload 'pkg-info-version-info "pkg-info" "\
Obtain complete version info for LIBRARY and PACKAGE.
LIBRARY is a symbol denoting a named feature, or a library name
as string. PACKAGE is a symbol denoting an ELPA package. If
omitted or nil, default to LIBRARY.
If SHOW is non-nil, show the version in the minibuffer.
When called interactively, prompt for LIBRARY. When called
interactively with prefix argument, prompt for PACKAGE as well.
Return a string with complete version information for LIBRARY.
This version information contains the version from the headers of
LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
part of. If PACKAGE is not installed, or if the PACKAGE version
is the same as the LIBRARY version, do not include a package
version.
\(fn LIBRARY &optional PACKAGE SHOW)" t nil)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "pkg-info" '("pkg-info-")))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; pkg-info-autoloads.el ends here

View file

@ -0,0 +1,2 @@
;;; -*- no-byte-compile: t -*-
(define-package "pkg-info" "20150517.1143" "Information about packages" '((epl "0.8")) :commit "76ba7415480687d05a4353b27fea2ae02b8d9d61" :keywords '("convenience") :authors '(("Sebastian Wiesner" . "swiesner@lunaryorn.com")) :maintainer '("Sebastian Wiesner" . "swiesner@lunaryorn.com") :url "https://github.com/lunaryorn/pkg-info.el")

View file

@ -0,0 +1,331 @@
;;; pkg-info.el --- Information about packages -*- lexical-binding: t; -*-
;; Copyright (C) 2013-2015 Sebastian Wiesner <swiesner@lunaryorn.com>
;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
;; URL: https://github.com/lunaryorn/pkg-info.el
;; Package-Version: 20150517.1143
;; Keywords: convenience
;; Version: 0.7-cvs
;; Package-Requires: ((epl "0.8"))
;; This file is not part of GNU Emacs.
;; 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 of the License, 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This library extracts information from installed packages.
;;;; Functions:
;; `pkg-info-library-version' extracts the version from the header of a library.
;;
;; `pkg-info-defining-library-version' extracts the version from the header of a
;; library defining a function.
;;
;; `pkg-info-package-version' gets the version of an installed package.
;;
;; `pkg-info-format-version' formats a version list as human readable string.
;;
;; `pkg-info-version-info' returns complete version information for a specific
;; package.
;;
;; `pkg-info-get-melpa-recipe' gets the MELPA recipe for a package.
;;
;; `pkg-info-get-melpa-fetcher' gets the fetcher used to build a package on
;; MELPA.
;;
;; `pkg-info-wiki-package-p' determines whether a package was build from
;; EmacsWiki on MELPA.
;;; Code:
(require 'epl)
(require 'lisp-mnt)
(require 'find-func)
(require 'json) ; `json-read'
(require 'url-http) ; `url-http-parse-response'
(defvar url-http-end-of-headers)
;;; Version information
(defun pkg-info-format-version (version)
"Format VERSION as human-readable string.
Return a human-readable string representing VERSION."
;; XXX: Find a better, more flexible way of formatting?
(package-version-join version))
(defsubst pkg-info--show-version-and-return (version show)
"Show and return VERSION.
When SHOW is non-nil, show VERSION in minibuffer.
Return VERSION."
(when show
(message (if (listp version) (pkg-info-format-version version) version)))
version)
(defun pkg-info--read-library ()
"Read a library from minibuffer."
(completing-read "Load library: "
(apply-partially 'locate-file-completion-table
load-path
(get-load-suffixes))))
(defun pkg-info--read-function ()
"Read a function name from minibuffer."
(let ((input (completing-read "Function: " obarray #'boundp :require-match)))
(if (string= input "") nil (intern input))))
(defun pkg-info--read-package ()
"Read a package name from minibuffer."
(let* ((installed (epl-installed-packages))
(names (sort (mapcar (lambda (pkg)
(symbol-name (epl-package-name pkg)))
installed)
#'string<))
(default (car names)))
(completing-read "Installed package: " names nil 'require-match
nil nil default)))
(defun pkg-info-library-source (library)
"Get the source file of LIBRARY.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
Return the source file of LIBRARY as string."
(find-library-name (if (symbolp library) (symbol-name library) library)))
(defun pkg-info-defining-library (function)
"Get the source file of the library defining FUNCTION.
FUNCTION is a function symbol.
Return the file name of the library as string. Signal an error
if the library does not exist, or if the definition of FUNCTION
was not found."
(unless (functionp function)
(signal 'wrong-type-argument (list 'functionp function)))
(let ((library (symbol-file function 'defun)))
(unless library
(error "Can't find definition of %s" function))
library))
(defun pkg-info-x-original-version (file)
"Read the X-Original-Version header from FILE.
Return the value as version list, or return nil if FILE lacks
this header. Signal an error, if the value of the header is not
a valid version."
(let ((version-str (with-temp-buffer
(insert-file-contents file)
(lm-header "X-Original-Version"))))
(when version-str
(version-to-list version-str))))
;;;###autoload
(defun pkg-info-library-original-version (library &optional show)
"Get the original version in the header of LIBRARY.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no X-Original-Version
header.
See Info node `(elisp)Library Headers' for more information
about library headers."
(interactive (list (pkg-info--read-library) t))
(let ((version (pkg-info-x-original-version
(pkg-info-library-source library))))
(if version
(pkg-info--show-version-and-return version show)
(error "Library %s has no original version" library))))
;;;###autoload
(defun pkg-info-library-version (library &optional show)
"Get the version in the header of LIBRARY.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no proper header.
See Info node `(elisp)Library Headers' for more information
about library headers."
(interactive (list (pkg-info--read-library) t))
(let* ((source (pkg-info-library-source library))
(version (epl-package-version (epl-package-from-file source))))
(pkg-info--show-version-and-return version show)))
;;;###autoload
(defun pkg-info-defining-library-original-version (function &optional show)
"Get the original version of the library defining FUNCTION.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header."
(interactive (list (pkg-info--read-function) t))
(pkg-info-library-original-version (pkg-info-defining-library function) show))
;;;###autoload
(defun pkg-info-defining-library-version (function &optional show)
"Get the version of the library defining FUNCTION.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header."
(interactive (list (pkg-info--read-function) t))
(pkg-info-library-version (pkg-info-defining-library function) show))
;;;###autoload
(defun pkg-info-package-version (package &optional show)
"Get the version of an installed PACKAGE.
If SHOW is non-nil, show the version in the minibuffer.
Return the version as list, or nil if PACKAGE is not installed."
(interactive (list (pkg-info--read-package) t))
(let* ((name (if (stringp package) (intern package) package))
(package (car (epl-find-installed-packages name))))
(unless package
(error "Can't find installed package %s" name))
(pkg-info--show-version-and-return (epl-package-version package) show)))
;;;###autoload
(defun pkg-info-version-info (library &optional package show)
"Obtain complete version info for LIBRARY and PACKAGE.
LIBRARY is a symbol denoting a named feature, or a library name
as string. PACKAGE is a symbol denoting an ELPA package. If
omitted or nil, default to LIBRARY.
If SHOW is non-nil, show the version in the minibuffer.
When called interactively, prompt for LIBRARY. When called
interactively with prefix argument, prompt for PACKAGE as well.
Return a string with complete version information for LIBRARY.
This version information contains the version from the headers of
LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
part of. If PACKAGE is not installed, or if the PACKAGE version
is the same as the LIBRARY version, do not include a package
version."
(interactive (list (pkg-info--read-library)
(when current-prefix-arg
(pkg-info--read-package))
t))
(let* ((package (or package (if (stringp library) (intern library) library)))
(orig-version (condition-case nil
(pkg-info-library-original-version library)
(error nil)))
;; If we have X-Original-Version, we assume that MELPA replaced the
;; library version with its generated version, so we use the
;; X-Original-Version header instead, and ignore the library version
;; header
(lib-version (or orig-version (pkg-info-library-version library)))
(pkg-version (condition-case nil
(pkg-info-package-version package)
(error nil)))
(version (if (and pkg-version
(not (version-list-= lib-version pkg-version)))
(format "%s (package: %s)"
(pkg-info-format-version lib-version)
(pkg-info-format-version pkg-version))
(pkg-info-format-version lib-version))))
(pkg-info--show-version-and-return version show)))
(defconst pkg-info-melpa-recipe-url "http://melpa.org/recipes.json"
"The URL from which to fetch MELPA recipes.")
(defvar pkg-info-melpa-recipes nil
"An alist of MELPA recipes.")
(defun pkg-info-retrieve-melpa-recipes ()
"Retrieve MELPA recipes from MELPA archive."
(let ((buffer (url-retrieve-synchronously pkg-info-melpa-recipe-url)))
(with-current-buffer buffer
(unwind-protect
(let ((response-code (url-http-parse-response)))
(unless (equal response-code 200)
(error "Failed to retrieve MELPA recipes from %s (code %s)"
pkg-info-melpa-recipe-url response-code))
(goto-char url-http-end-of-headers)
(json-read))
(when (and buffer (buffer-live-p buffer))
(kill-buffer buffer))))))
(defun pkg-info-get-melpa-recipes ()
"Get MELPA recipes."
(setq pkg-info-melpa-recipes
(or pkg-info-melpa-recipes
(pkg-info-retrieve-melpa-recipes))))
(defun pkg-info-get-melpa-recipe (package)
"Get the MELPA recipe for PACKAGE.
Return nil if PACKAGE is not on MELPA."
(cdr (assq package (pkg-info-get-melpa-recipes))))
(defun pkg-info-get-melpa-fetcher (package)
"Get the MELPA fetcher for PACKAGE."
(cdr (assq 'fetcher (pkg-info-get-melpa-recipe package))))
(defun pkg-info-wiki-package-p (package)
"Determine whether PACKAGE is build from the EmacsWiki."
(equal (pkg-info-get-melpa-fetcher package) "wiki"))
(provide 'pkg-info)
;; Local Variables:
;; indent-tabs-mode: nil
;; coding: utf-8
;; End:
;;; pkg-info.el ends here

Binary file not shown.

View file

@ -1729,7 +1729,9 @@ Return FALLBACK if non-nil, otherwise the value of
(or (cdr (assq (intern (pm--symbol-name name))
polymode-mode-name-aliases))
name)))
(mname (concat str "-mode")))
(mname (if (string-match-p "-mode$" str)
str
(concat str "-mode"))))
(or
;; direct search
(let ((mode (intern mname)))

Some files were not shown because too many files have changed in this diff Show more