diff --git a/init.el b/init.el index 6cb39c9..98989a1 100644 --- a/init.el +++ b/init.el @@ -136,7 +136,8 @@ tab-width 4 fill-column 80 comment-multi-line t - comment-empty-lines 'eol) + comment-empty-lines 'eol + show-trailing-whitespace t) ;; Tree sitter download locations (setq treesit-language-source-alist @@ -917,6 +918,81 @@ COMMAND and COMINT are like `compile'." `(,(concat (regexp-opt '("gschema" "gresource" "ui")) "\\'") . nxml-mode))) +;; Bibtex (built in) +(use-package bibtex + :ensure nil + :defer nil + :config + (defun my/bibtex-in-entry-p (&optional exclude-braces) + "Return t is point is inside a BibTeX entry. +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 + ;; go to top level and check if the character at point is { + (when (and (not exclude-braces) (= ?{ (char-after))) + (forward-char)) + (let ((start-pos (point)) + (last-valid (point))) + (condition-case _ + (while t + (up-list 1 t t) + (setq last-valid (point))) + (error + (and + (= ?\} (char-before last-valid)) + ;; up-point moves to the char after the last brace, so if the point + ;; started there, we aren't in the entry + (not (= start-pos last-valid)) + (or (not exclude-braces) + (not (= start-pos (1- last-valid)))))))))) + (defvar my/bibtex-indent-width 4 + "Width to indent for `my/bibtex-calculate-indentation'.") + (defun my/bibtex-calculate-indentation () + "Calculate the column to indent to on the current line." + (save-excursion + (back-to-indentation) + (if (my/bibtex-in-entry-p t) + my/bibtex-indent-width + 0))) + (defun my/bibtex-empty-line-p () + "Return t if the current line is only blank characters." + (save-excursion + (beginning-of-line) + (looking-at (rx (* blank) eol)))) + (defun my/bibtex-indent-line () + "Indent the current line." + (interactive) + (save-excursion + (beginning-of-line) + (when (my/bibtex-empty-line-p) + (delete-region (point) (match-end 0))) + (indent-to (my/bibtex-calculate-indentation))) + (when (looking-at (rx (+ blank) eol)) + (end-of-line))) + (defun my/bibtex-indent-or-find-text () + "Either indent the current line or jump to the current fields text. +If the current line is only whitespace call `my/bibtex-calculate-indentation', +otherwise, call `bibtex-find-text'." + (interactive) + (if (my/bibtex-empty-line-p) + (my/bibtex-indent-line) + (bibtex-find-text))) + (defun my/bibtex-indent-or-find-text-and-insert () + "Like `my/bibtex-indent-or-find-text', but enter insert mode after." + (interactive) + (my/bibtex-indent-or-find-text) + (if (my/bibtex-empty-line-p) + (evil-append 1) + (evil-insert 1))) + (defun my/-bibtex-setup-indent () + (setq-local indent-line-function 'my/bibtex-indent-line)) + (add-hook 'bibtex-mode-hook 'my/-bibtex-setup-indent) + (define-key bibtex-mode-map (kbd "RET") 'newline-and-indent) + (define-key bibtex-mode-map (kbd "TAB") 'my/bibtex-indent-or-find-text) + (evil-define-key 'normal bibtex-mode-map + (kbd "TAB") 'my/bibtex-indent-or-find-text-and-insert)) + ;; AUCTeX (use-package auctex :hook ((LaTeX-mode . turn-on-reftex)