aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2023-11-23 20:12:40 +0200
committerJuri Linkov2023-11-23 20:12:40 +0200
commit29d42d9158ae836fc30d72dbdf4a8236a01de87f (patch)
treec9ca67980367ac665cdd702025c747886fba3836
parent51222153df13c44f2dc74e17da21d95a29f91776 (diff)
downloademacs-29d42d9158ae836fc30d72dbdf4a8236a01de87f.tar.gz
emacs-29d42d9158ae836fc30d72dbdf4a8236a01de87f.zip
Support dired-movement-style in dired-next-dirline and dired-prev-dirline
* lisp/dired.el (dired-movement-style): Mention dired-next-dirline and dired-prev-dirline in the docstring (bug#67303). (dired-next-line): Refactor most code to dired--move-to-next-line. (dired--move-to-next-line): New function with code from dired-next-line. (dired--trivial-next-dirline): Rename from dired-next-dirline. (dired-next-dirline): New function body that uses dired-movement-style, dired--move-to-next-line and dired--trivial-next-dirline. (dired-prev-dirline): Mention dired-movement-style in the docstring.
-rw-r--r--etc/NEWS9
-rw-r--r--lisp/dired.el97
2 files changed, 59 insertions, 47 deletions
diff --git a/etc/NEWS b/etc/NEWS
index c0f76ed052b..259af667c03 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -490,10 +490,11 @@ that shows as diffs replacements in the marked files in Dired.
490 490
491--- 491---
492*** New user option 'dired-movement-style'. 492*** New user option 'dired-movement-style'.
493When non-nil, make 'dired-next-line' and 'dired-previous-line' skip 493When non-nil, make 'dired-next-line', 'dired-previous-line',
494empty lines. It also controls how to move point when encountering a 494'dired-next-dirline', 'dired-prev-dirline' skip empty lines.
495boundary (e.g., if every line is visible, invoking 'dired-next-line' 495It also controls how to move point when encountering a boundary
496at the last line will move to the first line). The default is nil. 496(e.g., if every line is visible, invoking 'dired-next-line' at
497the last line will move to the first line). The default is nil.
497 498
498** Ediff 499** Ediff
499 500
diff --git a/lisp/dired.el b/lisp/dired.el
index c212e3094f8..a3d7c636d29 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -499,7 +499,8 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used."
499 499
500(defcustom dired-movement-style nil 500(defcustom dired-movement-style nil
501 "Non-nil means point skips empty lines when moving in Dired buffers. 501 "Non-nil means point skips empty lines when moving in Dired buffers.
502This affects only `dired-next-line' and `dired-previous-line'. 502This affects only `dired-next-line', `dired-previous-line',
503`dired-next-dirline', `dired-prev-dirline'.
503 504
504Possible non-nil values: 505Possible non-nil values:
505 * `cycle': when moving from the last/first visible line, cycle back 506 * `cycle': when moving from the last/first visible line, cycle back
@@ -2688,11 +2689,11 @@ Otherwise, toggle `read-only-mode'."
2688(defun dired--trivial-next-line (arg) 2689(defun dired--trivial-next-line (arg)
2689 "Move down ARG lines, then position at filename." 2690 "Move down ARG lines, then position at filename."
2690 (let ((line-move-visual) 2691 (let ((line-move-visual)
2691 (goal-column)) 2692 (goal-column))
2692 (line-move arg t)) 2693 (line-move arg t))
2693 ;; We never want to move point into an invisible line. 2694 ;; We never want to move point into an invisible line.
2694 (while (and (invisible-p (point)) 2695 (while (and (invisible-p (point))
2695 (not (if (and arg (< arg 0)) (bobp) (eobp)))) 2696 (not (if (and arg (< arg 0)) (bobp) (eobp))))
2696 (forward-char (if (and arg (< arg 0)) -1 1))) 2697 (forward-char (if (and arg (< arg 0)) -1 1)))
2697 (dired-move-to-filename)) 2698 (dired-move-to-filename))
2698 2699
@@ -2705,44 +2706,41 @@ Whether to skip empty lines and how to move from last line
2705is controlled by `dired-movement-style'." 2706is controlled by `dired-movement-style'."
2706 (interactive "^p" dired-mode) 2707 (interactive "^p" dired-mode)
2707 (if dired-movement-style 2708 (if dired-movement-style
2708 (let ((old-position (progn 2709 (dired--move-to-next-line arg #'dired--trivial-next-line)
2709 ;; It's always true that we should move
2710 ;; to the filename when possible.
2711 (dired-move-to-filename)
2712 (point)))
2713 ;; Up/Down indicates the direction.
2714 (moving-down (if (cl-plusp arg)
2715 1 ; means Down.
2716 -1))) ; means Up.
2717 ;; Line by line in case we forget to skip empty lines.
2718 (while (not (zerop arg))
2719 (dired--trivial-next-line moving-down)
2720 (when (= old-position (point))
2721 ;; Now point is at beginning/end of movable area,
2722 ;; but it still wants to move farther.
2723 (if (eq dired-movement-style 'cycle)
2724 ;; `cycle': go to the other end.
2725 (goto-char (if (cl-plusp moving-down)
2726 (point-min)
2727 (point-max)))
2728 ;; `bounded': go back to the last non-empty line.
2729 (while (string-match-p "\\`[[:blank:]]*\\'"
2730 (buffer-substring-no-properties
2731 (line-beginning-position)
2732 (line-end-position)))
2733 (dired--trivial-next-line (- moving-down)))
2734 ;; Encountered a boundary, so let's stop movement.
2735 (setq arg moving-down)))
2736 (when (not (string-match-p "\\`[[:blank:]]*\\'"
2737 (buffer-substring-no-properties
2738 (line-beginning-position)
2739 (line-end-position))))
2740 ;; Has moved to a non-empty line. This movement does
2741 ;; make sense.
2742 (cl-decf arg moving-down))
2743 (setq old-position (point))))
2744 (dired--trivial-next-line arg))) 2710 (dired--trivial-next-line arg)))
2745 2711
2712(defun dired--move-to-next-line (arg jumpfun)
2713 (let ((old-position (progn
2714 ;; It's always true that we should move
2715 ;; to the filename when possible.
2716 (dired-move-to-filename)
2717 (point)))
2718 ;; Up/Down indicates the direction.
2719 (moving-down (if (cl-plusp arg)
2720 1 ; means Down.
2721 -1))) ; means Up.
2722 ;; Line by line in case we forget to skip empty lines.
2723 (while (not (zerop arg))
2724 (funcall jumpfun moving-down)
2725 (when (= old-position (point))
2726 ;; Now point is at beginning/end of movable area,
2727 ;; but it still wants to move farther.
2728 (if (eq dired-movement-style 'cycle)
2729 ;; `cycle': go to the other end.
2730 (goto-char (if (cl-plusp moving-down)
2731 (point-min)
2732 (point-max)))
2733 ;; `bounded': go back to the last non-empty line.
2734 (while (dired-between-files)
2735 (funcall jumpfun (- moving-down)))
2736 ;; Encountered a boundary, so let's stop movement.
2737 (setq arg moving-down)))
2738 (unless (dired-between-files)
2739 ;; Has moved to a non-empty line. This movement does
2740 ;; make sense.
2741 (cl-decf arg moving-down))
2742 (setq old-position (point)))))
2743
2746(defun dired-previous-line (arg) 2744(defun dired-previous-line (arg)
2747 "Move up ARG lines, then position at filename. 2745 "Move up ARG lines, then position at filename.
2748The argument ARG (interactively, prefix argument) says how many lines 2746The argument ARG (interactively, prefix argument) says how many lines
@@ -2753,9 +2751,8 @@ is controlled by `dired-movement-style'."
2753 (interactive "^p" dired-mode) 2751 (interactive "^p" dired-mode)
2754 (dired-next-line (- (or arg 1)))) 2752 (dired-next-line (- (or arg 1))))
2755 2753
2756(defun dired-next-dirline (arg &optional opoint) 2754(defun dired--trivial-next-dirline (arg &optional opoint)
2757 "Goto ARGth next directory file line." 2755 "Goto ARGth next directory file line."
2758 (interactive "p" dired-mode)
2759 (or opoint (setq opoint (point))) 2756 (or opoint (setq opoint (point)))
2760 (if (if (> arg 0) 2757 (if (if (> arg 0)
2761 (re-search-forward dired-re-dir nil t arg) 2758 (re-search-forward dired-re-dir nil t arg)
@@ -2763,10 +2760,24 @@ is controlled by `dired-movement-style'."
2763 (re-search-backward dired-re-dir nil t (- arg))) 2760 (re-search-backward dired-re-dir nil t (- arg)))
2764 (dired-move-to-filename) ; user may type `i' or `f' 2761 (dired-move-to-filename) ; user may type `i' or `f'
2765 (goto-char opoint) 2762 (goto-char opoint)
2766 (error "No more subdirectories"))) 2763 (unless dired-movement-style
2764 (error "No more subdirectories"))))
2765
2766(defun dired-next-dirline (arg &optional _opoint)
2767 "Goto ARGth next directory file line.
2768
2769Whether to skip empty lines and how to move from last line
2770is controlled by `dired-movement-style'."
2771 (interactive "p" dired-mode)
2772 (if dired-movement-style
2773 (dired--move-to-next-line arg #'dired--trivial-next-dirline)
2774 (dired--trivial-next-dirline arg)))
2767 2775
2768(defun dired-prev-dirline (arg) 2776(defun dired-prev-dirline (arg)
2769 "Goto ARGth previous directory file line." 2777 "Goto ARGth previous directory file line.
2778
2779Whether to skip empty lines and how to move from last line
2780is controlled by `dired-movement-style'."
2770 (interactive "p" dired-mode) 2781 (interactive "p" dired-mode)
2771 (dired-next-dirline (- arg))) 2782 (dired-next-dirline (- arg)))
2772 2783