summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog35
-rw-r--r--lisp/diff-mode.el65
-rw-r--r--lisp/vc-arch.el25
-rw-r--r--lisp/vc-cvs.el30
-rw-r--r--lisp/vc-git.el21
-rw-r--r--lisp/vc-hg.el12
-rw-r--r--lisp/vc-hooks.el7
-rw-r--r--lisp/vc.el60
8 files changed, 197 insertions, 58 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 6a74584fbd4..dfa662b791c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,38 @@
+2007-07-30 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * vc-git.el: (vc-directory-exclusion-list, vc-handled-backends):
+ Remove.
+ (vc-git-revision-completion-table): Enable.
+
+ * vc-hooks.el (vc-handled-backends): Add GIT and HG.
+
+ * vc.el (vc-directory-exclusion-list): Add .git and .hg.
+
+ * vc-hg.el (vc-hg-revision-completion-table): Re-enable.
+
+ * diff-mode.el (diff-mode-menu): New entries.
+
+2007-06-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * diff-mode.el (diff-beginning-of-file-and-junk): New function.
+ (diff-file-kill): Use it.
+ (diff-beginning-of-hunk): Add arg `try-harder' using it.
+ (diff-restrict-view, diff-find-source-location, diff-refine-hunk):
+ Use it so they find the hunk even when we're in the file header.
+
+ * vc.el: Add new VC operation `revision-completion-table'.
+ (vc-default-revision-completion-table): New function.
+ (vc-version-diff, vc-version-other-window): Use it to provide
+ completion of revision names if the backend provides it.
+
+ * vc-arch.el (vc-arch--version-completion-table)
+ (vc-arch-revision-completion-table): New functions to provide
+ completion of revision names.
+
+ * vc-cvs.el: Require CL.
+ (vc-cvs-revision-table, vc-cvs-revision-completion-table):
+ New functions to provide completion of revision names.
+
2007-07-29 Kimit Yada <kimitto@gmail.com> (tiny change)
* emacs-lisp/copyright.el (copyright-update-year, copyright-update)
diff --git a/lisp/diff-mode.el b/lisp/diff-mode.el
index 3f96ba6e453..f2800f1c337 100644
--- a/lisp/diff-mode.el
+++ b/lisp/diff-mode.el
@@ -164,12 +164,23 @@ when editing big diffs)."
'("Diff"
["Jump to Source" diff-goto-source t]
["Apply hunk" diff-apply-hunk t]
+ ["Test applying hunk" diff-test-hunk t]
["Apply diff with Ediff" diff-ediff-patch t]
- ["-----" nil nil]
+ "-----"
["Reverse direction" diff-reverse-direction t]
["Context -> Unified" diff-context->unified t]
["Unified -> Context" diff-unified->context t]
;;["Fixup Headers" diff-fixup-modifs (not buffer-read-only)]
+ "-----"
+ ["Split hunk" diff-split-hunk t]
+ ["Refine hunk" diff-refine-hunk t]
+ ["Kill current hunk" diff-hunk-kill t]
+ ["Kill current file's hunks" diff-file-kill t]
+ "-----"
+ ["Previous Hunk" diff-hunk-prev t]
+ ["Next Hunk" diff-hunk-next t]
+ ["Previous File" diff-file-prev t]
+ ["Next File" diff-file-next t]
))
(defcustom diff-minor-mode-prefix "\C-c="
@@ -390,13 +401,20 @@ when editing big diffs)."
;; The return value is used by easy-mmode-define-navigation.
(goto-char (or end (point-max)))))
-(defun diff-beginning-of-hunk ()
+(defun diff-beginning-of-hunk (&optional try-harder)
+ "Move back to beginning of hunk.
+If TRY-HARDER is non-nil, try to cater to the case where we're not in a hunk
+but in the file header instead, in which case move forward to the first hunk."
(beginning-of-line)
(unless (looking-at diff-hunk-header-re)
(forward-line 1)
(condition-case ()
(re-search-backward diff-hunk-header-re)
- (error (error "Can't find the beginning of the hunk")))))
+ (error
+ (if (not try-harder)
+ (error "Can't find the beginning of the hunk")
+ (diff-beginning-of-file-and-junk)
+ (diff-hunk-next))))))
(defun diff-beginning-of-file ()
(beginning-of-line)
@@ -425,7 +443,7 @@ when editing big diffs)."
If the prefix ARG is given, restrict the view to the current file instead."
(interactive "P")
(save-excursion
- (if arg (diff-beginning-of-file) (diff-beginning-of-hunk))
+ (if arg (diff-beginning-of-file) (diff-beginning-of-hunk 'try-harder))
(narrow-to-region (point)
(progn (if arg (diff-end-of-file) (diff-end-of-hunk))
(point)))
@@ -453,18 +471,37 @@ If the prefix ARG is given, restrict the view to the current file instead."
(diff-end-of-hunk)
(kill-region start (point)))))
+(defun diff-beginning-of-file-and-junk ()
+ "Go to the beginning of file-related diff-info.
+This is like `diff-beginning-of-file' except it tries to skip back over leading
+data such as \"Index: ...\" and such."
+ (let ((start (point))
+ (file (condition-case err (progn (diff-beginning-of-file) (point))
+ (error err)))
+ ;; prevhunk is one of the limits.
+ (prevhunk (save-excursion (ignore-errors (diff-hunk-prev) (point))))
+ err)
+ (when (consp file)
+ ;; Presumably, we started before the file header, in the leading junk.
+ (setq err file)
+ (diff-file-next)
+ (setq file (point)))
+ (let ((index (save-excursion
+ (re-search-backward "^Index: " prevhunk t))))
+ (when index (setq file index))
+ (if (<= file start)
+ (goto-char file)
+ ;; File starts *after* the starting point: we really weren't in
+ ;; a file diff but elsewhere.
+ (goto-char start)
+ (signal (car err) (cdr err))))))
+
(defun diff-file-kill ()
"Kill current file's hunks."
(interactive)
- (diff-beginning-of-file)
+ (diff-beginning-of-file-and-junk)
(let* ((start (point))
- (prevhunk (save-excursion
- (ignore-errors
- (diff-hunk-prev) (point))))
- (index (save-excursion
- (re-search-backward "^Index: " prevhunk t)))
(inhibit-read-only t))
- (when index (setq start index))
(diff-end-of-file)
(if (looking-at "^\n") (forward-char 1)) ;`tla' generates such diffs.
(kill-region start (point))))
@@ -1289,7 +1326,8 @@ SRC and DST are the two variants of text as returned by `diff-hunk-text'.
SWITCHED is non-nil if the patch is already applied."
(save-excursion
(let* ((other (diff-xor other-file diff-jump-to-old-file))
- (char-offset (- (point) (progn (diff-beginning-of-hunk) (point))))
+ (char-offset (- (point) (progn (diff-beginning-of-hunk 'try-harder)
+ (point))))
;; Check that the hunk is well-formed. Otherwise diff-mode and
;; the user may disagree on what constitutes the hunk
;; (e.g. because an empty line truncates the hunk mid-course),
@@ -1458,7 +1496,8 @@ For use in `add-log-current-defun-function'."
(defun diff-refine-hunk ()
"Refine the current hunk by ignoring space differences."
(interactive)
- (let* ((char-offset (- (point) (progn (diff-beginning-of-hunk) (point))))
+ (let* ((char-offset (- (point) (progn (diff-beginning-of-hunk 'try-harder)
+ (point))))
(opts (case (char-after) (?@ "-bu") (?* "-bc") (t "-b")))
(line-nb (and (or (looking-at "[^0-9]+\\([0-9]+\\)")
(error "Can't find line number"))
diff --git a/lisp/vc-arch.el b/lisp/vc-arch.el
index b0cdea9d31f..68a1b1b5f17 100644
--- a/lisp/vc-arch.el
+++ b/lisp/vc-arch.el
@@ -419,6 +419,31 @@ Return non-nil if FILE is unchanged."
(defun vc-arch-init-version () nil)
+;;; Completion of versions and revisions.
+
+(defun vc-arch--version-completion-table (root string)
+ (delq nil
+ (mapcar
+ (lambda (d)
+ (when (string-match "/\\([^/]+\\)/\\([^/]+\\)\\'" d)
+ (concat (match-string 2 d) "/" (match-string 1 d))))
+ (let ((default-directory root))
+ (file-expand-wildcards
+ (concat "*/*/"
+ (if (string-match "/" string)
+ (concat (substring string (match-end 0))
+ "*/" (substring string 0 (match-beginning 0)))
+ (concat "*/" string))
+ "*"))))))
+
+(defun vc-arch-revision-completion-table (file)
+ (lexical-let ((file file))
+ (lambda (string pred action)
+ ;; FIXME: complete revision patches as well.
+ (let* ((root (expand-file-name "{arch}" (vc-arch-root file)))
+ (table (vc-arch--version-completion-table root string)))
+ (complete-with-action action table string pred)))))
+
;;; Less obvious implementations.
(defun vc-arch-find-version (file rev buffer)
diff --git a/lisp/vc-cvs.el b/lisp/vc-cvs.el
index 0c9615e6469..a0eb2609ade 100644
--- a/lisp/vc-cvs.el
+++ b/lisp/vc-cvs.el
@@ -29,8 +29,7 @@
;;; Code:
-(eval-when-compile
- (require 'vc))
+(eval-when-compile (require 'cl) (require 'vc))
;;;
;;; Customization options
@@ -960,6 +959,33 @@ is non-nil."
(vc-file-setprop file 'vc-checkout-time 0)
(if set-state (vc-file-setprop file 'vc-state 'edited)))))))))
+;; Completion of revision names.
+;; Just so I don't feel like I'm duplicating code from pcl-cvs, I'll use
+;; `cvs log' so I can list all the revision numbers rather than only
+;; tag names.
+
+(defun vc-cvs-revision-table (file)
+ (let ((default-directory (file-name-directory file))
+ (res nil))
+ (with-temp-buffer
+ (vc-cvs-command t nil file "log")
+ (goto-char (point-min))
+ (when (re-search-forward "^symbolic names:\n" nil t)
+ (while (looking-at "^ \\(.*\\): \\(.*\\)")
+ (push (cons (match-string 1) (match-string 2)) res)
+ (forward-line 1)))
+ (while (re-search-forward "^revision \\([0-9.]+\\)" nil t)
+ (push (match-string 1) res))
+ res)))
+
+(defun vc-cvs-revision-completion-table (file)
+ (lexical-let ((file file)
+ table)
+ (setq table (lazy-completion-table
+ table (lambda () (vc-cvs-revision-table file))))
+ table))
+
+
(provide 'vc-cvs)
;;; arch-tag: 60e1402a-aa53-4607-927a-cf74f144b432
diff --git a/lisp/vc-git.el b/lisp/vc-git.el
index c0cfc1e88cc..256be2c6f03 100644
--- a/lisp/vc-git.el
+++ b/lisp/vc-git.el
@@ -111,13 +111,6 @@
(eval-when-compile (require 'cl) (require 'vc))
-;; XXX when this backend is considered sufficiently reliable this
-;; should be moved to vc-hooks.el
-(add-to-list 'vc-handled-backends 'GIT)
-(eval-after-load "vc"
- '(add-to-list 'vc-directory-exclusion-list ".git" t))
-
-
(defvar git-commits-coding-system 'utf-8
"Default coding system for git commits.")
@@ -331,14 +324,12 @@
(push (match-string 2) table)))
table))
-;; Commented out on the 22.x branch, VC here does not support it yet
-;; and when bytecompiling it max-specpdl-size is exceeded.
-;; (defun vc-git-revision-completion-table (file)
-;; (lexical-let ((file file)
-;; table)
-;; (setq table (lazy-completion-table
-;; table (lambda () (vc-git-revision-table file))))
-;; table))
+(defun vc-git-revision-completion-table (file)
+ (lexical-let ((file file)
+ table)
+ (setq table (lazy-completion-table
+ table (lambda () (vc-git-revision-table file))))
+ table))
(defun vc-git-diff-tree (dir &optional rev1 rev2)
(vc-git-diff dir rev1 rev2))
diff --git a/lisp/vc-hg.el b/lisp/vc-hg.el
index ea32c4a33b6..972adeed675 100644
--- a/lisp/vc-hg.el
+++ b/lisp/vc-hg.el
@@ -292,12 +292,12 @@
(buffer-substring-no-properties (point-min) (point-max))))))
;; Modelled after the similar function in vc-cvs.el
-;; (defun vc-hg-revision-completion-table (file)
-;; (lexical-let ((file file)
-;; table)
-;; (setq table (lazy-completion-table
-;; table (lambda () (vc-hg-revision-table file))))
-;; table))
+(defun vc-hg-revision-completion-table (file)
+ (lexical-let ((file file)
+ table)
+ (setq table (lazy-completion-table
+ table (lambda () (vc-hg-revision-table file))))
+ table))
(defalias 'vc-hg-diff-tree 'vc-hg-diff)
diff --git a/lisp/vc-hooks.el b/lisp/vc-hooks.el
index a47637d37ee..5a0c5395b96 100644
--- a/lisp/vc-hooks.el
+++ b/lisp/vc-hooks.el
@@ -62,8 +62,9 @@ interpreted as hostnames."
:type 'regexp
:group 'vc)
-(defcustom vc-handled-backends '(RCS CVS SVN SCCS Arch MCVS)
- ;; Arch and MCVS come last because they are per-tree rather than per-dir.
+(defcustom vc-handled-backends '(RCS CVS SVN SCCS GIT HG Arch MCVS)
+ ;; GIT, HG, Arch and MCVS come last because they are per-tree rather
+ ;; than per-dir.
"*List of version control backends for which VC will be used.
Entries in this list will be tried in order to determine whether a
file is under that sort of version control.
@@ -71,7 +72,7 @@ Removing an entry from the list prevents VC from being activated
when visiting a file managed by that backend.
An empty list disables VC altogether."
:type '(repeat symbol)
- :version "21.1"
+ :version "22.2"
:group 'vc)
(defcustom vc-path
diff --git a/lisp/vc.el b/lisp/vc.el
index c3c03131caa..835d2c50685 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -327,6 +327,11 @@
;; of either 0 (no differences found), or 1 (either non-empty diff
;; or the diff is run asynchronously).
;;
+;; - revision-completion-table (file)
+;;
+;; Return a completion table for existing revisions of FILE.
+;; The default is to not use any completion table.
+;;
;; - diff-tree (dir &optional rev1 rev2)
;;
;; Insert the diff for all files at and below DIR into the *vc-diff*
@@ -559,7 +564,8 @@ These are passed to the checkin program by \\[vc-register]."
:group 'vc
:version "20.3")
-(defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS" "MCVS" ".svn" "{arch}")
+(defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS" "MCVS" ".svn"
+ ".git" ".hg" "{arch}")
"List of directory names to be ignored when walking directory trees."
:type '(repeat string)
:group 'vc)
@@ -1752,6 +1758,8 @@ saving the buffer."
(message "No changes to %s since latest version" file)
(vc-version-diff file nil nil)))))
+(defun vc-default-revision-completion-table (backend file) nil)
+
(defun vc-version-diff (file rev1 rev2)
"List the differences between FILE's versions REV1 and REV2.
If REV1 is empty or nil it means to use the current workfile version;
@@ -1759,12 +1767,13 @@ REV2 empty or nil means the current file contents. FILE may also be
a directory, in that case, generate diffs between the correponding
versions of all registered files in or below it."
(interactive
- (let ((file (expand-file-name
- (read-file-name (if buffer-file-name
- "File or dir to diff (default visited file): "
- "File or dir to diff: ")
- default-directory buffer-file-name t)))
- (rev1-default nil) (rev2-default nil))
+ (let* ((file (expand-file-name
+ (read-file-name (if buffer-file-name
+ "File or dir to diff (default visited file): "
+ "File or dir to diff: ")
+ default-directory buffer-file-name t)))
+ (rev1-default nil) (rev2-default nil)
+ (completion-table (vc-call revision-completion-table file)))
;; compute default versions based on the file state
(cond
;; if it's a directory, don't supply any version default
@@ -1780,17 +1789,21 @@ versions of all registered files in or below it."
(if (string= rev1-default "") (setq rev1-default nil))
(setq rev2-default (vc-workfile-version file))))
;; construct argument list
- (list file
- (read-string (if rev1-default
- (concat "Older version (default "
- rev1-default "): ")
- "Older version: ")
- nil nil rev1-default)
- (read-string (if rev2-default
- (concat "Newer version (default "
- rev2-default "): ")
- "Newer version (default current source): ")
- nil nil rev2-default))))
+ (let* ((rev1-prompt (if rev1-default
+ (concat "Older version (default "
+ rev1-default "): ")
+ "Older version: "))
+ (rev2-prompt (concat "Newer version (default "
+ (or rev2-default "current source") "): "))
+ (rev1 (if completion-table
+ (completing-read rev1-prompt completion-table
+ nil nil nil nil rev1-default)
+ (read-string rev1-prompt nil nil rev1-default)))
+ (rev2 (if completion-table
+ (completing-read rev2-prompt completion-table
+ nil nil nil nil rev2-default)
+ (read-string rev2-prompt nil nil rev2-default))))
+ (list file rev1 rev2))))
(if (file-directory-p file)
;; recursive directory diff
(progn
@@ -1945,7 +1958,16 @@ The meaning of REV1 and REV2 is the same as for `vc-version-diff'."
"Visit version REV of the current file in another window.
If the current file is named `F', the version is named `F.~REV~'.
If `F.~REV~' already exists, use it instead of checking it out again."
- (interactive "sVersion to visit (default is workfile version): ")
+ (interactive
+ (save-current-buffer
+ (vc-ensure-vc-buffer)
+ (let ((completion-table
+ (vc-call revision-completion-table buffer-file-name))
+ (prompt "Version to visit (default is workfile version): "))
+ (list
+ (if completion-table
+ (completing-read prompt completion-table)
+ (read-string prompt))))))
(vc-ensure-vc-buffer)
(let* ((file buffer-file-name)
(version (if (string-equal rev "")