diff --git a/lisp/dired.el b/lisp/dired.el index 583cb2475e2..9d4b3d10ac4 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2705,44 +2746,41 @@ dired-next-line is controlled by `dired-movement-style'." (interactive "^p" dired-mode) (if dired-movement-style - (let ((old-position (progn - ;; It's always true that we should move - ;; to the filename when possible. - (dired-move-to-filename) - (point))) - ;; Up/Down indicates the direction. - (moving-down (if (cl-plusp arg) - 1 ; means Down. - -1))) ; means Up. - ;; Line by line in case we forget to skip empty lines. - (while (not (zerop arg)) - (dired--trivial-next-line moving-down) - (when (= old-position (point)) - ;; Now point is at beginning/end of movable area, - ;; but it still wants to move farther. - (if (eq dired-movement-style 'cycle) - ;; `cycle': go to the other end. - (goto-char (if (cl-plusp moving-down) - (point-min) - (point-max))) - ;; `bounded': go back to the last non-empty line. - (while (string-match-p "\\`[[:blank:]]*\\'" - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position))) - (dired--trivial-next-line (- moving-down))) - ;; Encountered a boundary, so let's stop movement. - (setq arg moving-down))) - (when (not (string-match-p "\\`[[:blank:]]*\\'" - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position)))) - ;; Has moved to a non-empty line. This movement does - ;; make sense. - (cl-decf arg moving-down)) - (setq old-position (point)))) + (dired--move-to-next-line arg #'dired--trivial-next-line) (dired--trivial-next-line arg))) +(defun dired--move-to-next-line (arg jumpfun) + (let ((old-position (progn + ;; It's always true that we should move + ;; to the filename when possible. + (dired-move-to-filename) + (point))) + ;; Up/Down indicates the direction. + (moving-down (if (cl-plusp arg) + 1 ; means Down. + -1))) ; means Up. + ;; Line by line in case we forget to skip empty lines. + (while (not (zerop arg)) + (funcall jumpfun moving-down) + (when (= old-position (point)) + ;; Now point is at beginning/end of movable area, + ;; but it still wants to move farther. + (if (eq dired-movement-style 'cycle) + ;; `cycle': go to the other end. + (goto-char (if (cl-plusp moving-down) + (point-min) + (point-max))) + ;; `bounded': go back to the last non-empty line. + (while (dired-between-files) + (funcall jumpfun (- moving-down))) + ;; Encountered a boundary, so let's stop movement. + (setq arg moving-down))) + (unless (dired-between-files) + ;; Has moved to a non-empty line. This movement does + ;; make sense. + (cl-decf arg moving-down)) + (setq old-position (point))))) + (defun dired-previous-line (arg) "Move up ARG lines, then position at filename. The argument ARG (interactively, prefix argument) says how many lines @@ -2753,9 +2791,8 @@ dired-previous-line (interactive "^p" dired-mode) (dired-next-line (- (or arg 1)))) -(defun dired-next-dirline (arg &optional opoint) +(defun dired--trivial-next-dirline (arg &optional opoint) "Goto ARGth next directory file line." - (interactive "p" dired-mode) (or opoint (setq opoint (point))) (if (if (> arg 0) (re-search-forward dired-re-dir nil t arg) @@ -2763,7 +2800,15 @@ dired-next-dirline (re-search-backward dired-re-dir nil t (- arg))) (dired-move-to-filename) ; user may type `i' or `f' (goto-char opoint) - (error "No more subdirectories"))) + (unless dired-movement-style + (error "No more subdirectories")))) + +(defun dired-next-dirline (arg &optional _opoint) + "Goto ARGth next directory file line." + (interactive "p" dired-mode) + (if dired-movement-style + (dired--move-to-next-line arg #'dired--trivial-next-dirline) + (dired--trivial-next-dirline arg))) (defun dired-prev-dirline (arg) "Goto ARGth previous directory file line."