# HG changeset patch # User Dan Nicolaescu # Date 1268991461 25200 # Node ID 1918e70c8b37b0b42cb5756f6fb585f0fc27259c # Parent 024cba2776d2af01415dbe82d047419891029e3d Add special markup processing for commit logs. * log-edit.el (log-edit-extra-flags): New variable. (log-edit): Add new argument MODE. Use that mode when non-nil instead of the log-view-mode. (log-view-process-buffer): New function. * vc.el: Document that the checkin method takes optional arguments. Document new backend specific method: log-view-mode. (vc-default-log-edit-mode): New function. (vc-checkin): Use a backend specific log-view-mode. Pass extra arguments to the checkin method. (vc-modify-change-comment): Pass a dummy extra argument. * vc-dispatcher.el (vc-log-edit): Add a mode argument, pass it to log-edit. (vc-start-logentry): Add a mode argument, pass it to vc-log-edit. (vc-finish-logentry): Process the log buffer before passing it down. Pass log-edit-extra-flags. * vc-bzr.el (vc-bzr-checkin): Pass extra arguments to the commit command. (log-edit-extra-flags, log-edit-before-checkin-process): New declarations. * vc-hg.el (vc-hg-checkin): Pass extra arguments to the commit command. (log-edit-extra-flags, log-edit-before-checkin-process): New declarations. (vc-hg-log-edit-mode): New derived mode. * vc-arch.el (vc-arch-checkin): * vc-cvs.el (vc-cvs-checkin): * vc-git.el (vc-git-checkin): * vc-mtn.el (vc-mtn-checkin): * vc-rcs.el (vc-rcs-checkin): * vc-sccs.el (vc-sccs-checkin): * vc-svn.el (vc-svn-checkin): Add an optional ignored argument. diff -r 024cba2776d2 -r 1918e70c8b37 etc/NEWS --- a/etc/NEWS Thu Mar 18 23:32:47 2010 -0400 +++ b/etc/NEWS Fri Mar 19 02:37:41 2010 -0700 @@ -63,6 +63,16 @@ *** vc-dir for Bzr supports viewing shelve contents and shelving snapshots. +*** Special markup can be added to log-edit buffers. + +**** For Bzr, adding an +Author: NAME +line will add "--author NAME" to the "bzr commit" command. + +**** For Hg, adding an +Author: NAME +line will add "--user NAME" to the "hg commit" command. + ** Directory local variables can apply to file-less buffers. For example, adding "(diff-mode . ((mode . whitespace)))" to your .dir-locals.el file, will turn on `whitespace-mode' for *vc-diff* diff -r 024cba2776d2 -r 1918e70c8b37 lisp/ChangeLog --- a/lisp/ChangeLog Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/ChangeLog Fri Mar 19 02:37:41 2010 -0700 @@ -1,3 +1,41 @@ +2010-03-19 Dan Nicolaescu + + Add special markup processing for commit logs. + * log-edit.el (log-edit-extra-flags): New variable. + (log-edit): Add new argument MODE. Use that mode when non-nil + instead of the log-view-mode. + (log-view-process-buffer): New function. + + * vc.el: Document that the checkin method takes optional + arguments. Document new backend specific method: log-view-mode. + (vc-default-log-edit-mode): New function. + (vc-checkin): Use a backend specific log-view-mode. + Pass extra arguments to the checkin method. + (vc-modify-change-comment): Pass a dummy extra argument. + + * vc-dispatcher.el (vc-log-edit): Add a mode argument, pass it to + log-edit. + (vc-start-logentry): Add a mode argument, pass it to vc-log-edit. + (vc-finish-logentry): Process the log buffer before passing it + down. Pass log-edit-extra-flags. + + * vc-bzr.el (vc-bzr-checkin): Pass extra arguments to the commit + command. + (log-edit-extra-flags, log-edit-before-checkin-process): New declarations. + + * vc-hg.el (vc-hg-checkin): Pass extra arguments to the commit + command. + (log-edit-extra-flags, log-edit-before-checkin-process): New declarations. + (vc-hg-log-edit-mode): New derived mode. + + * vc-arch.el (vc-arch-checkin): + * vc-cvs.el (vc-cvs-checkin): + * vc-git.el (vc-git-checkin): + * vc-mtn.el (vc-mtn-checkin): + * vc-rcs.el (vc-rcs-checkin): + * vc-sccs.el (vc-sccs-checkin): + * vc-svn.el (vc-svn-checkin): Add an optional ignored argument. + 2010-03-19 Stefan Monnier * outline.el (hide-sublevels): Don't hide trailing newline (and fix diff -r 024cba2776d2 -r 1918e70c8b37 lisp/log-edit.el --- a/lisp/log-edit.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/log-edit.el Fri Mar 19 02:37:41 2010 -0700 @@ -188,6 +188,25 @@ (defvar log-edit-callback nil) (defvar log-edit-diff-function nil) (defvar log-edit-listfun nil) +(defvar log-edit-extra-flags nil + "List of extra flags to pass to the check in command.") +(defvar log-edit-before-checkin-process nil + "Alist that contains instructions for processing the commit message before check in. + +The format is: (REGEXP . INSTRUCTIONS). + +All lines matching REGEXP are removed. + +For example: + +(\"^#.*\" . nil) +means: just remove all lines starting with #. This can be used +to insert lines in the commit buffer that contain, for example, the +list of files to be committed. + +(\"Author: \\(.*\\)\" . (list \"--author\" (match-string 1))) +means: append (list \"--author\" (match-string 1)) to +`log-edit-extra-flags'.") (defvar log-edit-parent-buffer nil) ;;; Originally taken from VC-Log mode @@ -318,9 +337,10 @@ (2 font-lock-function-name-face)))) ;;;###autoload -(defun log-edit (callback &optional setup params buffer &rest ignore) +(defun log-edit (callback &optional setup params buffer mode &rest ignore) "Setup a buffer to enter a log message. -\\The buffer will be put in `log-edit-mode'. +\\The buffer will be put in mode MODE or `log-edit-mode' +if MODE is nil. If SETUP is non-nil, the buffer is then erased and `log-edit-hook' is run. Mark and point will be set around the entire contents of the buffer so that it is easy to kill the contents of the buffer with \\[kill-region]. @@ -341,7 +361,9 @@ (when (and log-edit-setup-invert (not (eq setup 'force))) (setq setup (not setup))) (when setup (erase-buffer)) - (log-edit-mode) + (if mode + (funcall mode) + (log-edit-mode)) (set (make-local-variable 'log-edit-callback) callback) (if (listp params) (dolist (crt params) @@ -711,6 +733,17 @@ (log-edit-changelog-insert-entries (car buffer-entry) (cdr buffer-entry)) (when (cdr buffer-entry) (newline))))) +(defun log-view-process-buffer () + (when log-edit-before-checkin-process + (dolist (crt log-edit-before-checkin-process) + ;; Remove all lines matching (car crt) + ;; Append to `log-edit-extra-flags' the results of (cdr crt). + (goto-char (point-min)) + (while (re-search-forward (car crt) nil t) + (when (cdr crt) + (setq log-edit-extra-flags (append log-edit-extra-flags (eval (cdr crt))))) + (replace-match "" nil t))))) + (provide 'log-edit) ;; arch-tag: 8089b39c-983b-4e83-93cd-ed0a64c7fdcc diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-arch.el --- a/lisp/vc-arch.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-arch.el Fri Mar 19 02:37:41 2010 -0700 @@ -428,7 +428,7 @@ (message "There are unresolved conflicts in %s" (file-name-nondirectory rej)))))) -(defun vc-arch-checkin (files rev comment) +(defun vc-arch-checkin (files rev comment &optional extra-args-ignored) (if rev (error "Committing to a specific revision is unsupported")) ;; FIXME: This implementation probably only works for singleton filesets (let ((summary (file-relative-name (car files) (vc-arch-root (car files))))) diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-bzr.el --- a/lisp/vc-bzr.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-bzr.el Fri Mar 19 02:37:41 2010 -0700 @@ -451,11 +451,11 @@ "Unregister FILE from bzr." (vc-bzr-command "remove" nil 0 file "--keep")) -(defun vc-bzr-checkin (files rev comment) +(defun vc-bzr-checkin (files rev comment &optional extra-args) "Check FILE in to bzr with log message COMMENT. REV non-nil gets an error." (if rev (error "Can't check in a specific revision with bzr")) - (vc-bzr-command "commit" nil 0 files "-m" comment)) + (apply 'vc-bzr-command "commit" nil 0 files (append (list "-m" comment) extra-args))) (defun vc-bzr-find-revision (file rev buffer) "Fetch revision REV of file FILE and put it into BUFFER." @@ -545,6 +545,20 @@ (goto-char (point-min))) found))) +(defvar log-edit-extra-flags) +(defvar log-edit-before-checkin-process) + +(define-derived-mode vc-bzr-log-edit-mode log-edit-mode "Bzr-Log-Edit" + "Mode for editing Bzr commit logs. +If a line like: +Author: NAME +is present in the log, it is removed, and +--author NAME +is passed to the bzr commit command." + (set (make-local-variable 'log-edit-extra-flags) nil) + (set (make-local-variable 'log-edit-before-checkin-process) + '(("^Author:[ \t]+\\(.*\\)[ \t]*$" . (list "--author" (match-string 1)))))) + (defun vc-bzr-diff (files &optional rev1 rev2 buffer) "VC bzr backend for diff." ;; `bzr diff' exits with code 1 if diff is non-empty. diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-cvs.el --- a/lisp/vc-cvs.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-cvs.el Fri Mar 19 02:37:41 2010 -0700 @@ -313,7 +313,7 @@ (directory-file-name dir)))) (eq dir t))) -(defun vc-cvs-checkin (files rev comment) +(defun vc-cvs-checkin (files rev comment &optional extra-args-ignored) "CVS-specific version of `vc-backend-checkin'." (unless (or (not rev) (vc-cvs-valid-revision-number-p rev)) (if (not (vc-cvs-valid-symbolic-tag-name-p rev)) diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-dispatcher.el --- a/lisp/vc-dispatcher.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-dispatcher.el Fri Mar 19 02:37:41 2010 -0700 @@ -522,20 +522,22 @@ ;; Set up key bindings for use while editing log messages -(defun vc-log-edit (fileset) +(defun vc-log-edit (fileset mode) "Set up `log-edit' for use on FILE." (setq default-directory (with-current-buffer vc-parent-buffer default-directory)) (log-edit 'vc-finish-logentry nil `((log-edit-listfun . (lambda () ',fileset)) - (log-edit-diff-function . (lambda () (vc-diff nil))))) + (log-edit-diff-function . (lambda () (vc-diff nil)))) + nil + mode) (set (make-local-variable 'vc-log-fileset) fileset) (make-local-variable 'vc-log-extra) (set-buffer-modified-p nil) (setq buffer-file-name nil)) -(defun vc-start-logentry (files extra comment initial-contents msg logbuf action &optional after-hook) +(defun vc-start-logentry (files extra comment initial-contents msg logbuf mode action &optional after-hook) "Accept a comment for an operation on FILES with extra data EXTRA. If COMMENT is nil, pop up a LOGBUF buffer, emit MSG, and set the action on close to ACTION. If COMMENT is a string and @@ -560,7 +562,7 @@ (set (make-local-variable 'vc-parent-buffer) parent) (set (make-local-variable 'vc-parent-buffer-name) (concat " from " (buffer-name vc-parent-buffer))) - (vc-log-edit files) + (vc-log-edit files mode) (make-local-variable 'vc-log-after-operation-hook) (when after-hook (setq vc-log-after-operation-hook after-hook)) @@ -590,12 +592,16 @@ (or (vc-dispatcher-browsing) (vc-buffer-sync))) (unless vc-log-operation (error "No log operation is pending")) + + (log-view-process-buffer) + ;; save the parameters held in buffer-local variables (let ((logbuf (current-buffer)) (log-operation vc-log-operation) (log-fileset vc-log-fileset) (log-extra vc-log-extra) (log-entry (buffer-string)) + (extra-flags log-edit-extra-flags) (after-hook vc-log-after-operation-hook) (tmp-vc-parent-buffer vc-parent-buffer)) (pop-to-buffer vc-parent-buffer) @@ -604,7 +610,9 @@ (funcall log-operation log-fileset log-extra - log-entry)) + log-entry + extra-flags + )) ;; Remove checkin window (after the checkin so that if that fails ;; we don't zap the log buffer and the typing therein). ;; -- IMO this should be replaced with quit-window diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-git.el --- a/lisp/vc-git.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-git.el Fri Mar 19 02:37:41 2010 -0700 @@ -541,7 +541,7 @@ (vc-git-command nil 0 file "rm" "-f" "--cached" "--")) -(defun vc-git-checkin (files rev comment) +(defun vc-git-checkin (files rev comment &optional extra-args-ignored) (let ((coding-system-for-write git-commits-coding-system)) (vc-git-command nil 0 files "commit" "-m" comment "--only" "--"))) diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-hg.el --- a/lisp/vc-hg.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-hg.el Fri Mar 19 02:37:41 2010 -0700 @@ -279,6 +279,20 @@ ("^date: \\(.+\\)" (1 'change-log-date)) ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))) +(defvar log-edit-extra-flags) +(defvar log-edit-before-checkin-process) + +(define-derived-mode vc-hg-log-edit-mode log-edit-mode "Hg-log-edit" + "Mode for editing Hg commit logs. +If a line like: +Author: NAME +is present in the log, it is removed, and +--author NAME +is passed to the hg commit command." + (set (make-local-variable 'log-edit-extra-flags) nil) + (set (make-local-variable 'log-edit-before-checkin-process) + '(("^Author:[ \t]+\\(.*\\)[ \t]*$" . (list "--user" (match-string 1)))))) + (defun vc-hg-diff (files &optional oldvers newvers buffer) "Get a difference report using hg between two revisions of FILES." (let* ((firstfile (car files)) @@ -401,10 +415,10 @@ ;; "Unregister FILE from hg." ;; (vc-hg-command nil nil file "remove")) -(defun vc-hg-checkin (files rev comment) +(defun vc-hg-checkin (files rev comment &optional extra-args) "Hg-specific version of `vc-backend-checkin'. REV is ignored." - (vc-hg-command nil 0 files "commit" "-m" comment)) + (apply 'vc-hg-command nil 0 files (append (list "commit" "-m" comment) extra-args))) (defun vc-hg-find-revision (file rev buffer) (let ((coding-system-for-read 'binary) diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-mtn.el --- a/lisp/vc-mtn.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-mtn.el Fri Mar 19 02:37:41 2010 -0700 @@ -172,7 +172,7 @@ (defun vc-mtn-responsible-p (file) (vc-mtn-root file)) (defun vc-mtn-could-register (file) (vc-mtn-root file)) -(defun vc-mtn-checkin (files rev comment) +(defun vc-mtn-checkin (files rev comment &optional extra-args-ignored) (vc-mtn-command nil 0 files "commit" "-m" comment)) (defun vc-mtn-find-revision (file rev buffer) diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-rcs.el --- a/lisp/vc-rcs.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-rcs.el Fri Mar 19 02:37:41 2010 -0700 @@ -348,7 +348,7 @@ (yes-or-no-p (format "Directory %s is empty; remove it? " dir)) (delete-directory dir)))) -(defun vc-rcs-checkin (files rev comment) +(defun vc-rcs-checkin (files rev comment &optional extra-args-ignored) "RCS-specific version of `vc-backend-checkin'." (let ((switches (vc-switches 'RCS 'checkin))) ;; Now operate on the files diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-sccs.el --- a/lisp/vc-sccs.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-sccs.el Fri Mar 19 02:37:41 2010 -0700 @@ -235,7 +235,7 @@ (stringp (vc-sccs-search-project-dir (or (file-name-directory file) "") (file-name-nondirectory file))))) -(defun vc-sccs-checkin (files rev comment) +(defun vc-sccs-checkin (files rev comment &optional extra-args-ignored) "SCCS-specific version of `vc-backend-checkin'." (dolist (file (vc-expand-dirs files)) (apply 'vc-sccs-do-command nil 0 "delta" (vc-name file) diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc-svn.el --- a/lisp/vc-svn.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc-svn.el Fri Mar 19 02:37:41 2010 -0700 @@ -282,7 +282,7 @@ "Return non-nil if FILE could be registered in SVN. This is only possible if SVN is responsible for FILE's directory.") -(defun vc-svn-checkin (files rev comment) +(defun vc-svn-checkin (files rev comment &optional extra-args-ignored) "SVN-specific version of `vc-backend-checkin'." (if rev (error "Committing to a specific revision is unsupported in SVN")) (let ((status (apply diff -r 024cba2776d2 -r 1918e70c8b37 lisp/vc.el --- a/lisp/vc.el Thu Mar 18 23:32:47 2010 -0400 +++ b/lisp/vc.el Fri Mar 19 02:37:41 2010 -0700 @@ -261,7 +261,7 @@ ;; Unregister FILE from this backend. This is only needed if this ;; backend may be used as a "more local" backend for temporary editing. ;; -;; * checkin (files rev comment) +;; * checkin (files rev comment &optional extra-args) ;; ;; Commit changes in FILES to this backend. If REV is non-nil, that ;; should become the new revision number (not all backends do @@ -269,6 +269,7 @@ ;; implementation should pass the value of vc-checkin-switches to ;; the backend command. (Note: in older versions of VC, this ;; command took a single file argument and not a list.) +;; EXTRA-ARGS should be passed to the backend command. ;; ;; * find-revision (file rev buffer) ;; @@ -477,6 +478,12 @@ ;; Return the revision number that follows REV for FILE, or nil if no such ;; revision exists. ;; +;; - log-edit-mode () +;; +;; Turn on the mode used for editing the check in log. This +;; defaults to `log-edit-mode'. If changed, it should use a mode +;; derived from`log-edit-mode'. +;; ;; - check-headers () ;; ;; Return non-nil if the current buffer contains any version headers. @@ -1358,7 +1365,9 @@ files rev comment initial-contents "Enter a change comment." "*VC-log*" - (lambda (files rev comment) + (lambda () + (vc-call-backend backend 'log-edit-mode)) + (lambda (files rev comment extra-flags) (message "Checking in %s..." (vc-delistify files)) ;; "This log message intentionally left almost blank". ;; RCS 5.7 gripes about white-space-only comments too. @@ -1369,7 +1378,7 @@ ;; We used to change buffers to get local value of vc-checkin-switches, ;; but 'the' local buffer is not a well-defined concept for filesets. (progn - (vc-call-backend backend 'checkin files rev comment) + (vc-call-backend backend 'checkin files rev comment extra-flags) (mapc 'vc-delete-automatic-version-backups files)) `((vc-state . up-to-date) (vc-checkout-time . ,(nth 5 (file-attributes file))) @@ -1739,7 +1748,7 @@ files rev oldcomment t "Enter a replacement change comment." "*VC-log*" - (lambda (files rev comment) + (lambda (files rev comment ignored) (vc-call-backend ;; Less of a kluge than it looks like; log-view mode only passes ;; this function a singleton list. Arguments left in this form in @@ -2424,6 +2433,8 @@ (defalias 'vc-default-check-headers 'ignore) +(defun vc-default-log-edit-mode (backend) (log-edit-mode)) + (defun vc-default-log-view-mode (backend) (log-view-mode)) (defun vc-default-show-log-entry (backend rev)