programming (and other) musings
01 Feb 2021

consulting hunks

I use Dmitry Gutov's diff-hl to highlight (with fringe marks) modified hunks in my files under git revision control. The package comes with a command, diff-hl-next-hunk, that one can use to navigate them. So, taking a peek at consult-lines, it was straightforward to put together a consult function to navigate, with completion and preview (although i disable the latter) the hunks in the current file:

(defun jao-consult--diff-lines (&optional backward)
  (let ((candidates)
        (width (length (number-to-string
                        (line-number-at-pos (point-max)
      (while (ignore-errors (diff-hl-next-hunk backward))
        (let* ((str (buffer-substring (line-beginning-position)
               (no (line-number-at-pos (point)))
               (no (consult--line-number-prefix (point-marker) no width)))
          (push (concat no str) candidates))))
    (if backward candidates (nreverse candidates))))

(defun jao-consult-hunks ()
  "Search for modified hunks in the current buffer."
  (let ((candidates (append (jao-consult--diff-lines)
                            (jao-consult--diff-lines t))))
    (unless candidates (error "No changes!"))
    (consult--jump (consult--read candidates
                                  :prompt "Go to hunk: "
                                  :category 'consult--encode-location
                                  :require-match t
                                  :lookup #'consult--line-match
                                  :state (consult--jump-state)))))

(global-set-key (kbd "C-x v c") #'jao-consult-hunks)

i am sure i've taken one or two detours there that can be coded better using consult's API, but it was so nice to be able to have a working command in fifteen minutes that i couldn't resist showing off :)

Tags: emacs
Creative Commons License by jao is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.