YouTube Odysee

§Introducción

Hoy vamos a agregar algunas configuraciones a nuestro emacs de ejemplo.

Agregaremos un par de paquetes que a mi parecer son bastante útiles:

  • vertico
  • orderless

Y lo haremos de dos maneras distintas, aunque muy similares.

§¿Qué es todo esto?

Hay varias formas de configurar paquetes en emacs, desde copiar los archivos de código fuente directo a un directorio y agregar ese directoria a la load-path, hasta utilizar otros paquetes para instalar paquetes (sí, suena redundante, pero funciona).

En este video veremos un par de opciones para instalar paquetes con package.el y configurarlos utilizando únicamente emacs-lisp (nada de use-package, leaf, et. al.).

Básicamente hay dos maneras de instalar tus paquetes: lo que llamo el modo «tradicional», en donde encapsulas la instalacón y configuración de tu paquete en un bloque/archivo de código; y una manera que llamo «global», en que en distintas partes de tu código instalas los paquetes y en otra los configuras (ya sea distintos bloques o distintos archivos).

§Vamos al código fuente

Quien quiera acceder a esta sección sin toda la demás explicación y discusión (previa y posterior), puden acceder a él en la siguiente dirección: https://codeberg.org/barocio/emacs-config-examples/src/branch/0x0005/0x0005.

§Configurar y activar package.el

§Encabezado de init-pkg.el

;;; init-pkg.el -- Configuración de package.el         -*- lexical-binding:t -*-

§Configuración

Esto es importante para poder instalar paquetes en emacs. Por supuesto, no es la única manera de instalarlos, pero es la que viene por default en emacs y es la que voy a estar recomendando, sin menospreciar otros poderosos métodos que pudieran existir (straight.el, elpaca.el, etc.).

§Cierre de init-pkg.el

;;; init-pkg.el ends here

§Modo «tradicional»

§Encabezado del archivo init-trad.el

Esto no es absolutamente necesario, pero es muy recomendable incluirlo al inicio de cualquier archivo código fuente de emacs-lisp. Aquí indicamos el nombre del archivo, una muy, muy, muy breve descripción y activamos los lexical-bindings, que son una forma de decirle al intérprete de emacs-lisp cómo ejecutar este código, en particular que ligue los nombres de variables y funciones a su contexto léxico.

;;; init-trad.el --- Archivo de configuración de emacs -*- lexical-binding:t -*-

;;; 0x0004

(package-install 'beacon)
(beacon-mode +1)

(package-install 'evil)
(evil-mode +1)

(package-install '0x0)

(package-install 'doom-themes)
(load-theme 'doom-monokai-pro t)
(disable-theme 'wombat)

§Configurar y activar vertico

He elegido vértico precisamente porque es muy sencillo de configurar: sólo basta instalarlo y activar el modo.


;;; Vertico
;; Instalamos el paquete.
(package-install 'vertico)

;; Activamos el modo.
(vertico-mode +1)

Eso es todo.

§Configurar y activar orderless

Orderless es un paquete que se puede configurar de manera avanzada.

Comencemos por instalarlo:


;;; Orderless
;; Instalamos el paquete.
(package-install 'orderless)

Ahora configuraremos algunas variables que modifican su funcionamiento:

;; Con esta opción activamos el uso del paquete
(customize-set-variable 'completion-styles '(orderless))
;; (setopt completion-styles '(orderless))

;; Elegimos algunas opciones para la búsqueda, selección y filtrado de opciones.
(customize-set-variable 'orderless-matching-styles '(orderless-regexp))
;; (setopt orderless-matching-styles '(orderless-regexp))

Ahora podemos extender su funcionalidad:

;; Completa con las letras iniciales de la función/variable/objeto/símbolo.
(defun first-initialism (pattern index total)
  "Completes with the first letter of the function/variable/object/symbol."
  (if (= index 0) 'orderless-initialism))

;; Esto nunca lo entendí
(defun flex-if-twiddle (pattern index total)
  "Removes the pattern folowing a literal `~' from completions."
  (when (string-suffix-p "~" pattern)
    `(orderless-flex . ,(substring pattern 0 -1))))

;; Elimina de las complesiones las opciones que coincidan con lo que siga de la exclamación.
(defun without-if-bang (pattern index total)
  "Removes the pattern folowing a literal `!' from completions."
  (cond
   ((equal "!" pattern)
    '(orderless-literal . ""))
   ((string-prefix-p "!" pattern)
    `(orderless-without-literal . ,(substring pattern 1)))))

;; Activamos las opciones extra para `orderless'.
(customize-set-variable 'orderless-style-dispatchers
                        '(first-initialism
                          flex-if-twiddle
                          without-if-bang))

Para una expliación más completa, puedes ver el video de Andrew Tropin «Emacs Completion Explained».

§Finalización del archivo init-trad.el

Esta parte tampoco es necesaria, pero es una buena práctica indicar dónde termina el código del archivo. No tiene ningún efecto sobre el intérprete, pero es una manera de mantener un poco de órden mental. Aún más, cuando comencemos a extraer código de nuestro init.el y lo coloquemos en otros archivos, esta pieza de código, este comentario y el primero que pusimos en el archivo serán muy útiles.

;;; init-trad.el ends here

§Configuración directa, todos los paquetes a la vez.

Hay una manera de seleccionar los paquetes que se utilizarán e instalarlos de una sola vez. Por supuesto, esto requiere que se configure package.el.

§Encabezado del archivo init-alt.el

Esto no es absolutamente necesario, pero es muy recomendable incluirlo al inicio de cualquier archivo código fuente de emacs-lisp. Aquí indicamos el nombre del archivo, una muy, muy, muy breve descripción y activamos los lexical-bindings, que son una forma de decirle al intérprete de emacs-lisp cómo ejecutar este código, en particular que ligue los nombres de variables y funciones a su contexto léxico.

;;; init-alt.el --- Archivo de configuración de emacs  -*- lexical-binding:t -*-

§Seleccionar paquetes


;;; Selección e instalación de paquetes

Para seleccionar paquetes símplemente los agregamos a una lista especial.

;; Selección de paquetes

;;; 0x0004

(add-to-list 'package-selected-packages 'beacon)
(add-to-list 'package-selected-packages 'evil)
(add-to-list 'package-selected-packages '0x0)
(add-to-list 'package-selected-packages 'doom-themes)

;;; 0x0005
(add-to-list 'package-selected-packages 'vertico)
(add-to-list 'package-selected-packages 'orderless)

§Instalar los paquetes seleccionados

;; Instalación de paquetes
(package-install-selected-packages :noconfirm)

§Configurar paquetes


;;; Configurar paquetes

;;; 0x0004
(beacon-mode +1)
(evil-mode +1)
(load-theme 'doom-monokai-pro t)
(disable-theme 'wombat)

§Finalización del archivo init-alt.el

Esta parte tampoco es necesaria, pero es una buena práctica indicar dónde termina el código del archivo. No tiene ningún efecto sobre el intérprete, pero es una manera de mantener un poco de órden mental. Aún más, cuando comencemos a extraer código de nuestro init.el y lo coloquemos en otros archivos, esta pieza de código, este comentario y el primero que pusimos en el archivo serán muy útiles.

;;; init-alt.el ends here

§Archivo principal

Este sería el archivo de configuración init.el.

;;; init.el --- Archivo de configuración de emacs      -*- lexical-binding:t -*-

;;; 0x0003 -- Una configuración minimalista -- algo para comenzar
(load-theme 'wombat t)

(set-face-attribute 'default nil :height 160)

;; Pasamos un valor negativo a la función `menu-bar-mode'.
(menu-bar-mode -1)
;; Pasamos un valor negativo a la función `tool-bar-mode'.
(tool-bar-mode -1)
;; Pasamos un valor negativo a la función `scroll-bar-mode'
(scroll-bar-mode -1)

(setq inhibit-splash-screen t
      user-full-name "Alex Barocio")
(setq visible-bell t)

;;; 0x0004 -- Instalar paquetes en Emacs
;; Cambiar donde se guardan las customizaciones
(setq custom-file
      (expand-file-name "custom.el"
                        user-emacs-directory))

(add-hook 'emacs-startup-hook
          (lambda ()
            (when (file-exists-p custom-file)
              (load-file custom-file))))

;; Modificado en 0x0005: se extrajo y ampiló la configuración de
;; `package' en su propio archivo.
(load-file (expand-file-name "init-pkg.el" user-emacs-directory))

;;; 0x0005 -- Configurar Emacs usando emacs-lisp

;; (load-file (expand-file-name "init-trad.el" user-emacs-directory))
(load-file (expand-file-name "init-alt.el" user-emacs-directory))

;;; init.el ends here

§Comentarios

Al no utilizar use-package (ni ninguna otra macro) tenemos algunas ventajas y otras desventajas, como en (casi) todo.

§Ventajas

  • La mayoría de las configuraciones no necesitan de la macro use-package.
  • Promueve un conocimiento más claro de lo que se puede hacer con emacs-lisp.
  • No agrega paquetes extra (bloated software).
  • Para configuraciones pequeñas es sencillo y rápido.

§Desventajas

  • Las dependencias de configuración entre paquetes puede ser difícil de lograr.
  • No todos los usuarios de emacs les gusta programar.
  • Muchos desarrolladores de paquetes sugieren el uso de la macro use-package para configurar sus paquetes.
  • Para configuraciones grandes, es fácil perderse entre todo el código si no se tiene cuidado de mantenerlo ordenado.
  • Con configuraciones grandes es fácil que el arranque se vuelva lento.

§Conclusión

En realidad depende del tipo de configuración que tengas y el tipo de usuario que seas.

Te recomiendo que experimentes con distintos estilos de configuración (sí, incluyendo la interfaz customize), y elijas la que más te agrade o te convenga.

En emacs hay más de una forma de hacer las cosas, si es la adecuada o correcta dependerá de tu caso particular, tus habilidades y modo de trabajo.

§¿Y ahora qué?

En el próximo video veremos otra forma de configurar un paquete por medio de use-package.

Puedes acceder a mis notas en mi repositorio: https://git.sr.ht/~abarocio80/videos/tree/master/item/content/0x0005--configurar-emacs-usando-emacs-lisp.org

O en mi página: https://barocio.cc/videos/0x0005--configurar-emacs-usando-emacs-lisp.html

Si te interesa este tipo de contenido, suscríbete al canal y activa las notificaciones para que (tarde o temprano) te enteres de los nuevos videos que vaya subiendo.

Nos vemos luego.