emacs-orgmode
[Top][All Lists]
Advanced

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

Re: [O] overlay showing computed value of macro?


From: Matt Price
Subject: Re: [O] overlay showing computed value of macro?
Date: Fri, 23 Nov 2018 04:08:05 -0500

OH man, I know this is a lot of replies to my own thread.  Sorry for the noise. I just wanted to point out something I somehow failed to see as I was pretending to cook Thanksgiving dinner while working on this project (!!) -- my code does just fine producing overlays, which might be useful to some people, but it does not really help with my own need, which is to calculate timestamp values based on the position of the macro call in the buffer.  That's because I'm using a function that searches backwards for previous timestames, and the overlays are of course *not part of the buffer string*, so they don't get picked up by regexp-search-backward. 

To fix this I replaced my original function with a group of functions that searches the buffer string *and* the overlays, looking for a timestamp regep.  For the overlays, I endedu p writing a recursive function cause I oculdn't think howelse to do it. 

This is all much more verbose than my original function and I think pretty inelegant but I would be interested to hear what others htink. 

Here's the original function, which doesn't look for overlays:

(defun get-ts+7 (&optional weekly-times)
  "Return a string of the form <%Y-%m-d %a> where the date
elements are 7 days later than the (n - WEEKLY-TIMES timestamp)
in the buffer. That is, if WEEKLY-TIMES is nil or 1, return a
date one week later than the *PREVIOUS* timestamp. If
WEEKLY-TIMES is 2, return a time one week later than the
*SECOND-TO-LAST* timestamp above the previous location.

If there are not enough timestamps, right now it returns the last
found timestamp. "
  (interactive)
  (setq weekly-times (or weekly-times 1))
  (defun ts-search ()
    (save-match-data
      (goto-char (re-search-backward
                  (org-re-timestamp 'all) nil t))
      (let ((thismatch  (match-string 0)))
        (message "match: %s" thismatch)
        thismatch)))
  (let* (r
         (base-date (save-excursion
                     (cl-dotimes (time weekly-times r)
                       (condition-case nil
                           (progn (setq  r (or (ts-search) r))
                                  (message "r is %s" r))
                         (error
                          (message "Drat, there were %s timestamps, using the last one I found."
                                   (if (= 0 time) "no" time))
                          (return r))))))

        (result nil))
    (message "base-time is %s" base-date)
    (if base-date
        (format-time-string "<%Y-%m-%d %a>"
                            (time-add
                             (date-to-time base-date) (days-to-time (1+ 7))))
      "NO PREVIOUS TIMESTAMP") ))
-------------------------

and here are the several functions I felt I needed to solve the problem of searching in 2 dimmensions:


(defun ts-search-both ()
  (save-match-data
    (let* ((bufts
            (save-match-data
              (set-match-data nil)
              (save-excursion
                (re-search-backward
                 (org-re-timestamp 'all) nil t)
                (if (match-beginning 0)
                    `(,(match-beginning 0) ,(match-string 0))
                  nil))))
           (ovts (save-match-data (save-excursion  (ts-search-ov)))))
      (cond
       ((and bufts ovts)
        (if (> (car bufts) (car ovts))
            (goto-char (car bufts))
            (cadr bufts)
          (cadr ovts)))
       (bufts
        (goto-char (car bufts))
        (cadr bufts))
       (ovts
        (goto-char (car ovts))
        (cadr ovts))
       (t
        (goto-char (point-min)) nil)
       )
      )))

(defun ts-search-ov ()
  (let* ((ovend   (previous-single-char-property-change (point) 'macro-ov-p))
         (ovs (overlays-at ovend))
         (m  (cl-loop for o in ovs
                      if (string-match (org-re-timestamp 'all) (overlay-get o 'before-string))
                      ;;(goto-char (overlay-start o))
                      return (match-string 0 (overlay-get o 'before-string)))))
    (cond
     (m `(,(point) ,m))
     ((>= (point-min) ovend )
      (goto-char ovend)
      nil)
     (t
      (goto-char ovend)
      (ts-search-ov))
      )))

(defun get-ts+7-inc-ov (&optional weekly-times)
  "Return a string of the form <%Y-%m-d %a> where the date
elements are 7 days later than the (n - WEEKLY-TIMES timestamp)
in the buffer. That is, if WEEKLY-TIMES is nil or 1, return a
date one week later than the *PREVIOUS* timestamp. If
WEEKLY-TIMES is 2, return a time one week later than the
*SECOND-TO-LAST* timestamp above the previous location.

If there are not enough timestamps, right now it returns the last
found timestamp. "
  (interactive)
  (setq weekly-times (or weekly-times 1))
 
  (let* (r
         (base-date (save-excursion
                     (cl-dotimes (time weekly-times r)
                       (condition-case nil
                           (let ((s (ts-search-both)))
                             (if s
                                 (setq r s)
                               (message "Drat, there were %s timestamps, using the last one I found."
                                        (if (= 0 time) "no" time))
                               (return r)))
                        
                         ;; (error
                         ;;  (message "Drat, there were %s timestamps, using the last one I found."
                         ;;           (if (= 0 time) "no" time))
                         ;;  (return r))
                         ))))

        (result nil))
    (message "base-time is %s" base-date)
    (if base-date
        (format-time-string "<%Y-%m-%d %a>"
                            (time-add
                             (date-to-time base-date) (days-to-time (1+ 7))))
      "NO PREVIOUS TIMESTAMP") ))


-------------------------------

I'd be interested in feedback if others have some interest i nthe problem.



reply via email to

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