branch: elpa/git-commit commit 208dbd56898d1054fcbad6dbd585250d8f57d3a7 Author: Jonas Bernoulli <jo...@bernoul.li> Commit: Jonas Bernoulli <jo...@bernoul.li>
magit-section-goto-successor: Define as generic function --- lisp/magit-diff.el | 48 +++++++++++++++++++++++------------------------ lisp/magit-section.el | 52 ++++++++++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/lisp/magit-diff.el b/lisp/magit-diff.el index ffcece0b89..c4d4d49ca4 100644 --- a/lisp/magit-diff.el +++ b/lisp/magit-diff.el @@ -2877,30 +2877,30 @@ It the SECTION has a different type, then do nothing." beg (line-end-position)))) (t t)))))))) -(defun magit-hunk-goto-successor (section arg) - (and (magit-hunk-section-p section) - (and-let* ((parent (magit-get-section - (magit-section-ident - (oref section parent))))) - (let* ((children (oref parent children)) - (siblings (magit-section-siblings section 'prev)) - (previous (nth (length siblings) children))) - (if (not arg) - (--when-let (or previous (car (last children))) - (magit-section-goto it) - t) - (when previous - (magit-section-goto previous)) - (if (and (stringp arg) - (re-search-forward arg (oref parent end) t)) - (goto-char (match-beginning 0)) - (goto-char (oref (car (last children)) end)) - (forward-line -1) - (while (looking-at "^ ") (forward-line -1)) - (while (looking-at "^[-+]") (forward-line -1)) - (forward-line))))))) - -(add-hook 'magit-section-goto-successor-hook #'magit-hunk-goto-successor) +(cl-defmethod magit-section-goto-successor ((section magit-hunk-section) + line char arg) + (or (magit-section-goto-successor--same section line char) + (and-let* ((parent (magit-get-section + (magit-section-ident + (oref section parent))))) + (let* ((children (oref parent children)) + (siblings (magit-section-siblings section 'prev)) + (previous (nth (length siblings) children))) + (if (not arg) + (--when-let (or previous (car (last children))) + (magit-section-goto it) + t) + (when previous + (magit-section-goto previous)) + (if (and (stringp arg) + (re-search-forward arg (oref parent end) t)) + (goto-char (match-beginning 0)) + (goto-char (oref (car (last children)) end)) + (forward-line -1) + (while (looking-at "^ ") (forward-line -1)) + (while (looking-at "^[-+]") (forward-line -1)) + (forward-line))))) + (magit-section-goto-successor--related section))) ;;; Diff Sections diff --git a/lisp/magit-section.el b/lisp/magit-section.el index f1ace71f31..186fac3e15 100644 --- a/lisp/magit-section.el +++ b/lisp/magit-section.el @@ -81,11 +81,6 @@ value should be `show', `hide' or nil. If no function returns non-nil, determine the visibility as usual, i.e. use the hardcoded section specific default (see `magit-insert-section').") -(defvar magit-section-goto-successor-hook nil - "Hook used to go to the same section as was current before a refresh. -This is only used if the standard mechanism for doing so did not -succeed.") - ;;; Options (defgroup magit-section nil @@ -1701,26 +1696,33 @@ invisible." (line-number-at-pos start)) (- point (line-beginning-position))))) -(defun magit-section-goto-successor (section line char &optional arg) +(cl-defgeneric magit-section-goto-successor ()) + +(cl-defmethod magit-section-goto-successor ((section magit-section) + line char &optional _arg) + (or (magit-section-goto-successor--same section line char) + (magit-section-goto-successor--related section))) + +(defun magit-section-goto-successor--same (section line char) (let ((ident (magit-section-ident section))) - (--if-let (magit-get-section ident) - (let ((start (oref it start))) - (goto-char start) - (unless (eq it magit-root-section) - (ignore-errors - (forward-line line) - (forward-char char)) - (unless (eq (magit-current-section) it) - (goto-char start)))) - (or (run-hook-with-args-until-success - 'magit-section-goto-successor-hook section arg) - (goto-char (--if-let (magit-section-goto-successor-1 section) - (if (eq (oref it type) 'button) - (point-min) - (oref it start)) - (point-min))))))) - -(defun magit-section-goto-successor-1 (section) + (and-let* ((found (magit-get-section ident))) + (let ((start (oref found start))) + (goto-char start) + (unless (eq found magit-root-section) + (ignore-errors + (forward-line line) + (forward-char char)) + (unless (eq (magit-current-section) found) + (goto-char start)))) + t))) + +(defun magit-section-goto-successor--related (section) + (and-let* ((found (magit-section-goto-successor--related-1 section))) + (goto-char (if (eq (oref found type) 'button) + (point-min) + (oref found start))))) + +(defun magit-section-goto-successor--related-1 (section) (or (and-let* ((alt (pcase (oref section type) ('staged 'unstaged) ('unstaged 'staged) @@ -1733,7 +1735,7 @@ invisible." (magit-get-section (magit-section-ident prev))) (and-let* ((parent (oref section parent))) (or (magit-get-section (magit-section-ident parent)) - (magit-section-goto-successor-1 parent))))) + (magit-section-goto-successor--related-1 parent))))) ;;; Region