]> git.eshelyaron.com Git - emacs.git/commitdiff
2006-06-18 Michael Kifer <kifer@cs.stonybrook.edu>
authorMichael Kifer <kifer@cs.stonybrook.edu>
Sun, 18 Jun 2006 17:08:24 +0000 (17:08 +0000)
committerMichael Kifer <kifer@cs.stonybrook.edu>
Sun, 18 Jun 2006 17:08:24 +0000 (17:08 +0000)
* viper-cmd.el (viper-special-read-and-insert-char): use
read-key-sequence.
(viper-after-change-undo-hook): enhancements.
(viper-after-change-undo-hook): new hook.
(viper-undo): use viper-after-change-undo-hook.
(viper-add-newline-at-eob-if-necessary): widen before making changes.
(viper-next-line-at-bol): If point is on a widget or a button, simulate
clicking on that widget/button.

* viper.el (viper-mode): allow for a separate cursor color in Emacs
state.

* ediff-diff (ediff-test-patch-utility): catch errors.
(ediff-actual-diff-options, ediff-actual-diff3-options): new variables.
(ediff-set-actual-diff-options): new function.
(ediff-reset-diff-options, ediff-toggle-ignore-case):
use ediff-set-actual-diff-options.
(ediff-extract-diffs): catch errors.
(ediff-whitespace): add nonbreakable space.
(ediff-same-file-contents): catch errors.

* ediff-mult.el (ediff-collect-custom-diffs): save
coding-system-for-read.

* ediff-vers.el (ediff-keep-tmp-versions): new var.
(ediff-vc-internal, ediff-vc-merge-internal): use
ediff-delete-version-file.
(ediff-delete-version-file): new function.

* ediff-wind.el (ediff-control-frame-parameters): set frame fringes.

* ediff.el (ediff-directories, ediff-directory-revisions,
ediff-merge-directories, ediff-merge-directories-with-ancestor,
ediff-directories-internal, ediff-merge-directory-revisions,
ediff-merge-directory-revisions-with-ancestor,
ediff-directories3): use read-directory-name.

lisp/ChangeLog
lisp/ediff-diff.el
lisp/ediff-mult.el
lisp/ediff-vers.el
lisp/ediff-wind.el
lisp/ediff.el
lisp/emulation/viper-cmd.el
lisp/emulation/viper-util.el
lisp/emulation/viper.el

index a6a72978852142e7554333391fe28c1f4d6abb86..9fd0500b825242a05a1cdf875782b3dbad5415be 100644 (file)
@@ -1,3 +1,42 @@
+2006-06-18  Michael Kifer  <kifer@cs.stonybrook.edu>
+       
+       * viper-cmd.el (viper-special-read-and-insert-char): use
+       read-key-sequence.
+       (viper-after-change-undo-hook): enhancements.
+       (viper-after-change-undo-hook): new hook.
+       (viper-undo): use viper-after-change-undo-hook.
+       (viper-add-newline-at-eob-if-necessary): widen before making changes.
+       (viper-next-line-at-bol): If point is on a widget or a button, simulate
+       clicking on that widget/button.
+       
+       * viper.el (viper-mode): allow for a separate cursor color in Emacs
+       state.
+       
+       * ediff-diff (ediff-test-patch-utility): catch errors.
+       (ediff-actual-diff-options, ediff-actual-diff3-options): new variables.
+       (ediff-set-actual-diff-options): new function.
+       (ediff-reset-diff-options, ediff-toggle-ignore-case):
+       use ediff-set-actual-diff-options.
+       (ediff-extract-diffs): catch errors.
+       (ediff-whitespace): add nonbreakable space.
+       (ediff-same-file-contents): catch errors.
+       
+       * ediff-mult.el (ediff-collect-custom-diffs): save
+       coding-system-for-read.
+       
+       * ediff-vers.el (ediff-keep-tmp-versions): new var.
+       (ediff-vc-internal, ediff-vc-merge-internal): use
+       ediff-delete-version-file.
+       (ediff-delete-version-file): new function.
+       
+       * ediff-wind.el (ediff-control-frame-parameters): set frame fringes.
+       
+       * ediff.el (ediff-directories, ediff-directory-revisions,
+       ediff-merge-directories, ediff-merge-directories-with-ancestor,
+       ediff-directories-internal, ediff-merge-directory-revisions,
+       ediff-merge-directory-revisions-with-ancestor,
+       ediff-directories3): use read-directory-name.
+       
 2006-06-18  Ralf Angeli  <angeli@caeruleus.net>
 
        * textmodes/tex-mode.el (tex-font-lock-match-suscript): Remove
index 7746954292ddcea843222097ce2c658fa1fe98a8..e3675064010e1f75ae50205787bfe2ee6250de7c 100644 (file)
@@ -65,10 +65,11 @@ Must produce output compatible with Unix's diff3 program."
 ;; The following functions needed for setting diff/diff3 options
 ;; test if diff supports the --binary option
 (defsubst ediff-test-utility (diff-util option &optional files)
-  (condition-case ()
+  (condition-case nil
       (eq 0 (apply 'call-process
                   (append (list diff-util nil nil nil option) files)))
-    (file-error nil)))
+    (error (format "Cannot execute program %S." diff-util)))
+  )
 
 (defun ediff-diff-mandatory-option (diff-util)
   (let ((file (if (boundp 'null-device) null-device "/dev/null")))
@@ -77,13 +78,17 @@ Must produce output compatible with Unix's diff3 program."
           ((and (string= diff-util ediff-diff-program)
                 (ediff-test-utility
                  ediff-diff-program "--binary" (list file file)))
-           "--binary")
+           "--binary ")
           ((and (string= diff-util ediff-diff3-program)
                 (ediff-test-utility
                  ediff-diff3-program "--binary" (list file file file)))
-           "--binary")
+           "--binary ")
           (t ""))))
 
+
+;; must be before ediff-reset-diff-options to avoid compiler errors
+(fset 'ediff-set-actual-diff-options '(lambda () nil))
+
 ;; make sure that mandatory options are added even if the user changes
 ;; ediff-diff-options or ediff-diff3-options in the customization widget
 (defun ediff-reset-diff-options (symb val)
@@ -91,12 +96,9 @@ Must produce output compatible with Unix's diff3 program."
          (if (eq symb 'ediff-diff-options)
              ediff-diff-program
            ediff-diff3-program))
-        (mandatory-option (ediff-diff-mandatory-option diff-program))
-        (spacer (if (string-equal mandatory-option "") "" " ")))
-    (set symb
-        (if (string-match mandatory-option val)
-            val
-          (concat mandatory-option spacer val)))
+        (mandatory-option (ediff-diff-mandatory-option diff-program)))
+    (set symb (concat mandatory-option val))
+    (ediff-set-actual-diff-options)
     ))
 
 
@@ -155,7 +157,7 @@ GNU diff3 doesn't have such an option."
   :group 'ediff-diff)
 
 ;; the actual options used in comparison
-(ediff-defvar-local ediff-actual-diff-options "" "")
+(ediff-defvar-local ediff-actual-diff-options ediff-diff-options "")
 
 (defcustom ediff-custom-diff-program ediff-diff-program
   "*Program to use for generating custom diff output for saving it in a file.
@@ -178,7 +180,7 @@ This output is not used by Ediff internally."
   :group 'ediff-diff)
 
 ;; the actual options used in comparison
-(ediff-defvar-local ediff-actual-diff3-options "" "")
+(ediff-defvar-local ediff-actual-diff3-options ediff-diff3-options "")
 
 (defcustom ediff-diff3-ok-lines-regexp
   "^\\([1-3]:\\|====\\|  \\|.*Warning *:\\|.*No newline\\|.*missing newline\\|^\C-m$\\)"
@@ -1272,7 +1274,9 @@ delimiter regions"))
                ;; Similarly for Windows-*
                ;; In DOS, must synchronize because DOS doesn't have
                ;; asynchronous processes.
-               (apply 'call-process program nil buffer nil args)
+               (condition-case nil
+                   (apply 'call-process program nil buffer nil args)
+                 (error (format "Cannot execute program %S." program)))
              ;; On other systems, do it asynchronously.
              (setq proc (get-buffer-process buffer))
              (if proc (kill-process proc))
@@ -1328,7 +1332,8 @@ delimiter regions"))
 Used for splitting difference regions into individual words.")
 (make-variable-buffer-local 'ediff-forward-word-function)
 
-(defvar ediff-whitespace " \n\t\f"
+;; \240 is unicode symbol for nonbreakable whitespace
+(defvar ediff-whitespace " \n\t\f\r\240"
   "*Characters constituting white space.
 These characters are ignored when differing regions are split into words.")
 (make-variable-buffer-local 'ediff-whitespace)
@@ -1442,11 +1447,13 @@ arguments to `skip-chars-forward'."
   "Return t if files F1 and F2 have identical contents."
   (if (and (not (file-directory-p f1))
            (not (file-directory-p f2)))
-      (let ((res
-            (apply 'call-process ediff-cmp-program nil nil nil
-                   (append ediff-cmp-options (list f1 f2)))))
-       (and (numberp res) (eq res 0))))
-  )
+      (condition-case nil
+         (let ((res
+                (apply 'call-process ediff-cmp-program nil nil nil
+                       (append ediff-cmp-options (list f1 f2)))))
+           (and (numberp res) (eq res 0)))
+       (error (format "Cannot execute program %S." ediff-cmp-program)))
+    ))
 
 
 (defun ediff-same-contents (d1 d2 &optional filter-re)
@@ -1521,21 +1528,30 @@ affects only files whose names match the expression."
       (setq file-list-list (cdr file-list-list)))
     (reverse result)))
 
+
+(defun ediff-set-actual-diff-options ()
+  (if ediff-ignore-case
+      (setq ediff-actual-diff-options 
+           (concat ediff-diff-options " " ediff-ignore-case-option)
+           ediff-actual-diff3-options
+           (concat ediff-diff3-options " " ediff-ignore-case-option3))
+    (setq ediff-actual-diff-options ediff-diff-options
+         ediff-actual-diff3-options ediff-diff3-options)
+    )
+  (setq-default ediff-actual-diff-options ediff-actual-diff-options
+               ediff-actual-diff3-options ediff-actual-diff3-options)
+  )
+
+
 ;; Ignore case handling - some ideas from drew.adams@@oracle.com
 (defun ediff-toggle-ignore-case ()
   (interactive)
   (ediff-barf-if-not-control-buffer)
   (setq ediff-ignore-case (not ediff-ignore-case))
-  (cond (ediff-ignore-case
-        (setq ediff-actual-diff-options
-              (concat ediff-diff-options " " ediff-ignore-case-option)
-              ediff-actual-diff3-options
-              (concat ediff-diff3-options " " ediff-ignore-case-option3))
-        (message "Ignoring regions that differ only in case"))
-       (t
-        (setq ediff-actual-diff-options ediff-diff-options
-              ediff-actual-diff3-options ediff-diff3-options)
-        (message "Ignoring case differences turned OFF")))
+  (ediff-set-actual-diff-options)
+  (if ediff-ignore-case
+      (message "Ignoring regions that differ only in case")
+    (message "Ignoring case differences turned OFF"))
   (cond (ediff-merge-job
         (message "Ignoring letter case is too dangerous in merge jobs"))
        ((and ediff-diff3-job (string= ediff-ignore-case-option3 ""))
index 0bbd3298c7a0538a33f67473fdc8c5112eaaf3c0..71859a5d4c5611eaea2e2f7eeb9b6163ca07319a 100644 (file)
@@ -1656,22 +1656,26 @@ This operation is defined only for `ediff-directories' and
 multifile patches.  For `ediff-directory-revisions', we insist that
 all marked sessions must be active."
   (interactive)
-  (or (ediff-buffer-live-p ediff-meta-diff-buffer)
-      (setq ediff-meta-diff-buffer
-           (get-buffer-create
-            (ediff-unique-buffer-name "*Ediff Multifile Diffs" "*"))))
-  (ediff-with-current-buffer ediff-meta-diff-buffer
-    (setq buffer-read-only nil)
-    (erase-buffer))
-  (if (> (ediff-operate-on-marked-sessions 'ediff-append-custom-diff) 0)
-      ;; did something
-      (progn
-       (display-buffer ediff-meta-diff-buffer 'not-this-window)
-       (ediff-with-current-buffer ediff-meta-diff-buffer
-         (set-buffer-modified-p nil)
-         (setq buffer-read-only t)))
-    (beep)
-    (message "No marked sessions found")))
+  (let ((coding-system-for-read ediff-coding-system-for-read))
+    (or (ediff-buffer-live-p ediff-meta-diff-buffer)
+       (setq ediff-meta-diff-buffer
+             (get-buffer-create
+              (ediff-unique-buffer-name "*Ediff Multifile Diffs" "*"))))
+    (ediff-with-current-buffer ediff-meta-diff-buffer
+                              (setq buffer-read-only nil)
+                              (erase-buffer))
+    (if (> (ediff-operate-on-marked-sessions 'ediff-append-custom-diff) 0)
+       ;; did something
+       (progn
+         (display-buffer ediff-meta-diff-buffer 'not-this-window)
+         (ediff-with-current-buffer ediff-meta-diff-buffer
+                                    (set-buffer-modified-p nil)
+                                    (setq buffer-read-only t))
+         (if (fboundp 'diff-mode)
+             (with-current-buffer ediff-meta-diff-buffer
+               (diff-mode))))
+      (beep)
+      (message "No marked sessions found"))))
 
 (defun ediff-meta-show-patch ()
   "Show the multi-file patch associated with this group session."
index 3e8b1c375723a2ba91d91e9aedc502ac20969840..4cd1492a1c77788c92a65b5cc55068c0f0e4670e 100644 (file)
         )))
 ;; end pacifier
 
+(defcustom ediff-keep-tmp-versions nil
+  "*If t, do not delete temporary previous versions for the files on which
+comparison or merge operations are being performed."
+  :type 'boolean
+  :group 'ediff-vers
+  )
+
 ;; VC.el support
 
 (defun ediff-vc-latest-version (file)
@@ -87,8 +94,8 @@
              file2 (buffer-file-name)))
       (setq startup-hooks
            (cons `(lambda ()
-                    (delete-file ,file1)
-                    (or ,(string= rev2 "") (delete-file ,file2)))
+                    (ediff-delete-version-file ,file1)
+                    (or ,(string= rev2 "") (ediff-delete-version-file ,file2)))
                  startup-hooks)))
     (ediff-buffers
      rev1buf rev2buf
       (setq startup-hooks
            (cons
             `(lambda ()
-               (delete-file ,(buffer-file-name buf1))
+               (ediff-delete-version-file ,(buffer-file-name buf1))
                (or ,(string= rev2 "")
-                   (delete-file ,(buffer-file-name buf2)))
+                   (ediff-delete-version-file ,(buffer-file-name buf2)))
                (or ,(string= ancestor-rev "")
                    ,(not ancestor-rev)
-                   (delete-file ,(buffer-file-name ancestor-buf)))
+                   (ediff-delete-version-file ,(buffer-file-name ancestor-buf)))
                )
             startup-hooks)))
     (if ancestor-rev
              (find-file-noselect (cvs-fileinfo->full-name fileinfo)))
            nil ; startup-hooks
            'ediff-revisions)))
-    (if (stringp tmp-file) (delete-file tmp-file))
-    (if (stringp ancestor-file) (delete-file ancestor-file))))
+    (if (stringp tmp-file) (ediff-delete-version-file tmp-file))
+    (if (stringp ancestor-file) (ediff-delete-version-file ancestor-file))))
+
+
+;; delete version file on exit unless ediff-keep-tmp-versions is true
+(defun ediff-delete-version-file (file)
+  (or ediff-keep-tmp-versions (delete-file file)))
 
 
 (provide 'ediff-vers)
index 28369f9f6bde36710f3dc2459ff59bd19151767c..c0786b9cc43521c20e983921defb2931e97444b5 100644 (file)
@@ -158,6 +158,8 @@ In this case, Ediff will use those frames to display these buffers."
    '(scrollbar-height . 0)        ; XEmacs only
    '(menu-bar-lines . 0)          ; Emacs only
    '(tool-bar-lines . 0)          ; Emacs 21+ only
+   '(left-fringe    . 0)
+   '(right-fringe   . 0)
    ;; don't lower but auto-raise
    '(auto-lower . nil)
    '(auto-raise . t)
index 14f634f0cd20d931600f0aa84eb4e7eaba41aa95..3e0be86b18b612b8b289b5be1624a50f472422df 100644 (file)
@@ -500,12 +500,13 @@ expression; only file names that match the regexp are considered."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         f)
-     (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil))
-          (ediff-read-file-name "Directory B to compare:"
-                                (if ediff-use-last-dir
-                                    ediff-last-dir-B
-                                  (ediff-strip-last-dir f))
-                                nil)
+     (list (setq f (read-directory-name
+                   "Directory A to compare:" dir-A nil 'must-match))
+          (read-directory-name "Directory B to compare:"
+                          (if ediff-use-last-dir
+                              ediff-last-dir-B
+                            (ediff-strip-last-dir f))
+                          nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -532,8 +533,8 @@ names.  Only the files that are under revision control are taken into account."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         )
-     (list (ediff-read-file-name
-           "Directory to compare with revision:" dir-A nil)
+     (list (read-directory-name
+           "Directory to compare with revision:" dir-A nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -561,17 +562,17 @@ regular expression; only file names that match the regexp are considered."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         f)
-     (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil))
-          (setq f (ediff-read-file-name "Directory B to compare:"
-                                        (if ediff-use-last-dir
-                                            ediff-last-dir-B
-                                          (ediff-strip-last-dir f))
-                                        nil))
-          (ediff-read-file-name "Directory C to compare:"
-                                (if ediff-use-last-dir
-                                    ediff-last-dir-C
-                                  (ediff-strip-last-dir f))
-                                nil)
+     (list (setq f (read-directory-name "Directory A to compare:" dir-A nil))
+          (setq f (read-directory-name "Directory B to compare:"
+                                  (if ediff-use-last-dir
+                                      ediff-last-dir-B
+                                    (ediff-strip-last-dir f))
+                                  nil 'must-match))
+          (read-directory-name "Directory C to compare:"
+                          (if ediff-use-last-dir
+                              ediff-last-dir-C
+                            (ediff-strip-last-dir f))
+                          nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -597,12 +598,13 @@ expression; only file names that match the regexp are considered."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         f)
-     (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil))
-          (ediff-read-file-name "Directory B to merge:"
-                                (if ediff-use-last-dir
-                                    ediff-last-dir-B
-                                  (ediff-strip-last-dir f))
-                                nil)
+     (list (setq f (read-directory-name "Directory A to merge:"
+                                       dir-A nil 'must-match))
+          (read-directory-name "Directory B to merge:"
+                          (if ediff-use-last-dir
+                              ediff-last-dir-B
+                            (ediff-strip-last-dir f))
+                          nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -633,17 +635,17 @@ only file names that match the regexp are considered."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         f)
-     (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil))
-          (setq f (ediff-read-file-name "Directory B to merge:"
+     (list (setq f (read-directory-name "Directory A to merge:" dir-A nil))
+          (setq f (read-directory-name "Directory B to merge:"
                                 (if ediff-use-last-dir
                                     ediff-last-dir-B
                                   (ediff-strip-last-dir f))
-                                nil))
-          (ediff-read-file-name "Ancestor directory:"
+                                nil 'must-match))
+          (read-directory-name "Ancestor directory:"
                                 (if ediff-use-last-dir
                                     ediff-last-dir-C
                                   (ediff-strip-last-dir f))
-                                nil)
+                                nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -669,8 +671,8 @@ names.  Only the files that are under revision control are taken into account."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         )
-     (list (ediff-read-file-name
-           "Directory to merge with revisions:" dir-A nil)
+     (list (read-directory-name
+           "Directory to merge with revisions:" dir-A nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -699,8 +701,9 @@ names.  Only the files that are under revision control are taken into account."
    (let ((dir-A (ediff-get-default-directory-name))
         (default-regexp (eval ediff-default-filtering-regexp))
         )
-     (list (ediff-read-file-name
-           "Directory to merge with revisions and ancestors:" dir-A nil)
+     (list (read-directory-name
+           "Directory to merge with revisions and ancestors:"
+           dir-A nil 'must-match)
           (read-string
            (if (stringp default-regexp)
                (format "Filter through regular expression (default %s): "
@@ -733,11 +736,6 @@ names.  Only the files that are under revision control are taken into account."
 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname
                                        &optional startup-hooks
                                        merge-autostore-dir)
-  ;; ediff-read-file-name is set to attach a previously entered file name if
-  ;; the currently entered file is a directory.  This code takes care of that.
-  (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))
-       dir2 (if (file-directory-p dir2) dir2 (file-name-directory dir2)))
-
   (if (stringp dir3)
       (setq dir3 (if (file-directory-p dir3) dir3 (file-name-directory dir3))))
 
@@ -763,7 +761,7 @@ names.  Only the files that are under revision control are taken into account."
             (ediff-merge-metajob jobname)
             (not merge-autostore-dir))
        (setq merge-autostore-dir
-             (read-file-name "Save merged files in directory: "
+             (read-directory-name "Save merged files in directory: "
                              (if ediff-use-last-dir
                                        ediff-last-merge-autostore-dir
                                      (ediff-strip-last-dir dir1))
@@ -823,7 +821,7 @@ names.  Only the files that are under revision control are taken into account."
             (ediff-merge-metajob jobname)
             (not merge-autostore-dir))
        (setq merge-autostore-dir
-             (read-file-name "Save merged files in directory: "
+             (read-directory-name "Save merged files in directory: "
                              (if ediff-use-last-dir
                                  ediff-last-merge-autostore-dir
                                (ediff-strip-last-dir dir1))
index 645f4f26eaf180bf98cf0b75b9ff560f20ac0187..0dce3b94ff0525704571e618f27276c26763e214 100644 (file)
@@ -887,12 +887,15 @@ Vi's prefix argument will be used.  Otherwise, the prefix argument passed to
                   (setq ch (aref (read-key-sequence nil) 0)))
               (insert ch))
              (t
-              (setq ch (read-char-exclusive))
+              ;;(setq ch (read-char-exclusive))
+              (setq ch (aref (read-key-sequence nil) 0))
               ;; replace ^M with the newline
               (if (eq ch ?\C-m) (setq ch ?\n))
               ;; Make sure ^V and ^Q work as quotation chars
               (if (memq ch '(?\C-v ?\C-q))
-                  (setq ch (read-char-exclusive)))
+                  ;;(setq ch (read-char-exclusive))
+                  (setq ch (aref (read-key-sequence nil) 0))
+                )
               (insert ch))
              )
        (setq last-command-event
@@ -1730,20 +1733,34 @@ invokes the command before that, etc."
 \f
 ;; undoing
 
+;; hook used inside undo
+(defvar viper-undo-functions nil)
+
+;; Runs viper-before-change-functions inside before-change-functions
+(defun viper-undo-sentinel (beg end length)
+  (run-hook-with-args 'viper-undo-functions beg end length))
+
+(add-hook 'after-change-functions 'viper-undo-sentinel)
+
+;; Hook used in viper-undo
+(defun viper-after-change-undo-hook (beg end len)
+  (setq undo-beg-posn beg
+       undo-end-posn (or end beg))
+  ;; some other hooks may be changing various text properties in
+  ;; the buffer in response to 'undo'; so remove this hook to avoid
+  ;; its repeated invocation
+  (remove-hook 'viper-undo-functions 'viper-after-change-undo-hook 'local))
+
 (defun viper-undo ()
   "Undo previous change."
   (interactive)
   (message "undo!")
   (let ((modified (buffer-modified-p))
         (before-undo-pt (point-marker))
-       (after-change-functions after-change-functions)
        undo-beg-posn undo-end-posn)
 
-    ;; no need to remove this hook, since this var has scope inside a let.
-    (add-hook 'after-change-functions
-             '(lambda (beg end len)
-                (setq undo-beg-posn beg
-                      undo-end-posn (or end beg))))
+    ;; the viper-after-change-undo-hook removes itself after the 1st invocation
+    (add-hook 'viper-undo-functions 'viper-after-change-undo-hook nil 'local)
 
     (undo-start)
     (undo-more 2)
@@ -1765,7 +1782,8 @@ invokes the command before that, etc."
            (goto-char undo-beg-posn)))
       (push-mark before-undo-pt t))
     (if (and (eolp) (not (bolp))) (backward-char 1))
-    (if (not modified) (set-buffer-modified-p t)))
+    ;;(if (not modified) (set-buffer-modified-p t))
+    )
   (setq this-command 'viper-undo))
 
 ;; Continue undoing previous changes.
@@ -1813,7 +1831,7 @@ invokes the command before that, etc."
            (setq viper-undo-needs-adjustment t)))))
 
 
-
+;;; Viper's destructive Command ring utilities
 
 (defun viper-display-current-destructive-command ()
   (let ((text (nth 4 viper-d-com))
@@ -1927,12 +1945,15 @@ Undo previous insertion and inserts new."
       (end-of-line)
       ;; make sure all lines end with newline, unless in the minibuffer or
       ;; when requested otherwise (require-final-newline is nil)
-      (if (and (eobp)
-              (not (bolp))
-              require-final-newline
-              (not (viper-is-in-minibuffer))
-              (not buffer-read-only))
-         (insert "\n"))))
+      (save-restriction
+       (widen)
+       (if (and (eobp)
+                (not (bolp))
+                require-final-newline
+                (not (viper-is-in-minibuffer))
+                (not buffer-read-only))
+           (insert "\n")))
+      ))
 
 (defun viper-yank-defun ()
   (mark-defun)
@@ -3045,19 +3066,34 @@ On reaching beginning of line, stop and signal error."
     (setq this-command 'next-line)
     (if com (viper-execute-com 'viper-next-line val com))))
 
+
 (defun viper-next-line-at-bol (arg)
-  "Next line at beginning of line."
+  "Next line at beginning of line.
+If point is on a widget or a button, simulate clicking on that widget/button."
   (interactive "P")
-  (viper-leave-region-active)
-  (save-excursion
-    (end-of-line)
-    (if (eobp) (error "Last line in buffer")))
-  (let ((val (viper-p-val arg))
-       (com (viper-getCom arg)))
-    (if com (viper-move-marker-locally 'viper-com-point (point)))
-    (forward-line val)
-    (back-to-indentation)
-    (if com (viper-execute-com 'viper-next-line-at-bol val com))))
+  (let* ((field (get-char-property (point) 'field))
+        (button (get-char-property (point) 'button))
+        (doc (get-char-property (point) 'widget-doc))
+        (widget (or field button doc)))
+    (if (and widget
+             (if (symbolp widget)
+                 (get widget 'widget-type)
+               (and (consp widget)
+                    (get (widget-type widget) 'widget-type))))
+        (widget-button-press (point))
+      (if (button-at (point))
+          (push-button)
+       ;; not a widget or a button
+        (viper-leave-region-active)
+        (save-excursion
+          (end-of-line)
+          (if (eobp) (error "Last line in buffer")))
+        (let ((val (viper-p-val arg))
+              (com (viper-getCom arg)))
+          (if com (viper-move-marker-locally 'viper-com-point (point)))
+          (forward-line val)
+          (back-to-indentation)
+          (if com (viper-execute-com 'viper-next-line-at-bol val com)))))))
 
 
 (defun viper-previous-line (arg)
index c7fe792b5f25d8fa100004f6e189054008710314..252088a476d06714d18824ad44da4a29813a9eca 100644 (file)
 
 (defsubst viper-get-cursor-color ()
   (viper-cond-compile-for-xemacs-or-emacs
-   ;; xemacs
-   (color-instance-name (frame-property (selected-frame) 'cursor-color))
+   (color-instance-name
+    (frame-property (selected-frame) 'cursor-color)) ; xemacs
    (cdr (assoc 'cursor-color (frame-parameters))) ; emacs
    ))
 
index fc55d291550df837cd801f4bb5846b8456718b9b..8f858526da3fa3da9f19f8747b04fc676bdf8f3a 100644 (file)
@@ -534,6 +534,10 @@ If Viper is enabled, turn it off.  Otherwise, turn it on."
 (defun viper-mode ()
   "Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Viper'."
   (interactive)
+  (if (null viper-vi-state-cursor-color)
+      (modify-frame-parameters
+       (selected-frame)
+       (list (cons 'viper-vi-state-cursor-color (viper-get-cursor-color)))))
   (if (not noninteractive)
       (progn
        ;; if the user requested viper-mode explicitly
@@ -545,8 +549,6 @@ If Viper is enabled, turn it off.  Otherwise, turn it on."
        (if viper-first-time ; Important check.  Prevents mix-up of startup
            (progn           ; and expert-level msgs when viper-mode recurses
              (setq viper-first-time nil)
-             (setq viper-vi-state-cursor-color
-                   (viper-get-cursor-color))
              (if (not viper-inhibit-startup-message)
                  (save-window-excursion
                    (setq viper-inhibit-startup-message t)