0

I want to call org-update-radio-target-regexp as soon as org-mode recognises that a new <<<radio target>>> has been created (which seems to happen as soon as the third ">" is typed, at least this is when it gets fontified).

What hook can I use to get this done?

1

Following NickD's input on my first answer (thanks @NickD) I think a better approach is to limit org-update-radio-target-regexp to only fire when the target is first created. This is done by binding the ">" key and then testing whether point is just to the right of a <<<radio target>>> (after it is pressed). Here is the code:

(define-key org-mode-map (kbd ">")
  (lambda ()
    (interactive)
    (if (and (org-in-regexp org-target-regexp)
             (not (org-in-regexp org-target-regexp nil t)))
        (progn
          (insert ">")
          (org-update-radio-target-regexp))
      (insert ">"))))
3
  • Instead of binding the key globally, you should bind it in org-mode-map only, since you only want it active in Org mode buffers. You can then simplify the function by throwing away the testing of the mode. – NickD Feb 8 at 14:21
  • Aha! Thanks NickD. All done. – Adam Feb 8 at 16:41
  • Nice job! I think this is much more efficient than your initial attempt. – NickD Feb 8 at 17:16
0

This works:

(defun org-at-radio-target-p ()
  (not (eq (org-in-regexp org-radio-target-regexp) nil)))

(add-hook 'post-command-hook 
      (lambda () 
        (when (org-at-radio-target-p)
          (org-update-radio-target-regexp))))

I am not sure how efficient it is, hooking into post-command-hook. But it seems to work okay, so far...

12
  • 1
    The post-command-hook runs after every command: e.g. inserting a character in a buffer is done by the command self-insert-command, so the hook is going to run after every character you type in a buffer; BTW, that's any buffer, not just org mode buffers. If the buffer is large, you are going to be spending a lot of time looking for radio targets and even though the regexp is not particularly complicated, the searches are not free. If you find that when you type fast in a large buffer, emacs cannot keep up with your typing, then you have probably reached this limit. – NickD Feb 7 at 19:07
  • 1
    The doc string for post-command-hook says It is a bad idea to use this hook for expensive processing. If unavoidable, wrap your code in ‘(while-no-input (redisplay) CODE)’ to avoid making Emacs unresponsive while the user types. – NickD Feb 7 at 19:09
  • 2
    And as a minor point, (when (not (eq (foo) nil)) (do-something)) is equivalent to (when (foo) (do-something)) - you probably don't need the org-at-radio-target-p function. – NickD Feb 7 at 19:16
  • 1
    Finally (?), assuming that you want to check for radio targets only when you are in an Org mode buffer, you might want to write the hook function like this: (lambda () (when (eq major-mode 'org-mode) (when (org-in-regexp org-radio-target-regexp) (org-update-radio-target-regexp)))), so you only pay the penalty in Org mode buffers, not in every buffer. And in general, it is recommended that you name your hook functions: that makes it easier to delete them from the hook when the need arises. – NickD Feb 7 at 19:20
  • @NickD thanks. Have you tested this? I was not able to get this to work... – Adam Feb 7 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.