comparison lisp/pcvs.el @ 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 d089f0a330a0
children f7a0912532da
comparison
equal deleted inserted replaced
29576:961f303cda37 29577:ce3a0229bee7
12 ;; (Greg Klanderman) greg@alphatech.com 12 ;; (Greg Klanderman) greg@alphatech.com
13 ;; (Jari Aalto+mail.emacs) jari.aalto@poboxes.com 13 ;; (Jari Aalto+mail.emacs) jari.aalto@poboxes.com
14 ;; Maintainer: (Stefan Monnier) monnier+lists/cvs/pcl@flint.cs.yale.edu 14 ;; Maintainer: (Stefan Monnier) monnier+lists/cvs/pcl@flint.cs.yale.edu
15 ;; Keywords: CVS, version control, release management 15 ;; Keywords: CVS, version control, release management
16 ;; Version: $Name: $ 16 ;; Version: $Name: $
17 ;; Revision: $Id: pcvs.el,v 1.2 2000/03/22 02:56:55 monnier Exp $ 17 ;; Revision: $Id: pcvs.el,v 1.3 2000/05/10 22:28:36 monnier Exp $
18 18
19 ;; This file is part of GNU Emacs. 19 ;; This file is part of GNU Emacs.
20 20
21 ;; GNU Emacs is free software; you can redistribute it and/or modify 21 ;; GNU Emacs is free software; you can redistribute it and/or modify
22 ;; it under the terms of the GNU General Public License as published by 22 ;; it under the terms of the GNU General Public License as published by
56 ;;; Todo: 56 ;;; Todo:
57 57
58 ;; ******** FIX THE DOCUMENTATION ********* 58 ;; ******** FIX THE DOCUMENTATION *********
59 ;; 59 ;;
60 ;; - proper `g' that passes safe args and uses either cvs-status or cvs-examine 60 ;; - proper `g' that passes safe args and uses either cvs-status or cvs-examine
61 ;; - write cvs-fast-examine that parses CVS/Entries instead of running cvs
62 ;; we could even steal code from vc-cvs-hooks for that.
63 ;; - add toolbar entries 61 ;; - add toolbar entries
64 ;; - marking 62 ;; - marking
65 ;; marking directories should jump to just after the dir. 63 ;; marking directories should jump to just after the dir.
66 ;; allow (un)marking directories at a time with the mouse. 64 ;; allow (un)marking directories at a time with the mouse.
67 ;; marking with the mouse should not move point. 65 ;; marking with the mouse should not move point.
68 ;; - liveness indicator 66 ;; - liveness indicator
69 ;; - indicate in docstring if the cmd understands the `b' prefix(es). 67 ;; - indicate in docstring if the cmd understands the `b' prefix(es).
70 ;; - call smerge-mode when opening CONFLICT files. 68 ;; - call smerge-mode when opening CONFLICT files.
71 ;; - after-parse-hook (to eliminate *.elc from Emacs' CVS repository :-)
72 ;; - have vc-checkin delegate to cvs-mode-commit when applicable 69 ;; - have vc-checkin delegate to cvs-mode-commit when applicable
73 ;; - higher-level CVS operations 70 ;; - higher-level CVS operations
74 ;; cvs-mode-rename 71 ;; cvs-mode-rename
75 ;; cvs-mode-branch 72 ;; cvs-mode-branch
76 ;; - module-level commands 73 ;; - module-level commands
85 ;; - does "cvs -n tag LAST_VENDOR" to find old files into *cvs* 82 ;; - does "cvs -n tag LAST_VENDOR" to find old files into *cvs*
86 ;; cvs-export 83 ;; cvs-export
87 ;; (with completion on tag names and hooks to 84 ;; (with completion on tag names and hooks to
88 ;; help generate full releases) 85 ;; help generate full releases)
89 ;; - allow cvs-cmd-do to either clear the marks or not. 86 ;; - allow cvs-cmd-do to either clear the marks or not.
90 ;; - allow more concurrency: if the output buffer is busy, pick a new one.
91 ;; - display stickiness information. And current CVS/Tag as well. 87 ;; - display stickiness information. And current CVS/Tag as well.
92 ;; - write 'cvs-mode-admin' to do arbitrary 'cvs admin' commands 88 ;; - write 'cvs-mode-admin' to do arbitrary 'cvs admin' commands
89 ;; Most interesting would be version removal and log message replacement.
90 ;; The last one would be neat when called from log-view-mode.
93 ;; - cvs-mode-incorporate 91 ;; - cvs-mode-incorporate
94 ;; It would merge in the status from one ``*cvs*'' buffer into another. 92 ;; It would merge in the status from one *cvs* buffer into another.
95 ;; This would be used to populate such a buffer that had been created with 93 ;; This would be used to populate such a buffer that had been created with
96 ;; a `cvs {update,status,checkout} -l'. 94 ;; a `cvs {update,status,checkout} -l'.
97 ;; - cvs-mode-(i)diff-other-{file,buffer,cvs-buffer} 95 ;; - cvs-mode-(i)diff-other-{file,buffer,cvs-buffer}
98 ;; - offer the choice to kill the process when the user kills the cvs buffer. 96 ;; - offer the choice to kill the process when the user kills the cvs buffer.
99 ;; right now, it's killed without further ado. 97 ;; right now, it's killed without further ado.
149 (cvs-flags-define cvs-cvs-flags '(("-f"))) 147 (cvs-flags-define cvs-cvs-flags '(("-f")))
150 148
151 (cvs-flags-define cvs-checkout-flags (cvs-defaults '("-P"))) 149 (cvs-flags-define cvs-checkout-flags (cvs-defaults '("-P")))
152 (cvs-flags-define cvs-status-flags (cvs-defaults '("-v") nil)) 150 (cvs-flags-define cvs-status-flags (cvs-defaults '("-v") nil))
153 (cvs-flags-define cvs-log-flags (cvs-defaults nil)) 151 (cvs-flags-define cvs-log-flags (cvs-defaults nil))
154 (cvs-flags-define cvs-diff-flags (cvs-defaults '("-u" "-N") '("-c" "-N"))) 152 (cvs-flags-define cvs-diff-flags (cvs-defaults '("-u" "-N") '("-c" "-N") '("-u" "-b")))
155 (cvs-flags-define cvs-tag-flags (cvs-defaults nil)) 153 (cvs-flags-define cvs-tag-flags (cvs-defaults nil))
156 (cvs-flags-define cvs-add-flags (cvs-defaults nil)) 154 (cvs-flags-define cvs-add-flags (cvs-defaults nil))
157 (cvs-flags-define cvs-commit-flags (cvs-defaults nil)) 155 (cvs-flags-define cvs-commit-flags (cvs-defaults nil))
158 (cvs-flags-define cvs-remove-flags (cvs-defaults nil)) 156 (cvs-flags-define cvs-remove-flags (cvs-defaults nil))
159 ;;(cvs-flags-define cvs-undo-flags (cvs-defaults nil)) 157 ;;(cvs-flags-define cvs-undo-flags (cvs-defaults nil))
456 (let* ((dir (file-name-as-directory 454 (let* ((dir (file-name-as-directory
457 (abbreviate-file-name (expand-file-name dir)))) 455 (abbreviate-file-name (expand-file-name dir))))
458 (cvsbuf (cvs-make-cvs-buffer dir new))) 456 (cvsbuf (cvs-make-cvs-buffer dir new)))
459 ;; Check that dir is under CVS control. 457 ;; Check that dir is under CVS control.
460 (unless (file-directory-p dir) 458 (unless (file-directory-p dir)
461 (error "%s is not a directory." dir)) 459 (error "%s is not a directory" dir))
462 (unless (or noexist (file-directory-p (expand-file-name "CVS" dir))) 460 (unless (or noexist (file-directory-p (expand-file-name "CVS" dir)))
463 (error "%s does not contain CVS controlled files." dir)) 461 (error "%s does not contain CVS controlled files" dir))
464 462
465 (set-buffer cvsbuf) 463 (set-buffer cvsbuf)
466 (cvs-mode-run cmd flags fis 464 (cvs-mode-run cmd flags fis
467 :cvsargs cvsargs :dont-change-disc dont-change-disc) 465 :cvsargs cvsargs :dont-change-disc dont-change-disc)
468 466
470 (let ((pop-up-windows nil)) (pop-to-buffer cvsbuf))))) 468 (let ((pop-up-windows nil)) (pop-to-buffer cvsbuf)))))
471 ;; (funcall (if (and (boundp 'pop-up-frames) pop-up-frames) 469 ;; (funcall (if (and (boundp 'pop-up-frames) pop-up-frames)
472 ;; 'pop-to-buffer 'switch-to-buffer) 470 ;; 'pop-to-buffer 'switch-to-buffer)
473 ;; cvsbuf)))) 471 ;; cvsbuf))))
474 472
475 ;;----------
476 (defun cvs-run-process (args fis postprocess &optional single-dir) 473 (defun cvs-run-process (args fis postprocess &optional single-dir)
477 (assert (cvs-buffer-p cvs-buffer)) 474 (assert (cvs-buffer-p cvs-buffer))
478 (save-current-buffer 475 (save-current-buffer
479 (let ((procbuf (current-buffer)) 476 (let ((procbuf (current-buffer))
480 (cvsbuf cvs-buffer) 477 (cvsbuf cvs-buffer)
588 (if tin "End" "Empty") 585 (if tin "End" "Empty")
589 " ---------------------\n" 586 " ---------------------\n"
590 prev-msg)))))) 587 prev-msg))))))
591 588
592 589
593 ;;----------
594 (defun cvs-sentinel (proc msg) 590 (defun cvs-sentinel (proc msg)
595 "Sentinel for the cvs update process. 591 "Sentinel for the cvs update process.
596 This is responsible for parsing the output from the cvs update when 592 This is responsible for parsing the output from the cvs update when
597 it is finished." 593 it is finished."
598 (when (memq (process-status proc) '(signal exit)) 594 (when (memq (process-status proc) '(signal exit))
620 (cvs-update-header nil nil) ;FIXME: might need to be inline 616 (cvs-update-header nil nil) ;FIXME: might need to be inline
621 (message "CVS process has completed")))) 617 (message "CVS process has completed"))))
622 ;; This might not even be necessary 618 ;; This might not even be necessary
623 (set-buffer obuf))))) 619 (set-buffer obuf)))))
624 620
625 ;;----------
626 (defun cvs-parse-process (dcd &optional subdir) 621 (defun cvs-parse-process (dcd &optional subdir)
627 "FIXME: bad name, no doc" 622 "FIXME: bad name, no doc"
628 (let* ((from-buf (current-buffer)) 623 (let* ((from-buf (current-buffer))
629 (fileinfos (cvs-parse-buffer 'cvs-parse-table dcd subdir)) 624 (fileinfos (cvs-parse-buffer 'cvs-parse-table dcd subdir))
630 (_ (set-buffer cvs-buffer)) 625 (_ (set-buffer cvs-buffer))
636 (cvs-cleanup-collection cvs-cookies 631 (cvs-cleanup-collection cvs-cookies
637 (eq cvs-auto-remove-handled t) 632 (eq cvs-auto-remove-handled t)
638 cvs-auto-remove-directories 633 cvs-auto-remove-directories
639 nil) 634 nil)
640 ;; update the display (might be unnecessary) 635 ;; update the display (might be unnecessary)
641 (ewoc-refresh cvs-cookies) 636 ;;(ewoc-refresh cvs-cookies)
642 ;; revert buffers if necessary 637 ;; revert buffers if necessary
643 (when (and cvs-auto-revert (not dcd) (not cvs-from-vc)) 638 (when (and cvs-auto-revert (not dcd) (not cvs-from-vc))
644 (cvs-revert-if-needed fileinfos)) 639 (cvs-revert-if-needed fileinfos))
645 ;; get back to where we were. `save-excursion' doesn't seem to 640 ;; get back to where we were. `save-excursion' doesn't seem to
646 ;; work in this case, probably because the buffer is reconstructed 641 ;; work in this case, probably because the buffer is reconstructed
732 (ewoc-enter-after c tin fi) 727 (ewoc-enter-after c tin fi)
733 ;; fi == tin 728 ;; fi == tin
734 (cvs-fileinfo-update (ewoc-data tin) fi) 729 (cvs-fileinfo-update (ewoc-data tin) fi)
735 (ewoc-invalidate c tin)) 730 (ewoc-invalidate c tin))
736 tin))) 731 tin)))
732
733 (defcustom cvs-cleanup-functions nil
734 "Functions to tweak the cleanup process.
735 The functions are called with a single argument (a FILEINFO) and should
736 return a non-nil value if that fileinfo should be removed."
737 :group 'pcl-cvs
738 :type '(hook :options (cvs-cleanup-removed)))
739
740 (defun cvs-cleanup-removed (fi)
741 "Non-nil if FI has been cvs-removed but still exists.
742 This is intended for use on `cvs-cleanup-functions' when you have cvs-removed
743 automatically generated files (which should hence not be under CVS control)
744 but can't commit the removal because the repository's owner doesn't understand
745 the problem."
746 (and (or (eq (cvs-fileinfo->type fi) 'REMOVED)
747 (and (eq (cvs-fileinfo->type fi) 'CONFLICT)
748 (eq (cvs-fileinfo->subtype fi) 'REMOVED)))
749 (file-exists-p (cvs-fileinfo->full-path fi))))
737 750
738 ;; called at the following times: 751 ;; called at the following times:
739 ;; - postparse ((eq cvs-auto-remove-handled t) cvs-auto-remove-directories nil) 752 ;; - postparse ((eq cvs-auto-remove-handled t) cvs-auto-remove-directories nil)
740 ;; - pre-run ((eq cvs-auto-remove-handled 'delayed) nil t) 753 ;; - pre-run ((eq cvs-auto-remove-handled 'delayed) nil t)
741 ;; - remove-handled (t (or cvs-auto-remove-directories 'handled) t) 754 ;; - remove-handled (t (or cvs-auto-remove-directories 'handled) t)
765 ;; remove entries 778 ;; remove entries
766 (DEAD nil) 779 (DEAD nil)
767 ;; handled also? 780 ;; handled also?
768 (UP-TO-DATE (not rm-handled)) 781 (UP-TO-DATE (not rm-handled))
769 ;; keep the rest 782 ;; keep the rest
770 (t t)))) 783 (t (not (run-hook-with-args-until-success
784 'cvs-cleanup-functions fi))))))
771 785
772 ;; mark dirs for removal 786 ;; mark dirs for removal
773 (when (and keep rm-dirs 787 (when (and keep rm-dirs
774 (eq (cvs-fileinfo->type last-fi) 'DIRCHANGE) 788 (eq (cvs-fileinfo->type last-fi) 'DIRCHANGE)
775 (not (when first-dir (setq first-dir nil) t)) 789 (not (when first-dir (setq first-dir nil) t))
854 (not current-prefix-arg) 868 (not current-prefix-arg)
855 (not (eq last-command-char ?\r))) 869 (not (eq last-command-char ?\r)))
856 default-directory 870 default-directory
857 (read-file-name msg nil default-directory nil))) 871 (read-file-name msg nil default-directory nil)))
858 872
873 ;;;###autoload
874 (defun cvs-quickdir (dir &optional flags noshow)
875 "Open a *cvs* buffer on DIR without running cvs.
876 With a prefix argument, prompt for a directory to use.
877 A prefix arg >8 (ex: \\[universal-argument] \\[universal-argument]),
878 prevents reuse of an existing *cvs* buffer.
879 Optional argument NOSHOW if non-nil means not to display the buffer.
880 FLAGS is ignored."
881 (interactive (list (cvs-query-directory "CVS quickdir (directory): ")))
882 ;; FIXME: code duplication with cvs-cmd-do and cvs-parse-process
883 (let* ((dir (file-name-as-directory
884 (abbreviate-file-name (expand-file-name dir))))
885 (new (> (prefix-numeric-value current-prefix-arg) 8))
886 (cvsbuf (cvs-make-cvs-buffer dir new))
887 last)
888 ;; Check that dir is under CVS control.
889 (unless (file-directory-p dir)
890 (error "%s is not a directory" dir))
891 (unless (file-directory-p (expand-file-name "CVS" dir))
892 (error "%s does not contain CVS controlled files" dir))
893 (set-buffer cvsbuf)
894 (dolist (fi (cvs-fileinfo-from-entries ""))
895 (setq last (cvs-addto-collection cvs-cookies fi last)))
896 (cvs-cleanup-collection cvs-cookies
897 (eq cvs-auto-remove-handled t)
898 cvs-auto-remove-directories
899 nil)
900 (if noshow cvsbuf
901 (let ((pop-up-windows nil)) (pop-to-buffer cvsbuf)))))
859 902
860 ;;;###autoload 903 ;;;###autoload
861 (defun cvs-examine (directory flags &optional noshow) 904 (defun cvs-examine (directory flags &optional noshow)
862 "Run a `cvs -n update' in the specified DIRECTORY. 905 "Run a `cvs -n update' in the specified DIRECTORY.
863 That is, check what needs to be done, but don't change the disc. 906 That is, check what needs to be done, but don't change the disc.
906 (setf flags (cvs-flags-query 'cvs-status-flags nil 'noquery))) 949 (setf flags (cvs-flags-query 'cvs-status-flags nil 'noquery)))
907 (cvs-cmd-do "status" directory flags nil 950 (cvs-cmd-do "status" directory flags nil
908 (> (prefix-numeric-value current-prefix-arg) 8) 951 (> (prefix-numeric-value current-prefix-arg) 8)
909 :noshow noshow :dont-change-disc t)) 952 :noshow noshow :dont-change-disc t))
910 953
911 ;;----------
912 (defun cvs-update-filter (proc string) 954 (defun cvs-update-filter (proc string)
913 "Filter function for pcl-cvs. 955 "Filter function for pcl-cvs.
914 This function gets the output that CVS sends to stdout. It inserts 956 This function gets the output that CVS sends to stdout. It inserts
915 the STRING into (process-buffer PROC) but it also checks if CVS is waiting 957 the STRING into (process-buffer PROC) but it also checks if CVS is waiting
916 for a lock file. If so, it inserts a message cookie in the *cvs* buffer." 958 for a lock file. If so, it inserts a message cookie in the *cvs* buffer."
959 It actually behaves as a toggle. If prefixed by \\[universal-argument] \\[universal-argument], 1001 It actually behaves as a toggle. If prefixed by \\[universal-argument] \\[universal-argument],
960 the override will persist until the next toggle." 1002 the override will persist until the next toggle."
961 (interactive "P") 1003 (interactive "P")
962 (cvs-prefix-set 'cvs-force-command arg)) 1004 (cvs-prefix-set 'cvs-force-command arg))
963 1005
964 ;;----------
965 (put 'cvs-mode 'mode-class 'special) 1006 (put 'cvs-mode 'mode-class 'special)
966 (define-derived-mode cvs-mode fundamental-mode "CVS" 1007 (define-derived-mode cvs-mode fundamental-mode "CVS"
967 "Mode used for PCL-CVS, a frontend to CVS. 1008 "Mode used for PCL-CVS, a frontend to CVS.
968 Full documentation is in the Texinfo file." 1009 Full documentation is in the Texinfo file."
969 (setq mode-line-process 1010 (setq mode-line-process
1289 (interactive 1330 (interactive
1290 (list (read-file-name "File to insert: " nil nil nil 1331 (list (read-file-name "File to insert: " nil nil nil
1291 (ignore-errors 1332 (ignore-errors
1292 (cvs-fileinfo->dir 1333 (cvs-fileinfo->dir
1293 (car (cvs-mode-marked nil nil :read-only t))))))) 1334 (car (cvs-mode-marked nil nil :read-only t)))))))
1294 (let ((file (file-relative-name (directory-file-name file)))) 1335 (let ((file (file-relative-name (directory-file-name file))) last)
1295 (if (file-directory-p file) 1336 (dolist (fi (cvs-fileinfo-from-entries file))
1296 (let ((fi (cvs-create-fileinfo 'DIRCHANGE 1337 (setq last (cvs-addto-collection cvs-cookies fi last)))))
1297 (file-name-as-directory file)
1298 "."
1299 "cvs-mode-insert")))
1300 (cvs-addto-collection cvs-cookies fi))
1301 (let ((fi (cvs-create-fileinfo 'UNKNOWN
1302 (or (file-name-directory file) "")
1303 (file-name-nondirectory file)
1304 "cvs-mode-insert")))
1305 (cvs-mode-run "status" (cvs-flags-query 'cvs-status-flags nil 'noquery)
1306 (list fi) :dont-change-disc t)))))
1307 1338
1308 (defun-cvs-mode (cvs-mode-add . SIMPLE) (flags) 1339 (defun-cvs-mode (cvs-mode-add . SIMPLE) (flags)
1309 "Add marked files to the cvs repository. 1340 "Add marked files to the cvs repository.
1310 With prefix argument, prompt for cvs flags." 1341 With prefix argument, prompt for cvs flags."
1311 (interactive (list (cvs-flags-query 'cvs-add-flags "cvs add flags"))) 1342 (interactive (list (cvs-flags-query 'cvs-add-flags "cvs add flags")))
1329 ',dirs 1360 ',dirs
1330 '(cvs-parse-process t)) 1361 '(cvs-parse-process t))
1331 (dolist (fi ',dirs) (setf (cvs-fileinfo->type fi) 'DEAD)))))) 1362 (dolist (fi ',dirs) (setf (cvs-fileinfo->type fi) 'DEAD))))))
1332 (cvs-mode-run "add" flags fis :postproc postproc)))) 1363 (cvs-mode-run "add" flags fis :postproc postproc))))
1333 1364
1334 ;;----------
1335 (defun-cvs-mode (cvs-mode-diff . DOUBLE) (flags) 1365 (defun-cvs-mode (cvs-mode-diff . DOUBLE) (flags)
1336 "Diff the selected files against the repository. 1366 "Diff the selected files against the repository.
1337 This command compares the files in your working area against the 1367 This command compares the files in your working area against the
1338 revision which they are based upon." 1368 revision which they are based upon."
1339 (interactive 1369 (interactive
1341 (cvs-add-secondary-branch-prefix 1371 (cvs-add-secondary-branch-prefix
1342 (cvs-flags-query 'cvs-diff-flags "cvs diff flags"))))) 1372 (cvs-flags-query 'cvs-diff-flags "cvs diff flags")))))
1343 (cvs-mode-do "diff" flags 'diff 1373 (cvs-mode-do "diff" flags 'diff
1344 :show t)) ;; :ignore-exit t 1374 :show t)) ;; :ignore-exit t
1345 1375
1346 ;;----------
1347 (defun-cvs-mode (cvs-mode-diff-head . SIMPLE) (flags) 1376 (defun-cvs-mode (cvs-mode-diff-head . SIMPLE) (flags)
1348 "Diff the selected files against the head of the current branch. 1377 "Diff the selected files against the head of the current branch.
1349 See ``cvs-mode-diff'' for more info." 1378 See ``cvs-mode-diff'' for more info."
1350 (interactive (list (cvs-flags-query 'cvs-diff-flags "cvs diff flags"))) 1379 (interactive (list (cvs-flags-query 'cvs-diff-flags "cvs diff flags")))
1351 (cvs-mode-diff-1 (cons "-rHEAD" flags))) 1380 (cvs-mode-diff-1 (cons "-rHEAD" flags)))
1352 1381
1353 ;;----------
1354 (defun-cvs-mode (cvs-mode-diff-vendor . SIMPLE) (flags) 1382 (defun-cvs-mode (cvs-mode-diff-vendor . SIMPLE) (flags)
1355 "Diff the selected files against the head of the vendor branch. 1383 "Diff the selected files against the head of the vendor branch.
1356 See ``cvs-mode-diff'' for more info." 1384 See ``cvs-mode-diff'' for more info."
1357 (interactive (list (cvs-flags-query 'cvs-diff-flags "cvs diff flags"))) 1385 (interactive (list (cvs-flags-query 'cvs-diff-flags "cvs diff flags")))
1358 (cvs-mode-diff-1 (cons (concat "-r" cvs-vendor-branch) flags))) 1386 (cvs-mode-diff-1 (cons (concat "-r" cvs-vendor-branch) flags)))
1359 1387
1360 ;;----------
1361 ;; sadly, this is not provided by cvs, so we have to roll our own 1388 ;; sadly, this is not provided by cvs, so we have to roll our own
1362 (defun-cvs-mode (cvs-mode-diff-backup . SIMPLE) (flags) 1389 (defun-cvs-mode (cvs-mode-diff-backup . SIMPLE) (flags)
1363 "Diff the files against the backup file. 1390 "Diff the files against the backup file.
1364 This command can be used on files that are marked with \"Merged\" 1391 This command can be used on files that are marked with \"Merged\"
1365 or \"Conflict\" in the *cvs* buffer." 1392 or \"Conflict\" in the *cvs* buffer."
1379 (message "cvs diff backup...") 1406 (message "cvs diff backup...")
1380 (cvs-execute-single-file-list fis 'cvs-diff-backup-extractor 1407 (cvs-execute-single-file-list fis 'cvs-diff-backup-extractor
1381 cvs-diff-program flags)) 1408 cvs-diff-program flags))
1382 (message "cvs diff backup... Done.")) 1409 (message "cvs diff backup... Done."))
1383 1410
1384 ;;----------
1385 ;; (defun cvs-backup-diffable-p (fi)
1386 ;; "Check if the TIN is backup-diffable.
1387 ;; It must have a backup file to be diffable."
1388 ;; (cvs-fileinfo->backup-file fi))
1389
1390 ;;----------
1391 (defun cvs-diff-backup-extractor (fileinfo) 1411 (defun cvs-diff-backup-extractor (fileinfo)
1392 "Return the filename and the name of the backup file as a list. 1412 "Return the filename and the name of the backup file as a list.
1393 Signal an error if there is no backup file." 1413 Signal an error if there is no backup file."
1394 (let ((backup-file (cvs-fileinfo->backup-file fileinfo))) 1414 (let ((backup-file (cvs-fileinfo->backup-file fileinfo)))
1395 (unless backup-file 1415 (unless backup-file
1461 (after-find-file)) 1481 (after-find-file))
1462 (toggle-read-only 1) 1482 (toggle-read-only 1)
1463 (message "Retrieving revision %s... Done" rev) 1483 (message "Retrieving revision %s... Done" rev)
1464 buf)))) 1484 buf))))
1465 1485
1466 (eval-and-compile (autoload 'vc-resolve-conflicts "vc")) 1486 (eval-and-compile (autoload 'smerge-ediff "smerge-mode"))
1467 1487
1488 ;; FIXME: The user should be able to specify ancestor/head/backup and we should
1489 ;; provide sensible defaults when merge info is unavailable (rather than rely
1490 ;; on smerge-ediff). Also provide sane defaults for need-merge files.
1468 (defun-cvs-mode cvs-mode-imerge () 1491 (defun-cvs-mode cvs-mode-imerge ()
1469 "Merge interactively appropriate revisions of the selected file." 1492 "Merge interactively appropriate revisions of the selected file."
1470 (interactive) 1493 (interactive)
1471 (let ((fi (cvs-mode-marked 'merge nil :one t :file t))) 1494 (let ((fi (cvs-mode-marked 'merge nil :one t :file t)))
1472 (let ((merge (cvs-fileinfo->merge fi)) 1495 (let ((merge (cvs-fileinfo->merge fi))
1473 (file (cvs-fileinfo->full-path fi)) 1496 (file (cvs-fileinfo->full-path fi))
1474 (backup-file (cvs-fileinfo->backup-file fi))) 1497 (backup-file (cvs-fileinfo->backup-file fi)))
1475 (if (not (and merge backup-file)) 1498 (if (not (and merge backup-file))
1476 (let ((buf (find-file-noselect file))) 1499 (let ((buf (find-file-noselect file)))
1477 (message "Missing merge info or backup file, using VC.") 1500 (message "Missing merge info or backup file, using VC.")
1478 (save-excursion 1501 (with-current-buffer buf
1479 (set-buffer buf) 1502 (smerge-ediff)))
1480 (vc-resolve-conflicts)))
1481 (let* ((ancestor-buf (cvs-retrieve-revision fi (car merge))) 1503 (let* ((ancestor-buf (cvs-retrieve-revision fi (car merge)))
1482 (head-buf (cvs-retrieve-revision fi (cdr merge))) 1504 (head-buf (cvs-retrieve-revision fi (cdr merge)))
1483 (backup-buf (let ((auto-mode-alist nil)) 1505 (backup-buf (let ((auto-mode-alist nil))
1484 (find-file-noselect backup-file))) 1506 (find-file-noselect backup-file)))
1485 ;; this binding is used by cvs-ediff-startup-hook 1507 ;; this binding is used by cvs-ediff-startup-hook
1708 1730
1709 (defun cvs-mode-find-file (e &optional other) 1731 (defun cvs-mode-find-file (e &optional other)
1710 "Select a buffer containing the file. 1732 "Select a buffer containing the file.
1711 With a prefix, opens the buffer in an OTHER window." 1733 With a prefix, opens the buffer in an OTHER window."
1712 (interactive (list last-input-event current-prefix-arg)) 1734 (interactive (list last-input-event current-prefix-arg))
1713 (ignore-errors (mouse-set-point e)) ;for invocation via the mouse 1735 (when (ignore-errors (mouse-set-point e) t) ;for invocation via the mouse
1736 (unless (memq (get-text-property (point) 'face)
1737 '(cvs-dirname-face cvs-filename-face))
1738 (error "Not a file name")))
1714 (cvs-mode! 1739 (cvs-mode!
1715 (lambda (&optional rev) 1740 (lambda (&optional rev)
1716 (interactive (list (cvs-prefix-get 'cvs-branch-prefix))) 1741 (interactive (list (cvs-prefix-get 'cvs-branch-prefix)))
1717 (let* ((cvs-buf (current-buffer)) 1742 (let* ((cvs-buf (current-buffer))
1718 (fi (cvs-mode-marked nil nil :one t))) 1743 (fi (cvs-mode-marked nil nil :one t)))
1797 "Remove all marked files from the buffer." 1822 "Remove all marked files from the buffer."
1798 (interactive) 1823 (interactive)
1799 (dolist (fi (cvs-get-marked (cvs-ignore-marks-p "acknowledge") t)) 1824 (dolist (fi (cvs-get-marked (cvs-ignore-marks-p "acknowledge") t))
1800 (setf (cvs-fileinfo->type fi) 'DEAD)) 1825 (setf (cvs-fileinfo->type fi) 'DEAD))
1801 (cvs-cleanup-collection cvs-cookies nil nil nil)) 1826 (cvs-cleanup-collection cvs-cookies nil nil nil))
1802
1803 ;;----------
1804 (defun cvs-insert-full-path (tin)
1805 "Insert full path to the file described in TIN in the current buffer."
1806 (insert (format "%s\n" (cvs-full-path tin))))
1807 1827
1808 (defun cvs-do-removal (filter &optional cmd all) 1828 (defun cvs-do-removal (filter &optional cmd all)
1809 "Remove files. 1829 "Remove files.
1810 Returns a list of FIS that should be `cvs remove'd." 1830 Returns a list of FIS that should be `cvs remove'd."
1811 (let* ((files (cvs-mode-marked filter cmd :file t :read-only t)) 1831 (let* ((files (cvs-mode-marked filter cmd :file t :read-only t))
1875 (when (string-match "\\.el\\'" filename) 1895 (when (string-match "\\.el\\'" filename)
1876 (byte-compile-file filename)))))) 1896 (byte-compile-file filename))))))
1877 1897
1878 ;; ChangeLog support. 1898 ;; ChangeLog support.
1879 1899
1880 ;;----------
1881 (defun-cvs-mode cvs-mode-add-change-log-entry-other-window () 1900 (defun-cvs-mode cvs-mode-add-change-log-entry-other-window ()
1882 "Add a ChangeLog entry in the ChangeLog of the current directory." 1901 "Add a ChangeLog entry in the ChangeLog of the current directory."
1883 (interactive) 1902 (interactive)
1884 (let* ((fi (cvs-mode-marked nil nil :one t)) 1903 (let* ((fi (cvs-mode-marked nil nil :one t))
1885 (default-directory (cvs-expand-dir-name (cvs-fileinfo->dir fi))) 1904 (default-directory (cvs-expand-dir-name (cvs-fileinfo->dir fi)))
1909 1928
1910 ;;;; 1929 ;;;;
1911 ;;;; Utilities for the *cvs* buffer 1930 ;;;; Utilities for the *cvs* buffer
1912 ;;;; 1931 ;;;;
1913 1932
1914 ;;----------
1915 (defun cvs-full-path (tin)
1916 "Return the full path for the file that is described in TIN."
1917 (cvs-fileinfo->full-path (ewoc-data tin)))
1918
1919 ;;----------
1920 (defun cvs-dir-member-p (fileinfo dir) 1933 (defun cvs-dir-member-p (fileinfo dir)
1921 "Return true if FILEINFO represents a file in directory DIR." 1934 "Return true if FILEINFO represents a file in directory DIR."
1922 (and (not (eq (cvs-fileinfo->type fileinfo) 'DIRCHANGE)) 1935 (and (not (eq (cvs-fileinfo->type fileinfo) 'DIRCHANGE))
1923 (cvs-string-prefix-p dir (cvs-fileinfo->dir fileinfo)))) 1936 (cvs-string-prefix-p dir (cvs-fileinfo->dir fileinfo))))
1924 1937
1997 ;; 2010 ;;
1998 ;; Hook to allow calling PCL-CVS by visiting the /CVS subdirectory 2011 ;; Hook to allow calling PCL-CVS by visiting the /CVS subdirectory
1999 ;; 2012 ;;
2000 2013
2001 ;;;###autoload 2014 ;;;###autoload
2015 (defcustom cvs-dired-action 'cvs-examine
2016 "The action to be performed when opening a CVS directory.
2017 Sensible values are `cvs-examine', `cvs-status' and `cvs-quickdir'."
2018 :group 'pcl-cvs
2019 :type '(choice (const cvs-examine) (const cvs-status) (const cvs-quickdir)))
2020
2021 ;;;###autoload
2002 (defcustom cvs-dired-use-hook '(4) 2022 (defcustom cvs-dired-use-hook '(4)
2003 "Whether or not opening a CVS directory should run PCL-CVS. 2023 "Whether or not opening a CVS directory should run PCL-CVS.
2004 NIL means never do it. 2024 NIL means never do it.
2005 ALWAYS means to always do it unless a prefix argument is given to the 2025 ALWAYS means to always do it unless a prefix argument is given to the
2006 command that prompted the opening of the directory. 2026 command that prompted the opening of the directory.
2021 cvs-dired-use-hook 2041 cvs-dired-use-hook
2022 (if (eq cvs-dired-use-hook 'always) 2042 (if (eq cvs-dired-use-hook 'always)
2023 (not current-prefix-arg) 2043 (not current-prefix-arg)
2024 (equal current-prefix-arg cvs-dired-use-hook))) 2044 (equal current-prefix-arg cvs-dired-use-hook)))
2025 (save-excursion 2045 (save-excursion
2026 (cvs-examine (file-name-directory dir) t t)))))) 2046 (funcall cvs-dired-action (file-name-directory dir) t t))))))
2027 2047
2028 ;; 2048 ;;
2029 ;; hook into VC 2049 ;; hook into VC
2030 ;; 2050 ;;
2031 2051
2032 (defadvice vc-simple-command (after pcl-cvs-vc activate) 2052 (if (boundp 'vc-post-command-functions)
2033 (cvs-vc-command-advice "*vc-info*" (ad-get-arg 1) (ad-get-arg 3))) 2053 ;; Hook into the new VC.
2034 2054 (add-hook 'vc-post-command-functions
2035 (defadvice vc-do-command (after pcl-cvs-vc activate) 2055 (lambda (cmd file flags)
2036 (cvs-vc-command-advice (if (eq t (ad-get-arg 0)) (current-buffer) 2056 (cvs-vc-command-advice (current-buffer) cmd (car flags))))
2037 (or (ad-get-arg 0) "*vc*")) 2057 ;; Hook into the old VC.
2038 (ad-get-arg 2) 2058 (defadvice vc-simple-command (after pcl-cvs-vc activate)
2039 (if (stringp (ad-get-arg 4)) 2059 (cvs-vc-command-advice "*vc-info*" (ad-get-arg 1) (ad-get-arg 3)))
2040 (ad-get-arg 4) 2060 (defadvice vc-do-command (after pcl-cvs-vc activate)
2041 (ad-get-arg 5)))) 2061 (cvs-vc-command-advice (if (eq t (ad-get-arg 0)) (current-buffer)
2062 (or (ad-get-arg 0) "*vc*"))
2063 (ad-get-arg 2)
2064 (if (stringp (ad-get-arg 4))
2065 (ad-get-arg 4)
2066 (ad-get-arg 5)))))
2042 2067
2043 (defun cvs-vc-command-advice (buffer command cvscmd) 2068 (defun cvs-vc-command-advice (buffer command cvscmd)
2044 (when (and (setq buffer (get-buffer buffer)) 2069 (when (and (setq buffer (get-buffer buffer))
2045 (equal command "cvs") 2070 (equal command "cvs")
2046 ;; don't parse output we don't understand. 2071 ;; don't parse output we don't understand.