;;; todo-mode.el --- facilities for making and maintaining todo lists
-;; Copyright (C) 1997, 1999, 2001-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1999, 2001-2016 Free Software Foundation, Inc.
;; Author: Oliver Seidel <privat@os10000.net>
;; Stephen Berman <stephen.berman@gmx.net>
(let ((files (if (file-exists-p todo-directory)
(mapcar 'file-truename
(directory-files todo-directory t
- (if archives "\.toda$" "\.todo$") t)))))
+ (if archives "\\.toda$" "\\.todo$") t)))))
(sort files (lambda (s1 s2) (let ((cis1 (upcase s1))
(cis2 (upcase s2)))
(string< cis1 cis2))))))
(when (string= (widget-value widget) todo-item-mark)
(widget-put
widget :error
- "Invalid value: must be distinct from `todo-item-mark'")
+ (format-message
+ "Invalid value: must be distinct from `todo-item-mark'"))
widget)))
:initialize 'custom-initialize-default
:set 'todo-reset-prefix
todo-filtered-items-mode))))
(if (funcall todo-files-function)
(todo-read-file-name "Choose a todo file to visit: "
- nil t)
+ nil t)
(user-error "There are no todo files")))
((and (eq major-mode 'todo-archive-mode)
;; Called noninteractively via todo-quit
(when (or (member file todo-visited)
(eq todo-show-first 'first))
(unless (todo-check-file file) (throw 'end nil))
- (set-window-buffer (selected-window)
+ ;; If todo-show is called from the minibuffer, don't visit
+ ;; the todo file there.
+ (set-window-buffer (if (minibufferp) (minibuffer-selected-window)
+ (selected-window))
(set-buffer (find-file-noselect file 'nowarn)))
(if (equal (file-name-extension (buffer-file-name)) "toda")
(unless (derived-mode-p 'todo-archive-mode) (todo-archive-mode))
(setq todo-category-number (todo-category-number cat)))
;; If this is a new todo file, add its first category.
(when (zerop (buffer-size))
+ ;; Don't confuse an erased buffer with a fresh buffer for
+ ;; adding a new todo file -- it might have been erased by
+ ;; mistake or due to a bug (e.g. Bug#20832).
+ (when (buffer-modified-p)
+ (error "Buffer is empty but modified, please report a bug"))
(let (cat-added)
(unwind-protect
(setq todo-category-number
(snname (todo-short-file-name nname))
(files (directory-files todo-directory t
(concat ".*" (regexp-quote soname)
- ".*\.tod[aorty]$") t)))
+ ".*\\.tod[aorty]$") t)))
(dolist (f files)
(let* ((sfname (todo-short-file-name f))
(fext (file-name-extension f t))
"deleting it will also delete the file.\n"
"Do you want to proceed? ")))
((> archived 0)
- (todo-y-or-n-p (concat "This category has archived items; "
+ (todo-y-or-n-p (format-message
+ (concat "This category has archived items; "
"the archived category will remain\n"
"after deleting the todo category. "
"Do you still want to delete it\n"
"(see `todo-skip-archived-categories' "
- "for another option)? ")))
+ "for another option)? "))))
(t
(todo-y-or-n-p (concat "Permanently remove category \"" cat
"\"" (and arg " and all its entries")
(when (string= (widget-value widget) todo-prefix)
(widget-put
widget :error
- "Invalid value: must be distinct from `todo-prefix'")
+ (format-message
+ "Invalid value: must be distinct from `todo-prefix'"))
widget)))
:set (lambda (symbol value)
(custom-set-default symbol (propertize value 'face 'todo-mark)))
(defun todo-edit-item (&optional arg)
"Choose an editing operation for the current item and carry it out."
(interactive "P")
- (cond ((todo-done-item-p)
- (todo-edit-item--next-key todo-edit-done-item--param-key-alist))
- ((todo-item-string)
- (todo-edit-item--next-key todo-edit-item--param-key-alist arg))))
+ (let ((marked (assoc (todo-current-category) todo-categories-with-marks)))
+ (cond ((and (todo-done-item-p) (not marked))
+ (todo-edit-item--next-key todo-edit-done-item--param-key-alist))
+ ((or marked (todo-item-string))
+ (todo-edit-item--next-key todo-edit-item--param-key-alist arg)))))
(defun todo-edit-item--text (&optional arg)
"Function providing the text editing facilities of `todo-edit-item'."
- (let* ((opoint (point))
- (start (todo-item-start))
- (end (save-excursion (todo-item-end)))
- (item-beg (progn
- (re-search-forward
- (concat todo-date-string-start todo-date-pattern
- "\\( " diary-time-regexp "\\)?"
- (regexp-quote todo-nondiary-end) "?")
- (line-end-position) t)
- (1+ (- (point) start))))
- (include-header (eq arg 'include-header))
- (comment-edit (eq arg 'comment-edit))
- (comment-delete (eq arg 'comment-delete))
- (header-string (substring (todo-item-string) 0 item-beg))
- (item (if (or include-header comment-edit comment-delete)
- (todo-item-string)
- (substring (todo-item-string) item-beg)))
- (multiline (> (length (split-string item "\n")) 1))
- (comment (save-excursion
- (todo-item-start)
- (re-search-forward
- (concat " \\[" (regexp-quote todo-comment-string)
- ": \\([^]]+\\)\\]") end t)))
- (prompt (if comment "Edit comment: " "Enter a comment: "))
- (buffer-read-only nil))
- (cond
- ((or comment-edit comment-delete)
- (save-excursion
- (todo-item-start)
- (if (re-search-forward (concat " \\[" (regexp-quote todo-comment-string)
- ": \\([^]]+\\)\\]") end t)
- (if comment-delete
- (when (todo-y-or-n-p "Delete comment? ")
- (delete-region (match-beginning 0) (match-end 0)))
- (replace-match (read-string prompt (cons (match-string 1) 1))
- nil nil nil 1))
- (if comment-delete
- (user-error "There is no comment to delete")
- (insert " [" todo-comment-string ": "
- (prog1 (read-string prompt)
- ;; If user moved point during editing,
- ;; make sure it moves back.
- (goto-char opoint)
- (todo-item-end))
- "]")))))
- ((or multiline (eq arg 'multiline))
- (let ((buf todo-edit-buffer))
- (set-window-buffer (selected-window)
- (set-buffer (make-indirect-buffer (buffer-name) buf)))
- (narrow-to-region (todo-item-start) (todo-item-end))
- (todo-edit-mode)
- (message "%s" (substitute-command-keys
- (concat "Type \\[todo-edit-quit] "
- "to return to Todo mode.\n")))))
- (t
- (let ((new (concat (if include-header "" header-string)
- (read-string "Edit: " (if include-header
- (cons item item-beg)
- (cons item 0))))))
- (when include-header
- (while (not (string-match (concat todo-date-string-start
- todo-date-pattern) new))
- (setq new (read-from-minibuffer
- "Item must start with a date: " new))))
- ;; Ensure lines following hard newlines are indented.
- (setq new (replace-regexp-in-string "\\(\n\\)[^[:blank:]]"
- "\n\t" new nil nil 1))
- ;; If user moved point during editing, make sure it moves back.
- (goto-char opoint)
- (todo-remove-item)
- (todo-insert-with-overlays new)
- (move-to-column item-beg))))))
+ (let ((full-item (todo-item-string)))
+ ;; If there are marked items and user invokes a text-editing
+ ;; commands with point not on an item, todo-item-start is nil and
+ ;; 1+ signals an error, so just make this a noop.
+ (when full-item
+ (let* ((opoint (point))
+ (start (todo-item-start))
+ (end (save-excursion (todo-item-end)))
+ (item-beg (progn
+ (re-search-forward
+ (concat todo-date-string-start todo-date-pattern
+ "\\( " diary-time-regexp "\\)?"
+ (regexp-quote todo-nondiary-end) "?")
+ (line-end-position) t)
+ (1+ (- (point) start))))
+ (include-header (eq arg 'include-header))
+ (comment-edit (eq arg 'comment-edit))
+ (comment-delete (eq arg 'comment-delete))
+ (header-string (substring full-item 0 item-beg))
+ (item (if (or include-header comment-edit comment-delete)
+ full-item
+ (substring full-item item-beg)))
+ (multiline (or (eq arg 'multiline)
+ (> (length (split-string item "\n")) 1)))
+ (comment (save-excursion
+ (todo-item-start)
+ (re-search-forward
+ (concat " \\[" (regexp-quote todo-comment-string)
+ ": \\([^]]+\\)\\]") end t)))
+ (prompt (if comment "Edit comment: " "Enter a comment: "))
+ (buffer-read-only nil))
+ ;; When there are marked items, user can invoke todo-edit-item
+ ;; even if point is not on an item, but text editing only
+ ;; applies to the item at point.
+ (when (or (and (todo-done-item-p)
+ (or comment-edit comment-delete))
+ (and (not (todo-done-item-p))
+ (or (not arg) include-header multiline)))
+ (cond
+ ((or comment-edit comment-delete)
+ (save-excursion
+ (todo-item-start)
+ (if (re-search-forward (concat " \\["
+ (regexp-quote todo-comment-string)
+ ": \\([^]]+\\)\\]") end t)
+ (if comment-delete
+ (when (todo-y-or-n-p "Delete comment? ")
+ (delete-region (match-beginning 0) (match-end 0)))
+ (replace-match (read-string prompt (cons (match-string 1) 1))
+ nil nil nil 1))
+ (if comment-delete
+ (user-error "There is no comment to delete")
+ (insert " [" todo-comment-string ": "
+ (prog1 (read-string prompt)
+ ;; If user moved point during editing,
+ ;; make sure it moves back.
+ (goto-char opoint)
+ (todo-item-end))
+ "]")))))
+ (multiline
+ (let ((buf todo-edit-buffer))
+ (set-window-buffer (selected-window)
+ (set-buffer (make-indirect-buffer
+ (buffer-name) buf)))
+ (narrow-to-region (todo-item-start) (todo-item-end))
+ (todo-edit-mode)
+ (message "%s" (substitute-command-keys
+ (concat "Type \\[todo-edit-quit] "
+ "to return to Todo mode.\n")))))
+ (t
+ (let ((new (concat (if include-header "" header-string)
+ (read-string "Edit: " (if include-header
+ (cons item item-beg)
+ (cons item 0))))))
+ (when include-header
+ (while (not (string-match (concat todo-date-string-start
+ todo-date-pattern) new))
+ (setq new (read-from-minibuffer
+ "Item must start with a date: " new))))
+ ;; Ensure lines following hard newlines are indented.
+ (setq new (replace-regexp-in-string "\\(\n\\)[^[:blank:]]"
+ "\n\t" new nil nil 1))
+ ;; If user moved point during editing, make sure it moves back.
+ (goto-char opoint)
+ (todo-remove-item)
+ (todo-insert-with-overlays new)
+ (move-to-column item-beg)))))))))
(defun todo-edit-quit ()
"Return from Todo Edit mode to Todo mode.
(defun todo-edit-item--header (what &optional inc)
"Function providing header editing facilities of `todo-edit-item'."
- (let* ((cat (todo-current-category))
- (marked (assoc cat todo-categories-with-marks))
- (first t)
- (todo-date-from-calendar t)
- ;; INC must be an integer, but users could pass it via
- ;; `todo-edit-item' as e.g. `-' or `C-u'.
- (inc (prefix-numeric-value inc))
- (buffer-read-only nil)
- ndate ntime year monthname month day
- dayname) ; Needed by calendar-date-display-form.
+ (let ((marked (assoc (todo-current-category) todo-categories-with-marks))
+ (first t)
+ (todo-date-from-calendar t)
+ ;; INC must be an integer, but users could pass it via
+ ;; `todo-edit-item' as e.g. `-' or `C-u'.
+ (inc (prefix-numeric-value inc))
+ (buffer-read-only nil)
+ ndate ntime year monthname month day
+ dayname) ; Needed by calendar-date-display-form.
+ (when marked (todo--user-error-if-marked-done-item))
(save-excursion
(or (and marked (goto-char (point-min))) (todo-item-start))
(catch 'end
(mlist (append tmn-array nil))
(tma-array todo-month-abbrev-array)
(mablist (append tma-array nil))
- (yy (and oyear (unless (string= oyear "*")
- (string-to-number oyear))))
- (mm (or (and omonth (unless (string= omonth "*")
+ (yy (and oyear (string-to-number oyear))) ; 0 if year is "*".
+ (mm (or (and omonth (if (string= omonth "*") 13
(string-to-number omonth)))
(1+ (- (length mlist)
(length (or (member omonthname mlist)
(if omonth
(number-to-string mm)
(aref tma-array (1- mm))))))
- (let ((yy (string-to-number year)) ; 0 if year is "*".
- ;; When mm is 13 (corresponding to "*" as value
- ;; of month), this raises an args-out-of-range
- ;; error in calendar-last-day-of-month, so use 1
- ;; (corresponding to January) to get 31 days.
- (mm (if (= mm 13) 1 mm)))
+ ;; Since the number corresponding to the arbitrary
+ ;; month name "*" is out of the range of
+ ;; calendar-last-day-of-month, set it to 1
+ ;; (corresponding to January) to allow 31 days.
+ (let ((mm (if (= mm 13) 1 mm)))
(if (> (string-to-number day)
(calendar-last-day-of-month mm yy))
(user-error "%s %s does not have %s days"
monthname omonthname
day (cond
((not current-prefix-arg)
- (todo-read-date 'day mm oyear))
+ (todo-read-date 'day mm yy))
((string= oday "*")
(user-error "Cannot increment *"))
((or (string= omonth "*") (string= omonthname "*"))
(defun todo-edit-item--diary-inclusion (&optional nonmarking)
"Function providing diary marking facilities of `todo-edit-item'."
(let ((buffer-read-only)
- (marked (assoc (todo-current-category)
- todo-categories-with-marks)))
+ (marked (assoc (todo-current-category) todo-categories-with-marks)))
+ (when marked (todo--user-error-if-marked-done-item))
(catch 'stop
(save-excursion
(when marked (goto-char (point-min)))
(while (not (eobp))
- (if (todo-done-item-p)
- (throw 'stop (message "Done items cannot be edited"))
- (unless (and marked (not (todo-marked-item-p)))
- (let* ((beg (todo-item-start))
- (lim (save-excursion (todo-item-end)))
- (end (save-excursion
- (or (todo-time-string-matcher lim)
- (todo-date-string-matcher lim)))))
- (if nonmarking
- (if (looking-at (regexp-quote diary-nonmarking-symbol))
- (replace-match "")
- (when (looking-at (regexp-quote todo-nondiary-start))
- (save-excursion
- (replace-match "")
- (search-forward todo-nondiary-end (1+ end) t)
- (replace-match "")
- (todo-update-count 'diary 1)))
- (insert diary-nonmarking-symbol))
- (if (looking-at (regexp-quote todo-nondiary-start))
- (progn
+ (unless (and marked (not (todo-marked-item-p)))
+ (let* ((beg (todo-item-start))
+ (lim (save-excursion (todo-item-end)))
+ (end (save-excursion
+ (or (todo-time-string-matcher lim)
+ (todo-date-string-matcher lim)))))
+ (if nonmarking
+ (if (looking-at (regexp-quote diary-nonmarking-symbol))
+ (replace-match "")
+ (when (looking-at (regexp-quote todo-nondiary-start))
+ (save-excursion
(replace-match "")
(search-forward todo-nondiary-end (1+ end) t)
(replace-match "")
- (todo-update-count 'diary 1))
- (when end
- (when (looking-at (regexp-quote diary-nonmarking-symbol))
- (replace-match "")
- (setq end (1- end))) ; Since we deleted nonmarking symbol.
- (insert todo-nondiary-start)
- (goto-char (1+ end))
- (insert todo-nondiary-end)
- (todo-update-count 'diary -1))))))
- (unless marked (throw 'stop nil))
- (todo-forward-item)))))
- (todo-update-categories-sexp)))
+ (todo-update-count 'diary 1)))
+ (insert diary-nonmarking-symbol))
+ (if (looking-at (regexp-quote todo-nondiary-start))
+ (progn
+ (replace-match "")
+ (search-forward todo-nondiary-end (1+ end) t)
+ (replace-match "")
+ (todo-update-count 'diary 1))
+ (when end
+ (when (looking-at (regexp-quote diary-nonmarking-symbol))
+ (replace-match "")
+ (setq end (1- end))) ; Since we deleted nonmarking symbol.
+ (insert todo-nondiary-start)
+ (goto-char (1+ end))
+ (insert todo-nondiary-end)
+ (todo-update-count 'diary -1))))))
+ (unless marked (throw 'stop nil))
+ (todo-forward-item)))))
+ (todo-update-categories-sexp))
(defun todo-edit-category-diary-inclusion (arg)
"Make all items in this category diary items.
;; separator.
(when (looking-back (concat "^"
(regexp-quote todo-category-done)
- "\n"))
+ "\n")
+ (line-beginning-position 0))
(todo-backward-item))))
(todo-insert-with-overlays item)
;; If item was marked, restore the mark.
(interactive "P")
(let* ((cat (todo-current-category))
(marked (assoc cat todo-categories-with-marks)))
- (when marked
- (save-excursion
- (save-restriction
- (goto-char (point-max))
- (todo-backward-item)
- (unless (todo-done-item-p)
- (widen)
- (unless (re-search-forward
- (concat "^" (regexp-quote todo-category-beg)) nil t)
- (goto-char (point-max)))
- (forward-line -1))
- (while (todo-done-item-p)
- (when (todo-marked-item-p)
- (user-error "This command does not apply to done items"))
- (todo-backward-item)))))
+ (when marked (todo--user-error-if-marked-done-item))
(unless (and (not marked)
(or (todo-done-item-p)
;; Point is between todo and done items.
(goto-char (point-min))
(re-search-forward todo-done-string-start nil t)))
(buffer-read-only nil)
- item done-item opoint)
+ item done-item
+ (opoint (point)))
;; Don't add empty comment to done item.
(setq comment (unless (zerop (length comment))
(concat " [" todo-comment-string ": " comment "]")))
(todo-update-categories-sexp)
(let ((todo-show-with-done show-done))
(todo-category-select)
- ;; When done items are shown, put cursor on first just done item.
+ ;; When done items are visible, put point at the top of the
+ ;; done items section. When done items are hidden, restore
+ ;; point to its location prior to invoking this command.
(when opoint (goto-char opoint)))))))
(defun todo-item-undone ()
(while (not (eobp))
(when (or (not marked) (and marked (todo-marked-item-p)))
(if (not (todo-done-item-p))
- (user-error "Only done items can be undone")
+ (progn
+ (goto-char opoint)
+ (user-error "Only done items can be undone"))
(todo-item-start)
(unless marked
(setq ov (make-overlay (save-excursion (todo-item-start))
(defun todo-find-filtered-items-file ()
"Choose a filtered items file and visit it."
(interactive)
- (let ((files (directory-files todo-directory t "\.tod[rty]$" t))
+ (let ((files (directory-files todo-directory t "\\.tod[rty]$" t))
falist file)
(dolist (f files)
(let ((type (cond ((equal (file-name-extension f) "todr") "regexp")
(if (and (eobp)
(looking-back
(concat (regexp-quote todo-done-string)
- "\n")))
+ "\n")
+ (line-beginning-position 0)))
(delete-region (point) (progn
(forward-line -2)
(point))))))
(goto-char (match-beginning 0))
(goto-char (point-max)))
(backward-char)
- (when (looking-back "\\[\\([^][]+\\)\\]")
+ (when (looking-back "\\[\\([^][]+\\)\\]"
+ (line-beginning-position))
(setq cat (match-string 1))
(goto-char (match-beginning 0))
(replace-match ""))
;; If the item ends with a non-comment parenthesis not
;; followed by a period, we lose (but we inherit that
;; problem from the legacy code).
- (when (looking-back "(\\(.*\\)) ")
+ ;; FIXME: fails on multiline comment
+ (when (looking-back "(\\(.*\\)) " (line-beginning-position))
(setq comment (match-string 1))
(replace-match "")
(insert "[" todo-comment-string ": " comment "]"))
(widen)
(goto-char (point-min))
(setq todo-categories
- (if (looking-at "\(\(\"")
+ (if (looking-at "((\"")
(read (buffer-substring-no-properties
(line-beginning-position)
(line-end-position)))
;; Warn user if categories sexp has changed.
(unless (string= ssexp cats)
(message (concat "The sexp at the beginning of the file differs "
- "from the value of `todo-categories.\n"
+ "from the value of `todo-categories'.\n"
"If the sexp is wrong, you can fix it with "
"M-x todo-repair-categories-sexp,\n"
"but note this reverts any changes you have "
(add-function :override diary-goto-entry-function #'todo-diary-goto-entry)
+(defun todo-revert-buffer (&optional ignore-auto noconfirm)
+ "Call `revert-buffer', preserving buffer's current modes.
+Also preserve category display, if applicable."
+ (interactive (list (not current-prefix-arg)))
+ (let ((revert-buffer-function nil))
+ (revert-buffer ignore-auto noconfirm 'preserve-modes)
+ (when (memq major-mode '(todo-mode todo-archive-mode))
+ (todo-category-select))))
+
(defun todo-desktop-save-buffer (_dir)
`((catnum . ,(todo-category-number (todo-current-category)))))
(with-current-buffer buffer
(widen)
(let ((todo-category-number (cdr (assq 'catnum misc))))
- (todo-category-select))))
+ (todo-category-select)
+ (current-buffer))))
(add-to-list 'desktop-buffer-mode-handlers
'(todo-mode . todo-restore-desktop-buffer))
(progn (goto-char (point-min))
(looking-at todo-done-string-start)))))
+(defun todo--user-error-if-marked-done-item ()
+ "Signal user error on marked done items.
+Helper function for editing commands that apply only to (possibly
+marked) not done todo items."
+ (save-excursion
+ (save-restriction
+ (goto-char (point-max))
+ (todo-backward-item)
+ (unless (todo-done-item-p)
+ (widen)
+ (unless (re-search-forward
+ (concat "^" (regexp-quote todo-category-beg)) nil t)
+ (goto-char (point-max)))
+ (forward-line -1))
+ (while (todo-done-item-p)
+ (when (todo-marked-item-p)
+ (user-error "This command does not apply to done items"))
+ (todo-backward-item)))))
+
(defun todo-reset-done-separator (sep)
"Replace existing overlays of done items separator string SEP."
(save-excursion
(looking-at todo-done-string-start)
(looking-back (concat "^"
(regexp-quote todo-category-done)
- "\n")))
+ "\n")
+ (line-beginning-position 0)))
(setq num 1
done t))
(setq prefix (concat (propertize
The list consists of item insertion parameters that can be passed
as insertion command arguments in fixed positions. If a position
in the list is not occupied by the corresponding parameter, it is
-occupied by `nil'."
+occupied by nil."
(let* ((arg (list (car todo-insert-item--args)))
(args (nconc (cdr todo-insert-item--args)
(list (car (todo-insert-item--argsleft
'(add/edit delete))
" comment"))))
params " "))
- (this-key (char-to-string
- (read-key (concat todo-edit-item--prompt p->k))))
+ (key-prompt (substitute-command-keys todo-edit-item--prompt))
+ (this-key (let ((key (read-key (concat key-prompt p->k))))
+ (and (characterp key) (char-to-string key))))
(this-param (car (rassoc this-key params))))
(pcase this-param
(`edit (todo-edit-item--text))
(when deleted
(let ((pl (> (length deleted) 1))
(names (mapconcat (lambda (f) (concat "\"" f "\"")) deleted ", ")))
- (message (concat "File" (if pl "s" "") " " names " ha" (if pl "ve" "s")
+ (message (concat "File" (if pl "s" "") " %s ha" (if pl "ve" "s")
" been deleted and removed from\n"
- "the list of category completion files")))
+ "the list of category completion files")
+ names))
(todo-reevaluate-category-completions-files-defcustom)
(custom-set-default 'todo-category-completions-files
(symbol-value 'todo-category-completions-files))
(and day (setq day (if (eq day '*)
(symbol-name '*)
(number-to-string day))))
- (and month (setq month (if (eq month '*)
+ (and month (setq month (if (= month 13)
(symbol-name '*)
(number-to-string month))))
(if arg
"The :set function for user option `todo-nondiary-marker'."
(let* ((oldvalue (symbol-value symbol))
(files (append todo-files todo-archives
- (directory-files todo-directory t "\.tod[rty]$" t))))
+ (directory-files todo-directory t "\\.tod[rty]$" t))))
(custom-set-default symbol value)
;; Need to reset these to get font-locking right.
(setq todo-nondiary-start (nth 0 todo-nondiary-marker)
"The :set function for user option `todo-done-string'."
(let ((oldvalue (symbol-value symbol))
(files (append todo-files todo-archives
- (directory-files todo-directory t "\.todr$" t))))
+ (directory-files todo-directory t "\\.todr$" t))))
(custom-set-default symbol value)
;; Need to reset this to get font-locking right.
(setq todo-done-string-start
"The :set function for user option `todo-comment-string'."
(let ((oldvalue (symbol-value symbol))
(files (append todo-files todo-archives
- (directory-files todo-directory t "\.todr$" t))))
+ (directory-files todo-directory t "\\.todr$" t))))
(custom-set-default symbol value)
(when (not (equal value oldvalue))
(dolist (f files)
"The :set function for user option `todo-highlight-item'."
(let ((oldvalue (symbol-value symbol))
(files (append todo-files todo-archives
- (directory-files todo-directory t "\.tod[rty]$" t))))
+ (directory-files todo-directory t "\\.tod[rty]$" t))))
(custom-set-default symbol value)
(when (not (equal value oldvalue))
(dolist (f files)
(defun todo-modes-set-1 ()
"Make some settings that apply to multiple Todo modes."
(setq-local font-lock-defaults '(todo-font-lock-keywords t))
+ (setq-local revert-buffer-function 'todo-revert-buffer)
(setq-local tab-width todo-indent-to-here)
(setq-local indent-line-function 'todo-indent)
(when todo-wrap-lines
"Make some settings that apply to multiple Todo modes."
(add-to-invisibility-spec 'todo)
(setq buffer-read-only t)
- (when (and (boundp 'desktop-save-mode) desktop-save-mode)
- (setq-local desktop-save-buffer 'todo-desktop-save-buffer))
+ (setq-local desktop-save-buffer 'todo-desktop-save-buffer)
(when (boundp 'hl-line-range-function)
(setq-local hl-line-range-function
(lambda() (save-excursion
"Major mode for displaying, navigating and editing todo lists.
\\{todo-mode-map}"
- ;; (easy-menu-add todo-menu)
- (todo-modes-set-1)
- (todo-modes-set-2)
- (todo-modes-set-3)
- ;; Initialize todo-current-todo-file.
- (when (member (file-truename (buffer-file-name))
- (funcall todo-files-function))
- (setq-local todo-current-todo-file (file-truename (buffer-file-name))))
- (setq-local todo-show-done-only nil)
- (setq-local todo-categories-with-marks nil)
- ;; (add-hook 'find-file-hook 'todo-add-to-buffer-list nil t)
- (add-hook 'post-command-hook 'todo-update-buffer-list nil t)
- (when todo-show-current-file
- (add-hook 'pre-command-hook 'todo-show-current-file nil t))
- (add-hook 'window-configuration-change-hook
- 'todo-reset-and-enable-done-separator nil t)
- (add-hook 'kill-buffer-hook 'todo-reset-global-current-todo-file nil t))
+ (if (called-interactively-p 'any)
+ (message "%s"
+ (substitute-command-keys
+ "Type `\\[todo-show]' to enter Todo mode"))
+ (todo-modes-set-1)
+ (todo-modes-set-2)
+ (todo-modes-set-3)
+ ;; Initialize todo-current-todo-file.
+ (when (member (file-truename (buffer-file-name))
+ (funcall todo-files-function))
+ (setq-local todo-current-todo-file (file-truename (buffer-file-name))))
+ (setq-local todo-show-done-only nil)
+ (setq-local todo-categories-with-marks nil)
+ ;; (add-hook 'find-file-hook 'todo-add-to-buffer-list nil t)
+ (add-hook 'post-command-hook 'todo-update-buffer-list nil t)
+ (when todo-show-current-file
+ (add-hook 'pre-command-hook 'todo-show-current-file nil t))
+ (add-hook 'window-configuration-change-hook
+ 'todo-reset-and-enable-done-separator nil t)
+ (add-hook 'kill-buffer-hook 'todo-reset-global-current-todo-file nil t)))
(put 'todo-archive-mode 'mode-class 'special)