emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Carsten Dominik <carsten.dominik@gmail.com>
To: "Ryan C. Thompson" <rct2c@virginia.edu>
Cc: emacs-orgmode@gnu.org
Subject: Re: Org-remember-handler fix for empty remember buffer
Date: Mon, 8 Jun 2009 19:45:37 +0200	[thread overview]
Message-ID: <A1C5A829-5C73-463B-BE12-533FCCEC5A1E@gmail.com> (raw)
In-Reply-To: <4A280827.2070705@virginia.edu>

Fixed, thanks.

- Carsten

On Jun 4, 2009, at 7:45 PM, Ryan C. Thompson wrote:

> Hi,
>
> I ran into a problem with org's remember functionality, and found a  
> fix for it. The problem is that if you attempt to either abort or  
> remember an empty buffer (that is, a buffer containing only  
> whitespace and comments), then org-mode hits an error and fails to  
> do either, leaving the buffer annoyingly open.
>
> The bug is in the loop that deletes trailing comments and  
> whitespace. If the buffer is empty, then this loop reaches the first  
> line, and attempts to delete a region starting at position zero,  
> which causes the error. Here is the modified function definition  
> that checks for this condition.
>
> As a bonus, the function also auto-aborts instead of saving if the  
> buffer is empty.
>
> Thank you,
>
> Ryan Thompson
>
>
>
> ;; Fix for empty remember buffer.
> (defun org-remember-handler ()
> "Store stuff from remember.el into an org file.
> When the template has specified a file and a headline, the entry is  
> filed
> there, or in the location defined by `org-default-notes-file' and
> `org-remember-default-headline'.
>
> If no defaults have been defined, or if the current prefix argument
> is 1 (so you must use `C-1 C-c C-c' to exit remember), an interactive
> process is used to select the target location.
>
> When the prefix is 0 (i.e. when remember is exited with `C-0 C-c C- 
> c'),
> the entry is filed to the same location as the previous note.
>
> When the prefix is 2 (i.e. when remember is exited with `C-2 C-c C- 
> c'),
> the entry is filed as a subentry of the entry where the clock is
> currently running.
>
> When `C-u' has been used as prefix argument, the note is stored and  
> emacs
> moves point to the new location of the note, so that editing can be
> continued there (similar to inserting \"%&\" into the template).
>
> Before storing the note, the function ensures that the text has an
> org-mode-style headline, i.e. a first line that starts with
> a \"*\".  If not, a headline is constructed from the current date and
> some additional data.
>
> If the variable `org-adapt-indentation' is non-nil, the entire text is
> also indented so that it starts in the same column as the headline
> \(i.e. after the stars).
>
> See also the variable `org-reverse-note-order'."
> (interactive)
> (when (and (equal current-prefix-arg 2)
>        (not (marker-buffer org-clock-marker)))
>   (error "No running clock"))
> (when (org-bound-and-true-p org-jump-to-target-location)
>   (let* ((end (min (point-max) (1+ (point))))
>      (beg (point)))
>     (if (= end beg) (setq beg (1- beg)))
>     (put-text-property beg end 'org-position-cursor t)))
> (goto-char (point-min))
> (while (looking-at "^[ \t]*\n\\|^##.*\n")
>   (replace-match ""))
> (goto-char (point-max))
> (beginning-of-line 1)
> (catch 'quit
>   (while (looking-at "[ \t]*$\\|##.*")
>     ;; Abort on empty buffer
>     (if (= (point) (point-min))
>         (throw 'quit nil)
>       (previous-line)))
>   (delete-region (point) (point-max))
>   (backward-delete-char 1)
>   (if org-note-abort (throw 'quit nil))
>   ;; Also abort on an empty (i.e. whitespace-only) buffer
>   ;; (if (not (string-match "[^[:space:]]" (buffer-substring-no- 
> properties (point-min) (point-max)))) (return t))
>   (let* ((visitp (org-bound-and-true-p org-jump-to-target-location))
>      (previousp (and (member current-prefix-arg '((16) 0))
>              org-remember-previous-location))
>      (clockp (equal current-prefix-arg 2))
>      (fastp (org-xor (equal current-prefix-arg 1)
>              org-remember-store-without-prompt))
>      (file (cond
>         (fastp org-default-notes-file)
>         ((and (eq org-remember-interactive-interface 'refile)
>           org-refile-targets)
>          org-default-notes-file)
>         ((not previousp)
>          (org-get-org-file))))
>      (heading org-remember-default-headline)
>      (visiting (and file (org-find-base-buffer-visiting file)))
>      (org-startup-folded nil)
>      (org-startup-align-all-tables nil)
>      (org-goto-start-pos 1)
>      spos exitcmd level reversed txt)
>     (when (equal current-prefix-arg '(4))
>   (setq visitp t))
>     (when previousp
>   (setq file (car org-remember-previous-location)
>         visiting (and file (org-find-base-buffer-visiting file))
>         heading (cdr org-remember-previous-location)
>         fastp t))
>     (when clockp
>   (setq file (buffer-file-name (marker-buffer org-clock-marker))
>         visiting (and file (org-find-base-buffer-visiting file))
>         heading org-clock-heading-for-remember
>         fastp t))
>     (setq current-prefix-arg nil)
>     ;; Modify text so that it becomes a nice subtree which can be  
> inserted
>     ;; into an org tree.
>     (goto-char (point-min))
>     (if (re-search-forward "[ \t\n]+\\'" nil t)
>     ;; remove empty lines at end
>     (replace-match ""))
>     (goto-char (point-min))
>     (unless (looking-at org-outline-regexp)
>   ;; add a headline
>   (insert (concat "* " (current-time-string)
>           " (" (remember-buffer-desc) ")\n"))
>   (backward-char 1)
>   (when org-adapt-indentation
>     (while (re-search-forward "^" nil t)
>       (insert "  "))))
>     (goto-char (point-min))
>     (if (re-search-forward "\n[ \t]*\n[ \t\n]*\\'" nil t)
>     (replace-match "\n\n")
>   (if (re-search-forward "[ \t\n]*\\'")
>       (replace-match "\n")))
>     (goto-char (point-min))
>     (setq txt (buffer-string))
>     (org-save-markers-in-region (point-min) (point-max))
>     (when (and (eq org-remember-interactive-interface 'refile)
>        (not fastp))
>   (org-refile nil (or visiting (find-file-noselect file)))
>   (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit- 
> immediately))
>   (save-excursion
>     (bookmark-jump "org-refile-last-stored")
>     (bookmark-set "org-remember-last-stored")
>     (move-marker org-remember-last-stored-marker (point)))
>   (throw 'quit t))
>     ;; Find the file
>     (with-current-buffer (or visiting (find-file-noselect file))
>   (unless (org-mode-p)
>     (error "Target files for remember notes must be in Org-mode"))
>   (save-excursion
>     (save-restriction
>       (widen)
>       (and (goto-char (point-min))
>        (not (re-search-forward "^\\* " nil t))
>        (insert "\n* " (or (and (stringp heading) heading)
>                   "Notes") "\n"))
>       (setq reversed (org-notes-order-reversed-p))
>
>       ;; Find the default location
>       (when heading
>         (cond
>          ((eq heading 'top)
>       (goto-char (point-min))
>       (or (looking-at org-outline-regexp)
>           (re-search-forward org-outline-regexp nil t))
>       (setq org-goto-start-pos (or (match-beginning 0) (point-min))))
>          ((eq heading 'bottom)
>       (goto-char (point-max))
>       (or (bolp) (newline))
>       (setq org-goto-start-pos (point)))
>          ((and (stringp heading) (string-match "\\S-" heading))
>       (goto-char (point-min))
>       (if (re-search-forward
>            (concat "^\\*+[ \t]+" (regexp-quote heading)
>                (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$"))
>            nil t)
>           (setq org-goto-start-pos (match-beginning 0))
>         (when fastp
>           (goto-char (point-max))
>           (unless (bolp) (newline))
>           (insert "* " heading "\n")
>           (setq org-goto-start-pos (point-at-bol 0)))))
>          (t (goto-char (point-min)) (setq org-goto-start-pos (point)
>                       heading 'top))))
>
>       ;; Ask the User for a location, using the appropriate interface
>       (cond
>        ((and fastp (memq heading '(top bottom)))
>         (setq spos org-goto-start-pos
>             exitcmd (if (eq heading 'top) 'left nil)))
>        (fastp (setq spos org-goto-start-pos
>             exitcmd 'return))
>        ((eq org-remember-interactive-interface 'outline)
>         (setq spos (org-get-location (current-buffer)
>                      org-remember-help)
>           exitcmd (cdr spos)
>           spos (car spos)))
>        ((eq org-remember-interactive-interface 'outline-path- 
> completion)
>         (let ((org-refile-targets '((nil . (:maxlevel . 10))))
>           (org-refile-use-outline-path t))
>       (setq spos (org-refile-get-location "Heading: ")
>             exitcmd 'return
>             spos (nth 3 spos))))
>        (t (error "This should not happen")))
>       (if (not spos) (throw 'quit nil)) ; return nil to show we did
>                   ; not handle this note
>       (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit- 
> immediately))
>       (goto-char spos)
>       (cond ((org-on-heading-p t)
>          (org-back-to-heading t)
>          (setq level (funcall outline-level))
>          (cond
>           ((eq exitcmd 'return)
>            ;; sublevel of current
>            (setq org-remember-previous-location
>              (cons (abbreviate-file-name file)
>                (org-get-heading 'notags)))
>            (if reversed
>            (outline-next-heading)
>              (org-end-of-subtree t)
>              (if (not (bolp))
>              (if (looking-at "[ \t]*\n")
>                  (beginning-of-line 2)
>                (end-of-line 1)
>                (insert "\n"))))
>            (org-paste-subtree (org-get-valid-level level 1) txt)
>            (and org-auto-align-tags (org-set-tags nil t))
>            (bookmark-set "org-remember-last-stored")
>            (move-marker org-remember-last-stored-marker (point)))
>           ((eq exitcmd 'left)
>            ;; before current
>            (org-paste-subtree level txt)
>            (and org-auto-align-tags (org-set-tags nil t))
>            (bookmark-set "org-remember-last-stored")
>            (move-marker org-remember-last-stored-marker (point)))
>           ((eq exitcmd 'right)
>            ;; after current
>            (org-end-of-subtree t)
>            (org-paste-subtree level txt)
>            (and org-auto-align-tags (org-set-tags nil t))
>            (bookmark-set "org-remember-last-stored")
>            (move-marker org-remember-last-stored-marker (point)))
>           (t (error "This should not happen"))))
>
>         ((eq heading 'bottom)
>          (org-paste-subtree 1 txt)
>          (and org-auto-align-tags (org-set-tags nil t))
>          (bookmark-set "org-remember-last-stored")
>          (move-marker org-remember-last-stored-marker (point)))
>
>         ((and (bobp) (not reversed))
>          ;; Put it at the end, one level below level 1
>          (save-restriction
>            (widen)
>            (goto-char (point-max))
>            (if (not (bolp)) (newline))
>            (org-paste-subtree (org-get-valid-level 1 1) txt)
>            (and org-auto-align-tags (org-set-tags nil t))
>            (bookmark-set "org-remember-last-stored")
>            (move-marker org-remember-last-stored-marker (point))))
>
>         ((and (bobp) reversed)
>          ;; Put it at the start, as level 1
>          (save-restriction
>            (widen)
>            (goto-char (point-min))
>            (re-search-forward "^\\*+ " nil t)
>            (beginning-of-line 1)
>            (org-paste-subtree 1 txt)
>            (and org-auto-align-tags (org-set-tags nil t))
>            (bookmark-set "org-remember-last-stored")
>            (move-marker org-remember-last-stored-marker (point))))
>         (t
>          ;; Put it right there, with automatic level determined by
>          ;; org-paste-subtree or from prefix arg
>          (org-paste-subtree
>           (if (numberp current-prefix-arg) current-prefix-arg)
>           txt)
>          (and org-auto-align-tags (org-set-tags nil t))
>          (bookmark-set "org-remember-last-stored")
>          (move-marker org-remember-last-stored-marker (point))))
>
>       (when remember-save-after-remembering
>         (save-buffer)
>         (if (and (not visiting)
>              (not (equal (marker-buffer org-clock-marker)
>                  (current-buffer))))
>         (kill-buffer (current-buffer)))))))))
>
> t)    ;; return t to indicate that we took care of this note.
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

  parent reply	other threads:[~2009-06-08 17:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-04 17:45 Org-remember-handler fix for empty remember buffer Ryan C. Thompson
2009-06-07 14:18 ` Carsten Dominik
2009-06-08 17:45 ` Carsten Dominik [this message]
2009-06-08 19:45   ` Ryan C. Thompson
2009-06-08 20:51     ` Carsten Dominik

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=A1C5A829-5C73-463B-BE12-533FCCEC5A1E@gmail.com \
    --to=carsten.dominik@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=rct2c@virginia.edu \
    /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).