From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marc-Oliver Ihm Subject: Possibly new function to view your notes in chronological order Date: Sun, 17 Jul 2011 11:03:18 +0200 Message-ID: <4E22A556.3010202@online.de> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Return-path: Received: from eggs.gnu.org ([140.186.70.92]:49300) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QiNG2-0006kY-Le for emacs-orgmode@gnu.org; Sun, 17 Jul 2011 05:03:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QiNG0-0000sv-QF for emacs-orgmode@gnu.org; Sun, 17 Jul 2011 05:03:26 -0400 Received: from moutng.kundenserver.de ([212.227.126.186]:59852) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QiNG0-0000sr-3q for emacs-orgmode@gnu.org; Sun, 17 Jul 2011 05:03:24 -0400 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Hello All ! I would like to submit the new function org-find-timestamps for disussion. Citing its documentation: > 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. I would be grateful to for any comments; please find the defun below. regards, Marc (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 ((working-buffer (get-buffer-create "*org-find-timestamps working buffer*")) (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 (set-buffer working-buffer) (erase-buffer) ;; ask user for date-range (setq first-date (org-read-date nil nil nil "Starting date: " nil nil)) (setq last-date (org-read-date nil nil nil "End date: " 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))) ;; done with temporary buffer (kill-buffer working-buffer) ) ;; 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)) (set-buffer occur-buffer-name) (toggle-read-only) (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 ) (set-buffer-modified-p nil) (toggle-read-only) (message (concat "occur-buffer with matches " pretty-dates " (`C-h m' for help)")) ) ;; switch to occur-buffer (if (get-buffer occur-buffer-name) (switch-to-buffer occur-buffer-name)) ) ) )