emacs-devel
[Top][All Lists]
Advanced

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

Re: New version of todo-mode.el (announcement + user guide)


From: Stephen Berman
Subject: Re: New version of todo-mode.el (announcement + user guide)
Date: Mon, 17 Jun 2013 00:52:35 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

On Sat, 15 Jun 2013 20:44:03 -0400 Stefan Monnier <address@hidden> wrote:

>> restore the proper display.  But what happens between widening and
>> re-narrowing is different in the two situations (indicated below by the
>
> You could unify the two with something like
>
> (defvar diary-goto-entry-function
>     (lambda (pos)
>       (if (number-or-marker-p pos) (goto-char pos))
>         (goto-char (point-min))
>         (when (re-search-forward (format "%s.*\\(%s\\)"
>                                          (regexp-quote (car locator))
>                                          (regexp-quote (nth 1 locator)))
>                                  nil t)
>           (goto-char (match-beginning 1))))
>   "Function called to jump to a diary entry.
> Called with one argument which can be either a simple buffer position,
> or a description of the form (FOO BAR) where FOO is some leading text
> and BAR is the actual text of the entry.")
>
> (defun diary-goto-entry (button)
>   "Jump to the diary entry for the BUTTON at point."
>   (let* ((locator (button-get button 'locator))
>          (marker (car locator))
>          (file (nth 1 locator))
>          (place (cond
>                  ;; If marker pointing to diary location is valid, use that.
>                  ((and marker (marker-buffer marker))
>                   (cons (marker-buffer marker) marker))
>                  ;; Marker is invalid (eg buffer has been killed).
>                  ((and file (file-exists-p file))
>                   (cons (find-file-noselect file) (cddr locator)))
>                  (t (message "Unable to locate this diary entry") nil))))
>     (when place
>       (pop-to-buffer (car place))
>       (funcall diary-goto-entry-function (cdr place)))))
>

Ok, thanks.  So, you can use :around advice if you build the two types
of entry locating operations into the auxiliary function -- but not
without reimplementing diary-goto-entry accordingly.  Note, however,
that FOO can't just be "some leading text" but really has to be the
entry's date string, i.e. (nth 2 locator) [(car locator) is a typo, as
is (nth 1 locator), that should be 3 instead of 1; also I think it's
cleaner to use (nth 2 pos) and (nth 3 pos) and in diary-goto-entry cons
file to locator instead of (cddr locator)], otherwise either the wrong
or no entry will be found.  In other words, diary-goto-entry-function
can really only have that exact function as its value, so might be
better defined as a defconst.

>> Actually, I don't see why the first situation, using a valid marker, is
>> needed.
>
> I don't have any opinion on that part because I don't use this part of
> the diary.

So I think we now have three alternatives to choose from:
1. Keep diary-goto-entry as it is and add the variable
   diary-goto-entry-function with default value 'diary-goto-entry, which
   other packages can override (though the overriding function will
   still have to contain the same entry locating operations).
2. Change diary-goto-entry as above and add the variable (or defconst)
   diary-goto-entry-function, which other packages can modify with
   :around advice.
3. If using a marker to locate the entry is not necessary, then we could
   use the following somewhat simpler definitions (here, too, maybe the
   defvar should be a defconst):

   (defvar diary-goto-entry-function
     (lambda (pos)
       (let ((specifier (regexp-quote (nth 2 pos)))
             (literal (regexp-quote (nth 3 pos))))
         (goto-char (point-min))
         (if (re-search-forward (format "%s.*\\(%s\\)" specifier literal) nil t)
          (goto-char (match-beginning 1))))))
   
   (defun diary-goto-entry (button)
     "Jump to the diary entry for the BUTTON at point."
     (let* ((locator (button-get button 'locator))
            (file (cadr locator)))
       (if (not (and (file-exists-p file) (find-file-other-window file)))
           (message "Unable to locate this diary entry")
         (when (eq major-mode (default-value 'major-mode)) (diary-mode))
         (funcall diary-goto-entry-function locator))))

   This works with :around advice according to my tests. Glenn, is there
   some situation where it's necessary or highly advantageous to use a
   marker to locate the diary entry?

If all three alternatives are equally viable, is there any reason to
prefer one over the others?

Steve Berman



reply via email to

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