aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose A. Ortega Ruiz2022-09-30 15:08:40 +0200
committerLars Ingebrigtsen2022-09-30 15:08:40 +0200
commitb23e062d7463b76d25dfd9ba4a80c1848a448e42 (patch)
tree468460b2d0b64f07d5d835356e603792d6ac1b25
parent0332142e8e78b49b4f98438be21d2868e738986b (diff)
downloademacs-b23e062d7463b76d25dfd9ba4a80c1848a448e42.tar.gz
emacs-b23e062d7463b76d25dfd9ba4a80c1848a448e42.zip
docview: fixes for imenu generation
* lisp/doc-view.el: (doc-view--pdf-outline): (doc-view-imenu-index): (doc-view-imenu-setup): Fix multiple empty index generation for documents without an outline, caching the result (see discussion in bug#58103). (doc-view--imenu-subtree): Fix for nested imenus (bug introduced in commit fe002cc8ce) (bug#58180).
-rw-r--r--lisp/doc-view.el43
1 files changed, 25 insertions, 18 deletions
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 80c4fd21deb..b1ea90c212b 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1900,6 +1900,9 @@ If BACKWARD is non-nil, jump to the previous match."
1900(defconst doc-view--outline-rx 1900(defconst doc-view--outline-rx
1901 "[^\t]+\\(\t+\\)\"\\(.+\\)\"\t#\\(?:page=\\)?\\([0-9]+\\)") 1901 "[^\t]+\\(\t+\\)\"\\(.+\\)\"\t#\\(?:page=\\)?\\([0-9]+\\)")
1902 1902
1903(defvar-local doc-view--outline nil
1904 "Cached PDF outline, so that it is only computed once per document.")
1905
1903(defun doc-view--pdf-outline (&optional file-name) 1906(defun doc-view--pdf-outline (&optional file-name)
1904 "Return a list describing the outline of FILE-NAME. 1907 "Return a list describing the outline of FILE-NAME.
1905Return a list describing the current file if FILE-NAME is nil. 1908Return a list describing the current file if FILE-NAME is nil.
@@ -1907,19 +1910,20 @@ Return a list describing the current file if FILE-NAME is nil.
1907Each element in the returned list contains information about a section's 1910Each element in the returned list contains information about a section's
1908title, nesting level and page number. The list is flat: its tree 1911title, nesting level and page number. The list is flat: its tree
1909structure is extracted by `doc-view--imenu-subtree'." 1912structure is extracted by `doc-view--imenu-subtree'."
1910 (let* ((outline nil) 1913 (let ((fn (or file-name (buffer-file-name))))
1911 (fn (or file-name (buffer-file-name))) 1914 (when fn
1912 (fn (shell-quote-argument (expand-file-name fn)))) 1915 (let ((outline nil)
1913 (with-temp-buffer 1916 (fn (shell-quote-argument (expand-file-name fn))))
1914 (insert (shell-command-to-string (format "mutool show %s outline" fn))) 1917 (with-temp-buffer
1915 (goto-char (point-min)) 1918 (insert (shell-command-to-string (format "mutool show %s outline" fn)))
1916 (while (re-search-forward doc-view--outline-rx nil t) 1919 (goto-char (point-min))
1917 (push `((level . ,(length (match-string 1))) 1920 (while (re-search-forward doc-view--outline-rx nil t)
1918 (title . ,(replace-regexp-in-string "\\\\[rt]" " " 1921 (push `((level . ,(length (match-string 1)))
1919 (match-string 2))) 1922 (title . ,(replace-regexp-in-string "\\\\[rt]" " "
1920 (page . ,(string-to-number (match-string 3)))) 1923 (match-string 2)))
1921 outline))) 1924 (page . ,(string-to-number (match-string 3))))
1922 (nreverse outline))) 1925 outline)))
1926 (nreverse outline)))))
1923 1927
1924(defun doc-view--imenu-subtree (outline act) 1928(defun doc-view--imenu-subtree (outline act)
1925 "Construct a tree of imenu items for the given outline list and action. 1929 "Construct a tree of imenu items for the given outline list and action.
@@ -1932,7 +1936,8 @@ entries at an upper level."
1932 (nested (not doc-view-imenu-flatten)) 1936 (nested (not doc-view-imenu-flatten))
1933 (index nil)) 1937 (index nil))
1934 (while (and (car outline) 1938 (while (and (car outline)
1935 (or nested (<= level (alist-get 'level (car outline))))) 1939 (or (not nested)
1940 (<= level (alist-get 'level (car outline)))))
1936 (let-alist (car outline) 1941 (let-alist (car outline)
1937 (let ((title (format-spec doc-view-imenu-title-format 1942 (let ((title (format-spec doc-view-imenu-title-format
1938 `((?t . ,.title) (?p . ,.page))))) 1943 `((?t . ,.title) (?p . ,.page)))))
@@ -1953,16 +1958,18 @@ For extensibility, callers can specify a FILE-NAME to indicate
1953the buffer other than the current buffer, and a jumping function 1958the buffer other than the current buffer, and a jumping function
1954GOTO-PAGE-FN other than `doc-view-goto-page'." 1959GOTO-PAGE-FN other than `doc-view-goto-page'."
1955 (let* ((goto (or goto-page-fn 'doc-view-goto-page)) 1960 (let* ((goto (or goto-page-fn 'doc-view-goto-page))
1956 (act (lambda (_name _pos page) (funcall goto page)))) 1961 (act (lambda (_name _pos page) (funcall goto page)))
1957 (car (doc-view--imenu-subtree (doc-view--pdf-outline file-name) act)))) 1962 (outline (or doc-view--outline (doc-view--pdf-outline file-name))))
1963 (car (doc-view--imenu-subtree outline act))))
1958 1964
1959(defun doc-view-imenu-setup () 1965(defun doc-view-imenu-setup ()
1960 "Set up local state in the current buffer for imenu, if needed." 1966 "Set up local state in the current buffer for imenu, if needed."
1961 (when (and doc-view-imenu-enabled (executable-find "mutool")) 1967 (when (and doc-view-imenu-enabled (executable-find "mutool"))
1962 (setq-local imenu-create-index-function #'doc-view-imenu-index 1968 (setq-local imenu-create-index-function #'doc-view-imenu-index
1963 imenu-submenus-on-top nil 1969 imenu-submenus-on-top nil
1964 imenu-sort-function nil) 1970 imenu-sort-function nil
1965 (imenu-add-to-menubar "Outline"))) 1971 doc-view--outline (doc-view--pdf-outline))
1972 (when doc-view--outline (imenu-add-to-menubar "Outline"))))
1966 1973
1967;;;; User interface commands and the mode 1974;;;; User interface commands and the mode
1968 1975