X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/34afb86c94c81a0a7fdcd8cc432238659da41532..29197bc02c1b5087017da9a86214e9b620f0439e:/contrib/stgit.el diff --git a/contrib/stgit.el b/contrib/stgit.el index 82f0d38..1cb4dd2 100644 --- a/contrib/stgit.el +++ b/contrib/stgit.el @@ -70,10 +70,52 @@ Argument DIR is the repository path." (insert "Branch: ") (stgit-run "branch") (stgit-run "series" "--description") + (stgit-rehighlight (point-min) (point-max)) (if curpatch (stgit-goto-patch curpatch) (goto-line curline)))) +(defface stgit-description-face + '((((background dark)) (:foreground "tan")) + (((background light)) (:foreground "dark red"))) + "The face used for StGit desriptions") + +(defface stgit-top-patch-face + '((((background dark)) (:weight bold :foreground "yellow")) + (((background light)) (:weight bold :foreground "purple")) + (t (:weight bold))) + "The face used for the top patch names") + +(defface stgit-applied-patch-face + '((((background dark)) (:foreground "light yellow")) + (((background light)) (:foreground "purple")) + (t ())) + "The face used for applied patch names") + +(defface stgit-unapplied-patch-face + '((((background dark)) (:foreground "gray80")) + (((background light)) (:foreground "orchid")) + (t ())) + "The face used for unapplied patch names") + +(defun stgit-rehighlight (start end) + "Refresh fontification of region between START and END." + (save-excursion + (goto-char start) + (while (< (point) end) + (cond ((looking-at "Branch: \\(.*\\)") + (put-text-property (match-beginning 1) (match-end 1) 'face 'bold)) + ((looking-at "\\([>+-]\\) \\([^ ]+\\) *| \\(.*\\)") + (let ((state (match-string 1))) + (put-text-property + (match-beginning 2) (match-end 2) + 'face (cond ((string= state ">") 'stgit-top-patch-face) + ((string= state "+") 'stgit-applied-patch-face) + ((string= state "-") 'stgit-unapplied-patch-face))) + (put-text-property (match-beginning 3) (match-end 3) + 'face 'stgit-description-face)))) + (forward-line 1)))) + (defvar stgit-mode-hook nil "Run after `stgit-mode' is setup.") @@ -85,8 +127,15 @@ Argument DIR is the repository path." (suppress-keymap stgit-mode-map) (define-key stgit-mode-map "?" 'stgit-help) (define-key stgit-mode-map "h" 'stgit-help) + (define-key stgit-mode-map "p" 'previous-line) + (define-key stgit-mode-map "n" 'next-line) (define-key stgit-mode-map "g" 'stgit-refresh) (define-key stgit-mode-map "r" 'stgit-rename) + (define-key stgit-mode-map "e" 'stgit-edit) + (define-key stgit-mode-map "N" 'stgit-new) + (define-key stgit-mode-map "\C-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) @@ -112,7 +161,7 @@ Commands: (save-excursion (beginning-of-line) (if (looking-at "[>+-] \\([^ ]*\\)") - (match-string 1) + (match-string-no-properties 1) nil))) (defun stgit-goto-patch (patch) @@ -136,6 +185,25 @@ Commands: (stgit-refresh) (stgit-goto-patch name))) +(defun stgit-repair () + "Run stg repair" + (interactive) + (stgit-capture-output nil + (stgit-run "repair")) + (stgit-refresh)) + +(defun stgit-commit () + "Run stg commit." + (interactive) + (stgit-capture-output nil (stgit-run "commit")) + (stgit-refresh)) + +(defun stgit-uncommit (arg) + "Run stg uncommit. Numeric arg determines number of patches to uncommit." + (interactive "p") + (stgit-capture-output nil (stgit-run "uncommit" "-n" (number-to-string arg))) + (stgit-refresh)) + (defun stgit-push-next () "Push the first unapplied patch" (interactive) @@ -180,6 +248,68 @@ Commands: (goto-char (point-min)) (diff-mode)))) +(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"))) + (edit-buf (get-buffer-create "*stgit edit*")) + (dir default-directory)) + (log-edit 'stgit-confirm-edit t nil edit-buf) + (set (make-local-variable 'stgit-edit-patch) patch) + (setq default-directory dir) + (let ((standard-output edit-buf)) + (stgit-run "edit" "--save-template=-" patch)))) + +(defun stgit-confirm-edit () + (interactive) + (let ((file (make-temp-file "stgit-edit-"))) + (write-region (point-min) (point-max) file) + (stgit-capture-output nil + (stgit-run "edit" "-f" file stgit-edit-patch)) + (with-current-buffer log-edit-parent-buffer + (stgit-refresh)))) + +(defun stgit-new () + "Create a new patch" + (interactive) + (let ((edit-buf (get-buffer-create "*stgit edit*"))) + (log-edit 'stgit-confirm-new t nil edit-buf))) + +(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)))))) + (write-region (point-min) (point-max) file) + (stgit-capture-output nil + (stgit-run "new" "-m" "placeholder" patch) + (stgit-run "edit" "-f" file patch)) + (with-current-buffer log-edit-parent-buffer + (stgit-refresh)))) + +(defun stgit-create-patch-name (description) + "Create a patch name from a long description" + (let ((patch "")) + (while (> (length description) 0) + (cond ((string-match "\\`[a-zA-Z_-]+" description) + (setq patch (downcase (concat patch (match-string 0 description)))) + (setq description (substring description (match-end 0)))) + ((string-match "\\` +" description) + (setq patch (concat patch "-")) + (setq description (substring description (match-end 0)))) + ((string-match "\\`[^a-zA-Z_-]+" description) + (setq description (substring description (match-end 0)))))) + (cond ((= (length patch) 0) + "patch") + ((> (length patch) 20) + (substring patch 0 20)) + (t patch)))) + (defun stgit-help () "Display help for the StGit mode." (interactive)