diff --git a/README.org b/README.org
index 42c841f6e..473450d8a 100644
--- a/README.org
+++ b/README.org
@@ -100,6 +100,12 @@ Activate =magit-todos-mode=. Then open a Magit status buffer, or run ~magit-tod
+ @@html:@@RET@@html:@@ :: Show item at point, or open dedicated buffer if point is on top heading.
+ @@html:@@SPC@@html:@@ :: Peek at the item at point.
+*When magit-todos-follow-mode is activated:*
++ @@html:@@n@@html:@@ :: Peek at the next item.
++ @@html:@@p@@html:@@ :: Peek at the previous item.
+
+
+
*** Commands
+ =magit-todos-mode= :: Activate =magit-todos-mode=, which automatically inserts the to-do list in Magit status buffers.
diff --git a/magit-todos.el b/magit-todos.el
index 30f030b6e..01850a928 100644
--- a/magit-todos.el
+++ b/magit-todos.el
@@ -135,6 +135,13 @@ magit-status buffer.")
See https://magit.vc/manual/magit/Creating-Sections.html for more
details about how section maps work.")
+(defvar magit-todos-follow-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [remap magit-section-forward] #'magit-todos-next-todo)
+ (define-key map [remap magit-section-backward] #'magit-todos-previous-todo)
+ map)
+ "Keymap for `magit-todos-follow-mode'.")
+
(defvar-local magit-todos-show-filenames nil
"Whether to show filenames next to to-do items.
Set automatically depending on grouping.")
@@ -365,6 +372,11 @@ This can be toggled locally in Magit buffers with command
(remove-hook 'magit-status-sections-hook #'magit-todos--insert-todos)
(remove-hook 'magit-status-mode-hook #'magit-todos--add-to-status-buffer-kill-hook)))
+(define-minor-mode magit-todos-follow-mode
+ :init-value nil
+ :keymap magit-todos-follow-map
+ :group 'magit-todos)
+
(defun magit-todos-update ()
"Update the to-do list manually.
Only necessary when option `magit-todos-update' is nil."
@@ -389,20 +401,36 @@ Only necessary when option `magit-todos-update' is nil."
"Show current item.
If PEEK is non-nil, keep focus in status buffer window."
(interactive)
- (let* ((status-window (selected-window))
- (buffer (magit-todos--item-buffer item)))
- (pop-to-buffer buffer)
- (magit-todos--goto-item item)
- (when (derived-mode-p 'org-mode)
- (org-show-entry))
- (when peek
- (select-window status-window))))
+ (if-let* ((status-window (selected-window))
+ (item (oref (magit-current-section) value))
+ (is-valid-item (cl-struct-p item))
+ (buffer (magit-todos--item-buffer item)))
+ (progn
+ (pop-to-buffer buffer)
+ (magit-todos--goto-item item)
+ (when (derived-mode-p 'org-mode)
+ (org-show-entry))
+ (when peek
+ (select-window status-window)))
+ (message "Not a todo item.")))
(defun magit-todos-peek-at-item ()
"Peek at current item."
(interactive)
(magit-todos-jump-to-item :peek t))
+(defun magit-todos-next-todo ()
+ "Peek at next item."
+ (interactive)
+ (magit-section-forward)
+ (magit-todos-peek-at-item))
+
+(defun magit-todos-previous-todo ()
+ "Peek at previous item."
+ (interactive)
+ (magit-section-backward)
+ (magit-todos-peek-at-item))
+
;;;;; Jump to section
(magit-define-section-jumper magit-jump-to-todos "TODOs" todos)