Mercurial > emacs
changeset 29577:ce3a0229bee7
(cvs-parse-process): Don't blindly refresh all cookies.
(cvs-cleanup-removed): New function.
(cvs-cleanup-functions): New var.
(cvs-cleanup-collection): Use cvs-cleanup-functions to allow the user
some flexibility in specifying additional entries to auto-cleanup.
(cvs-quickdir): New function.
(cvs-mode-insert): Use cvs-fileinfo-from-entries.
(cvs-mode-imerge): Use smerge-ediff rather than vc-resolve-conflicts.
(cvs-mode-find-file): Check that we are on a filename or dirname
when invoked through a mouse-click.
(cvs-full-path): Remove.
(cvs-dired-action): Re-introduced.
(cvs-dired-noselect): Use it.
(vc-post-command-functions): use this new hook if available.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Mon, 12 Jun 2000 04:48:35 +0000 |
parents | 961f303cda37 |
children | cf89b9b2ef40 |
files | lisp/pcvs.el |
diffstat | 1 files changed, 93 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/pcvs.el Mon Jun 12 04:37:50 2000 +0000 +++ b/lisp/pcvs.el Mon Jun 12 04:48:35 2000 +0000 @@ -14,7 +14,7 @@ ;; Maintainer: (Stefan Monnier) monnier+lists/cvs/pcl@flint.cs.yale.edu ;; Keywords: CVS, version control, release management ;; Version: $Name: $ -;; Revision: $Id: pcvs.el,v 1.2 2000/03/22 02:56:55 monnier Exp $ +;; Revision: $Id: pcvs.el,v 1.3 2000/05/10 22:28:36 monnier Exp $ ;; This file is part of GNU Emacs. @@ -58,8 +58,6 @@ ;; ******** FIX THE DOCUMENTATION ********* ;; ;; - proper `g' that passes safe args and uses either cvs-status or cvs-examine -;; - write cvs-fast-examine that parses CVS/Entries instead of running cvs -;; we could even steal code from vc-cvs-hooks for that. ;; - add toolbar entries ;; - marking ;; marking directories should jump to just after the dir. @@ -68,7 +66,6 @@ ;; - liveness indicator ;; - indicate in docstring if the cmd understands the `b' prefix(es). ;; - call smerge-mode when opening CONFLICT files. -;; - after-parse-hook (to eliminate *.elc from Emacs' CVS repository :-) ;; - have vc-checkin delegate to cvs-mode-commit when applicable ;; - higher-level CVS operations ;; cvs-mode-rename @@ -87,11 +84,12 @@ ;; (with completion on tag names and hooks to ;; help generate full releases) ;; - allow cvs-cmd-do to either clear the marks or not. -;; - allow more concurrency: if the output buffer is busy, pick a new one. ;; - display stickiness information. And current CVS/Tag as well. ;; - write 'cvs-mode-admin' to do arbitrary 'cvs admin' commands +;; Most interesting would be version removal and log message replacement. +;; The last one would be neat when called from log-view-mode. ;; - cvs-mode-incorporate -;; It would merge in the status from one ``*cvs*'' buffer into another. +;; It would merge in the status from one *cvs* buffer into another. ;; This would be used to populate such a buffer that had been created with ;; a `cvs {update,status,checkout} -l'. ;; - cvs-mode-(i)diff-other-{file,buffer,cvs-buffer} @@ -151,7 +149,7 @@ (cvs-flags-define cvs-checkout-flags (cvs-defaults '("-P"))) (cvs-flags-define cvs-status-flags (cvs-defaults '("-v") nil)) (cvs-flags-define cvs-log-flags (cvs-defaults nil)) -(cvs-flags-define cvs-diff-flags (cvs-defaults '("-u" "-N") '("-c" "-N"))) +(cvs-flags-define cvs-diff-flags (cvs-defaults '("-u" "-N") '("-c" "-N") '("-u" "-b"))) (cvs-flags-define cvs-tag-flags (cvs-defaults nil)) (cvs-flags-define cvs-add-flags (cvs-defaults nil)) (cvs-flags-define cvs-commit-flags (cvs-defaults nil)) @@ -458,9 +456,9 @@ (cvsbuf (cvs-make-cvs-buffer dir new))) ;; Check that dir is under CVS control. (unless (file-directory-p dir) - (error "%s is not a directory." dir)) + (error "%s is not a directory" dir)) (unless (or noexist (file-directory-p (expand-file-name "CVS" dir))) - (error "%s does not contain CVS controlled files." dir)) + (error "%s does not contain CVS controlled files" dir)) (set-buffer cvsbuf) (cvs-mode-run cmd flags fis @@ -472,7 +470,6 @@ ;; 'pop-to-buffer 'switch-to-buffer) ;; cvsbuf)))) -;;---------- (defun cvs-run-process (args fis postprocess &optional single-dir) (assert (cvs-buffer-p cvs-buffer)) (save-current-buffer @@ -590,7 +587,6 @@ prev-msg)))))) -;;---------- (defun cvs-sentinel (proc msg) "Sentinel for the cvs update process. This is responsible for parsing the output from the cvs update when @@ -622,7 +618,6 @@ ;; This might not even be necessary (set-buffer obuf))))) -;;---------- (defun cvs-parse-process (dcd &optional subdir) "FIXME: bad name, no doc" (let* ((from-buf (current-buffer)) @@ -638,7 +633,7 @@ cvs-auto-remove-directories nil) ;; update the display (might be unnecessary) - (ewoc-refresh cvs-cookies) + ;;(ewoc-refresh cvs-cookies) ;; revert buffers if necessary (when (and cvs-auto-revert (not dcd) (not cvs-from-vc)) (cvs-revert-if-needed fileinfos)) @@ -735,6 +730,24 @@ (ewoc-invalidate c tin)) tin))) +(defcustom cvs-cleanup-functions nil + "Functions to tweak the cleanup process. +The functions are called with a single argument (a FILEINFO) and should +return a non-nil value if that fileinfo should be removed." + :group 'pcl-cvs + :type '(hook :options (cvs-cleanup-removed))) + +(defun cvs-cleanup-removed (fi) + "Non-nil if FI has been cvs-removed but still exists. +This is intended for use on `cvs-cleanup-functions' when you have cvs-removed +automatically generated files (which should hence not be under CVS control) +but can't commit the removal because the repository's owner doesn't understand +the problem." + (and (or (eq (cvs-fileinfo->type fi) 'REMOVED) + (and (eq (cvs-fileinfo->type fi) 'CONFLICT) + (eq (cvs-fileinfo->subtype fi) 'REMOVED))) + (file-exists-p (cvs-fileinfo->full-path fi)))) + ;; called at the following times: ;; - postparse ((eq cvs-auto-remove-handled t) cvs-auto-remove-directories nil) ;; - pre-run ((eq cvs-auto-remove-handled 'delayed) nil t) @@ -767,7 +780,8 @@ ;; handled also? (UP-TO-DATE (not rm-handled)) ;; keep the rest - (t t)))) + (t (not (run-hook-with-args-until-success + 'cvs-cleanup-functions fi)))))) ;; mark dirs for removal (when (and keep rm-dirs @@ -856,6 +870,35 @@ default-directory (read-file-name msg nil default-directory nil))) +;;;###autoload +(defun cvs-quickdir (dir &optional flags noshow) + "Open a *cvs* buffer on DIR without running cvs. +With a prefix argument, prompt for a directory to use. +A prefix arg >8 (ex: \\[universal-argument] \\[universal-argument]), + prevents reuse of an existing *cvs* buffer. +Optional argument NOSHOW if non-nil means not to display the buffer. +FLAGS is ignored." + (interactive (list (cvs-query-directory "CVS quickdir (directory): "))) + ;; FIXME: code duplication with cvs-cmd-do and cvs-parse-process + (let* ((dir (file-name-as-directory + (abbreviate-file-name (expand-file-name dir)))) + (new (> (prefix-numeric-value current-prefix-arg) 8)) + (cvsbuf (cvs-make-cvs-buffer dir new)) + last) + ;; Check that dir is under CVS control. + (unless (file-directory-p dir) + (error "%s is not a directory" dir)) + (unless (file-directory-p (expand-file-name "CVS" dir)) + (error "%s does not contain CVS controlled files" dir)) + (set-buffer cvsbuf) + (dolist (fi (cvs-fileinfo-from-entries "")) + (setq last (cvs-addto-collection cvs-cookies fi last))) + (cvs-cleanup-collection cvs-cookies + (eq cvs-auto-remove-handled t) + cvs-auto-remove-directories + nil) + (if noshow cvsbuf + (let ((pop-up-windows nil)) (pop-to-buffer cvsbuf))))) ;;;###autoload (defun cvs-examine (directory flags &optional noshow) @@ -908,7 +951,6 @@ (> (prefix-numeric-value current-prefix-arg) 8) :noshow noshow :dont-change-disc t)) -;;---------- (defun cvs-update-filter (proc string) "Filter function for pcl-cvs. This function gets the output that CVS sends to stdout. It inserts @@ -961,7 +1003,6 @@ (interactive "P") (cvs-prefix-set 'cvs-force-command arg)) -;;---------- (put 'cvs-mode 'mode-class 'special) (define-derived-mode cvs-mode fundamental-mode "CVS" "Mode used for PCL-CVS, a frontend to CVS. @@ -1291,19 +1332,9 @@ (ignore-errors (cvs-fileinfo->dir (car (cvs-mode-marked nil nil :read-only t))))))) - (let ((file (file-relative-name (directory-file-name file)))) - (if (file-directory-p file) - (let ((fi (cvs-create-fileinfo 'DIRCHANGE - (file-name-as-directory file) - "." - "cvs-mode-insert"))) - (cvs-addto-collection cvs-cookies fi)) - (let ((fi (cvs-create-fileinfo 'UNKNOWN - (or (file-name-directory file) "") - (file-name-nondirectory file) - "cvs-mode-insert"))) - (cvs-mode-run "status" (cvs-flags-query 'cvs-status-flags nil 'noquery) - (list fi) :dont-change-disc t))))) + (let ((file (file-relative-name (directory-file-name file))) last) + (dolist (fi (cvs-fileinfo-from-entries file)) + (setq last (cvs-addto-collection cvs-cookies fi last))))) (defun-cvs-mode (cvs-mode-add . SIMPLE) (flags) "Add marked files to the cvs repository. @@ -1331,7 +1362,6 @@ (dolist (fi ',dirs) (setf (cvs-fileinfo->type fi) 'DEAD)))))) (cvs-mode-run "add" flags fis :postproc postproc)))) -;;---------- (defun-cvs-mode (cvs-mode-diff . DOUBLE) (flags) "Diff the selected files against the repository. This command compares the files in your working area against the @@ -1343,21 +1373,18 @@ (cvs-mode-do "diff" flags 'diff :show t)) ;; :ignore-exit t -;;---------- (defun-cvs-mode (cvs-mode-diff-head . SIMPLE) (flags) "Diff the selected files against the head of the current branch. See ``cvs-mode-diff'' for more info." (interactive (list (cvs-flags-query 'cvs-diff-flags "cvs diff flags"))) (cvs-mode-diff-1 (cons "-rHEAD" flags))) -;;---------- (defun-cvs-mode (cvs-mode-diff-vendor . SIMPLE) (flags) "Diff the selected files against the head of the vendor branch. See ``cvs-mode-diff'' for more info." (interactive (list (cvs-flags-query 'cvs-diff-flags "cvs diff flags"))) (cvs-mode-diff-1 (cons (concat "-r" cvs-vendor-branch) flags))) -;;---------- ;; sadly, this is not provided by cvs, so we have to roll our own (defun-cvs-mode (cvs-mode-diff-backup . SIMPLE) (flags) "Diff the files against the backup file. @@ -1381,13 +1408,6 @@ cvs-diff-program flags)) (message "cvs diff backup... Done.")) -;;---------- -;; (defun cvs-backup-diffable-p (fi) -;; "Check if the TIN is backup-diffable. -;; It must have a backup file to be diffable." -;; (cvs-fileinfo->backup-file fi)) - -;;---------- (defun cvs-diff-backup-extractor (fileinfo) "Return the filename and the name of the backup file as a list. Signal an error if there is no backup file." @@ -1463,8 +1483,11 @@ (message "Retrieving revision %s... Done" rev) buf)))) -(eval-and-compile (autoload 'vc-resolve-conflicts "vc")) +(eval-and-compile (autoload 'smerge-ediff "smerge-mode")) +;; FIXME: The user should be able to specify ancestor/head/backup and we should +;; provide sensible defaults when merge info is unavailable (rather than rely +;; on smerge-ediff). Also provide sane defaults for need-merge files. (defun-cvs-mode cvs-mode-imerge () "Merge interactively appropriate revisions of the selected file." (interactive) @@ -1475,9 +1498,8 @@ (if (not (and merge backup-file)) (let ((buf (find-file-noselect file))) (message "Missing merge info or backup file, using VC.") - (save-excursion - (set-buffer buf) - (vc-resolve-conflicts))) + (with-current-buffer buf + (smerge-ediff))) (let* ((ancestor-buf (cvs-retrieve-revision fi (car merge))) (head-buf (cvs-retrieve-revision fi (cdr merge))) (backup-buf (let ((auto-mode-alist nil)) @@ -1710,7 +1732,10 @@ "Select a buffer containing the file. With a prefix, opens the buffer in an OTHER window." (interactive (list last-input-event current-prefix-arg)) - (ignore-errors (mouse-set-point e)) ;for invocation via the mouse + (when (ignore-errors (mouse-set-point e) t) ;for invocation via the mouse + (unless (memq (get-text-property (point) 'face) + '(cvs-dirname-face cvs-filename-face)) + (error "Not a file name"))) (cvs-mode! (lambda (&optional rev) (interactive (list (cvs-prefix-get 'cvs-branch-prefix))) @@ -1800,11 +1825,6 @@ (setf (cvs-fileinfo->type fi) 'DEAD)) (cvs-cleanup-collection cvs-cookies nil nil nil)) -;;---------- -(defun cvs-insert-full-path (tin) - "Insert full path to the file described in TIN in the current buffer." - (insert (format "%s\n" (cvs-full-path tin)))) - (defun cvs-do-removal (filter &optional cmd all) "Remove files. Returns a list of FIS that should be `cvs remove'd." @@ -1877,7 +1897,6 @@ ;; ChangeLog support. -;;---------- (defun-cvs-mode cvs-mode-add-change-log-entry-other-window () "Add a ChangeLog entry in the ChangeLog of the current directory." (interactive) @@ -1911,12 +1930,6 @@ ;;;; Utilities for the *cvs* buffer ;;;; -;;---------- -(defun cvs-full-path (tin) - "Return the full path for the file that is described in TIN." - (cvs-fileinfo->full-path (ewoc-data tin))) - -;;---------- (defun cvs-dir-member-p (fileinfo dir) "Return true if FILEINFO represents a file in directory DIR." (and (not (eq (cvs-fileinfo->type fileinfo) 'DIRCHANGE)) @@ -1999,6 +2012,13 @@ ;; ;;;###autoload +(defcustom cvs-dired-action 'cvs-examine + "The action to be performed when opening a CVS directory. +Sensible values are `cvs-examine', `cvs-status' and `cvs-quickdir'." + :group 'pcl-cvs + :type '(choice (const cvs-examine) (const cvs-status) (const cvs-quickdir))) + +;;;###autoload (defcustom cvs-dired-use-hook '(4) "Whether or not opening a CVS directory should run PCL-CVS. NIL means never do it. @@ -2023,22 +2043,27 @@ (not current-prefix-arg) (equal current-prefix-arg cvs-dired-use-hook))) (save-excursion - (cvs-examine (file-name-directory dir) t t)))))) + (funcall cvs-dired-action (file-name-directory dir) t t)))))) ;; ;; hook into VC ;; -(defadvice vc-simple-command (after pcl-cvs-vc activate) - (cvs-vc-command-advice "*vc-info*" (ad-get-arg 1) (ad-get-arg 3))) - -(defadvice vc-do-command (after pcl-cvs-vc activate) - (cvs-vc-command-advice (if (eq t (ad-get-arg 0)) (current-buffer) - (or (ad-get-arg 0) "*vc*")) - (ad-get-arg 2) - (if (stringp (ad-get-arg 4)) - (ad-get-arg 4) - (ad-get-arg 5)))) +(if (boundp 'vc-post-command-functions) + ;; Hook into the new VC. + (add-hook 'vc-post-command-functions + (lambda (cmd file flags) + (cvs-vc-command-advice (current-buffer) cmd (car flags)))) + ;; Hook into the old VC. + (defadvice vc-simple-command (after pcl-cvs-vc activate) + (cvs-vc-command-advice "*vc-info*" (ad-get-arg 1) (ad-get-arg 3))) + (defadvice vc-do-command (after pcl-cvs-vc activate) + (cvs-vc-command-advice (if (eq t (ad-get-arg 0)) (current-buffer) + (or (ad-get-arg 0) "*vc*")) + (ad-get-arg 2) + (if (stringp (ad-get-arg 4)) + (ad-get-arg 4) + (ad-get-arg 5))))) (defun cvs-vc-command-advice (buffer command cvscmd) (when (and (setq buffer (get-buffer buffer))