Fix cache update when radio targets are being refreshed

* lisp/org-element.el (org-element-cache-refresh): New function.
* lisp/org.el (org-update-radio-target-regexp): Make it standalone.
  Also refresh fontification only when necessary.
(org-all-targets, org-make-target-link-regexp): Remove functions.

* testing/lisp/test-org.el (test-org/update-radio-target-regexp): New
  test
(test-org/all-targets): Remove test.

We need to manually reset cache on radio links as re-fontification
doesn't trigger a buffer change, and, as a consequence, a cache reset.
This commit is contained in:
Nicolas Goaziou 2014-04-19 14:38:25 +02:00
parent f7c6cf6432
commit 6eb940a8dc
3 changed files with 55 additions and 50 deletions

View File

@ -5510,8 +5510,7 @@ change, as an integer."
(defun org-element-cache-reset (&optional all)
"Reset cache in current buffer.
When optional argument ALL is non-nil, reset cache in all Org
buffers. This function will do nothing if
`org-element-use-cache' is nil."
buffers."
(interactive "P")
(dolist (buffer (if all (buffer-list) (list (current-buffer))))
(with-current-buffer buffer
@ -5530,6 +5529,14 @@ buffers. This function will do nothing if
(add-hook 'after-change-functions
#'org-element--cache-after-change nil t)))))
;;;###autoload
(defun org-element-cache-refresh (pos)
"Refresh cache at position POS."
(when (org-element--cache-active-p)
(org-element--cache-sync (current-buffer) pos)
(org-element--cache-submit-request pos pos 0)
(org-element--cache-set-timer (current-buffer))))
;;; The Toolbox

View File

@ -6089,12 +6089,41 @@ by a #."
t)))))
(defun org-update-radio-target-regexp ()
"Find all radio targets in this file and update the regular expression."
"Find all radio targets in this file and update the regular expression.
Also refresh fontification if needed."
(interactive)
(when (memq 'radio org-activate-links)
(let ((old-regexp org-target-link-regexp)
(targets
(org-with-wide-buffer
(goto-char (point-min))
(let (rtn)
(while (re-search-forward org-radio-target-regexp nil t)
;; Make sure point is really within the object.
(backward-char)
(let ((obj (org-element-context)))
(when (eq (org-element-type obj) 'radio-target)
(add-to-list 'rtn (org-element-property :value obj)))))
rtn))))
(setq org-target-link-regexp
(org-make-target-link-regexp (org-all-targets 'radio)))
(org-restart-font-lock)))
(and targets
(concat "\\(?:^\\|[^[:alnum:]]\\)\\("
(mapconcat
(lambda (x)
(replace-regexp-in-string
" +" "\\s-+" (regexp-quote x) t t))
targets
"\\|")
"\\)\\(?:$\\|[^[:alnum:]]\\)")))
(unless (equal old-regexp org-target-link-regexp)
;; Clean-up cache.
(when old-regexp
(org-with-wide-buffer
(goto-char (point-min))
(while (re-search-forward old-regexp nil t)
(org-element-cache-refresh (match-beginning 1)))))
;; Re fontify buffer.
(when (memq 'radio org-activate-links)
(org-restart-font-lock)))))
(defun org-hide-wide-columns (limit)
(let (s e)
@ -6160,34 +6189,6 @@ done, nil otherwise."
(font-lock-mode -1)
(font-lock-mode 1)))
(defun org-all-targets (&optional radio)
"Return a list of all targets in this file.
When optional argument RADIO is non-nil, only find radio
targets."
(let ((re (if radio org-radio-target-regexp org-target-regexp)) rtn)
(save-excursion
(goto-char (point-min))
(while (re-search-forward re nil t)
;; Make sure point is really within the object.
(backward-char)
(let ((obj (org-element-context)))
(when (memq (org-element-type obj) '(radio-target target))
(add-to-list 'rtn (downcase (org-element-property :value obj))))))
rtn)))
(defun org-make-target-link-regexp (targets)
"Make regular expression matching all strings in TARGETS.
The regular expression finds the targets also if there is a line break
between words."
(and targets
(concat "\\(?:^\\|[^[:alnum:]]\\)\\("
(mapconcat
(lambda (x)
(replace-regexp-in-string " +" "\\s-+" (regexp-quote x) t t))
targets
"\\|")
"\\)\\(?:$\\|[^[:alnum:]]\\)")))
(defun org-activate-tags (limit)
(if (re-search-forward (org-re "^\\*+.*[ \t]\\(:[[:alnum:]_@#%:]+:\\)[ \r\n]") limit t)
(progn

View File

@ -1514,23 +1514,20 @@ Text.
;;; Targets and Radio Targets
;;; Radio Targets
(ert-deftest test-org/update-radio-target-regexp ()
"Test `org-update-radio-target-regexp' specifications."
(org-test-with-temp-text "radio\n\nParagraph\n\nradio"
(save-excursion (goto-char (point-max)) (org-element-context))
(insert "<<<")
(search-forward "o")
(insert ">>>")
(replace-match "<<<radio>>>")
(org-update-radio-target-regexp)
(goto-char (point-max))
(org-element-type (org-element-context))))
(ert-deftest test-org/all-targets ()
"Test `org-all-targets' specifications."
;; Without an argument.
(should
(equal '("radio-target" "target")
(org-test-with-temp-text "<<target>> <<<radio-target>>>\n: <<verb>>"
(org-all-targets))))
(should
(equal '("radio-target")
(org-test-with-temp-text "<<<radio-target>>>!" (org-all-targets))))
;; With argument.
(should
(equal '("radio-target")
(org-test-with-temp-text "<<target>> <<<radio-target>>>"
(org-all-targets t)))))
;;; Visibility