]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new commands to go to headings/sections in the NEWS file
authorLars Ingebrigtsen <larsi@gnus.org>
Sat, 16 Apr 2022 17:14:34 +0000 (19:14 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Sat, 16 Apr 2022 17:14:42 +0000 (19:14 +0200)
* lisp/textmodes/emacs-news-mode.el (emacs-news-find-heading)
(emacs-news-goto-section): New commands.

lisp/textmodes/emacs-news-mode.el

index 85cbb1847bbc9fb7012018a0ae01f4cd3e84f5f2..a766352917ef2f7eaa4d911cbf3df30819b0f222 100644 (file)
@@ -42,6 +42,8 @@
 (defvar-keymap emacs-news-mode-map
   "C-c C-s" #'emacs-news-next-untagged-entry
   "C-c C-r" #'emacs-news-previous-untagged-entry
+  "C-c C-g" #'emacs-news-goto-section
+  "C-c C-f" #'emacs-news-find-heading
   "C-c C-n" #'emacs-news-count-untagged-entries)
 
 (defvar emacs-news-mode-font-lock-keywords
@@ -99,19 +101,15 @@ untagged NEWS entry."
                 (funcall (if reverse #'re-search-backward
                            #'re-search-forward)
                          "^\\(\\*+\\) " nil t))
-      (unless (save-excursion
-                (forward-line -1)
-                (looking-at "---$\\|\\+\\+\\+$"))
-        ;; We have an entry without a tag before it, but check whether
-        ;; it's a heading (which we can determine if the next entry has
-        ;; more asterisks).
-        (let ((level (length (match-string 1))))
-          (when (save-excursion
-                  (goto-char (match-end 0))
-                  (re-search-forward "^\\(\\*+\\) " nil t))
-            (when (<= (length (match-string 1)) level)
-              ;; It wasn't a sub-heading, so we've found one.
-              (setq found t))))))
+      (when (and (not (save-excursion
+                        (forward-line -1)
+                        (looking-at "---$\\|\\+\\+\\+$")))
+                 ;; We have an entry without a tag before it, but
+                 ;; check whether it's a heading (which we can
+                 ;; determine if the next entry has more asterisks).
+                 (not (emacs-news--heading-p)))
+        ;; It wasn't a sub-heading, so we've found one.
+        (setq found t)))
     (if found
         (progn
           (push-mark start)
@@ -122,6 +120,15 @@ untagged NEWS entry."
       (goto-char start)
       nil)))
 
+(defun emacs-news--heading-p ()
+  (save-excursion
+    (beginning-of-line)
+    (and (looking-at "\\(\\*+\\) ")
+         (let ((level (length (match-string 1))))
+           (goto-char (match-end 0))
+           (when (re-search-forward "^\\(\\*+\\) " nil t)
+             (> (length (match-string 1)) level))))))
+
 (defun emacs-news-previous-untagged-entry ()
   "Go to the previous untagged NEWS entry."
   (interactive nil emacs-news-mode)
@@ -166,6 +173,38 @@ untagged NEWS entry."
                             (lambda (node) (info node))
                             (match-string 1)))))))
 
+(defun emacs-news--sections (regexp)
+  (let ((sections nil))
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward (concat "^" regexp "\\(.*\\)") nil t)
+        (when (save-match-data (emacs-news--heading-p))
+          (push (buffer-substring-no-properties
+                 (match-beginning 1) (match-end 1))
+                sections))))
+    (nreverse sections)))
+
+(defun emacs-news-goto-section (section)
+  "Go to SECTION in the Emacs NEWS file."
+  (interactive (list
+                (completing-read "Goto section: " (emacs-news--sections "\\* ")
+                                 nil t))
+               emacs-news-mode)
+  (goto-char (point-min))
+  (when (search-forward (concat "\n* " section) nil t)
+    (beginning-of-line)))
+
+(defun emacs-news-find-heading (heading)
+  "Go to HEADING in the Emacs NEWS file."
+  (interactive (list
+                (completing-read "Goto heading: "
+                                 (emacs-news--sections "\\*\\*\\*? ")
+                                 nil t))
+               emacs-news-mode)
+  (goto-char (point-min))
+  (when (re-search-forward (concat "^*+ " (regexp-quote heading)) nil t)
+    (beginning-of-line)))
+
 (provide 'emacs-news-mode)
 
 ;;; emacs-news-mode.el ends here