help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: post-command-hook to slow?


From: Pascal J. Bourguignon
Subject: Re: post-command-hook to slow?
Date: Fri, 06 Jun 2014 01:05:30 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Thorsten Jolitz <address@hidden> writes:

> Its a bit hard to explain, in fact I don't want to run a
> post-command-hook, I just want to call an Org function in a temporary
> buffer - but that function runs a post-command hook, and I have to deal
> with that (it is somehow run too late, when the temp buffer is already
> closed).
>
> An MWE is difficult unless you are an Org user, but anyway:
>
> Evaluate this in an emacs-lisp-mode buffer (without the
> surrounding #+begin_ and #+end_ delimiters):
>
> #+begin_src emacs-lisp
> (setq org-todo-keywords
>       (quote
>        ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!/!)")
>       (sequence
>        "WAITING(w@/!)" "HOLD(h@/!)" "|"
>        "CANCELLED(c@/!)" "PHONE"))))
>
> (with-temp-buffer
>   (org-mode)
>   (insert "* Level 1\nSome Text\n")
>   (org-todo)
>   (message "%s" (buffer-substring-no-properties
>      (point-min) (point-max))))
> #+end_src
>
> you should be prompted for a state, choose TODO first (t) and it should
>  work.
>
> Then evaluate 'with-temp-buffer again, this time chosing a state with an
>  @ in its definition:
>
>  "WAITING" or "HOLD" or "CANCELLED
>
> because thats triggers taking a log note (and calling a
> post-command-hook function).
>
> You should get the error:
>
> ,-----------------------------------------------
> | Error in post-command-hook (org-add-log-note):
> | (error "Marker does not point anywhere")
> `-----------------------------------------------
>
> When you insert a message statement at the very beginning of
> `org-add-log-note' that print current-buffer an major-mode, you will see
> that its called in the emacs-lisp buffer and not in the temp buffer. 

Ok.   So you see how things go.  This is a general technique in emacs
applications, since we start from an editing event loop. 

org-todo opens a menu buffer with a list of choices.    In this case, it
reads the user choice modaly, with org-icompleting-read: you cannot do
anything else than select a menu item.

But then, in some cases, it needs to let the user edit a note.
To do that,
org-todo adds org-add-log-note to post-command-hook, and
org-add-log-note removes itself from it.  This chains the org-todo and
org-add-log-note commands in the main editing event loop.

org-add-log-note sets up a *Org Note* buffer, and similarly, returns, to
let the user edit it in the main editing event loop.  When the user
types C-c C-c, the org-ctrl-c-ctrl-c command is called which store the
note.  In the mean time a lot of commands can be given by the user.  He
may switch to other buffers and come back to the note a long time later.

Since the org application doesn't expect to do anything else once the
note is stored, org-store-log-note doesn't have any final hook.  We
would have to advice it, to add one.  On the other hand,
org-store-log-note is called from the org-finish-function hook, set up
by org-add-log-note, so we could set this hook to call
org-store-log-note, and our own function.


In any case, we have two architectures, either:

- we may use the same modeless model as the org application (and any
  other emacs application), therefore not using with-temp-buffer, but
  creating a temporary buffer, and by way of hooks, chain the activities
  we need.  or:

- we can still use with-temp-buffer, but we have to call
  (recursive-edit) to insert an editing event loop to let the user gain
  control until we (OR the user!) choose to exit or abort the recursive
  edit.

Here is how you would implement this later case:

(defun pjb-finish-store-log-note-and-exit-recursive-edit ()
  (org-store-log-note)
  (exit-recursive-edit))

(with-temp-buffer
  (org-mode)
  (insert "* Level 1\nSome Text\n")
  (org-todo)
  (message "BEFORE: %s" (buffer-substring-no-properties
                         (point-min) (point-max)))
  (when (marker-buffer org-log-note-marker)
    (org-add-log-note)
    (org-set-local 'org-finish-function 
'pjb-finish-store-log-note-and-exit-recursive-edit)
    (recursive-edit))
  (message "AFTER: %s" (buffer-substring-no-properties
                        (point-min) (point-max))))


Notice that in this problem post-command-hook is only incidental, even
if the error message reporte mentionned it.  It's used to chain the
commands, but the problem is not related to commands and
post-command-hook at all.

-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"


reply via email to

[Prev in Thread] Current Thread [Next in Thread]