From: Shynur Xie <one.last.kiss@outlook.com>
To: Eli Zaretskii <eliz@gnu.org>, Drew Adams <drew.adams@oracle.com>,
Stefan Kangas <stefankangas@gmail.com>
Cc: "65621@debbugs.gnu.org" <65621@debbugs.gnu.org>
Subject: bug#65621: [PATCH] `dired-next-line' go to meaningful line
Date: Thu, 31 Aug 2023 18:15:09 +0000 [thread overview]
Message-ID: <PH0PR11MB7470C711EBAB79091E0EC63FD7E5A@PH0PR11MB7470.namprd11.prod.outlook.com> (raw)
In-Reply-To: <SJ0PR10MB54888D6513C3B137D776C841F3E5A@SJ0PR10MB5488.namprd10.prod.outlook.com>
[-- Attachment #1: Type: text/plain, Size: 1866 bytes --]
The final patch is attached. (See the end for how to test it.)
> Eli:
> it will need to be an opt-in feature.
By default, it's disabled.
> Dradams:
> Be sure to consider also the behavior when subdir listings are
> inserted in the buffer.
Considered.
> Stefan:
> But Drew's point about inserted subdirs would need to be addressed.
Addressed.
> Stefan
> I'd probably enable it if we had such an option, FWIW.
Stefan likes my original patch, so please set
`dired-cursor-goto-meaningful-line' to `bounded' and
`dired-headerline-is-meaningful' to nil.
> Dradams:
> it should move to the subdir header line, skipping only the blank
> line before it.
> `dired-(next|previous)-line' should move to header lines, as well as
> to file/dir lines.
> If you really DON'T want `n'|`p' to go to header lines then maybe
> set some option.
Have taken your advice. You like what your Dired+ does, so please set
`dired-cursor-goto-meaningful-line' to `cycle' and
`dired-headerline-is-meaningful' to t.
___
- To Test It:
There is totally 4 (not 6) kinds of combinations of the 2 new options:
1. (setq dired-cursor-goto-meaningful-line 'bounded
dired-headerline-is-meaningful nil)
2. (setq dired-cursor-goto-meaningful-line 'cycle
dired-headerline-is-meaningful nil)
3. (setq dired-cursor-goto-meaningful-line 'bounded
dired-headerline-is-meaningful t)
4. (setq dired-cursor-goto-meaningful-line 'cycle
dired-headerline-is-meaningful t)
Test them in 3 kinds of dired buffers:
1. regular dired buffer
2. buffer inserted subdirs
3. the option `dired-listing-switches' is an empty string, the
directory is empty, and there is no subdir inserted. I.e., there
is no filename lines. Only empty lines or header lines.
Move cursor from anywhere.
[-- Attachment #2: 0001-dired-next-line-go-to-meaningful-line.patch --]
[-- Type: application/octet-stream, Size: 5554 bytes --]
From 8ddfb99a9213414e438fc4946ce3935b21b6ca3d Mon Sep 17 00:00:00 2001
From: shynur <one.last.kiss@outlook.com>
Date: Fri, 1 Sep 2023 02:12:25 +0800
Subject: [PATCH] `dired-next-line' go to meaningful line
---
lisp/dired.el | 95 +++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 88 insertions(+), 7 deletions(-)
diff --git a/lisp/dired.el b/lisp/dired.el
index e96b85a..3d7d6a6 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -495,6 +495,30 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used."
(string :tag "Switches"))
:version "29.1")
+(defcustom dired-cursor-goto-meaningful-line nil
+ "Non-nil means moving cursor only to a pathname line.
+This option makes `dired-next-line' and `dired-previous-line' move
+cursor to:
+ - a line containing filename if such a line does exist.
+ - or, a header line if `dired-headerline-is-meaningful' is non-nil.
+
+Possible non-nil values:
+ * `cycle': the next/previous line of the last/first line is the
+ first/last line.
+ * `bounded': cursor cannot move up/down if the current line is the
+ first/last line.
+ * any other symbol: the effect is the same as `bounded', but it is
+ not recommended for use."
+ :type '(choice (const :tag "Move to any line" nil)
+ (const :tag "Loop through pathname lines" cycle)
+ (const :tag "Only to pathname line" bounded))
+ :group 'dired)
+
+(defcustom dired-headerline-is-meaningful t
+ "Non-nil means never skip header line when moving cursor."
+ :type 'boolean
+ :group 'dired)
+
(defcustom dired-hide-details-preserved-columns nil
"List of columns which are not hidden in `dired-hide-details-mode'."
:type '(repeat integer)
@@ -2666,22 +2690,79 @@ Otherwise, toggle `read-only-mode'."
(wdired-change-to-wdired-mode)
(read-only-mode 'toggle)))
-(defun dired-next-line (arg)
- "Move down lines then position at filename.
-Optional prefix ARG says how many lines to move; default is one line."
- (interactive "^p")
+(defun dired--trivial-next-line (arg)
+ "Move down ARG lines then position at filename."
(let ((line-move-visual)
- (goal-column))
+ (goal-column))
(line-move arg t))
;; We never want to move point into an invisible line.
(while (and (invisible-p (point))
- (not (if (and arg (< arg 0)) (bobp) (eobp))))
+ (not (if (and arg (< arg 0)) (bobp) (eobp))))
(forward-char (if (and arg (< arg 0)) -1 1)))
(dired-move-to-filename))
+(defun dired--meaningful-line-p ()
+ "Return t if the current line contains a filename, or is a header
+line if `dired-headerline-is-meaningful' is non-nil."
+ (save-excursion
+ ;; Move to BOL or filename.
+ (dired-move-to-filename)
+ (or (get-char-property (point) 'dired-filename)
+ (when dired-headerline-is-meaningful
+ (skip-chars-forward "[[:blank:]]")
+ (eq (get-text-property (point) 'face) 'dired-header)))))
+
+(defun dired-next-line (arg)
+ "Move down lines then position at filename.
+Optional prefix ARG says how many lines to move; default is one line.
+
+Cursor won't go to empty line when `dired-cursor-goto-meaningful-line'
+is non-nil; further, it also skips dired header lines if
+`dired-headerline-is-meaningful' is nil."
+ (interactive "^p")
+ (if dired-cursor-goto-meaningful-line
+ (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 (natnump arg)
+ 1 ; means Down.
+ -1)) ; means Up.
+ ;; The following while-loop runs this many times at
+ ;; most, unless there is not even a meaningful line,
+ ;; but this is almost impossible.
+ (total-moves (* 3 arg moving-down)))
+ ;; Line by line in case we forget to skip meaningless lines.
+ (while (and (not (zerop arg))
+ ;; If there's no meaningful lines, stop the
+ ;; endless while-loop.
+ (natnump total-moves))
+ (cl-decf total-moves)
+ (dired--trivial-next-line moving-down)
+ (when (= old-position (point))
+ ;; Now cursor is at beginning/end of buffer,
+ ;; but the cursor still wants to move farther.
+ (if (eq dired-cursor-goto-meaningful-line 'cycle)
+ (goto-char (if (= 1 moving-down)
+ (point-min)
+ (point-max)))
+ (unless (dired--meaningful-line-p)
+ (dired--trivial-next-line (- moving-down))
+ (setq arg moving-down))))
+ (setq old-position (point))
+ (when (dired--meaningful-line-p)
+ (cl-decf arg moving-down))))
+ (dired--trivial-next-line arg)))
+
(defun dired-previous-line (arg)
"Move up lines then position at filename.
-Optional prefix ARG says how many lines to move; default is one line."
+Optional prefix ARG says how many lines to move; default is one line.
+
+Cursor won't go to empty line when `dired-cursor-goto-meaningful-line'
+is non-nil; further, it also skips dired header lines if
+`dired-headerline-is-meaningful' is nil."
(interactive "^p")
(dired-next-line (- (or arg 1))))
--
2.41.0.windows.3
next prev parent reply other threads:[~2023-08-31 18:15 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-30 13:02 bug#65621: [PATCH] `dired-next-line' go to meaningful line Shynur Xie
2023-08-30 13:36 ` Eli Zaretskii
2023-08-30 13:50 ` Shynur Xie
2023-08-30 14:20 ` Eli Zaretskii
2023-08-30 19:14 ` Stefan Kangas
2023-08-30 20:58 ` Drew Adams
2023-08-30 21:34 ` Stefan Kangas
2023-08-30 22:36 ` Drew Adams
2023-08-31 5:45 ` Shynur Xie
2023-08-31 15:35 ` Drew Adams
2023-08-31 15:46 ` Shynur Xie
2023-08-31 15:55 ` Drew Adams
2023-08-31 18:15 ` Shynur Xie [this message]
2023-08-31 19:10 ` Drew Adams
2023-08-31 19:17 ` Drew Adams
2023-08-31 19:44 ` Shynur Xie
2023-08-31 21:51 ` Drew Adams
2023-08-31 21:35 ` Stefan Kangas
2023-08-31 21:37 ` Stefan Kangas
2023-09-01 17:29 ` Shynur Xie
2023-09-01 18:46 ` Drew Adams
2023-09-01 20:51 ` Shynur Xie
2023-09-01 21:06 ` Drew Adams
2023-09-02 12:05 ` Shynur Xie
2023-09-02 12:13 ` Eli Zaretskii
2023-09-02 12:18 ` Shynur Xie
2023-09-02 12:39 ` Eli Zaretskii
2023-09-02 14:40 ` Shynur Xie
2023-09-10 7:45 ` Eli Zaretskii
2023-09-03 21:47 ` Drew Adams
2023-09-07 15:04 ` Shynur Xie
2023-08-30 14:54 ` Drew Adams
2023-08-30 15:39 ` Shynur Xie
2023-08-30 15:55 ` Drew Adams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=PH0PR11MB7470C711EBAB79091E0EC63FD7E5A@PH0PR11MB7470.namprd11.prod.outlook.com \
--to=one.last.kiss@outlook.com \
--cc=65621@debbugs.gnu.org \
--cc=drew.adams@oracle.com \
--cc=eliz@gnu.org \
--cc=stefankangas@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).