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
next prev 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
* 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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.