X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/fd64ee5713a2e6618c7f47742b24aa618db53d6f..00be16b0cde8e6c6cf23f0c3e530f85a4d4fbd90:/contrib/stgit.el diff --git a/contrib/stgit.el b/contrib/stgit.el index b7c4b7f..7ab17a9 100644 --- a/contrib/stgit.el +++ b/contrib/stgit.el @@ -904,8 +904,9 @@ file for (applied) copies and renames." :active (stgit-patch-name-at-point nil t)] ["Rename patch" stgit-rename :active (stgit-patch-name-at-point nil t)] ["Push/pop patch" stgit-push-or-pop - :label (if (stgit-applied-at-point-p) "Pop patch" "Push patch") - :active (stgit-patch-name-at-point nil t)] + :label (if (subsetp (stgit-patches-marked-or-at-point nil t) + (stgit-applied-patchsyms t)) + "Pop patches" "Push patches")] ["Delete patches" stgit-delete :active (stgit-patches-marked-or-at-point nil t)] "-" @@ -1014,8 +1015,9 @@ Commands for patches: \\[stgit-expand] Show changes in marked patches \\[stgit-collapse] Hide changes in marked patches -\\[stgit-new] Create a new, empty patch \\[stgit-new-and-refresh] Create a new patch from index or work tree +\\[stgit-new] Create a new, empty patch + \\[stgit-rename] Rename patch \\[stgit-edit] Edit patch description \\[stgit-delete] Delete patch(es) @@ -1025,11 +1027,11 @@ Commands for patches: \\[stgit-push-next] Push next patch onto stack \\[stgit-pop-next] Pop current patch from stack -\\[stgit-push-or-pop] Push or pop patch at point -\\[stgit-goto] Make current patch current by popping or pushing +\\[stgit-push-or-pop] Push or pop marked patches +\\[stgit-goto] Make patch at point current by popping or pushing \\[stgit-squash] Squash (meld together) patches -\\[stgit-move-patches] Move patch(es) to point +\\[stgit-move-patches] Move marked patches to point \\[stgit-commit] Commit patch(es) \\[stgit-uncommit] Uncommit patch(es) @@ -1463,20 +1465,38 @@ With numeric prefix argument, pop that many patches." (stgit-reload) (stgit-refresh-git-status)) -(defun stgit-applied-at-point-p () - "Return non-nil if the patch at point is applied." - (let ((patch (stgit-patch-at-point t))) - (not (eq (stgit-patch-status patch) 'unapplied)))) +(defun stgit-applied-patches (&optional only-patches) + "Return a list of the applied patches. + +If ONLY-PATCHES is not nil, exclude index and work tree." + (let ((states (if only-patches + '(applied top) + '(applied top index work))) + result) + (ewoc-map (lambda (patch) (when (memq (stgit-patch-status patch) states) + (setq result (cons patch result)))) + stgit-ewoc) + result)) + +(defun stgit-applied-patchsyms (&optional only-patches) + "Return a list of the symbols of the applied patches. + +If ONLY-PATCHES is not nil, exclude index and work tree." + (mapcar #'stgit-patch-name (stgit-applied-patches only-patches))) (defun stgit-push-or-pop () - "Push or pop the patch on the current line." + "Push or pop the marked patches." (interactive) (stgit-assert-mode) - (let ((patchsym (stgit-patch-name-at-point t t)) - (applied (stgit-applied-at-point-p))) + (let* ((patchsyms (stgit-patches-marked-or-at-point t t)) + (applied-syms (stgit-applied-patchsyms t)) + (unapplied (set-difference patchsyms applied-syms))) (stgit-capture-output nil - (stgit-run (if applied "pop" "push") patchsym)) - (stgit-reload))) + (apply 'stgit-run + (if unapplied "push" "pop") + "--" + (stgit-sort-patches (if unapplied unapplied patchsyms))))) + (stgit-reload)) (defun stgit-goto () "Go to the patch on the current line." @@ -1784,13 +1804,21 @@ the work tree and index." "Return the patchsym indicating a target patch for `stgit-move-patches'. -This is either the patch at point, or one of :top and :bottom, if -the point is after or before the applied patches." - - (let ((patchsym (stgit-patch-name-at-point nil t))) - (cond (patchsym patchsym) - ((save-excursion (re-search-backward "^>" nil t)) :top) - (t :bottom)))) +This is either the first unmarked patch at or after point, or one +of :top and :bottom if the point is after or before the applied +patches." + + (save-excursion + (let (result) + (while (not result) + (let ((patchsym (stgit-patch-name-at-point))) + (cond ((memq patchsym '(:work :index)) (setq result :top)) + (patchsym (if (memq patchsym stgit-marked-patches) + (stgit-next-patch) + (setq result patchsym))) + ((re-search-backward "^>" nil t) (setq result :top)) + (t (setq result :bottom))))) + result))) (defun stgit-sort-patches (patchsyms) "Returns the list of patches in PATCHSYMS sorted according to @@ -1829,20 +1857,17 @@ Interactively, move the marked patches to where the point is." (unless target-patch (error "Point not at a patch")) - (if (eq target-patch :top) - (stgit-capture-output nil - (apply 'stgit-run "float" patchsyms)) - - ;; need to have patchsyms sorted by position in the stack - (let ((sorted-patchsyms (stgit-sort-patches patchsyms))) - (while sorted-patchsyms - (setq sorted-patchsyms - (and (stgit-capture-output nil - (if (eq target-patch :bottom) - (stgit-run "sink" "--" (car sorted-patchsyms)) - (stgit-run "sink" "--to" target-patch "--" - (car sorted-patchsyms)))) - (cdr sorted-patchsyms)))))) + ;; need to have patchsyms sorted by position in the stack + (let ((sorted-patchsyms (stgit-sort-patches patchsyms))) + (stgit-capture-output nil + (if (eq target-patch :top) + (apply 'stgit-run "float" sorted-patchsyms) + (apply 'stgit-run + "sink" + (append (unless (eq target-patch :bottom) + (list "--to" target-patch)) + '("--") + sorted-patchsyms))))) (stgit-reload)) (defun stgit-squash (patchsyms)