Cuando se empieza a utilizar Emacs, la mayoría de las veces copiamos código de aquí y de allí, funciones que realmente no sabemos que hacen o si las vamos a utilizar, poco a poco, según empiezas a utilizar Emacs vas desechando código, añadiendo nuevas funciones o paquetes, en definitiva, tienes un fichero de configuración que va cambiando constantemente.
Creo haber alcanzado un cierto nivel de estabilidad en Emacs, como para tener un fichero de configuración más o menos estable, solo utilizo lo que necesito, es decir, organizo mi día a día con Org Mode (agenda, calendario y notas, creo y publico los artículos del blog (ox-hugo), utilizo el lector rss (elfeed) para estar al día, interactuo en Mastodon (mastodn.el) y Telegram (telega.el) y gestiono mi correo electrónico (mu4e), además suelo utilizar el navegador EWW con bastante frecuencia.
He dejado de jugar con Python, por lo que he borrado todos los paquetes relacionados con él aligerando bastante el fichero de configuración. Asi qeu si buscas un fichero de configuración simple, esperoq ue este te puedda ser de utiliddad.
Introducción
Esta configuración tiene como base la serie de artículos escritos en el sitio Emacs From Scratch. 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 genera 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.
UTF-8
;; Codificación UTF-8 por defecto
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(if (boundp 'buffer-file-coding-system)
(setq-default buffer-file-coding-system 'utf-8)
(setq default-buffer-file-coding-system 'utf-8))
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
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 su configuración. 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.
;; Initialize package sources
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")))
;;("org" . "https://orgmode.org/elpa/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
;; Initialize use-package on non-Linux platforms
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
Configuración básica de la interfaz de usuario
En esta sección configuro las 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)
(scroll-bar-mode -1) ; Disable visible scrollbar
(tool-bar-mode -1) ; Disable the toolbar
(tooltip-mode -1) ; Disable tooltips
(set-fringe-mode 10) ; Give some breathing room
(menu-bar-mode -1) ; Disable the menú bar
;; Set up the visible bell
(setq visible-bell t)
(column-number-mode)
(global-display-line-numbers-mode t)
;; Set frame transparency
(set-frame-parameter (selected-frame) 'alpha '(95 .95 ))
(add-to-list 'default-frame-alist `(alpha . (95 . 95)))
(set-frame-parameter (selected-frame) 'fullscreen 'maximized)
(add-to-list 'default-frame-alist '(fullscreen . maximized))
;; sustituye yes/no por y/n
(fset 'yes-or-no-p 'y-or-n-p)
;; Disable line numbers for some modes
(dolist (mode '(org-mode-hook
treemacs-mode-hook
shell-mode-hook
mastodon-mode-hook
telega-root-mode-hook
telega-chat-mode-hook
elfeed-show-mode-hook
elfeed-search-mode-hook
mu4e-main-mode-hook
vterm-mode-hook
wallabag-search-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
;; Dislay Clock
(display-time)
(setq
display-time-24hr-format t ; Muestra el reloj en formato 24 hrs
display-time-format "%H:%M" ; Le da formato a la hora
load-prefer-newer t ; Prefiere la versión más reciente de un archivo.
select-enable-clipboard t ; Sistema de fusión y portapapeles de Emacs.
vc-follow-symlinks t ; Siempre sigue los enlaces simbólicos.
make-backup-files nil ; No realiza backups de ficheros
auto-save-default nil ; Deshabilita #file#
;; org-footnote-section "Referencias:" ; cambio footnotes por referencias
;; global-hl-line-mode t ; Highlight current line
kill-ring-max 128 ; Longitud máxima del anillo de matar
create-lockfiles nil ; Impido la creación de ficheros .#
)
Configuración de la fuente
Uso las fuentes Fira Code para esta configuración, lo más probable es que sea necesario instalarla en tu máquina. Generalmente se puede encontrar en los diversos administradores de paquetes de distribución Linux o se pueden descargar desde los enlaces anteriores.
(set-face-attribute 'default nil :font "Fira Code" :height 120)
;; Set the fixed pitch face
(set-face-attribute 'fixed-pitch nil :font "Fira Code" :height 120)
Ligaduras
La GUI predeterminada de Emacs no admite ligaduras de programación. Si estás usando una versión >= 28 de Emacs , el método más fácil es usar ligature.el de Mickey Petersen ( de “Mastering Emacs”)
(setq master-font-family "FiraCode")
(use-package ligature
:config
(ligature-set-ligatures 't '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "
: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 my/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"),
my/org-contacts-template)
("f" "Fecha" entry (file+headline "~/.personal/agenda/reubicar.org" "Fechas"),
my/org-basic-task-template)
("n" "Nota" entry (file+headline "~/.personal/agenda/reubicar.org" "Nota"),
my/org-basic-task-template)
("i" "Cita" entry (file+datetree "~/.personal/agenda/diario.org"),
my/org-meeting-template)
("b" "Blog" entry (file+headline "~/.personal/agenda/reubicar.org" "Blog"),
my/org-basic-task-template)
("t" "Tarea" entry (file+headline "~/.personal/agenda/reubicar.org" "Tareas"),
my/org-basic-task-template))))
Cifrado / Descifrado
Para poder habilitar el cifrado y descifrado de archivos .gpg con org-mode, necesitaremos 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-crypt
:ensure nil
:after org)
(org-crypt-use-before-save-magic)
(setq org-tags-exclude-from-inheritance (quote ("crypt")))
(setq org-crypt-key "xxxxxxxx")
(setq org-crypt-disable-auto-save nil)
Teclas rápidas para tareas
Teclas rápidas para gestionar las tareas. Te debes de posicionar al inicio del encabezado y pulsar la tecla rápìda para que la tarea cambie de estado. Se encesita 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
(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
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 poner que empiece el calendario en Lunes (por defecto lo hace en Domingo) y además pongo los meses y los días de la semana 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 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
(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 sincronizarán 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)
:preface
:custom
;; Calendarios a utilizar
(org-caldav-url "https://server.es/caldav/group==familia")
(org-caldav-calendars
'((:calendar-id "carlos--xxxxx"
:files ("~/.personal/agenda/diario.org")
:inbox "~/.personal/agenda/diario-ibx.org")))
(org-caldav-backup-file "~/.personal/calendario/org-caldav-backup.org")
(org-caldav-save-directory "~/.personal/calendario/")
(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 '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
Auto-tangle Ficheros de Configuración
Este snippet agrega un enlace a los búferes org-mode para que efs/org-babel-tangle-config se ejecute cada vez que se guarda dicho búfer. Esta función comprueba si el archivo que se está guardando es el archivo Emacs.org que estás viendo en este momento, y si es así, exporta automáticamente la configuración a los archivos de salida asociados.
;; Automatically tangle our Emacs.org config file when we save it
(defun efs/org-babel-tangle-config ()
(when (string-equal (file-name-directory (buffer-file-name))
(expand-file-name user-emacs-directory))
;; Dynamic scoping to the rescue
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle))))
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'efs/org-babel-tangle-config)))
Desarrollo
Lenguajes
Markdown
A veces escribo notas en Markdown, por eso lo mantengo, utilizo pandoc
(use-package markdown-mode
:commands (markdown-mode gfm-mode)
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . gfm-mode)
("\\.markdown\\'" . markdown-mode))
:init (setq markdown-command "pandoc")
: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)
Rainbow Delimiters
rainbow-delimiters es útil en los modos de programación porque colorea los paréntesis y corchetes anidados de acuerdo con su profundidad de anidación. Esto hace que sea mucho más fácil hacer coincidir visualmente los paréntesis en el código
;; Mostrar al padre
(show-paren-mode 1)
;; auto close bracket insertion.
(electric-pair-mode 1)
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
Ox-hugo
Exporta archivos org a formato markdown compatible con Hugo Server, mi blog está construido así
(use-package ox-hugo
:after ox)
Terminal
Vterm
Porque es rápido, altamente compatible y e 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
(use-package tramp
:ensure nil
:defer t
:config
(setq tramp-default-user "carlos"
tramp-default-method "ssh")
(use-package counsel-tramp
:bind ("C-c t" . counsel-tramp))
(put 'temporary-file-directory 'standard-value '("/tmp")))
Administrador de Archivos
Dired
Dired es un administrador de archivos integrado para Emacs que hace cosas asombrosas. Aquí hay algunas combinaciones de teclas que debes probar:
Atajos de teclado
Navegación
n- próxima líneap- lìnea previaj- saltar al archivo en el búferRET- seleccionar archivo o directorio^- ir al directorio superiorS-RET- Abrir fichero en “otra” ventanaM-RET- Mostrar archivo en otra ventana sin enfocar (vista previa de archivos)g o(dired-view-file) -Abrir archivo pero en modo “vista previa”, cerrar conqg/g rActualice el búfer conrevert-bufferdespués de cambiar la configuración (¡y después de que cambie el sistema de archivos!)
Marcar archivos
m- MArca un archivou- Desmarca un archivoU- Desmarca todos los archivos del búfer* t/t-Invierte archivos marcados en el búfer% m- Marcar archivos en el búfer usando expresión regular*- Muchas otras funciones de marcado automáticok/K- “Eliminar” elementos marcados (actualizar el búfer cong/g rpara recuperarlos)- ¡Se pueden realizar muchas operaciones en un solo archivo si no hay marcas activas!
Copiar y renombrar archivos
C- Copiar archivos marcados (o si no hay archivos marcados, el archivo actual)- Copia de archivos únicos y múltiples
U- Desmarcar todos los archivos en el búferR- ¡Cambiar el nombre de los archivos marcados, cambiar el nombre de varios es un movimiento!% R- Cambiar el nombre según la expresión regular: = ^ test =, = old - \ & =
Comando:
C-x C-q = (=dired-toggle-read-only) - ¡Hace que todos los nombres de archivo en el búfer sean editables directamente para cambiarles el nombre! PresioneZ Zpara confirmar el cambio de nombre oZ Qpara cancelar.Eliminando archivos
D- Eliminar archivo marcadod- Marcar archivo para borrarx- Ejecutar eliminación de marcasdelete-by-moving-to-trash- Mover a la papelera en lugar de eliminar permanentemente
Creación y extracción de archivos.
Z- Comprimir o descomprimir un archivo o carpeta en (.tar.gz)c- Comprimir la selección a un archivo específicodired-compress-files-alist- Vincular comandos de compresión a la extensión del archivo+- Crear un directorio nuevo
Otras operaciones habituales
T- Toque (cambiar marca de tiempo)M- Cambiar modo de archivoO- Cambiar propietario del archivoG- Cambiar grupo de archivosS- Crea un enlace simbólico a este archivoL- Carga un archivo Emacs Lisp en Emacs
Configuración
(use-package dired
:ensure nil
:commands (dired dired-jump)
:bind (("C-x C-j" . dired-jump))
:custom ((dired-listing-switches "-agho --group-directories-first")))
(use-package all-the-icons-dired
:hook (dired-mode . all-the-icons-dired-mode))
;; Por defecto los ficheros ocultos no se muestran hasta que pulsamos la tecla .
(use-package dired-hide-dotfiles
:bind
(:map dired-mode-map
("." . dired-hide-dotfiles-mode))
:hook
(dired-mode . dired-hide-dotfiles-mode))
Social
Correo
Manejo mis cuentas de correo desde Emacs, escribí un artillo sobre como preparar y configurar Emacs para Gamil. quizas estes interesado en echarle un vistazo :eyes:
Mbsync
Se utiliza para descargar correos electrónicos desde diferentes servidores IMAP y sincronizar los cambios realizados con nuestro buzón local.
Necesitamos crear un fichero de configuración para mbsync, crea un fichero llamado .mbsyncrc en tu $HOME con el siguiente código:
IMAPAccount gmail
Host imap.gmail.com
User [email protected]
Pass password_gmail
AuthMechs LOGIN
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore gmail-remote
Account gmail
MaildirStore gmail-local
Subfolders Verbatim
Path ~/.mail/gmail/
Inbox ~/.mail/gmail/Inbox
Channel gmail
Far :gmail-remote:
Near :gmail-local:
Patterns * ![Gmail]* "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail"
Create Both
SyncState *
IMAPStore synology-remote
Account synology
IMAPAccount synology
Host dominio.es
User [email protected]
Pass xxxxxxx
AuthMechs LOGIN
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore synology-remote
Account synology
MaildirStore synology-local
Subfolders Verbatim
Path ~/.mail/synology/
Inbox ~/.mail/synology/Inbox
Channel synology
Far :synology-remote:
Near :synology-local:
Patterns *
Create Both
SyncState *
Mu4e
El siguiente código está configurado para poder consultar mi correo de gmail y el de mi propio servidor de correo alojado en mi NAS.
(use-package mu4e
:ensure nil
:bind ("C-c m" . mu4e)
:config
(setq mail-user-agent 'mu4e-user-agent ; mu4e e-mail default program
message-kill-buffer-on-exit t
message-send-mail-function 'smtpmail-send-it
mu4e-attachment-dir "~/Descargas"
mu4e-change-filenames-when-moving t
mu4e-completing-read-function 'completing-read
mu4e-compose-complete-addresses t
mu4e-compose-context-policy nil
mu4e-compose-dont-reply-to-self t
mu4e-compose-keep-self-cc nil
mu4e-context-policy 'pick-first
mu4e-get-mail-command "mbsync -a"
mu4e-headers-date-format "%d-%m-%Y %H:%M"
mu4e-headers-fields '((:human-date . 20)
(:flags . 6)
(:mailing-list . 10)
(:from . 22)
(:subject))
mu4e-headers-include-related t
mu4e-sent-messages-behavior 'delete ; don't save messages to Sent Messages
mu4e-view-show-addresses t
smtpmail-debug-info t
smtpmail-stream-type 'starttls
mm-sign-option 'guided
mu4e-html2text-command "w3m -T text/html" ; how to hanfle html-formatted emails
mu4e-update-interval 300 ; seconds between each mail retrieval
mu4e-headers-auto-update t ; avoid to type `g' to update
mu4e-view-show-images t ; show images in the view buffer
mu4e-compose-signature-auto-include nil ; I don't want a message signature
mu4e-use-fancy-chars t) ; allow fancy icons for mail threads
(when (fboundp 'imagemagick-register-types)
(imagemagick-register-types))
(defun sign-or-encrypt-message ()
(let ((answer (read-from-minibuffer "Firmar o cifrar?\nEn blanco no hace nada.\n[f/c]: ")))
(cond
((string-equal answer "f") (progn
(message "Firmando mensaje.")
(mml-secure-message-sign-pgpmime)))
((string-equal answer "c") (progn
(message "Cifrando y formando mensaje.")
(mml-secure-message-encrypt-pgpmime)))
(t (progn
(message "No firmar o cifrar mensaje.")
nil)))))
(add-hook 'message-send-hook 'sign-or-encrypt-message)
(setq mu4e-contexts
`( ,(make-mu4e-context
:name "gmail"
:enter-func (lambda ()
(mu4e-message "Entering gmail context")
(when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
(revert-buffer)))
:leave-func (lambda ()
(mu4e-message "Leaving gmail context")
(when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
(revert-buffer)))
:match-func (lambda (msg)
(when msg
(or (mu4e-message-contact-field-matches msg :to "[email protected]")
(mu4e-message-contact-field-matches msg :from "[email protected]")
(mu4e-message-contact-field-matches msg :cc "[email protected]")
(mu4e-message-contact-field-matches msg :bcc "[email protected]")
(string-match-p "^/gmail/Inbox" (mu4e-message-field msg :maildir)))))
:vars '( ( user-mail-address . "[email protected]" )
( smtpmail-smtp-user . "[email protected]" )
( mu4e-compose-signature . "Carlos M." )
( smtpmail-smtp-server . "smtp.gmail.com" )
( smtpmail-smtp-service . 587 )
( mu4e-maildir-shortcuts . ((:maildir "/gmail/Inbox" :key ?i)))
( mu4e-bookmarks
.
(( :name "Unread messages"
:query "maildir:/gmail/Inbox AND flag:unread AND NOT flag:trashed AND NOT outdoorexperten"
:key ?u)
( :name "Today's messages"
:query "maildir:/gmail/Inbox AND date:today..now"
:key ?t)
( :name "Last 7 days"
:query "maildir:/gmail/Inbox AND date:7d..now"
:hide-unread t
:key ?w)
( :name "Deleted"
:query "flag:trashed"
:key ?d)))))
,(make-mu4e-context
:name "synology"
:enter-func (lambda ()
(mu4e-message "Entering synology context")
(when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
(revert-buffer)))
:leave-func (lambda ()
(mu4e-message "Leaving synology context")
(when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
(revert-buffer)))
:match-func (lambda (msg)
(when msg
(or (mu4e-message-contact-field-matches msg :to "[email protected]")
(mu4e-message-contact-field-matches msg :from "[email protected]")
(mu4e-message-contact-field-matches msg :cc "[email protected]")
(mu4e-message-contact-field-matches msg :bcc "[email protected]"))))
:vars '( ( user-mail-address . "[email protected]" )
( smtpmail-smtp-user . "[email protected]" )
( smtpmail-smtp-server . "smtp.dominio.es" )
( smtpmail-smtp-service . 587 )
( mu4e-compose-signature . "Carlos M." )
( mu4e-maildir-shortcuts . ((:maildir "/synology/Inbox" :key ?i)))
( mu4e-bookmarks
.
(
( :name "Unread messages"
:query "maildir:/synology/Inbox AND flag:unread AND NOT flag:trashed"
:key ?u)
( :name "Draft mails"
:query "maildir:/synology/Draft"
:key ?b)
( :name "Sent mails"
:query "maildir:/synology/Sent"
:key ?s)
( :name "Junk"
:query "maildir:/synology/Junk"
:key ?j)
( :name "Trash"
:query "maildir:/synology/Trash"
:key ?t)
( :name "Deleted"
:query "flag:trashed"
:key ?d))))))))
OrgMsg
OrgMsg es un modo menor global de Emacs que combina el modo Org y el modo Mensaje para redactar y responder correos electrónicos en un estilo compatible con HTML.
(use-package org-msg
:after mu4e
:config
(setq mail-user-agent 'mu4e-user-agent)
(require 'org-msg)
(setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t"
org-msg-startup "hidestars indent inlineimages"
org-msg-default-alternatives '((new . (text html))
(reply-to-html . (text html))
(reply-to-text . (text)))
org-msg-convert-citation t)
(org-msg-mode))
Elfeed
Lector de feeds RSS. Utilizo elfeed-org para guardar las direcciones de los feeds, elfeed-goddies para tener las vistas search y show en la misma ventana y elfeed-protocol para conectar con mi servidor FreshRss.
(use-package elfeed
:bind
("C-x w" . elfeed))
(use-package elfeed-org
:config
(elfeed-org)
(setq rmh-elfeed-org-files (list "~/.config/elfeed/elfeed.org"))
(defun elfeed-search-format-date (date)
(format-time-string "%Y-%m-%d %H:%M" (seconds-to-time date)))
;; Mark all YouTube entries
(add-hook 'elfeed-new-entry-hook
(elfeed-make-tagger :feed-url "youtube\\.com"
:add '(youtube)))
;; Mark all reddit entries
(add-hook 'elfeed-new-entry-hook
(elfeed-make-tagger :feed-url "reddit\\.com"
:add '(reddit))))
(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))
Mastodon
Cliente para Mastodon
(use-package mastodon)
(setq mastodon-instance-url "https://mastodon.social"
mastodon-active-user "@[email protected]")
Telegram
telega.el es un cliente no oficial con todas las funciones para la plataforma Telegram en Emacs.
(use-package tracking)
(use-package telega
:commands telega
:defer t
:custom
(telega-use-tracking-for '(any pin unread))
(telega-chat-use-markdown-formatting t)
(telega-emoji-use-images t)
(telega-completing-read-function #'selectrum-completing-read)
(telega-msg-rainbow-title t)
(telega-chat-fill-column 75)
;; (telega-appindicator-mode t)
(telega-notifications-mode t)
(telega-filters-custom nil))
(define-key global-map (kbd "C-c t") telega-prefix-map)
Emojify
Emojify es una extensión Emacs para mostrar emojis. Puede mostrar emojis de estilo github como :smile: o simples ascii como :)
(use-package emojify
:hook (after-init . global-emojify-mode))
Puedes encontrar mi fichero de configuración en mi repositorio de Gitlab
Espero que te haya gustado pasa un gran día, 🐧