Fixed some bugs related to coding systems and dvc-diff.
Some changes for XEmacs compatibility (incomplete).
Some clarifications to docs/xmtn-readme.txt .
Support monotone release 0.34.
diff -N -aur orig/docs/xmtn-readme.txt new/docs/xmtn-readme.txt
--- orig/docs/xmtn-readme.txt 2007-04-07 11:35:35.000000000 +0200
+++ new/docs/xmtn-readme.txt 2007-04-07 11:35:36.000000000 +0200
@@ -10,6 +10,9 @@
reusable by code that is unrelated to DVC, even though they currently
depend on the subprocess handling utilities that DVC provides.
+xmtn should work on GNU Emacs 21 or newer. Work on supporting XEmacs
+has started but is unfinished; patches welcome. On XEmacs, xmtn
+requires MULE.
* Download and installation
@@ -83,8 +86,10 @@
These commands can also be used from dired buffers.
C-x V s shows the status buffer. This currently shows modified,
-renamed and unknown files. I don't use it much, C-x V = seems
-preferable.
+renamed and unknown files. It's supposed to allow operations like
+diff, commit, revert etc. (like pcl-cvs), but that's not implemented
+yet. C-x V = is preferable at the moment, although it doesn't show
+unknown files.
C-x V a can be used to add a ChangeLog entry to _MTN/log.
@@ -112,9 +117,8 @@
the user has customized monotone's ignore_file hook in a way that
changes the meaning of this file.
-It would be nice to be able to perform operations such as diff and
-commit from the status buffer. For now, use the tree diff buffer for
-this.
+The ability to perform operations such as diff and commit from the
+status buffer is missing. For now, use the tree diff buffer for this.
xmtn doesn't define any key bindings for monotone-specific commands.
Only the backend-independent key bindings defined by DVC are available.
diff -N -aur orig/lisp/dvc-diff.el new/lisp/dvc-diff.el
--- orig/lisp/dvc-diff.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/dvc-diff.el 2007-04-07 11:35:36.000000000 +0200
@@ -725,9 +725,13 @@
(modified-file (make-temp-file "DVC-file-diff-mod")))
(with-temp-buffer
(insert (with-current-buffer base-buffer (buffer-string)))
+ (setq buffer-file-coding-system (with-current-buffer base-buffer
+ buffer-file-coding-system))
(write-file base-file))
(with-temp-buffer
(insert (with-current-buffer modified-buffer (buffer-string)))
+ (setq buffer-file-coding-system (with-current-buffer modified-buffer
+ buffer-file-coding-system))
(write-file modified-file))
(dvc-switch-to-buffer buffer)
(let ((inhibit-read-only t)
diff -N -aur orig/lisp/tests/xmtn-tests.el new/lisp/tests/xmtn-tests.el
--- orig/lisp/tests/xmtn-tests.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/tests/xmtn-tests.el 2007-04-07 11:35:36.000000000 +0200
@@ -34,7 +34,8 @@
(eval-and-compile
(require 'elunit)
(require 'cl)
- (require 'xmtn-match))
+ (require 'xmtn-match)
+ (require 'xmtn-dvc))
(defun xmtn-tests--keypair-string ()
"[keypair xmtn-test]
@@ -281,6 +282,48 @@
((($email ok $cert-name-here $cert-value-here t))
(assert (equal cert-name-here cert-name) t)
(assert (equal cert-value-here cert-value) t)))))))))
+ (dvc-file-diff-with-non-ascii-contents
+ (save-window-excursion
+ (let ((umlaut (string (make-char 'latin-iso8859-1 #xe4)))) ; umlaut a
+ (xmtn-tests--with-test-environment (&key root)
+ (let ((file-name "foo")
+ (contents (concat umlaut
+ "\n" ; avoid "buffer does not end in newline"
+ ))
+ (coding-system 'utf-8-unix))
+ (with-temp-buffer
+ (setq buffer-file-coding-system coding-system)
+ (insert contents)
+ (write-file file-name))
+ (xmtn--add-files root (list file-name))
+ (xmtn--run-command-sync root (list "commit" "--message=commit foo"))
+ (with-temp-buffer
+ (let ((coding-system-for-read coding-system))
+ (insert-file-contents file-name t))
+ (dvc-file-diff file-name)
+ (assert (eql (point-min) (point-max)))))))))
+ (buffer-file-coding-system-in-dvc-dvc-file-diff
+ (save-window-excursion
+ (let ((umlaut (string (make-char 'latin-iso8859-1 #xe4)))) ; umlaut a
+ (xmtn-tests--with-test-environment (&key root)
+ (let ((file-name "foo")
+ (contents (concat umlaut
+ "\n" ; avoid "buffer does not end in newline"
+ ))
+ (coding-system-1 'utf-8-unix)
+ (coding-system-2 'iso-8859-1-unix))
+ (with-temp-buffer
+ (setq buffer-file-coding-system coding-system-1)
+ (insert contents)
+ (write-file file-name))
+ (xmtn--add-files root (list file-name))
+ (xmtn--run-command-sync root (list "commit" "--message=commit foo"))
+ (with-temp-buffer
+ (insert-file-contents file-name t)
+ (setq buffer-file-coding-system coding-system-2)
+ (let ((coding-system-for-read coding-system-1))
+ (dvc-file-diff file-name))
+ (assert (not (eql (point-min) (point-max))))))))))
(file-diff-after-rename
(xmtn-tests--with-test-history (&key root ((:file-name file-name-1))
revision-2
@@ -288,7 +331,7 @@
(let ((file-name-2 "bar"))
(xmtn--run-command-sync root
(xmtn--version-case
- ((or mainline (> 0 33))
+ ((>= 0 34)
`("mv" "--" ,file-name-1 ,file-name-2))
(t
`("mv" "-e" "--" ,file-name-1
,file-name-2))))
diff -N -aur orig/lisp/xmtn-automate.el new/lisp/xmtn-automate.el
--- orig/lisp/xmtn-automate.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/xmtn-automate.el 2007-04-07 11:35:36.000000000 +0200
@@ -533,7 +533,8 @@
(signal t)))
(setq process (xmtn-automate--start-process session))
(setf (xmtn-automate--session-process session) process))
- (xmtn--assert-optional (buffer-name (xmtn-automate--session-buffer
session)))
+ (xmtn--assert-optional (buffer-live-p (xmtn-automate--session-buffer
+ session)))
process))
(defun xmtn-automate--new-buffer (session)
@@ -542,7 +543,7 @@
(buffer (generate-new-buffer buffer-base-name)))
(with-current-buffer buffer
(buffer-disable-undo)
- (set-buffer-multibyte nil)
+ (xmtn--set-buffer-multibyte nil)
(setq buffer-read-only t))
(setf (xmtn-automate--session-buffer session) buffer)
buffer))
@@ -594,7 +595,7 @@
(setq buffer (get-buffer-create buffer-name))
(with-current-buffer buffer
(buffer-disable-undo)
- (set-buffer-multibyte t)
+ (xmtn--set-buffer-multibyte t)
(setq buffer-read-only t)
(let ((inhibit-read-only t))
(when option-plist
@@ -642,7 +643,7 @@
mtn-number session-number))
(with-current-buffer buffer
(buffer-disable-undo)
- (set-buffer-multibyte nil)
+ (xmtn--set-buffer-multibyte nil)
(setq buffer-read-only t)
(xmtn--assert-optional (and (eql (point) (point-min))
(eql (point) (point-max))))
@@ -689,7 +690,7 @@
((= chars-to-read 0)
nil)
((> chars-to-read 0)
- (if (null (buffer-name command-output-buffer))
+ (if (not (buffer-live-p command-output-buffer))
;; Buffer has already been killed, just discard input.
(progn)
(with-current-buffer command-output-buffer
@@ -809,6 +810,20 @@
;; t)
(set-marker read-marker (match-end 0)))
(setq tag 'again))
+ ;; This is just a simple heuristic, there are many
+ ;; kinds of invalid input that it doesn't detect.
+ ;; FIXME: This can errorneously be triggered by
+ ;; warnings that mtn prints on stderr; but Emacs
+ ;; interleaves stdout and stderr (see (elisp)
+ ;; Output from Processes) with no way to
+ ;; distinguish between them. We'll probably have
+ ;; to spawn mtn inside a shell that redirects
+ ;; stderr to a file. But I don't think that's
+ ;; possible in a portable way...
+ ((looking-at "[^0-9]")
+ (error "Invalid output from mtn: %s"
+ (buffer-substring-no-properties (point)
+ (point-max))))
(t
(xmtn--assert-optional command)
(setq tag 'exit-loop)))))
@@ -823,11 +838,15 @@
(let ((status (process-status process))
(session (xmtn-automate--process-session process)))
(let ((buffer (xmtn-automate--session-buffer session)))
- (when (buffer-name buffer)
+ (when (buffer-live-p buffer)
(with-current-buffer buffer
(let ((inhibit-read-only t)
deactivate-mark)
(save-excursion
+ ;; This seems to fail in XEmacs when running the test
+ ;; `file-diff'. I don't know why.
+ (xmtn--assert-optional (marker-position (process-mark process))
+ t)
(goto-char (process-mark process))
(insert (format "\n(process exited: %S)\n"
(if (eql (aref event-string
@@ -865,7 +884,7 @@
(let ((session (xmtn-automate--process-session process)))
(let ((buffer (xmtn-automate--session-buffer session)))
(xmtn--assert-optional (eql (process-buffer process) buffer))
- (xmtn--assert-optional (buffer-name buffer))
+ (xmtn--assert-optional (buffer-live-p buffer))
(with-current-buffer buffer
(let* ((mark (process-mark process))
(move-point-p (= (point) mark)))
diff -N -aur orig/lisp/xmtn-compat.el new/lisp/xmtn-compat.el
--- orig/lisp/xmtn-compat.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/xmtn-compat.el 2007-04-07 11:35:36.000000000 +0200
@@ -33,6 +33,11 @@
(eval-and-compile
(require 'cl))
+(defun xmtn--temp-directory ()
+ (if (fboundp 'temp-directory)
+ (temp-directory)
+ temporary-file-directory))
+
(defun xmtn--make-temp-file (prefix &optional dirp suffix)
;; Do this in a temp buffer to ensure we use the default file output
;; encoding. Emacs 21's `make-temp-file' uses the current buffer's
@@ -40,6 +45,9 @@
;; with a string as its first argument, but coding conversion errors
;; when `write-region' is called in this way.
(with-temp-buffer
+ ;; XEmacs' `make-temp-file' doesn't automatically use temp
+ ;; directory.
+ (setq prefix (expand-file-name prefix (xmtn--temp-directory)))
;; FIXME: Ignoring suffix for now since Emacs 21 doesn't support it.
(make-temp-file prefix dirp)))
@@ -83,6 +91,11 @@
`(with-no-warnings ,@body)
`(progn ,@body)))
+(defmacro* xmtn--with-temp-message (message &body body)
+ (if (fboundp 'with-temp-message)
+ `(with-temp-message ,message ,@body)
+ `(progn ,@body)))
+
(defmacro* xmtn--dotimes-with-progress-reporter ((i n-form &optional res-form)
message-form
&body body)
@@ -92,11 +105,15 @@
(let ((message (gensym)))
`(let ((,message ,message-form))
(prog1
- (with-temp-message ,message
+ (xmtn--with-temp-message ,message
(dotimes (,i ,n-form ,res-form)
,@body))
(message "%sdone" ,message))))))
+(defun xmtn--set-buffer-multibyte (flag)
+ (when (fboundp 'set-buffer-multibyte)
+ (set-buffer-multibyte flag)))
+
(provide 'xmtn-compat)
;;; xmtn-compat.el ends here
diff -N -aur orig/lisp/xmtn-dvc.el new/lisp/xmtn-dvc.el
--- orig/lisp/xmtn-dvc.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/xmtn-dvc.el 2007-04-07 11:35:36.000000000 +0200
@@ -41,7 +41,9 @@
(require 'xmtn-ids)
(require 'xmtn-match)
(require 'dvc-log)
- (require 'dvc-diff))
+ (require 'dvc-diff)
+ (require 'dvc-core)
+ (require 'ewoc))
;; For debugging.
(defun xmtn--load ()
@@ -832,7 +834,7 @@
(xmtn--run-command-sync
root `("rename"
,@(xmtn--version-case
- ((or mainline (> 0 33))
+ ((>= 0 34)
(if do-not-execute `("--bookkeep-only") `()))
(t
(if do-not-execute `() `("--execute"))))
@@ -1082,15 +1084,43 @@
;; should be computed against an empty file. So just
;; leave the buffer empty.
(progn)
- ;; Note: This could be simplified slightly with the new
- ;; automate get_file_of operation. Not worth any effort
- ;; right now, though. And it would break compatibility with
- ;; 0.30 for no good reason.
- (let ((contents-hash
- (xmtn--revision-file-contents-hash root backend-id
- corresponding-file)))
- (xmtn--insert-file-contents root contents-hash
- (current-buffer))))))))
+ (let (temp-dir)
+ (unwind-protect
+ (progn
+ (setq temp-dir (xmtn--make-temp-file
+ "xmtn--revision-get-file-" t))
+ ;; Using `insert-file-contents' in conjunction with
+ ;; as much of the original file name as possible
+ ;; seems to be the best way to make sure that Emacs'
+ ;; entire file coding system detection logic is
+ ;; applied. Functions like
+ ;; `find-operation-coding-system' and
+ ;; `find-file-name-handler' are not a complete
+ ;; replacement since they don't look at the contents
+ ;; at all.
+ (let ((temp-file (concat temp-dir "/" corresponding-file)))
+ (make-directory (file-name-directory temp-file) t)
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (setq buffer-file-coding-system 'binary)
+ ;; This could be simplified slightly with the
+ ;; new automate get_file_of operation. Not
+ ;; worth any effort right now, though. And it
+ ;; would break compatibility with 0.30 for no
+ ;; good reason.
+ (let ((contents-hash
+ (xmtn--revision-file-contents-hash
+ root backend-id corresponding-file)))
+ (xmtn--insert-file-contents root contents-hash
+ (current-buffer)))
+ (write-file temp-file))
+ (let ((output-buffer (current-buffer)))
+ (with-temp-buffer
+ (insert-file-contents temp-file)
+ (let ((input-buffer (current-buffer)))
+ (with-current-buffer output-buffer
+ (insert-buffer-substring input-buffer)))))))
+ (dvc-delete-recursively temp-dir))))))))
(defun xmtn--get-corresponding-path (root normalized-file-name
diff -N -aur orig/lisp/xmtn-match.el new/lisp/xmtn-match.el
--- orig/lisp/xmtn-match.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/xmtn-match.el 2007-04-07 11:35:36.000000000 +0200
@@ -57,6 +57,16 @@
;; (pprint (macroexpand '(xmtn-match x ([t $y ($y . t)] y))))
+(deftype xmtn-match--bool-vector ()
+ (if (fboundp 'bool-vector-p)
+ ;; For Emacs.
+ `bool-vector
+ ;; For XEmacs.
+ `nil))
+
+(deftype xmtn-match--atom ()
+ `(not cons))
+
;; They say it's bad style if function definitions are too big to fit
;; on a screen. A small font is recommended for this one.
(defun xmtn-match--generate-branch (var-name-prefix-char
@@ -96,7 +106,7 @@
`(,part-reader ,subobject)))))
;; I think this will also allow char-tables.
;; Not sure how useful that is.
- ((and array (not string) (not bool-vector))
+ ((and array (not string) (not xmtn-match--bool-vector))
`((unless (and (typep ,subobject ',(type-of
subpattern))
(eql (length ,subobject)
,(length subpattern)))
@@ -105,7 +115,7 @@
append (walk-part
(aref subpattern index)
`(aref ,subobject ,index)))))
- (t ;; Should be atom, but that errors.
+ (xmtn-match--atom
(if (and (symbolp subpattern)
(eql (aref (symbol-name subpattern) 0)
var-name-prefix-char))
diff -N -aur orig/lisp/xmtn-run.el new/lisp/xmtn-run.el
--- orig/lisp/xmtn-run.el 2007-04-07 11:35:35.000000000 +0200
+++ new/lisp/xmtn-run.el 2007-04-07 11:35:36.000000000 +0200
@@ -33,7 +33,9 @@
(eval-and-compile
(require 'cl)
- (require 'dvc-unified))
+ (require 'dvc-unified)
+ (when (featurep 'xemacs)
+ (require 'un-define)))
(define-coding-system-alias 'xmtn--monotone-normal-form 'utf-8-unix)
@@ -136,7 +138,9 @@
(setq got-output-p t)))
nil))))))))
(lambda ()
- (while (accept-process-output process))
+ (assert (member (process-status process) '(run exit signal)) t)
+ (while (and (eql (process-status process) 'run)
+ (accept-process-output process)))
(assert (member (process-status process) '(exit signal)) t)
;; This (including discarding input) is needed to allow the
;; sentinel to run, at least on GNU Emacs 21.4.2 and on GNU
@@ -297,12 +301,12 @@
;; while they generally have syntax and semantics that match the
;; upcoming release; i.e., their syntax and semantics don't match
;; the version number they report.)
- `(let ((.latest. (xmtn--latest-mtn-release)))
- (or (> (car ,version-var) (car .latest.))
- (and (= (car ,version-var) (car .latest.))
- (or (> (cadr ,version-var) (cadr .latest.))
- (and (= (cadr ,version-var) (cadr .latest.))
- (not (equal (caddr .latest.)
+ `(let ((-latest- (xmtn--latest-mtn-release)))
+ (or (> (car ,version-var) (car -latest-))
+ (and (= (car ,version-var) (car -latest-))
+ (or (> (cadr ,version-var) (cadr -latest-))
+ (and (= (cadr ,version-var) (cadr -latest-))
+ (not (equal (caddr -latest-)
(caddr ,version-var)))))))))
(t
(let ((operator (car condition))
@@ -356,9 +360,9 @@
collect condition)))))))
(defun xmtn--latest-mtn-release ()
- ;; Version and revision id of the latest mtn release at the time of
- ;; this xmtn release,
- '(0 33 "f93b47fe55221c5ce51cc01e522ec0b92df49a2b"))
+ ;; Version number and revision id of the latest mtn release at the
+ ;; time of this xmtn release.
+ '(0 34 "6ae6de16b31495a773ac3002505ad51f2e4a8616"))
(provide 'xmtn-run)
_______________________________________________
Dvc-dev mailing list
[email protected]
https://mail.gna.org/listinfo/dvc-dev