contrib/mq.el
changeset 2995 e2bad806ccc3
parent 2993 425413d9ef59
child 2996 06696f9c30c0
equal deleted inserted replaced
2994:c203ccd7d838 2995:e2bad806ccc3
    29 (defcustom mq-global-prefix "\C-cq"
    29 (defcustom mq-global-prefix "\C-cq"
    30   "The global prefix for Mercurial Queues keymap bindings."
    30   "The global prefix for Mercurial Queues keymap bindings."
    31   :type 'sexp
    31   :type 'sexp
    32   :group 'mercurial)
    32   :group 'mercurial)
    33 
    33 
       
    34 (defcustom mq-edit-mode-hook nil
       
    35   "Hook run after a buffer is populated to edit a patch description."
       
    36   :type 'sexp
       
    37   :group 'mercurial)
       
    38 
    34 
    39 
    35 ;;; Internal variables.
    40 ;;; Internal variables.
    36 
    41 
    37 (defvar mq-patch-history nil)
    42 (defvar mq-patch-history nil)
       
    43 
       
    44 (defvar mq-prev-buffer nil)
       
    45 (make-variable-buffer-local 'mq-prev-buffer)
       
    46 (put 'mq-prev-buffer 'permanent-local t)
    38 
    47 
    39 
    48 
    40 ;;; Global keymap.
    49 ;;; Global keymap.
    41 
    50 
    42 (defvar mq-global-map (make-sparse-keymap))
    51 (defvar mq-global-map (make-sparse-keymap))
    49 (define-key mq-global-map "r" 'mq-refresh)
    58 (define-key mq-global-map "r" 'mq-refresh)
    50 (define-key mq-global-map "e" 'mq-refresh-edit)
    59 (define-key mq-global-map "e" 'mq-refresh-edit)
    51 (define-key mq-global-map "n" 'mq-next)
    60 (define-key mq-global-map "n" 'mq-next)
    52 (define-key mq-global-map "p" 'mq-previous)
    61 (define-key mq-global-map "p" 'mq-previous)
    53 (define-key mq-global-map "t" 'mq-top)
    62 (define-key mq-global-map "t" 'mq-top)
       
    63 
       
    64 
       
    65 ;;; Refresh edit mode keymap.
       
    66 
       
    67 (defvar mq-edit-mode-map (make-sparse-keymap))
       
    68 (define-key mq-edit-mode-map "\C-c\C-c" 'mq-edit-finish)
       
    69 (define-key mq-edit-mode-map "\C-c\C-k" 'mq-edit-kill)
    54 
    70 
    55 
    71 
    56 ;;; Helper functions.
    72 ;;; Helper functions.
    57 
    73 
    58 (defun mq-read-patch-name (&optional source prompt)
    74 (defun mq-read-patch-name (&optional source prompt)
   155 (defun mq-pop-all ()
   171 (defun mq-pop-all ()
   156   "Push patches until none are applied."
   172   "Push patches until none are applied."
   157   (interactive)
   173   (interactive)
   158   (mq-pop "-a"))
   174   (mq-pop "-a"))
   159 
   175 
       
   176 (defun mq-refresh-internal (root &rest args)
       
   177   (hg-sync-buffers root)
       
   178   (let ((patch (mq-patch-info "qtop")))
       
   179     (message "Refreshing %s..." patch)
       
   180     (let ((ret (apply 'hg-run "qrefresh" args)))
       
   181       (if (equal (car ret) 0)
       
   182 	  (message "Refreshing %s... done." patch)
       
   183 	(error "Refreshing %s... %s" patch (hg-chomp (cdr ret)))))))
       
   184 
   160 (defun mq-refresh ()
   185 (defun mq-refresh ()
   161   "Refresh the topmost applied patch."
   186   "Refresh the topmost applied patch."
   162   (interactive)
   187   (interactive)
   163   (let ((root (hg-root)))
   188   (let ((root (hg-root)))
   164     (unless root
   189     (unless root
   165       (error "Cannot refresh outside a repository!"))
   190       (error "Cannot refresh outside of a repository!"))
   166     (hg-sync-buffers root)
   191   (mq-refresh-internal root)))
   167     (message "Refreshing patch...")
   192 
   168     (let ((ret (hg-run "qrefresh")))
   193 (defun mq-patch-info (cmd &optional msg)
   169       (if (equal (car ret) 0)
   194   (let* ((ret (hg-run cmd))
   170 	  (message "Refreshing patch... done.")
   195 	 (info (hg-chomp (cdr ret))))
   171 	(error "Refreshing patch... %s" (hg-chomp (cdr ret)))))))
       
   172 
       
   173 (defun mq-patch-info (msg cmd)
       
   174   (let ((ret (hg-run cmd)))
       
   175     (if (equal (car ret) 0)
   196     (if (equal (car ret) 0)
   176 	(message "%s %s" msg (hg-chomp (cdr ret)))
   197 	(if msg
   177       (error "%s" (cdr ret)))))
   198 	    (message "%s patch: %s" msg info)
       
   199 	  info)
       
   200       (error "%s" info))))
   178 
   201 
   179 (defun mq-top ()
   202 (defun mq-top ()
   180   "Print the name of the topmost applied patch."
   203   "Print the name of the topmost applied patch."
   181   (interactive)
   204   (interactive)
   182   (mq-patch-info "Top patch is " "qtop"))
   205   (mq-patch-info "qtop" "Top"))
   183 
   206 
   184 (defun mq-next ()
   207 (defun mq-next ()
   185   "Print the name of the next patch to be pushed."
   208   "Print the name of the next patch to be pushed."
   186   (interactive)
   209   (interactive)
   187   (mq-patch-info "Next patch is " "qnext"))
   210   (mq-patch-info "qnext" "Next"))
   188 
   211 
   189 (defun mq-previous ()
   212 (defun mq-previous ()
   190   "Print the name of the first patch below the topmost applied patch.
   213   "Print the name of the first patch below the topmost applied patch.
   191 This would become the active patch if popped to."
   214 This would become the active patch if popped to."
   192   (interactive)
   215   (interactive)
   193   (mq-patch-info "Previous patch is " "qprev"))
   216   (mq-patch-info "qprev" "Previous"))
   194 
   217 
       
   218 (defun mq-edit-finish ()
       
   219   (interactive)
       
   220   (unless (equal (mq-patch-info "qtop") mq-top)
       
   221     (error "Topmost patch has changed!"))
       
   222   (hg-sync-buffers hg-root)
       
   223   (mq-refresh-internal hg-root "-m" (buffer-substring (point-min) (point-max)))
       
   224   (let ((buf mq-prev-buffer))
       
   225     (kill-buffer nil)
       
   226     (switch-to-buffer buf)))
       
   227   
       
   228 (defun mq-edit-kill ()
       
   229   "Kill the edit currently being prepared."
       
   230   (interactive)
       
   231   (when (or (not (buffer-modified-p)) (y-or-n-p "Really kill this edit? "))
       
   232     (let ((buf mq-prev-buffer))
       
   233       (kill-buffer nil)
       
   234       (switch-to-buffer buf))))
       
   235 
       
   236 (defun mq-edit-mode ()
       
   237   "Mode for editing the description of a patch.
       
   238 
       
   239 Key bindings
       
   240 ------------
       
   241 \\[mq-edit-finish]	use this description
       
   242 \\[mq-edit-kill]	abandon this description"
       
   243   (interactive)
       
   244   (use-local-map mq-edit-mode-map)
       
   245   (set-syntax-table text-mode-syntax-table)
       
   246   (setq local-abbrev-table text-mode-abbrev-table
       
   247 	major-mode 'mq-edit-mode
       
   248 	mode-name "MQ-Edit")
       
   249   (set-buffer-modified-p nil)
       
   250   (setq buffer-undo-list nil)
       
   251   (run-hooks 'text-mode-hook 'mq-edit-mode-hook))
       
   252   
   195 (defun mq-refresh-edit ()
   253 (defun mq-refresh-edit ()
   196   "Refresh the topmost applied patch, editing the patch description."
   254   "Refresh the topmost applied patch, editing the patch description."
   197   (interactive)
   255   (interactive)
   198   (error "Not yet implemented"))
   256   (while mq-prev-buffer
       
   257     (set-buffer mq-prev-buffer))
       
   258   (let ((root (hg-root))
       
   259 	(prev-buffer (current-buffer))
       
   260 	(patch (mq-patch-info "qtop")))
       
   261     (hg-sync-buffers root)
       
   262     (let ((buf-name (format "*MQ: Edit description of %s*" patch)))
       
   263       (switch-to-buffer (get-buffer-create buf-name))
       
   264       (when (= (point-min) (point-max))
       
   265 	(set (make-local-variable 'hg-root) root)
       
   266 	(set (make-local-variable 'mq-top) patch)
       
   267 	(setq mq-prev-buffer prev-buffer)
       
   268 	(insert (hg-run0 "qheader"))
       
   269 	(goto-char (point-min)))
       
   270       (mq-edit-mode)
       
   271       (cd root)))
       
   272   (message "Type `C-c C-c' to finish editing and refresh the patch."))
   199 
   273 
   200 
   274 
   201 (provide 'mq)
   275 (provide 'mq)
   202 
   276 
   203 
   277