Skip to main content
wildebeest-emacs.jpg
By Pablo
Machón
Pablo Machón is a self taught, dedicated technologist.
Así se hace
Emacs
Fácil
Iniciación

Configuración de Emacs 1

Configuración de emacs con «programación literaria», paso a paso

El objetivo es construir una configuración completa de emacs para todo tipo de tareas. Se va desarrollando un archivo de configuración poco a poco, comprendiendo los diversos aspectos del editor.

El plan de trabajo

La idea es controlar la configuración de emacs desde un solo archivo. En él se almacenará la documentación y el código necesario; cada vez que se grabe ese archivo central, se regenerarán todos los archivos necesarios para el uso de emacs según nuestro diseño.

emacs-1-diagram-1.svg

El archivo central se escribe en formato «org-mode» de emacs, que permite la generación de otros archivos a partir de bloques de código. Esta acción se denomina «tangle»1. De manera que utilizaremos el propio emacs para escribir el archivo central en modo «org-mode», y lo llamaremos emacs-config.org, y a partir de él generaremos los dos archivos necesarios:

  • El archivo de configuración de emacs, en lenguaje emacslisp. Nombre: init.el
  • Un programa para iniciar el propio emacs, en lenguaje bash. Nombre: e
emacs-1-diagram-2.svg

Al final del proceso tendremos un programa e con el que lanzamos el emacs. Con emacs podemos editar el archivo central de configuración emacs-config.org, en el que escribiremos documentación y código2. Al grabar ese archivo se generarán automáticamente los archivos init.el (cargado automáticamente al iniciar emacs) y e (utilizado por el usuario para iniciar emacs).

emacs-1-diagram-3.svg

Obviamente, el primer lanzamiento de emacs debe realizarse tecleando emacs y no e, ya que en un primer momento ese archivo todavía no existirá.

Creación de la estructura de carpetas del proyecto

Se crea una carpeta de nombre Projects/emacs. Desde un terminal:

mkdir -p ~/Projects/emacs

Nos desplazamos a esa carpeta:

cd ~/Projects/emacs

Una vez en ella, creamos la carpeta src

mkdir ./src

Podemos comprobar que se ha creado la estructura

tree .

El resultado debe ser algo como:

Projects/
└── emacs
    └── src

El archivo src/emacs-configuration.org

El archivo principal que dará origen a los demás es emacs-configuration.org, dentro del directorio src.

1: #+title Configuracion de Emacs
2: #+auto_tangle: t
3: #+PROPERTY: header-args:emacs-lisp :tangle "../var/init.el" :mkdirp yes
4: 
5: * Configuración de Emacs
6: Archivo de documentación y generación de la configuración de emacs.
7: 

El archivo se inicia con el título. A continuación, una línea para activar la generación automática de archivos cuando se graba. Finalmente, la definición de los datos necesarios relativos al archivo generado principal para bloques de tipo emacs-lisp, que será init.el y estará en la ruta correspondiente: ../var/ (hay que tener en cuenta que el archivo que se está escribiendo está en Projects/emacs/src/, por lo tanto para llegar a Projects/emacs/var/ hay que indicar ../var/). Con :mkdirp yes se indica que deben crearse los subdirectorios indicados que no existan, en este caso var.

Inmediatamente después se incluye un bloque especial de programa en bash, que será el comando utilizado para iniciar el emacs:

  ** Archivo de ejecución de emacs
  Con este script de bash se inicia el emacs, ajustando los directorios y configuraciones. El script se aloja en el directorio =bin/=, y la sintaxis de uso es:

  #+BEGIN_EXAMPLE
  bin/e archivo_a_editar.txt
  #+END_EXAMPLE

  #+begin_src bash-script :tangle ../bin/e :mkdirp yes :tangle-mode (identity #o755)
  #!/bin/bash
  # Emacs startup script

  #################################################
  #  vars
  emacs_bin=/usr/bin/emacs
  emacs_base="$(cd "$(dirname "$(realpath "$0")")/.." && pwd)"
  emacs_home=${emacs_base}/var
  emacs_init_el=${emacs_base}/var/init.el

  bin=${emacs_bin}

  #################################################
  # run basic emacs

  ${bin} \
      --init-directory=${emacs_home}\
      --debug-init\
      -q --no-site-file --load "${emacs_init_el}"\
      $@ &

#+end_src

En este bloque se incica que debe grabarse como ../bin/e, y que será ejecutable (permisos 0755). También se indica que si ../bin/ no existe, debe crearse.

El programa, escrito en bash, simplemente inicia el programa emacs utilizando la configuración que se va a generar en ../var/init.el, y utilizando como base interna el directorio ../var/. En ese directorio se almacenarán todos los paquetes de emacs que se instalen, así omo todo tipo de archivos auxiliares.

También se indica --debug-init al iniciar emacs, para se notifique cualquier error al arrancar.

Por último, un nuevo bloque de código en emacs lisp será el inicio de la configuración de emacs:

** Configuración de emacs
El archivo =var/init.el= se cargará al iniciar emacs.
#+begin_src emacs-lisp
  ;; Emacs Configuration
  (message "Hello World!")
#+end_src

Este bloque no tiene datos para su grabación en archivo separado, por lo tanto utiliza los datos por defecto especificados al principio: se grabará en ../var/init.el

Generación inicial de archivos

Dado que todavía no se ha creado el sistema de generación o actualización e archivos para cada vez que se grabe, se debe realizar todo a mano por el momento. En emacs, pulsar las teclas M-x y luego teclear org-babel-tangle, RETURN . En la consola se puede comprobar que los dos archivos se han creado:

tree .

El resultado debe ser algo como:

Projects/
└── emacs
    ├── bin
    │   └── e
    ├── src
    │   └── emacs-configuration.org
    │   └── emacs-configuration.org~
    └── var
        └── init.el
    

El archivo emacs-configuration.org~ es una copia de seguridad que emacs genera automáticamente al editar un archivo.

Se puede salir de emacs con C-x C-c, e iniciarlo de nuevo, pero ya con nuestra configuración, con:

bin/e src/emacs-configuration.org

Emacs screen after first successful initialization
Emacs screen after first successful initialization

Interface de usuario (UI)

Al iniciar emacs, la pantalla aparece partida por la mitad, y en su parte inferior muestra un texto de bienvenida. Para desactivarlo, creamos una sección «UI», en el archivo de configuración, dedicada a los aspectos de la interacción con el usuario.

** UI: interacción
En este bloque se configuran los aspectos visuales y de interacción con el usuario.

#+begin_src emacs-lisp
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UI

;; inhibit initial screens
(setq inhibit-splash-screen t
      inhibit-startup-screen t)

#+end_src

Auto tangle (generación automática de archivos al grabar)

El siguiente objetivo es conseguir que el proceso de generación de archivos (tangle), que ahora se dispara tecleando M-x org-babel-tangle, se produxca de forma automática cada vez que se graba el archivo .org. En concreto, este automatismo debe funcionar cuando el archivo incluya el código #+auto_tangle: t.

Para ello se agrega la siguiente parte en el archivo emacs-conig.org:

** Org-mode: autotangle
Genera bloques src a sus archivos designados si "autotangle" está configurado en un archivo org.

Ajustar ~#+auto_tangle: t~ para activarlo. Luego, ajustar ~#+PROPERTY: header-args:emacs-lisp :tangle "../var/init.el" :mkdirp yes~ para controlarel ajuste general, y

#+begin_example
:PROPERTIES:
:header-args:emacs-lisp: :tangle (expand-file-name "file.el" user-emacs-directory) :mkdirp yes
:END:
#+end_example

#+begin_src emacs-lisp

;; SYNC autotangle (avoid autotangle package, incompatible with our
;; on-the-fly module modifications)

(defun my-org-tangle-on-save ()
"Tangle the current Org file synchronously if #+auto_tangle: t is set."
(when (derived-mode-p 'org-mode)
(save-excursion
(goto-char (point-min))
(let* ((keywords (org-collect-keywords '("auto_tangle")))
(auto-tangle (cadr (assoc "AUTO_TANGLE" keywords))))
(when (and auto-tangle (string= (downcase auto-tangle) "t"))
;;(message "Tangling %s synchronously..." (buffer-file-name))
(let ((start-time (current-time)))
(org-babel-tangle)
(message "Tangling completed in %.2f seconds" (float-time (time-since start-time)))))))))

;; Enable this in all Org buffers
(add-hook 'org-mode-hook
(lambda ()
(add-hook 'after-save-hook #'my-org-tangle-on-save nil t)))
;;
#+end_src
"Pablo Machón icon"

Notas al pie de página:

1

«Tangle» es una característica de Org-mode en Emacs, que permite crear archivos de diversos formatos a partir de un documento org-mode.

2

Desarrollar código y documentación en el mismo archivo es una técnica denominada «programación literaria», inventada por Donald Knuth.