Skip to content

stgit.el improvements #2 #552

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 12, 2025
138 changes: 76 additions & 62 deletions contrib/stgit.el
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;;; stgit.el --- major mode for StGit interaction
;;; stgit.el --- major mode for StGit interaction -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2007-2013 David Kågedal
;;
Expand Down Expand Up @@ -58,6 +58,32 @@
(require 'ewoc)
(require 'easymenu)
(require 'format-spec)
(require 'vc)

(defvar log-edit-parent-buffer)

(defvar-local stgit-marked-patches nil
"List of marked patches.")

(defvar-local stgit-index-node nil)
(defvar-local stgit-worktree-node nil)
(defvar-local stgit-expanded-patches '(:work :index))
(defvar-local stgit-svn-find-rev-hash nil)
(defvar-local stgit-committed-count)
(defvar-local stgit-show-committed)
(defvar-local stgit-show-ignored)
(defvar-local stgit-show-patch-names)
(defvar-local stgit-show-svn)
(defvar-local stgit-show-unknown)
(defvar-local stgit-show-worktree)
(defvar-local stgit-ewoc)
(defvar-local stgit-edit-patchsym)
(defvar-local stgit-refresh-after-new)
(defvar-local stgit-refresh-after-new)
(defvar-local stgit-sink-to)
(defvar-local stgit-patchsyms)
(defvar-local old-process-sentinel)
(defvar-local stgit-buffer)

(defun stgit-set-default (symbol value)
"Set default value of SYMBOL to VALUE using `set-default' and
Expand Down Expand Up @@ -308,6 +334,15 @@ format characters are recognized:
"StGit mode face used for modified file status."
:group 'stgit-faces)

(defconst stgit-patch-status-face-alist
'((applied . stgit-applied-patch-face)
(top . stgit-top-patch-face)
(unapplied . stgit-unapplied-patch-face)
(committed . stgit-committed-patch-face)
(index . stgit-index-work-tree-title-face)
(work . stgit-index-work-tree-title-face))
"Alist of face to use for a given patch status.")

(defun stgit (dir)
"Manage StGit patches for the tree in DIR.

Expand Down Expand Up @@ -425,8 +460,8 @@ Argument DIR is the repository path."
(with-current-buffer buf
(setq default-directory dir)
(stgit-mode)
(set (make-local-variable 'stgit-ewoc)
(ewoc-create #'stgit-patch-pp "Branch:\n\n" "--\n" t))
(setq stgit-ewoc
(ewoc-create #'stgit-patch-pp "Branch:\n\n" "--\n" t))
(setq buffer-read-only t))
buf))

Expand Down Expand Up @@ -543,20 +578,18 @@ been advised to update the stgit status when necessary.")
(ewoc-invalidate (car stgit-worktree-node) (cdr stgit-worktree-node))))

(defun stgit-run-series-insert-index (ewoc)
;; TODO: non-lexical stuff happening here (`index-node' and `worktree-node').
;; Fix this before enabling lexical binding.
(setq index-node (cons ewoc (ewoc-enter-last ewoc
(make-stgit-patch
:status 'index
:name :index
:desc nil
:empty nil)))
worktree-node (cons ewoc (ewoc-enter-last ewoc
(make-stgit-patch
:status 'work
:name :work
:desc nil
:empty nil)))))
(setq stgit-index-node (cons ewoc (ewoc-enter-last ewoc
(make-stgit-patch
:status 'index
:name :index
:desc nil
:empty nil)))
stgit-worktree-node (cons ewoc (ewoc-enter-last ewoc
(make-stgit-patch
:status 'work
:name :work
:desc nil
:empty nil)))))

(defun stgit-get-position (&optional position)
"Return `stgit-mode' position information at POSITION (point by
Expand Down Expand Up @@ -672,6 +705,7 @@ using (make-hash-table :test \='equal)."
(commit-abbrev (when (string-match "%-\\([0-9]+\\)n" fmt)
(string-to-number (match-string 1 fmt))))
(exit-status (stgit-run-git-silent "--no-pager" "log"
"--no-color"
"--reverse"
"--pretty=oneline"
nentries
Expand Down Expand Up @@ -707,9 +741,7 @@ using (make-hash-table :test \='equal)."
:desc desc
:empty empty)))
(forward-line 1)))))))
(let ((inserted-index (not stgit-show-worktree))
index-node
worktree-node)
(let ((inserted-index (not stgit-show-worktree)))
(with-temp-buffer
(let* ((standard-output (current-buffer))
(exit-status (stgit-run-silent "series"
Expand All @@ -726,7 +758,7 @@ using (make-hash-table :test \='equal)."
(match-string 0))))
(while (not (eobp))
(unless (looking-at
"\\([*0 ]\\)\\([>+-]\\)\\( \\)\\([^ ]+\\) *[|#] \\(.*\\)")
"\\([*0 ]\\)\\([>+-]\\)\\( \\)\\([^ ]+\\) *[|#] ?\\(.*\\)")
(error "Syntax error in output from stg series"))
(let* ((state-str (match-string 2))
(state (cond ((string= state-str ">") 'top)
Expand All @@ -751,9 +783,7 @@ using (make-hash-table :test \='equal)."
(forward-line 1)))))
(unless inserted-index
(stgit-run-series-insert-index ewoc))
(setq stgit-index-node index-node
stgit-worktree-node worktree-node
stgit-marked-patches (cl-intersection stgit-marked-patches
(setq stgit-marked-patches (cl-intersection stgit-marked-patches
all-patchsyms)))))

(defun stgit-current-branch ()
Expand Down Expand Up @@ -802,15 +832,6 @@ during the operation."
(ignore "Ignored" stgit-ignored-file-face)))
"Alist of code symbols to description strings.")

(defconst stgit-patch-status-face-alist
'((applied . stgit-applied-patch-face)
(top . stgit-top-patch-face)
(unapplied . stgit-unapplied-patch-face)
(committed . stgit-committed-patch-face)
(index . stgit-index-work-tree-title-face)
(work . stgit-index-work-tree-title-face))
"Alist of face to use for a given patch status.")

(defun stgit-file-status-code-as-string (file)
"Return stgit status code for FILE as a string."
(let* ((code (assq (stgit-file->status file)
Expand Down Expand Up @@ -1007,7 +1028,7 @@ If NO-QUOTES is non-nil, do not enclose the result in double quotes."
(insert ":0 0 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 " file-flag "\0")
(forward-char name-len)))))

(defun stgit-process-files (callback)
(defun stgit-process-files (patch callback)
(goto-char (point-min))
(when (looking-at "[0-9A-Fa-f]\\{40\\}\0")
(goto-char (match-end 0)))
Expand All @@ -1018,7 +1039,6 @@ If NO-QUOTES is non-nil, do not enclose the result in double quotes."
(let ((file
(cond ((looking-at
"\\([CR]\\)\\([0-9]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0")
;; TODO: Where does `patch' come from?
(let* ((patch-status (stgit-patch->status patch))
(file-subexp (if (eq patch-status 'unapplied)
3
Expand Down Expand Up @@ -1082,7 +1102,7 @@ at point."
(sort-regexp-fields nil ":[^\0]*\0\\([^\0]*\\)\0" "\\1"
(point-min) (point-max)))

(stgit-process-files (lambda (file) (ewoc-enter-last ewoc file)))
(stgit-process-files patch (lambda (file) (ewoc-enter-last ewoc file)))

(unless (ewoc-nth ewoc 0)
(ewoc-set-hf ewoc ""
Expand Down Expand Up @@ -1110,7 +1130,7 @@ at point."
'switch-to-buffer-other-window
'switch-to-buffer)
(find-file-noselect filename))
(set (make-local-variable 'vc-parent-buffer) filename)))
(setq vc-parent-buffer filename)))

(defun stgit-find-file (&optional other-window this-rev)
(let* ((file (or (stgit-patched-file-at-point)
Expand Down Expand Up @@ -1192,7 +1212,8 @@ See also `stgit-expand'."
"--no-empty-directory" "--"
filename)
"X")
(stgit-process-files (lambda (f)
(stgit-process-files patch
(lambda (f)
(setq node (ewoc-enter-after ewoc node f))))))

(move-to-column (stgit-goal-column))
Expand Down Expand Up @@ -1683,21 +1704,16 @@ See also \\[customize-group] for the \"stgit\" group."
major-mode 'stgit-mode
goal-column 2)
(use-local-map stgit-mode-map)
(mapc (lambda (x) (set (make-local-variable (car x)) (cdr x)))
`((list-buffers-directory . ,default-directory)
(parse-sexp-lookup-properties . t)
(stgit-expanded-patches . (:work :index))
(stgit-index-node . nil)
(stgit-worktree-node . nil)
(stgit-marked-patches . nil)
(stgit-svn-find-rev-hash . ,(make-hash-table :test 'equal))
(stgit-committed-count . ,stgit-default-committed-count)
(stgit-show-committed . ,stgit-default-show-committed)
(stgit-show-ignored . ,stgit-default-show-ignored)
(stgit-show-patch-names . ,stgit-default-show-patch-names)
(stgit-show-svn . ,stgit-default-show-svn)
(stgit-show-unknown . ,stgit-default-show-unknown)
(stgit-show-worktree . ,stgit-default-show-worktree)))
(setq list-buffers-directory default-directory)
(setq-local parse-sexp-lookup-properties t)
(setq stgit-svn-find-rev-hash (make-hash-table :test 'equal))
(setq stgit-committed-count stgit-default-committed-count)
(setq stgit-show-committed stgit-default-show-committed)
(setq stgit-show-ignored stgit-default-show-ignored)
(setq stgit-show-patch-names stgit-default-show-patch-names)
(setq stgit-show-svn stgit-default-show-svn)
(setq stgit-show-unknown stgit-default-show-unknown)
(setq stgit-show-worktree stgit-default-show-worktree)
(set-variable 'truncate-lines 't)
(add-hook 'after-save-hook 'stgit-update-stgit-for-buffer)
(unless stgit-did-advise
Expand Down Expand Up @@ -2427,7 +2443,7 @@ which stage to diff against in the case of unmerged files."
(if (eq patch-id :index)
'("--cached")
(list unmerged-stage))))
(let ((args (append '("show" "-O" "--patch-with-stat")
(let ((args (append '("show" "--color=never" "-O" "--patch-with-stat")
`("-O" ,(stgit-find-copies-harder-diff-arg))
(and space-arg (list "-O" space-arg))
(list (stgit-patch-name-at-point)))))
Expand Down Expand Up @@ -2604,7 +2620,7 @@ file ended up. You can then jump to the file with \
(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-patchsym) patchsym)
(setq stgit-edit-patchsym patchsym)
(setq default-directory dir)
(let ((standard-output edit-buf))
(save-excursion
Expand Down Expand Up @@ -2660,8 +2676,8 @@ that name (a symbol)."
(dir default-directory))
(log-edit 'stgit-confirm-new t nil edit-buf)
(setq default-directory dir)
(set (make-local-variable 'stgit-refresh-after-new) refresh)
(set (make-local-variable 'stgit-sink-to) sink-to)
(setq stgit-refresh-after-new refresh)
(setq stgit-sink-to sink-to)
(when add-sign
(save-excursion
(let ((standard-output (current-buffer)))
Expand Down Expand Up @@ -2835,7 +2851,7 @@ deepest patch had before the squash."
(dir default-directory)
(sorted-patchsyms (stgit-sort-patches patchsyms)))
(log-edit 'stgit-confirm-squash t nil edit-buf)
(set (make-local-variable 'stgit-patchsyms) sorted-patchsyms)
(setq stgit-patchsyms sorted-patchsyms)
(setq default-directory dir)
(let ((result (let ((standard-output edit-buf))
(save-excursion
Expand Down Expand Up @@ -2939,10 +2955,8 @@ When the command has finished, reload the stgit buffer."
(let ((old-buffer (current-buffer)))
(with-current-buffer buffer
(let ((process (get-buffer-process buffer)))
(set (make-local-variable 'old-process-sentinel)
(process-sentinel process))
(set (make-local-variable 'stgit-buffer)
old-buffer)
(setq old-process-sentinel (process-sentinel process))
(setq stgit-buffer old-buffer)
(set-process-filter process 'stgit-execute-process-filter)
(set-process-sentinel process 'stgit-execute-process-sentinel))))
(with-current-buffer buffer
Expand Down
Loading