org-footnote-new: Do not throw an error at bol for inline/anonymous footnotes

* lisp/org-footnote.el (org-footnote--allow-reference-p): New optional
argument indicating that the footnote reference is going to be
anonymous/inline.  It is then allowed to be at bol.
(org-footnote-new): Check whether a footnote reference can be inserted
in place taking into account the footnote type.
* testing/lisp/test-org-footnote.el (test-org-footnote/new): New test
cases.

Reported-by: Suhail Singh <suhailsingh247@gmail.com>
Link: https://orgmode.org/list/877carzufa.fsf@gmail.com
This commit is contained in:
Ihor Radchenko 2024-10-13 10:51:50 +02:00
parent b6a72e134d
commit b6dbf88810
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
2 changed files with 25 additions and 5 deletions

View File

@ -248,13 +248,16 @@ otherwise."
;;;; Internal functions
(defun org-footnote--allow-reference-p ()
"Non-nil when a footnote reference can be inserted at point."
(defun org-footnote--allow-reference-p (&optional inline)
"Non-nil when a footnote reference can be inserted at point.
When optional argument INLINE is non-nil, assume that the footnote
reference is an inline or anonymous footnote (and can be placed at the
beginning of the line)."
;; XXX: This is similar to `org-footnote-in-valid-context-p' but
;; more accurate and usually faster, except in some corner cases.
;; It may replace it after doing proper benchmarks as it would be
;; used in fontification.
(unless (bolp)
(unless (and (not inline) (bolp))
(let* ((context (org-element-context))
(type (org-element-type context)))
(cond
@ -665,8 +668,6 @@ This command prompts for a label. If this is a label referencing an
existing label, only insert the label. If the footnote label is empty
or new, let the user edit the definition of the footnote."
(interactive)
(unless (org-footnote--allow-reference-p)
(user-error "Cannot insert a footnote here"))
(let* ((all (org-footnote-all-labels))
(label
(unless (eq org-footnote-auto-label 'anonymous)
@ -680,16 +681,24 @@ or new, let the user edit the definition of the footnote."
(mapcar #'list all) nil nil
(and (eq org-footnote-auto-label 'confirm) propose)))))))))
(cond ((not label)
(unless (org-footnote--allow-reference-p 'anonymous)
(user-error "Cannot insert a footnote here"))
(insert "[fn::]")
(backward-char 1))
((member label all)
(unless (org-footnote--allow-reference-p)
(user-error "Cannot insert a footnote here"))
(insert "[fn:" label "]")
(message "New reference to existing note"))
(org-footnote-define-inline
(unless (org-footnote--allow-reference-p 'inline)
(user-error "Cannot insert a footnote here"))
(insert "[fn:" label ":]")
(backward-char 1)
(org-footnote-auto-adjust-maybe))
(t
(unless (org-footnote--allow-reference-p)
(user-error "Cannot insert a footnote here"))
(insert "[fn:" label "]")
(let ((p (org-footnote-create-definition label)))
;; `org-footnote-goto-definition' needs to be called

View File

@ -57,6 +57,17 @@
(should-error
(org-test-with-temp-text "<point>Test"
(org-footnote-new)))
;; ... but not when inserting anonymous or inline footnote
(should
(org-test-with-temp-text "<point>Test"
(let ((org-footnote-define-inline t))
(org-footnote-new)
t)))
(should
(org-test-with-temp-text "<point>Test"
(let ((org-footnote-auto-label 'anonymous))
(org-footnote-new)
t)))
;; Error at keywords.
(should-error
(org-test-with-temp-text "#+TIT<point>LE: value"