2 İşlemeler 788b9e1c2f ... b6c2144f50

Yazar SHA1 Mesaj Tarih
  Fred Gilham b6c2144f50 Add commentary select; fix xrefs 2 hafta önce
  Fred Gilham eced6fe890 Fix one of the places where the module name is removed from buffer 2 hafta önce
1 değiştirilmiş dosya ile 222 ekleme ve 121 silme
  1. 222 121
      bible.el

+ 222 - 121
bible.el

@@ -3,10 +3,10 @@
 ;; Copyright (c) 2025-2026 Fred Gilham
 
 ;; Author: Fred Gilham <fmgilham@gmail.com>
-;; Version: 1.1.1
+;; Version: 1.2.0
 ;; Keywords: files, text, hypermedia
 ;; Package-Requires: ((emacs "29.1") cl-lib dom shr)
-;; URL: https://gitbot.homedns.org/fred/bible-mode
+;; URL: https://gitbot.homedns.org/fred/bible
 
 ;; This file is not part of GNU Emacs.
 
@@ -206,7 +206,8 @@ See `bible--display-lemma-hebrew'."
 
 (defconst bible--verse-regexp "\\(I \\|1 \\|II \\|2 \\|III \\|3 \\)??[a-zA-Z]+?[ \t\n][0-9]+[:][0-9]+")
 
-(defvar bible--modules (lazy-completion-table bible--modules bible--list-biblical-modules))
+(defvar bible--texts (lazy-completion-table bible--texts bible--list-biblical-texts))
+(defvar bible--commentaries (lazy-completion-table bible--commentaries bible--list-biblical-commentaries))
 
 ;; REVIEW: I believe these chapter counts aren't the same for all modules, e.g. JPS. (FMG 5-Mar-2026)
 (defvar bible--books
@@ -242,25 +243,53 @@ See `bible--display-lemma-hebrew'."
 ;; TODO: Add abbreviations found in other documents/commentaries? (FMG 5-Mar-2026)
 (defvar bible--book-name-abbreviations
   '(;; Old Testament
-    ("Ge"     . "Genesis")         ("Ex"    . "Exodus")           ("Le"   . "Leviticus")     ("Nu"    . "Numbers")
-    ("De"     . "Deuteronomy")     ("Js"    . "Joshua")           ("Jg"   . "Judges")        ("Judg"   . "Judges")
-    ("Ru"    . "Ruth")             ("1 Samuel"     . "I Samuel")  ("I Sa"  . "I Samuel")     ("1 Sa" . "I Samuel")
-    ("2 Samuel"     . "II Samuel") ("II Sa" . "II Samuel")        ("2 Sa" . "II Samuel")     ("1 Kings"  . "I Kings")
-    ("I Ki"  . "I Kings")          ("1 Ki" . "I Kings")           ("2 Kings"      . "II Kings") ("II Ki" . "II Kings")
-    ("2 Ki" . "II Kings")          ("1 Chronicles" . "I Chronicles")  ("I Ch"  . "I Chronicles")  ("1 Ch" . "I Chronicles")
+    ("Ge" . "Genesis") ("Gen" . "Genesis")
+    ("Ex" . "Exodus")
+    ("Le" . "Leviticus")
+    ("Nu" . "Numbers")
+    ("De" . "Deuteronomy") ("Deu" . "Deuteronomy")
+    ("Js" . "Joshua")
+    ("Jg" . "Judges")  ("Judg" . "Judges")
+    ("Ru" . "Ruth")
+    ("1 Samuel" . "I Samuel") ("I Sa" . "I Samuel") ("1 Sa" . "I Samuel")
+    ("2 Samuel" . "II Samuel") ("II Sa" . "II Samuel") ("2 Sa" . "II Samuel")
+    ("1 Kings" . "I Kings") ("I Ki" . "I Kings") ("1 Ki" . "I Kings")
+    ("2 Kings" . "II Kings") ("II Ki" . "II Kings") ("2 Ki" . "II Kings")
+    ("1 Chronicles" . "I Chronicles")  ("I Ch" . "I Chronicles")  ("1 Ch" . "I Chronicles")
     ("2 Chronicles" . "II Chronicles") ("II Ch" . "II Chronicles") ("2 Ch" . "II Chronicles")
-    ("Ezr"  . "Ezra")          ("Ne"    . "Nehemiah")
-    ("Es"     . "Esther")          ("Jb"    . "Job")              ("Ps"   . "Psalms")        ("Pr"    . "Proverbs")
-    ("Ec"     . "Ecclesiastes")    ("So"    . "Song of Solomon")  ("Is"   . "Isaiah")        ("Je"    . "Jeremiah")
-    ("La"     . "Lamentations")    ("Ez"    . "Ezekiel")          ("Da"   . "Daniel")        ("Ho"    . "Hosea")
-    ("Joe"    . "Joel")            ("Am"    . "Amos")             ("Ob"   . "Obadiah")       ("Jon"   . "Jonah")
-    ("Mi"     . "Micah")           ("Na"    . "Nahum")            ("Ha"   . "Habakkuk")      ("Zep"   . "Zephaniah")
-    ("Hag"    . "Haggai")          ("Ze"    . "Zechariah")        ("Mal"  . "Malachi")
+    ("Ezr" . "Ezra")
+    ("Ne" . "Nehemiah")
+    ("Es" . "Esther")
+    ("Jb" . "Job")
+    ("Ps" . "Psalms")
+    ("Pr" . "Proverbs")
+    ("Ec" . "Ecclesiastes")
+    ("So" . "Song of Solomon")
+    ("Is" . "Isaiah")
+    ("Je" . "Jeremiah")
+    ("La" . "Lamentations")
+    ("Ez" . "Ezekiel")
+    ("Da" . "Daniel")
+    ("Ho" . "Hosea")
+    ("Joe" . "Joel")
+    ("Am" . "Amos")
+    ("Ob" . "Obadiah")
+    ("Jon" . "Jonah")
+    ("Mi" . "Micah")
+    ("Na" . "Nahum")
+    ("Ha" . "Habakkuk")
+    ("Zep" . "Zephaniah")
+    ("Hag" . "Haggai")
+    ("Ze"    . "Zechariah")
+    ("Mal"  . "Malachi")
 
     ;; New Testament
     ;; Added AbbottSmith lexicon abbreviations to allow proper following of cross references in lexicon buffers.
     ("Mt" . "Matthew") ("Matt" . "Matthew")
-    ("Mk" . "Mark") ("Lk" . "Luke") ("Jo" . "John") ("Ac" . "Acts")
+    ("Mk" . "Mark")
+    ("Lk" . "Luke")
+    ("Jo" . "John")
+    ("Ac" . "Acts")
     ("Ro" . "Romans") ("Rom" . "Romans")
     ("1 Corintihans" . "I Corinthians") ("I Co" . "I Corinthians") ("1 Co" . "I Corinthians") ("ICor" . "I Corinthians")
     ("2 Corinthians" . "II Corinthians") ("II Co" . "II Corinthians") ("2 Co" . "II Corinthians") ("IICor" . "II Corinthians")
@@ -274,15 +303,15 @@ See `bible--display-lemma-hebrew'."
     ("2 Timothy" . "II Timothy")  ("II Ti" . "II Timothy") ("2 Ti" . "II Timothy") ("IITim" . "II Timothy")
     ("Tit" . "Titus")
     ("Phm" . "Philemon") ("Phlm" . "Philemon")
-    ("He"   . "Hebrews") ("Heb"   . "Hebrews")
-    ("Ja"    . "James") ("Jas"    . "James")
-    ("1 Peter" . "I Peter")   ("I Pe"   . "I Peter")  ("1 Pe" . "I Peter")
-    ("2 Peter" . "II Peter")  ("II Pe"  . "II Peter") ("2 Pe" . "II Peter") ("IIPet" . "II Peter")
-    ("1 John"  . "I John")    ("I Jo"   . "I John")   ("1 Jo" . "I John") ("IJohn" . "I John")
-    ("2 John"  . "II John")   ("II Jo"  . "II John")  ("2 Jo" . "II John")   ("IIJohn" . "II John")
-    ("3 John"  . "III John")  ("III Jo" . "III John") ("3 Jo" . "III John") ("IIIJohn" . "III John")
-    ("Ju"    . "Jude")
-    ("Re"   . "Revelation of John") ("Rev"   . "Revelation of John"))
+    ("He" . "Hebrews") ("Heb" . "Hebrews")
+    ("Ja" . "James") ("Jas" . "James")
+    ("1 Peter" . "I Peter") ("I Pe" . "I Peter") ("1 Pe" . "I Peter")
+    ("2 Peter" . "II Peter")  ("II Pe" . "II Peter") ("2 Pe" . "II Peter") ("IIPet" . "II Peter")
+    ("1 John" . "I John") ("I Jo" . "I John") ("1 Jo" . "I John") ("IJohn" . "I John")
+    ("2 John" . "II John") ("II Jo"  . "II John") ("2 Jo" . "II John") ("IIJohn" . "II John")
+    ("3 John" . "III John") ("III Jo" . "III John") ("3 Jo" . "III John") ("IIIJohn" . "III John")
+    ("Ju" . "Jude")
+    ("Re" . "Revelation of John") ("Rev" . "Revelation of John"))
   "A-list of abbreviations for Bible books.")
 
 ;;;;; Book / chapter
@@ -345,7 +374,8 @@ See `bible--display-lemma-hebrew'."
 
 ;;;;; Misc key bindings
 
-(define-key bible-map "m" 'bible-select-module)
+(define-key bible-map "T" 'bible-select-text)
+(define-key bible-map "C" 'bible-select-commentary)
 (define-key bible-map "w" 'bible-toggle-word-study)
 (define-key bible-map "l" 'bible-toggle-red-letter)
 
@@ -359,35 +389,6 @@ See `bible--display-lemma-hebrew'."
             [menu-bar bible split-display]
             '("Split Display" . bible-split-display))
 
-;;;;; Search
-
-(define-key bible-map "/" 'bible-search)
-(define-key bible-map "s" 'bible-search)
-(define-key bible-map
-            [menu-bar bible search]
-            '("Search" . bible-search))
-
-(define-key bible-map "r" 'bible-set-search-range)
-(define-key bible-map
-            [menu-bar bible range]
-            '("Set Search Range" . bible-set-search-range))
-
-(defconst bible-search-mode-map (make-keymap))
-(define-key bible-search-mode-map "s" 'bible-search)
-(define-key bible-search-mode-map "w" 'bible-toggle-word-study)
-(define-key bible-search-mode-map "n" 'bible-next-search-item)
-(define-key bible-search-mode-map "p" 'bible-previous-search-item)
-(define-key bible-search-mode-map (kbd "RET") 'bible-search-mode-follow-verse)
-
-;;;;; Term display
-
-(defconst bible-term-hebrew-mode-map (make-sparse-keymap))
-(define-key bible-term-hebrew-mode-map "z" 'text-scale-adjust)
-
-(defconst bible-term-greek-mode-map (make-sparse-keymap))
-(define-key bible-term-greek-mode-map "z" 'text-scale-adjust)
-(define-key bible-term-greek-mode-map [mouse-1] 'bible-search-mode-follow-xref)
-
 ;;;;; Navigation
 
 (define-key bible-map "p" 'bible-previous-chapter)
@@ -423,6 +424,33 @@ See `bible--display-lemma-hebrew'."
 (define-key bible-map "\C-n" 'next-logical-line)
 (define-key bible-map "\C-p" 'previous-logical-line)
 
+;;;;; Search
+
+(define-key bible-map "/" 'bible-search)
+(define-key bible-map "s" 'bible-search)
+(define-key bible-map
+            [menu-bar bible search]
+            '("Search" . bible-search))
+
+(define-key bible-map "r" 'bible-set-search-range)
+(define-key bible-map
+            [menu-bar bible range]
+            '("Set Search Range" . bible-set-search-range))
+
+(defconst bible-search-mode-map (make-keymap))
+(define-key bible-search-mode-map "s" 'bible-search)
+(define-key bible-search-mode-map "w" 'bible-toggle-word-study)
+(define-key bible-search-mode-map "n" 'bible-next-search-item)
+(define-key bible-search-mode-map "p" 'bible-previous-search-item)
+(define-key bible-search-mode-map (kbd "RET") 'bible-search-mode-follow-verse)
+
+;;;;; Term display
+
+(defconst bible-term-mode-map (make-sparse-keymap))
+(define-key bible-term-mode-map "z" 'text-scale-adjust)
+(define-key bible-term-mode-map [mouse-1] 'bible-search-mode-follow-xref)
+
+
 (defun bible-toggle-display-diatheke ()
   "Toggle diatheke args display."
   (interactive)
@@ -491,9 +519,13 @@ See `bible--display-lemma-hebrew'."
             [menu-bar bible sepp]
             '(menu-item '"--"))
 
+(define-key bible-map
+            [menu-bar bible select-biblical-commentary]
+            '("Select Commentary" . bible-display-available-commentaries))
+
 (define-key bible-map
             [menu-bar bible select-biblical-text]
-            '("Select Module" . bible-display-available-modules))
+            '("Select Text" . bible-display-available-texts))
 
 ;;;; Terms
 
@@ -556,25 +588,26 @@ This command is run by clicking on text, not directly by the user."
   (setq buffer-read-only t)
   (visual-line-mode t))
 
-(define-derived-mode bible-term-hebrew-mode special-mode "Bible Term (Hebrew)"
-  "Mode for researching Hebrew terms in the Bible.
-\\{bible-term-hebrew-mode-map}"
+
+(define-derived-mode bible-term-mode special-mode "Bible Term"
+  "Mode for researching terms in the Bible.
+\\{bible-term-mode-map}"
   (buffer-disable-undo)
   (font-lock-mode t)
-  (use-local-map bible-term-hebrew-mode-map)
+  (use-local-map bible-term-mode-map)
   (setq buffer-read-only t)
   (visual-line-mode t))
 
-(define-derived-mode bible-term-greek-mode special-mode "Bible Term (Greek)"
+(define-derived-mode bible-term-hebrew-mode bible-term-mode "Bible Term (Hebrew)"
+  "Mode for researching Hebrew terms in the Bible.
+\\{bible-term-hebrew-mode-map}")
+
+(define-derived-mode bible-term-greek-mode bible-term-mode "Bible Term (Greek)"
   "Mode for researching Greek terms in the Bible.
-\\{bible-term-greek-mode-map}"
-  (buffer-disable-undo)
-  (font-lock-mode t)
-  (use-local-map bible-term-greek-mode-map)
-  (setq buffer-read-only t)
-  (visual-line-mode t))
+\\{bible-term-greek-mode-map}")
 
-(define-derived-mode bible-module-select-mode special-mode "Select Text Module"
+
+(define-derived-mode bible-module-select-mode special-mode "Select Module"
   (buffer-disable-undo)
   (font-lock-mode t)
   (setq buffer-read-only t))
@@ -667,10 +700,18 @@ specifies the module to use."
         (setq bible-search-range nil)
       (setq bible-search-range range))))
 
-(defun bible-select-module ()
+(defun bible-select-text ()
   "Ask user for a new text module for the current `bible' buffer."
   (interactive)
-  (let ((module (completing-read "Module: " bible--modules)))
+  (let ((module (completing-read "Text: " bible--texts)))
+    (unless (string= module "")
+      (setq-default bible-module module)
+      (bible--display module))))
+
+(defun bible-select-commentary ()
+  "Ask user for a new text module for the current `bible' buffer."
+  (interactive)
+  (let ((module (completing-read "Commentary: " bible--commentaries)))
     (unless (string= module "")
       (setq-default bible-module module)
       (bible--display module))))
@@ -739,6 +780,7 @@ Handle abbreviations from lexicon module (AbbottSmith)."
          book
          chapter
          verse)
+    (message "Trying to follow %s" xref)
     (cond ((= (length verse-ref) 2) ; Mat 5 or the like
            (setq book-abbrev (car verse-ref)
                  chapter-verse (split-string (cadr verse-ref) ":")))
@@ -823,21 +865,13 @@ MODULE is the text module to use and defaults to the current module."
       (apply #'call-process args))
     (buffer-string)))
 
-;; TODO: Bible chapter titles mostly appear in Psalms. This code works
-;;       OK except for Psalm 119 which changes the chapter title to
-;;       indicate the Hebrew letter that each verse of a stanza begins
-;;       with.
-;;
-;;       Chapter titles seem to be part of each verse in the modules I saw.
-;;
-;;       Fixing this issue would require keeping track of the current
-;;       chapter title and emitting the title whenever it changed.
-;;       Since there is (AFAIK) only one chapter in the Bible that has
-;;       this issue, it doesn't seem like a high priority now.
 (defvar-local bible-chapter-title nil
   "Text preceding start of chapter.
 Mostly in Psalms, like `Of David' or the like.")
 
+(defvar-local bible-level "0"
+  "Used by some modules for indentation and line breaks.")
+
 ;;;; Greek and Hebrew lexeme and morpheme tooltip rendering.
 
 ;;;;; Hash tables for Lexical definitions.
@@ -1187,7 +1221,6 @@ in buffer)."
               (add-face-text-property refstart (point) '(:foreground "blue"))
               (put-text-property refstart (point) 'keymap bible-lemma-keymap))))))))
 
-
 (defun bible-new-line ()
   "Ensure beginning of line.  Try to avoid redundant blank lines."
   (unless (= (current-column) 0)
@@ -1199,8 +1232,6 @@ Since each verse will have a `title' tag, keep track and only emit a
 title when the new title in `title-node' is different from the one
 stored in `bible-chapter-title'."
   (unless (equal bible-chapter-title title-node)
-;;    (unless bible-chapter-title
-;;      (goto-char (point-min)))
     (setq-local bible-chapter-title title-node)
     (let ((title-text (bible-dom-texts bible-chapter-title)))
       (let ((refstart (point))
@@ -1212,6 +1243,23 @@ stored in `bible-chapter-title'."
 	(setq refend (point))
 	(put-text-property refstart refend 'face 'bold)))))
 
+;; These tags appear in ESV modules (and maybe others?)
+;; REVIEW: Is this right? (FMG 5-Mar-2026)
+(defun bible--level-tag (node)
+  "Indent or break line as dictated by NODE."
+  (let ((type (dom-attr node 'type))
+	(level (dom-attr node 'level)))
+    (cond ((and type (string-equal-ignore-case type "x-br"))
+	   (newline))
+          ((and type (string-equal-ignore-case type "x-indent"))
+           (insert "\t"))
+	  ;; REVIEW: Some modules use `level' tag but
+	  ;; not in a consistent way. (FMG 7-Mar-2026)
+	  ((equal level "1")
+	   (insert " "))
+          ((equal level "2")
+	   (newline)))))
+
 (defun bible--insert-domnode-recursive (node &optional iproperties)
   "Recursively parse domnode NODE obtained from `libxml-parse-html-region'.
 Inserts resulting text into active buffer with properties specified in
@@ -1243,7 +1291,9 @@ In processing subnodes, each case will prepend a space if it needs it."
 		;; talking about YOU, Psalm 119.
 		(if bible-chapter-title 
 		    (bible--insert-title subnode) ; Middle of chapter.
-		  (save-excursion (goto-char (point-min)) (bible--insert-title subnode)))) ; Beginning of chapter.
+		  (save-excursion
+		    (goto-char (point-min))
+		    (bible--insert-title subnode)))) ; Beginning of chapter.
 	       ;; Font tag should be ignored, treat as if 'w
                ('font (insert " ") (bible--process-word subnode iproperties))
                ('hi (when (equal (dom-attr subnode 'type) "bold")
@@ -1258,20 +1308,7 @@ In processing subnodes, each case will prepend a space if it needs it."
                ;; 'q is used for red letter.
                ;; NASB Module uses 'seg to indicate OT quotations (and others?).
 	       ((or 'body 'seg 'p 'q) (bible--insert-domnode-recursive subnode iproperties))
-               ;; These tags appear in ESV modules (and maybe others?)
-               ;; REVIEW: Is this right? (FMG 5-Mar-2026)
-               ('l
-                (let ((attributes (dom-attributes subnode)))
-                  (cond ((equal (dom-attr subnode 'type) "x-br")
-                         (bible-new-line))
-                        ((equal (dom-attr subnode 'type) "x-indent")
-                         (insert "\t"))
-                        ((dom-attr subnode 'level)
-                         (let ((indent (string-to-number (alist-get 'level attributes))))
-			   ;; REVIEW: Some modules use `level' tag but
-			   ;; not in a consistent way. (FMG 7-Mar-2026)
-                           (cond ((= indent 1) (insert " "))
-                                 ((= indent 2) (bible-new-line) (insert "\t\t"))))))))
+               ('l (bible--level-tag subnode))
 	       ;; REVIEW: divine name handling doesn't seem to work the same
 	       ;;         with all modules.
 	       ('divinename (bible-handle-divine-name subnode))
@@ -1288,9 +1325,10 @@ In processing subnodes, each case will prepend a space if it needs it."
                   (let ((start (point)))
                     (insert " " word)
                     (let ((end (point)))
+		      (message "crossreferencing %s" (buffer-substring start end))
                       (put-text-property start end 'xref word)
-                      (put-text-property start end 'keymap bible-search-mode-map)
-                      (put-text-property start end 'help-echo (concat "Go to " word " (doesn't work yet)"))
+                      (put-text-property start end 'keymap bible-term-mode-map)
+                      (put-text-property start end 'help-echo (concat "Go to " word " (incomplete feature)"))
                       (add-face-text-property start end '(:foreground "blue"))))))
                ;; Various text properties---ignore for now
                ((or 'b 'u) (bible--insert-domnode-recursive subnode iproperties))
@@ -1303,7 +1341,8 @@ In processing subnodes, each case will prepend a space if it needs it."
                     (add-face-text-property (- (point) (length word)) (point) '(:foreground "gray50")))))))))))
 
 (defun bible--display (&optional module verse)
-  "Render a page of Bible text.
+  "Render a page (chapter) of a Bible module.
+Defaults to using `bible-module'.
 If optional argument MODULE is supplied, use that module for display.
 If optional argument VERSE is supplied, set cursor at verse."
   (when module (setq-local bible-module module))
@@ -1375,36 +1414,97 @@ If optional argument VERSE is supplied, set cursor at verse."
     (when verse
       (re-search-forward (concat " ?" (number-to-string verse)) nil t)))
 
-;;;; Modules (Bible texts)
+;;;; Modules (Bible texts, commentaries)
+
+(defun compare-module-names (n1 n2)
+  "Compare N1 and N2, ignoring case, using collation order."
+  (string-collate-lessp n1 n2 nil t))
+
+
+(defun bible--get-biblical-modules ()
+  "Populate `bible--texts' and `bible--commentaries' lists."
+  (let ((lines 
+	 (split-string
+	  (bible--exec-diatheke "modulelist" nil "plain" "system")
+	  "[\n\r]+"))
+	(texts nil)
+	(commentaries nil)
+	(doing-texts nil)
+	(doing-commentaries nil))
+    (setq bible--texts nil)
+    (setq bible--commentaries nil)
+    (catch 'done
+      (dolist (line lines)
+	(when doing-texts
+	  (push (split-string line " : ") texts))
+	(when doing-commentaries
+	  (push (split-string line " : ") commentaries))
+	(when (string-equal line "Biblical Texts:")
+	  (setq doing-texts t))
+	(when (string-equal line "Commentaries:")
+	  (setq doing-texts nil)
+	  (pop texts) ; Remove `Commentaries:' line from `bible--texts'.
+	  (setq doing-commentaries t))
+	(when (string-equal line "Lexicons / Dictionaries:")
+	  (pop commentaries) ; Remove `Lexicons / Dictionaries:' line
+			     ; from bible--commentaries.
+	  (throw 'done nil))))
+    (setq bible--texts (sort texts :key #'car :lessp #'compare-module-names))
+    (setq bible--commentaries (sort commentaries :key #'car :lessp #'compare-module-names)))
+  nil)
+
+
+
+(defun bible--list-biblical-texts ()
+  "Return a list of accessible Biblical Text modules."
+  (bible--get-biblical-modules) ; Make sure the lists are fresh.
+  bible--texts)
 
-(defun bible--list-biblical-modules ()
+(defun bible--list-biblical-commentaries ()
   "Return a list of accessible Biblical Text modules."
-  (let ((text (bible--exec-diatheke "modulelist" nil nil "system"))
-        modules)
-    (catch 'done
-      (dolist (line (split-string text "[\n\r]+"))
-        (when (equal line "Commentaries:")
-          (throw 'done nil))
-        (unless (equal "Biblical Texts:" line)
-          (push (split-string line " : ") modules))))
-    (reverse modules)))
+  (bible--get-biblical-modules) ; Make sure the lists are fresh.
+  bible--commentaries)
 
 (defconst bible-module-map (make-keymap))
 (define-key bible-module-map [mouse-1] 'bible-pick-module)
 (define-key bible-module-map (kbd "RET") 'bible-pick-module)
 
 
-(defun bible-display-available-modules ()
+(defun bible-display-available-texts ()
+  "Display available modules, allow user to select."
+  (interactive)
+  (bible--get-biblical-modules) ; Make sure lists are fresh.
+  (with-current-buffer (get-buffer-create "Texts")
+    (bible-module-select-mode)
+    (let ((buffer-read-only nil))
+      (erase-buffer)
+      (setq-local tab-stop-list '(25))
+      (dolist (text bible--texts)
+        (let ((name (string-trim (car text)))
+              (description (string-trim-left (cadr text))))
+          (insert
+           (propertize (string-trim name)
+                       'face 'bold
+                       'module name
+                       'help-echo (concat "Select " name)
+                       'keymap bible-module-map))
+          (move-to-tab-stop)
+          (insert (format "%s\n" description)))))
+    (goto-char (point-min))
+    (pop-to-buffer (current-buffer) nil t)))
+
+(defun bible-display-available-commentaries ()
   "Display available modules, allow user to select."
   (interactive)
-  (with-current-buffer (get-buffer-create "Modules")
+  (bible--get-biblical-modules) ; Make sure lists are fresh.
+  (with-current-buffer (get-buffer-create "Commentaries")
     (bible-module-select-mode)
     (let ((buffer-read-only nil))
       (erase-buffer)
       (setq-local tab-stop-list '(25))
-      (dolist (mod (bible--list-biblical-modules))
-        (let ((name (string-trim (car mod)))
-              (description (string-trim-left (cadr mod))))
+      (dolist (commentary bible--commentaries)
+        (let ((name (string-trim (car commentary)))
+              (description (string-trim-left (cadr commentary))))
           (insert
            (propertize (string-trim name)
                        'face 'bold
@@ -1460,7 +1560,7 @@ If optional argument VERSE is supplied, set cursor at verse."
              "III " "3"
              matchstr))))
          verses)))
-    (sort verses #'string-version-lessp)
+    (sort verses :in-place t :lessp #'string-version-lessp)
     (dolist (verse verses)
       (if query-verses
           (setq query-verses (concat query-verses ";" verse))
@@ -1471,8 +1571,9 @@ If optional argument VERSE is supplied, set cursor at verse."
       (erase-buffer)
       (bible--insert-domnode-recursive (dom-by-tag html-dom-tree 'body) nil))
     (goto-char (point-min))
+    ;; Remove module name from buffer.
     (save-excursion
-      (while (re-search-forward (concat "^.*" module) nil t)
+      (while (re-search-forward (concat "^.*" module ".*$") nil t)
         (replace-match ""))))
   (setq mode-name (concat "Bible Search (" module))
   (when bible-search-range