Emacs: Mi fichero configuración 2024

2024-04-15

Índice

  1. Bienvenid@!
  2. Consejos de uso
  3. Configuración del sistema de paquetes
  4. Configuración básica de la interfaz de usuario
    1. Configuración de fuente
    2. Configuración combinación de teclas
  5. Configuración UI
    1. Color Theme
  6. Complementos
    1. Finalización minifuffer
      1. Vertico
      2. Guarda el histórico
      3. Orderless
      4. Marginalia
      5. Consult
    2. Ficheros a usar para la autenticación
    3. Actualizar automáticamente los paquetes
    4. Corrector ortográfico
      1. FlySpell
    5. Hacer/deshacer
    6. Autorevert
    7. Archivos recientes
    8. Buffer
    9. Dashboard
    10. Which Key
    11. Lectura Ebooks
    12. Lectura PDF
    13. Sin distracciones
    14. Tomando notas rápidas
    15. Company
    16. Dired
  7. Org Mode
    1. Configuración Básica
    2. Org-agenda
      1. Org-Contacts
      2. Agenda
      3. Notificaciones
      4. Captura
      5. Cifrado / Descifrado
    3. Teclas rápidas para tareas
    4. Funciones propias
    5. Personalizando el calendario
      1. Personalizando los meses y semana
      2. Festivos
      3. Poniendo una vista bonita al calendario
      4. Sincronización con Caldav
    6. Configurar Lenguajes en Babel
  8. Lenguajes
    1. Markdown
    2. Magit
    3. Ox-hugo
  9. Terminal
    1. Vterm
    2. Tramp
  10. Social
    1. Elfeed
    2. Mastodon
    3. Lingva

Cada año suelo publicar un articulo con mi configuración de Emacs, con el paso del tiempo, a medida que iba aprendiendo, he ido quitando aquellos paquetes y código que no necesitaba o finalmente no utilizaba.

Mirando atrás y al ver ese primer fichero de configuración, veo errores de código y funciones obsoletas. se puede observar como el fichero de configuración ha ido perdiendo lineas de código, paquetes y funciones.

Esta es una configuración sencilla, basada principalmente en el uso de Org Mode como base para organizar mi día a día, lo utilizo como agenda, calendario y notas, también como lector RSS gracias a elfeed y como cliente de Mastodon (mastodn.el) y como no, para la publicación de este blog (ox-hugo).

He procurado comentar cada sección del fichero de configuración, también he limpiado el repositorio de Gitlab para alojar la nueva configuración.

Bienvenid@!

Esta configuración tiene como base la serie de artículos escritos en Emacs From Scratch y Emacs Writing Studio. La primera vez que cargues este archivo puedes generar el fichero init.el con la combinación de teclas C-c C-v t , después, cada vez que modifiques el archivo y lo guardes, se vuelve a generar de forma automática.

Consejos de uso

En este documento, hay enlaces en muchos lugares que llevan a la documentación de los distintos paquetes que utilizo. Si estás viendo este archivo en Emacs, puedes colocar el cursor en un enlace y presionar C-c C-o o ejecutar M-x org-open-at-point para abrir el enlace en el navegador web.

Configuración del sistema de paquetes

Emacs tiene un administrador de paquetes integrado, pero no facilita la instalación automática de paquetes en un nuevo sistema la primera vez que despliega. Use-package es un paquete realmente útil que se utiliza en esta configuración para facilitar la automatización de la instalación y configuración de todo lo que vamos a usar.

Esta configuración ha sido creada para la versión 29 o superior de Emacs, si no es el caso, generará una advertencia en el búfer Messages por lo que algunas funcionalidades podrían no estar disponibles

    ;; Emacs 29?
    (unless (>= emacs-major-version 29)
      (error "Emacs Writing Studio requires Emacs version 29 or later"))
    
    ;; Ajustes personalizados en un archivo separado y cargar la configuración personalizada
    (setq-default custom-file
                  (expand-file-name "custom.el" user-emacs-directory))
    (when (file-exists-p custom-file)
      (load custom-file))
    
    ;; Establecer archivos de paquetes
    (use-package package
      :config
      (add-to-list 'package-archives
                   '("melpa" . "https://melpa.org/packages/"))
      (package-initialize))
    
    ;; Gestión de paquetes
    (use-package use-package
      :custom
      (use-package-always-ensure t)
      (package-native-compile t)
      (warning-minimum-level :error))

Configuración básica de la interfaz de usuario

Configuraciones básicas de la interfaz de usuario que eliminan los elementos innecesarios para hacer que Emacs se vea mucho más minimalista y moderno. Si estás comenzando en Emacs, la barra de menú puede ser útil, si la quieres visualizar elimina la línea (menu-bar-mode -1).

    (setq user-full-name "Carlos M.")
    (setq inhibit-startup-message t
          use-short-answers t)
    (tool-bar-mode -1)                                            ; Desactivar la barra de herramientas
    (menu-bar-mode -1)                                            ; Desactivar la barra de menús
    (scroll-bar-mode -1)                                          ; Desactivar la barra de desplazamiento visible
    (add-to-list 'default-frame-alist '(fullscreen . maximized))  ; Activar frame maximizado
    (display-time)                                                ;
    (setq display-time-24hr-format t)                             ;
    (delete-selection-mode t)                                     ; Sobrescribir el texto seleccionado
    (electric-pair-mode 1)                                        ; Cierre automático de bracket.
    ;;(setq-default line-spacing 2)                             ; Aumentar el interlineado

Configuración de fuente

Utilizo Source Code Pro, son un conjunto de fuentes OpenType que han sido diseñadas para funcionar bien en entornos de interfaz de usuario (UI). Lo más probable es que sea necesario instalarlas en tu máquina. Generalmente se pueden instalar desde el administrador de paquetes de tu distribución de GNU/Linux o se pueden descargar desde el enlace anterior.

    (set-face-attribute 'default nil :family "Source Code Pro" :height 120 :weight 'light)
    (set-face-attribute 'bold nil :weight 'semibold)
    (set-face-attribute 'italic nil :family "Source Code Pro")

Configuración combinación de teclas

Utilizo la tecla ESC para salir de los prompts, Con C-+ y C– incrementa o disminuye el tamaño de la fuente y las teclas de dirección para moverme entre ventanas

    (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
    (global-set-key (kbd "C-+") 'text-scale-increase)
    (global-set-key (kbd "C--") 'text-scale-decrease)
    (global-set-key (kbd "C-c <left>")  'windmove-left)
    (global-set-key (kbd "C-c <right>") 'windmove-right)
    (global-set-key (kbd "C-c <up>")    'windmove-up)
    (global-set-key (kbd "C-c <down>")  'windmove-down)

Configuración UI

Color Theme

Los temas Modus están diseñados para una legibilidad accesible. Cumplen la norma más estricta de contraste de colores entre combinaciones de valores de fondo y primer plano.

    (setq modus-themes-bold-constructs t
          modus-themes-italic-constructs t
          modus-themes-fringes 'subtle
          modus-themes-tabs-accented t
          modus-themes-paren-match '(bold intense)
          modus-themes-prompts '(bold intense)
          modus-themes-completions 'opinionated
          modus-themes-org-blocks 'gray-background
          modus-themes-scale-headings t
          modus-themes-to-toggle
          '(modus-operand modus-vivendi)
          modus-themes-region '(bg-only)
          modus-themes-headings
          '((1 . (rainbow overline background 1.4))
            (2 . (rainbow background 1.3))
            (3 . (rainbow bold 1.2))
            (t . (semilight 1.1))))
    
    ;; Inicia en el tema oscuro por defecto
    (load-theme 'modus-vivendi)             
    ;; F5 para cambiar entre modus-operandi y modus-vivendi
    (define-key global-map (kbd "<f5>") #'modus-themes-toggle)

Complementos

Finalización minifuffer

Vertico

Vertico mejora el aspecto del minibuffer y cómo interactúas con él.

    (use-package vertico
      :init
      (vertico-mode)
      :custom
      (vertico-count 13)                    ; Número de candidatos a mostrar
      (vertico-resize t)
      (vertico-cycle t)
      (vertico-sort-function 'vertico-sort-history-alpha))

Guarda el histórico

El paquete Savehist recuerda tus selecciones y guarda el historial de tu minibuffer al salir de Emacs. Este paquete asegura que tus selecciones más populares permanezcan en la parte superior para mayor comodidad.

    (use-package savehist
      :init
      (savehist-mode))

Orderless

El paquete Orderless empareja patrones, independientemente del orden en que se escriban.

    (use-package orderless
      :custom
      (completion-styles '(orderless basic))
      (completion-category-defaults nil)
      (completion-category-overrides
       '((file (styles partial-completion)))))

Marginalia

El paquete Marginala muestra cuando escriba M-x, una lista de funciones y una breve descripción de lo que hacen, lo que le facilitará aún más encontrar la función que necesitas.

    (use-package marginalia
      :init
      (marginalia-mode))

Consult

Consult proporciona comandos de búsqueda y navegación, permite seleccionar rápidamente un elemento de una lista de candidatos. Además, ofrece un comando avanzado de cambio de búfer, consult-buffer, para cambiar entre búferes, archivos abiertos recientemente, marcadores y candidatos similares a búferes de otras fuentes. Algunos de los comandos de Consult son versiones mejoradas de comandos incorporadosc por Emacs.

    (use-package consult
      :bind (
             ("C-c M-x" . consult-mode-command)
             ;; ("C-c k" . consult-kmacro)
             ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
             ("C-x r b" . consult-bookmark)            ;; orig. bookmark-jump
             ("M-y" . consult-yank-pop)                ;; orig. yank-pop
             ("M-g o" . consult-outline)               ;; Alternativa: consult-org-heading
             ("M-g i" . consult-imenu)
             ("M-g I" . consult-imenu-multi)
             ("M-s d" . consult-find)                  ;; Alternativa: consult-fd
             ("M-s g" . consult-grep)
             ("M-s l" . consult-line)))

Ficheros a usar para la autenticación

Ubicación del fichero authinfo.pgp para la autenticación en diversos servidores.

    (setq auth-source-debug  t)
    (setq auth-sources
          '((:source "~/.gnupg/shared/authinfo.gpg")))

Actualizar automáticamente los paquetes

Actualiza los paquetes cada 7 días a las 09:00 horas, sustituye antiguas versiones por la nuevas

    (use-package auto-package-update
      :custom
      (auto-package-update-interval 7)
      (auto-package-update-delete-old-versions t)
      (auto-package-update-prompt-before-update t)
      (auto-package-update-hide-results t)
      :config
      (auto-package-update-maybe)
      (auto-package-update-at-time "09:00"))

Corrector ortográfico

Corrector de ortografía en español, has de tener instalado hunspell en el sistema

FlySpell

flyspell habilita la revisión ortográfica sobre la marcha en Emacs.

    (use-package flyspell
      :config
      (setq ispell-program-name "hunspell"
            ispell-default-dictionary "es_ES")
      :hook (text-mode . flyspell-mode)
      :bind (("M-<f7>" . flyspell-buffer)
             ("<f7>" . flyspell-word)))
    
    (use-package flyspell-correct
      :after (flyspell)
      :bind (("C-;" . flyspell-auto-correct-previous-word)
             ("<f7>" . flyspell-correct-wrapper)))

Hacer/deshacer

En lugar de tratar el deshacer/rehacer como una secuencia lineal de cambios, el modo undo-tree-mode trata el historial de deshacer como una rama de cambios.

    (use-package undo-tree
      :init
      (global-undo-tree-mode 1)
      :custom
      (undo-tree-visualizer-timestamps t)
      (undo-tree-visualizer-diff t)
      (undo-tree-auto-save-history nil))

Autorevert

Recarga los archivos al ser modificados

    (use-package autorevert
      :ensure nil
      :diminish
      :hook (after-init . global-auto-revert-mode))

Archivos recientes

recentf es un modo menor en Emacs que crea una lista de archivos visitados recientemente, proporciona un acceso rápido a los archivos recientes mediante C-c r. Excluyo algunos archivos que nunca quiero volver a visitar, y también establezco el número máximo de elementos guardados a 50.

    (use-package recentf
      :defer 2
      :bind ("C-c r" . recentf-open-files)
      :init (recentf-mode)
      :custom
      (recentf-max-menu-items 10)
      (recentf-max-saved-items 50)
      (recentf-exclude (list "COMMIT_EDITMSG"
                             "~$"
                             "/scp:"
                             "/ssh:"
                             "/sudo:"
                             "diario.*"
                             "recentf*"
                             "bookmark*"
                             "/archivo*"
                             "birthday*"
                             "*elpa/*"
                             "/tmp/"
                             "drafts/*"
                             "/.elfeed"
                             "/.config"
                             "~/.emacs.d/url/*"
                             "~/.emacs.d/s*"))
      :config (run-at-time nil (* 5 60) 'recentf-save-list))

Buffer

No pregunta antes de matar un buffer.

    (global-set-key [remap kill-buffer] #'kill-this-buffer)
    ;;(kill-buffer "*scratch*")

Dashboard

Dashboard es un paquete que usa Spacemacs en el inicio solo que adaptado para poder ser usado en cualquier Emacs aunque no usemos Spacemacs.

    (use-package all-the-icons)
    
    (setq dashboard-icon-type 'all-the-icons)
    (use-package dashboard
      :custom
      (dashboard-startup-banner "~/Imágenes/mariposa.png")
      (dashboard-banner-logo-title (format "Buen día %s" user-full-name))
      (dashboard-items '((recents . 4)
                         (bookmarks . 4)
                         (agenda . 3)))
      :config
      (dashboard-setup-startup-hook)
      (setq dashboard-set-heading-icons t
            dashboard-set-file-icons t
            dashboard-set-init-info t
            dashboard-set-navigator t)
      (setq dashboard-navigator-buttons
            `((
               (,(when (display-graphic-p)
                   (all-the-icons-octicon "home" :height 1.1 :v-adjust 0.0))
                "Página web" "El Blog de Lázaro"
                (lambda (&rest _) (browse-url "https://elblogdelazaro.org")))
               (,(when (display-graphic-p)
                   (all-the-icons-material "home" :height 1.35 :v-adjust -0.24))
                "Localhost" "Abrir Hugo localhost"
                (lambda (&rest _) (browse-url "http://localhost:1313/")))
               (,(when (display-graphic-p)
                   (all-the-icons-octicon "tools" :height 1.0 :v-adjust 0.0))
                "Configuración" "Abrir configuración de emacs (.org)"
                 (lambda (&rest _) (find-file (expand-file-name  "~/.emacs.d/Emacs.org"))))
               (,(when (display-graphic-p)
                   (all-the-icons-octicon "calendar" :height 1.0 :v-adjust 0.0))
                "Agenda" "Agenda personal"
                (lambda (&rest _)
                  (interactive)
                  (if (get-buffer "*Org Agenda*")
                      (progn
                        (switch-to-buffer-other-window "*Org Agenda*")
                        (kill-buffer "*Org Agenda*")
                        (org-agenda-list))
                    (split-window-right)
                    (org-agenda-list))))
               ))))
    ;; F10 para ir al Dashboard
    (global-set-key (kbd "<f10>") 'open-dashboard)
    
    (defun open-dashboard ()
      "Abre el buffer *dashboard* y salta al primer widget."
      (interactive)
      (delete-other-windows)
      ;; Refresca  dashboard buffer
      (if (get-buffer dashboard-buffer-name)
          (kill-buffer dashboard-buffer-name))
      (dashboard-insert-startupify-lists)
      (switch-to-buffer dashboard-buffer-name))

Which Key

Which-key es un panel que aparece cuando comienzas a presionar cualquier combinación de teclas en Emacs para ofrecerte todas las terminaciones posibles para el prefijo. Por ejemplo, si presiona C-c (mantén presionada la tecla control y presiona la letra c), aparecerá un panel en la parte inferior del marco que muestra todos los enlaces bajo ese prefijo y qué comando ejecutan. Esto es muy útil para aprender las posibles combinaciones de teclas en el modo de su búfer actual.

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

Lectura Ebooks

nov modo principal para leer EPUBs en Emacs

    (use-package nov
      :init
      (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)))
    (use-package doc-view
      :custom
      (doc-view-resolution 300)
      (doc-view-mupdf-use-svg t)
      (large-file-warning-threshold (* 50 (expt 2 20))))

Lectura PDF

Emacs puede mostrar archivos PDF con el modo principal DocView. Sin embargo, necesitas algún software externo para que DocView funcione. GhostScript o MUPDF convierten archivos PDF en imágenes y las proporcionan a DocView.

Si utilizas Emacs 29.1 o superior y tienes instalado MUPDF DocView convertirá las páginas PDF en archivos SVG en lugar de archivos PNG, lo que proporciona una imagen más nítida y mejor para hacer zoom a la imagen.

    (use-package doc-view
      :custom
      (doc-view-resolution 300)
      (doc-view-mupdf-use-svg t)
      (large-file-warning-threshold (* 50 (expt 2 20))))

Sin distracciones

Olivetti es sencillo modo menor de Emacs para un entorno de escritura agradable.que facilita la escritura sin distracciones.

    (defun ews-distraction-free ()
        "Distraction-free writing environment using Olivetti package."
        (interactive)
        (if (equal olivetti-mode nil)
            (progn
              (window-configuration-to-register 1)
              (delete-other-windows)
              (text-scale-set 2)
              (olivetti-mode t))
          (progn
            (if (eq (length (window-list)) 1)
                (jump-to-register 1))
            (olivetti-mode 0)
            (text-scale-set 0))))
    
      (use-package olivetti
        :demand t
        :bind
        (("<f9>" . ews-distraction-free)))

Tomando notas rápidas

Notas fugaces en el buffer Scratch, persistent-scratch hace persistentes las notas aunque salgas de Emacs

    (setq initial-major-mode 'org-mode
          initial-scratch-message
          "#+title: Scratch Buffer\n\nFor random thoughts.\n\n")
    
    (use-package persistent-scratch
      :hook
      (after-init . persistent-scratch-setup-default)
      :init
      (persistent-scratch-setup-default)
      (persistent-scratch-autosave-mode)
      :bind
      (("C-c w x" . scratch-buffer)))

Company

Company es un paquete que puede ayudarte a completar palabras largas. Su objetivo principal es ayudar a los desarrolladores a escribir código, pero también puede ayudarle a completar palabras. Utiliza las flechas y la tecla Intro para seleccionar la opción deseada o simplemente ignora el menú y sigue escribiendo.

El paquete company-posframe evita que el menú desplegable se distorsione cuando se utilizan fuentes de paso variable.

    (use-package company
      :custom
      (company-idle-delay 0)
      (company-minimum-prefix-length 4)
      (company-selection-wrap-around t)
      :init
      (global-company-mode))
    
    (use-package company-posframe
      :config
      (company-posframe-mode 1))

Dired

Dired es un administrador de archivos integrado para Emacs que hace cosas asombrosas. Aquí hay algunas combinaciones de teclas que debes probar:

    (use-package dired
      :ensure
      nil
      :commands
      (dired dired-jump)
      :custom
      (dired-listing-switches
       "-goah --group-directories-first --time-style=long-iso")
      (dired-dwim-target t)
      (delete-by-moving-to-trash t)
      :init  ;; Abrir carpetas dired en el mismo búfer
      (put 'dired-find-alternate-file 'disabled nil))
    
    ;; Ocultar archivos ocultos
    (use-package dired-hide-dotfiles
      :hook
      (dired-mode . dired-hide-dotfiles-mode)
      :bind
      (:map dired-mode-map ("." . dired-hide-dotfiles-mode)))
    
    ;; Archivos de copia de seguridad
    (setq-default backup-directory-alist
                  `(("." . ,(expand-file-name "backups/" user-emacs-directory)))
                  create-lockfiles nil)  ; No crea ficheros lock
    
    ;; Visor de imágenes
    (use-package emacs
      :bind
      ((:map image-mode-map
                  ("k" . image-kill-buffer)
                  ("<right>" . image-next-file)
                  ("<left>"  . image-previous-file))
       (:map dired-mode-map
        ("C-<return>" . image-dired-dired-display-external))))

Org Mode

Org Mode es una de las características distintivas de Emacs y por las que empece a utilizar Emacs. Es un rico editor de documentos, planificador de proyectos, rastreador de tareas y de tiempo, generador de blogs y programación literaria, todo en un solo paquete.

Configuración Básica

      (setq-default org-startup-indented t
                    org-pretty-entities t
                    org-use-sub-superscripts "{}"
                    org-hide-emphasis-markers t
                    org-startup-with-inline-images t
                    org-image-actual-width '(300))
    
    ;; Mostrar marcadores de énfasis ocultos
    (use-package org-appear
        :hook
        (org-mode . org-appear-mode))
    
    (use-package org
      :config
      (setq org-agenda-start-with-log-mode t)
      (setq org-log-done 'time)
      (setq org-log-into-drawer t)
    
      ;; archivos utilizados por la agenda
      (setq org-agenda-files
            '("~/.personal/agenda/personal.org"
              "~/.personal/agenda/trabajo.org"
              "~/.personal/agenda/diario-familia.org"
              "~/.personal/agenda/diario-familia-ibx.org"
              "~/.personal/agenda/diario-personal.org"
              "~/.personal/agenda/diario-personal-ibx.org"))
    
      ;; utilizo mi propio diario para a la agenda, asi que deshabilito el de emacs
      (setq org-agenda-include-diary nil)
      (setq org-agenda-diary-file "~/.personal/agenda/diario-familia.org")
    
      ;; ubicacion de los ficheros cuando son archivados, organizados por fecha
      (setq org-archive-location "~/.personal/archivo/%s_archivo.org::datetree/")
    
      (setq org-todo-keywords
                  '((sequence "PORHACER(p!)"
                              "ENPROCESO(e!)"
                              "BLOQUEADO(b!)"
                              "|" "HECHO(h!)" "ARCHIVAR(a!)")))
    
      ;; (setq org-todo-keyword-faces
      ;;       '(("PORHACER" . "#ff0000")
      ;;         ("ENPROCESO" . "#ff00ff")
      ;;         ("BLOQUEADO" . "#ff00ff")
      ;;         ("HECHO" . "#a3cfa0")
      ;;         ("ARCHIVAR" . "#ffff00")))
    
      (setq org-refile-targets
            '(("personal.org" :maxlevel . 1)
              ("trabajo.org" :maxlevel . 1)))
    
      ;; Guarda los buffers Org despues de rellenar
      (advice-add 'org-refile :after 'org-save-all-org-buffers)
    
      ;; Etiquetas que utilizo para mis notas
      (setq org-tag-alist '(("@nota" . ?n)
                            ("@casa" . ?c)
                            ("@finanzas" . ?d)
                            ("@fecha" . ?f)
                            ("@salud" . ?s)
                            ("@tarea" . ?t)
                            ("@coche" . ?h)
                            ("@trabajo" . ?b)
                            ("crypt" . ?C)))
      (setq org-tags-exclude-from-inheritance '("crypt"))
    
      ;; Registro del progresodelas tareas
      ;; Cuando un elemento TODO entra en DONE, añade una propiedad CLOSED: con la fecha y hora actual en el cajón
      (setq org-log-done 'time)
      (setq org-log-into-drawer "LOGBOOK")
    
      ;; Alinea etiquetas
      (setq org-tags-column 70))
    
    ;; Aspecto mejorado al identar
    (add-hook 'org-mode-hook 'org-indent-mode)
    
    ;; Finalmente haremos que cuando se visualice un fichero con extensión .org éste se adapte a la ventana y cuando la línea llegue al final de esta, haga un salto de carro.
    (add-hook 'org-mode-hook 'visual-line-mode)
    
    ;; Actualiza los ficheros Org con la última fecha de modificación cuando #+lastmod: está disponible
    (setq time-stamp-active t
          time-stamp-start "#\\+lastmod:[ \t]*"
          time-stamp-end "$"
          time-stamp-format "[%04Y-%02m-%02d %a]")
    (add-hook 'before-save-hook 'time-stamp nil)

Org-agenda

Contiene la configuración de las vistas de agenda, los contactos, plantillas de capturas, tareas, notificaciones, etc.

Org-Contacts

La mejor solución para mantener tus contactos. Suelo usar org-contacts está disponible en org-contrib. Los contactos se guardan de forma automática en el fichero contactos.org

    (use-package org-contacts
      :after org
      :custom
      (org-contacts-files '("~/.personal/agenda/contactos.org")))

Agenda

Org-agenda me permite estar organizado con las tareas diarias.

La vista de agenda se activa la tecla F6 y tiene asociada dos vistas a las teclas (z) para la vista trabajo y (x) para la personal.

Para filtrar las vistas utilizo org-super-agenda, este paquete te permite “sobrealimentar” la agenda diaria/semanal. La idea es agrupar elementos en secciones, en lugar de tenerlos todos en una gran lista.

    (global-set-key (kbd "<f6>") 'org-agenda)
    
        (use-package org-super-agenda
          :config
          (org-super-agenda-mode))
    
        (setq org-agenda-skip-scheduled-if-done t
              org-agenda-skip-deadline-if-done t
              org-agenda-compact-blocks t
              org-agenda-window-setup 'current-window
              org-agenda-start-on-weekday 1
              org-deadline-warning-days 7
              org-agenda-time-grid '((daily today require-timed))
              org-agenda-custom-commands
              '(
                ("x" "Vista trabajo"
                 ((agenda "" ((org-agenda-span 3)
                              (org-super-agenda-groups
                               '((:name "Hoy"
                                        :discard (:tag "personal")
                                        :time-grid t
                                        :scheduled past
                                        :deadline past
                                        :date today
                                        :order 1)))))
                  (alltodo "" ((org-agenda-overriding-header "")
                               (org-super-agenda-groups
                                '((:discard (:tag "personal" ))
                                  (:name "Vencimiento hoy"
                                         :deadline today
                                         :order 5)
                                  (:name "Próximamente"
                                         :deadline future
                                         :order 11)
                                  (:name "Atrasado"
                                         :scheduled past
                                         :deadline past
                                         :order 12)
                                  (:name "Por hacer"
                                          ;:discard (:scheduled future :deadline future)
                                         :todo "PORHACER"
                                         :order 12)
                                  (:name "Esperando"
                                         :todo "BLOQUEADO"
                                         :order 14)))))
                  (tags "trabajo/HECHO"
                        ((org-agenda-overriding-header " Tareas Hechas")))))
    
                ("z" "Vista personal"
                 ((agenda "" ((org-agenda-span 3)
                              (org-super-agenda-groups
                               '((:name "Hoy"
                                        :discard (:tag "trabajo" :scheduled past :deadline past)
                                        :time-grid t
                                        :date today
                                        :scheduled today
                                        :order 1)
                                 (:name ""
                                        :tag "agenda"
                                        :todo "Aniversarios")))))
                  (alltodo "" ((org-agenda-overriding-header "")
                               (org-super-agenda-groups
                                '((:discard (:tag "trabajo" ))
                                  (:name "Vencimiento hoy"
                                         :deadline today
                                         :order 5)
                                  (:name "Atrasado"
                                         :scheduled past
                                         :deadline past
                                         :order 11)
                                  (:name "Por hacer"
                                         :discard (:scheduled future :deadline future)
                                         :todo "PORHACER"
                                         :order 12)
                                  (:name "Esperando"
                                         :todo "BLOQUEADO"
                                         :order 14)))))
                  (tags "personal/HECHO"
                        ((org-agenda-overriding-header " Tareas Hechas")))))
                ))

Notificaciones

Muestra notificaciones de otros paquetes de diversas formas. Por ahora solo lo uso para mostrar notificaciones de escritorio.

    (require 'appt)
    (appt-activate 1)
    
    (use-package notifications
      :demand t)
    (add-hook 'org-finalize-agenda-hook 'org-agenda-to-appt) ;; actualiza la lista de  citas en la vista agenda 
    
    (setq appt-display-format 'window
          appt-message-warning-time '5)
    (setq appt-disp-window-function
          (lambda (nmins curtime msg)
            (notifications-notify :title "Recordatorio!!"
                                  :body (format "Tienes una cita %s en %d minutos" msg (string-to-number nmins))
                                  :app-name "Emacs: Org"
                                  :sound-name "alarm-clock-elapsed")))
    (display-time)   ;; activar la visualización de la hora
    (run-at-time "24:01" 3600 'org-agenda-to-appt)   ;; actualizar la lista de citas cada hora
    (setq org-agenda-finalize-hook 'org-agenda-to-appt)

Captura

Las plantillas para org-capture ahorran mucho tiempo al agregar nuevas entradas. yo las suelo usar para registrar rápidamente tareas, entradas de libro mayor, notas y otra información.

    (use-package org
      :bind ("C-c c" . org-capture)
      :preface
      (defvar org-basic-task-template "* PORHACER %?
       Añadido: %U" "Plantilla básica de tareas.")
    
      (defvar org-meeting-template "* Cita con %^{CON}
       :PROPERTIES:
       :SUMMARY: %^{DESCRIPCION ....}
       :NOMOBRE: %^{NOMBRE ....}
       :LUGAR: %^{DONDE ....}
       :DIRECCION: %^{CALLE ....}
       :TELEFONO: %^{123-456-789}
       :NOTA: %^{NOTAS}
       :AÑADIDA: %U
       :END:
       Fecha de la reunión: %?%T" "Plantilla para programar reuniones.")
    
      (defvar org-contacts-template "* %(org-contacts-template-name)
       :PROPERTIES:
       :EMAIL: %(org-contacts-template-email)
       :PHONE: %^{123-456-789}
       :HOUSE: %^{123-456-789}
       :ALIAS: %^{nick}
       :NICKNAME: %^{hefistion}
       :IGNORE:
       :NOTE: %^{NOTA}
       :ADDRESS: %^{Calle Ejemplo 1 2A, 28320, Pinto, Madrid, España}
       :BIRTHDAY: %^{yyyy-mm-dd}
       :END:" "Plantilla para org-contacts.")
      :custom
      (org-capture-templates
       `(("c" "Contactos" entry (file+headline "~/.personal/agenda/contactos.org" "Amigos"),
          org-contacts-template)
    
         ("n" "Nota" entry (file+headline "~/.personal/agenda/reubicar.org" "Nota"),
          org-basic-task-template)
    
         ("i" "Cita familiar" entry (file+datetree "~/.personal/agenda/diario-familia.org"),
          org-meeting-template)
    
         ("I" "Cita personal" entry (file+datetree "~/.personal/agenda/diario-personal.org"),
          org-meeting-template)
    
         ("t" "Tarea" entry (file+headline "~/.personal/agenda/reubicar.org" "Tareas"),
          org-basic-task-template))))

Cifrado / Descifrado

Para poder habilitar el cifrado y descifrado de archivos .gpg con org-mode, necesitas instalar gnupg2. Una vez hecho esto, simplemente configuramos org-crypt para aceptar nuestro identificador de clave pública para permitir el cifrado asimétrico. NOTA: necesitas modificar la variable org-crypt-key para reemplazar mi identificador de clave por el tuyo (o nil para permitir el cifrado simétrico). org-crypt cifra el texto de una entrada, pero no el título o las propiedades

    (use-package org
        :after org
        :config
        (require 'org-crypt))
        (org-crypt-use-before-save-magic)
        (setq org-tags-exclude-from-inheritance (quote ("crypt")))
        (setq org-crypt-key "XXXXXXXX0XXXXXXX.XX")
        (setq org-crypt-disable-auto-save nil)

Teclas rápidas para tareas

Teclas rapidas para gestionar las tareas. Te debes de posicionar al inicio del encabezado y pulsar la tecla rápida para que la tarea cambie de estado. Se necesita la función org-use-speed-commands-for-headings-and-lists definida en el apartado Funciones propias.

Cuando iniciamos el reloj la tarea cambia al estado ENPROCESO y cuando paremos el reloj a BLOQUEADO.

    (setq org-use-speed-commands 'my-org-use-speed-commands-for-headings-and-lists)
    (with-eval-after-load 'org
      (let ((listvar (if (boundp 'org-speed-commands) 'org-speed-commands
                       'org-speed-commands-user)))
        (add-to-list listvar '("A" org-archive-subtree-default))
        (add-to-list listvar '("a" org-todo "ARCHIVAR"))
        (add-to-list listvar '("b" org-todo "BLOQUEADO"))
        (add-to-list listvar '("e" org-todo "ENPROCESO"))
        (add-to-list listvar '("x" org-todo "HECHO"))
        (add-to-list listvar '("x" org-todo-yesterday "HECHO"))
        (add-to-list listvar '("s" call-interactively 'org-schedule))
        (add-to-list listvar '("i" call-interactively 'org-clock-in))
        (add-to-list listvar '("o" call-interactively 'org-clock-out))
        (add-to-list listvar '("d" call-interactively 'org-clock-display))
        (add-to-list listvar '("$" call-interactively 'org-archive-subtree))))
    
    ;; Cambiamos el estado de la tarea cuando inicia o para el reloj
    (setq org-clock-in-switch-to-state "ENPROCESO")
    (setq org-clock-out-switch-to-state "BLOQUEADO")

Funciones propias

Funciones muy simples que simplemente me van a ayudar a acceder fácilmente a mis ficheros de actividades, tareas y notas, escribiéndolo en el mini-buffer con M-x

    ;; Funciones propias
        (defun my-org-use-speed-commands-for-headings-and-lists ()
            "Activate speed commands on list items too."
          (or (and (looking-at org-outline-regexp) (looking-back "^\**" nil))
              (save-excursion (and (looking-at (org-item-re)) (looking-back "^[ \t]*" nil)))))

Personalizando el calendario

Con calfw-org tendremos un calendario muy resultón donde aparecerán nuestras tareas. Para acceder a él escribiremos M-x: cfw-caledario o pulsando la (f8)

Además realizo unos ajustes de aspecto, como que el calendario empiece en Lunes (por defecto lo hace en Domingo) y además los meses y los días de la semana aparecen en español.

Personalizando los meses y semana

    (setq calendar-month-name-array
          ["Enero" "Febrero" "Marzo" "Abril" "Mayo" "Junio"
           "Julio"    "Agosto"   "Septiembre" "Octubre" "Noviembre" "Diciembre"])
    
    (setq calendar-day-name-array
          ["Domingo" "Lunes" "Martes" "Miércoles" "Jueves" "Viernes" "Sábado"])
    
    (setq org-icalendar-timezone "Europe/Madrid") ;; timezone
    (setq calendar-week-start-day 1) ;; la semana empieza el lunes
    (setq european-calendar-style t) ;; estilo europeo

Festivos

Lista de fechas importantes según mi país, España. Es muy probable que algunas fechas sean diferentes en tu país o Comunidad Autónoma, por lo tanto, adapta la configuración como corresponda.

    (setq calendar-holidays '((holiday-fixed 1 1 "Año Nuevo")
                              (holiday-fixed 1 6 "Reyes Magos")
                              (holiday-fixed 3 19 "San José")
                              (holiday-fixed 5 1 "Dia del Trabajo")
                              (holiday-fixed 5 2 "Comunidad de Madrid")
                              (holiday-fixed 5 15 "San Isidro")
                              (holiday-fixed 8 15 "Asunción")
                              (holiday-fixed 10 02 "Día de la Policía")
                              (holiday-fixed 10 12 "Día de la Hispanidad")
                              (holiday-fixed 11 01 "Todos los Santos")
                              (holiday-fixed 11 09 "Almudena")
                              (holiday-fixed 12 06 "Constitución")
                              (holiday-fixed 12 08 "Inmaculada")
                              (holiday-fixed 12 25 "Navidad")
                              ))

Poniendo una vista bonita al calendario

    (use-package calfw
      :config
      (setq cfw:org-overwrite-default-keybinding t)) ;; atajos de teclado de la agenda org-mode
    ;; (setq cfw:display-calendar-holidays nil) ;; para esconder fiestas calendario emacs
    
    (use-package calfw-org
      :ensure t
      :config
      (setq cfw:org-overwrite-default-keybinding t)
      :bind ([f8] . cfw:open-org-calendar))

Sincronización con Caldav

Utilizo org-caldav para la sincronización bidireccional del calendario con servidores CalDav. :files son las ficheros que contienen los eventos que se sincronizaran con el calendario remoto, :inbox es el fichero donde se descargan los eventos del calendario remoto

    (use-package org-caldav
      :bind ([f4] . org-caldav-sync)
      :config
      ;; Calendarios a utilizar
      (setq org-caldav-url "https://XXX.XXXXXXXXXXX.XX")
      (setq org-caldav-calendars
            '((:calendar-id "familia/XXXXXXXXXXXXXXXXXXXXX"
                            :files ("~/.personal/agenda/diario-familia.org")
                            :inbox "~/.personal/agenda/diario-familia-ibx.org")
              (:calendar-id "familia/XXXXXXXXXXXXXXXXXXXXXX"
                            :files ("~/.personal/agenda/diario-personal.org")
                            :inbox "~/.personal/agenda/diario-personal-ibx.org"
                            )))
      (setq org-caldav-backup-file "~/.personal/calendario/org-caldav-backup.org")
      (setq org-caldav-save-directory "~/.personal/calendario/")
      (setq org-icalendar-alarm-time 1))

Configurar Lenguajes en Babel

Para ejecutar o exportar código en bloques de código en org-mode, debes configurar org-babel-load-languages para cada lenguaje que desees utilizar. Esta página documenta todos los lenguajes que puedes usar con org-babel.

La función structure templates del Modo Org permite insertar rápidamente bloques de código en tus archivos Org escribiendo C-c C-, seguido del nombre de la plantilla como el o py y luego presione TAB. Por ejemplo, para insertar un bloque emacs-lisp vacío a continuación, puede escribir C-c C-, y presionar TAB para expandirlo en dicho bloque.

Puedes agregar más plantillas src de bloque, copiando una de las líneas y cambiando las dos cadenas al final, la primera para que sea el nombre de la plantilla y la segunda para que contenga el nombre del lenguaje como lo conoce Org Babel.

    (org-babel-do-load-languages
     'org-babel-load-languages
     '((lisp . t)
       (python . t)
       (shell . t)
       ))
    (add-to-list 'org-structure-template-alist '("py" . "src python"))
    (add-to-list 'org-structure-template-alist '("sh" . "src shell"))
    (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
    ;; (add-to-list 'org-structure-template-alist '("d" . "description"))
    ;; (add-to-list 'org-structure-template-alist '("n" . "note"))
    ;; (add-to-list 'org-structure-template-alist '("al" . "alert"))

Lenguajes

Markdown

Tienes que tener instalado markdown en tu sistema

    (use-package markdown-mode
      :commands (markdown-mode gfm-mode)
      :mode (("README\\.md\\'" . gfm-mode)
             ("\\.md\\'" . gfm-mode)
             ("\\.markdown\\'" . markdown-mode))
      :init (setq markdown-command "markdown2")
      :config
      (setq visual-line-column 80)
      (setq markdown-fontify-code-blocks-natively t)
      (setq markdown-enable-math t))

Magit

Magit es una interfaz para el sistema de control de versiones Git, implementado como un paquete Emacs.

git-gutter permite ver las líneas que se están modificando en el archivo mientras lo estoy editando.

Con git-timemachine visualizas fácilmente los cambios realizados en commits anteriores.

    (use-package magit
      :bind
      ("C-x g" . magit-status))
    
    (use-package git-gutter
      :defer 0.3
      :delight
      :init (global-git-gutter-mode))
    
    (use-package git-timemachine
      :defer 1
      :delight)

Ox-hugo

Exporta archivos org a formato markdown compatible con hugo server

    (use-package ox-hugo
      :after ox)

Terminal

Vterm

Porque es rápido, altamente compatible y es como se anuncia: “Usar vterm es como usar Gnome Terminal dentro de Emacs”. A diferencia de eshell, vterm respeta mi archivo de configuración .zshrc.

    (use-package vterm
      :bind
      (:map
       vterm-mode-map
       ("C-y" . vterm-yank)
       ("C-q" . vterm-send-next-key)))

Tramp

Tramp es excelente para trabajar en archivos remotos. La configuración es simple

    (custom-set-variables
     '(tramp-default-method "ssh")
     '(tramp-default-user "root")
     '(tramp-default-host "192.168.1.2#2231"))

Social

Elfeed

Lector de feeds RSS elfeed-goddies para tener las vistas search y show en la misma ventana y elfeed-protocol para conectr con mi servidor FreshRss.

    (use-package elfeed-goodies
      :after elfeed
      :config
      (elfeed-goodies/setup)
      (setq elfeed-goodies/entry-pane-position 'bottom
            elfeed-goodies/powerline-default-separator 'bar
            elfeed-goodies/entry-pane-size 0.65
            elfeed-goodies/feed-source-column-width 13
            elfeed-goodies/tag-column-width 24))
    ;; elfeed-goodies/switch-to-entry nil))
    
    (use-package elfeed
      :ensure t
      :bind
      ("C-x w" . elfeed)
      :config
      (setq elfeed-use-curl t))
    
    (use-package elfeed-protocol
      :demand t
      :after elfeed
      :bind
      ("C-x q" . elfeed-protocol-fever-reinit)
      :config
      (elfeed-protocol-enable)
      (defun elfeed-search-format-date (date)
        (format-time-string "%Y-%m-%d %H:%M" (seconds-to-time date)))
      :custom
      (elfeed-use-curl t)
      ;; (elfeed-protocol-fever-maxsize 100)
      (elfeed-log-level 'debug)
      (elfeed-protocol-fever-update-unread-only t)
      (elfeed-protocol-feeds (list
                              (list "fever+https://[email protected]"
                                    :api-url "https://[email protected]/fever/"
                                    :password "XXXXXXXXXXXX"
                                    ;;:autotags '(("example.com" comic))
                                    ))))

Mastodon

Cliente para Mastodon

    (use-package mastodon)
    (setq mastodon-instance-url "https://mastodon.social"
          mastodon-active-user "@[email protected]")
    (setq mastodon-tl--highlight-current-toot 1)

Lingva

El paquete lingva.el nos va a permitir hacer uso de lingva-translate pare realizar traducciones desde Emacs sin ser trakeados por Google.

    (use-package lingva
      :config
      (setq lingva-source "auto"
            lingva-target "es"
            lingva-instance "https://translate.plausibility.cloud"))

Puedes encontrar mi fichero de configuracion en mi repositorio de Gitlab

Espero que te haya gustado pasa un gran día, 🐧


Ingrese la dirección de su instancia