浏览代码

Use `with-silent-modifications' instead of `org-unmodified' when it makes sense

* org-macs.el: Add a comment on when to use `org-unmodified'
and when to use `with-silent-modifications'.

* org-colview.el (org-columns-display-here)
(org-columns-remove-overlays, org-columns-quit)
(org-columns-edit-value, org-columns-compute-all)
(org-columns-compute, org-agenda-colview-compute):
* org-clock.el (org-clock-sum):
* org.el (org-refresh-category-properties)
(org-refresh-properties, org-entry-blocked-p)
(org-agenda-prepare-buffers): Use `with-silent-modifications'
instead of `org-unmodified'.

Thanks to Stefan Monnier for reminding me about `with-silent-modifications'!
Bastien Guerry 12 年之前
父节点
当前提交
43c8aa02cc
共有 4 个文件被更改,包括 176 次插入176 次删除
  1. 79 79
      lisp/org-clock.el
  2. 30 31
      lisp/org-colview.el
  3. 2 0
      lisp/org-macs.el
  4. 65 66
      lisp/org.el

+ 79 - 79
lisp/org-clock.el

@@ -1700,85 +1700,85 @@ each headline in the time range with point at the headline.  Headlines for
 which HEADLINE-FILTER returns nil are excluded from the clock summation.
 PROPNAME lets you set a custom text property instead of :org-clock-minutes."
   (interactive)
-  (org-unmodified
-   (let* ((re (concat "^\\(\\*+\\)[ \t]\\|^[ \t]*"
-		      org-clock-string
-		      "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
-	  (lmax 30)
-	  (ltimes (make-vector lmax 0))
-	  (t1 0)
-	  (level 0)
-	  ts te dt
-	  time)
-     (if (stringp tstart) (setq tstart (org-time-string-to-seconds tstart)))
-     (if (stringp tend) (setq tend (org-time-string-to-seconds tend)))
-     (if (consp tstart) (setq tstart (org-float-time tstart)))
-     (if (consp tend) (setq tend (org-float-time tend)))
-     (remove-text-properties (point-min) (point-max)
-			     `(,(or propname :org-clock-minutes) t
-			       :org-clock-force-headline-inclusion t))
-     (save-excursion
-       (goto-char (point-max))
-       (while (re-search-backward re nil t)
-	 (cond
-	  ((match-end 2)
-	   ;; Two time stamps
-	   (setq ts (match-string 2)
-		 te (match-string 3)
-		 ts (org-float-time
-		     (apply 'encode-time (org-parse-time-string ts)))
-		 te (org-float-time
-		     (apply 'encode-time (org-parse-time-string te)))
-		 ts (if tstart (max ts tstart) ts)
-		 te (if tend (min te tend) te)
-		 dt (- te ts)
-		 t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1)))
-	  ((match-end 4)
-	   ;; A naked time
-	   (setq t1 (+ t1 (string-to-number (match-string 5))
-		       (* 60 (string-to-number (match-string 4))))))
-	  (t ;; A headline
-	   ;; Add the currently clocking item time to the total
-	   (when (and org-clock-report-include-clocking-task
-		      (equal (org-clocking-buffer) (current-buffer))
-		      (equal (marker-position org-clock-hd-marker) (point))
-		      tstart
-		      tend
-		      (>= (org-float-time org-clock-start-time) tstart)
-		      (<= (org-float-time org-clock-start-time) tend))
-	     (let ((time (floor (- (org-float-time)
-				   (org-float-time org-clock-start-time)) 60)))
-	       (setq t1 (+ t1 time))))
-	   (let* ((headline-forced
-		   (get-text-property (point)
-				      :org-clock-force-headline-inclusion))
-		  (headline-included
-		   (or (null headline-filter)
-		       (save-excursion
-			 (save-match-data (funcall headline-filter))))))
-	     (setq level (- (match-end 1) (match-beginning 1)))
-	     (when (or (> t1 0) (> (aref ltimes level) 0))
-	       (when (or headline-included headline-forced)
-		 (if headline-included
-		     (loop for l from 0 to level do
-			   (aset ltimes l (+ (aref ltimes l) t1))))
-		 (setq time (aref ltimes level))
-		 (goto-char (match-beginning 0))
-		 (put-text-property (point) (point-at-eol)
-				    (or propname :org-clock-minutes) time)
-		 (if headline-filter
-		     (save-excursion
-		       (save-match-data
-			 (while
-			     (> (funcall outline-level) 1)
-			   (outline-up-heading 1 t)
-			   (put-text-property
-			    (point) (point-at-eol)
-			    :org-clock-force-headline-inclusion t))))))
-	       (setq t1 0)
-	       (loop for l from level to (1- lmax) do
-		     (aset ltimes l 0)))))))
-       (setq org-clock-file-total-minutes (aref ltimes 0))))))
+  (with-silent-modifications
+    (let* ((re (concat "^\\(\\*+\\)[ \t]\\|^[ \t]*"
+		       org-clock-string
+		       "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
+	   (lmax 30)
+	   (ltimes (make-vector lmax 0))
+	   (t1 0)
+	   (level 0)
+	   ts te dt
+	   time)
+      (if (stringp tstart) (setq tstart (org-time-string-to-seconds tstart)))
+      (if (stringp tend) (setq tend (org-time-string-to-seconds tend)))
+      (if (consp tstart) (setq tstart (org-float-time tstart)))
+      (if (consp tend) (setq tend (org-float-time tend)))
+      (remove-text-properties (point-min) (point-max)
+			      `(,(or propname :org-clock-minutes) t
+				:org-clock-force-headline-inclusion t))
+      (save-excursion
+	(goto-char (point-max))
+	(while (re-search-backward re nil t)
+	  (cond
+	   ((match-end 2)
+	    ;; Two time stamps
+	    (setq ts (match-string 2)
+		  te (match-string 3)
+		  ts (org-float-time
+		      (apply 'encode-time (org-parse-time-string ts)))
+		  te (org-float-time
+		      (apply 'encode-time (org-parse-time-string te)))
+		  ts (if tstart (max ts tstart) ts)
+		  te (if tend (min te tend) te)
+		  dt (- te ts)
+		  t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1)))
+	   ((match-end 4)
+	    ;; A naked time
+	    (setq t1 (+ t1 (string-to-number (match-string 5))
+			(* 60 (string-to-number (match-string 4))))))
+	   (t ;; A headline
+	    ;; Add the currently clocking item time to the total
+	    (when (and org-clock-report-include-clocking-task
+		       (equal (org-clocking-buffer) (current-buffer))
+		       (equal (marker-position org-clock-hd-marker) (point))
+		       tstart
+		       tend
+		       (>= (org-float-time org-clock-start-time) tstart)
+		       (<= (org-float-time org-clock-start-time) tend))
+	      (let ((time (floor (- (org-float-time)
+				    (org-float-time org-clock-start-time)) 60)))
+		(setq t1 (+ t1 time))))
+	    (let* ((headline-forced
+		    (get-text-property (point)
+				       :org-clock-force-headline-inclusion))
+		   (headline-included
+		    (or (null headline-filter)
+			(save-excursion
+			  (save-match-data (funcall headline-filter))))))
+	      (setq level (- (match-end 1) (match-beginning 1)))
+	      (when (or (> t1 0) (> (aref ltimes level) 0))
+		(when (or headline-included headline-forced)
+		  (if headline-included
+		      (loop for l from 0 to level do
+			    (aset ltimes l (+ (aref ltimes l) t1))))
+		  (setq time (aref ltimes level))
+		  (goto-char (match-beginning 0))
+		  (put-text-property (point) (point-at-eol)
+				     (or propname :org-clock-minutes) time)
+		  (if headline-filter
+		      (save-excursion
+			(save-match-data
+			  (while
+			      (> (funcall outline-level) 1)
+			    (outline-up-heading 1 t)
+			    (put-text-property
+			     (point) (point-at-eol)
+			     :org-clock-force-headline-inclusion t))))))
+		(setq t1 0)
+		(loop for l from level to (1- lmax) do
+		      (aset ltimes l 0)))))))
+	(setq org-clock-file-total-minutes (aref ltimes 0))))))
 
 (defun org-clock-sum-current-item (&optional tstart)
   "Return time, clocked on current item in total."

+ 30 - 31
lisp/org-colview.el

@@ -223,17 +223,17 @@ This is the compiled version of the format.")
       (setq s2 (org-columns-add-ellipses (or modval val) width))
       (setq string (format f s2))
       ;; Create the overlay
-      (org-unmodified
-       (setq ov (org-columns-new-overlay
-		 beg (setq beg (1+ beg)) string (if dateline face1 face)))
-       (overlay-put ov 'keymap org-columns-map)
-       (overlay-put ov 'org-columns-key property)
-       (overlay-put ov 'org-columns-value (cdr ass))
-       (overlay-put ov 'org-columns-value-modified modval)
-       (overlay-put ov 'org-columns-pom pom)
-       (overlay-put ov 'org-columns-format f)
-       (overlay-put ov 'line-prefix "")
-       (overlay-put ov 'wrap-prefix ""))
+      (with-silent-modifications
+	(setq ov (org-columns-new-overlay
+		  beg (setq beg (1+ beg)) string (if dateline face1 face)))
+	(overlay-put ov 'keymap org-columns-map)
+	(overlay-put ov 'org-columns-key property)
+	(overlay-put ov 'org-columns-value (cdr ass))
+	(overlay-put ov 'org-columns-value-modified modval)
+	(overlay-put ov 'org-columns-pom pom)
+	(overlay-put ov 'org-columns-format f)
+	(overlay-put ov 'line-prefix "")
+	(overlay-put ov 'wrap-prefix ""))
       (if (or (not (char-after beg))
 	      (equal (char-after beg) ?\n))
 	  (let ((inhibit-read-only t))
@@ -332,11 +332,11 @@ for the duration of the command.")
 	(remove-hook 'post-command-hook 'org-columns-hscoll-title 'local))
       (move-marker org-columns-begin-marker nil)
       (move-marker org-columns-top-level-marker nil)
-      (org-unmodified
-       (mapc 'delete-overlay org-columns-overlays)
-       (setq org-columns-overlays nil)
-       (let ((inhibit-read-only t))
-	 (remove-text-properties (point-min) (point-max) '(read-only t))))
+      (with-silent-modifications
+	(mapc 'delete-overlay org-columns-overlays)
+	(setq org-columns-overlays nil)
+	(let ((inhibit-read-only t))
+	  (remove-text-properties (point-min) (point-max) '(read-only t))))
       (when org-columns-flyspell-was-active
 	(flyspell-mode 1))
       (when (local-variable-p 'org-colview-initial-truncate-line-value)
@@ -384,10 +384,10 @@ CPHR is the complex heading regexp to use for parsing ITEM."
 (defun org-columns-quit ()
   "Remove the column overlays and in this way exit column editing."
   (interactive)
-  (org-unmodified
-   (org-columns-remove-overlays)
-   (let ((inhibit-read-only t))
-     (remove-text-properties (point-min) (point-max) '(read-only t))))
+  (with-silent-modifications
+    (org-columns-remove-overlays)
+    (let ((inhibit-read-only t))
+      (remove-text-properties (point-min) (point-max) '(read-only t))))
   (when (eq major-mode 'org-agenda-mode)
     (setq org-agenda-columns-active nil)
     (message
@@ -488,9 +488,9 @@ Where possible, use the standard interface for changing this line."
 	  (org-agenda-columns)))
        (t
 	(let ((inhibit-read-only t))
-	  (org-unmodified
-	   (remove-text-properties
-	    (max (point-min) (1- bol)) eol '(read-only t)))
+	  (with-silent-modifications
+	    (remove-text-properties
+	     (max (point-min) (1- bol)) eol '(read-only t)))
 	  (unwind-protect
 	      (progn
 		(setq org-columns-overlays
@@ -920,8 +920,8 @@ Don't set this, this is meant for dynamic scoping.")
 
 (defun org-columns-compute-all ()
   "Compute all columns that have operators defined."
-  (org-unmodified
-   (remove-text-properties (point-min) (point-max) '(org-summaries t)))
+  (with-silent-modifications
+    (remove-text-properties (point-min) (point-max) '(org-summaries t)))
   (let ((columns org-columns-current-fmt-compiled)
 	(org-columns-time (time-to-number-of-days (current-time)))
 	col)
@@ -996,9 +996,9 @@ Don't set this, this is meant for dynamic scoping.")
 	  (if (assoc property sum-alist)
 	      (setcdr (assoc property sum-alist) useval)
 	    (push (cons property useval) sum-alist)
-	    (org-unmodified
-	     (add-text-properties sumpos (1+ sumpos)
-				  (list 'org-summaries sum-alist))))
+	    (with-silent-modifications
+	      (add-text-properties sumpos (1+ sumpos)
+				   (list 'org-summaries sum-alist))))
 	  (when (and val (not (equal val (if flag str val))))
 	    (org-entry-put nil property (if flag str val)))
 	  ;; add current to current level accumulator
@@ -1509,9 +1509,8 @@ This will add overlays to the date lines, to show the summary for each day."
 	(save-excursion
 	  (save-restriction
 	    (widen)
-	    (org-unmodified
-	     (remove-text-properties (point-min) (point-max)
-				     '(org-summaries t)))
+	    (with-silent-modifications
+	      (remove-text-properties (point-min) (point-max) '(org-summaries t)))
 	    (goto-char (point-min))
 	    (org-columns-get-format-and-top-level)
 	    (while (setq fm (pop fmt))

+ 2 - 0
lisp/org-macs.el

@@ -117,6 +117,8 @@ Otherwise return nil."
 (def-edebug-spec org-preserve-lc (body))
 
 ;; Copied from bookmark.el
+;; Use `org-unmodified' to ignore real modifications, otherwise
+;; `with-silent-modifications' is enough to ignore cosmetic ones
 (defmacro org-unmodified (&rest body)
   "Run BODY while preserving the buffer's `buffer-modified-p' state."
   (org-with-gensyms (was-modified)

+ 65 - 66
lisp/org.el

@@ -8948,24 +8948,24 @@ call CMD."
 		  ((symbolp org-category) (symbol-name org-category))
 		  (t org-category)))
 	beg end cat pos optionp)
-    (org-unmodified
-     (save-excursion
-       (save-restriction
-	 (widen)
-	 (goto-char (point-min))
-	 (put-text-property (point) (point-max) 'org-category def-cat)
-	 (while (re-search-forward
-		 "^\\(#\\+CATEGORY:\\|[ \t]*:CATEGORY:\\)\\(.*\\)" nil t)
-	   (setq pos (match-end 0)
-		 optionp (equal (char-after (match-beginning 0)) ?#)
-		 cat (org-trim (match-string 2)))
-	   (if optionp
-	       (setq beg (point-at-bol) end (point-max))
-	     (org-back-to-heading t)
-	     (setq beg (point) end (org-end-of-subtree t t)))
-	   (put-text-property beg end 'org-category cat)
-	   (put-text-property beg end 'org-category-position beg)
-	   (goto-char pos)))))))
+    (with-silent-modifications
+      (save-excursion
+	(save-restriction
+	  (widen)
+	  (goto-char (point-min))
+	  (put-text-property (point) (point-max) 'org-category def-cat)
+	  (while (re-search-forward
+		  "^\\(#\\+CATEGORY:\\|[ \t]*:CATEGORY:\\)\\(.*\\)" nil t)
+	    (setq pos (match-end 0)
+		  optionp (equal (char-after (match-beginning 0)) ?#)
+		  cat (org-trim (match-string 2)))
+	    (if optionp
+		(setq beg (point-at-bol) end (point-max))
+	      (org-back-to-heading t)
+	      (setq beg (point) end (org-end-of-subtree t t)))
+	    (put-text-property beg end 'org-category cat)
+	    (put-text-property beg end 'org-category-position beg)
+	    (goto-char pos)))))))
 
 (defun org-refresh-properties (dprop tprop)
   "Refresh buffer text properties.
@@ -8973,17 +8973,17 @@ DPROP is the drawer property and TPROP is the corresponding text
 property to set."
   (let ((case-fold-search t)
 	(inhibit-read-only t) p)
-    (org-unmodified
-     (save-excursion
-       (save-restriction
-	 (widen)
-	 (goto-char (point-min))
-	 (while (re-search-forward (concat "^[ \t]*:" dprop ": +\\(.*\\)[ \t]*$") nil t)
-	   (setq p (org-match-string-no-properties 1))
-	   (save-excursion
-	     (org-back-to-heading t)
-	     (put-text-property
-	      (point-at-bol) (point-at-eol) tprop p))))))))
+    (with-silent-modifications
+      (save-excursion
+	(save-restriction
+	  (widen)
+	  (goto-char (point-min))
+	  (while (re-search-forward (concat "^[ \t]*:" dprop ": +\\(.*\\)[ \t]*$") nil t)
+	    (setq p (org-match-string-no-properties 1))
+	    (save-excursion
+	      (org-back-to-heading t)
+	      (put-text-property
+	       (point-at-bol) (point-at-eol) tprop p))))))))
 
 
 ;;;; Link Stuff
@@ -12159,16 +12159,15 @@ changes because there are unchecked boxes in this entry."
 
 (defun org-entry-blocked-p ()
   "Is the current entry blocked?"
-  (org-unmodified
-   (if (org-entry-get nil "NOBLOCKING")
-       nil ;; Never block this entry
-     (not
-      (run-hook-with-args-until-failure
-       'org-blocker-hook
-       (list :type 'todo-state-change
-	     :position (point)
-	     :from 'todo
-	     :to 'done))))))
+  (with-silent-modifications
+    (if (org-entry-get nil "NOBLOCKING")
+	nil ;; Never block this entry
+      (not (run-hook-with-args-until-failure
+	    'org-blocker-hook
+	    (list :type 'todo-state-change
+		  :position (point)
+		  :from 'todo
+		  :to 'done))))))
 
 (defun org-update-statistics-cookies (all)
   "Update the statistics cookie, either from TODO or from checkboxes.
@@ -17601,34 +17600,34 @@ When a buffer is unmodified, it is just killed.  When modified, it is saved
 	      (org-check-agenda-file file)
 	      (set-buffer (org-get-agenda-file-buffer file)))
 	    (widen)
-	    (org-unmodified
-	     (org-refresh-category-properties)
-	     (org-refresh-properties org-effort-property 'org-effort)
-	     (org-refresh-properties "APPT_WARNTIME" 'org-appt-warntime)
-	     (setq org-todo-keywords-for-agenda
-		   (append org-todo-keywords-for-agenda org-todo-keywords-1))
-	     (setq org-done-keywords-for-agenda
-		   (append org-done-keywords-for-agenda org-done-keywords))
-	     (setq org-todo-keyword-alist-for-agenda
-		   (append org-todo-keyword-alist-for-agenda org-todo-key-alist))
-	     (setq org-drawers-for-agenda
-		   (append org-drawers-for-agenda org-drawers))
-	     (setq org-tag-alist-for-agenda
-		   (append org-tag-alist-for-agenda org-tag-alist))
+	    (with-silent-modifications
+	      (org-refresh-category-properties)
+	      (org-refresh-properties org-effort-property 'org-effort)
+	      (org-refresh-properties "APPT_WARNTIME" 'org-appt-warntime)
+	      (setq org-todo-keywords-for-agenda
+		    (append org-todo-keywords-for-agenda org-todo-keywords-1))
+	      (setq org-done-keywords-for-agenda
+		    (append org-done-keywords-for-agenda org-done-keywords))
+	      (setq org-todo-keyword-alist-for-agenda
+		    (append org-todo-keyword-alist-for-agenda org-todo-key-alist))
+	      (setq org-drawers-for-agenda
+		    (append org-drawers-for-agenda org-drawers))
+	      (setq org-tag-alist-for-agenda
+		    (append org-tag-alist-for-agenda org-tag-alist))
 
-	     (save-excursion
-	       (remove-text-properties (point-min) (point-max) pall)
-	       (when org-agenda-skip-archived-trees
-		 (goto-char (point-min))
-		 (while (re-search-forward rea nil t)
-		   (if (org-at-heading-p t)
-		       (add-text-properties (point-at-bol) (org-end-of-subtree t) pa))))
-	       (goto-char (point-min))
-	       (setq re (format org-heading-keyword-regexp-format
-				org-comment-string))
-	       (while (re-search-forward re nil t)
-		 (add-text-properties
-		  (match-beginning 0) (org-end-of-subtree t) pc))))))))
+	      (save-excursion
+		(remove-text-properties (point-min) (point-max) pall)
+		(when org-agenda-skip-archived-trees
+		  (goto-char (point-min))
+		  (while (re-search-forward rea nil t)
+		    (if (org-at-heading-p t)
+			(add-text-properties (point-at-bol) (org-end-of-subtree t) pa))))
+		(goto-char (point-min))
+		(setq re (format org-heading-keyword-regexp-format
+				 org-comment-string))
+		(while (re-search-forward re nil t)
+		  (add-text-properties
+		   (match-beginning 0) (org-end-of-subtree t) pc))))))))
     (setq org-todo-keywords-for-agenda
           (org-uniquify org-todo-keywords-for-agenda))
     (setq org-todo-keyword-alist-for-agenda