From dae7521ccf53e68a370d4051d6909d38d4ac2ad0 Mon Sep 17 00:00:00 2001 From: BardofSprites <89086143+BardofSprites@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:18:44 -0500 Subject: enhanced LaTeX editing --- bard-elisp/bard-writing.el | 23 ++++++++- bard-emacs-modules/bard-emacs-org.el | 4 +- bard-emacs-modules/bard-emacs-writing.el | 54 ++++++++++++++++++++- config.org | 81 ++++++++++++++++++++++++++++++-- 4 files changed, 156 insertions(+), 6 deletions(-) diff --git a/bard-elisp/bard-writing.el b/bard-elisp/bard-writing.el index 2ba5a6e..fcf2762 100644 --- a/bard-elisp/bard-writing.el +++ b/bard-elisp/bard-writing.el @@ -124,6 +124,27 @@ (org-fragtog-mode t) (org-cdlatex-mode t) (electric-pair-local-mode t) - (bard/cdlatex-add-math-symbols)) + (bard/cdlatex-add-math-symbols) + ;; sending math to calc from latex doc + (define-key org-mode-map (kbd "C-S-e") #'latex-math-from-calc)) + +;; latex into calc +(defun latex-math-from-calc () + "Evaluate `calc' on the contents of line at point." + (interactive) + (cond ((region-active-p) + (let* ((beg (region-beginning)) + (end (region-end)) + (string (buffer-substring-no-properties beg end))) + (kill-region beg end) + (insert (calc-eval `(,string calc-language latex + calc-prefer-frac t + calc-angle-mode rad))))) + (t (let ((l (thing-at-point 'line))) + (end-of-line 1) (kill-line 0) + (insert (calc-eval `(,l + calc-language latex + calc-prefer-frac t + calc-angle-mode rad))))))) (provide 'bard-writing) diff --git a/bard-emacs-modules/bard-emacs-org.el b/bard-emacs-modules/bard-emacs-org.el index 976e106..a34a917 100644 --- a/bard-emacs-modules/bard-emacs-org.el +++ b/bard-emacs-modules/bard-emacs-org.el @@ -77,7 +77,9 @@ (use-package cdlatex :ensure t - ) + :hook (LaTeX-mode . turn-on-cdlatex) + :bind (:map cdlatex-mode-map + ("" . cdlatex-tab))) ;; latex editing niceness (use-package org-fragtog diff --git a/bard-emacs-modules/bard-emacs-writing.el b/bard-emacs-modules/bard-emacs-writing.el index 317dd42..1daed2a 100644 --- a/bard-emacs-modules/bard-emacs-writing.el +++ b/bard-emacs-modules/bard-emacs-writing.el @@ -29,10 +29,25 @@ (use-package yasnippet :ensure t + :hook ((LaTeX-mode . yas-minor-mode) + (post-self-insert . my/yas-try-expanding-auto-snippets)) :config (setq yas-snippet-dirs '("~/.emacs.d/snippets")) (yas-global-mode t) - ) + (use-package warnings + :config + (cl-pushnew '(yasnippet backquote-change) + warning-suppress-types + :test 'equal)) + + (setq yas-triggers-in-field t) + + ;; Function that tries to autoexpand YaSnippets + ;; The double quoting is NOT a typo! + (defun my/yas-try-expanding-auto-snippets () + (when (and (boundp 'yas-minor-mode) yas-minor-mode) + (let ((yas-buffer-local-condition ''(require-snippet-condition . auto))) + (yas-expand))))) (use-package yasnippet-capf :ensure t @@ -40,6 +55,43 @@ :config (add-to-list 'completion-at-point-functions #'yasnippet-capf)) +(use-package cdlatex + :hook ((cdlatex-tab . yas-expand) + (cdlatex-tab . cdlatex-in-yas-field)) + :config + (use-package yasnippet + :bind (:map yas-keymap + ("" . yas-next-field-or-cdlatex) + ("TAB" . yas-next-field-or-cdlatex)) + :config + (defun cdlatex-in-yas-field () + ;; Check if we're at the end of the Yas field + (when-let* ((_ (overlayp yas--active-field-overlay)) + (end (overlay-end yas--active-field-overlay))) + (if (>= (point) end) + ;; Call yas-next-field if cdlatex can't expand here + (let ((s (thing-at-point 'sexp))) + (unless (and s (assoc (substring-no-properties s) + cdlatex-command-alist-comb)) + (yas-next-field-or-maybe-expand) + t)) + ;; otherwise expand and jump to the correct location + (let (cdlatex-tab-hook minp) + (setq minp + (min (save-excursion (cdlatex-tab) + (point)) + (overlay-end yas--active-field-overlay))) + (goto-char minp) t)))) + + (defun yas-next-field-or-cdlatex nil + (interactive) + "Jump to the next Yas field correctly with cdlatex active." + (if + (or (bound-and-true-p cdlatex-mode) + (bound-and-true-p org-cdlatex-mode)) + (cdlatex-tab) + (yas-next-field-or-maybe-expand))))) + (use-package denote :ensure t :config diff --git a/config.org b/config.org index 93e6cdf..de73227 100644 --- a/config.org +++ b/config.org @@ -1370,7 +1370,9 @@ For a long time I really struggled with Emacs tab completion. It still only kind (use-package cdlatex :ensure t - ) + :hook (LaTeX-mode . turn-on-cdlatex) + :bind (:map cdlatex-mode-map + ("" . cdlatex-tab))) ;; latex editing niceness (use-package org-fragtog @@ -2108,16 +2110,68 @@ Watch [[https://protesilaos.com/codelog/2024-02-08-emacs-window-rules-display-bu #+begin_src emacs-lisp :tangle bard-emacs-modules/bard-emacs-writing.el :mkdirp yes (use-package yasnippet :ensure t + :hook ((LaTeX-mode . yas-minor-mode) + (post-self-insert . my/yas-try-expanding-auto-snippets)) :config (setq yas-snippet-dirs '("~/.emacs.d/snippets")) (yas-global-mode t) - ) + (use-package warnings + :config + (cl-pushnew '(yasnippet backquote-change) + warning-suppress-types + :test 'equal)) + + (setq yas-triggers-in-field t) + + ;; Function that tries to autoexpand YaSnippets + ;; The double quoting is NOT a typo! + (defun my/yas-try-expanding-auto-snippets () + (when (and (boundp 'yas-minor-mode) yas-minor-mode) + (let ((yas-buffer-local-condition ''(require-snippet-condition . auto))) + (yas-expand))))) (use-package yasnippet-capf :ensure t :after cape :config (add-to-list 'completion-at-point-functions #'yasnippet-capf)) + + (use-package cdlatex + :hook ((cdlatex-tab . yas-expand) + (cdlatex-tab . cdlatex-in-yas-field)) + :config + (use-package yasnippet + :bind (:map yas-keymap + ("" . yas-next-field-or-cdlatex) + ("TAB" . yas-next-field-or-cdlatex)) + :config + (defun cdlatex-in-yas-field () + ;; Check if we're at the end of the Yas field + (when-let* ((_ (overlayp yas--active-field-overlay)) + (end (overlay-end yas--active-field-overlay))) + (if (>= (point) end) + ;; Call yas-next-field if cdlatex can't expand here + (let ((s (thing-at-point 'sexp))) + (unless (and s (assoc (substring-no-properties s) + cdlatex-command-alist-comb)) + (yas-next-field-or-maybe-expand) + t)) + ;; otherwise expand and jump to the correct location + (let (cdlatex-tab-hook minp) + (setq minp + (min (save-excursion (cdlatex-tab) + (point)) + (overlay-end yas--active-field-overlay))) + (goto-char minp) t)))) + + (defun yas-next-field-or-cdlatex nil + (interactive) + "Jump to the next Yas field correctly with cdlatex active." + (if + (or (bound-and-true-p cdlatex-mode) + (bound-and-true-p org-cdlatex-mode)) + (cdlatex-tab) + (yas-next-field-or-maybe-expand))))) #+end_src *** Denote Note taking @@ -4340,7 +4394,28 @@ I want to have a custom format for my daily journal file to start what I want to (org-fragtog-mode t) (org-cdlatex-mode t) (electric-pair-local-mode t) - (bard/cdlatex-add-math-symbols)) + (bard/cdlatex-add-math-symbols) + ;; sending math to calc from latex doc + (define-key org-mode-map (kbd "C-S-e") #'latex-math-from-calc)) + + ;; latex into calc + (defun latex-math-from-calc () + "Evaluate `calc' on the contents of line at point." + (interactive) + (cond ((region-active-p) + (let* ((beg (region-beginning)) + (end (region-end)) + (string (buffer-substring-no-properties beg end))) + (kill-region beg end) + (insert (calc-eval `(,string calc-language latex + calc-prefer-frac t + calc-angle-mode rad))))) + (t (let ((l (thing-at-point 'line))) + (end-of-line 1) (kill-line 0) + (insert (calc-eval `(,l + calc-language latex + calc-prefer-frac t + calc-angle-mode rad))))))) #+end_src *** Provide library -- cgit v1.2.3