[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/diff-hl a056055 1/3: New command: diff-hl-stage-current
From: |
ELPA Syncer |
Subject: |
[elpa] externals/diff-hl a056055 1/3: New command: diff-hl-stage-current-hunk |
Date: |
Sat, 30 Oct 2021 22:57:18 -0400 (EDT) |
branch: externals/diff-hl
commit a0560551cd45efafe389a3303c7a88fe78ffc2cf
Author: Dmitry Gutov <dgutov@yandex.ru>
Commit: Dmitry Gutov <dgutov@yandex.ru>
New command: diff-hl-stage-current-hunk
#71
---
diff-hl.el | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 84 insertions(+), 13 deletions(-)
diff --git a/diff-hl.el b/diff-hl.el
index 5481caa..f4491f9 100644
--- a/diff-hl.el
+++ b/diff-hl.el
@@ -555,17 +555,9 @@ in the source file, or the last line of the hunk above it."
(with-no-warnings
(let (diff-auto-refine-mode)
(diff-hl-diff-skip-to line)))
- (save-excursion
- (while (looking-at "[-+]") (forward-line 1))
- (setq end-line (line-number-at-pos (point)))
- (setq m-end (point-marker))
- (unless (eobp) (diff-split-hunk)))
- (unless (looking-at "[-+]") (forward-line -1))
- (while (looking-at "[-+]") (forward-line -1))
- (setq beg-line (line-number-at-pos (point)))
- (unless (looking-at "@")
- (forward-line 1)
- (diff-split-hunk))
+ (setq m-end (diff-hl-split-away-changes 0))
+ (setq beg-line (line-number-at-pos)
+ end-line (line-number-at-pos m-end))
(funcall diff-hl-highlight-revert-hunk-function m-end)
(let ((wbh (window-body-height)))
(if (>= wbh (- end-line beg-line))
@@ -586,6 +578,35 @@ in the source file, or the last line of the hunk above it."
(message "Hunk reverted"))))
(quit-windows-on diff-buffer t)))))
+(defun diff-hl-split-away-changes (max-context)
+ "Split away the minimal hunk at point from the rest of the hunk.
+
+The minimal hunk is the hunk a diff program would produce if
+asked for 0 lines of context. Add MAX-CONTEXT lines of context at
+most (stop when encounter another minimal hunk).
+
+Move point to the beginning of the delineated hunk and return
+its end position."
+ (let (end-marker)
+ (save-excursion
+ (while (looking-at "[-+]") (forward-line 1))
+ (dotimes (_i max-context)
+ (unless (looking-at "@\\|[-+]")
+ (forward-line 1)))
+ (setq end-marker (point-marker))
+ (unless (or (eobp)
+ (looking-at "@"))
+ (diff-split-hunk)))
+ (unless (looking-at "[-+]") (forward-line -1))
+ (while (looking-at "[-+]") (forward-line -1))
+ (dotimes (_i max-context)
+ (unless (looking-at "@\\|[-+]")
+ (forward-line -1)))
+ (unless (looking-at "@")
+ (forward-line 1)
+ (diff-split-hunk))
+ end-marker))
+
(defun diff-hl-revert-hunk ()
"Revert the diff hunk with changes at or above the point."
(interactive)
@@ -641,6 +662,53 @@ in the source file, or the last line of the hunk above it."
(goto-char (overlay-start hunk))
(push-mark (overlay-end hunk) nil t)))
+(defvar diff-hl-diff-buffer-with-reference-no-context t)
+
+(defun diff-hl-stage-current-hunk ()
+ (interactive)
+ (diff-hl-find-current-hunk)
+ (let* ((line (line-number-at-pos))
+ (file buffer-file-name)
+ (dest-buffer (get-buffer-create " *diff-hl-stage*"))
+ (orig-buffer (current-buffer))
+ (file-base (shell-quote-argument (file-name-nondirectory file)))
+ (diff-hl-diff-buffer-with-reference-no-context nil)
+ success)
+ (with-current-buffer dest-buffer
+ (let ((inhibit-read-only t))
+ (erase-buffer)))
+ (diff-hl-diff-buffer-with-reference file dest-buffer)
+ (with-current-buffer dest-buffer
+ (with-no-warnings
+ (let (diff-auto-refine-mode)
+ (diff-hl-diff-skip-to line)))
+ (let ((inhibit-read-only t))
+ (diff-hl-split-away-changes 3)
+ (save-excursion
+ (diff-end-of-hunk)
+ (delete-region (point) (point-max)))
+ (diff-beginning-of-hunk)
+ (delete-region (point-min) (point))
+ ;; diff-no-select creates a very ugly header; Git rejects it
+ (insert (format "diff a/%s b/%s\n" file-base file-base))
+ (insert (format "--- a/%s\n" file-base))
+ (insert (format "+++ b/%s\n" file-base)))
+ (let ((patchfile (make-temp-file "diff-hl-stage-patch")))
+ (write-region (point-min) (point-max) patchfile
+ nil 'silent)
+ (unwind-protect
+ (with-current-buffer orig-buffer
+ (with-output-to-string
+ (vc-git-command standard-output 0
+ patchfile
+ "apply" "--cached" ))
+ (setq success t))
+ (delete-file patchfile))))
+ (when success
+ (message "Hunk staged")
+ (unless diff-hl-show-staged-changes
+ (diff-hl-update)))))
+
(defvar diff-hl-command-map
(let ((map (make-sparse-keymap)))
(define-key map "n" 'diff-hl-revert-hunk)
@@ -848,8 +916,11 @@ the `diff-program' to be in your `exec-path'."
(diff-hl-create-revision
file
(or diff-hl-reference-revision
- (diff-hl-working-revision file backend))))))
- (diff-no-select rev (current-buffer) "-U 0 --strip-trailing-cr" 'noasync
+ (diff-hl-working-revision file backend)))))
+ (switches (if diff-hl-diff-buffer-with-reference-no-context
+ "-U 0 --strip-trailing-cr"
+ "-u --strip-trailing-cr")))
+ (diff-no-select rev (current-buffer) switches 'noasync
(get-buffer-create dest-buffer))
(with-current-buffer dest-buffer
(let ((inhibit-read-only t))