Ihor Radchenko <yanta...@posteo.net> writes: > Tor-björn Claesson <tclaes...@gmail.com> writes: > >> Den tis 12 nov. 2024 kl 20:02 skrev Ihor Radchenko <yanta...@posteo.net>: >>> >>> I am not sure if it is a good idea. >>> Commands in org-cite-basic-follow-actions may or may not need it, while >>> your code will _aways_ prompt user about citation key; even when the >>> citation key is never used. >>> >>> If you realy, really want it, we can go into `cl-symbol-macrolet' and >>> lazy evaluation, but will be tricky (especially arranging for >>> (setq !citation-key ...) to work. >>> >> >> Wouldn't my beginner approach with recursive replacement fix this problem? > > Nope. Mindlessly replacing instances of !citation-key with value may > break the code. Consider, for example, > > (lambda () > (let ((citation! (concat citation! "-foo"))) ...)) > > There will be more complex cases as well. > > `cl-symbol-macrolet' it trying to handle what you tried with recursive > replacement, but more carefully. But even `cl-symbol-macrolet' fails in > certain edge cases.
Ah, then it has to go. Here comes a fixed patch. The code is much simpler like this, but i kept the let under the lambda because for some reason it did not work for me. Also, the interactive clause in the transient, while working, upset make test, but this could be fixed by requiring org-element and quoting citation and citation-reference. Thanks for taking the time to explain! Cheers, Tor-björn
From b0e8d8284df02983804d22378bc8eb018992f42b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor-bj=C3=B6rn=20Claesson?= <tclaesson@gmail.com> Date: Tue, 12 Nov 2024 11:09:16 +0200 Subject: [PATCH] lisp/oc-basic.el: Transient menu for following citations * lisp/oc-basic.el (require 'transient): Pull in transient. (require 'org-element): Pull in org-element. (org-cite-basic-follow-ask): New customization option. should `org-cite-basic-follow' prompt the user for an action? (org-cite-basic-follow-actions): New customization option, that specifies the contents of the transient menu. (org-cite-basic-follow): New function. Displays a menu asking how to follow a citation if `org-cite-basic-follow-ask' is non-nil. Otherwise, it retains the default behaviour of opening the bibliography entry. This can be inversed with a negative prefix argument. (org-cite-basic-follow--parse-suffix-specification and org-cite-basic-follow--setup): Helper functions for `org-cite-basic-follow'. (org-cite-register-processor 'basic): Update the basic citation processor to follow citations using `org-cite-basic-follow'. * etc/ORG_NEWS (Menu for choosing how to follow citations): Describe the new feature (New option ~org-cite-basic-follow-ask~): Describe this new customization option. (New option ~org-cite-basic-follow-actions~): Describe this new customization option, which specifies the layout of the `org-cite-basic-follow' transient menu. This change was co-authored with much support from Ihor Radchenko and Jonas Bernoulli, thanks! --- etc/ORG-NEWS | 22 ++++++++++++ lisp/oc-basic.el | 87 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index de4f11b25..b859b0ada 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -114,6 +114,15 @@ The keybindings in the repeat-maps can be changed by customizing See the new [[info:org#Repeating commands]["Repeating commands"]] section in Org mode manual. +*** Menu for choosing how to follow citations + +Following citations with the org-cite-basic citation backend can now present a +transient menu. To show this menu, set ~org-cite-basic-follow-ask~ to non-nil. +This behaviour can be reversed with a negativ prefix. + +The contents of this menu can be customized in +~org-cite-basic-follow-actions~. + ** New and changed options # Chanes deadling with changing default values of customizations, @@ -158,6 +167,19 @@ English. The default value is ~t~ as the CSL standard assumes that English titles are specified in sentence-case but the bibtex bibliography format requires them to be written in title-case. +*** New option ~org-cite-basic-follow-ask~ + +When this option is non-nil, following a citation with the basic citation +backend will present a transient menu with choices for how to follow the +citation. +If nil, following a citation will open its bibliography entry. + +This behaviour can be reversed with a negative prefix argument. + +*** New option ~org-cite-basic-follow-actions~ + +This option specifies the options presented by ~org-cite-basic-follow~. + ** New functions and changes in function arguments # This also includes changes in function behavior from Elisp perspective. diff --git a/lisp/oc-basic.el b/lisp/oc-basic.el index e207a1997..613c09e27 100644 --- a/lisp/oc-basic.el +++ b/lisp/oc-basic.el @@ -74,6 +74,8 @@ (require 'map) (require 'oc) (require 'seq) +(require 'transient) +(require 'org-element) (declare-function org-open-at-point "org" (&optional arg)) (declare-function org-open-file "org" (path &optional in-emacs line search)) @@ -140,6 +142,30 @@ :type 'face :safe #'facep) +(defcustom org-cite-basic-follow-ask nil + "Should `org-cite-basic' ask how to follow citations? + +When this option is nil, `org-cite-basic-follow' opens the bibliography entry. +Otherwise, `org-cite-basic-follow' will display a transient menu prompting the +user for an action. The contents of this menu can be customized in +`org-cite-basic-follow-actions'." + :group 'org-cite + :package-version '(Org . "9.8") + :type 'boolean) + +(defcustom org-cite-basic-follow-actions + '[["Open" + ("b" "bibliography entry" (org-cite-basic-goto !citation !prefix))]] + "Actions in the `org-cite-basic-follow' transient menu. + +This option uses the same syntax as `transient-define-prefix', see Info node +`(transient)Binding Suffix and Infix Commands'. In addition, it is possible +to specify a function call for the COMMAND part, where !citation and +!prefix can be used to access those values." + :group 'org-cite + :package-version '(Org . "9.8") + :type 'sexp) + ;;; Internal variables (defvar org-cite-basic--bibliography-cache nil @@ -832,6 +858,65 @@ present in the citation." (bibtex-set-dialect) (bibtex-search-entry key))))) +(transient-define-prefix org-cite-basic-follow (citation-object &optional prefix) + "Follow citation. + +If `org-cite-basic-follow-ask' is non-nil, this transient will present +a menu prompting the user for an action. +Otherwise, it will open the bibliography entry for the citation at point. +This behaviour is inverted when the transient is called with a negative prefix +argument. + +The contents of the menu are defined in the variable +`org-cite-basic-follow-actions'." + [:class transient-columns + :setup-children org-cite-basic-follow--setup + :pad-keys t] + (interactive + (list (let ((obj (org-element-context))) + (pcase (org-element-type obj) + ((or 'citation 'citation-reference) obj) + (_ (user-error "No citation at point")))))) + (if (xor org-cite-basic-follow-ask + (equal prefix '(-4))) + (transient-setup 'org-cite-basic-follow nil nil + :scope (list citation-object prefix)) + (org-cite-basic-goto citation-object prefix))) + +(defun org-cite-basic-follow--parse-suffix-specification (specification) + "Handle special syntax for `org-cite-basic-follow-actions'." + (pcase specification + (`(,key ,desc (lambda ,args . ,fn-args) . ,other) + `(,key ,desc + (lambda ,args + ,(unless (and (listp (car fn-args)) + (equal (caar fn-args) + 'interactive)) + '(interactive)) + (let ((!citation (car (transient-scope))) + (!prefix (cadr (transient-scope)))) + ,@fn-args)) + ,@other)) + (`(,key ,desc (,fn . ,fn-args) . ,other) + `(,key ,desc + (lambda () + (interactive) + (let ((!citation (car (transient-scope))) + (!prefix (cadr (transient-scope)))) + (,fn ,@fn-args))) + ,@other)) + (other other))) + +(defun org-cite-basic-follow--setup (_) + "Update `org-cite-basic-follow' when `org-cite-basic-follow-actions' changes." + (transient-parse-suffixes + 'org-cite-basic-follow + (cl-map 'vector + (lambda (group) + (cl-map 'vector #'org-cite-basic-follow--parse-suffix-specification + group)) + org-cite-basic-follow-actions))) + ;;; "Insert" capability (defun org-cite-basic--complete-style (_) @@ -920,7 +1005,7 @@ Raise an error when no bibliography is set in the buffer." :activate #'org-cite-basic-activate :export-citation #'org-cite-basic-export-citation :export-bibliography #'org-cite-basic-export-bibliography - :follow #'org-cite-basic-goto + :follow #'org-cite-basic-follow :insert (org-cite-make-insert-processor #'org-cite-basic--complete-key #'org-cite-basic--complete-style) :cite-styles -- 2.46.0