Merge branch 'stable'
[stgit] / contrib / stgit.el
index e8bbb2c..5aaf311 100644 (file)
 (defun stgit (dir)
   "Manage stgit patches"
   (interactive "DDirectory: \n")
-  (switch-to-stgit-buffer dir)
+  (switch-to-stgit-buffer (git-get-top-dir dir))
   (stgit-refresh))
 
+(defun git-get-top-dir (dir)
+  "Retrieve the top-level directory of a git tree."
+  (let ((cdup (with-output-to-string
+                (with-current-buffer standard-output
+                  (cd dir)
+                  (unless (eq 0 (call-process "git" nil t nil
+                                              "rev-parse" "--show-cdup"))
+                    (error "cannot find top-level git tree for %s." dir))))))
+    (expand-file-name (concat (file-name-as-directory dir)
+                              (car (split-string cdup "\n"))))))
+
 (defun switch-to-stgit-buffer (dir)
   "Switch to a (possibly new) buffer displaying StGit patches for DIR"
   (setq dir (file-name-as-directory dir))
@@ -107,7 +118,7 @@ Argument DIR is the repository path."
         (cond ((looking-at "Branch: \\(.*\\)")
                (put-text-property (match-beginning 1) (match-end 1)
                                   'face 'bold))
-              ((looking-at "\\([>+-]\\)\\( \\)\\([^ ]+\\) *| \\(.*\\)")
+              ((looking-at "\\([>+-]\\)\\( \\)\\([^ ]+\\) *[|#] \\(.*\\)")
                (let ((state (match-string 1))
                      (patchsym (intern (match-string 3))))
                  (put-text-property
@@ -143,14 +154,15 @@ Argument DIR is the repository path."
   (define-key stgit-mode-map "e"   'stgit-edit)
   (define-key stgit-mode-map "c"   'stgit-coalesce)
   (define-key stgit-mode-map "N"   'stgit-new)
-  (define-key stgit-mode-map "\C-r"   'stgit-repair)
+  (define-key stgit-mode-map "R"   'stgit-repair)
   (define-key stgit-mode-map "C"   'stgit-commit)
   (define-key stgit-mode-map "U"   'stgit-uncommit)
   (define-key stgit-mode-map ">"   'stgit-push-next)
   (define-key stgit-mode-map "<"   'stgit-pop-next)
   (define-key stgit-mode-map "P"   'stgit-push-or-pop)
   (define-key stgit-mode-map "G"   'stgit-goto)
-  (define-key stgit-mode-map "="   'stgit-show))
+  (define-key stgit-mode-map "="   'stgit-show)
+  (define-key stgit-mode-map "D"   'stgit-delete))
 
 (defun stgit-mode ()
   "Major mode for interacting with StGit.
@@ -187,6 +199,15 @@ Commands:
         (match-string-no-properties 1)
       nil)))
 
+(defun stgit-patches-marked-or-at-point ()
+  "Return the names of the marked patches, or the patch on the current line."
+  (if stgit-marked-patches
+      (stgit-marked-patches)
+    (let ((patch (stgit-patch-at-point)))
+      (if patch
+          (list patch)
+        '()))))
+
 (defun stgit-goto-patch (patch)
   "Move point to the line containing PATCH"
   (let ((p (point)))
@@ -290,9 +311,7 @@ Commands:
 (defun stgit-edit ()
   "Edit the patch on the current line"
   (interactive)
-  (let ((patch (if (stgit-applied-at-point)
-                   (stgit-patch-at-point)
-                 (error "This patch is not applied")))
+  (let ((patch (stgit-patch-at-point))
         (edit-buf (get-buffer-create "*StGit edit*"))
         (dir default-directory))
     (log-edit 'stgit-confirm-edit t nil edit-buf)
@@ -318,16 +337,10 @@ Commands:
 
 (defun stgit-confirm-new ()
   (interactive)
-  (let ((file (make-temp-file "stgit-edit-"))
-        (patch (stgit-create-patch-name
-                (buffer-substring (point-min)
-                                  (save-excursion (goto-char (point-min))
-                                                  (end-of-line)
-                                                  (point))))))
+  (let ((file (make-temp-file "stgit-edit-")))
     (write-region (point-min) (point-max) file)
     (stgit-capture-output nil
-      (stgit-run "new" "-m" "placeholder" patch)
-      (stgit-run "edit" "-f" file patch))
+      (stgit-run "new" "-f" file))
     (with-current-buffer log-edit-parent-buffer
       (stgit-refresh))))
 
@@ -349,6 +362,17 @@ Commands:
            (substring patch 0 20))
           (t patch))))
 
+(defun stgit-delete (patch-names)
+  "Delete the named patches"
+  (interactive (list (stgit-patches-marked-or-at-point)))
+  (if (zerop (length patch-names))
+      (error "No patches to delete")
+    (when (yes-or-no-p (format "Really delete %d patches? "
+                               (length patch-names)))
+      (stgit-capture-output nil
+        (apply 'stgit-run "delete" patch-names))
+      (stgit-refresh))))
+
 (defun stgit-coalesce (patch-names)
   "Run stg coalesce on the named patches"
   (interactive (list (stgit-marked-patches)))