E.g., have a “notes” buffer and a main buffer. In the main buffer, save “snapshots” of the scroll position of the other buffer.
Could also be used for translation, porting, rewriting, etc., any task that demand two files open side by side.
Option to automatically save positions, whenever something is written in the “auxiliary” buffer, attach it to the visible position in the “main” buffer.
;;; -*- lexical-binding: t; -*-(load (expand-file-name "elpaca-init" user-emacs-directory))Now we make it so that use-package declarations are installed by Elpaca by default.
(setopt use-package-always-ensure t
use-package-always-defer t)- turns out the newline character
\nis not in the space category of the org-mode syntax table, or at least it should not be. If this is not the case, you start getting errors withorg-edit-src-block. At least one instance of this issue was fixed by deleting the desktop file so that the problematic org file would not be restored from it.It seems to also be fixed by
(modify-syntax-entry ?\n "-" org-mode-syntax-table), BUT then, smartparens gets horribly slow!!!(defun fix-org-syntax-bug () (interactive) (modify-syntax-entry ?\n "-" org-mode-syntax-table) (org-element-cache-reset))
- In terminal, sometimes buried child frames appear and won’t go away. This command exterminates all of them.
(defun child-frame-delete-all () (interactive) (dolist (frame (frame-list)) (when (frame-parameter frame 'parent-frame) (delete-frame frame))))
(defmacro cmd! (&rest forms) `(lambda () (interactive) ,@forms))(defmacro buffer-fp-match! (regex)
`(lambda (buffer-or-name &rest _)
(when-let* ((buffer (get-buffer buffer-or-name))
(file (buffer-file-name buffer)))
(string-match-p ,regex file))))
(defmacro buffer-mode-p! (&rest modes)
`(lambda (buffer-or-name &rest _)
(with-current-buffer buffer-or-name
(derived-mode-p ',modes))))(defun setmap (map &rest defs)
(while defs
(keymap-set map (car defs) (cadr defs))
(setq defs (cddr defs))));; borrowed from gptel
(defun api-key-from-auth-source (host &optional user)
"Lookup api key for HOST, USER in the auth source."
(if-let* ((secret
(plist-get
(car (auth-source-search
:host host
:user (or user "apikey")
:require '(:secret)))
:secret)))
(if (functionp secret)
(encode-coding-string (funcall secret) 'utf-8)
secret)
(user-error "No api-key found in the auth source")))(use-package gcmh
:init
(gcmh-mode))(keymap-global-set "C-s" #'save-buffer)
(keymap-global-set "M-z" #'toggle-frame-tab-bar)(defvar leader-key (kbd "SPC"))
(defvar leader-alt-key (kbd "M-SPC"))(defvar map-local-overrides nil)
(defun modal-setmap (active-map map &rest defs)
(cl-symbol-macrolet ((overrides (alist-get active-map map-local-overrides)))
(let ((new-map (alist-get map overrides)) new-leader)
(unless new-map
(setq new-map (make-sparse-keymap)
new-leader (make-sparse-keymap))
(setf (alist-get map overrides) new-map)
(set-keymap-parent new-map map)
(set-keymap-parent new-leader leader-map)
(keymap-substitute new-leader map new-map)
(require 'evil-core)
(evil-define-key* 'motion active-map leader-key new-leader)
(evil-define-key* 'insert active-map leader-alt-key new-leader))
(apply #'setmap new-map defs))))(repeat-mode)(defvar-keymap leader-map
:doc "Leader key keymap.")
(defvar-keymap file-map
:doc "File actions keymap.")
(defvar-keymap toggle-map
:doc "Toggle actions keymap.")
(defvar-keymap open-map
:doc "Open actions keymap.")
(defvar-keymap buffer-map
:doc "Buffer actions keymap.")
(defvar-keymap debug-map
:doc "Debug actions keymap.")
(defvar-keymap code-map
:doc "Code actions keymap.")
(defvar-keymap window-map
:doc "Window actions keymap.")
(defvar-keymap project-map
:doc "Mode actions keymap.")
(defvar-keymap mode-map
:doc "Mode actions keymap.")
(setmap file-map
"f" #'find-file
"c" #'copy-file
"s" #'save-buffer
"m" #'rename-visited-file)
(setmap toggle-map
"l" #'display-line-numbers-mode)
(setmap debug-map
"e" #'toggle-debug-on-error
"q" #'toggle-debug-on-quit
"t" #'trace-function
"T" #'untrace-function)
(setmap buffer-map
"d" (defun kill-this-buffer () (interactive) (kill-buffer))
"i" #'ibuffer
"r" #'revert-buffer)
(setmap window-map
"C-w" (defun mru-window ()
(interactive)
(when-let* ((window (get-mru-window nil t t t)))
(select-window window)))
"p" #'other-window-prefix
"P" #'same-window-prefix)
(setmap leader-map
"w" (cons "Window" window-map)
"x" (cons "x" ctl-x-map)
"b" (cons "Buffer" buffer-map)
"d" (cons "Debug" debug-map)
"c" (cons "Code" code-map)
"s" (cons "Search" search-map)
"p" (cons "Project" project-map)
"h" (cons "Help" help-map)
"t" (cons "Toggle" toggle-map)
"o" (cons "Open" open-map)
"f" (cons "File" file-map)
"m" (cons "Mode" mode-map)
"TAB" (cons "Tabs" tab-prefix-map)
"." #'find-file
"x" #'scratch-buffer
"u" #'universal-argument)
(setmap universal-argument-map
"C-u" nil
"SPC u" #'universal-argument-more)
(setmap open-map
"f" #'make-frame)This functionality allows binding many keys to TAB via a hook. The command will run all commands in the hook in order and stop at the first function that returns non-nil.
(defvar tab-actions '(indent-for-tab-command)
"TAB actions hook.")
(defun run-tab-actions ()
(interactive)
(cl-dolist (action tab-actions)
(when-let* ((res (call-interactively action)))
(cl-return res))))
(global-set-key (kbd "TAB") #'indent-for-tab-command)(use-package smartparens
:hook (prog-mode LaTeX-mode)
:init
(defun smartparens-tab (&optional this)
(lambda (&optional arg)
(interactive "P")
(if-let* ((e (plist-get
(and smartparens-mode
(sp--looking-at
(sp--get-closing-regexp
(sp--get-pair-list-context 'navigate)))
(sp-get-enclosing-sexp))
:cl)))
(forward-char (length e))
(let ((this-command this))
(indent-for-tab-command arg)))))
:config
(global-set-key (kbd "TAB") (smartparens-tab))
(global-set-key (kbd "<backtab>") #'sp-up-sexp)
(require 'smartparens-config)
(dolist (h '(prog-mode-hook LaTeX-mode-hook))
(add-hook h 'smartparens-mode 99 nil)))(use-package link-hint
:bind (:map search-map ("l" . link-hint-open-link)))(use-package evil
:bind (("C-w" . evil-delete-backward-word))
:init
(setopt evil-want-integration t
evil-ex-substitute-global t
evil-lookup-func #'helpful-at-point
evil-shift-round nil
evil-shift-width 2
evil-move-beyond-eol t
evil-cross-lines t
evil-symbol-word-search t
evil-want-abbrev-expand-on-insert-exit nil
evil-undo-system 'undo-redo
evil-move-cursor-back nil
evil-want-fine-undo t
evil-want-keybinding nil)
(evil-mode)
(with-eval-after-load 'evil-collection-unimpaired
(evil-define-key '(normal visual) evil-collection-unimpaired-mode-map
(kbd "] e") (cmd! () (flymake-goto-next-error current-prefix-arg '(:error)))
(kbd "[ e") (cmd! () (flymake-goto-prev-error current-prefix-arg '(:error)))))
:config
(keymap-global-set "C-j" (cmd! (evil-next-visual-line) (scroll-up 1)))
(keymap-global-set "C-k" (cmd! (evil-previous-visual-line) (scroll-down 1)))
(set-keymap-parent window-map evil-window-map)
(keymap-set evil-motion-state-map "C-w" window-map)
(evil-define-key '(motion visual) 'global
(kbd "g s s") #'evil-avy-goto-char-timer
(kbd "g s 2") #'evil-avy-goto-char-2)
(evil-define-key 'motion 'global
"j" #'evil-next-visual-line
"k" #'evil-previous-visual-line)
(keymap-global-set "M-SPC" leader-map)
(evil-define-key 'insert 'global
(kbd "C-v") #'evil-paste-before
(kbd "M-TAB") #'completion-at-point
(kbd "C-g") #'evil-normal-state)
(evil-define-key 'motion 'global
(kbd "SPC") leader-map
(kbd "C-u") #'evil-scroll-up
(kbd "C-t") nil)
(setmap buffer-map
"l" #'evil-switch-to-windows-last-buffer
"D" (defun quit-this-buffer () (interactive) (kill-buffer) (evil-quit))))(use-package evil-anzu
:after (evil)
:init
(global-anzu-mode)
(require 'evil-anzu))(use-package evil-exchange
:after evil
:init
(evil-exchange-install))(use-package evil-collection
:after evil
:init
(evil-collection-init)
:config
(evil-define-key 'normal help-mode-map (kbd "SPC") nil))(use-package evil-multiedit
:init
(require 'evil-multiedit)
(evil-multiedit-default-keybinds))(use-package evil-surround
:after evil
:init
(global-evil-surround-mode))(use-package evil-snipe
:after evil
:init
(setopt evil-snipe-spillover-scope 'visible)
(evil-snipe-mode)
(evil-snipe-override-mode)
(add-hook 'magit-mode-hook 'turn-off-evil-snipe-override-mode))(use-package evil-textobj-tree-sitter
:after evil
:init
(setmap evil-outer-text-objects-map
"c" (evil-textobj-tree-sitter-get-textobj "comment.outer"))
(setmap evil-inner-text-objects-map
"c" (evil-textobj-tree-sitter-get-textobj "comment.inner")))(use-package ace-window
:custom
(aw-keys '(?q ?w ?e ?r ?t ?y))
:bind (:map window-map
("w" . ace-window))
:config
(when (assoc ?e aw-dispatch-alist)
(setf (car (assoc ?e aw-dispatch-alist)) ?E))
(custom-set-faces
'(aw-leading-char-face ((t (:height 1.0))))))(use-package orderless
:init
(setopt completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion))))
:config
(setopt orderless-component-separator #'orderless-escapable-split-on-space
orderless-matching-styles '(orderless-initialism
orderless-literal
orderless-regexp)))(use-package cape
:bind (:map mode-specific-map
("c p" . completion-at-point) ;; capf
("c t" . complete-tag) ;; etags
("c d" . cape-dabbrev) ;; or dabbrev-completion
("c f" . cape-file)
("c k" . cape-keyword)
("c s" . cape-symbol)
("c a" . cape-abbrev)
("c l" . cape-line)
("c w" . cape-dict)
("c \\" . cape-tex)
("c &" . cape-sgml)
("c r" . cape-rfc1345))
:config
(setopt cape-dabbrev-min-length 3
cape-dict-file
(mapcar (lambda (s)
(expand-file-name (format "dicts/%s" s) user-emacs-directory))
'("en-small" "pt-br-small"))
dabbrev-case-fold-search t
cape-dabbrev-check-other-buffers t)
:init
(advice-add #'comint-completion-at-point :around #'cape-wrap-nonexclusive)
(advice-add #'eglot-completion-at-point :around #'cape-wrap-nonexclusive)
(advice-add #'pcomplete-completions-at-point :around #'cape-wrap-nonexclusive)
(defun +corfu-add-cape-file-h ()
(add-hook 'completion-at-point-functions #'cape-file -10 t))
(add-hook 'prog-mode-hook #'+corfu-add-cape-file-h)
(defun +corfu-add-cape-elisp-block-h ()
(add-hook 'completion-at-point-functions #'cape-elisp-block 0 t))
(dolist (h '(org-mode-hook markdown-mode-hook))
(add-hook h #'+corfu-add-cape-elisp-block-h))
(with-eval-after-load 'dabbrev
(setq dabbrev-ignored-buffer-regexps
'("^ " "\\(TAGS\\|tags\\|ETAGS\\|etags\\|GTAGS\\|GRTAGS\\|GPATH\\)\\(<[0-9]+>\\)?")
dabbrev-upcase-means-case-search t)
(add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode))
(defun +corfu-add-cape-dabbrev-dict-h ()
(add-hook 'completion-at-point-functions (cape-capf-super #'cape-dabbrev #'cape-dict) 30 t))
(add-hook 'text-mode-hook #'+corfu-add-cape-dabbrev-dict-h))The cape-dabbrev backend does not handle casing very well; see my issue here. The following advice makes cape-dabbrev match the case of uppercase words with the case of the completion prefix.
(advice-add #'cape--dabbrev-list :override
(defun cape--dabbrev-list-ad (input)
"Find all Dabbrev expansions for INPUT."
(cape--silent
(let ((dabbrev-check-other-buffers (not (null cape-dabbrev-check-other-buffers)))
(dabbrev-check-all-buffers (eq cape-dabbrev-check-other-buffers t)))
(dabbrev--reset-global-variables))
(cons
(apply-partially #'string-prefix-p input)
(cl-loop with min-len = (+ cape-dabbrev-min-length (length input))
with ic = (cape--case-fold-p dabbrev-case-fold-search)
for w in (dabbrev--find-all-expansions input ic)
if (>= (length w) min-len) collect
(let ((dw (if (let (case-fold-search) (not (string-match-p "[[:lower:]]" w)))
w (downcase w))))
(cape--case-replace (and ic dabbrev-case-replace) input dw)))))))(use-package consult
:ensure (:host github :repo "estradilua/consult" :ref "flymake-better-project")
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map leader-map
("," . consult-buffer)
:map file-map
("r" . consult-recent-file)
:map search-map
("d" . consult-find) ;; Alternative: consult-fd
("c" . consult-locate)
("g" . consult-grep)
("G" . consult-git-grep)
("r" . consult-ripgrep)
("s" . consult-line)
("S" . consult-line-multi)
("k" . consult-keep-lines)
("u" . consult-focus-lines)
("i" . consult-imenu)
("I" . consult-imenu-multi)
:map code-map
("X" . consult-flymake)
("x" . (lambda () (interactive) (consult-flymake t)))
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<")) ;; "C-+"
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
;; By default `consult-project-function' uses `project-root' from project.el.
;; Optionally configure a different project root function.
;;;; 1. project.el (the default)
;; (setq consult-project-function #'consult--default-project--function)
;;;; 2. vc.el (vc-root-dir)
;; (setq consult-project-function (lambda (_) (vc-root-dir)))
;;;; 3. locate-dominating-file
;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git")))
;;;; 4. projectile.el (projectile-project-root)
;; (autoload 'projectile-project-root "projectile")
;; (setq consult-project-function (lambda (_) (projectile-project-root)))
;;;; 5. No project support
;; (setq consult-project-function nil)(use-package consult-recoll)(use-package autoinsert
:ensure nil
:init
(auto-insert-mode)
:config
(setopt auto-insert-directory
(expand-file-name "auto-insert/" user-emacs-directory)))(use-package gitignore-templates)(use-package license-templates)(use-package gptel
:config
(setopt gptel-api-key #'gptel-api-key-from-auth-source)
(gptel-make-anthropic "Claude"
:stream t
:key #'gptel-api-key-from-auth-source)
(gptel-make-deepseek "DeepSeek"
:stream t
:key #'gptel-api-key-from-auth-source))(use-package gptel-quick
:ensure (:host github :repo "karthink/gptel-quick"))(use-package minuet
:config
(setopt minuet-provider 'openai-fim-compatible)
(plist-put minuet-openai-fim-compatible-options :api-key
(lambda () (api-key-from-auth-source "api.deepseek.com")))
(plist-put minuet-claude-options :api-key
(lambda () (api-key-from-auth-source "api.anthropic.com"))))(use-package copilot
:bind (:map copilot-completion-map
("<tab>" . copilot-accept-completion-by-word)
("TAB" . copilot-accept-completion-by-word)
("<backtab>" . copilot-accept-completion)))(use-package whisper
:ensure (:host github :repo "natrys/whisper.el")
:custom
(whisper-install-directory "~/dados/Applications/")
(whisper-model "small")
(whisper-language "auto")
:bind (:map text-mode-map
("M-s" . whisper-run)))(use-package marginalia
:bind (:map minibuffer-mode-map
("M-A" . marginalia-cycle))
:init
(marginalia-mode))(use-package nerd-icons-completion
:after marginalia
:init
(nerd-icons-completion-mode)
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))(use-package tempel
:ensure (:repo "git@github.com:lucasvreis/tempel.git")
:bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
("M-*" . tempel-insert))
:init
(advice-add #'tempel-next :after
(defun tempel-next-ad (arg)
"Move ARG fields forward and REALLY quit at the end."
(unless (tempel--find arg)
(tempel-done))))
;; Setup completion at point
(defun tempel-setup-capf ()
;; Add the Tempel Capf to `completion-at-point-functions'.
;; `tempel-expand' only triggers on exact matches. Alternatively use
;; `tempel-complete' if you want to see all matches, but then you
;; should also configure `tempel-trigger-prefix', such that Tempel
;; does not trigger too often when you don't expect it. NOTE: We add
;; `tempel-expand' *before* the main programming mode Capf, such
;; that it will be tried first.
(add-hook 'completion-at-point-functions #'tempel-expand 20 t))
(add-hook 'conf-mode-hook 'tempel-setup-capf)
(add-hook 'prog-mode-hook 'tempel-setup-capf)
(add-hook 'text-mode-hook 'tempel-setup-capf)
:config
(setmap tempel-map
"TAB" #'tempel-next
"<backtab>" #'tempel-previous
"M-d" (cmd! (tempel-kill) (tempel-next 1))))(use-package aas)Some monkey patching to keep the order of hooks reasonable. Otherwise there is a huge mess with smartparens.
(with-eval-after-load 'aas
(define-minor-mode aas-mode
"Minor mode for dynamically auto-expanding snippets.
This does not set any default keymaps. For that use
`aas-activate-for-major-mode' and `aas-activate-keymap'."
:init-value nil
:group 'aas
(if aas-mode
(add-hook 'post-self-insert-hook #'aas-post-self-insert-hook 90 t)
(remove-hook 'post-self-insert-hook #'aas-post-self-insert-hook t))))(use-package vertico
:init
(vertico-mode)
:config
(setopt vertico-resize nil
vertico-count 8)
(vertico-mouse-mode)
(vertico-multiform-mode)
(add-to-list 'vertico-multiform-categories '(embark-keybinding grid)))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
(setopt minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt)
enable-recursive-minibuffers t
read-extended-command-predicate #'command-completion-default-include-p)(use-package vertico-directory
:after vertico
:ensure nil
;; More convenient directory navigation commands
:bind (:map vertico-map
("RET" . vertico-directory-enter)
("DEL" . vertico-directory-delete-char)
("M-DEL" . vertico-directory-delete-word))
;; Tidy shadowed file names
:hook (rfn-eshadow-update-overlay . vertico-directory-tidy))(use-package vertico-repeat
:after vertico
:ensure nil
:bind (("M-R" . vertico-repeat)
:map vertico-map
("M-P" . vertico-repeat-previous)
("M-N" . vertico-repeat-next)
("S-<prior>" . vertico-repeat-previous)
("S-<next>" . vertico-repeat-next))
:hook (minibuffer-setup . vertico-repeat-save))(use-package corfu
:init
(defun corfu-enable-in-minibuffer ()
"Enable Corfu in the minibuffer."
(when (local-variable-p 'completion-at-point-functions)
;; (setq-local corfu-auto nil) ;; Enable/disable auto completion
(setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
corfu-popupinfo-delay nil)
(corfu-mode)))
(remove-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer)
(global-corfu-mode)
:custom-face (corfu-default ((t (:inherit fixed-pitch))))
:bind (:map corfu-map
("<remap> <completion-at-point>" . corfu-complete)
("TAB" . corfu-next)
("<backtab>" . corfu-previous)
("C-<tab>" . corfu-expand)
("\\" . corfu-quit)
("M-s" . corfu-insert-separator)
:map evil-insert-state-map
("C-<tab>" . completion-at-point))
:config
(setopt corfu-cycle t
corfu-preselect 'directory
corfu-auto nil
corfu-auto-prefix 3
corfu-count 16
corfu-auto-delay 0.4
corfu-max-width 120
corfu-on-exact-match 'insert
corfu-preview-current 'insert
global-corfu-minibuffer t
tab-always-indent t)
(add-hook 'evil-insert-state-exit-hook #'corfu-quit)
;; In case you ever get `args-out-of-range 0 0' errors when using
;; Corfu with Eglot, try setting this. It is also related to ``:exlusive 'no''.
(add-to-list 'completion-category-overrides `(eglot-capf (styles ,@completion-styles)))
;; Per-mode settings)
(require 'mode-local)
(setq-mode-local prog-mode
corfu-auto-prefix 2
corfu-auto-delay 0))(advice-add #'corfu--make-buffer :filter-return
(defun corfu-no-line-spacing-ad (buffer)
(with-current-buffer buffer
(setq-local line-spacing 0)
buffer)))(use-package corfu-history
:ensure nil
:after (savehist corfu)
:hook ((corfu-mode . corfu-history-mode))
:config
(add-to-list 'savehist-additional-variables 'corfu-history))(use-package corfu-popupinfo
:ensure nil
:after corfu
:hook ((corfu-mode . corfu-popupinfo-mode))
:config
(setopt corfu-popupinfo-delay '(0 . 1.0)))(use-package kind-icon
:after corfu
:init
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)
:config
(setopt kind-icon-default-face 'corfu-default
kind-icon-blend-background t
kind-icon-default-style '(:padding 0
:stroke 0
:margin 0
:radius 0
:height 0.8
:scale 1.0))
(add-hook 'after-enable-theme-hook #'kind-icon-reset-cache))(use-package embark
:bind (("C-;" . embark-act)
("C-:" . embark-dwim)
([remap describe-bindings] . embark-bindings)
:map embark-file-map
("C" . copy-directory))
:init
(setq which-key-use-C-h-commands nil
prefix-help-command #'embark-prefix-help-command)
:config
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "…" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
(setopt embark-indicators '(embark-highlight-indicator
embark-isearch-highlight-indicator))
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
:bind (:map embark-consult-search-map
("s" . consult-line)
("S" . consult-line-multi))
:hook (embark-collect-mode . consult-preview-at-point-mode))(with-eval-after-load 'embark
(when (require 'which-key nil t)
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "…" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
(setq embark-indicators
'(embark-which-key-indicator
embark-highlight-indicator
embark-isearch-highlight-indicator))
(defun embark-hide-which-key-indicator (fn &rest args)
"Hide the which-key indicator immediately when using the completing-read prompter."
(which-key--hide-popup-ignore-command)
(let ((embark-indicators
(remq #'embark-which-key-indicator embark-indicators)))
(apply fn args)))
(advice-add #'embark-completing-read-prompter
:around #'embark-hide-which-key-indicator)))Let’s group by projects using a handy package.
(use-package ibuffer-project
:init
(add-hook
'ibuffer-hook
(lambda ()
(setq ibuffer-filter-groups (ibuffer-project-generate-filter-groups))
(unless (eq ibuffer-sorting-mode 'project-file-relative)
(ibuffer-do-sort-by-project-file-relative)))))(use-package bufferfile
:bind (:map file-map
("c" . bufferfile-copy)
("d" . bufferfile-delete)))
;; NB: bufferfile-rename prompt is bad. `rename-visited-file' does the right thing.
;; ("m" . bufferfile-rename)))(use-package change-case
:ensure (:host github :repo "TakesxiSximada/change-case.el"))(setopt custom-file "/dev/null")Add a hook after theme changes.
(use-package custom
:ensure nil
:init
(defvar after-enable-theme-hook nil)
(defun run-after-enable-theme-hook (&rest _args)
(run-hooks 'after-enable-theme-hook))
(advice-add 'enable-theme :after #'run-after-enable-theme-hook))(use-package eglot
:ensure (:repo "~/dados/projetos/codigo/emacs/emacs/lisp/progmodes/"
:files ("eglot.el"))
:custom-face
(eglot-diagnostic-tag-unnecessary-face ((t (:inherit shadow))))
(eglot-inlay-hint-face ((t (:height unspecified :inherit shadow))))
(eglot-code-action-indicator-face ((t (:weight bold :inherit (font-lock-escape-face default)))))
:custom
(eglot-code-action-indicator "↯")
(eglot-autoshutdown t)
(eglot-send-changes-idle-time 0.2)
(eglot-advertise-cancellation t)
(eglot-confirm-server-edits '((eglot-rename) (t . maybe-summary)))
(eglot-events-buffer-config '(:size 0 :format short))
(eglot-ignored-server-capabilities '(:inlayHintProvider))
:config
(add-to-list 'eglot-server-programs
(cons '(latex-mode plain-tex-mode context-mode bibtex-mode tex-mode)
'("texlab")))
(modal-setmap eglot-mode-map code-map
"a" #'eglot-code-actions
"f" #'eglot-format
"I" #'consult-eglot-symbols
"r" #'eglot-rename)
(advice-add 'eglot--format-markup :around
(defun eglot--format-markup-ad (fn markup &optional mode)
(let ((markdown-fontify-code-block-default-mode (or mode major-mode)))
(apply fn markup mode))))
(require 'markdown-mode))(use-package consult-eglot)
(use-package consult-eglot-embark
:after eglot
:init
(consult-eglot-embark-mode))(use-package eglot-booster
:ensure (:host github :repo "jdtsmith/eglot-booster")
:after eglot
:init
(eglot-booster-mode))(with-eval-after-load 'flymake
(setopt flymake-indicator-type 'margins)
(setopt flymake-margin-indicators-string
'((error "‼" compilation-error)
(warning "!" compilation-warning)
(note "!" success))
flymake-diagnostic-format-alist
'((:help-echo origin code message) (:eol oneliner) (:eldoc origin code message)
(:eldoc-echo origin code oneliner) (t origin code oneliner)))
(custom-set-faces
'(flymake-error-echo ((t (:inherit (error fixed-pitch)))))
'(flymake-note-echo ((t (:inherit (success fixed-pitch)))))
'(flymake-warning-echo ((t (:inherit (warning fixed-pitch)))))))
(with-eval-after-load 'flymake-proc
(remove-hook 'flymake-diagnostic-functions 'flymake-proc-legacy-flymake))(use-package sideline
:custom-face
(sideline-default ((t (:inherit fixed-pitch))))
:config
(setopt sideline-delay 0.2))(use-package sideline-flymake
:hook (flymake-mode . sideline-mode)
:custom-face
(sideline-flymake-error ((t (:height 0.85 :inherit (error fixed-pitch)))))
(sideline-flymake-note ((t (:height 0.85 :inherit (success fixed-pitch)))))
(sideline-flymake-warning ((t (:height 0.85 :inherit (warning fixed-pitch)))))
(sideline-flymake-success ((t (:height 0.85 :inherit (success fixed-pitch)))))
:init
(setq sideline-flymake-display-mode 'point)
(setq sideline-backends-right '(sideline-flymake)))
;; (advice-add 'elisp-flymake-byte-compile :after #'sideline-render-this))(use-package eldoc
:ensure nil
:config
(make-variable-buffer-local 'eldoc-last-message)
(add-hook 'eldoc-mode-hook
(defun eldoc/fix-hooks ()
(if eldoc-mode
(progn
(remove-hook 'pre-command-hook #'eldoc-pre-command-refresh-echo-area t)
(add-hook 'post-command-hook #'eldoc-pre-command-refresh-echo-area nil t))
(remove-hook 'post-command-hook #'eldoc-pre-command-refresh-echo-area t))))
(setopt eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit
eldoc-help-at-pt t
eldoc-idle-delay 0.1))(use-package eldoc-box
:after eldoc
:custom-face
(eldoc-box-body ((t (:height 1.0 :weight normal :inherit (variable-pitch corfu-default)))))
(eldoc-box-border ((t (:background unspecified :inherit corfu-border))))
(eldoc-box-markdown-separator
((t :height 0.5
:underline (:color foreground-color :style wave :position nil)
:strike-through unspecified
:inherit shadow)))
:init
(with-eval-after-load 'eglot
(evil-define-key 'normal eglot-mode-map
"K" #'eldoc-box-help-at-point))
:config
(setopt eldoc-box-max-pixel-height 400)
(setcdr (assoc 'internal-border-width eldoc-box-frame-parameters) 1)
(setcdr (assoc 'left-fringe eldoc-box-frame-parameters) 5)
(setcdr (assoc 'right-fringe eldoc-box-frame-parameters) 5)
(defun eldoc-box-better-at-point-position-function (width height)
"See `eldoc-box--default-at-point-position-function' for WIDTH & HEIGHT docs."
(let* ((pos (posn-x-y (posn-at-point)))
(edge (window-inside-pixel-edges))
;; calculate point coordinate relative to native frame
;; because childframe coordinate is relative to native frame
(x (+ (car edge) (car pos)))
(y (+ (cadr edge) (window-tab-line-height) (cdr pos)))
(em (default-line-height)))
(cons (if (< (- (frame-inner-width) width) x)
;; space on the right of the pos is not enough
;; put to left
(max 0 (- x width))
;; normal, just return x
x)
(if (< (- (frame-inner-height) height) y)
;; space under the pos is not enough
;; put above
(max 0 (- y height))
;; normal, just return y + em
(+ y em)))))
(setopt eldoc-box-at-point-position-function #'eldoc-box-better-at-point-position-function))(use-package gif-screencast
:bind (:map gif-screencast-mode-map
("C-c C-s" . gif-screencast-stop))
:config
(setopt gif-screencast-program "grim"
gif-screencast-convert-program "magick"
gif-screencast-convert-args '("-delay" "100" "-loop" "0" "-dither" "None" "-fuzz" "40%")
gif-screencast-capture-prefer-internal nil
gif-screencast-args '()))(use-package helpful
:hook (helpful-mode . (lambda () (setq truncate-lines t)))
:bind (("C-h f" . #'helpful-callable)
("C-h F" . #'helpful-function)
("C-h v" . #'helpful-variable)
("C-h k" . #'helpful-key)
("C-h x" . #'helpful-command)
("C-h '" . #'helpful-at-point)
("C-h m" . #'helpful-macro)))
(with-eval-after-load 'embark
(setmap embark-symbol-map "h" #'helpful-symbol))(setopt indent-tabs-mode nil
user-full-name "Lua Viana Reis"
user-mail-address "me@lua.blog.br"
trusted-content '("~/dados/projetos/" "~/dados/arquivo/")
inhibit-startup-screen t
frame-resize-pixelwise t
vc-follow-symlinks t
recenter-redisplay nil
scroll-conservatively 0
backup-inhibited t
switch-to-buffer-obey-display-actions t
confirm-kill-emacs #'y-or-n-p
use-dialog-box nil
standard-indent 2
ring-bell-function #'ignore
kill-buffer-quit-windows t
text-scale-mode-step 1.05
revert-without-query '(".")
display-line-numbers-width-start t
use-short-answers t
auto-save-file-name-transforms
`(("\\`/\\([^/]*[/:]\\)*\\([^/]*\\)\\'" ,(concat user-emacs-directory "auto-save-list/\\2") t))
create-lockfiles nil
;; what the fuck, emacs!
sentence-end-double-space nil
auth-sources `(,(expand-file-name "authinfo.gpg" user-emacs-directory)))
(column-number-mode)
(undelete-frame-mode)
(defun display-startup-echo-area-message ())(use-package magit
:ensure (:source "NonGNU ELPA")
:config
(setopt magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1
magit-bury-buffer-function #'magit-restore-window-configuration))
(use-package transient
:ensure (:source "NonGNU ELPA"))Let’s add some keys to it.
(use-package magit
:ensure nil
:init
(defvar-keymap git-map :doc "Actions related to Git.")
(keymap-set leader-map "g" (cons "Git" git-map))
:bind
(:map git-map
("g" . magit)
("G" . magit-status-here)
("S" . magit-stage)
("u" . magit-unstage)
("c c" . magit-commit-create)
("c a" . magit-commit-amend)
("c f" . magit-commit-fixup)
("p" . magit-push)
("l" . magit-log)))(use-package hl-todo
:ensure (:tag "v3.7.0"))
(use-package magit-todos
:after magit
:init
(magit-todos-mode)
:config
(setopt magit-todos-exclude-globs
'(".git/" "**/elpaca/")))(use-package forge)(use-package diff-hl
:hook ((prog-mode conf-mode text-mode) . diff-hl-mode)
:commands (diff-hl-stage-dwim)
:init
(setmap git-map
"s" (cons "Stage hunk" #'diff-hl-stage-dwim)
"r" (cons "Revert hunk" #'diff-hl-revert-hunk)
"h" (cons "Show hunk" #'diff-hl-show-hunk))
:config
(setopt diff-hl-show-staged-changes nil
diff-hl-draw-borders nil
diff-hl-update-async t
diff-hl-fringe-bmp-function #'diff-hl-fringe-bmp-from-pos
diff-hl-margin-symbols-alist
'((insert . " ") (delete . " ") (change . " ")
(unknown . " ") (ignored . " ")))
(diff-hl-flydiff-mode))(use-package savehist
:ensure nil
:hook (after-init . savehist-mode)
:config
(add-to-list 'savehist-additional-variables 'custom-enabled-themes)
(add-to-list 'savehist-additional-variables 'register-alist)
(add-hook 'elpaca-after-init-hook
(defun savehist-apply-theme-h ()
(dolist (theme custom-enabled-themes)
(load-theme theme :no-confirm)))))(add-hook 'elpaca-after-init-hook
(defun enable-desktop-save-h ()
(desktop-read)
(desktop-save-mode))
99)(use-package tab-bookmark
:ensure (:repo "https://github.com/minad/tab-bookmark.git"))(with-eval-after-load 'emacs
(save-place-mode))(use-package project
:ensure nil
:init
(require 'project)
:config
(defun project-remember-and-open (dir &optional dont-open)
(interactive "DDirectory: \nP")
(project--ensure-read-project-list)
(if-let* ((project (project--find-in-directory dir)))
(progn (project-remember-project project)
(message "Found %s..." (project-root project))
(unless dont-open
(project-switch-project (project-root project))))
(message "No projects were found")))
(setmap project-prefix-map
"a" #'project-remember-and-open
"A" #'project-remember-projects-under
"d" #'project-forget-project
"D" #'project-forget-projects-under)
(set-keymap-parent project-map project-prefix-map)
(keymap-set leader-map "SPC" #'project-find-file)
(setopt project-switch-commands #'project-find-file
project-prompter #'project-prompt-project-dir
project-vc-extra-root-markers '("latexmkrc" "package.json")))(use-package epx
:after project
:bind
(:map project-map
("e e" . #'epx-run-command-in-shell)
("e c" . #'epx-add-command)
("e d" . #'epx-remove-command))
:init
(put 'epx-commands 'safe-local-variable (lambda (_) t)))(defun clear-vc-obarray-cache ()
(interactive)
(setq vc-file-prop-obarray (obarray-make)))fixes read function when project directory listing is empty
(with-eval-after-load 'project
(defun project--read-file-cpd-relative (prompt
all-files &optional predicate
hist mb-default)
"Read a file name, prompting with PROMPT.
ALL-FILES is a list of possible file name completions.
PREDICATE and HIST have the same meaning as in `completing-read'.
MB-DEFAULT is used as part of \"future history\", to be inserted
by the user at will."
(let* ((common-parent-directory
(let ((common-prefix (try-completion "" all-files)))
(if (> (length common-prefix) 0)
(file-name-directory common-prefix))))
(cpd-length (length common-parent-directory))
(common-parent-directory (if (and (car all-files)
(file-name-absolute-p (car all-files)))
common-parent-directory
(concat default-directory common-parent-directory)))
(prompt (if (and (zerop cpd-length)
all-files
(file-name-absolute-p (car all-files)))
prompt
(concat prompt (format " in %s" common-parent-directory))))
(substrings (mapcar (lambda (s) (substring s cpd-length)) all-files))
(new-collection (project--file-completion-table substrings))
(relname (project--completing-read-strict prompt
new-collection
predicate
hist mb-default
(unless (equal common-parent-directory "")
common-parent-directory)))
(absname (expand-file-name relname common-parent-directory)))
absname)))(use-package recentf
:ensure nil
:hook (after-init . recentf-mode))Thank you so much, https://emacs.stackexchange.com/a/55478!
(add-hook 'window-scroll-functions
(defun window-scroll-functions/recenter-after-jump (window new-win-start)
(with-selected-window window
(let* ((new-start-line (line-number-at-pos new-win-start))
(old-start-line (or (bound-and-true-p last-start-line-memo)
(line-number-at-pos (point))))
(distance (abs (- old-start-line new-start-line))))
(when (and (> distance 5)
(not (memq last-command '(next-line
recenter-top-bottom)))
(not (and (symbolp last-command)
(get last-command 'scroll-command))))
(recenter))
(setq-local last-start-line-memo new-start-line)))))(setopt pixel-scroll-precision-interpolation-factor 0.1
pixel-scroll-precision-interpolate-mice t
pixel-scroll-precision-interpolate-page t
pixel-scroll-precision-interpolation-total-time 0.15)(use-package ultra-scroll
:ensure (:repo "https://github.com/jdtsmith/ultra-scroll")
:init
(ultra-scroll-mode)
:custom
(auto-window-vscroll nil) ; Don't adjust window-vscroll for tall lines
(next-screen-context-lines 4) ; Preserve this many lines when jumping a screenful
(scroll-margin 0) ; Scroll when cursor is this many lines to screen edge
(scroll-conservatively 101) ; Only 'jump' when moving this far off the screen
(scroll-preserve-screen-position t)) ; Preserve line/column (nicer M-v, C-v, etc.)(use-package server
:ensure nil
:init
(server-force-delete)
(server-start nil t))(use-package jinx
:hook (text-mode conf-mode)
:config
(setq jinx-languages "pt_BR en_US")
(cl-pushnew 'font-lock-constant-face (alist-get 'tex-mode jinx-exclude-faces))
(cl-pushnew 'markdown-math-face (alist-get 'markdown-mode jinx-exclude-faces))
(cl-pushnew 'markdown-ts-code-block (alist-get 'markdown-ts-mode jinx-exclude-faces))
(define-key evil-visual-state-map "z=" 'jinx-correct)
(define-key evil-normal-state-map "z=" 'jinx-correct))Let’s also add a dir-local saving option.
(with-eval-after-load 'jinx
(defun jinx--save-dir (save key word)
"Save WORD in dir-local variable.
If SAVE is non-nil save, otherwise format candidate given action KEY."
(if save
(progn
(jinx--add-local-word 'jinx-dir-local-words word)
(save-excursion
(modify-dir-local-variable nil 'jinx-dir-local-words jinx-dir-local-words 'add-or-replace)
(save-buffer)
(kill-buffer)))
(list key word "Directory")))
(add-to-list 'jinx--save-keys '(?/ . jinx--save-dir)))(use-package elcord
:config
(setopt elcord-use-major-mode-as-main-icon t
elcord-idle-message "cat is sleeping on the keyboard")
(add-to-list 'elcord-mode-icon-alist '(LaTeX-mode . "latex-mode_icon"))
(add-to-list 'elcord-mode-icon-alist '(haskell-ts-mode . "haskell-mode_icon")))(use-package nerd-icons
:config
(setopt tab-bar-back-button "<"
tab-bar-forward-button ">"))
;; (nerd-icons-octicon "nf-oct-chevron_left")
;; (nerd-icons-octicon "nf-oct-chevron_right")))
(use-package tab-bar
:ensure nil
:custom-face
(tab-bar ((t (:height 0.9))))
(tab-bar-tab-group-inactive ((t (:box nil))))
(tab-bar-tab-group-current ((t (:slant italic :weight normal :box nil))))
:bind (:map tab-prefix-map
("<left>" . tab-bar-history-back)
("h" . tab-bar-history-back)
("<right>" . tab-bar-history-forward)
("l" . tab-bar-history-forward))
:init
(tab-bar-mode)
(cl-loop for i from 1 to 9 do
(keymap-global-set (format "M-%s" i) `(lambda () (interactive) (tab-select ,i))))
(tab-bar-history-mode)
:config
(setopt tab-bar-close-button-show nil
tab-bar-new-button "+"
tab-bar-tab-group-format-function
(lambda (tab i &optional p)
(propertize
(concat " " (tab-bar-tab-group-format-default tab i p) " ")
'face (if p 'tab-bar-tab-group-current 'tab-bar-tab-group-inactive)))
tab-bar-tab-name-format-function
(lambda (tab i)
(propertize
(concat " " (tab-bar-tab-name-format-default tab i) " ")
'face (funcall tab-bar-tab-face-function tab)))
tab-bar-format '(tab-bar-format-history
tab-bar-format-tabs-groups
tab-bar-separator
tab-bar-format-add-tab)
tab-bar-tab-hints nil
tab-bar-new-tab-choice #'get-scratch-buffer-create))
(use-package tab-line
:ensure nil
:custom-face
(tab-line ((t (:height 0.9))))
:custom
(tab-line-close-tab-function 'kill-buffer))(use-package eat
:init
(setmap open-map
"T" (cons "Terminal" #'eat-other-window)
"t" (cons "Terminal (project)" #'eat-project-other-window))
:config
(setq eat-kill-buffer-on-exit t
eat-shell "zsh"))(use-package dtrt-indent
:hook (prog-mode . dtrt-indent-mode))(use-package adaptive-wrap
:hook ((text-mode prog-mode) . adaptive-wrap-prefix-mode)
:config
(add-hook 'adaptive-wrap-prefix-mode-hook
(defun adaptive-wrap/disable-on-org-indent ()
(when (and adaptive-wrap-prefix-mode
(bound-and-true-p org-indent-mode))
(adaptive-wrap-prefix-mode -1)))))(setq tramp-default-method "ssh")(advice-add #'completion-file-name-table :around
(defun completion-file-name-table-ad (fn str pred action)
(let ((pred (if (eq pred 'file-directory-p)
(lambda (s)
(let ((len (length s)))
(and (> len 0) (memq (aref s (1- len)) '(?/ ?: ?@)))))
pred)))
(funcall fn str pred action))))(use-package treemacs
:bind (:map toggle-map
("p" . treemacs))
:custom-face
(treemacs-window-background-face ((t :inherit corfu-default)))
(treemacs-file-face ((t :inherit variable-pitch)))
(treemacs-directory-face ((t :inherit (variable-pitch font-lock-function-name-face))))
(treemacs-git-untracked-face ((t :inherit (variable-pitch font-lock-string-face))))
(treemacs-git-added-face ((t :inherit (variable-pitch font-lock-type-face))))
(treemacs-git-ignored-face ((t :inherit (variable-pitch font-lock-comment-face))))
(treemacs-git-modified-face ((t :inherit (variable-pitch font-lock-variable-name-face))))
:config
(setopt treemacs-position 'left
treemacs-width 35)
(treemacs-project-follow-mode))
(use-package treemacs-evil
:after (treemacs evil)
:demand t)
(use-package treemacs-nerd-icons
:after (treemacs)
:demand t
:config
(treemacs-load-theme "nerd-icons"))
(use-package treemacs-tab-bar ;;treemacs-tab-bar if you use tab-bar-mode
:after (treemacs)
:demand t
:config
(treemacs-set-scope-type 'Tabs))(use-package treesit
:ensure nil
:config
(setopt treesit-language-source-alist
'((haskell "https://github.com/tree-sitter/tree-sitter-haskell.git")
(html "https://github.com/tree-sitter-grammars/tree-sitter-html")
(kdl "https://github.com/tree-sitter-grammars/tree-sitter-kdl.git")
(lean "~/dados/projetos/codigo/emacs/tree-sitter-lean/")
(markdown "https://github.com/tree-sitter-grammars/tree-sitter-markdown" nil "tree-sitter-markdown/src")
(markdown-inline "https://github.com/tree-sitter-grammars/tree-sitter-markdown" nil "tree-sitter-markdown-inline/src")
(qmljs "https://github.com/yuja/tree-sitter-qmljs")
(rust "https://github.com/tree-sitter/tree-sitter-rust.git")
(toml "https://github.com/tree-sitter-grammars/tree-sitter-toml")
(tsx "https://github.com/tree-sitter/tree-sitter-typescript.git" nil "tsx/src")
(typescript "https://github.com/tree-sitter/tree-sitter-typescript.git" nil "typescript/src")
(typst "https://github.com/uben0/tree-sitter-typst")
(yaml "https://github.com/tree-sitter-grammars/tree-sitter-yaml"))))(use-package ts-query-highlight
:ensure (:repo "https://git.sr.ht/~meow_king/ts-query-highlight"))(use-package expreg
:bind (("M-r" . expreg-expand)
("C-M-r" . expreg-contract)))(use-package transpose-frame
:init
(setmap window-map
"C-r" #'rotate-frame-clockwise
"C-R" #'rotate-frame-anticlockwise
"C-t" #'transpose-frame))(use-package popper
:bind (("C-," . popper-toggle)
("M-," . popper-cycle)
("C-M-," . popper-toggle-type))
:init
(setopt popper-reference-buffers
`("\\*Messages\\*"
"\\*Warnings\\*"
"\\*eldoc\\*"
"\\*Async Shell Command\\*"
"\\*eat\\*" eat-mode
"\\*ChatGPT\\*"
;; "\\*scratch\\*"
help-mode
helpful-mode
compilation-mode
comint-mode
shell-mode
,(buffer-fp-match! "/\\.lake/packages/"))
popper-mode-line '(:eval (propertize " P " 'face 'mode-line-emphasis))
popper-group-function nil
popper-display-control 'user)
(popper-mode))- [ ] Write a proper
popper-group-function. - [ ] Write a consult backend
(defvar consult-popper-buffer-history nil)
(defun consult-popper--buffers ()
(let (out)
(dolist (g popper-buried-popup-alist)
(dolist (b (cdr g))
(when (buffer-live-p (cdr b))
(push (consult--buffer-pair (cdr b)) out))))
(dolist (b popper-open-popup-alist)
(push (consult--buffer-pair (cdr b)) out))
out))
(defvar consult-popper-buffer-source
`( :name "Popper buffers"
:narrow ?,
:hidden t
:category buffer
:default t
:face consult-buffer
:history consult-popper-buffer-history
:action ,#'switch-to-buffer
:items ,#'consult-popper--buffers)
"Source for `consult-buffer' to list Denote buffers.")
(with-eval-after-load 'consult
(add-to-list 'consult-buffer-sources 'consult-popper-buffer-source 'append))(use-package shackle
:init
(shackle-mode)
:config
(setopt shackle-rules `((("^\\*.*shell\\*$" compilation-mode)
:regexp t :popup t :align 'below :size 0.4 :select t))))
(defun display-buffer-pred-window (buf alist)
(let ((win (cl-find-if (cdr (assq 'pred alist))
(window-list)
:key #'window-buffer)))
(when (and win (window-live-p win))
(with-selected-window win
(display-buffer-same-window buf alist)))))
(defmacro display-grouped (pred actions &rest alist)
(let ((pfun (eval pred)))
`'(,pfun ,(push 'display-buffer-pred-window actions)
,@(push `(pred . ,pfun) alist))))
(setq display-buffer-alist
`(("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil
(window-parameters (mode-line-format . none)))
("\\`\\*Warnings\\*"
(display-buffer-in-side-window))
,(display-grouped
(buffer-fp-match! "/\\.lake/packages/")
(display-buffer-in-side-window)
(window-height . 0.6)
(side . bottom))
,(display-grouped
(buffer-mode-p! messages-buffer-mode)
(display-buffer-in-side-window)
(window-height . 0.3)
(side . bottom))
,(display-grouped
(buffer-mode-p! eat-mode)
(display-buffer-in-side-window)
(window-height . 0.3)
(side . bottom))
,(display-grouped
(buffer-mode-p! helpful-mode Info-mode)
(display-buffer-in-side-window)
(window-width . 80)
(side . right))
(shackle-display-buffer-condition shackle-display-buffer-action)))(defcustom abbrev/math-text-lang 'pt
"docs"
:safe #'symbolp)
(defun abbrev/set-math-text-lang ()
(interactive)
(when-let* ((key (car (org-collect-keywords '("language")))))
(setq abbrev/math-text-lang (make-symbol (cadr key)))))
(defun abbrev/math-text-pt-p () (and (not (texmathp)) (string= abbrev/math-text-lang 'pt)))
(defun abbrev/math-text-en-p () (and (not (texmathp)) (string= abbrev/math-text-lang 'en)))(setq abbrev/math-text-abbrevs-pt
'(("pa" "podemos assumir")
("pd" "por definição")
("ie" "i.e.")
("tq" "tal que")
("ssg" "suficientemente grande")
("spg" "sem perda de generalidade")
("qtp" "q.t.p.")
("sss" "se, e somente se,")
("mdd" "medida")
("cjto" "conjunto")
("li" "linearmente independentes")))
(setq abbrev/math-text-abbrevs-en
'(("wlog" "without loss of generality")
("iff" "if, and only if,")
("ie" "i.e.")
("st" "such that")
("ae" "a.e.")
("pos" "positive")
("neg" "negative")
("wrt" "with respect to")
("meas" "measure")
("bd" "by definition")
("li" "linearly independent")))(setq abbrev/var-abbrevs-pt '(b c d f g h i j k l m n p q r s t u v w x y z))
(setq abbrev/var-abbrevs-en '(b c d e f g h j k l m n o p q r s t u v w x y z))
(defun abbrev/compile-var-abbrevs (abbrevs)
(mapcar (lambda (s) (list (symbol-name s) (format "\\(%s\\)" s) nil :system t))
abbrevs))(setq abbrev/tables
`((abbrev/math-text-pt-table
,(append
abbrev/math-text-abbrevs-pt
(abbrev/compile-var-abbrevs abbrev/var-abbrevs-pt))
abbrev/math-text-pt-p)
(abbrev/math-text-en-table
,(append
abbrev/math-text-abbrevs-en
(abbrev/compile-var-abbrevs abbrev/var-abbrevs-en))
abbrev/math-text-en-p)))
(defun abbrev/setup ()
(require 'abbrev)
(setq-local local-abbrev-table nil)
(pcase-dolist (`(,name ,defs ,cond) abbrev/tables)
(define-abbrev-table name defs :enable-function cond)
(push (symbol-value name) local-abbrev-table))
(abbrev-mode))
(add-hook 'LaTeX-mode-hook #'abbrev/setup)Custom predicate for composing only inside LaTeX delimiters.
(defun math-prettify--symbols-compose-p (start end _match)
(and
(or
;; Allow for math delimiters
(eq ?\) (char-before end))
(eq ?\( (char-before end))
;; Only compose inside math
t)
(or
;; If the matched symbol doesn't end in a word character, then we
;; simply allow composition. The symbol is probably something like
;; \|, \(, etc.
(not (eq ?w (char-syntax (char-before end))))
;; Else we look at what follows the match in order to decide.
(let* ((after-char (char-after end))
(after-syntax (char-syntax after-char)))
(not (or
;; Don't compose \alpha@foo.
(eq after-char ?@)
;; The \alpha in \alpha2 or \alpha-\beta may be composed but
;; of course \alphax may not.
(and (eq after-syntax ?w)
(not (memq after-char
'(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?+ ?- ?' ?\" ?$ ?_))))
;; Don't compose inside verbatim blocks.
(eq 2 (nth 7 (syntax-ppss)))))))))(defvar math-prettify--symbols-alist nil)
(with-eval-after-load 'tex-mode
(setq math-prettify--symbols-alist
(append
'(("\\left" . ?ʟ)
("\\right" . ?ʀ)
("\\middle" . ?ᴍ)
("\\tilde" . ?˜)
("\\implies" . ?⇒)
("\\colon" . ?:)
("\\impliedby" . ?⇐)
("\\sqrt" . ?√)
("\\dots" . ?…)
("\\not\\subset" . ?⊄))
(bound-and-true-p tex--prettify-symbols-alist))))
(defun math-prettify-activate ()
(interactive)
(setq-local prettify-symbols-alist math-prettify--symbols-alist)
(setq-local prettify-symbols-unprettify-at-point 'right-edge)
(setq-local prettify-symbols-compose-predicate
#'math-prettify--symbols-compose-p)
(prettify-symbols-mode))
;; (dolist (h '(LaTeX-mode-hook latex-mode-hook org-mode-hook))
;; (add-hook h #'math-prettify-activate))(use-package citar
:init
(put 'citar-bibliography 'safe-local-variable #'list-of-strings-p)
:config
(setopt citar-file-open-functions '(("pdf" . citar-file-open-external)
(t . citar-file-open-external))
citar-bibliography '("~/Zotero/bibs/all.bib")
org-cite-csl-styles-dir "~/Zotero/styles"
citar-symbol-separator " "))(use-package citar-embark
:after embark
:init
(citar-embark-mode))(defun boox/copy-and-process (basename callback)
(let ((fp "/adb:8A3DF2BF:storage/self/primary/note/export/export.pdf"))
(when (file-readable-p fp)
(when-let* ((tmpdir (make-temp-file "boox-export" t))
(tmpin (concat tmpdir "/in.pdf"))
(tmpout (format "%s/%s.png" tmpdir basename)))
(copy-file fp tmpin)
(let ((lastpage (shell-command-to-string (format "pdfinfo %s | awk '/^Pages:/ {print $2}'" tmpin)))
(marker (point-marker)))
(async-start-process
"inkscape-convert"
"inkscape"
(lambda (_)
(message "Inkscape finished.")
(with-current-buffer (marker-buffer marker)
(without-restriction
(save-excursion
(goto-char (marker-position marker))
(condition-case e
(funcall callback tmpout)
(error (message "Handler threw an error: %s" e)))
(delete-directory tmpdir t nil)))))
"--actions=select-by-selector:svg>g>use;delete;page-fit-to-selection"
"--pdf-poppler"
(concat "--pages=" lastpage)
"-o" tmpout
tmpin))))))
(defun boox/org-handler (tmpout)
(require 'org-attach)
(require 'org-download)
(let ((org-attach-store-link-p 'attached))
(org-attach-attach tmpout nil 'cp))
(org-insert-link nil (caar org-stored-links) ""))
(defun boox/tex-handler (tmpout)
(let* ((file (read-file-name "Directory or file: " nil ""))
(out (if (or (string= file "") (file-directory-p file))
(concat file (file-name-nondirectory tmpout))
file)))
(make-directory (file-name-directory out) 't)
(copy-file tmpout out t)
(let ((LaTeX-default-environment "figure")
(TeX-default-macro "includegraphics")
(LaTeX-includegraphics-read-file (lambda () (file-relative-name out))))
(call-interactively #'LaTeX-environment)
(call-interactively #'TeX-insert-macro))))
(defvar boox/handlers '((org-mode . boox/org-handler)
(latex-mode . boox/tex-handler)))
(defun boox/attach-last-figure-adb (basename)
(interactive "sName: ")
(if-let* ((handler (alist-get major-mode boox/handlers)))
(boox/copy-and-process basename handler)
(message "No handlers available for mode.")))(use-package aas
:ensure nil
:init
(defun +activate-aas-h ()
(require 'latex)
(aas-mode)
(setq-local TeX-font-list LaTeX-font-list)
(LaTeX-math-mode)
(aas-activate-keymap 'aas-math))
(dolist (h '(LaTeX-mode-hook markdown-mode-hook))
(add-hook h #'+activate-aas-h))
:config
(defvar-local aas-math-delimiters (cons "\\(" "\\)"))
(defvar-mode-local markdown-mode
aas-math-delimiters (cons "$" "$"))
(defun tex-not-command-p ()
(and (not (looking-back "\\\\[[:alpha:]]*?" (line-beginning-position)))
(not (looking-back "\\(^\\|[^\\]\\)\\[[^]]*" (line-beginning-position)))))
(defun latex-brace-tempel-elt (elt)
(when (eq (car-safe elt) 'sb)
(let ((var (or (nth 3 elt) 'sb-str)))
`(l ,(nth 1 elt)
(if (length> ,var 1) "{" "")
(p ,(nth 2 elt) ,var)
(if (length> ,var 1) "}" "")))))
(defun i-binop (str)
(cmd!
(if (memq (char-before) '(?\( ?\{ ?\[ ?^ ?_))
(insert str)
(insert (if (eq (char-before) 32) "" " ") str " "))))
(with-eval-after-load 'tempel
(add-to-list 'tempel-user-elements #'latex-brace-tempel-elt))
(aas-set-snippets 'aas-math
:cond (lambda ()
(and (memq (char-before) '(32 ?- ?\( ?\n))
(not (texmathp))))
" " '(tempel (car aas-math-delimiters) q (cdr aas-math-delimiters))
";cas" '(tempel "\\begin\{cases\}" p "\\end\{cases\}")
:cond #'texmathp
".." "\\dots"
"+" (i-binop "+")
"-" (i-binop "-")
"=" (i-binop "=")
"<" (i-binop "<")
">" (i-binop ">")
"**" (i-binop "\\cdot")
"_" '(tempel (sb "_" "n"))
"^" '(tempel (sb "^" "n"))
:cond (lambda () (and (tex-not-command-p) (texmathp)))
"em" (i-binop "\\in")
"xx" (i-binop "\\times")
"ss" (i-binop "\\subseteq")
"sps" (i-binop "\\supeteq")
"ne" (i-binop "\\ne")
"le" (i-binop "\\le")
"ge" (i-binop "\\ge")
"com" (i-binop "\\circ")
"norm" (cmd! (TeX-insert-macro "norm"))
"abs" (cmd! (TeX-insert-macro "abs"))
"set" (cmd! (TeX-insert-macro "set"))
"fun" '(tempel (p "f") " \\colon " (p "A") " \\to " (p "B"))
;; Modifiers
"bb" (cmd! (TeX-font nil 19))
"cal" (cmd! (TeX-font nil 1))
"tt" (cmd! (TeX-font nil 20))
"sr" (cmd! (TeX-insert-macro "sqrt"))
"fr" '(tempel "\\frac{" p "}{" p "}")
"to" (i-binop "\\to")
"mto" (i-binop "\\mapsto")
"sm" (i-binop "\\setminus")
"NN" "\\NN"
"ZZ" "\\ZZ"
"xto" (cmd! (TeX-insert-macro "xrightarrow"))
"oo" "\\infty"
"c.." "\\cdots"
"sq" "^2"
"cb" "^3"
"inv" "^{-1}"
"lim" '(tempel "\\lim" (sb "_" "n \\to \\infty") " ")
"bcap" '(tempel "\\bigcap" (sb "_" "i = 1") (sb "^" "\\infty" v2) " ")
"bcup" '(tempel "\\bigcup" (sb "_" "i = 1") (sb "^" "\\infty" v2) " ")
"prod" '(tempel "\\prod" (sb "_" "i = 1") (sb "^" "\\infty" v2) " ")
"sum" '(tempel "\\sum" (sb "_" "i = 1") (sb "^" "\\infty" v2) " ")
"bsum" '(tempel "\\frac{1}{" (p "n" var) "}\\sum_{" (p "i") " = 0}^{" var " - 1} ")
"int" '(tempel "\\int" (sb "_" "-\\infty") (sb "^" "\\infty" v2) " " p (when (length> meas 0) "\\;d") (p "\\mu" meas))
"arccos" "\\arccos"
"arccot" "\\arccot"
"arccot" "\\arccot"
"arccsc" "\\arccsc"
"arcsec" "\\arcsec"
"arcsin" "\\arcsin"
"arctan" "\\arctan"
"cos" "\\cos"
"cot" "\\cot"
"csc" "\\csc"
"exp" "\\exp"
"ln" "\\ln"
"log" "\\log"
"perp" "\\perp"
"sin" "\\sin"
"star" "\\star"
"gcd" "\\gcd"
"min" "\\min"
"max" "\\max"
"inf" "\\inf"
"sup" "\\sup"))(use-package evil-tex
:hook ((LaTeX-mode org-mode) . evil-tex-mode))(use-package denote
:config
(setopt denote-file-type 'markdown-yaml))
(use-package denote-explore)
(use-package denote-refs)
(use-package consult-denote
:after (:and denote consult)
:init
(consult-denote-mode))
(use-package denote-menu)(use-package citar-denote
:after denote
:init
(citar-denote-mode))(use-package mixed-pitch
:hook (LaTeX-mode)
:init
(defun add-fixed-face-to-prespace ()
"Add fixed-pitch face to all spaces at line starts."
(font-lock-add-keywords nil '(("^\\( +\\)" (1 'fixed-pitch append)))))
:config
(add-hook 'mixed-pitch-mode-hook #'add-fixed-face-to-prespace)
(add-hook 'mixed-pitch-mode-hook
(defun mixed-pitch-line-spacing-h ()
(setq line-spacing 6)))
(add-to-list 'mixed-pitch-fixed-pitch-faces 'rainbow-delimiters-depth-1-face))
(use-package rainbow-delimiters
:hook (LaTeX-mode))(use-package org-roam
:custom
(org-roam-directory (file-truename "~/dados/notas/"))
(org-roam-capture-templates
'(("d" "default" plain "%?"
:target (file+head "%<%Y%m%d%H%M%S>.org" "#+title: ${title}
#+language: pt
")
:unnarrowed t
("m" "math" plain "%?"
:target (file+head "math/%<%Y%m%d%H%M%S>.org" "#+title: ${title}
#+language: pt
")
:unnarrowed t))))
(org-roam-capture-ref-templates
'(("m" "math" plain "%?"
:target (file+head "math/%<%Y%m%d%H%M%S>.org" "#+title: ${title}\n\n${body}")
:unnarrowed t)
("fr" "Add to my future-read list" entry "* ${title}\n%?"
:target (file+olp "to-read.org" ("${title}"))
:empty-lines-before 1 nil nil)
("r" "ref" plain "%?" :target
(file+head "${slug}.org" "#+title: ${title}")
:unnarrowed t)))
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . org-roam-node-find)
("C-c n g" . org-roam-graph)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
;; Dailies
("C-c n j" . org-roam-dailies-capture-today))
:config
;; If you're using a vertical completion framework, you might want a more informative completion interface
(setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
(org-roam-db-autosync-mode)
;; If using org-roam-protocol
(require 'org-roam-protocol))(use-package org-mem
:config
(setopt org-mem-watch-dirs '("~/dados/notas/")
org-mem-do-sync-with-org-id t)
(org-mem-updater-mode))
(use-package org-node
:config
(org-node-cache-mode)
(org-node-roam-accelerator-mode)
(setopt org-node-creation-fn #'org-node-new-via-roam-capture
org-node-file-slug-fn #'org-node-slugify-like-roam-default
org-node-file-timestamp-format "%Y%m%d%H%M%S-"))
(put 'org-attach-id-dir 'safe-local-variable #'stringp)(set-face-font 'default (font-spec :family "Victor Mono" :size 13 :weight 'medium))
(custom-set-faces
'(fixed-pitch ((t (:family "Victor Mono"))))
'(variable-pitch ((t (:weight normal :family "IBM Plex Sans"))))
'(ef-themes-ui-variable-pitch ((t (:inherit variable-pitch)))))(use-package ligature
:init
(global-ligature-mode t)
:config
(ligature-set-ligatures
'haskell-ts-mode
'("</" "</>" "/>" "~-" "-~" "~@" "<~" "<~>" "<~~" "~>" "~~"
"~~>" ">=" "<=" "<!--" "##" "###" "####" "|-" "-|" "|->"
"<-|" ">-|" "|-<" "|=" "|=>" "<-" "<--" "-->" "->" "-<"
">->" ">>-" "<<-" "<->" "->>" "-<<" "<-<" "==>" "=>" "=/="
"!==" "!=" "<==" ">>=" "=>>" ">=>" "<=>" "<=<" "<<=" "=<<"
".-" ".=" "=:=" "=!=" "==" "===" "::" ":="
"<|" "<|>" "|>" "<>" "<$" "<$>" "$>" "<+" "<+>" "+>"
"?=" "/=" "/==" "/\\" "\\/" "__" "&&" "++" "+++"))
(ligature-set-ligatures
'lean-ts-mode
'("</" "</>" "/>" "~-" "-~" "~@" "<~" "<~>" "<~~" "~>" "~~"
"~~>" ">=" "<=" "<!--" "##" "###" "####" "|-" "-|" "|->"
"<-|" ">-|" "|-<" "|=" "|=>" "<-" "<--" "-->" "->" "-<"
">->" ">>-" "<<-" "<->" "->>" "-<<" "<-<" "==>" "=>" "=/="
"!==" "!=" "<==" ">>=" "=>>" ">=>" "<=>" "<=<" "<<=" "=<<"
".-" ".=" "=:=" "=!=" "==" "===" "::" ":="
"<|" "<|>" "|>" "<>" "<$" "<$>" "$>" "<+" "<+>" "+>"
"?=" "/=" "/==" "/\\" "\\/" "__" "&&" "++" "+++")))(setopt use-default-font-for-symbols t
scalable-fonts-allowed t
face-font-selection-order '(:height :width :weight :slant)
face-font-rescale-alist '(("JuliaMono" . 0.99)
("Symbols Nerd Font Mono" . 0.90)))
(defun adjust-symbolic-fonts ()
(setup-default-fontset)
(dolist (script '(symbol mathematical unicode))
(set-fontset-font t script (font-spec :family "Julia Mono" :weight 'normal))
(set-fontset-font t script (font-spec :family "Victor Mono") nil 'append))
(dolist (script '(han kana cjk-misc kanbun bopomofo ideographic-description))
(set-fontset-font t script (font-spec :family "IBM Plex Sans JP")))
(set-fontset-font t 'emoji "Twemoji" nil 'prepend))
(adjust-symbolic-fonts)
(add-hook 'after-setting-font-hook #'adjust-symbolic-fonts)(setopt tool-bar-mode nil
scroll-bar-mode nil
menu-bar-mode nil)(use-package darkroom
:ensure (:repo "~/dados/projetos/codigo/emacs/darkroom/")
:hook ((text-mode prog-mode conf-mode) . darkroom-mode)
:config
(setopt darkroom-fringes-outside-margins nil
darkroom-text-scale-increase 0))- write split-window-preferred-function (window-parameter window ‘split-window)
(use-package indent-bars
:custom
(indent-bars-no-descend-lists t) ; no extra bars in continued func arg lists
(indent-bars-treesit-support t)
(indent-bars-width-frac 0.1)
(indent-bars-pad-frac 0.4)
(indent-bars-treesit-ignore-blank-lines-types '("module"))
;; Add other languages as needed
(indent-bars-depth-update-delay 0.075)
(indent-bars-starting-column nil)
(indent-bars-display-on-blank-lines 'least)
(indent-bars-treesit-wrap '((rust arguments parameters)))
(indent-bars-treesit-scope '((rust trait_item impl_item
macro_definition macro_invocation
struct_item enum_item mod_item
const_item let_declaration
function_item for_expression
if_expression loop_expression
while_expression match_expression
match_arm call_expression
token_tree token_tree_pattern
token_repetition)))
:hook ((prog-mode) . indent-bars-mode))(fringe-mode '(4 . 4))(use-package ef-themes
:bind (:map toggle-map ("t" . ef-themes-toggle))
:custom-face
(ef-themes-fixed-pitch ((t (:inherit fixed-pitch))))
:config
(setopt ef-themes-to-toggle '(ef-reverie ef-dream)
ef-themes-mixed-fonts t
ef-themes-variable-pitch-ui t))(use-package doric-themes)This is a beatiful, extremely readable and highly customizable theme. Protesilaos at its finest. I like it a lot for long writing sessions without worries about getting sick or distracted by a colorful theme.
(use-package modus-themes
:ensure nil
:custom-face
(modus-themes-tab-active ((t (:box nil))))
(modus-themes-tab-inactive ((t (:box nil))))
:custom
(modus-themes-tabs-accented t)
(modus-themes-variable-pitch-ui t)
(modus-themes-mixed-fonts t)
(modus-themes-common-palette-overrides
'((fringe nil)
(bg-prose-block-contents bg-yellow-nuanced)
(bg-prose-block-delimiter bg-ochre)
(fg-prose-block-delimiter yellow-cooler)))
(modus-themes-mode-line '(accented borderless)))Let’s change the color of the terminal background to match the theme color.
(defun set-terminal-theme (bg cursor)
"Set the terminal background BG and CURSOR (in #rrggbb)."
(when (not (display-graphic-p)) ; only in TTY
(send-string-to-terminal (format "\e]11;%s\a" bg))
(send-string-to-terminal (format "\e]12;%s\a" cursor))))
(defun sync-theme-to-terminal ()
(let ((bg (face-attribute 'default :background))
(cs (face-attribute 'cursor :background)))
(set-terminal-theme bg cs)))
(add-hook 'after-enable-theme-hook #'sync-theme-to-terminal)(use-package doom-modeline
:init
(doom-modeline-mode)
:config
(custom-set-faces
'(mode-line ((t (:family "Julia Mono" :height 95))))
'(mode-line-inactive ((t (:family "Julia Mono" :height 95))))
'(doom-modeline-buffer-read-only-modeoodified ((t (:underline t)))))
(setopt doom-modeline-irc nil
doom-modeline-height 18
doom-modeline-buffer-encoding nil
doom-modeline-workspace-name nil
doom-modeline-display-misc-in-all-mode-lines nil
doom-modeline-bar-width 1
doom-modeline-icon nil))(with-eval-after-load 'doom-modeline
(doom-modeline-def-segment buffer-name
"Display the current buffer's name, without any other information."
(concat
(doom-modeline-spc)
(doom-modeline--buffer-name)))
(doom-modeline-def-segment pdf-icon
"PDF icon from all-the-icons."
(concat
(doom-modeline-spc)
(doom-modeline-icon 'octicon "file-pdf" nil nil
:face (if (doom-modeline--active)
'all-the-icons-red
'mode-line-inactive)
:v-adjust 0.02)))
(defun doom-modeline-update-pdf-pages ()
"Update PDF pages."
(setq doom-modeline--pdf-pages
(let ((current-page-str (number-to-string (eval `(pdf-view-current-page))))
(total-page-str (number-to-string (pdf-cache-number-of-pages))))
(concat
(propertize
(concat (make-string (- (length total-page-str) (length current-page-str)) 32)
" P" current-page-str)
'face 'mode-line)
(propertize (concat "/" total-page-str) 'face 'doom-modeline-buffer-minor-mode)))))
(doom-modeline-def-segment pdf-pages
"Display PDF pages."
(if (doom-modeline--active) doom-modeline--pdf-pages
(propertize doom-modeline--pdf-pages 'face 'mode-line-inactive)))
(doom-modeline-def-modeline 'pdf
'(bar window-number pdf-pages pdf-icon buffer-name)
'(misc-info matches major-mode process vcs)))When in a project, display Flymake diagnostics counts for the whole project.
(advice-add
'doom-modeline--flymake-count-errors :around
(defun doom-modeline--flymake-count-project-errors (old-fn)
(if (project-current)
(let ((warning-level (warning-numeric-level :warning))
(note-level (warning-numeric-level :debug))
(note 0) (warning 0) (error 0))
(dolist (diag (flymake--project-diagnostics))
(let ((severity (flymake--lookup-type-property
(flymake--diag-type diag)
'severity
(warning-numeric-level :error))))
(cond ((> severity warning-level) (cl-incf error))
((> severity note-level) (cl-incf warning))
(t (cl-incf note)))))
`((note . ,note) (warning . ,warning) (error . ,error)))
(funcall old-fn))))(use-package mlscroll
:init
(mlscroll-mode))(use-package hide-mode-line
:hook helpful-mode)(setopt xterm-set-window-title t
visible-cursor nil)
(add-hook 'tty-setup-hook #'xterm-mouse-mode)(use-package evil-terminal-cursor-changer
:hook (tty-setup . evil-terminal-cursor-changer-activate))(use-package kkp
:hook (tty-setup . global-kkp-mode))
;; :config
;; (setq kkp--progressive-enhancement-flags '((disambiguate-escape-codes :bit 1)
;; (report-alternate-keys :bit 4)
;; (report-all-keys-as-escape-codes :bit 8))
;; kkp-active-enhancements '(disambiguate-escape-codes
;; report-alternate-keys
;; report-all-keys-as-escape-codes)))(use-package clipetty
:init
(global-clipetty-mode))(add-hook 'server-after-make-frame-hook #'run-after-enable-theme-hook)(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(setopt fill-column 100)(add-to-list 'auto-mode-alist '("\\.c\\'" . c-ts-mode))(use-package parinfer-rust-mode
:hook emacs-lisp-mode)(use-package highlight-defined
:custom-face (highlight-defined-face-name-face ((t (:inherit nil))))
:hook (emacs-lisp-mode . highlight-defined-mode))(use-package elisp-mode
:ensure nil
:config
(add-hook 'emacs-lisp-mode-hook #'cursor-sensor-mode)
(setopt elisp-fontify-semantically t))(with-eval-after-load 'elisp-mode
(add-hook 'emacs-lisp-mode-hook #'flymake-mode)
(add-variable-watcher 'load-path (defun elpaca-load-path (_ newval op local)
(when (and (eq op 'set) (not local))
(setopt elisp-flymake-byte-compile-load-path
(cons "./" newval))))))(with-eval-after-load 'elisp-mode
(defun elisp-flymake-byte-compile--executable ()
"Return absolute file name of the Emacs executable for flymake byte-compilation."
(let ((filename
(when (stringp elisp-flymake-byte-compile-executable)
(if (file-name-absolute-p elisp-flymake-byte-compile-executable)
elisp-flymake-byte-compile-executable
(when-let* ((pr (project-current)))
(file-name-concat (project-root pr)
elisp-flymake-byte-compile-executable))))))
(if (and filename (file-executable-p filename))
filename
(when elisp-flymake-byte-compile-executable
(message "No such `elisp-flymake-byte-compile-executable': %s"
filename))
(expand-file-name invocation-name invocation-directory)))))(use-package haskell-ts-mode
:mode "\\.hs\\'"
:config
(setopt haskell-ts-prettify-words t)
(add-hook 'haskell-ts-mode-hook 'prettify-symbols-mode)
(add-hook 'haskell-ts-mode-hook 'eglot-ensure)
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(haskell-cabal-mode "haskell-language-server-wrapper" "--lsp"))
(setopt eglot-workspace-configuration
(plist-put eglot-workspace-configuration
:haskell `(:cabalFormattingProvider "cabal-gild"
:formattingProvider "fourmolu"
:plugin (:semanticTokens (:globalOn t)
:fourmolu (:config (:external t))))))))(defun haskell-guess-module-name (file)
"Guess Haskell module name from FILE, capitalizing path components only if needed."
(let* ((root (project-root (project-current t)))
(rel (file-relative-name file root))
(no-ext (file-name-sans-extension rel))
(parts (split-string no-ext "/")))
(string-join
(seq-filter (lambda (p) (char-uppercase-p (string-to-char p))) parts)
".")))
(with-eval-after-load 'autoinsert
(define-auto-insert
'(haskell-ts-mode . "Haskell module skeleton")
'(lambda ()
(let* ((module-name (haskell-guess-module-name buffer-file-name)))
(insert "module " module-name " where\n\n")))))(use-package julia-snail
:custom
(julia-snail-terminal-type :eat)
(julia-indent-offset 2)
:hook
(julia-mode . julia-snail-mode))(use-package lean-ts-mode
:ensure (:repo "~/dados/projetos/codigo/emacs/lean-ts-mode/"
:files ("*.el" "data")))
(with-eval-after-load 'autoinsert
(add-to-list 'auto-insert-alist
(cons '(predicate
(lambda ()
(when-let* ((_ (derived-mode-p 'lean-ts-mode))
(fp (buffer-file-name)))
(string-match-p "Mathlib/" fp))))
"mathlib.lean")))(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))
(add-hook 'conf-toml-mode-hook 'eglot-ensure)
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(conf-toml-mode . ("taplo" "lsp" "stdio"))))
(with-eval-after-load 'rust-ts-mode
(setopt rust-ts-mode-indent-offset 2))(use-package qml-ts-mode
:ensure (:host github :repo "xhcoding/qml-ts-mode")
:config
(setopt qml-ts-mode-indent-offset 2)
(add-hook 'qml-ts-mode-hook
(defun setup-qml-ts-mode ()
(setq-local electric-indent-chars '(?\n ?\( ?\) ?{ ?} ?\[ ?\] ?\; ?,))
(eglot-ensure))))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs '(qml-ts-mode "qmlls")))(use-package web-mode)(with-eval-after-load 'css-mode
(setopt css-indent-offset 2))(use-package typescript-ts-mode
:ensure nil
:mode (("\\.ts\\'" . typescript-ts-mode)
("\\.tsx\\'" . tsx-ts-mode))
:config
(add-hook 'typescript-ts-base-mode-hook #'eglot-ensure))(use-package js
:ensure nil
:mode (("\\.js\\'" . js-ts-mode))
:custom
(js-indent-level 2)
:config
(add-hook 'js-ts-mode-hook #'eglot-ensure))
(with-eval-after-load 'eglot
(setopt eglot-workspace-configuration
(plist-put eglot-workspace-configuration
:javascript (list :format (list :indentSize 2)))))(add-hook 'text-mode-hook #'visual-line-mode)
(with-eval-after-load 'text-mode
(setopt text-mode-ispell-word-completion nil))(use-package font-latex
:ensure nil
:custom-face (font-latex-math-face ((t (:inherit modus-themes-fixed-pitch))))
:config
(setopt font-latex-script-display '((raise -0.3) . (raise 0.4))
font-latex-fontify-script 'multi-level))(use-package tex
:ensure (auctex :pre-build (("./autogen.sh")
("./configure"
"--with-texmf-dir=$(dirname $(kpsexpand '$TEXMFHOME'))")
("make"))
:repo "https://github.com/emacsmirror/auctex.git"
:branch "master")
:hook (LaTeX-mode . (lambda () (require 'latex) (LaTeX-math-mode)))
:config
(add-hook 'LaTeX-mode-hook #'LaTeX-math-mode)
(add-hook 'LaTeX-mode-hook #'diff-hl-mode)
(add-hook 'LaTeX-mode-hook #'diff-hl-margin-local-mode)
(setopt TeX-parse-self t
TeX-auto-save t))
(use-package latex
:ensure nil
:hook (LaTeX-mode . eglot-ensure)
:bind (:map LaTeX-mode-map ("C-j" . nil))
:config
(setopt LaTeX-flymake-chktex-options '("-n1" "-n3"))
(add-hook 'LaTeX-mode-hook
(defun eglot-flymake-add-chktex ()
(add-hook 'eglot-managed-mode-hook
(lambda () (add-to-list 'flymake-diagnostic-functions 'LaTeX-flymake))
nil t)))
(modal-setmap LaTeX-mode-map mode-map
"@" #'citar-insert-citation
"!" #'citar-open-files))(use-package preview-dvisvgm
:after preview
:defer nil
:config
(setopt preview-image-type 'dvisvgm
TeX-PDF-mode nil
preview-dvisvgm-command "dvisvgm --bbox=preview --no-fonts %d --page=- --output=\"%m/prev%%3p.svg\""))
(with-eval-after-load 'preview
(setopt preview-default-preamble
'("\\RequirePackage[" ("," . preview-default-option-list)
"]{preview}[2004/11/05]"
"\\definecolor{fg}{rgb}{%(fg)}"
"\\definecolor{bg}{rgb}{%(bg)}"
"\\color{fg}"
"\\pagecolor{bg}"))
(setopt TeX-expand-list
'(("%(fg)" (lambda ()
(mapconcat #'preview-gs-color-value
(aref (nth 2 (preview-get-geometry)) 1)
",")))
("%(bg)" (lambda ()
(mapconcat #'preview-gs-color-value
(aref (nth 2 (preview-get-geometry)) 0)
",")))))
(setopt preview-leave-open-previews-visible t
preview-protect-point t
preview-scale-function (lambda ()
(let ((f (preview-scale-from-face)))
(lambda () (* 1.25 (funcall f))))))
(advice-add 'preview-inactive-string :override
(defun preview-inactive-string/better-newline (ov)
(concat
(preview-make-clickable (overlay-get ov 'preview-map)
(if preview-leave-open-previews-visible
(overlay-get ov 'preview-image)
preview-icon)
"\
%s redisplays preview
%s more options")
(with-current-buffer (overlay-buffer ov)
(save-excursion
(save-restriction
(widen)
(goto-char (overlay-start ov))
(beginning-of-line)
(skip-chars-forward "[:space:]")
(if (eq (point) (overlay-start ov))
(concat "\n" (buffer-substring-no-properties (pos-bol) (point)))
"")))))))
(advice-add 'preview-ascent-from-bb :filter-return
(defun preview-ascent-from-bb/add-offset (ascent)
(min 100 (+ ascent 3))))
(advice-add 'preview-create-icon :filter-return
(defun preview-create-icon/add-foreground (img)
(cons `(,@(car img) :foreground ,(face-attribute 'default :foreground))
(cdr img)))))
(use-package reftex
:ensure nil
:hook (LaTeX-mode . turn-on-reftex)
:config
(setopt reftex-label-alist '(("theorem" ?h "thm:" nil nil nil -3)
("lemma" ?l "lem:" nil nil nil -3)
("example" ?g "eg:" nil nil nil -3)
("corollary" ?c "col:" nil nil nil -3)
("proposition" ?p "prop:" nil nil nil -3))
reftex-ref-style-default-list '("Cleveref" "AMSmath")
reftex-plug-into-AUCTeX t
reftex-insert-label-flags '("s" "sfthlgcp")))lsp-mode, for some weird reason, is really lagging in LaTeX documents, while Eglot is not. This tends to annoy and distract me. Let’s create a simple interface to Texlab features with Eglot.
(with-eval-after-load 'eglot
(setopt eglot-workspace-configuration
(plist-put eglot-workspace-configuration
:texlab '(:build
(:args ["-interaction=nonstopmode" "-synctex=1" "%f"]
:buildParent t)
:forwardSearch
(:executable "sioyek"
:args ["--forward-search-file" "%f"
"--forward-search-line" "%l" "%p"])
;; (:executable "zathura"
;; :args ["--synctex-forward" "%l:1:%f" "%p"])
:experimental
(:labelReferenceCommands ["nameref"]))))
(defun eglot-texlab-build ()
(interactive)
(save-buffer)
(jsonrpc-async-request
(eglot--current-server-or-lose)
:textDocument/build (eglot--TextDocumentPositionParams)
:success-fn (lambda (r) (message "Build %s" r))
:error-fn (lambda (r) (message "Error %s" r))
:deferred t))
(defun eglot-texlab-forward-search ()
(interactive)
(jsonrpc-async-request
(eglot--current-server-or-lose)
:textDocument/forwardSearch (eglot--TextDocumentPositionParams)
:success-fn (lambda (r) (message "Search %s" r))
:error-fn (lambda (r) (message "Error %s" r))
:deferred t))
(with-eval-after-load 'latex
(modal-setmap LaTeX-mode-map mode-map
"a" #'eglot-texlab-build
"f" #'eglot-texlab-forward-search)
(setmap LaTeX-mode-map
"C-c C-a" #'eglot-texlab-build
"C-c C-c" #'eglot-texlab-forward-search
"C-c @" #'citar-insert-citation)))(use-package markdown-mode
:config
(setmap markdown-mode-map
"TAB" (smartparens-tab 'markdown-cycle))
(setopt markdown-fontify-code-blocks-natively t
markdown-enable-math t)
(modal-setmap markdown-mode-map mode-map
"@" #'citar-insert-citation
"!" #'citar-open-files)
(add-hook 'markdown-mode-hook #'smartparens-mode)
(with-eval-after-load 'smartparens
(sp-local-pair '(markdown-mode) "$" "$"
:actions '(wrap insert autoskip navigate))))
(use-package markdown-ts-mode
:ensure (:repo "~/dados/projetos/codigo/emacs/emacs/lisp/textmodes/"
:files ("markdown-ts-mode.el")))(use-package org
:ensure nil
:mode ("\\.org\\'" . org-mode)
:commands (org-mode)
:config
(require 'org-mouse)
(modal-setmap org-mode-map mode-map
"." #'consult-org-heading
"i" #'consult-org-heading
"s p" #'org-paste-subtree
"s y" #'org-copy-subtree
"s d" #'org-cut-subtree
"s a" #'org-archive-subtree
"l s" #'org-store-link)
(setmap org-mode-map "C-," nil)
(evil-define-key 'normal org-mode-map
"\\" #'org-edit-special
(kbd "TAB") #'org-cycle)
(evil-define-minor-mode-key 'normal 'org-src-mode "\\" #'org-edit-src-exit)
(setopt org-indent-indentation-per-level 1
org-src-window-setup 'split-window-below
org-directory "~/dados/org"
org-startup-indented t
org-support-shift-select t
org-insert-heading-respect-content t
org-hide-leading-stars t
org-fold-show-context-detail '((agenda . local) (bookmark-jump . lineage) (isearch . local) (default . ancestors))
org-id-method 'ts
org-src-lang-modes (cl-pushnew '("latex" . LaTeX) org-src-lang-modes)
org-highlight-latex-and-related '(native latex script)
org-src-preserve-indentation t)
(setq org-attach-auto-tag nil
org-attach-id-to-path-function-list
'(org-attach-id-ts-folder-format org-attach-id-uuid-folder-format identity)))(define-minor-mode organon-follow-mode
"Set whether organon should follow your every move in Emacs."
:lighter " organon"
:global t
:group 'organon
:init-value nil
(if organon-follow-mode
(progn
(add-hook 'post-command-hook #'organon--update-position)
(message "organon will now follow you around."))
(remove-hook 'post-command-hook #'organon--update-position)
(message "organon will now leave you alone.")))
(defvar organon--last-pos nil)
(defvar organon--conn nil)
(defun organon--connect ()
(require 'websocket)
(unless organon--conn
(websocket-open
"ws://127.0.0.1:9160"
:on-open (lambda (ws) (message "organon: connected") (setq organon--conn ws))
:on-close (lambda (ws) (message "organon: disconnected") (setq organon--conn nil)))))
(defun organon--get-info ()
(list :id (org-entry-get nil "ID" t)
:file (buffer-file-name)
:anchor (or (org-entry-get nil "CUSTOM_ID")
(condition-case nil
(let ((str (or (nth 4 (org-heading-components)) "")))
(string-match "[^[:alpha:]]*\\(.*\\)" str)
(substring str (match-beginning 1)))
(user-error nil)))))
(defun organon--update-position ()
(when-let* ((_ (eq major-mode 'org-mode))
(cur-pos (organon--get-info))
(_ (not (equal cur-pos organon--last-pos))))
(setq organon--last-pos cur-pos)
(send-to-organon)))
(defun send-to-organon ()
(interactive)
(organon--connect)
(when organon--conn
(let ((cur-info (organon--get-info)))
(websocket-send-text organon--conn (json-encode cur-info)))))(advice-add #'org-cycle-internal-local :around
(defun org-cycle-internal-local-ad (f)
(if (eq org-cycle-subtree-status 'children)
(let ((last-command nil))
(funcall f))
(funcall f))))Org reuses the org-src-font-lock-fontify-block function to fontify LaTeX fragments natively. But this function adds the very inappropiate face org-block to everything. Let’s remove it when the native block is one of our fragments.
(defvar org--font-locking-latex-fragment nil)
(advice-add #'org-do-latex-and-related :around
(defun signal-font-locking-latex (orig-fun &rest args)
(let ((org--font-locking-latex-fragment t))
(apply orig-fun args))))
(advice-add #'org-src-font-lock-fontify-block :after
(defun do-not-org-block-my-latex-advice (_ start end)
(when org--font-locking-latex-fragment
(alter-text-property start end 'face (lambda (l) (remove 'org-block l))))))(defun org-add-indent-face-to-prespace ()
(setq
org-font-lock-extra-keywords
(append (delete
'("^ *\\([-+]\\|\\(?:[0-9]+\\|[a-zA-Z]\\)[).]\\)[ \t]" 1 'org-list-dt append)
org-font-lock-extra-keywords)
;; Add org-indent face to all spaces at line starts
'(("^\\( +\\)"
(1 'org-indent append))
;; Also fontify * bullets
("^ +\\(\\*\\)\\([ \t]\\)"
(1 'org-list-dt append)
(2 'org-indent append))
;; This is modified from user @psii
;; https://github.com/doomemacs/themes/pull/716
("^ *\\([-+]\\|\\(?:[0-9]+\\|[a-zA-Z]\\)[).]\\)\\([ \t]\\)"
(1 'org-list-dt append)
(2 'org-indent append))))))
(add-hook 'org-font-lock-set-keywords-hook #'org-add-indent-face-to-prespace)We can also make list bullets fixed-pitch, so they are even more aligned.
(with-eval-after-load 'mixed-pitch
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-list-dt)
(add-to-list 'mixed-pitch-fixed-pitch-faces 'rainbow-delimiters-depth-1-face))(defun org-fontify-counter-cookies ()
(setq
org-font-lock-extra-keywords
(append org-font-lock-extra-keywords
'(("^[ \t]*\\(?:[-+*]\\|\\(?:[0-9]+\\|[a-zA-Z]\\)[.)]\\)[ \t]+\\(\\[@\\(?:start:\\)?\\(?:[0-9]+\\|[a-zA-Z]\\)\\]\\)"
(1 'org-property-value prepend))))))
(add-hook 'org-font-lock-set-keywords-hook #'org-fontify-counter-cookies)(use-package org-superstar
:after (org)
:hook (org-mode . org-superstar-mode)
:config
(setq org-superstar-headline-bullets-list '(?◆ ?❉ ?🞱 ?🞽 ?✺)))(use-package kdl-ts-mode
:mode "\\.kdl\\'"
:ensure (:repo "https://github.com/dataphract/kdl-ts-mode.git" :main "kdl-ts-mode.el"))(use-package yaml-mode)(use-package systemd)
(use-package daemons)
(with-eval-after-load 'autoinsert
(add-to-list 'auto-insert-alist
(cons 'systemd-mode
(lambda ()
(tempel-insert
'("[Unit]" n
"PartOf="(p "graphical-session" tgt)".target" n
"After=" tgt ".target" n
"Requisite=" tgt ".target" n n
"[Service]" n
"ExecStart=" p n
"Restart=on-failure"))))))(use-package pdf-tools
:mode ("\\.pdf\\'" . pdf-view-mode)
:config
(setopt pdf-view-display-size 'fit-page)
(add-hook 'pdf-view-mode-hook
(defun pdf-evil-disable-cursor ()
(set (make-local-variable 'evil-normal-state-cursor) (list nil))))
(advice-add 'pdf-view-enlarge :after (lambda (_) (pdf-view-center-in-window))))(use-package ement)(use-package smudge
:config
(setopt smudge-oauth2-client-id "55d2deb3878f4b73912f72a3a131024c"
smudge-oauth2-client-secret (api-key-from-auth-source "api.spotify.com")))