emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Matt Price <moptop99@gmail.com>
To: emacs-orgmode@gnu.org
Subject: Re: overlay showing computed value of macro?
Date: Fri, 23 Nov 2018 04:08:05 -0500	[thread overview]
Message-ID: <CAN_Dec_f2COiiiBco+RtrPXi0m3zi02pt5M5HPW46Y8kPL5aZQ@mail.gmail.com> (raw)
In-Reply-To: <CAN_Dec9PzcWFiwDoy3d0tY4RNqZk20uUWHiZLD8Wzbhs3w91yg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5848 bytes --]

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.

[-- Attachment #2: Type: text/html, Size: 8004 bytes --]

  reply	other threads:[~2018-11-23  9:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-22 18:19 overlay showing computed value of macro? Matt Price
2018-11-22 21:06 ` Matt Price
2018-11-22 22:37   ` Matt Price
2018-11-23  9:08     ` Matt Price [this message]
2018-11-23  9:32       ` Eric S Fraga
2018-11-23 12:49         ` Matt Price
2018-11-23 14:15           ` Eric S Fraga

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAN_Dec_f2COiiiBco+RtrPXi0m3zi02pt5M5HPW46Y8kPL5aZQ@mail.gmail.com \
    --to=moptop99@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).