[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/vc-got ba12390 027/145: adding vc-got-stage
From: |
ELPA Syncer |
Subject: |
[elpa] externals/vc-got ba12390 027/145: adding vc-got-stage |
Date: |
Thu, 9 Sep 2021 15:58:26 -0400 (EDT) |
branch: externals/vc-got
commit ba123905bee33e736ce9f4e97bf5f3e714a7d39f
Author: Omar Polo <op@omarpolo.com>
Commit: Omar Polo <op@omarpolo.com>
adding vc-got-stage
vc-got-stage is a minor mode for vc-diff buffers controlled by Got.
It's a tentative at implementing the stage operation for specific
changes instead of whole files. vc.el works with filesets, and this
is fine. But sometimes you want to commit only certain hunks.
This initial implementation allows the user to stage changes, but you
can't commit them (yet).
---
vc-got-stage.el | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vc-got.el | 7 ++
2 files changed, 212 insertions(+)
diff --git a/vc-got-stage.el b/vc-got-stage.el
new file mode 100644
index 0000000..ae553d2
--- /dev/null
+++ b/vc-got-stage.el
@@ -0,0 +1,205 @@
+;; vc-got-stage.el --- Stage changes in vc-got diff buffers -*-
lexical-binding: t; -*-
+
+(eval-when-compile
+ (require 'subr-x))
+
+(defgroup vc-got-stage nil
+ "Stage hunks in vc-got diff buffers"
+ :group 'faces
+ :prefix "vc-got-stage-")
+
+(defface vc-got-stage-staged-face
+ '((t (:foreground "red" :background "yellow")))
+ "Face used to highlight the staged mark on changes."
+ :group 'vc-got-stage)
+
+(defvar vc-got-stage-fileset nil
+ "The files diffed in the last call to `vc-got-diff'.")
+
+(defvar vc-got-stage-overlay-priority 0
+ "Specify overlay priority.
+Higher values means higher priority. DON'T use negative numbers.")
+
+(defvar vc-got-stage--overlays nil
+ "The list of overlays.")
+
+(defvar vc-got-stage-prefix-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "A") #'vc-got-stage-apply)
+ (define-key map (kbd "b") #'vc-got-stage-beginning-of-change)
+ (define-key map (kbd "e") #'vc-got-stage-end-of-change)
+ (define-key map (kbd "n") #'vc-got-stage-next-change)
+ (define-key map (kbd "p") #'vc-got-stage-prev-change)
+ (define-key map (kbd "t") #'vc-got-stage-toggle-mark)
+ map)
+ "Keymap for function `vc-got-stage-mode'.")
+
+;;;###autoload
+(define-minor-mode vc-got-stage-mode
+ "Stage hunks in vc-got diff buffers.
+
+\\{vc-got-stage-mode-map}"
+ :group vc-got-stage
+ :keymap (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c g") vc-got-stage-prefix-map)
+ map))
+
+;;;###autoload (defun vc-got-stage-activate ()
+;;;###autoload "Activate vg-got-stage-mode if the current buffer is a vc-got
diff."
+;;;###autoload (when-let (root (vc-find-root default-directory ".got"))
+;;;###autoload (vc-got-stage-mode +1)))
+
+(defun vc-got-stage-activate ()
+ "Activate vg-got-stage-mode if the current buffer is a vc-got diff."
+ (message "VC got stage activate? %s" (vc-find-root default-directory ".got"))
+ (when-let (root (vc-find-root default-directory ".got"))
+ (vc-got-stage-mode +1)))
+
+;;;###autoload (add-hook 'diff-mode-hook #'vc-got-stage-activate)
+(add-hook 'diff-mode-hook #'vc-got-stage-activate)
+
+(defun vc-got-stage--in-change ()
+ "T if the point is in a line that's part of a change."
+ (save-excursion
+ (beginning-of-line)
+ (when-let (ch (char-after))
+ (or (= ch ?\-)
+ (= ch ?\+)))))
+
+(defun vc-got-stage--change-marked-p ()
+ "T if the current change is marked."
+ (let ((p (point)))
+ (cl-loop
+ for overlay in vc-got-stage--overlays
+ if (and (overlay-start overlay)
+ (= p (overlay-start overlay)))
+ return t
+ finally (return nil))))
+
+(defun vc-got-stage--compute-y-or-n (buf)
+ "Fill BUF with ``y'' or ``n'' lines for staging purpose."
+ (save-excursion
+ (goto-char (point-min))
+ (let ((p (point)))
+ (while (not (= p (progn (vc-got-stage-next-change)
+ (point))))
+ (setq p (point))
+ (if (vc-got-stage--change-marked-p)
+ (with-current-buffer buf
+ (insert "y\n"))
+ (with-current-buffer buf
+ (insert "n\n")))))))
+
+(defun vc-got-stage--apply-impl (script tmp-file)
+ "Apply the stages using SCRIPT as script (TMP-FILE is the path)."
+ (interactive "P")
+ (let* ((default-directory (vc-got-root default-directory))
+ (stage-buf (get-buffer-create "*vc-got-stage*")))
+ (unless (zerop (apply #'process-file "got" nil stage-buf nil "unstage"
+ (mapcar #'file-relative-name vc-got-stage-fileset)))
+ (pop-to-buffer stage-buf)
+ (error "Got unstage failed"))
+ (vc-got-stage--compute-y-or-n script)
+ (with-current-buffer script
+ (save-buffer))
+ (unless (zerop (apply #'process-file "got" nil stage-buf nil "stage" "-p"
+ "-F" tmp-file (mapcar #'file-relative-name
+ vc-got-stage-fileset)))
+ (pop-to-buffer stage-buf)
+ (error "Got stage failed"))))
+
+(defun vc-got-stage-apply ()
+ "Apply the stages.
+This will first reset the stages of all the involved files, then
+stage the marked changes."
+ (interactive)
+ (let* ((tmp-file (make-temp-file "vc-got-stage-script"))
+ (script (find-file-noselect tmp-file)))
+ (unwind-protect
+ (vc-got-stage--apply-impl script tmp-file)
+ (kill-buffer script)
+ (delete-file tmp-file))))
+
+(defun vc-got-stage-beginning-of-change ()
+ "Goto the beginning of the current change."
+ (interactive)
+ (ignore-errors
+ (beginning-of-line)
+ (while (vc-got-stage--in-change)
+ (forward-line -1))
+ (forward-line)))
+
+(defun vc-got-stage-end-of-change ()
+ "Goto the end of the current change."
+ (interactive)
+ (ignore-errors
+ (beginning-of-line)
+ (while (vc-got-stage--in-change)
+ (forward-line))
+ (forward-line -1)))
+
+(defun vc-got-stage--prevnext-change (n)
+ "Goto next/previous change by N."
+ (let ((start (point)))
+ (beginning-of-line)
+ (while (and (not (= (point) (if (= n -1)
+ (point-min)
+ (point-max))))
+ (vc-got-stage--in-change))
+ (forward-line n))
+ (while (let ((face (get-text-property (point) 'face)))
+ (and (not (= (point) (if (= n -1)
+ (point-min)
+ (point-max))))
+ (or (eq face 'diff-hunk-header)
+ (eq face 'diff-header)
+ (eq face 'diff-context))))
+ (forward-line n))
+ (if (= n -1)
+ (vc-got-stage-beginning-of-change))
+ (unless (vc-got-stage--in-change)
+ (goto-char start)
+ (message "No prev/next change"))))
+
+(defun vc-got-stage-prev-change ()
+ "Goto previous change."
+ (interactive)
+ (vc-got-stage--prevnext-change -1))
+
+(defun vc-got-stage-next-change ()
+ "Goto next change."
+ (interactive)
+ (vc-got-stage--prevnext-change +1))
+
+(defun vc-got-stage--delete-overlay-at (point)
+ "Delete overlays at POINT.
+Return t if something was deleted."
+ (let (delp)
+ (cl-delete-if (lambda (overlay)
+ (let ((start (overlay-start overlay)))
+ ;; silently drop dangling overlays
+ (cond ((not start)
+ t)
+ ((= point start)
+ (delete-overlay overlay)
+ (setq delp t)))))
+ vc-got-stage--overlays)
+ delp))
+
+(defun vc-got-stage-toggle-mark ()
+ "Toggle the staged status on the change at point."
+ (interactive)
+ (when (vc-got-stage--in-change)
+ (save-excursion
+ (vc-got-stage-beginning-of-change)
+ (unless (vc-got-stage--delete-overlay-at (point))
+ (let ((overlay (make-overlay (point) (point))))
+ (overlay-put overlay
+ 'before-string
+ (propertize "A"
+ 'display '(left-fringe right-triangle)
+ 'face 'vc-got-stage-staged-face))
+ (push overlay vc-got-stage--overlays))))))
+
+(provide 'vc-got-stage)
+;;; vc-got-stage.el ends here
diff --git a/vc-got.el b/vc-got.el
index 32c1b2a..083718c 100755
--- a/vc-got.el
+++ b/vc-got.el
@@ -107,6 +107,8 @@
(require 'seq)
(require 'vc)
+(require 'vc-got-stage)
+
(defvar vc-got-cmd "got"
"The got command.")
@@ -496,6 +498,11 @@ LIMIT limits the number of commits, optionally starting at
START-REVISION."
(let* ((buffer (get-buffer-create (or buffer "*vc-diff*")))
(inhibit-read-only t))
(with-current-buffer buffer
+ (vc-got-stage-mode +1)
+ ;; TODO: this shouldn't be done in an unconditioned fashion. If
+ ;; we're diffing two revision, we can't stage hunks; we can
+ ;; stage only when diffing the local modifications.
+ (setq vc-got-stage-fileset files)
(vc-got-with-worktree (car files)
(cond ((and (null rev1)
(null rev2))
- [elpa] externals/vc-got 0071376 125/145: change the description in the header, (continued)
- [elpa] externals/vc-got 0071376 125/145: change the description in the header, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 622993f 117/145: remove vc-got-stage, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 49945a0 105/145: mark ignore and ignore-completion-table as NOT NEEDED, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 807ca5a 120/145: mark completely staged files as 'up-to-date, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 9114bbc 112/145: use wrapper function instead of replicating it, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 01bf4e0 128/145: reword docstring to avoid checkdoc complain, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 65255dc 133/145: update README.md, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got c3185bf 113/145: add various -- to avoid arguments being interpreted as flags, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 8b45e61 137/145: mention version requirement for got send, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got d06f988 019/145: suggest to add .got to vc-directory-exclusion-list, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got ba12390 027/145: adding vc-got-stage,
ELPA Syncer <=
- [elpa] externals/vc-got 21914ca 032/145: apply-impl should not be interactive, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 0a66694 046/145: vc-got--log: add flag for reverse and mark as no side effects, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got a5c1731 047/145: drop vc-got-stage, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 8da4c01 049/145: remove debugging comments, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 3f25d9f 051/145: add vc-got-annotate (#4), ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 8228942 050/145: fix vc-got-dir-status-files, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got fab791a 052/145: vc-got--call flatten and filter arg list, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got 8b635a9 054/145: implement repository-url, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got c27df03 055/145: print more info in vc-got-dir-extra-headers, ELPA Syncer, 2021/09/09
- [elpa] externals/vc-got a96df0e 056/145: provide unregister and delete-file commands (#7), ELPA Syncer, 2021/09/09