diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 35 | ||||
| -rw-r--r-- | lisp/diff-mode.el | 65 | ||||
| -rw-r--r-- | lisp/vc-arch.el | 25 | ||||
| -rw-r--r-- | lisp/vc-cvs.el | 30 | ||||
| -rw-r--r-- | lisp/vc-git.el | 21 | ||||
| -rw-r--r-- | lisp/vc-hg.el | 12 | ||||
| -rw-r--r-- | lisp/vc-hooks.el | 7 | ||||
| -rw-r--r-- | lisp/vc.el | 60 |
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 "") |
