From eff23ff37606569028a6ef96ba2481df6b061ec4 Mon Sep 17 00:00:00 2001 From: Dan Nicolaescu Date: Mon, 30 Jul 2007 00:19:06 +0000 Subject: [PATCH] * 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. * 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. * eval.c (init_eval_once): Bump max_lisp_eval_depth to 400. * vc2-xtra.texi (Customizing VC): Add GIT and HG. --- etc/NEWS | 2 ++ lisp/ChangeLog | 35 +++++++++++++++++++++++++ lisp/diff-mode.el | 65 +++++++++++++++++++++++++++++++++++++---------- lisp/vc-arch.el | 25 ++++++++++++++++++ lisp/vc-cvs.el | 30 ++++++++++++++++++++-- lisp/vc-git.el | 21 +++++---------- lisp/vc-hg.el | 12 ++++----- lisp/vc-hooks.el | 7 ++--- lisp/vc.el | 60 +++++++++++++++++++++++++++++-------------- man/ChangeLog | 4 +++ man/vc2-xtra.texi | 6 ++--- src/ChangeLog | 4 +++ src/eval.c | 2 +- 13 files changed, 211 insertions(+), 62 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 45d4819f10e..eff08166324 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -63,6 +63,8 @@ in to make it use the scrollbars from the system theme. ** VC +*** VC backends can provide completion of revision names. + *** VC has some support for Mercurial (hg). *** VC has some support for Git. 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 + + * 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 + + * 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 (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 "") diff --git a/man/ChangeLog b/man/ChangeLog index c12acbc89ee..904dfb3ed33 100644 --- a/man/ChangeLog +++ b/man/ChangeLog @@ -1,3 +1,7 @@ +2007-07-30 Dan Nicolaescu + + * vc2-xtra.texi (Customizing VC): Add GIT and HG. + 2007-07-28 Nick Roberts * building.texi (GDB Graphical Interface): Qualify use of "M-x gdba". diff --git a/man/vc2-xtra.texi b/man/vc2-xtra.texi index 11c8ea1fb96..5a8d131705a 100644 --- a/man/vc2-xtra.texi +++ b/man/vc2-xtra.texi @@ -588,9 +588,9 @@ headers. @subsection Customizing VC @vindex vc-handled-backends -The variable @code{vc-handled-backends} determines which version -control systems VC should handle. The default value is @code{(RCS CVS -SVN SCCS Arch MCVS)}, so it contains all six version systems that are +The variable @code{vc-handled-backends} determines which version control +systems VC should handle. The default value is @code{(RCS CVS SVN SCCS +GIT HG Arch MCVS)}, so it contains all six version systems that are currently supported. If you want VC to ignore one or more of these systems, exclude its name from the list. To disable VC entirely, set this variable to @code{nil}. diff --git a/src/ChangeLog b/src/ChangeLog index 419f39e034f..835379d9cde 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2007-07-30 Stefan Monnier + + * eval.c (init_eval_once): Bump max_lisp_eval_depth to 400. + 2007-07-25 Glenn Morris * Relicense all FSF files to GPLv3 or later. diff --git a/src/eval.c b/src/eval.c index 0993767b9e3..60e3c77a3a3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -221,7 +221,7 @@ init_eval_once () specpdl_ptr = specpdl; /* Don't forget to update docs (lispref node "Local Variables"). */ max_specpdl_size = 1000; - max_lisp_eval_depth = 300; + max_lisp_eval_depth = 400; Vrun_hooks = Qnil; } -- 2.39.2