branch: externals/org
commit fe92a3cedba541482d5954eacb2b13e6f57a39c4
Author: Ihor Radchenko <[email protected]>
Commit: Ihor Radchenko <[email protected]>
Provide a uniform way to inform users about missing third-party packages
* lisp/org-macs.el (org-require-package): New macro trying to load a
library and displaying custom error message or warning on failure.
The actual package (not library) name can be provided as optional
argument.
* lisp/ob-R.el (org-babel-R-initiate-session):
* lisp/ob-clojure.el (ob-clojure-eval-with-inf-clojure):
(ob-clojure-eval-with-cider):
(ob-clojure-eval-with-slime):
* lisp/ob-forth.el (org-babel-forth-session-execute):
* lisp/ob-gnuplot.el (org-babel-execute:gnuplot):
(org-babel-gnuplot-initiate-session):
* lisp/ob-haskell.el (org-babel-interpret-haskell):
(org-babel-haskell-initiate-session):
* lisp/ob-js.el (org-babel-execute:js):
(org-babel-js-initiate-session):
* lisp/ob-julia.el (org-babel-julia-initiate-session):
* lisp/ob-lisp.el (org-babel-execute:lisp):
* lisp/ob-ocaml.el (org-babel-prep-session:ocaml):
* lisp/ob-octave.el (org-babel-octave-initiate-session):
* lisp/ob-processing.el (org-babel-processing-view-sketch):
* lisp/ob-ruby.el (org-babel-execute:ruby):
(org-babel-ruby-initiate-session):
* lisp/ol-bbdb.el (org-bbdb-open):
(org-bbdb-complete-link):
(org-bbdb-anniv-export-ical):
* lisp/org-agenda.el:
* lisp/org-plot.el (org-plot/gnuplot):
* lisp/org.el:
* lisp/ox-ascii.el (org-ascii-table):
* lisp/ox-html.el (org-html-htmlize-generate-css):
* lisp/ox-org.el: Use the new macro.
* lisp/oc-csl.el: Add FIXME. oc-csl uses a custom function doing
similar job.
* lisp/ob-js.el (org-babel-js-initiate-session): Add FIXME noting that
the third-party package is outdated.
---
lisp/ob-R.el | 2 +-
lisp/ob-clojure.el | 9 +++------
lisp/ob-forth.el | 2 +-
lisp/ob-gnuplot.el | 4 ++--
lisp/ob-haskell.el | 4 ++--
lisp/ob-js.el | 10 ++++++----
lisp/ob-julia.el | 3 ++-
lisp/ob-lisp.el | 6 +++---
lisp/ob-ocaml.el | 2 +-
lisp/ob-octave.el | 6 ++++--
lisp/ob-processing.el | 2 +-
lisp/ob-ruby.el | 4 ++--
lisp/oc-csl.el | 1 +
lisp/ol-bbdb.el | 8 ++++----
lisp/org-agenda.el | 3 +--
lisp/org-macs.el | 9 +++++++++
lisp/org-plot.el | 2 +-
lisp/org.el | 2 +-
lisp/ox-ascii.el | 2 +-
lisp/ox-html.el | 3 +--
lisp/ox-org.el | 3 +--
21 files changed, 48 insertions(+), 39 deletions(-)
diff --git a/lisp/ob-R.el b/lisp/ob-R.el
index 4ee091118e..2d22a4657a 100644
--- a/lisp/ob-R.el
+++ b/lisp/ob-R.el
@@ -276,7 +276,7 @@ This function is called by `org-babel-execute-src-block'."
(when (get-buffer session)
;; Session buffer exists, but with dead process
(set-buffer session))
- (require 'ess) (R)
+ (org-require-package 'ess "ESS") (R)
(let ((R-proc (get-process (or ess-local-process-name
ess-current-process-name))))
(while (process-get R-proc 'callbacks)
diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index d993e0cb79..5f589db00d 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -186,8 +186,7 @@ or set the `:backend' header argument"))))
(defvar inf-clojure-comint-prompt-regexp)
(defun ob-clojure-eval-with-inf-clojure (expanded params)
"Evaluate EXPANDED code block with PARAMS using inf-clojure."
- (condition-case nil (require 'inf-clojure)
- (user-error "inf-clojure not available"))
+ (org-require-package 'inf-clojure)
;; Maybe initiate the inf-clojure session
(unless (and inf-clojure-buffer
(buffer-live-p (get-buffer inf-clojure-buffer)))
@@ -228,8 +227,7 @@ or set the `:backend' header argument"))))
(defun ob-clojure-eval-with-cider (expanded params)
"Evaluate EXPANDED code block with PARAMS using cider."
- (condition-case nil (require 'cider)
- (user-error "cider not available"))
+ (org-require-package 'cider "Cider")
(let ((connection (cider-current-connection (cdr (assq :target params))))
(result-params (cdr (assq :result-params params)))
result0)
@@ -256,8 +254,7 @@ or set the `:backend' header argument"))))
(defun ob-clojure-eval-with-slime (expanded params)
"Evaluate EXPANDED code block with PARAMS using slime."
- (condition-case nil (require 'slime)
- (user-error "slime not available"))
+ (org-require-package 'slime "SLIME")
(with-temp-buffer
(insert expanded)
(slime-eval
diff --git a/lisp/ob-forth.el b/lisp/ob-forth.el
index e5dcad6d03..bd9ec04a4c 100644
--- a/lisp/ob-forth.el
+++ b/lisp/ob-forth.el
@@ -55,7 +55,7 @@ This function is called by `org-babel-execute-src-block'."
(car (last all-results))))))
(defun org-babel-forth-session-execute (body params)
- (require 'forth-mode)
+ (org-require-package 'forth-mode)
(let ((proc (forth-proc))
(rx " \\(\n:\\|compiled\n\\|ok\n\\)")
(result-start))
diff --git a/lisp/ob-gnuplot.el b/lisp/ob-gnuplot.el
index e3e42918c7..79770c7fd2 100644
--- a/lisp/ob-gnuplot.el
+++ b/lisp/ob-gnuplot.el
@@ -198,7 +198,7 @@ code."
(defun org-babel-execute:gnuplot (body params)
"Execute a block of Gnuplot code.
This function is called by `org-babel-execute-src-block'."
- (require 'gnuplot)
+ (org-require-package 'gnuplot)
(let ((session (cdr (assq :session params)))
(result-type (cdr (assq :results params)))
(body (org-babel-expand-body:gnuplot body params))
@@ -262,7 +262,7 @@ This function is called by `org-babel-execute-src-block'."
If there is not a current inferior-process-buffer in SESSION
then create one. Return the initialized session. The current
`gnuplot-mode' doesn't provide support for multiple sessions."
- (require 'gnuplot)
+ (org-require-package 'gnuplot)
(unless (string= session "none")
(save-window-excursion
(gnuplot-send-string-to-gnuplot "" "line")
diff --git a/lisp/ob-haskell.el b/lisp/ob-haskell.el
index 7185ed61ff..2b1441c2a8 100644
--- a/lisp/ob-haskell.el
+++ b/lisp/ob-haskell.el
@@ -122,7 +122,7 @@ a parameter, such as \"ghc -v\"."
(cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))))
(defun org-babel-interpret-haskell (body params)
- (require 'inf-haskell)
+ (org-require-package 'inf-haskell "haskell-mode")
(add-hook 'inferior-haskell-hook
(lambda ()
(setq-local comint-prompt-regexp
@@ -167,7 +167,7 @@ a parameter, such as \"ghc -v\"."
"Initiate a haskell session.
If there is not a current inferior-process-buffer in SESSION
then create one. Return the initialized session."
- (require 'inf-haskell)
+ (org-require-package 'inf-haskell "haskell-mode")
(or (get-buffer "*haskell*")
(save-window-excursion (run-haskell) (sleep-for 0.25) (current-buffer))))
diff --git a/lisp/ob-js.el b/lisp/ob-js.el
index 910c116866..e19a6e5436 100644
--- a/lisp/ob-js.el
+++ b/lisp/ob-js.el
@@ -96,7 +96,7 @@ This function is called by `org-babel-execute-src-block'."
;; Indium Node REPL. Separate case because Indium
;; REPL is not inherited from Comint mode.
((string= session "*JS REPL*")
- (require 'indium-repl)
+ (org-require-package 'indium-repl "indium")
(unless (get-buffer session)
(indium-run-node org-babel-js-cmd))
(indium-eval full-body))
@@ -168,7 +168,7 @@ Return the initialized session."
((string= session "none")
(warn "Session evaluation of ob-js is not supported"))
((string= "*skewer-repl*" session)
- (require 'skewer-repl)
+ (org-require-package 'skewer-repl "skewer-mode")
(let ((session-buffer (get-buffer "*skewer-repl*")))
(if (and session-buffer
(org-babel-comint-buffer-livep (get-buffer session-buffer))
@@ -180,7 +180,7 @@ Return the initialized session."
(skewer-repl)
session-buffer)))
((string= "*Javascript REPL*" session)
- (require 'js-comint)
+ (org-require-package 'js-comint)
(let ((session-buffer "*Javascript REPL*"))
(if (and (org-babel-comint-buffer-livep (get-buffer session-buffer))
(comint-check-proc session-buffer))
@@ -189,7 +189,9 @@ Return the initialized session."
(sit-for .5)
session-buffer)))
((string= "mozrepl" org-babel-js-cmd)
- (require 'moz)
+ ;; FIXME: According to https://github.com/bard/mozrepl, this REPL
+ ;; is outdated and does not work for Firefox >54.
+ (org-require-package 'moz "mozrepl")
(let ((session-buffer (save-window-excursion
(run-mozilla nil)
(rename-buffer session)
diff --git a/lisp/ob-julia.el b/lisp/ob-julia.el
index cb5c7fa3b0..495169da1b 100644
--- a/lisp/ob-julia.el
+++ b/lisp/ob-julia.el
@@ -196,7 +196,8 @@ end"
(when (get-buffer session)
;; Session buffer exists, but with dead process
(set-buffer session))
- (require 'ess) (set-buffer (julia))
+ (org-require-package 'ess "ESS")
+ (set-buffer (julia))
(rename-buffer
(if (bufferp session)
(buffer-name session)
diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el
index 048ef883ca..03f23c82df 100644
--- a/lisp/ob-lisp.el
+++ b/lisp/ob-lisp.el
@@ -90,9 +90,9 @@ current directory string."
"Execute a block of Common Lisp code with Babel.
BODY is the contents of the block, as a string. PARAMS is
a property list containing the parameters of the block."
- (require (pcase org-babel-lisp-eval-fn
- (`slime-eval 'slime)
- (`sly-eval 'sly)))
+ (pcase org-babel-lisp-eval-fn
+ (`slime-eval (org-require-package 'slime "SLIME"))
+ (`sly-eval (org-require-package 'sly "SLY")))
(org-babel-reassemble-table
(let ((result
(funcall (if (member "output" (cdr (assq :result-params params)))
diff --git a/lisp/ob-ocaml.el b/lisp/ob-ocaml.el
index 09224b98ba..4ab58e1504 100644
--- a/lisp/ob-ocaml.el
+++ b/lisp/ob-ocaml.el
@@ -109,7 +109,7 @@
(defvar tuareg-interactive-buffer-name)
(defun org-babel-prep-session:ocaml (session _params)
"Prepare SESSION according to the header arguments in PARAMS."
- (require 'tuareg)
+ (org-require-package 'tuareg)
(let ((tuareg-interactive-buffer-name (if (and (not (string= session "none"))
(not (string= session
"default"))
(stringp session))
diff --git a/lisp/ob-octave.el b/lisp/ob-octave.el
index 1de263a52d..56559cbb8e 100644
--- a/lisp/ob-octave.el
+++ b/lisp/ob-octave.el
@@ -154,8 +154,10 @@ create. Return the initialized session."
"Create an octave inferior process buffer.
If there is not a current inferior-process-buffer in SESSION then
create. Return the initialized session."
- (if matlabp (require 'matlab) (or (require 'octave-inf nil 'noerror)
- (require 'octave)))
+ (if matlabp
+ (org-require-package 'matlab "matlab-mode")
+ (or (require 'octave-inf nil 'noerror)
+ (require 'octave)))
(unless (string= session "none")
(let ((session (or session
(if matlabp "*Inferior Matlab*" "*Inferior Octave*"))))
diff --git a/lisp/ob-processing.el b/lisp/ob-processing.el
index 4eeaf98e0a..460e6e3818 100644
--- a/lisp/ob-processing.el
+++ b/lisp/ob-processing.el
@@ -78,7 +78,7 @@
(defun org-babel-processing-view-sketch ()
"Show the sketch of the Processing block under point in an external viewer."
(interactive)
- (require 'processing-mode)
+ (org-require-package 'processing-mode)
(let ((info (org-babel-get-src-block-info)))
(if (string= (nth 0 info) "processing")
(let* ((body (nth 1 info))
diff --git a/lisp/ob-ruby.el b/lisp/ob-ruby.el
index b94bc73dd7..ba8697731c 100644
--- a/lisp/ob-ruby.el
+++ b/lisp/ob-ruby.el
@@ -86,7 +86,7 @@ This function is called by `org-babel-execute-src-block'."
body params (org-babel-variable-assignments:ruby params)))
(result (if (member "xmp" result-params)
(with-temp-buffer
- (require 'rcodetools)
+ (org-require-package 'rcodetools "rcodetools (gem
package)")
(insert full-body)
(xmp (cdr (assq :xmp-option params)))
(buffer-string))
@@ -161,7 +161,7 @@ Emacs-lisp table, otherwise return the results as a string."
If there is not a current inferior-process-buffer in SESSION
then create one. Return the initialized session."
(unless (string= session "none")
- (require 'inf-ruby)
+ (org-require-package 'inf-ruby)
(let* ((command (cdr (or (assq :ruby params)
(assoc inf-ruby-default-implementation
inf-ruby-implementations))))
diff --git a/lisp/oc-csl.el b/lisp/oc-csl.el
index 432738a97f..94c2ed94ca 100644
--- a/lisp/oc-csl.el
+++ b/lisp/oc-csl.el
@@ -417,6 +417,7 @@ Label is in match group 1.")
;;; Internal functions
+;; FIXME: We use `org-require-package' in other places.
(defun org-cite-csl--barf-without-citeproc ()
"Raise an error if Citeproc library is not loaded."
(unless (featurep 'citeproc)
diff --git a/lisp/ol-bbdb.el b/lisp/ol-bbdb.el
index 47bd9d98cb..915d83df29 100644
--- a/lisp/ol-bbdb.el
+++ b/lisp/ol-bbdb.el
@@ -255,7 +255,7 @@ italicized, in all other cases it is left unchanged."
(defun org-bbdb-open (name _)
"Follow a BBDB link to NAME."
- (require 'bbdb-com)
+ (org-require-package 'bbdb-com "bbdb")
(let ((inhibit-redisplay (not debug-on-error)))
(if (fboundp 'bbdb-name)
(org-bbdb-open-old name)
@@ -369,7 +369,7 @@ This is used by Org to re-create the anniversary hash
table."
"Extract anniversaries from BBDB for display in the agenda.
When called programmatically, this function expects the `date'
variable to be globally bound."
- (require 'bbdb)
+ (org-require-package 'bbdb)
(require 'diary-lib)
(unless (hash-table-p org-bbdb-anniv-hash)
(setq org-bbdb-anniv-hash
@@ -500,7 +500,7 @@ must be positive"))
(defun org-bbdb-complete-link ()
"Read a bbdb link with name completion."
- (require 'bbdb-com)
+ (org-require-package 'bbdb-com "bbdb")
(let ((rec (bbdb-completing-read-record "Name: ")))
(concat "bbdb:"
(bbdb-record-name (if (listp rec)
@@ -509,7 +509,7 @@ must be positive"))
(defun org-bbdb-anniv-export-ical ()
"Extract anniversaries from BBDB and convert them to icalendar format."
- (require 'bbdb)
+ (org-require-package 'bbdb)
(require 'diary-lib)
(unless (hash-table-p org-bbdb-anniv-hash)
(setq org-bbdb-anniv-hash
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 8fd5ad2439..7e54121dcf 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -3635,8 +3635,7 @@ the agenda to write."
(kill-buffer (current-buffer))
(message "Org file written to %s" file)))
((member extension '("html" "htm"))
- (or (require 'htmlize nil t)
- (error "Please install htmlize from
https://github.com/hniksic/emacs-htmlize"))
+ (org-require-package 'htmlize)
(declare-function htmlize-buffer "htmlize" (&optional buffer))
(set-buffer (htmlize-buffer (current-buffer)))
(when org-agenda-export-html-style
diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 8761404512..c7f9d5364e 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -107,6 +107,15 @@ Version mismatch is commonly encountered in the following
situations:
;;; Macros
+(defmacro org-require-package (symbol &optional name noerror)
+ "Try to load library SYMBOL and display error otherwise.
+With optional parameter NAME, use NAME as package name instead of
+SYMBOL. Show warning instead of error when NOERROR is non-nil."
+ `(unless (require ,symbol nil t)
+ (,(if noerror 'warn 'user-error)
+ "`%s' failed to load required package \"%s\""
+ this-command ,(or name symbol))))
+
(defmacro org-with-gensyms (symbols &rest body)
(declare (debug (sexp body)) (indent 1))
`(let ,(mapcar (lambda (s)
diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index fe61e9ace7..d39ffc4b47 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -641,7 +641,7 @@ manner suitable for prepending to a user-specified script."
If not given options will be taken from the +PLOT
line directly before or after the table."
(interactive)
- (require 'gnuplot)
+ (org-require-package 'gnuplot)
(save-window-excursion
(delete-other-windows)
(when (get-buffer "*gnuplot*") ; reset *gnuplot* if it already running
diff --git a/lisp/org.el b/lisp/org.el
index 4d12084d94..cc2c09e3a9 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -15449,7 +15449,7 @@ in Org mode.
\\{org-cdlatex-mode-map}"
:lighter " OCDL"
(when org-cdlatex-mode
- (require 'cdlatex)
+ (org-require-package 'cdlatex)
(run-hooks 'cdlatex-mode-hook)
(cdlatex-compute-tables))
(unless org-cdlatex-texmathp-advice-is-done
diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el
index 9c4424b14f..e5bdf92cba 100644
--- a/lisp/ox-ascii.el
+++ b/lisp/ox-ascii.el
@@ -1856,7 +1856,7 @@ contextual information."
(cond ((eq (org-element-property :type table) 'org) contents)
((and (plist-get info :ascii-table-use-ascii-art)
(eq (plist-get info :ascii-charset) 'utf-8)
- (require 'ascii-art-to-unicode nil t))
+ (org-require-package 'ascii-art-to-unicode nil 'noerror))
(with-temp-buffer
(insert (org-remove-indentation
(org-element-property :value table)))
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 5e58ccba3f..37c4744096 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -1823,8 +1823,7 @@ If you then set `org-html-htmlize-output-type' to `css',
calls
to the function `org-html-htmlize-region-for-paste' will
produce code that uses these same face definitions."
(interactive)
- (unless (require 'htmlize nil t)
- (error "htmlize library missing. Aborting"))
+ (org-require-package 'htmlize)
(and (get-buffer "*html*") (kill-buffer "*html*"))
(with-temp-buffer
(let ((fl (face-list))
diff --git a/lisp/ox-org.el b/lisp/ox-org.el
index ed72cf4f2b..9329eb1599 100644
--- a/lisp/ox-org.el
+++ b/lisp/ox-org.el
@@ -320,8 +320,7 @@ publishing directory.
Return output file name."
(org-publish-org-to 'org filename ".org" plist pub-dir)
(when (plist-get plist :htmlized-source)
- (or (require 'htmlize nil t)
- (error "Please install htmlize from
https://github.com/hniksic/emacs-htmlize"))
+ (org-require-package 'htmlize)
(require 'ox-html)
(let* ((org-inhibit-startup t)
(htmlize-output-type 'css)