master 5e28bcb2d8f: Improve vc-dir-next-* commands (bug#81248)
Stephen Berman via Mailing list for Emacs changes <[email protected]>
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: master commit 5e28bcb2d8fc7f7ae3d66868ddfe6d05e15b4bfe Author: Stephen Berman <[email protected]> Commit: Stephen Berman <[email protected]> Improve vc-dir-next-* commands (bug#81248) * lisp/vc/vc-dir.el (vc-dir--before-dotname-p): New function. (vc-dir-next-line, vc-dir-next-directory): Use it to enable using these commands to move point to the VC Dir root directory entry "./". * test/lisp/vc/vc-tests/vc-test-misc.el (vc-test-vc-dir-next/previous): New test. --- lisp/vc/vc-dir.el | 21 ++++++++++-- test/lisp/vc/vc-tests/vc-test-misc.el | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 57a7488825e..596c2fe7362 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -710,12 +710,27 @@ information." t) t)) +;; By design the vc-dir-next-* commands move point from the current +;; entry to the next one of the same type. But for technical reasons +;; any buffer position before the "./" entry is part of that entry, so +;; there is no previous entry from which to move via vc-dir-next-* to +;; this entry. But from the UX perspective such movement is natural, so +;; we enable it by making these commands move point directly to the "./" +;; entry (instead of the "next" one) whenever point is before this +;; entry, as determined by the following function. See bug#81248 for +;; further details. +(defun vc-dir--before-dotname-p () + "Return non-nil if point is before the \"./\" entry." + (< (point) (ewoc-location (ewoc-nth vc-ewoc 0)))) + (defun vc-dir-next-line (arg) "Go to the next line. With prefix argument ARG, move that many lines." (interactive "p") (with-no-warnings - (ewoc-goto-next vc-ewoc arg) + (if (vc-dir--before-dotname-p) + (ewoc-goto-node vc-ewoc (ewoc-nth vc-ewoc 0)) + (ewoc-goto-next vc-ewoc arg)) (vc-dir-move-to-goal-column))) (defun vc-dir-previous-line (arg) @@ -732,7 +747,9 @@ With prefix argument ARG, move that many lines." (if (catch 'foundit (while t - (let* ((next (ewoc-next vc-ewoc (ewoc-locate vc-ewoc)))) + (let* ((next (if (vc-dir--before-dotname-p) + (ewoc-nth vc-ewoc 0) + (ewoc-next vc-ewoc (ewoc-locate vc-ewoc))))) (cond ((not next) (throw 'foundit t)) (t diff --git a/test/lisp/vc/vc-tests/vc-test-misc.el b/test/lisp/vc/vc-tests/vc-test-misc.el index 066c49df324..83a69867220 100644 --- a/test/lisp/vc/vc-tests/vc-test-misc.el +++ b/test/lisp/vc/vc-tests/vc-test-misc.el @@ -298,5 +298,65 @@ See bug#80803 and bug#80967." (should (equal (vc-dir-fileinfo->state data) 'edited)))))))))) +(ert-deftest vc-test-vc-dir-next/previous () + "Test navigating with `vc-dir-{next,previous}-{line,directory}'." + (skip-unless (executable-find vc-git-program)) + (vc-test--with-author-identity 'Git + (let ((vc-handled-backends '(Git))) + (ert-with-temp-directory tempdir + (let ((default-directory tempdir) + (n 0) + vc-dir-buf) + (vc-test--create-repo-function 'Git) + (dolist (file '("file01" "dir1/file11")) + (make-empty-file file t)) + (vc-dir default-directory 'Git) + (while (vc-dir-busy) (sit-for 0.05)) + (setq vc-dir-buf (current-buffer)) + (should (bobp)) + (while (vc-dir--before-dotname-p) + (vc-dir-next-line 1) + (should (and (looking-at "\\./$") (looking-back "^ +"))) + (incf n 1) + (goto-char (point-min)) + (forward-line n)) + (vc-dir-next-line 1) + (should (looking-at "file01$")) + (vc-dir-next-line 1) + (should (looking-at "dir1/$")) + (vc-dir-next-line 1) + (should (looking-at "dir1/file11$")) + (vc-dir-next-line 1) + (should (looking-at "^$")) + (let ((end (point))) + (vc-dir-next-line 1) + (should (equal (point) end))) + (goto-char (point-min)) + (vc-dir-next-directory) + (should (and (looking-at "\\./$") (looking-back "^ +"))) + (vc-dir-next-directory) + (should (and (looking-at "dir1/$") (looking-back "^ +"))) + (vc-dir-next-directory) + (should (and (looking-at "dir1/$") (looking-back "^ +"))) + (goto-char (point-max)) + (vc-dir-previous-line 1) + (should (looking-at "dir1/file11$")) + (vc-dir-previous-line 1) + (should (and (looking-at "dir1/$") (looking-back "^ +"))) + (vc-dir-previous-line 1) + (should (looking-at "file01$")) + (vc-dir-previous-line 1) + (should (and (looking-at "\\./$") (looking-back "^ +"))) + (vc-dir-previous-line 1) + (should (and (looking-at "\\./$") (looking-back "^ +"))) + (goto-char (point-max)) + (vc-dir-previous-directory) + (should (and (looking-at "dir1/$") (looking-back "^ +"))) + (vc-dir-previous-directory) + (should (and (looking-at "\\./$") (looking-back "^ +"))) + (vc-dir-previous-directory) + (should (and (looking-at "\\./$") (looking-back "^ +"))) + (kill-buffer vc-dir-buf)))))) + (provide 'vc-test-misc) ;;; vc-test-misc.el ends here