mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-09-29 22:37:47 +00:00
ol: Extend open tooling in link parameters
* lisp/ol.el (org-link-parameters): Extend :follow parameter to handle a second argument. (org-link-open): Call custom-link functions after internal ones. (org-link-open-as-file): New function. (org-link-parameters): Reference new function. (org-link-open): Use new function.
This commit is contained in:
parent
ab9166ad29
commit
afd3b04ecc
21
etc/ORG-NEWS
21
etc/ORG-NEWS
|
@ -20,6 +20,21 @@ otherwise the result is None. Also, None will now show up under
|
||||||
"#+RESULTS:", as it already did with ~:results value~ for non-session
|
"#+RESULTS:", as it already did with ~:results value~ for non-session
|
||||||
blocks.
|
blocks.
|
||||||
|
|
||||||
|
*** Calling conventions changes when opening or exporting custom links
|
||||||
|
|
||||||
|
This changes affects export back-ends, and libraries providing new
|
||||||
|
link types.
|
||||||
|
|
||||||
|
Function used in ~:follow~ link parameter is required to accept
|
||||||
|
a second argument. Likewise, function used in ~:export~ parameter
|
||||||
|
needs to accept a fourth argument. See ~org-link-set-parameters~ for
|
||||||
|
details.
|
||||||
|
|
||||||
|
Eventually, the function ~org-export-custom-protocol-maybe~ is now
|
||||||
|
called with a fourth argument. Even though the 3-arguments definition
|
||||||
|
is still supported, at least for now, we encourage back-end developers
|
||||||
|
to switch to the new signature.
|
||||||
|
|
||||||
*** In HTML export, change on how outline-container-* is set
|
*** In HTML export, change on how outline-container-* is set
|
||||||
|
|
||||||
When the headline has a =CUSTOM_ID=, use this custom id to build the
|
When the headline has a =CUSTOM_ID=, use this custom id to build the
|
||||||
|
@ -122,6 +137,12 @@ When this startup option is set, display headings as numeroted.
|
||||||
|
|
||||||
Use =#+startup: nonum= to turn this off.
|
Use =#+startup: nonum= to turn this off.
|
||||||
|
|
||||||
|
*** New tools for custom links
|
||||||
|
|
||||||
|
Org provides two new tools, ~org-link-open-as-file~ and
|
||||||
|
~org-export-link-as-file~, useful when defining new link types similar
|
||||||
|
to "file"-type links. See docstring for details.
|
||||||
|
|
||||||
*** =ob-clojure.el= supports inf-clojure.el and ClojureScript evaluation
|
*** =ob-clojure.el= supports inf-clojure.el and ClojureScript evaluation
|
||||||
|
|
||||||
You can now set ~(setq org-babel-clojure-backend 'inf-clojure)~ and
|
You can now set ~(setq org-babel-clojure-backend 'inf-clojure)~ and
|
||||||
|
|
133
lisp/ol.el
133
lisp/ol.el
|
@ -98,8 +98,12 @@ below.
|
||||||
|
|
||||||
`:follow'
|
`:follow'
|
||||||
|
|
||||||
Function that takes the link path (a string) as an argument and
|
Function used to follow the link, when the `org-open-at-point'
|
||||||
\"opens\" the link.
|
command runs on it. It is called with two arguments: the path,
|
||||||
|
as a string, and a universal prefix argument.
|
||||||
|
|
||||||
|
Here, you may use `org-link-open-as-file' helper function for
|
||||||
|
types similar to \"file\".
|
||||||
|
|
||||||
`:export'
|
`:export'
|
||||||
|
|
||||||
|
@ -991,60 +995,52 @@ for internal and \"file\" links, or stored as a parameter in
|
||||||
`org-link-parameters', which see."
|
`org-link-parameters', which see."
|
||||||
(let ((type (org-element-property :type link))
|
(let ((type (org-element-property :type link))
|
||||||
(path (org-element-property :path link)))
|
(path (org-element-property :path link)))
|
||||||
(cond
|
(pcase type
|
||||||
((member type '("file" "attachment"))
|
;; Opening a "file" link requires special treatment since we
|
||||||
(when (string= type "attachment")
|
;; first need to integrate search option, if any.
|
||||||
(setq path (org-attach-link-expand link)))
|
((or "file" "attachment")
|
||||||
(if (string-match "[*?{]" (file-name-nondirectory path))
|
(when (string= type "attachment")
|
||||||
(dired path)
|
(setq path (org-attach-link-expand link)))
|
||||||
;; Look into `org-link-parameters' in order to find
|
(let* ((option (org-element-property :search-option link))
|
||||||
;; a DEDICATED-FUNCTION to open file. The function will be
|
(path (if option (concat path "::" option) path)))
|
||||||
;; applied on raw link instead of parsed link due to the
|
(org-link-open-as-file path
|
||||||
;; limitation in `org-add-link-type' ("open" function called
|
(pcase (org-element-property :application link)
|
||||||
;; with a single argument). If no such function is found,
|
((guard arg) arg)
|
||||||
;; fallback to `org-open-file'.
|
("emacs" 'emacs)
|
||||||
(let* ((option (org-element-property :search-option link))
|
("sys" 'system)))))
|
||||||
(app (org-element-property :application link))
|
;; Internal links.
|
||||||
(dedicated-function
|
((or "coderef" "custom-id" "fuzzy" "radio")
|
||||||
(org-link-get-parameter (if app (concat type "+" app) type)
|
(unless (run-hook-with-args-until-success 'org-open-link-functions path)
|
||||||
:follow)))
|
(if (not arg) (org-mark-ring-push)
|
||||||
(if dedicated-function
|
(switch-to-buffer-other-window (org-link--buffer-for-internals)))
|
||||||
(funcall dedicated-function
|
(let ((destination
|
||||||
(concat path
|
(org-with-wide-buffer
|
||||||
(and option (concat "::" option))))
|
(if (equal type "radio")
|
||||||
(apply #'org-open-file
|
(org-link--search-radio-target path)
|
||||||
path
|
(org-link-search
|
||||||
(cond (arg)
|
(pcase type
|
||||||
((equal app "emacs") 'emacs)
|
("custom-id" (concat "#" path))
|
||||||
((equal app "sys") 'system))
|
("coderef" (format "(%s)" path))
|
||||||
(cond ((not option) nil)
|
(_ path))
|
||||||
((string-match-p "\\`[0-9]+\\'" option)
|
;; Prevent fuzzy links from matching themselves.
|
||||||
(list (string-to-number option)))
|
(and (equal type "fuzzy")
|
||||||
(t (list nil option))))))))
|
(+ 2 (org-element-property :begin link)))))
|
||||||
((functionp (org-link-get-parameter type :follow))
|
(point))))
|
||||||
(funcall (org-link-get-parameter type :follow) path))
|
(unless (and (<= (point-min) destination)
|
||||||
((member type '("coderef" "custom-id" "fuzzy" "radio"))
|
(>= (point-max) destination))
|
||||||
(unless (run-hook-with-args-until-success 'org-open-link-functions path)
|
(widen))
|
||||||
(if (not arg) (org-mark-ring-push)
|
(goto-char destination))))
|
||||||
(switch-to-buffer-other-window (org-link--buffer-for-internals)))
|
(_
|
||||||
(let ((destination
|
;; Look for a dedicated "follow" function in custom links.
|
||||||
(org-with-wide-buffer
|
(let ((f (org-link-get-parameter type :follow)))
|
||||||
(if (equal type "radio")
|
(when (functionp f)
|
||||||
(org-link--search-radio-target path)
|
;; Function defined in `:follow' parameter may use a single
|
||||||
(org-link-search
|
;; argument, as it was mandatory before Org 9.4. This is
|
||||||
(pcase type
|
;; deprecated, but support it for now.
|
||||||
("custom-id" (concat "#" path))
|
(condition-case nil
|
||||||
("coderef" (format "(%s)" path))
|
(funcall (org-link-get-parameter type :follow) path arg)
|
||||||
(_ path))
|
(wrong-number-of-arguments
|
||||||
;; Prevent fuzzy links from matching themselves.
|
(funcall (org-link-get-parameter type :follow) path)))))))))
|
||||||
(and (equal type "fuzzy")
|
|
||||||
(+ 2 (org-element-property :begin link)))))
|
|
||||||
(point))))
|
|
||||||
(unless (and (<= (point-min) destination)
|
|
||||||
(>= (point-max) destination))
|
|
||||||
(widen))
|
|
||||||
(goto-char destination))))
|
|
||||||
(t (browse-url-at-point)))))
|
|
||||||
|
|
||||||
(defun org-link-open-from-string (s &optional arg)
|
(defun org-link-open-from-string (s &optional arg)
|
||||||
"Open a link in the string S, as if it was in Org mode.
|
"Open a link in the string S, as if it was in Org mode.
|
||||||
|
@ -1242,6 +1238,28 @@ of matched result, which is either `dedicated' or `fuzzy'."
|
||||||
(reverse slines))) "\n")))))
|
(reverse slines))) "\n")))))
|
||||||
(mapconcat #'identity (split-string s) " ")))
|
(mapconcat #'identity (split-string s) " ")))
|
||||||
|
|
||||||
|
(defun org-link-open-as-file (path arg)
|
||||||
|
"Pretend PATH is a file name and open it.
|
||||||
|
|
||||||
|
According to \"file\"-link syntax, PATH may include additional
|
||||||
|
search options, separated from the file name with \"::\".
|
||||||
|
|
||||||
|
This function is meant to be used as a possible tool for
|
||||||
|
`:follow' property in `org-link-parameters'."
|
||||||
|
(if (string-match "[*?{]" (file-name-nondirectory path))
|
||||||
|
(dired path)
|
||||||
|
(let* ((option (and (string-match "::\\(.*\\)\\'" path)
|
||||||
|
(match-string 1 path)))
|
||||||
|
(path (if (not option) path
|
||||||
|
(substring path 0 (match-beginning 0)))))
|
||||||
|
(apply #'org-open-file
|
||||||
|
path
|
||||||
|
arg
|
||||||
|
(cond ((not option) nil)
|
||||||
|
((string-match-p "\\`[0-9]+\\'" option)
|
||||||
|
(list (string-to-number option)))
|
||||||
|
(t (list nil option)))))))
|
||||||
|
|
||||||
(defun org-link-display-format (s)
|
(defun org-link-display-format (s)
|
||||||
"Replace links in string S with their description.
|
"Replace links in string S with their description.
|
||||||
If there is no description, use the link target."
|
If there is no description, use the link target."
|
||||||
|
@ -1304,7 +1322,8 @@ PATH is a symbol name, as a string."
|
||||||
(dolist (scheme '("ftp" "http" "https" "mailto" "news"))
|
(dolist (scheme '("ftp" "http" "https" "mailto" "news"))
|
||||||
(org-link-set-parameters scheme
|
(org-link-set-parameters scheme
|
||||||
:follow
|
:follow
|
||||||
(lambda (url) (browse-url (concat scheme ":" url)))))
|
(lambda (url arg)
|
||||||
|
(browse-url (concat scheme ":" url) arg))))
|
||||||
|
|
||||||
;;;; "shell" link type
|
;;;; "shell" link type
|
||||||
(defun org-link--open-shell (path)
|
(defun org-link--open-shell (path)
|
||||||
|
|
Loading…
Reference in a new issue