mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-11-29 19:46:17 +01:00
168 lines
5.1 KiB
Org Mode
168 lines
5.1 KiB
Org Mode
|
:PROPERTIES:
|
||
|
:ID: a0514202-b2ef-41a4-9d77-01efaa7e8d64
|
||
|
:END:
|
||
|
#+title: Tempel
|
||
|
#+filetags: emacs-load
|
||
|
|
||
|
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
|
||
|
#
|
||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||
|
|
||
|
#+begin_quote
|
||
|
Tempel is a tiny template package for Emacs, which uses the syntax of the Emacs Tempo library. Tempo is an ancient
|
||
|
temple of the church of Emacs. It is 27 years old, but still in good shape since it successfully resisted change over
|
||
|
the decades. However it may look a bit dusty here and there. Therefore we present to you, Tempel, a modernized
|
||
|
implementation of Tempo, in the form of three commands.
|
||
|
#+end_quote
|
||
|
|
||
|
#+begin_src emacs-lisp :noweb yes
|
||
|
(use-package tempel
|
||
|
:straight '(tempel :type git :host github :repo "minad/tempel")
|
||
|
:config
|
||
|
<<tempel-path>>
|
||
|
:init
|
||
|
<<tempel-hooks>>
|
||
|
<<tempel-keymaps>>)
|
||
|
#+END_SRC
|
||
|
|
||
|
Set the template file to the result of tangling [[id:3e8f0e02-dbfe-4f34-9b00-8b7ecd0a238d][Tempel - Templates]].
|
||
|
|
||
|
#+name: tempel-path
|
||
|
#+begin_src emacs-lisp
|
||
|
(setq tempel-path (expand-file-name "~/roam/emacs-lisp/templates.lisp"))
|
||
|
#+end_src
|
||
|
|
||
|
Hook ~tempel-capf~ on both ~prog-mode~ and ~text-mode~.
|
||
|
|
||
|
#+name: tempel-hooks
|
||
|
#+begin_src emacs-lisp
|
||
|
(defun tempel-setup-capf ()
|
||
|
(add-hook 'completion-at-point-functions #'tempel-complete -100 'local))
|
||
|
|
||
|
(add-hook 'prog-mode-hook 'tempel-setup-capf)
|
||
|
(add-hook 'text-mode-hook 'tempel-setup-capf)
|
||
|
(add-hook 'lsp-mode-hook 'tempel-setup-capf)
|
||
|
#+end_src
|
||
|
|
||
|
Define keymaps, the defaults are unnecessarily hard to trigger.
|
||
|
|
||
|
#+name: tempel-keymaps
|
||
|
#+begin_src emacs-lisp
|
||
|
(general-define-key
|
||
|
:keymaps '(insert normal)
|
||
|
"C-n" 'nil
|
||
|
"C-p" 'nil)
|
||
|
(general-define-key
|
||
|
:keymaps 'tempel-map
|
||
|
"M-{" nil
|
||
|
"M-}" nil
|
||
|
"C-n" 'tempel-next
|
||
|
"C-p" 'tempel-previous)
|
||
|
#+end_src
|
||
|
|
||
|
Fix LSP not getting notified about changes, can be fixed by notifying it at the end of template expansion.
|
||
|
|
||
|
#+begin_src emacs-lisp
|
||
|
(advice-add
|
||
|
'tempel--disable
|
||
|
:before
|
||
|
(lambda (&rest r)
|
||
|
(when lsp-mode
|
||
|
(let* ((region-start (tempel--beginning))
|
||
|
(region-end (tempel--end)))
|
||
|
(lsp-on-change region-start region-end (- region-end region-start))))))
|
||
|
#+end_src
|
||
|
|
||
|
To setup a post template return point, use ~(tempel-retpoint-here)~ in a template.
|
||
|
|
||
|
#+begin_src emacs-lisp
|
||
|
(defun org-edit-special-latex-preview (&rest _)
|
||
|
(let ((datum (org-element-context)))
|
||
|
(when (and (memq (org-element-type datum) '(latex-environment latex-fragment))
|
||
|
(let ((beg (org-element-property :begin datum))
|
||
|
(end (org-element-property :end datum)))
|
||
|
(when (org-clear-latex-preview beg end)
|
||
|
(setq-local tempel-latex-preview t)))))))
|
||
|
|
||
|
(advice-add
|
||
|
'org-edit-special
|
||
|
:before
|
||
|
#'org-edit-special-latex-preview)
|
||
|
#+end_src
|
||
|
|
||
|
#+begin_src emacs-lisp
|
||
|
(defvar-local tempel-retpoint (make-marker))
|
||
|
(defvar-local tempel-latex-preview nil)
|
||
|
|
||
|
(defun tempel-retpoint-here ()
|
||
|
"Place a marker at `point' to allow for return on tempel exit."
|
||
|
(set-marker tempel-retpoint (point))
|
||
|
"")
|
||
|
|
||
|
(defun tempel-retpoint-goto ()
|
||
|
"Move `point' to `tempel-retpoint'."
|
||
|
(when (marker-position tempel-retpoint)
|
||
|
(goto-char (marker-position tempel-retpoint))
|
||
|
(set-marker tempel-retpoint nil)))
|
||
|
|
||
|
(add-hook
|
||
|
'tempel--disable
|
||
|
#'tempel-retpoint-goto)
|
||
|
|
||
|
(defvar org-src-mode-exit-hook nil)
|
||
|
|
||
|
(defun org-edit-src-exit-run-hooks (&rest _)
|
||
|
"Run hooks from `org-edit-src-exit-hook' upon exiting org-src edit buffer."
|
||
|
(run-hooks 'org-src-mode-exit-hook))
|
||
|
|
||
|
(advice-add
|
||
|
'org-edit-src-exit
|
||
|
:after
|
||
|
#'org-edit-src-exit-run-hooks)
|
||
|
|
||
|
(defun org-edit-src-exit-tempel-retpoint ()
|
||
|
"Return to `tempel-retpoint' if set."
|
||
|
(tempel-retpoint-goto))
|
||
|
|
||
|
(defun org-edit-src-exit-tempel-latex-preview ()
|
||
|
"Toggle LaTeX preview of templated LaTeX fragment."
|
||
|
(when tempel-latex-preview
|
||
|
(org-latex-preview)
|
||
|
(setq-local tempel-latex-preview nil)))
|
||
|
|
||
|
(add-hook
|
||
|
'org-src-mode-exit-hook
|
||
|
#'org-edit-src-exit-tempel-latex-preview)
|
||
|
|
||
|
(add-hook
|
||
|
'org-src-mode-exit-hook
|
||
|
#'org-edit-src-exit-tempel-retpoint)
|
||
|
|
||
|
(defun tempel-post-edit-latex (&optional preview move-back)
|
||
|
"Move `point' back and run `org-edit-special'.
|
||
|
If PREVIEW is non-nil then `org-latex-preview' will be called on
|
||
|
the resulting LaTeX block. Move point that MOVE-BACK lines back to
|
||
|
reach a good spot in the LaTeX block, defaults to `-2'."
|
||
|
(forward-line (or move-back -2))
|
||
|
(end-of-line)
|
||
|
(setq-local tempel-latex-preview preview)
|
||
|
(org-edit-special))
|
||
|
#+end_src
|
||
|
|
||
|
To allow for ~=>~ as template keys, ~'symbol~ won't work, but ~'evil-word~ will.
|
||
|
|
||
|
#+begin_src emacs-lisp
|
||
|
(defun tempel--prefix-bounds ()
|
||
|
"Return prefix bounds."
|
||
|
(if tempel-trigger-prefix
|
||
|
(let ((end (point))
|
||
|
(beg (save-excursion
|
||
|
(search-backward tempel-trigger-prefix
|
||
|
(line-beginning-position) 'noerror))))
|
||
|
(when (and beg (save-excursion
|
||
|
(not (re-search-backward "\\s-" beg 'noerror))))
|
||
|
(cons (+ beg (length tempel-trigger-prefix)) end)))
|
||
|
(bounds-of-thing-at-point 'symbol)))
|
||
|
#+end_src
|
||
|
|