Skip to content

Commit

Permalink
legit: list stashes in status, stash push, stash pop
Browse files Browse the repository at this point in the history
  • Loading branch information
vindarel committed Nov 20, 2024
1 parent a2c1f6f commit 0b61dbb
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 2 deletions.
1 change: 1 addition & 0 deletions extensions/legit/legit-common.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
(:export :legit-status
:*prompt-for-commit-abort-p*
:*ignore-all-space*
:*show-stashes*
:*vcs-existence-order*
:*peek-legit-keymap*
:peek-legit-discard-file
Expand Down
38 changes: 36 additions & 2 deletions extensions/legit/legit.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ Ongoing:
Currently Git-only. Concretely, this calls Git with the -w option.")

(defvar *show-stashes* t "List stashes on the Legit status buffer.")


;; Supercharge patch-mode with our keys.
(define-major-mode legit-diff-mode lem-patch-mode:patch-mode
(:name "legit-diff"
Expand Down Expand Up @@ -103,6 +106,10 @@ Currently Git-only. Concretely, this calls Git with the -w option.")
(define-key *peek-legit-keymap* "r c" 'rebase-continue)
(define-key *peek-legit-keymap* "r s" 'rebase-skip)

;; Stashes
(define-key *peek-legit-keymap* "z z" 'legit-stash-push)
(define-key *peek-legit-keymap* "z p" 'legit-stash-pop)

;; redraw everything:
(define-key *peek-legit-keymap* "g" 'legit-status)

Expand Down Expand Up @@ -466,7 +473,7 @@ Currently Git-only. Concretely, this calls Git with the -w option.")


(define-command legit-status () ()
"Show changes, untracked files and latest commits in an interactive window."
"Show changes, untracked files, stashes and latest commits in an interactive window."
(with-current-project (vcs)
(multiple-value-bind (untracked-files unstaged-files staged-files)
(lem/porcelain:components vcs)
Expand Down Expand Up @@ -503,6 +510,15 @@ Currently Git-only. Concretely, this calls Git with the -w option.")
(insert-string point file :attribute 'filename-attribute :read-only t)))
(collector-insert "<none>"))


;; Stashes.
(collector-insert "")
(let ((stashes (lem/porcelain:stash-list vcs)))
(collector-insert (format nil "Stashes (~a)" (length stashes)) :header t)
(when *show-stashes*
(loop for line in stashes
do (collector-insert line))))

;; Unstaged changes
(collector-insert "")
(collector-insert (format nil "Unstaged changes (~a):" (length unstaged-files)) :header t)
Expand Down Expand Up @@ -748,6 +764,21 @@ Currently Git-only. Concretely, this calls Git with the -w option.")
commits-per-page)))
(display-commits-log vcs last-page-offset))))

(define-command legit-stash-push () ()
"Ask for a message and stash the current changes."
(with-current-project (vcs)
(let ((message (prompt-for-string "Stash message: ")))
(lem/porcelain::stash-push vcs :message message)
(legit-status))))

(define-command legit-stash-pop () ()
"Pop the latest staged changes"
(with-current-project (vcs)
(let ((confirm (prompt-for-y-or-n-p "Pop the latest stash to the current branch? ")))
(when confirm
(lem/porcelain::stash-pop vcs)
(legit-status)))))

(define-command legit-quit () ()
"Quit"
(%legit-quit)
Expand All @@ -767,10 +798,12 @@ Currently Git-only. Concretely, this calls Git with the -w option.")
(format s "(b)ranches-> checkout another (b)ranch.~&")
(format s " -> (c)reate.~&")
(format s "(l)og-> (l) commits log~&")
(format s " -> (F) first page of the commits history~&")
(format s " -> (F) first page of the commits history.~&")
(format s " Navigate commit pages with (b) and (f).~&")
(format s "(F)etch, pull-> (p) from remote branch~&")
(format s "(P)push -> (p) to remote branch~&")
(format s "(r)ebase -> (i)nteractively from commit at point, (a)bort~&")
(format s "(z) stashes -> (z) stash changes (p)op latest stash~&")
(format s "(g) -> refresh~&")
(format s "~%")
(format s "Navigate: n and p, C-n and C-p, M-n and M-p.~&")
Expand All @@ -781,6 +814,7 @@ Currently Git-only. Concretely, this calls Git with the -w option.")
(format s "~%")
(format s "You can customize:~&")
(format s "~%")
(format s "lem/legit:*show-stashes* : set to nil to not see the list of stashes in the status buffer~&")
(format s "lem/porcelain:*nb-latest-commits* which defaults to 10~&")
(format s "(and more)~&")
))
Expand Down
18 changes: 18 additions & 0 deletions extensions/legit/porcelain-git.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,21 @@ I am stopping in case you still have something valuable there."))
(run-git (list "rebase" "--skip")))
(t
(porcelain-error "No git rebase in process? PID not found."))))

(defmethod stash-push ((vcs vcs-git) &key message)
"Stash the current changes. Ask for a stash message."
(if message
(run-git (list "stash" "push" "-m" message))
(run-git (list "stash" "push"))))

(defmethod stash-pop ((vcs vcs-git) &key (position 0))
"Pop the latest stashed changes."
(declare (ignorable position))
(run-git (list "stash" "pop")))

(defmethod stash-list ((vcs vcs-git))
;; each line is like
;; stash@{7}: On main: notes: legit vim interference
;; just display them.
(str:lines
(run-git (list "stash" "list"))))
24 changes: 24 additions & 0 deletions extensions/legit/porcelain.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
:show-commit-diff
:stage
:unstage
:stash-list
:stash-pop
:stash-push
:*diff-context-lines*
:commits-log
:*commits-log-page-size*
Expand Down Expand Up @@ -257,3 +260,24 @@ M src/ext/porcelain.lisp
(defgeneric rebase-skip (vcs)
(:method (vcs)
(porcelain-error "lem/porcelain:rebase-skip not implemented for vcs ~a" (vcs-name vcs))))

;;;
;;; Stash.
;;;
(defgeneric stash-push (vcs &key message)
(:method (vcs &key message)
(declare (ignorable message))
(porcelain-error "lem/porcelain:stash not implemented for vcs ~a" (vcs-name vcs)))
(:documentation "Stash the current changes. Ask for a stash message."))

(defgeneric stash-pop (vcs &key position)
(:method (vcs &key position)
(declare (ignorable position))
(porcelain-error "lem/porcelain:stash-pop not implemented for vcs ~a" (vcs-name vcs)))
(:documentation "Pop saved stashes. Defaults to the latest stash."))

(defgeneric stash-list (vcs)
(:method (vcs)
(declare (ignorable position))
(values))
(:documentation "List stashes"))

0 comments on commit 0b61dbb

Please sign in to comment.