Fichero de Configuración de Emacs

Table of Contents

1. Sobre este fichero

Este es mi fichero de configuración de Emacs, usando Programación Literaria.

Está configurado para Emacs 29.1 o superior.

Es un intento de simplificar la configuración de Emacs, después de usar spacemacs por años.

Se ha creado usando los consejos de https://github.com/frap/emacs-literate

2. Configuración General

Configuración que mejora sin paquetes adicionales.

2.1. Mensajes de depuración

Primero activo los mensajes de depuración

;  (setq debug-on-error t)
  (setq user-full-name "Daniel Molina"
  user-mail-address "dmolina@decsai.ugr.es")

2.2. Añado Melpa

Añado el Repositorio Melpa

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Comment/uncomment this line to enable MELPA Stable if desired.  See `package-archive-priorities`
;; and `package-pinned-packages`. Most users will not need or want to do this.
;;(add-to-list 'package-archives ("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)

2.3. Hago que use-package compruebe siempre

(setq use-package-always-ensure t)

2.4. Permito instalar paquetes de github

(use-package vc-use-package
     :ensure t)

2.5. Al borrar debe enviar a papelera

(setq delete-by-moving-to-trash t)
; (setq trash-directory "~/.Trash")

Y añado un paquete para permitir recuperar/eliminar de la papelera más cómodamente.

(use-package trashed
 :ensure t
 :bind ("C-c T" . trashed))

2.6. Quito la ventana por defecto

(setq inhibit-startup-message t)  ; Dont show the splash screen

2.7. Desactivo el scroll inicial

Desactivo el tool-bar y el scroll, que me pone nervioso.

(tool-bar-mode -1)
(scroll-bar-mode -1)

2.8. Activo backup

Creo los ficheros de backup en directorios especiales para no mezclarlos con los directorios originales.

(make-directory "~/.emacs_backups/" t)
(make-directory "~/.emacs_autosave/" t)
(setq auto-save-file-name-transforms '((".*" "~/.emacs_autosave/" t)))
(setq backup-directory-alist '(("." . "~/.emacs_backups/")))

Lo hace más eficiente:

(setq backup-by-copying t)

2.9. Modo visual

Activo en todos los ficheros visual-line-mode que permite visualizar las líneas que no caben en varias líneas en vez de tener que hacer scroll.

(global-visual-line-mode)

2.10. Numero líneas

Numero las líneas de los ficheros a programar usando opción del propio emacs.

;; Display line numbers in every buffer
(add-hook 'prog-mode-hook 'display-line-numbers-mode)

2.11. Destaco la línea actual

Hago que la línea actual destaque.

(global-hl-line-mode)

2.12. Simplificar confirmación

Permito usar y/n en vez de yes/no:

(fset 'yes-or-no-p 'y-or-n-p)

2.13. Mostrando hora

Muestro la hora abajo

(display-time-mode 1)

2.14. Uso de ibuffer

Ibuffer es mejor que el formato por defecto, pero no se activa con "C-x C-b".

(global-set-key (kbd "C-x C-b") 'ibuffer)

2.15. Ordenar los buffer por último acceso

Este paquete permite que los buffer se ordenen por frecuencia en vez de por nombre:

(use-package bookmark-frecency
:ensure t
:config
(bookmark-frecency-mode 1)
(setq bookmark-sort-flag 'last-modified)
)

2.16. Moverme fácilmente entre ventanas

Tab y flechas permite moverme entre la ventana.

(windmove-default-keybindings)

Además, hago que F3 me cambie de ventana.

(use-package ace-window
    :ensure t
    :bind (("<f3>" . ace-window))
)

2.17. Aumentar memoria

Permito uso de más memoria antes del recolector de basura, para mejorar rendimiento.

(setq gc-cons-threshold 100000000)

2.18. Permitir copiar/mover entre carpetas

Dired permite copiar/mover ficheros entre carpetas si hay más de una ventana de directorio.

(setq dired-dwim-target t)

2.19. Ignorar backups en dired

Mientras se trabajan ficheros se crean ficheros auxiliares tanto por backup como por los undo, pero son molestos de ver.

Esta configuración los hace "invisibles" en dired

(add-hook 'dired-mode-hook 'dired-omit-mode)

2.20. Mejorar el listado en eshell

Indico que quiero los ficheros antes que los directorios

Primero pongo coloreS:

(setq eshell-ls-use-colors t)

Añado autocompletado tras un cd.

(setq eshell-list-files-after-cd t)

Indico opciones por defecto, tamaño para humanos, con detalles, y ordenado por fecha:

(setq eshell-ls-initial-args '("-hlt"))

2.21. Evitar molestos mensajes sobre Async

Al crear un programa en segundo plano (como un mpv, o algo), sale un molesto mensaje sobre si quiero otro. Esto debería de evitar ese molesto mensaje, al renombrar el anterior.

(defadvice shell-command (after shell-in-new-buffer (command &optional output-buffer error-buffer))
    (when (get-buffer "*Async Shell Command*")
      (with-current-buffer "*Async Shell Command*"
         (rename-uniquely))))
 (ad-activate 'shell-command)

3. Paquetes imprescindibles

3.1. Ver las teclas posibles

Es uno de mis imprescindibles, al empezar al pulsar teclas muestra las opciones posibles.

  (use-package which-key
  :ensure t
  :config
  (which-key-mode)
)

3.2. Deshacer

Es un imprescindible, la mejora del undo.

(use-package undo-tree
:diminish
:bind (("C-c _" . undo-tree-visualize))
:config
(global-undo-tree-mode +1)
(unbind-key "M-_" undo-tree-map))

3.3. Ver ficheros recientes

Inicio recentf para cargar últimos ficheros.

(use-package recentf
:config
(add-to-list 'recentf-exclude "\\elpa")
(setq recentf-max-menu-items 50)
(setq recentf-max-saved-items 500)
(global-set-key "\C-x\ \C-r" 'recentf-open-files)
(recentf-mode 1))

Añado directorios a los ficheros recientes con `recentf-ext`.

(use-package recentf-ext
:ensure t)

3.4. Ruta paquetes

Ahora cambio la ruta de los paquetes a instalar.

(setq startup-redirect-eln-cache "~/Descargas/emacs/emacs.d")

3.5. Smarparens

Vamos a poder marcar un paréntesis con otro:

(use-package smartparens
   :ensure t
:hook (prog-mode text-mode markdown-mode latex-mode) ;; add `smartparens-mode` to these hooks
:config
;; load default config
(require 'smartparens-config)
)

3.6. VTerm

Terminal avanzado, necesario para julia y otros sistemas.

(use-package vterm
  :ensure t)

3.7. Expandir región

Con esto se permite ir expandiendo la región seleccionada.

  (use-package expand-region
    :ensure t
    :bind (("C-+" . er/expand-region)
           ("C--" . er/contract-region))
)

3.8. Uso de M-x con histórico

M-x siempre muestra alfabéticamente, pero con esto muestra primero las más recientes.

(use-package amx
  :ensure t
  :config
  (amx-mode)
  )

3.9. Projectile

Permite moverse y trabajar más cómodamente entre proyectos (los identifica por estar en un SCV o usar ficheros de compilación como Make, …).

Aunque project, que viene con Emacs cada vez es más potente, `projectile` admite más tipos de documentos.

(use-package projectile
:ensure t
:init
(projectile-mode +1)
:bind (:map projectile-mode-map
            ("s-p" . projectile-command-map)
            ("C-c p" . projectile-command-map)))

Uso consult para autocompletar:

    (use-package consult-projectile
    :ensure t
    :after (projectile consult)
)

3.10. Plantillas con Yasnippet

Estas plantillas permiten simplificar la escritura de muchos tipos de documentos.

(use-package yasnippet
  :ensure t
  :config
  (yas-reload-all)
  :hook (prog-mode . yas-minor-mode)
  :hook (latex-mode . yas-minor-mode)
  :hook (org-mode . yas-minor-mode)
) 

El listado de plantillas está en otro paquete:

  (use-package yasnippet-snippets
    :after yasnippet
    :ensure t
    :config
    (yas-reload-all)
)

3.11. EPub

Añado soporte de epub

(use-package nov
:ensure t
:mode ("\\.epub\\'" . nov-mode))

3.12. PDF

    (use-package pdf-tools
      :ensure t
      :magic ("%PDF" . pdf-view-mode)
      :config
      (pdf-tools-install :no-query)
;; Recargo siempre
(add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode)
)

Con esto permite cargar la última página vista:

(use-package pdf-view-restore
  :ensure t
  :after pdf-tools
  :config
  (add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode))

Permito actualizar sin preguntar.

(setq revert-without-query '(".pdf"))

3.12.1. Paquete org-pdftools

Permite

(use-package org-pdftools
  :hook (org-mode . org-pdftools-setup-link))

3.13. Markdown

(use-package markdown-mode
:ensure t
:mode ("\\.md\\'" . markdown-mode))

4. Distintos formatos

5. Mejorando manejo de ficheros

5.1. Eligiendo aplicaciones con &

Con "W" puedes abrir un programa, pero a veces interesa poner un programa distinto. Voy a definir para usar mpv y vlc para los de video.

(setq dired-guess-shell-alist-user
    '(("\\.mp4" "mpv" "vlc")
      ("\\.wmv" "mpv" "vlc")))

5.2. Dired-narrow

Para poder usar "s" en dired-mode para ver sólo los ficheros que cumplen el filtro. Con "g r" (revert) se anula el filtrado.

(use-package dired-narrow
   :ensure t)

5.3. Uso de directorios en recentf

Lo siguiente permite guardar los directorios en recientes.

  (use-package dired-recent
  :ensure t
  :init
  (dired-recent-mode 1)
)

5.4. No preguntar confirmación

(setq dired-clean-confirm-killing-deleted-buffers nil)
  (setq dired-no-confirm t)
  (setq dired-recursive-copies 'always)

5.5. Directorios primero

(setq dired-listing-switches "-aBhl  --group-directories-first")

5.6. Encontrar ficheros con fd

  (use-package quick-find-files
  :defer t
  :ensure t
:vc (:fetcher github :repo "Phundrak/quick-find-files.el")
  :custom ; Depending on your preferences, of course
  (quick-find-files-program 'fd)
    (quick-find-files-dirs '((:dir "~/Descargas/emacs/" :ext "org")
                             (:dir "~/Descargas")
                             (:dir "~/working")))
  )

5.7. Cambiar el criterio de ordenación

Por defecto en directorio con "o" se puede cambiar entre últimos y nombre. A veces nos interesa otro criterio como tamaño, … Con esto, al pulsar "C-c s" en un directorio lo ordena según un menú visual.

(use-package dired-quick-sort
  :ensure t
  :bind (:map dired-mode-map
        ("C-c s" . 'hydra-dired-quick-sort/body))       
)

6. Comprobar el texto

6.1. Uso de Diccionario

Inicio flyspell usando aspell.

(use-package flyspell
  :defer t
  :init
    (flyspell-mode 1)
  :config
    (setq ispell-program-name "aspell")
    (setq ispell-list-command "--list") ;; run flyspell with aspell, not ispell
  :hook ((text-mode . flyspell-mode)
         (prog-mode . flyspell-prog-mode))
 )

Añadimos flyspell-correct para elegir más fácilmente eligiendo con un popup.

  (use-package flyspell-correct
  :ensure t
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-popup
  :ensure t
  :after flyspell-correct
  :defer t)

Vamos a crear un reinicio si se cambia el diccionario.

(defun restart-flyspell-mode ()
  (when flyspell-mode
    (flyspell-mode-off)
    (flyspell-mode-on)))
(add-hook 'ispell-change-dictionary-hook 'restart-flyspell-mode)

Lo activo en modo org-mode y text-mode.

(defun turn-on-flyspell () (flyspell-mode 1)) 
 (add-hook 'org-mode-hook 'turn-on-flyspell)
 (add-hook 'text-mode-hook 'turn-on-flyspell)

Añadimos consult-flyspell para facilitar el cambio

(use-package consult-flyspell
  :ensure t
  :config
  ;; default settings
  (setq consult-flyspell-select-function 'flyspell-correct-at-point
        consult-flyspell-set-point-after-word t
        consult-flyspell-always-check-buffer nil))

6.2. Detecto el idioma

Con este paquete identifico el idioma a partir del texto de forma automática.

(use-package guess-language
  :ensure t
  :defer t
  :init (add-hook 'text-mode-hook #'guess-language-mode)
  :config
;; Optionally:
(setq guess-language-languages '(en es fr))
(setq guess-language-min-paragraph-length 35)
)

6.3. Flycheck

Este paquete permite mejorar la sintaxis de muchos lenguajes, incluyendo lenguaje natural.

  (use-package flycheck
    :ensure t
    :init (global-flycheck-mode)
)

6.4. Control de gramática con langtool

Esto requiere tener langtool instalado, como yo lo tengo lo configuro:

(use-package langtool
  :ensure t
  :config
  (setq langtool-java-classpath
      "/usr/share/languagetool:/usr/share/java/languagetool/*")
)

Y lo añado a flycheck:

  (use-package flycheck-languagetool
  :ensure t
  :after langtool flycheck
  :hook (text-mode . flycheck-languagetool-setup)
  :init
  (setq flycheck-languagetool-server-jar "/usr/share/java/languagetool/languagetool-server.jar")
) 

6.5. Añadiendo traducción automática

Añadimos soporte de Google Translate de text usando C-c G.

(use-package google-translate
  :ensure t
  :init
  (require 'google-translate-smooth-ui)
  :bind ("C-c G" . google-translate-smooth-translate))

7. Presentación

7.1. Cambio el powerline

El telephone-line es sencillo, y mantiene la hora.

(use-package telephone-line
    :ensure t
    :config
(telephone-line-mode 1)
)

;; Desactivo el color en projectile (pone verde por defecto)
(set-face-foreground 'telephone-line-projectile nil)

7.2. Tema

Uso el tema 'modus-operandi' ya que es muy claro, se puede poner en oscuro con `modus-themes-toggle`.

(use-package modus-themes
  :ensure t
  :config
  ;; Load the Modus Light theme
  (load-theme 'modus-operandi t)
  ;; Allow to use variable-pitch-mode without problems in org-table and code blocks.
  (setq modus-themes-mixed-fonts t)
  )

7.3. Padding

Con esto permite ampliar el padding entre buffer, con lo que es mucho más bonito.

(use-package spacious-padding
:ensure t
:config
(spacious-padding-mode 1))

7.4. Panel inicial

Permite un panel inicial.

  (use-package dashboard
    :ensure t
    :after all-the-icons
    :config
    (dashboard-setup-startup-hook)
      ;; Content is not centered by default. To center, set
  (setq dashboard-center-content t)
  ;; use `all-the-icons` package
    (setq dashboard-icon-type 'all-the-icons)
  ;; To add icons to the widget headings and their items:
  ; (setq dashboard-set-heading-icons t)
; (setq dashboard-set-file-icons t)
    (setq dashboard-projects-backend 'projectile)
   (setq dashboard-items '(
                      (projects . 5)
                      (recents  . 5)
                        (agenda . 5)
                      ; (bookmarks . 5)
                      (registers . 5)))
)

7.5. Estilo variable

Este paquete permite usar variable-pitch-mode que es visualmente más clara dependiendo del tipo de fichero.

(use-package mixed-pitch
:hook
;; If you want it in all text modes:
(text-mode . mixed-pitch-mode))

7.6. Iconos en dired

Cargo iconos sencillos, menos problemas de dependencias.

(use-package all-the-icons
  :if (display-graphic-p)
  :hook (dired-mode . all-the-icons-dired-mode))

7.7. Iconos en ibuffer

Permite usar iconos de ficheros en listado de buffers (ibuffer).

(use-package all-the-icons-ibuffer
  :after all-the-icons
  :ensure t
  :hook (ibuffer-mode . all-the-icons-ibuffer-mode))

7.8. Ordeno ibuffer usando proyectos

Esto permite ordenar el ibuffer con proyectos. Parece complejo pero está sacado de la página oficial del paquete.

(use-package ibuffer-projectile
  :ensure t
  :config
  (add-hook 'ibuffer-hook
    (lambda ()
      (ibuffer-projectile-set-filter-groups)
      (unless (eq ibuffer-sorting-mode 'alphabetic)
        (ibuffer-do-sort-by-alphabetic))))
)

7.9. Org-mode

Activo el modo "moderno" para un estilo más elegante y más legible.

    (use-package org-modern
    :ensure t
    :hook ((org-mode . org-modern-mode))
)

También permito escalar imágenes con attrorg: :width …

(setq org-image-actual-width nil)

y cambio la elipsis por el triángulo en vez de los puntos suspensivos.

(setq org-ellipsis "  ▼")

7.10. Centrar las opciones

Normalmente vertico muestra abajo, pero es visualmente más cómodo que centre.

(use-package vertico-posframe
:after vertico
:config
(vertico-posframe-mode 1)
)

7.11. Ecuaciones en org-mode

Esto permite pre-visualizar una ecuación en org-mode.

(use-package org-fragtog
  :after org
  :hook
  (add-hook 'org-mode-hook 'org-fragtog-mode)
  :custom
  (org-format-latex-options
   (plist-put org-format-latex-options :scale 2)))

7.12. Modo presentación

Asocio F6 con modo presentación.

(use-package org-present
  :bind ("<f6>" . org-present)
  :bind (:map org-present-mode-keymap
              ("C-<right>" . org-present-next)
              ("C-<left>" . org-present-prev)))

7.13. Modo presentación bonita

Con esta opción es más bonito, f5.

(use-package org-bullets
  :no-require t
  :custom
  (org-bullets-bullet-list '("◉" "●" "○" "●" "○" "●")))

(use-package hide-lines)

(use-package hide-mode-line
  :defer t)

(defun terror/slide-setup ()
  (global-hl-line-mode -1)
  (setq org-hide-emphasis-markers t)
  (org-bullets-mode 1)
  (setq text-scale-mode-amount 3)
  (text-scale-mode 1)
  (set-frame-parameter (selected-frame)
                       'internal-border-width 75)
  (org-display-inline-images)
  (toggle-frame-fullscreen)
  (hide-mode-line-mode 1)
  (hide-lines-matching "#\\+begin")
  (hide-lines-matching "#\\+end"))

(defun terror/slide-end ()
  (global-hl-line-mode 1)
  (setq org-hide-emphasis-markers nil)
  (org-bullets-mode -1)
  (setq text-scale-mode-amount 0)
  (text-scale-mode -1)
  (set-frame-parameter (selected-frame)
                       'internal-border-width 20)
  (toggle-frame-fullscreen)
  (hide-mode-line-mode -1)
  (hide-lines-show-all)
  (org-fold-show-all))

(use-package org-tree-slide
  :after org
  :bind ("<f5>" . org-tree-slide-mode)
:bind (:map org-tree-slide-mode-map
            ("C-<right>" . org-tree-slide-move-next-tree)
            ("C-<left>" . org-tree-slide-move-previous-tree))
  :hook ((org-tree-slide-play . terror/slide-setup)
         (org-tree-slide-stop . terror/slide-end))
  :config
  (setq org-tree-slide-slide-in-effect nil
        org-image-actual-width nil
        org-tree-slide-header t
        org-tree-slide-breadcrumbs " > "
        org-tree-slide-activate-message "Let's begin..."
        org-tree-slide-deactivate-message "The end :)"))

7.14. Facilitadores de lectura

7.14.1. Modo focus

Permite acceder a focus para mostrar sólo el párrafo anterior. Desactivado por defecto, se activa con focus-mode.

(use-package focus
  :ensure t
  :defer t)

7.14.2. Modo writeroom

Ideado para leer con comodidad. Hay que activarlo manualmente con writeroom-mode. Asocio ambas, si está en modo writeroom activo también automáticamente el focus.

  (use-package writeroom-mode
    :ensure t
    :after focus
    :hook (writeroom-mode . focus-mode)
)

8. Desarrollo

8.1. Fossil

Instalo vc-fossil para trabajar con Fossil.

(use-package vc-fossil
  :ensure t
  ;; Keep from loading unnecessarily at startup.
  :defer t
  ;; This allows VC to load vc-fossil when needed.
  :init (add-to-list 'vc-handled-backends 'Fossil t))

8.2. Magit

Instalo Magit (para sincronizar directorios git)

(use-package magit
 :ensure t
 :bind ("C-x g" . magit-status))

8.3. Ver diferencias en buffer

Configuro para que se vean las diferencias usando git al guardar.

(use-package git-gutter
 :ensure t
  :hook (prog-mode org-mode markdown-mode text-mode latex-mode)
  :custom (git-gutter:update-interval 0.02))

(use-package git-gutter-fringe
  :after git-gutter
  :config
  ;; https://ianyepan.github.io/posts/emacs-git-gutter/
    (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated))
    (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
    (define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240] nil nil 'bottom))

8.4. Julia

Uso Julia Snail para soporte de Julia.

(use-package julia-mode
  :ensure t)

(use-package julia-snail
  :ensure t
  :after julia-mode
  :hook (julia-mode . julia-snail-mode))

Uso eglot-jl

(use-package eglot-jl
:ensure t)

Lo añado para poder ejecutarlo dentro de python

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (R . t)
   (julia . t)))

8.5. HTML

Activo para HTML

 (use-package web-mode
  :ensure t
  :mode (("\\.php$" .  web-mode)
         ("\\.html$" .  web-mode))
) 

8.6. Rust

(use-package rust-mode
  :ensure t
  :config
  (setq rust-format-on-save t)
(add-hook 'rust-mode-hook
          (lambda () (prettify-symbols-mode)))
)

8.7. Treesit

Aunque treesit está incluído, este paquete evita distinguir entre <name>-mode y <name>-ts-mode.

Por ahora lo desactivo por un problema de treesit.

    (use-package treesit-auto
      :ensure t
;;      :config
;;      (global-treesit-auto-mode)
    )

8.8. Notebooks de Python

Vamos a activar para poder abrir ficheros notebook de python (sobre python con eglot vamos bien).

Para que funcione bien también activamos elpy.

(use-package elpy
  :ensure t
  :defer t
  :init
  (elpy-enable))

(use-package ein
  :ensure t
  :defer t)

8.9. Eliminar automáticamente la ventana al compilar

Al compilar un proyecto se suele quedar un buffer que, cuando no hay errores ni warning, no nos sirve de nada.

El siguiente código (sacado de https://stackoverflow.com/questions/11043004/emacs-compile-buffer-auto-close) nos permite cerrarlo automáticamente si no hay errores. He usado el "truco" más actual, los anteriores no me funcionaban.

Definiendo en auto-hide-compile-buffer-delay un valor distinto de 0 se puede ver.

  (add-hook 'compilation-start-hook 'compilation-started)
(add-hook 'compilation-finish-functions 'hide-compile-buffer-if-successful)

(defcustom auto-hide-compile-buffer-delay 1
  "Time in seconds before auto hiding compile buffer."
  :group 'compilation
  :type 'number
)

(defun hide-compile-buffer-if-successful (buffer string)
  (setq compilation-total-time (time-subtract nil compilation-start-time))
  (setq time-str (concat " (Time: " (format-time-string "%s.%3N" compilation-total-time) "s)"))

  (if
    (with-current-buffer buffer
      (setq warnings (eval compilation-num-warnings-found))
      (setq warnings-str (concat " (Warnings: " (number-to-string warnings) ")"))
      (setq errors (eval compilation-num-errors-found))

      (if (eq errors 0) nil t)
    )

    ;;If Errors then
    (message (concat "Compiled with Errors" warnings-str time-str))

    ;;If Compiled Successfully or with Warnings then
    (progn
      (bury-buffer buffer)
      (run-with-timer auto-hide-compile-buffer-delay nil 'delete-window (get-buffer-window buffer 'visible))
      (message (concat "Compiled Successfully" warnings-str time-str))
    )
  )
)

(make-variable-buffer-local 'compilation-start-time)

(defun compilation-started (proc) 
  (setq compilation-start-time (current-time))
)

8.10. Generar licencias

Con esto y `license-templates-new-file` permite crear un fichero licencia. Usa el API de Github, por lo que sin internet puede no funcionar.

(use-package license-templates
    :ensure t) 

Esto otro indica menos texto, pero no requiere internet:

(use-package lice
  :ensure t)

8.11. Soporte Polymode

Permite usar ficheros .org y markdown usando bloques de código que se tratarán con el lenguaje correspondiente.

(use-package polymode
  :ensure t)
(use-package poly-markdown
  :after polymode
  :ensure t)

8.12. Soporte de Quarto

(use-package quarto-mode
  :mode (("\\.Rmd" . poly-quarto-mode))
)

9. Autocompleto

9.1. Completado

Usando consult para autocompletar. Dado que no configura teclas, iré añadiendo poco a poco.

     ;; Example configuration for Consult
(use-package consult
     :ensure t
     ;; Replace bindings. Lazily loaded due by `use-package'.
     :bind (;; C-c bindings in `mode-specific-map'
            ;; C-x bindings in `ctl-x-map'
            ("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 r b" . consult-bookmark)            ;; orig. bookmark-jump
            ("C-x p b" . consult-project-buffer)      ;; orig. project-switch-to-buffer

   )

   ;; 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)

 :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.
 (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)
)

9.2. Completando comando

Usando vertico para auto-completar con M-x.

  ;; Enable vertico
(use-package vertico
  :ensure t
  :init
  (vertico-mode)
)

Incorporo histórico para que lo ordene vertico por su posición.

;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
  :ensure t
  :init
  (savehist-mode))

9.3. Informando sobre comandos

  ;; Enable rich annotations using the Marginalia package
(use-package marginalia
  :ensure t
  ;; Bind `marginalia-cycle' locally in the minibuffer.  To make the binding
  ;; available in the *Completions* buffer, add it to the
  ;; `completion-list-mode-map'.
  :bind (:map minibuffer-local-map
         ("M-A" . marginalia-cycle))

  :init
  (marginalia-mode))

9.4. Completar de forma difusa

Uso el paquete hotfuzz

(use-package hotfuzz
  :ensure t
:init
  (hotfuzz-vertico-mode)
:after vertico
:config
(add-to-list 'completion-styles 'hotfuzz)
)

9.5. Completando con tab (dabbrev)

Esto permite completar de forma automática la escritura usando el paquete `fancy-dabbrev`.

A veces puede ser un poco intrusivo porque sugiere conforme vas escribiendo pero es muy cómodo una vez que te acostumbras.

    (use-package fancy-dabbrev
    :ensure t
  :custom
  ;; Ignore several files to complete (in other buffers)
  (dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\|py\\|jl\\)\\^'"))
    :config
    ;; Enable fancy-dabbrev previews everywhere:
    (global-fancy-dabbrev-mode)
  ;; Let dabbrev searches ignore case and expansions preserve case:
  (setq dabbrev-case-distinction nil)
  (setq dabbrev-case-fold-search t)
  (setq dabbrev-case-replace nil)
  ;; If you want TAB to indent the line like it usually does when the cursor
  ;; is not next to an expandable word, use 'fancy-dabbrev-expand-or-indent
  ;; instead of `fancy-dabbrev-expand`:
  (global-set-key (kbd "\t") 'fancy-dabbrev-expand-or-indent)
;  (global-set-key (kbd "\t") 'dabbrev-expand)
  (global-set-key (kbd "<backtab>") 'fancy-dabbrev-backward)
  )

9.6. Uso de Hippie-expand

Con esto asocio el tab para hippie-expand, lo cual mejora mucho el auto-completado.

(advice-add #'indent-for-tab-command :after #'hippie-expand)

(global-set-key (kbd "TAB") (make-hippie-expand-function
                         '(try-expand-dabbrev-visible
                           try-expand-dabbrev
                           try-expand-dabbrev-all-buffers) t))
    ;(global-set-key "C-;" 'hippie-expand)

9.7. Uso de company

Company es un paquete de auto-completado que por defecto usa tab.

    (use-package company
      :ensure t
      :config
      (global-company-mode 1)
;; Configuración para hacer que company-mode sea sensible a las mayúsculas
(setq company-dabbrev-downcase t)
(setq company-dabbrev-ignore-case nil)
  )

10. Investigar

10.1. Permitir comentar un PDF

(use-package org-noter
  :ensure t
  :defer t)

10.2. Usando Zotero para bajarse documentos

Este pequeño paquete permite bajarse referencias y pdf usando zotero: https://github.com/mpedramfar/zotra

(use-package zotra
:ensure t)

Para que funcione requiere zotra-cli que se puede instalar fácilmente (usar npm -g para que Emacs lo encuentre).

10.3. Diccionario de palabras en inglés

Este pequeño paquete permite consultar el diccionario de una palabra en inglés.

(use-package define-word
:ensure t
:bind("C-c d" . define-word-at-point))

11. Documentos complejos: Latex y Pandoc

Primero vamos a instalar latex y lo asocio:

(use-package latex
  :ensure auctex
 :mode
    ("\\.tex\\'" . latex-mode)
  :bind
  (:map LaTeX-mode-map
        ("M-<delete>" . TeX-remove-macro)
        ("C-c C-r" . reftex-query-replace-document)
        ("C-c C-g" . reftex-grep-document))
  )

Activo reftex para poder navegar bien entre secciones (y autocompletar).

(use-package reftex
  :ensure t
  :after (latex)
  ;; :bind (:map reftex-toc-map
  ;;          ("j" . reftex-toc-next)
  ;;          ("k" . reftex-toc-previous))
  :config
  (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
  (add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
  (setq reftex-plug-into-AUCTeX t))

Y ahora permito abrir con pdf-tools:

;; Use pdf-tools to open PDF files
(setq TeX-view-program-selection '((output-pdf "PDF Tools"))
      TeX-source-correlate-start-server t)

;; Update PDF buffers after successful LaTeX runs
(add-hook 'TeX-after-compilation-finished-functions
           #'TeX-revert-document-buffer)

11.0.1. Latexmk

Añado latexmk en las opciones porque me resulta mucho más cómodo.

    (use-package auctex-latexmk
      :ensure t
      :after (latex)
:config
(auctex-latexmk-setup)
 (setq auctex-latexmk-inherit-TeX-PDF-mode t)
)

11.0.2. Permitiendo clases KOMA-Script en Latex

Permito clases de KOMA-script en Latex

Añado scrartcl

(with-eval-after-load "ox-latex"
  (add-to-list 'org-latex-classes
               '("scrartcl" "\\documentclass{scrartcl}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))

Y scrbook

(with-eval-after-load "ox-latex"
  (add-to-list 'org-latex-classes
               '("scrbook" "\\documentclass{scrbook}"
                 ("\\chapter{%s}" . "\\chapter*{%s}")
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))

11.0.3. Editar tablas

Añado latex-wizard que me permite editar muy cómodamente una tabla usando la función del mismo nombre (moverme, editar, añadir o borrar filas y columnas, …).

(use-package latex-table-wizard
  :ensure t
  :after latex
  :defer t)

12. Pequeñas utilidades

12.1. Copiar el nombre del fichero.

Copiar el nombre del fichero con <space-C>

(defun my-put-file-name-on-clipboard ()
  "Put the current file name on the clipboard"
  (interactive)
  (let ((filename (if (equal major-mode 'dired-mode)
                      default-directory
                    (buffer-file-name))))
    (when filename
      (with-temp-buffer
        (insert filename)
        (clipboard-kill-region (point-min) (point-max)))
      (message filename))))

12.2. Moverme más fácilmente en un fichero (dejando marcas)

El paquete blinky permite mover fácilmente poniendo marcas.

(use-package binky
  :hook (after-init-hook . (lambda () (binky-mode) (binky-margin-mode))))

El manejo es sencillo, tras <space-g> se puede pulsar una tecla que idetificará la posición. Si no está la crea, y si está se mueve ahí. Si se pulsa en mayúsculas la borra.

12.3. QR

Este código permite crear códigos QR de url en la posición mediante `qrencode-url-at-point`:

(use-package qrencode
  :ensure t)

13. Modo vim (evil)

13.1. Evil

(use-package evil
    :ensure t
    :init
    (setq evil-want-integration t) ;; This is optional since it's already set to t by default.
    (setq evil-want-keybinding nil)
    :config
    (evil-mode 1)
    )
    ; Surround 
      (use-package evil-surround
      :ensure t
      :config
      (global-evil-surround-mode 1)
    )
;; (use-package evil-smartparens
;;     :ensure t
;;     :after evil smartparens
;;     :hook (prog-mode . evil-smartparens-mode)
;; )

13.2. Evil matching con tags

Permite usar % para moverse no solo entre símbolos como y, también en lenguajes como html. Además, teclas como va% permite marcar todo el elemento (y da% borrar).

(use-package evil-matchit
  :after evil
  :ensure t
  :config
  (global-evil-matchit-mode 1)
)

13.3. Mis teclas

Voy a asociar teclas rápidas usando espacio. Las teclas son:

  • f: Abrir fichero.
  • d: Abrir directorio.
  • b: Bookmark.
  • r: Fichero recientes.
  • m: Imenu.
  • '|e: eshell.
  • v: vterm.
  (use-package evil-leader
  :ensure t
  :init
(global-evil-leader-mode)
  :config
  (evil-leader/set-leader "<SPC>")
(evil-leader/set-key "f" 'find-file)
(evil-leader/set-key "F" 'toggle-frame-fullscreen)
(evil-leader/set-key "C" 'my-put-file-name-on-clipboard)
(evil-leader/set-key "m" 'consult-imenu)
(evil-leader/set-key "l" 'consult-line)
(evil-leader/set-key "R" 'recompile)
(evil-leader/set-key "r" 'consult-recent-file)
(evil-leader/set-key "c" 'consult-flymake)
(evil-leader/set-key "g" 'binky-binky)
(evil-leader/set-key "G" 'consult-ripgrep)
(evil-leader/set-key "e" 'eshell)
(evil-leader/set-key "'" 'eshell)
(evil-leader/set-key "v" 'vterm)
(evil-leader/set-key "D" 'dashboard-open)
(evil-leader/set-key "d" 'dired)
(evil-leader/set-key "b" 'consult-buffer)
(evil-leader/set-key "p" 'consult-projectile-switch-project)
(evil-leader/set-key "M" 'notmuch-hello)
(evil-leader/set-key "s" 'consult-flyspell)
(evil-leader/set-key "w" 'writeroom-mode)
(evil-leader/set-key "+" 'global-text-scale-adjust)
(evil-leader/set-key "-" 'global-text-scale-adjust)
(evil-leader/set-key "<SPC>" 'execute-extended-command)
 )

13.4. Salir rápidamente

Asocio la tecla "Q" en modo normal para salir del buffer actual.

(with-eval-after-load 'evil-maps
   (define-key evil-normal-state-map (kbd "Q") 'kill-this-buffer))

13.5. Evil Collection

(use-package evil-collection
  :after evil
  :ensure t
  :config
  (evil-collection-init))

13.6. Company

(use-package company
:bind (:map company-active-map
       ("C-n" . company-select-next)
       ("C-p" . company-select-previous))
:config
(setq company-idle-delay 0.3)
(global-company-mode t))

13.7. Ventana emergente

Uso el paquete corfu para autocompletar, supongo que se puede mejorar.

(use-package corfu
  :ensure t
  :custom
  (corfu-auto t)          ;; Enable auto completion
  ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space
  :bind
  ;; Another key binding can be used, such as S-SPC.
  ;; (:map corfu-map ("M-SPC" . corfu-insert-separator))
  :init
  (global-corfu-mode))

13.8. Uso de rsync

(use-package dired-rsync
  :ensure t
  :bind (:map dired-mode-map
              ("C-c C-r" . dired-rsync))
)

14. Facilitando movimiento entre

14.1. Pestañas

Emacs ahora contiene tabs, voy a redefinir f4 para moverme entre ellas.

(global-set-key (kbd "<f4>") 'tab-next)

15. Correo

Aquí configuro mi correo (no es nada personal, siempre que se use el mismo software).

15.1. Configurar notmuch

Configuro notmuch para leer los emails, usando mailsync se los descarga.

(use-package notmuch
  :ensure-system-package (notmuch . notmuch)
  :ensure t
  :defer t)

(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)

15.2. Indicador de notmuch

Vamos a visualizar nuevos mensajes, destacando:

  • Mensajes sin leer.
  • Mensajes de mi novia.
(use-package notmuch-indicator
  :ensure t
  :after notmuch
:config
  (setq notmuch-indicator-args
        '((:terms "tag:unread" :label "🧐")
          ; (:terms "tag:todo and tag:urgente" :label "😱")
          (:terms "--output threads tag:unread and from:amalia" :label "💕")))
  (setq notmuch-indicator-hide-empty-counters t)
  (notmuch-indicator-mode)
)

15.3. Poder usar bookmark

Los bookmarks son muy útiles, con esto vamos a poder añadir un email como un bookmark.

(use-package notmuch-bookmarks
   :after notmuch
   :config
   (notmuch-bookmarks-mode)
   (notmuch-bookmarks-annotation-mode))

15.4. Correo de salida

Me falta cómo enviar, vamos a verlo poco a poco.

Depende de msmtp y el fichero de configuración, funciona solo al responder.

(setq send-mail-function 'sendmail-send-it
      sendmail-program "/usr/bin/msmtp"
      mail-specify-envelope-from t
      message-sendmail-envelope-from 'header
      mail-envelope-from 'header)

16. Navegando

16.1. Soporte de enlaces

Activo

(use-package eww-lnum
  :ensure t
  :bind (:map eww-mode-map
  ("f" . eww-lnum-follow)
  ; ("F" . eww-lnum-universal)
  )
)

17. Gestionar paquetes del sistema

Con este paquete podemos gestionar e instalar paquetes sin usar eshell

(use-package system-packages
  :ensure t)

18. Para administradores

19. Mejorando org-mode

19.1. Org-aggregate

Este paquete es maravilloso, ya que permite crear tablas resumen en org muy fácilmente. Mira https://github.com/tbanel/orgaggregate/blob/master/README.org para ver cómo funciona. Lo he mostrado en mi propio blog.

(use-package orgtbl-aggregate
  :ensure t
  :defer t)

19.2. Añadiendo índice a org-mode

(use-package toc-org
  :ensure t
  :hook org-mode)

19.3. Permitir formatos en referencias en org-mode

Este paquete permite usar formatos csl de bibliografía (como ieee.csl) para org-citer

(use-package citeproc
  :ensure t
  :defer t)

19.4. Permitir exportar a docx por defecto

Esto es algo lamentable pero es útil cuando uso org y luego trabajo con compañer@s que no usan LibreOffice:

(setq-default org-odt-preferred-output-format "docx")

19.5. Hago que <f7> exporte de Org a PDF

(global-set-key (kbd "<f7>") 'org-latex-export-to-pdf)

19.6. Permitiendo copiar fácilmente

El paquete org-rich-yank permite copiar a un fichero .org automáticamente añadiendo el lenguaje de origen.

(use-package org-rich-yank
  :ensure t
  :bind (:map org-mode-map
              (("C-M-y" . org-rich-yank))
              )
)

20. Multimedia

Añado soporte empv para ver videos youtube o similar. Para poder buscar en youtube añado una instancia de https://api.invidious.io/. Con "M-x m" activamos las teclas.

               (use-package empv
                 :ensure t
                 :defer t
           :config
     (empv-toggle-video)
     (setq empv-invidious-instance "https://invidious.fdn.fr/api/v1")
   (add-to-list 'empv-mpv-args "--ytdl-format=best")
  (add-to-list 'empv-mpv-args "--save-position-on-quit")
  (bind-key "C-x m" empv-map)
)

21. Personal

Aquí indico configuración más personal.

21.1. Redes Sociales

21.1.1. Uso de Mastodon

Configuro Emacs para usar Mastodon en mi cuenta de `fosstodon`.

    (use-package mastodon
      :ensure t
    :init
  (setq mastodon-instance-url "https://fosstodon.org")
  (setq mastodon-active-user "@dmolina.fosstodon")
)

21.1.2. Uso de Telegram

Configuro para usar Telegram, es necesario instalar tdlib antes: https://zevlg.github.io/telega.el/

  (use-package telega
  :ensure t
  :config
 (define-key global-map (kbd "C-c t") telega-prefix-map)
)

21.2. Ob-zola

Añado ob-zola para poder escribir más fácilmente mi blog www.danimolina.net

      (use-package ox-zola
        :ensure t
        :after ox-hugo
:vc (:fetcher github :repo gicrisf/ox-zola)
  )

  (use-package ox-hugo
:ensure t   
:pin melpa  
:after ox)

Author: Daniel Molina Cabrera

Created: 2023-12-30 sáb 15:19

Validate