1;;; pcvs-defs.el --- variable definitions for PCL-CVS 2 3;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 4;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 5 6;; Author: Stefan Monnier <monnier@iro.umontreal.ca> 7;; Keywords: pcl-cvs 8 9;; This file is part of GNU Emacs. 10 11;; GNU Emacs is free software; you can redistribute it and/or modify 12;; it under the terms of the GNU General Public License as published by 13;; the Free Software Foundation; either version 2, or (at your option) 14;; any later version. 15 16;; GNU Emacs is distributed in the hope that it will be useful, 17;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19;; GNU General Public License for more details. 20 21;; You should have received a copy of the GNU General Public License 22;; along with GNU Emacs; see the file COPYING. If not, write to the 23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24;; Boston, MA 02110-1301, USA. 25 26;;; Commentary: 27 28 29;;; Code: 30 31(eval-when-compile (require 'cl)) 32(require 'pcvs-util) 33 34;;;; ------------------------------------------------------- 35;;;; START OF THINGS TO CHECK WHEN INSTALLING 36 37(defvar cvs-program "cvs" 38 "*Name or full path of the cvs executable.") 39 40(defvar cvs-version 41 ;; With the divergence of the CVSNT codebase and version numbers, this is 42 ;; not really good any more. 43 (ignore-errors 44 (with-temp-buffer 45 (call-process cvs-program nil t nil "-v") 46 (goto-char (point-min)) 47 (when (re-search-forward "(CVS\\(NT\\)?) \\([0-9]+\\)\\.\\([0-9]+\\)" 48 nil t) 49 (cons (string-to-number (match-string 1)) 50 (string-to-number (match-string 2)))))) 51 "*Version of `cvs' installed on your system. 52It must be in the (MAJOR . MINOR) format.") 53 54;; FIXME: this is only used by cvs-mode-diff-backup 55(defvar cvs-diff-program (or (and (boundp 'diff-command) diff-command) "diff") 56 "*Name or full path of the best diff program you've got. 57NOTE: there are some nasty bugs in the context diff variants of some vendor 58versions, such as the one in SunOS-4.") 59 60;;;; END OF THINGS TO CHECK WHEN INSTALLING 61;;;; -------------------------------------------------------- 62 63;;;; 64;;;; User configuration variables: 65;;;; 66;;;; NOTE: these should be set in your ~/.emacs (or site-lisp/default.el) file. 67;;;; 68 69(defgroup pcl-cvs nil 70 "Special support for the CVS versioning system." 71 :version "21.1" 72 :group 'tools 73 :prefix "cvs-") 74 75;; 76;; cvsrc options 77;; 78 79(defcustom cvs-cvsrc-file "~/.cvsrc" 80 "Path to your cvsrc file." 81 :group 'pcl-cvs 82 :type '(file)) 83 84(defvar cvs-shared-start 4 85 "Index of the first shared flag. 86If set to 4, for instance, a numeric argument smaller than 4 will 87select a non-shared flag, while a numeric argument greater than 3 88will select a shared-flag.") 89 90(defvar cvs-shared-flags (make-list cvs-shared-start nil) 91 "List of flags whose settings is shared among several commands.") 92 93(defvar cvs-cvsroot nil 94 "*Specifies where the (current) cvs master repository is. 95Overrides the environment variable $CVSROOT by sending \" -d dir\" to 96all CVS commands. This switch is useful if you have multiple CVS 97repositories. It can be set interactively with \\[cvs-change-cvsroot.] 98There is no need to set this if $CVSROOT is set to a correct value.") 99 100(defcustom cvs-auto-remove-handled nil 101 "If up-to-date files should be acknowledged automatically. 102If T, they will be removed from the *cvs* buffer after every command. 103If DELAYED, they will be removed from the *cvs* buffer before every command. 104If STATUS, they will only be removed after a `cvs-mode-status' command. 105Else, they will never be automatically removed from the *cvs* buffer." 106 :group 'pcl-cvs 107 :type '(choice (const nil) (const status) (const delayed) (const t))) 108 109(defcustom cvs-auto-remove-directories 'handled 110 "If ALL, directory entries will never be shown. 111If HANDLED, only non-handled directories will be shown. 112If EMPTY, only non-empty directories will be shown." 113 :group 'pcl-cvs 114 :type '(choice (const :tag "No" nil) (const all) (const handled) (const empty))) 115 116(defcustom cvs-auto-revert t 117 "Non-nil if changed files should automatically be reverted." 118 :group 'pcl-cvs 119 :type '(boolean)) 120 121(defcustom cvs-sort-ignore-file t 122 "Non-nil if `cvs-mode-ignore' should sort the .cvsignore automatically." 123 :group 'pcl-cvs 124 :type '(boolean)) 125 126(defcustom cvs-force-dir-tag t 127 "If non-nil, tagging can only be applied to directories. 128Tagging should generally be applied a directory at a time, but sometimes it is 129useful to be able to tag a single file. The normal way to do that is to use 130`cvs-mode-force-command' so as to temporarily override the restrictions," 131 :group 'pcl-cvs 132 :type '(boolean)) 133 134(defcustom cvs-default-ignore-marks nil 135 "Non-nil if cvs mode commands should ignore any marked files. 136Normally they run on the files that are marked (with `cvs-mode-mark'), 137or the file under the cursor if no files are marked. If this variable 138is set to a non-nil value they will by default run on the file on the 139current line. See also `cvs-invert-ignore-marks'" 140 :group 'pcl-cvs 141 :type '(boolean)) 142 143(defvar cvs-diff-ignore-marks t) 144(make-obsolete-variable 'cvs-diff-ignore-marks 145 'cvs-invert-ignore-marks) 146 147(defcustom cvs-invert-ignore-marks 148 (let ((l ())) 149 (unless (equal cvs-diff-ignore-marks cvs-default-ignore-marks) 150 (push "diff" l)) 151 (when (and cvs-force-dir-tag (not cvs-default-ignore-marks)) 152 (push "tag" l)) 153 l) 154 "List of cvs commands that invert the default ignore-mark behavior. 155Commands in this set will use the opposite default from the one set 156in `cvs-default-ignore-marks'." 157 :group 'pcl-cvs 158 :type '(set (const "diff") 159 (const "tag") 160 (const "ignore"))) 161 162(defcustom cvs-confirm-removals t 163 "Ask for confirmation before removing files. 164Non-nil means that PCL-CVS will ask confirmation before removing files 165except for files whose content can readily be recovered from the repository. 166A value of `list' means that the list of files to be deleted will be 167displayed when asking for confirmation." 168 :group 'pcl-cvs 169 :type '(choice (const list) 170 (const t) 171 (const nil))) 172 173(defcustom cvs-add-default-message nil 174 "Default message to use when adding files. 175If set to nil, `cvs-mode-add' will always prompt for a message." 176 :group 'pcl-cvs 177 :type '(choice (const :tag "Prompt" nil) 178 (string))) 179 180(defvar cvs-diff-buffer-name "*cvs-diff*") 181(make-obsolete-variable 'cvs-diff-buffer-name 182 'cvs-buffer-name-alist) 183 184(defcustom cvs-find-file-and-jump nil 185 "Jump to the modified area when finding a file. 186If non-nil, `cvs-mode-file-file' will place the cursor at the beginning of 187the modified area. If the file is not locally modified, this will obviously 188have no effect." 189 :group 'pcl-cvs 190 :type '(boolean)) 191 192(defcustom cvs-buffer-name-alist 193 '(("diff" cvs-diff-buffer-name diff-mode) 194 ("status" "*cvs-info*" cvs-status-mode) 195 ("tree" "*cvs-info*" cvs-status-mode) 196 ("message" "*cvs-commit*" nil log-edit) 197 ("log" "*cvs-info*" log-view-mode)) 198 "Buffer name and mode to be used for each command. 199This is a list of elements of the form 200 201 (CMD BUFNAME MODE &optional POSTPROC) 202 203CMD is the name of the command. 204BUFNAME is an expression that should evaluate to a string used as 205 a buffer name. It can use the variable CMD if it wants to. 206MODE is the command to use to setup the buffer. 207POSTPROC is a function that should be executed when the command terminates 208 209The CMD used for `cvs-mode-commit' is \"message\". For that special 210 case, POSTPROC is called just after MODE with special arguments." 211 :group 'pcl-cvs 212 :type '(repeat 213 (list (choice (const "diff") 214 (const "status") 215 (const "tree") 216 (const "message") 217 (const "log") 218 (string)) 219 (choice (const "*vc-diff*") 220 (const "*cvs-info*") 221 (const "*cvs-commit*") 222 (const (expand-file-name "*cvs-commit*")) 223 (const (format "*cvs-%s*" cmd)) 224 (const (expand-file-name (format "*cvs-%s*" cmd))) 225 (sexp :value "my-cvs-info-buffer") 226 (const nil)) 227 (choice (function-item diff-mode) 228 (function-item cvs-edit-mode) 229 (function-item cvs-status-mode) 230 function 231 (const nil)) 232 (set :inline t 233 (choice (function-item cvs-status-cvstrees) 234 (function-item cvs-status-trees) 235 function))))) 236 237(defvar cvs-buffer-name '(expand-file-name "*cvs*" dir) ;; "*cvs*" 238 "Name of the cvs buffer. 239This expression will be evaluated in an environment where DIR is set to 240the directory name of the cvs buffer.") 241 242(defvar cvs-temp-buffer-name 243 ;; Was '(expand-file-name " *cvs-tmp*" dir), but that causes them to 244 ;; become non-hidden if uniquification is done `forward'. 245 " *cvs-tmp*" 246 "*Name of the cvs temporary buffer. 247Output from cvs is placed here for asynchronous commands.") 248 249(defcustom cvs-idiff-imerge-handlers 250 (if (fboundp 'ediff) 251 '(cvs-ediff-diff . cvs-ediff-merge) 252 '(cvs-emerge-diff . cvs-emerge-merge)) 253 "Pair of functions to be used for resp. diff'ing and merg'ing interactively." 254 :group 'pcl-cvs 255 :type '(choice (const :tag "Ediff" (cvs-ediff-diff . cvs-ediff-merge)) 256 (const :tag "Emerge" (cvs-emerge-diff . cvs-emerge-merge)))) 257 258(defvar cvs-mode-hook nil 259 "Run after `cvs-mode' was setup.") 260 261 262;;;; 263;;;; Internal variables, used in the process buffer. 264;;;; 265 266(defvar cvs-postprocess nil 267 "(Buffer local) what to do once the process exits.") 268 269;;;; 270;;;; Internal variables for the *cvs* buffer. 271;;;; 272 273(defcustom cvs-reuse-cvs-buffer 'subdir 274 "When to reuse an existing cvs buffer. 275Alternatives are: 276 CURRENT: just reuse the current buffer if it is a cvs buffer 277 SAMEDIR: reuse any cvs buffer displaying the same directory 278 SUBDIR: or reuse any cvs buffer displaying any sub- or super- directory 279 ALWAYS: reuse any cvs buffer." 280 :group 'pcl-cvs 281 :type '(choice (const always) (const subdir) (const samedir) (const current))) 282 283(defvar cvs-temp-buffer nil 284 "(Buffer local) The temporary buffer associated with this *cvs* buffer.") 285 286(defvar cvs-lock-file nil 287 "Full path to a lock file that CVS is waiting for (or was waiting for). 288This variable is buffer local and only used in the *cvs* buffer.") 289 290(defvar cvs-lock-file-regexp "^#cvs\\.\\([trw]fl\\.[-.a-z0-9]+\\|lock\\)\\'" 291 "Regexp matching the possible names of locks in the CVS repository.") 292 293(defconst cvs-cursor-column 22 294 "Column to position cursor in in `cvs-mode'.") 295 296;;;; 297;;;; Global internal variables 298;;;; 299 300(defconst cvs-vendor-branch "1.1.1" 301 "The default branch used by CVS for vendor code.") 302 303(easy-mmode-defmap cvs-mode-diff-map 304 '(("E" "imerge" . cvs-mode-imerge) 305 ("=" . cvs-mode-diff) 306 ("e" "idiff" . cvs-mode-idiff) 307 ("2" "other" . cvs-mode-idiff-other) 308 ("d" "diff" . cvs-mode-diff) 309 ("b" "backup" . cvs-mode-diff-backup) 310 ("h" "head" . cvs-mode-diff-head) 311 ("r" "repository" . cvs-mode-diff-repository) 312 ("y" "yesterday" . cvs-mode-diff-yesterday) 313 ("v" "vendor" . cvs-mode-diff-vendor)) 314 "Keymap for diff-related operations in `cvs-mode'." 315 :name "Diff") 316;; This is necessary to allow correct handling of \\[cvs-mode-diff-map] 317;; in substitute-command-keys. 318(fset 'cvs-mode-diff-map cvs-mode-diff-map) 319 320(easy-mmode-defmap cvs-mode-map 321 ;;(define-prefix-command 'cvs-mode-map-diff-prefix) 322 ;;(define-prefix-command 'cvs-mode-map-control-c-prefix) 323 '(;; simulate `suppress-keymap' 324 (self-insert-command . undefined) 325 (("0" "1" "2" "3" "4" "5" "6" "7" "8" "9") . digit-argument) 326 ("-" . negative-argument) 327 ;; various 328 ;; (undo . cvs-mode-undo) 329 ("?" . cvs-help) 330 ("h" . cvs-help) 331 ("q" . cvs-bury-buffer) 332 ("z" . kill-this-buffer) 333 ("F" . cvs-mode-set-flags) 334 ;; ("\M-f" . cvs-mode-force-command) 335 ("!" . cvs-mode-force-command) 336 ("\C-c\C-c" . cvs-mode-kill-process) 337 ;; marking 338 ("m" . cvs-mode-mark) 339 ("M" . cvs-mode-mark-all-files) 340 ("S" . cvs-mode-mark-on-state) 341 ("u" . cvs-mode-unmark) 342 ("\C-?". cvs-mode-unmark-up) 343 ("%" . cvs-mode-mark-matching-files) 344 ("T" . cvs-mode-toggle-marks) 345 ("\M-\C-?" . cvs-mode-unmark-all-files) 346 ;; navigation keys 347 (" " . cvs-mode-next-line) 348 ("n" . cvs-mode-next-line) 349 ("p" . cvs-mode-previous-line) 350 ;; M- keys are usually those that operate on modules 351 ;;("\M-C". cvs-mode-rcs2log) ; i.e. "Create a ChangeLog" 352 ;;("\M-t". cvs-rtag) 353 ;;("\M-l". cvs-rlog) 354 ("\M-c". cvs-checkout) 355 ("\M-e". cvs-examine) 356 ("g" . cvs-mode-revert-buffer) 357 ("\M-u". cvs-update) 358 ("\M-s". cvs-status) 359 ;; diff commands 360 ("=" . cvs-mode-diff) 361 ("d" . cvs-mode-diff-map) 362 ;; keys that operate on individual files 363 ("\C-k" . cvs-mode-acknowledge) 364 ("A" . cvs-mode-add-change-log-entry-other-window) 365 ;;("B" . cvs-mode-byte-compile-files) 366 ("C" . cvs-mode-commit-setup) 367 ("O" . cvs-mode-update) 368 ("U" . cvs-mode-undo) 369 ("I" . cvs-mode-insert) 370 ("a" . cvs-mode-add) 371 ("b" . cvs-set-branch-prefix) 372 ("B" . cvs-set-secondary-branch-prefix) 373 ("c" . cvs-mode-commit) 374 ("e" . cvs-mode-examine) 375 ("f" . cvs-mode-find-file) 376 ("\C-m" . cvs-mode-find-file) 377 ("i" . cvs-mode-ignore) 378 ("l" . cvs-mode-log) 379 ("o" . cvs-mode-find-file-other-window) 380 ("r" . cvs-mode-remove) 381 ("s" . cvs-mode-status) 382 ("t" . cvs-mode-tag) 383 ("v" . cvs-mode-view-file) 384 ("x" . cvs-mode-remove-handled) 385 ;; cvstree bindings 386 ("+" . cvs-mode-tree) 387 ;; mouse bindings 388 ([mouse-2] . cvs-mode-find-file) 389 ([follow-link] . (lambda (pos) 390 (if (eq (get-char-property pos 'face) 'cvs-filename) t))) 391 ([(down-mouse-3)] . cvs-menu) 392 ;; dired-like bindings 393 ("\C-o" . cvs-mode-display-file) 394 ;; Emacs-21 toolbar 395 ;;([tool-bar item1] . (menu-item "Examine" cvs-examine :image (image :file "/usr/share/icons/xpaint.xpm" :type xpm))) 396 ;;([tool-bar item2] . (menu-item "Update" cvs-update :image (image :file "/usr/share/icons/mail1.xpm" :type xpm))) 397 ) 398 "Keymap for `cvs-mode'." 399 :dense t) 400 401(fset 'cvs-mode-map cvs-mode-map) 402 403(easy-menu-define cvs-menu cvs-mode-map "Menu used in `cvs-mode'." 404 '("CVS" 405 ["Open file.." cvs-mode-find-file t] 406 [" ..other window" cvs-mode-find-file-other-window t] 407 ["Display in other window" cvs-mode-display-file t] 408 ["Interactive merge" cvs-mode-imerge t] 409 ("View diff" 410 ["Interactive diff" cvs-mode-idiff t] 411 ["Current diff" cvs-mode-diff t] 412 ["Diff with head" cvs-mode-diff-head t] 413 ["Diff with vendor" cvs-mode-diff-vendor t] 414 ["Diff with backup" cvs-mode-diff-backup t]) 415 ["View log" cvs-mode-log t] 416 ["View status" cvs-mode-status t] 417 ["View tag tree" cvs-mode-tree t] 418 "----" 419 ["Insert" cvs-mode-insert] 420 ["Update" cvs-mode-update (cvs-enabledp 'update)] 421 ["Re-examine" cvs-mode-examine t] 422 ["Commit" cvs-mode-commit-setup (cvs-enabledp 'commit)] 423 ["Tag" cvs-mode-tag (cvs-enabledp (when cvs-force-dir-tag 'tag))] 424 ["Undo changes" cvs-mode-undo (cvs-enabledp 'undo)] 425 ["Add" cvs-mode-add (cvs-enabledp 'add)] 426 ["Remove" cvs-mode-remove (cvs-enabledp 'remove)] 427 ["Ignore" cvs-mode-ignore (cvs-enabledp 'ignore)] 428 ["Add ChangeLog" cvs-mode-add-change-log-entry-other-window t] 429 "----" 430 ["Mark" cvs-mode-mark t] 431 ["Mark all" cvs-mode-mark-all-files t] 432 ["Mark by regexp..." cvs-mode-mark-matching-files t] 433 ["Mark by state..." cvs-mode-mark-on-state t] 434 ["Unmark" cvs-mode-unmark t] 435 ["Unmark all" cvs-mode-unmark-all-files t] 436 ["Hide handled" cvs-mode-remove-handled t] 437 "----" 438 ["Quit" cvs-mode-quit t])) 439 440;;;; 441;;;; CVS-Minor mode 442;;;; 443 444(defcustom cvs-minor-mode-prefix "\C-xc" 445 "Prefix key for the `cvs-mode' bindings in `cvs-minor-mode'." 446 :group 'pcl-cvs) 447 448(easy-mmode-defmap cvs-minor-mode-map 449 `((,cvs-minor-mode-prefix . cvs-mode-map) 450 ("e" . (menu-item nil cvs-mode-edit-log 451 :filter (lambda (x) (if (derived-mode-p 'log-view-mode) x))))) 452 "Keymap for `cvs-minor-mode', used in buffers related to PCL-CVS.") 453 454(defvar cvs-buffer nil 455 "(Buffer local) The *cvs* buffer associated with this buffer.") 456(put 'cvs-buffer 'permanent-local t) 457;;(make-variable-buffer-local 'cvs-buffer) 458 459(defvar cvs-minor-wrap-function nil 460 "Function to call when switching to the *cvs* buffer. 461Takes two arguments: 462- a *cvs* buffer. 463- a zero-arg function which is guaranteed not to switch buffer. 464It is expected to call the function.") 465;;(make-variable-buffer-local 'cvs-minor-wrap-function) 466 467(defvar cvs-minor-current-files) 468;;"Current files in a `cvs-minor-mode' buffer." 469;; This should stay `void' because we want to be able to tell the difference 470;; between an empty list and no list at all. 471 472(defconst cvs-pcl-cvs-dirchange-re "^pcl-cvs: descending directory \\(.*\\)$") 473 474;;;; 475;;;; autoload the global menu 476;;;; 477 478;;;###autoload 479(defvar cvs-global-menu 480 (let ((m (make-sparse-keymap "PCL-CVS"))) 481 (define-key m [status] 482 '(menu-item "Directory Status" cvs-status 483 :help "A more verbose status of a workarea")) 484 (define-key m [checkout] 485 '(menu-item "Checkout Module" cvs-checkout 486 :help "Check out a module from the repository")) 487 (define-key m [update] 488 '(menu-item "Update Directory" cvs-update 489 :help "Fetch updates from the repository")) 490 (define-key m [examine] 491 '(menu-item "Examine Directory" cvs-examine 492 :help "Examine the current state of a workarea")) 493 (fset 'cvs-global-menu m))) 494 495 496;; cvs-1.10 and above can take file arguments in other directories 497;; while others need to be executed once per directory 498(defvar cvs-execute-single-dir 499 (if (or (null cvs-version) 500 (or (>= (cdr cvs-version) 10) (> (car cvs-version) 1))) 501 ;; Supposedly some recent versions of CVS output some directory info 502 ;; as they recurse downthe tree, but it's not good enough in the case 503 ;; where we run "cvs status foo bar/foo". 504 '("status") 505 t) 506 "Whether cvs commands should be executed a directory at a time. 507If a list, specifies for which commands the single-dir mode should be used. 508If T, single-dir mode should be used for all operations. 509 510CVS versions before 1.10 did not allow passing them arguments in different 511directories, so pcl-cvs checks what version you're using to determine 512whether to use the new feature or not. 513Sadly, even with a new cvs executable, if you connect to an older cvs server 514\(typically a cvs-1.9 on the server), the old restriction applies. In such 515a case the sanity check made by pcl-cvs fails and you will have to manually 516set this variable to t (until the cvs server is upgraded). 517When the above problem occurs, pcl-cvs should (hopefully) catch cvs' error 518message and replace it with a message telling you to change this variable.") 519 520;; 521(provide 'pcvs-defs) 522 523;; arch-tag: c7c701d0-d1d4-4aa9-a302-007bb03aca5e 524;;; pcvs-defs.el ends here 525