Browse Source

Undo: Cluster self-insert characters for undo

Undo will now remove up to 20 characters typed consecutively, just
like Emacs normally does.  We need a special implementation for this
because Org has its own self-insert command.

The code for doing this is a patch by Martin Pohlack.
Carsten Dominik 16 years ago
parent
commit
8b0d614702
4 changed files with 53 additions and 9 deletions
  1. 3 0
      doc/org.texi
  2. 9 0
      lisp/ChangeLog
  3. 21 8
      lisp/org-table.el
  4. 20 1
      lisp/org.el

+ 3 - 0
doc/org.texi

@@ -10745,6 +10745,9 @@ links, among other things.
 @i{Pete Phillips} helped during the development of the TAGS feature, and
 provided frequent feedback.
 @item
+@i{Martin Pohlack} provided the code snippet to bundle character insertion
+into bundles of 20 for undo.
+@item
 @i{T.V. Raman} reported bugs and suggested improvements.
 @item
 @i{Matthias Rempe} (Oelde) provided ideas, Windows support, and quality

+ 9 - 0
lisp/ChangeLog

@@ -1,3 +1,12 @@
+2009-02-25  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org-table.el (orgtbl-self-insert-command): Cluster undo for 20
+	characters.
+
+	* org.el (org-self-insert-cluster-for-undo): New option.
+	(org-self-insert-command): Cluster undo for 20 characters.
+	(org-self-insert-command-undo-counter): New variable.
+
 2009-02-24  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org-exp.el (org-export-as-html): Fix problem with closing colone

+ 21 - 8
lisp/org-table.el

@@ -3568,14 +3568,27 @@ overwritten, and the table is not marked as requiring realignment."
 	(goto-char (match-beginning 0))
 	(self-insert-command N))
     (setq org-table-may-need-update t)
-    (let (orgtbl-mode a)
-      (call-interactively
-       (or (key-binding
-	    (or (and (listp function-key-map)
-		     (setq a (assoc last-input-event function-key-map))
-		     (cdr a))
-		(vector last-input-event)))
-	   'self-insert-command)))))
+    (let* (orgtbl-mode
+	   a
+	   (cmd (or (key-binding
+		     (or (and (listp function-key-map)
+			      (setq a (assoc last-input-event function-key-map))
+			      (cdr a))
+			 (vector last-input-event)))
+	   'self-insert-command)))
+      (call-interactively cmd)
+      (if (and org-self-insert-cluster-for-undo
+	       (eq cmd 'self-insert-command))
+	  (if (not (eq last-command 'orgtbl-self-insert-command))
+	      (setq org-self-insert-command-undo-counter 1)
+	    (if (>= org-self-insert-command-undo-counter 20)
+		(setq org-self-insert-command-undo-counter 1)
+	      (and (> org-self-insert-command-undo-counter 0)
+		   buffer-undo-list
+		   (not (cadr buffer-undo-list)) ; remove nil entry
+		   (setcdr buffer-undo-list (cddr buffer-undo-list)))
+	      (setq org-self-insert-command-undo-counter
+		    (1+ org-self-insert-command-undo-counter))))))))
 
 (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
   "Regular expression matching exponentials as produced by calc.")

+ 20 - 1
lisp/org.el

@@ -903,6 +903,14 @@ See also the variable `org-table-auto-blank-field'."
 	  (const :tag "on" t)
 	  (const :tag "on, optimized" optimized)))
 
+(defcustom org-self-insert-cluster-for-undo t
+  "Non-nil means cluster self-insert commands for undo when possible.
+If this is set, then, like in the Emacs command loop, 20 consequtive
+characters will be undone together.
+This is configurable, because there is some impact on typing performance."
+  :group 'org-table
+  :type 'boolean)
+
 (defcustom org-table-tab-recognizes-table.el t
   "Non-nil means, TAB will automatically notice a table.el table.
 When it sees such a table, it moves point into it and - if necessary -
@@ -13286,7 +13294,18 @@ overwritten, and the table is not marked as requiring realignment."
 	(self-insert-command N))
     (setq org-table-may-need-update t)
     (self-insert-command N)
-    (org-fix-tags-on-the-fly)))
+    (org-fix-tags-on-the-fly)
+    (if org-self-insert-cluster-for-undo
+	(if (not (eq last-command 'org-self-insert-command))
+	    (setq org-self-insert-command-undo-counter 1)
+	  (if (>= org-self-insert-command-undo-counter 20)
+	      (setq org-self-insert-command-undo-counter 1)
+	    (and (> org-self-insert-command-undo-counter 0)
+		 buffer-undo-list
+		 (not (cadr buffer-undo-list)) ; remove nil entry
+		 (setcdr buffer-undo-list (cddr buffer-undo-list)))
+	    (setq org-self-insert-command-undo-counter
+		  (1+ org-self-insert-command-undo-counter)))))))
 
 (defun org-fix-tags-on-the-fly ()
   (when (and (equal (char-after (point-at-bol)) ?*)