From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marc-Oliver Ihm Subject: 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 Message-ID: <4E29C4BA.5090906@online.de> References: <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]:47220) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkKgo-0008PS-4x for emacs-orgmode@gnu.org; Fri, 22 Jul 2011 14:43:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QkKgm-00035R-Ox for emacs-orgmode@gnu.org; Fri, 22 Jul 2011 14:43:10 -0400 Received: from moutng.kundenserver.de ([212.227.126.186]:56325) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkKgm-000357-4u for emacs-orgmode@gnu.org; Fri, 22 Jul 2011 14:43:08 -0400 In-Reply-To: <4E22A556.3010202@online.de> 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, Bastien Cc: Marc-Oliver Ihm 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)) ) ) )