# HG changeset patch # User Bryan O'Sullivan # Date 1156291162 25200 # Node ID e2bad806ccc3716abd9dc490e60854db881a42ca # Parent c203ccd7d838f008481c82478bfe74aae94d2860 mq.el: add ability to edit a patch. diff -r c203ccd7d838 -r e2bad806ccc3 contrib/mq.el --- a/contrib/mq.el Tue Aug 22 16:59:09 2006 -0700 +++ b/contrib/mq.el Tue Aug 22 16:59:22 2006 -0700 @@ -31,11 +31,20 @@ :type 'sexp :group 'mercurial) +(defcustom mq-edit-mode-hook nil + "Hook run after a buffer is populated to edit a patch description." + :type 'sexp + :group 'mercurial) + ;;; Internal variables. (defvar mq-patch-history nil) +(defvar mq-prev-buffer nil) +(make-variable-buffer-local 'mq-prev-buffer) +(put 'mq-prev-buffer 'permanent-local t) + ;;; Global keymap. @@ -53,6 +62,13 @@ (define-key mq-global-map "t" 'mq-top) +;;; Refresh edit mode keymap. + +(defvar mq-edit-mode-map (make-sparse-keymap)) +(define-key mq-edit-mode-map "\C-c\C-c" 'mq-edit-finish) +(define-key mq-edit-mode-map "\C-c\C-k" 'mq-edit-kill) + + ;;; Helper functions. (defun mq-read-patch-name (&optional source prompt) @@ -157,45 +173,103 @@ (interactive) (mq-pop "-a")) +(defun mq-refresh-internal (root &rest args) + (hg-sync-buffers root) + (let ((patch (mq-patch-info "qtop"))) + (message "Refreshing %s..." patch) + (let ((ret (apply 'hg-run "qrefresh" args))) + (if (equal (car ret) 0) + (message "Refreshing %s... done." patch) + (error "Refreshing %s... %s" patch (hg-chomp (cdr ret))))))) + (defun mq-refresh () "Refresh the topmost applied patch." (interactive) (let ((root (hg-root))) (unless root - (error "Cannot refresh outside a repository!")) - (hg-sync-buffers root) - (message "Refreshing patch...") - (let ((ret (hg-run "qrefresh"))) - (if (equal (car ret) 0) - (message "Refreshing patch... done.") - (error "Refreshing patch... %s" (hg-chomp (cdr ret))))))) + (error "Cannot refresh outside of a repository!")) + (mq-refresh-internal root))) -(defun mq-patch-info (msg cmd) - (let ((ret (hg-run cmd))) +(defun mq-patch-info (cmd &optional msg) + (let* ((ret (hg-run cmd)) + (info (hg-chomp (cdr ret)))) (if (equal (car ret) 0) - (message "%s %s" msg (hg-chomp (cdr ret))) - (error "%s" (cdr ret))))) + (if msg + (message "%s patch: %s" msg info) + info) + (error "%s" info)))) (defun mq-top () "Print the name of the topmost applied patch." (interactive) - (mq-patch-info "Top patch is " "qtop")) + (mq-patch-info "qtop" "Top")) (defun mq-next () "Print the name of the next patch to be pushed." (interactive) - (mq-patch-info "Next patch is " "qnext")) + (mq-patch-info "qnext" "Next")) (defun mq-previous () "Print the name of the first patch below the topmost applied patch. This would become the active patch if popped to." (interactive) - (mq-patch-info "Previous patch is " "qprev")) + (mq-patch-info "qprev" "Previous")) +(defun mq-edit-finish () + (interactive) + (unless (equal (mq-patch-info "qtop") mq-top) + (error "Topmost patch has changed!")) + (hg-sync-buffers hg-root) + (mq-refresh-internal hg-root "-m" (buffer-substring (point-min) (point-max))) + (let ((buf mq-prev-buffer)) + (kill-buffer nil) + (switch-to-buffer buf))) + +(defun mq-edit-kill () + "Kill the edit currently being prepared." + (interactive) + (when (or (not (buffer-modified-p)) (y-or-n-p "Really kill this edit? ")) + (let ((buf mq-prev-buffer)) + (kill-buffer nil) + (switch-to-buffer buf)))) + +(defun mq-edit-mode () + "Mode for editing the description of a patch. + +Key bindings +------------ +\\[mq-edit-finish] use this description +\\[mq-edit-kill] abandon this description" + (interactive) + (use-local-map mq-edit-mode-map) + (set-syntax-table text-mode-syntax-table) + (setq local-abbrev-table text-mode-abbrev-table + major-mode 'mq-edit-mode + mode-name "MQ-Edit") + (set-buffer-modified-p nil) + (setq buffer-undo-list nil) + (run-hooks 'text-mode-hook 'mq-edit-mode-hook)) + (defun mq-refresh-edit () "Refresh the topmost applied patch, editing the patch description." (interactive) - (error "Not yet implemented")) + (while mq-prev-buffer + (set-buffer mq-prev-buffer)) + (let ((root (hg-root)) + (prev-buffer (current-buffer)) + (patch (mq-patch-info "qtop"))) + (hg-sync-buffers root) + (let ((buf-name (format "*MQ: Edit description of %s*" patch))) + (switch-to-buffer (get-buffer-create buf-name)) + (when (= (point-min) (point-max)) + (set (make-local-variable 'hg-root) root) + (set (make-local-variable 'mq-top) patch) + (setq mq-prev-buffer prev-buffer) + (insert (hg-run0 "qheader")) + (goto-char (point-min))) + (mq-edit-mode) + (cd root))) + (message "Type `C-c C-c' to finish editing and refresh the patch.")) (provide 'mq)