comparison contrib/mq.el @ 2995:e2bad806ccc3

mq.el: add ability to edit a patch.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue, 22 Aug 2006 16:59:22 -0700
parents 425413d9ef59
children 06696f9c30c0
comparison
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