Function: diff-hl-stage-some

diff-hl-stage-some is an interactive and natively compiled function defined in diff-hl.el.

Signature

(diff-hl-stage-some &optional BEG END)

Documentation

Stage some or all of the current changes, interactively.

Pops up a diff buffer that can be edited to choose the changes to stage.

Key Bindings

This command is not in any keymaps.

Source Code

;; Defined in /nix/store/cfz56rl3lp066226i0bmmgiicls3gcq7-emacs-packages-deps/share/emacs/site-lisp/elpa/diff-hl-20261001.135/diff-hl.el
(defun diff-hl-stage-some (&optional beg end)
  "Stage some or all of the current changes, interactively.
Pops up a diff buffer that can be edited to choose the changes to stage."
  (interactive "r")
  (diff-hl--ensure-staging-supported)
  (let* ((line-beg (and beg (line-number-at-pos beg t)))
         (line-end (and end (line-number-at-pos end t)))
         (file (diff-hl--buffer-file-name))
         (dest-buffer (get-buffer-create "*diff-hl-stage-some*"))
         (orig-buffer (current-buffer))
         (diff-hl-update-async nil)
         ;; FIXME: If the file name has double quotes, these need to be quoted.
         (file-base (file-name-nondirectory file)))
    (with-current-buffer dest-buffer
      (let ((inhibit-read-only t))
        (erase-buffer)))
    (let (diff-hl-reference-revision)
      (diff-hl-diff-buffer-with-reference file dest-buffer nil 3))
    (with-current-buffer dest-buffer
      (let ((inhibit-read-only t))
        (when end
          (with-no-warnings
            (let (diff-auto-refine-mode)
              (diff-hl-diff-skip-to line-end)
              (diff-hl-split-away-changes 3)
              (diff-end-of-hunk)))
          (delete-region (point) (point-max)))
        (if beg
            (with-no-warnings
              (let (diff-auto-refine-mode)
                (diff-hl-diff-skip-to line-beg)
                (diff-hl-split-away-changes 3)
                (diff-beginning-of-hunk)))
          (goto-char (point-min))
          (forward-line 3))
        (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 ((diff-default-read-only t))
        (diff-hl-stage-diff-mode))
      (setq-local diff-hl-stage--orig orig-buffer))
    (pop-to-buffer dest-buffer)
    (message "Press %s and %s to navigate, %s to split, %s to kill hunk, %s to undo, and %s to stage the diff after editing"
             (substitute-command-keys "\\`n'")
             (substitute-command-keys "\\`p'")
             (substitute-command-keys "\\[diff-split-hunk]")
             (substitute-command-keys "\\[diff-hunk-kill]")
             (substitute-command-keys "\\[diff-undo]")
             (substitute-command-keys "\\[diff-hl-stage-finish]"))))