A bunch of changes
This commit is contained in:
parent
2c08ad6436
commit
a6ba5e74a3
273
elisp/latex-help.el
Normal file
273
elisp/latex-help.el
Normal file
@ -0,0 +1,273 @@
|
||||
;;; latex-help.el --- Lookup LaTeX symbols -*- lexical-binding: t -*-
|
||||
|
||||
;;; Commentary:
|
||||
;; This is inspired by an old package (originally from the 90s!!) called
|
||||
;; ltx-help.el. This package used to be called latex-help.el too, but it seems
|
||||
;; to have had its name changed sometime around 2010. This package aims for
|
||||
;; similar functionality, but using more up to date and convention-conforming
|
||||
;; Elisp. For example, the original package still assumes that you may not have
|
||||
;; `add-hook' or `buffer-substring-no-properties'. Only very old versions of
|
||||
;; Emacs are missing these, so almost everyone has them nowadays.
|
||||
|
||||
;;; Code:
|
||||
(require 'info)
|
||||
|
||||
(defcustom latex-help-info-manual "latex2e"
|
||||
"The name of the info manual to use when looking up latex commands."
|
||||
:group 'latex-help
|
||||
:type '(choice
|
||||
(string :tag "English" "latex2e")
|
||||
(string :tag "French" "latex2e-fr")
|
||||
(string :tag "Spanish" "latex2e-es")))
|
||||
|
||||
(defcustom latex-help-buffer-name "*latex-help*"
|
||||
"The name of the info buffer to use when showing LaTeX documentation."
|
||||
:group 'latex-help
|
||||
:type 'string)
|
||||
|
||||
(defun latex-help--run-index-search (regexp)
|
||||
"Search the LaTeX info pages index for REGEXP.
|
||||
This returns a list of cache entries suitable for use in
|
||||
`latex-help--commands-cache'."
|
||||
(with-temp-buffer
|
||||
(Info-mode)
|
||||
(Info-find-node latex-help-info-manual "Index" nil t)
|
||||
(let ((found))
|
||||
(while (re-search-forward regexp nil t)
|
||||
(let ((match (match-string-no-properties 1))
|
||||
(node (match-string-no-properties 2)))
|
||||
(if (equal (caar found) match)
|
||||
(push (cons node (pos-bol)) (cdar found))
|
||||
(push (list match (cons node (pos-bol))) found))))
|
||||
found)))
|
||||
|
||||
(defvar latex-help--commands-cache nil
|
||||
"Cahce of discovered of LaTeX commands.
|
||||
These do NOT have a leading '\\'.")
|
||||
|
||||
(defun latex-help--discover-commands ()
|
||||
"Discover LaTeX commands.
|
||||
This is done by parsing the index for `latex-help-info-manual'."
|
||||
(let ((found (latex-help--run-index-search
|
||||
(rx (and bol "* \\"
|
||||
(group (or
|
||||
","
|
||||
(+ (not (any " " "{" ",")))))
|
||||
(*? any) ":" (+ " ")
|
||||
(group (+? any)) ".")))))
|
||||
(push (list "(SPACE)" "\\(SPACE)") found)
|
||||
(when-let (entry (assoc "(...\\)" found))
|
||||
(setq found (assoc-delete-all "(...\\)" found))
|
||||
(push (cons "(" (cdr entry)) found)
|
||||
(push (cons ")" (cdr entry)) found))
|
||||
(when-let (entry (assoc "[...\\]" found))
|
||||
(setq found (assoc-delete-all "[...\\]" found))
|
||||
(push (cons "[" (cdr entry)) found)
|
||||
(push (cons "]" (cdr entry)) found))
|
||||
found))
|
||||
|
||||
(defvar latex-help--package-cache nil
|
||||
"Cache of discovered LaTeX packages.")
|
||||
|
||||
(defun latex-help--discover-packages ()
|
||||
"Discover LaTeX packages.
|
||||
This is done by parsing the index for `latex-help-info-manual'."
|
||||
(latex-help--run-index-search (rx (and bol "* package, "
|
||||
(group (+? any))
|
||||
(any " " ":")
|
||||
(+? any) (+ " ")
|
||||
(group (+? any))
|
||||
"."))))
|
||||
|
||||
(defvar latex-help--environment-cache nil
|
||||
"Cache of discovered LaTeX environments.")
|
||||
|
||||
(defun latex-help--discover-environments ()
|
||||
"Discover LaTeX environments.
|
||||
This is done by parsing the index for `latex-help-info-manual'."
|
||||
(latex-help--run-index-search (rx (and bol "* environment, "
|
||||
(group (+? any))
|
||||
(any " " ":" "-")
|
||||
(+? any) (+ " ")
|
||||
(group (+? any))
|
||||
"."))))
|
||||
|
||||
(defvar latex-help--class-cache nil
|
||||
"Cache of discovered LaTeX document classes.")
|
||||
|
||||
(defun latex-help--discover-classes ()
|
||||
"Discover LaTeX document classes.
|
||||
This is done by parsing the index for `latex-help-info-manual'."
|
||||
(latex-help--run-index-search (rx (and bol "* "
|
||||
(group (+ (not (any "," " "))))
|
||||
" class:" (+ " ")
|
||||
(group (+ (not ".")))))))
|
||||
|
||||
(defun latex-help--goto-entry (entry)
|
||||
"Open the info page for ENTRY, a cache entry."
|
||||
(let ((buffer (get-buffer-create latex-help-buffer-name)))
|
||||
(with-current-buffer buffer
|
||||
(unless (derived-mode-p 'Info-mode)
|
||||
(Info-mode))
|
||||
(Info-find-node latex-help-info-manual "Index" nil t)
|
||||
(goto-char (cdr entry))
|
||||
(Info-follow-nearest-node))
|
||||
(pop-to-buffer buffer)))
|
||||
|
||||
(defvar latex-help--caches-initialized-p nil
|
||||
"Non-nil if the latex-help caches have been initialized.")
|
||||
|
||||
(defun latex-help--get-cache-for-type (type)
|
||||
"Lookup the cache for TYPE.
|
||||
If the caches are not yet initialized, do that first."
|
||||
(unless latex-help--caches-initialized-p
|
||||
(setq latex-help--commands-cache (latex-help--discover-commands)
|
||||
latex-help--package-cache (latex-help--discover-packages)
|
||||
latex-help--environment-cache (latex-help--discover-environments)
|
||||
latex-help--class-cache (latex-help--discover-classes)
|
||||
latex-help--caches-initialized-p t))
|
||||
(cond
|
||||
((eq type 'command)
|
||||
latex-help--commands-cache)
|
||||
((eq type 'package)
|
||||
latex-help--package-cache)
|
||||
((eq type 'environment)
|
||||
latex-help--environment-cache)
|
||||
((eq type 'class)
|
||||
latex-help--class-cache)))
|
||||
|
||||
(defun latex-help--history nil
|
||||
"History list for `latex-help--maybe-prompt-entry'.")
|
||||
|
||||
(defun latex-help--maybe-prompt-entry (name type &optional default)
|
||||
"Lookup and prompt the user for the node of NAME.
|
||||
The lookup is performed in the correct cache for TYPE. If there is only one
|
||||
node associated with NAME, return its entry. Otherwise, ask the user which node
|
||||
they want to use.
|
||||
|
||||
If DEFAULT is non-nil, use that instead of prompting. If it does not exist,
|
||||
return nil."
|
||||
(when-let (entries (alist-get name (latex-help--get-cache-for-type type)
|
||||
nil nil 'equal))
|
||||
(cond
|
||||
(default
|
||||
(assoc default entries))
|
||||
((length= entries 1)
|
||||
(car entries))
|
||||
(t
|
||||
(let ((resp (completing-read "Select Node: " (mapcar 'car entries)
|
||||
nil t nil)))
|
||||
(assoc resp entries))))))
|
||||
|
||||
(defun latex-help--get-thing-at-point ()
|
||||
"Return a cons of the LaTeX thing at point and its type (as a symbol).
|
||||
If nothing is found, return nil.
|
||||
The following types are known:
|
||||
- command
|
||||
- package
|
||||
- environment
|
||||
- class
|
||||
|
||||
The following are some examples:
|
||||
- \\textbf{Hello World} -> \\='(\"textbf\" . command)
|
||||
- \\begin{math} (on \"math\") -> \\='(\"math\" . environment)
|
||||
- \\begin{math} (on \"begin\") -> \\='(\"begin\" . command)
|
||||
- \\usepackage{amsmath} (on \"amsmath\") -> \\='(\"amsmath\" . package)
|
||||
- \\usepackage{amsmath} (on \"usepackage\") -> \\='(\"usepackage\" . command)"
|
||||
(save-excursion
|
||||
(let ((orig-point (point)))
|
||||
(when (eq (char-after) ?\\)
|
||||
(forward-char))
|
||||
(when (and (search-backward "\\" nil t)
|
||||
(looking-at (rx "\\"
|
||||
(group (+ (not (any " " "\n" "("
|
||||
"{" "[" "|"
|
||||
"}" "]" ")")))))))
|
||||
(let ((cmd (match-string-no-properties 1)))
|
||||
(if (> (match-end 1) orig-point)
|
||||
(cons cmd 'command)
|
||||
(goto-char orig-point)
|
||||
(condition-case _
|
||||
(progn
|
||||
(backward-up-list nil t t)
|
||||
(when (looking-at (rx "{" (group (+ (not (any "}" "\n"))))))
|
||||
(let ((thing (match-string-no-properties 1)))
|
||||
(cond
|
||||
((equal cmd "usepackage")
|
||||
(cons thing 'package))
|
||||
((or (equal cmd "begin")
|
||||
(equal cmd "end"))
|
||||
(cons thing 'environment))
|
||||
((equal cmd "documentclass")
|
||||
(cons thing 'class))))))
|
||||
;; just return nil
|
||||
((or user-error scan-error)))))))))
|
||||
|
||||
(defun latex-help--prompt-for (type)
|
||||
"Prompt for a command, environment, etc. from TYPE.
|
||||
This returns the name of the thing that was prompted."
|
||||
(let* ((cache (latex-help--get-cache-for-type type))
|
||||
(tap (latex-help--get-thing-at-point))
|
||||
(default (and (eq (cdr tap) type) (car tap))))
|
||||
(unless (assoc default cache)
|
||||
(setq default nil))
|
||||
(completing-read (format "LaTeX %s%s: "
|
||||
(capitalize (symbol-name type))
|
||||
(if default
|
||||
(format " (default %s)" default)
|
||||
""))
|
||||
(latex-help--get-cache-for-type type)
|
||||
nil t nil 'latex-help--history
|
||||
default)))
|
||||
|
||||
(defun latex-help-command (name &optional node)
|
||||
"Lookup the LaTeX command NAME.
|
||||
Unless NODE is non-nil, if NAME is in more than one node, prompt the user for
|
||||
which to use. If NODE is non-nil, use that instead."
|
||||
(interactive (list (latex-help--prompt-for 'command)))
|
||||
(when-let (entry (latex-help--maybe-prompt-entry name 'command node))
|
||||
(latex-help--goto-entry entry)))
|
||||
|
||||
(defun latex-help-environment (name &optional node)
|
||||
"Lookup the LaTeX environment NAME.
|
||||
Unless NODE is non-nil, if NAME is in more than one node, prompt the user for
|
||||
which to use. If NODE is non-nil, use that instead."
|
||||
(interactive (list (latex-help--prompt-for 'environment)))
|
||||
(when-let (entry (latex-help--maybe-prompt-entry name 'environment node))
|
||||
(latex-help--goto-entry entry)))
|
||||
|
||||
(defun latex-help-package (name &optional node)
|
||||
"Lookup the LaTeX package NAME.
|
||||
Unless NODE is non-nil, if NAME is in more than one node, prompt the user for
|
||||
which to use. If NODE is non-nil, use that instead."
|
||||
(interactive (list (latex-help--prompt-for 'package)))
|
||||
(when-let (entry (latex-help--maybe-prompt-entry name 'package node))
|
||||
(latex-help--goto-entry entry)))
|
||||
|
||||
(defun latex-help-class (name &optional node)
|
||||
"Lookup the LaTeX document class NAME.
|
||||
Unless NODE is non-nil, if NAME is in more than one node, prompt the user for
|
||||
which to use. If NODE is non-nil, use that instead."
|
||||
(interactive (list (latex-help--prompt-for 'class)))
|
||||
(when-let (entry (latex-help--maybe-prompt-entry name 'class node))
|
||||
(latex-help--goto-entry entry)))
|
||||
|
||||
(defun latex-help-at-point ()
|
||||
"Try to lookup the LaTeX thing at point, whatever it may be.
|
||||
This will try to look up the command, package, document class, or environment at
|
||||
point. If that thing at point is valid, it will open an info buffer to the
|
||||
documentation for that thing."
|
||||
(interactive)
|
||||
(if-let (thing (latex-help--get-thing-at-point))
|
||||
(if-let (entry (latex-help--maybe-prompt-entry (car thing)
|
||||
(cdr thing)))
|
||||
(latex-help--goto-entry entry)
|
||||
(user-error "Unknown %s: \"%s\""
|
||||
(symbol-name (cdr thing))
|
||||
(if (eq (cdr thing) 'command)
|
||||
(concat "\\" (car thing))
|
||||
(car thing))))
|
||||
(user-error "Nothing at point to look up")))
|
||||
|
||||
(provide 'latex-help)
|
||||
;;; latex-help.el ends here
|
93
init.el
93
init.el
@ -215,7 +215,8 @@ BUFFER can be a string or a buffer."
|
||||
((stringp buffer)
|
||||
(not (string-prefix-p " " buffer)))
|
||||
((bufferp buffer)
|
||||
(my/buffer-visible-p (buffer-name buffer)))
|
||||
(and (stringp (buffer-name buffer))
|
||||
(my/buffer-visible-p (buffer-name buffer))))
|
||||
(t
|
||||
(signal 'wrong-type-argument `((or bufferp stringp) ,buffer)))))
|
||||
|
||||
@ -378,7 +379,8 @@ directory. Otherwise, run `find-file' on that file."
|
||||
:hook (undo-tree-visualizer-mode . my/-undo-tree-visualizer-mode-setup)
|
||||
:config
|
||||
(defun my/-undo-tree-visualizer-mode-setup ()
|
||||
(visual-line-mode -1))
|
||||
(visual-line-mode -1)
|
||||
(setq truncate-lines t))
|
||||
(global-undo-tree-mode))
|
||||
|
||||
;; evil
|
||||
@ -722,11 +724,21 @@ to `posframe-show' if the display is graphical."
|
||||
:init
|
||||
(defun my/flymake-show-diagnostic-at-point ()
|
||||
(interactive)
|
||||
(if-let ((pos (point))
|
||||
(diag (and flymake-mode
|
||||
(get-char-property pos 'flymake-diagnostic)))
|
||||
(message (flymake--diag-text diag)))
|
||||
(my/floating-tooltip " *flymake-error-posframe*" message))))
|
||||
(when flymake-mode
|
||||
(let* ((diag (get-char-property (point) 'flymake-diagnostic))
|
||||
(diag-msg (when diag
|
||||
(apply 'concat
|
||||
(mapcar
|
||||
(lambda (msg)
|
||||
(concat "•" msg "\n"))
|
||||
(split-string (flymake--diag-text diag)
|
||||
"\n")))))
|
||||
(jinx-msg (when (jinx--get-overlays (point) (1+ (point)))
|
||||
"•misspelled word\n")))
|
||||
(unless (and (zerop (length diag-msg))
|
||||
(zerop (length jinx-msg)))
|
||||
(my/floating-tooltip " *flymake-error-posframe*"
|
||||
(concat diag-msg jinx-msg)))))))
|
||||
|
||||
;; flycheck
|
||||
(use-package flycheck
|
||||
@ -740,12 +752,15 @@ to `posframe-show' if the display is graphical."
|
||||
(defun my/flycheck-show-diagnostic-at-point ()
|
||||
(interactive)
|
||||
(if-let ((flycheck-mode)
|
||||
(errors (flycheck-overlay-errors-at (point)))
|
||||
(message (apply 'concat
|
||||
(mapcar
|
||||
(lambda (error)
|
||||
(concat "•" (flycheck-error-message error) "\n"))
|
||||
errors))))
|
||||
(message
|
||||
(apply 'concat
|
||||
(nconc (mapcar
|
||||
(lambda (error)
|
||||
(concat "•" (flycheck-error-message error) "\n"))
|
||||
(flycheck-overlay-errors-at (point)))
|
||||
(when (jinx--get-overlays (point) (1+ (point)))
|
||||
'("•misspelled word\n")))))
|
||||
((not (zerop (length message)))))
|
||||
(my/floating-tooltip " *flycheck-error-posframe*"
|
||||
(substring message 0 (1- (length message)))))))
|
||||
(use-package consult-flycheck
|
||||
@ -1019,7 +1034,7 @@ When EXCLUDE-BRACES is non-nil, don't count the first and last brace of the
|
||||
entry as in the entry. That is, if the point is on the first { or last } of the
|
||||
entry, return nil."
|
||||
(save-excursion
|
||||
(when (and exclude-braces (= ?\} (char-after)))
|
||||
(when (and exclude-braces (eq ?\} (char-after)))
|
||||
(forward-char))
|
||||
;; go to top level and check if the character at point is {
|
||||
(let ((start-pos (point))
|
||||
@ -1030,7 +1045,7 @@ entry, return nil."
|
||||
(setq last-valid (point)))
|
||||
(error
|
||||
(and
|
||||
(= ?\{ (char-after last-valid))
|
||||
(eq ?\{ (char-after last-valid))
|
||||
(or (not exclude-braces)
|
||||
(not (= start-pos last-valid)))))))))
|
||||
(defvar my/bibtex-indent-width 4
|
||||
@ -1082,10 +1097,14 @@ otherwise, call `bibtex-find-text'."
|
||||
(evil-define-key 'normal bibtex-mode-map
|
||||
(kbd "TAB") 'my/bibtex-indent-or-find-text-and-insert)
|
||||
|
||||
;; Latex help (from elisp file)
|
||||
(require 'latex-help)
|
||||
|
||||
;; AUCTeX
|
||||
(use-package auctex
|
||||
:hook ((LaTeX-mode . turn-on-reftex)
|
||||
(LaTeX-mode . LaTeX-math-mode))
|
||||
(LaTeX-mode . LaTeX-math-mode)
|
||||
(LaTeX-mode . my/-setup-LaTeX-mode))
|
||||
:init
|
||||
(add-to-list 'major-mode-remap-alist '(plain-tex-mode . plain-TeX-mode))
|
||||
(add-to-list 'major-mode-remap-alist '(latex-mode . LaTeX-mode))
|
||||
@ -1095,6 +1114,8 @@ otherwise, call `bibtex-find-text'."
|
||||
(add-to-list 'major-mode-remap-alist '(doctex-mode . docTeX-mode))
|
||||
(add-to-list 'auto-mode-alist '("/\\.latexmkrc\\'" . perl-mode))
|
||||
:config
|
||||
(defun my/-setup-LaTeX-mode ()
|
||||
(setq evil-lookup-func 'latex-help-at-point))
|
||||
(setq TeX-auto-save t
|
||||
TeX-parse-self t
|
||||
reftex-plug-into-AUCTeX t)
|
||||
@ -1419,7 +1440,7 @@ argument."
|
||||
(funcall-interactively #'sage-shell:run-sage
|
||||
(sage-shell:read-command)))))
|
||||
|
||||
;; fricas (because I like calculator)
|
||||
;; fricas (because I like calculators)
|
||||
(add-to-list 'load-path "/usr/lib/fricas/emacs/")
|
||||
(use-package fricas
|
||||
:ensure nil
|
||||
@ -1762,10 +1783,14 @@ If no name is given, list all bookmarks instead."
|
||||
(setq-local evil-lookup-func #'helpful-at-point))
|
||||
(defun my/-setup-helpful-mode ()
|
||||
(setq-local evil-lookup-func #'helpful-at-point))
|
||||
(defvar my/helpful-symbol-history-size 20
|
||||
(defvar my/helpful-symbol-history-size 50
|
||||
"Max size of `my/helpful-symbol-history'.")
|
||||
(defvar my/helpful-symbol-history '()
|
||||
"History of helpful symbols.")
|
||||
(defvar my/-helpful-inhibit-history nil
|
||||
"If non-nil, don't add symbols to `my/helpful-symbol-history'.")
|
||||
(defvar my/-helpful-last-entry nil
|
||||
"Last entry looked up with helpful.")
|
||||
(defun my/helpful-history-back (count)
|
||||
"Go back COUNT symbols in `my/helpful-symbol-history'. If called
|
||||
interactively, COUNT defaults to 1."
|
||||
@ -1791,7 +1816,8 @@ the oldest entry if -COUNT is larger than the history."
|
||||
((and (< count 0) (= (1+ current-pos) hist-len))
|
||||
(message "%s" "No older symbol!"))
|
||||
(t
|
||||
(let ((entry (cond
|
||||
(let ((my/-helpful-inhibit-history t)
|
||||
(entry (cond
|
||||
((<= new-pos 0)
|
||||
(seq-first my/helpful-symbol-history))
|
||||
((>= new-pos hist-len)
|
||||
@ -1804,29 +1830,29 @@ the oldest entry if -COUNT is larger than the history."
|
||||
(defun my/-helpful-switch-buffer-function (helpful-buf)
|
||||
"Like `pop-to-buffer', but kill previous helpful buffers and save the new
|
||||
buffers `helpful--sym' to `my/helpful-symbol-history'."
|
||||
(cl-loop for buf in (buffer-list)
|
||||
with window = nil
|
||||
with last-index = nil
|
||||
(cl-loop with window = nil
|
||||
for buf in (buffer-list)
|
||||
when (and
|
||||
(not (eq buf helpful-buf))
|
||||
(eq (buffer-local-value 'major-mode buf) 'helpful-mode))
|
||||
do
|
||||
(when-let (cur-window (get-buffer-window buf nil))
|
||||
(setq window cur-window))
|
||||
(when-let (entry (buffer-local-value 'helpful--sym buf))
|
||||
(setq last-index (seq-position my/helpful-symbol-history entry 'equal)))
|
||||
(kill-buffer buf)
|
||||
finally
|
||||
(when-let ((entry (cons (buffer-local-value 'helpful--sym helpful-buf)
|
||||
(buffer-local-value 'helpful--callable-p
|
||||
helpful-buf)))
|
||||
((not (seq-contains-p my/helpful-symbol-history entry
|
||||
'equal))))
|
||||
(when last-index
|
||||
(let ((entry (cons (buffer-local-value 'helpful--sym helpful-buf)
|
||||
(buffer-local-value 'helpful--callable-p
|
||||
helpful-buf))))
|
||||
(unless my/-helpful-inhibit-history
|
||||
(when-let (from-current-hist
|
||||
(member my/-helpful-last-entry
|
||||
my/helpful-symbol-history))
|
||||
(setq my/helpful-symbol-history from-current-hist))
|
||||
(cl-pushnew entry my/helpful-symbol-history :test 'equal)
|
||||
(setq my/helpful-symbol-history
|
||||
(seq-drop my/helpful-symbol-history last-index)))
|
||||
(push entry my/helpful-symbol-history)
|
||||
(seq-take my/helpful-symbol-history my/helpful-symbol-history-size))
|
||||
(seq-take my/helpful-symbol-history
|
||||
my/helpful-symbol-history-size)))
|
||||
(setq my/-helpful-last-entry entry))
|
||||
(if window
|
||||
(window--display-buffer helpful-buf window 'reuse)
|
||||
(pop-to-buffer helpful-buf))))
|
||||
@ -1957,7 +1983,6 @@ one of the normal rainbow-delimiters-depth-N-face faces."
|
||||
|
||||
;; page break lines
|
||||
(use-package page-break-lines
|
||||
:hook (helpful-mode . page-break-lines-mode)
|
||||
:config
|
||||
(global-page-break-lines-mode 1)
|
||||
(add-to-list 'page-break-lines-modes 'prog-mode)
|
||||
|
Loading…
Reference in New Issue
Block a user