emacs-orgmode
[Top][All Lists]
Advanced

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

[O] New version which is compatible with emacs 24: New function to view


From: Marc-Oliver Ihm
Subject: [O] New version which is compatible with emacs 24: New function to view your notes in chronological order
Date: Fri, 22 Jul 2011 20:43:06 +0200
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20110624 Thunderbird/5.0

Hello !

Unfortunately, org-find-timestamps as posted before was not compatible with 
emacs 24.
(More precise, it hat problems with the read-only property, that emacs 24 
applies to text within the occur-buffer)

The version below is now compatible with both emacs 23 and 24.


Have fun !

with kind regards, Marc-Oliver Ihm



(defun org-find-timestamps ()
  "Find inactive timestamps within a date-range and maybe sort them.

This function can help to bring the notes, that you take within
org-mode, into a chronological order, even if they are scattered
among many different nodes. The result is somewhat like a diary,
listing your notes for each successive day. Please be aware
however: This intended usage requires, that you routinely
insert inactive timestamps into the notes that you write.

org-find-timstamps works by creating a regular expression to
match a given range of dates, doing a search for it and
displaying the results either as a sparse tree or with the help
of occur. The original buffer is not modified.
"
  (interactive)
  (let ((occur-buffer-name "*Occur*")
        (occur-header-regex "^[0-9]+ match\\(es\\)?") ;; regexp to match for 
header-lines in *Occur* buffer
        first-date 
        last-date 
        pretty-dates
        swap-dates
        (days 0) 
        date-regex
        position-before-year
        collect-method
        buff
        org-buffers)
    (save-window-excursion
      ;; temporary buffer for date-manipulations
      (with-temp-buffer
        ;; ask user for date-range
        (setq last-date (org-read-date nil nil nil "End date (or start): " nil 
nil))
        (setq first-date (org-read-date nil nil nil "Start date (or end): " nil 
nil))
        ;; swap dates, if required
        (when (string< last-date first-date)
          (setq swap-dates last-date)
          (setq last-date first-date)
          (setq first-date swap-dates))
        (setq pretty-dates (concat "from " first-date " to " last-date))
        ;; construct list of dates in working buffer
        ;; loop as long we did not reach end-date
        (while (not (looking-at-p last-date))
          (end-of-buffer)
          ;; only look for inactive timestamps
          (insert "[")
          (setq position-before-year (point))
          ;; Monday is probably wrong, will be corrected below
          (insert first-date " Mo]\n") 
          (goto-char position-before-year)
          ;; advance number of days and correct day of week
          (org-timestamp-change days 'day) 
          (setq days (1+ days))
          )
        (end-of-buffer)
        ;; transform constructed list of dates into a single, optimized regex
        (setq date-regex (regexp-opt (split-string (buffer-string) "\n" t)))
        )
      )
    ;; ask user, which buffers to search and how to present results
    (setq collect-method 
          (car (split-string (org-icompleting-read "Please choose, which 
buffers to search and how to present the matches: " '("multi-occur -- all 
org-buffers, list" "org-occur -- this-buffer, sparse tree") nil t nil nil 
"occur -- this buffer, list")))
          )
    ;; Perform the actual search
    (save-window-excursion
      (cond ((string= collect-method "occur")
             (occur date-regex)
             )
            ((string= collect-method "org-occur")
             (if (string= major-mode "org-mode")
                 (org-occur date-regex)
               (error "Buffer not in org-mode"))
             )
            ((string= collect-method "multi-occur")
             ;; construct list of all org-buffers
             (dolist (buff (buffer-list))
               (set-buffer buff)
               (if (string= major-mode "org-mode")
                   (setq org-buffers (cons buff org-buffers))))
             (multi-occur org-buffers date-regex)))
      )
    ;; Postprocessing: Optionally sort buffer with results
    ;; org-occur operates on the current buffer, so we cannot modify its 
results afterwards
    (if (string= collect-method "org-occur")
        (message (concat "Sparse tree with matches " pretty-dates))
      ;; switch to occur-buffer and modify it
      (if (not (get-buffer occur-buffer-name))
          (message (concat "Did not find any matches " pretty-dates))
        (let ((original-inhibit-read-only inhibit-read-only))
          (unwind-protect 
              (progn
                ;; next line might be risky, so we unwind-protect it
                (setq inhibit-read-only t)
                (set-buffer occur-buffer-name)
                (goto-char (point-min))
                ;; beautify the occur-buffer by replacing the potentially long 
original regexp
                (while (search-forward (concat " for \"" date-regex "\"") nil t)
                  (replace-match "" nil t))
                (goto-char (point-min))
                ;; Sort results by matching date ?
                (when (y-or-n-p "Sort results by date ? ")
                  (when (string= collect-method "multi-occur")
                    ;; bring all header lines ('xx matches for ..') to top of 
buffer, all lines with matches to bottom
                    (sort-subr t
                               'forward-line
                               'end-of-line
                               ;; search-key for this sort only differentiates 
between header-lines and matche-lines
                               (lambda () (if (looking-at-p occur-header-regex) 
2 1))
                               nil)
                    )
                  ;; goto first line of matches
                  (goto-char (point-max))
                  (search-backward-regexp occur-header-regex)
                  (forward-line)
                  ;; sort all matches according to date, that matched the regex
                  (sort-subr t
                             'forward-line
                             'end-of-line
                             ;; search-key for this sort is date
                             (lambda () (search-forward-regexp date-regex) 
(match-string 0))
                             nil 
                             'string<)
                  ;; pretend, that we did not modify the occur-buffer
                  )
                (insert "Searched " pretty-dates "\n")
                (goto-char (point-min))
                (set-buffer-modified-p nil)
                (message (concat "occur-buffer with matches " pretty-dates " 
(`C-h m' for help)"))
                )
            (setq inhibit-read-only original-inhibit-read-only)
            )
          )
        )
      ;; switch to occur-buffer
      (if (get-buffer occur-buffer-name)
          (switch-to-buffer occur-buffer-name))
      )
    )
  )




reply via email to

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