Hace tiempo que vengo oyendo las maravillas del modo org de Emacs y siempre había pasado de él. Hasta hace unos días que me dio por probarlo. Lo conté ya en esta entrada el otro día y como continuación de la historia quiero contar qué cosas he ido investigando y haciendo.
Lo primero Lisp
Lisp es un lenguaje que tenía absolutamente olvidado. Lo conocí hace muchos años y lo abandoné –como abandoné también mi querido smalltalk y otras cosas de los primeros ordenadores que utilicé–. Lisp es un lenguaje sencillo y potente, en su día enfocado a la IA –uno de esos campos que, como psicólogo, siempre me han llamado la atención–. Al final, todo es recuperar un poco de memoria de cómo funciona y qué se puede hacer con él, me ha llevado poco tiempo. Recordar un poco las funciones, listas y bloques de código.
Documentación
He leído mucha documentación. Aunque no he leído completo el manual del modo org que viene con el propio Emacs (C-h i) y/o en el comando info en una consola de texto. Esto es otra de las cosas que he rescatado del baúl de los recuerdos. Hacía años que no abría con tanta frecuencia una documentación info. El control de teclas para saltar de un texto al siguiente o al anterior, o al superior jerárquico se recuerdan fácilmente.
Es importante, porque al final de ahí es de donde he sacado la mayoría de las cosas útiles que me han funcionado. Porque, probar he probado mucho código copiado de Internet pero muchas veces no ha funcionado porque no coincidían las versiones: ya fueran las versiones de Emacs o las de algún paquete en concreto. Y eso hay que contarlo más despacio.
Paquetes para el editor
Por ahí leí que los paquetes facilitan la vida del usuario de Emacs. En ocasiones pienso que sí, porque son el resultado de cubrir algunas necesidades que el uso y la práctica han ido estableciendo. Pero hay tantos que se han convertido en un infierno y prefiero mantener en el mínimo los instalados.
Emacs los pone en el directorio oculto .emacs.d
y no interfieren
con ningún otro paquete del sistema.
El primer problema que me encontré, y para el que necesitaba solución urgente, es que no recuerdo muy bien todos los comandos que necesito, algunos nunca los aprendí y otros los olvidé y otros los utilizo tan de vez en cuando que no me los aprendo nunca. Necesitaba no ser tan preciso con los nombres de los comandos, una especie de autocompletado como cuando programas que te muestre sugerencias de los comandos que tienes disponibles.
Encontré referencias a dos modos menores que sirven para eso Ivy y Helm. El segundo es más completo que el primero y hace muchísimas más cosas ... pero es muy pesado. Ivy es más ligero. Puedes incluso instalar los dos, pero ¿cómo?
Hasta ahora no había necesitado ni querido instalar paquetes raros o que no fuera a utilizar. Pero al final he instalado los dos que he mencionado antes –y estoy probándolos para ver cuál dejo, o a lo mejor dejo los dos– y el modo Markdown para escribir cómodamente el blog. ¿De dónde sacar los paquetes? ¿Cómo instalarlos?
Encontré por ahí unas líneas que copié1
;;; packages
(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
("marmalade" . "https://marmalade-repo.org/packages/")
("org" . "http://orgmode.org/elpa/")
("melpa" . "http://melpa.milkbox.net/packages/")))
;
Luego sólo hace falta la secuencia M-x list-packages
para que
aparezca un buffer repleto con una lista de paquetes, versiones,
descripciones y demás. Instalarlo es tan sencillo como situar el
cursor sobre uno, pulsar Enter
y leer un poquito (pero que muy
poquito de inglés).
Ponerlo bonito o a mi gusto
El Emacs por defecto no está mal del todo si pensamos que es uno de los programas más veteranos del menú linuxero. Sin embargo, –y en esto he de reconocer que casi más por moda que por otras cuestiones– le cambié la apariencia a mi Emacs para que parezca más agradable. Y en otras cuestiones para españolizar algunas cosas, como los nombres de los meses o de los días de la semana. O que las semanas en el calendario comiencen por el lunes y no por el domingo como está configurado por defecto.
Y así luce mi Emacs mientras estoy editando estas líneas
Todas esas opciones se configuran a través del menú Options
→
Customize Emacs
que proporciona formularios para cambiarlas de forma
más visual. Al guardarlas, escribe en .emacs
entradas para cada
variable. Por ejemplo, por defecto las fechas se mostraban en formato
americano de mm/dd aaaa
y yo prefiero las fechas en formato iso
aaaa-mm-dd
que me permiten una ordenación directa más sencilla.
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(calendar-date-style (quote iso))
'(calendar-day-header-array ["Do" "Lu" "Ma" "Mi" "Ju" "Vi" "Sa"])
'(calendar-day-name-array
["Domingo" "Lunes" "Martes" "Miércoles" "Jueves" "Viernes" "Sábado"])
'(calendar-month-abbrev-array
["Ene" "Feb" "Mar" "Abr" "May" "Jun" "Jul" "Ago" "Sep" "Oct" "Nov" "Dic"])
'(calendar-month-name-array
["enero" "febrero" "marzo" "abril" "mayo" "junio" "julio" "agosto" "septiembre" "octubre" "noviembre" "diciembre"])
'(calendar-week-start-day 1)
'(column-number-mode t)
'(custom-enabled-themes (quote (tsdh-dark)))
'(delete-selection-mode nil)
'(diary-file "~/owncloud/agenda/diario.org")
'(html-mode-hook nil)
'(inhibit-startup-screen t)
'(ispell-program-name "aspell")
'(make-backup-files nil)
'(org-agenda-diary-file "~/owncloud/agenda/diario.org")
'(org-agenda-files (quote ("~/owncloud/agenda/cal_pica.org" "~/owncloud/agenda/agenda.org")))
'(org-agenda-include-diary t)
'(org-archive-location "~/owncloud/agenda/archive.org::* Desde %s")
'(truncate-lines t)
'(word-wrap t))
Modo de trabajo y como organizarme
Tiendo al caos y debo reprimirme mucho para mantener un mínimo de
orden. Cuando decidí probar el modo org pensé que tenerlo todo en
ficheros de texto e introducir las notas y tareas a mano podría
ser casi autodestructivo. Luego he visto que el comando org-agenda
lo ordena todo muy bien por fechas, con timelines y
colorines... pero ¿cómo mantener todo en un mínimo orden?
Para empezar utilizo una serie de archivos para varias cosas:
agenda.org
: es un fichero que mantiene mis tareas y recordatorios personales, como por ejemplo, cuándo le toca la ITV al coche u otras tareas como el mantenimiento del blog y otras que se podrán ir añadiendo.cal_pica.org
: en este fichero anoto las tareas y eventos que realizo con la Asociación PICA. Asociación donde colaboro como asociado voluntario casi a jornada completa.diario.org
: en este fichero se guardan fechas de aniversarios, cumpleaños y esos asuntos que debes recordar, pero que no son una tarea en sí.archive.org
: este fichero es el colector de las tareas hechas. En el modo agenda al pulsara
guarda la entrada sobre la que estés en este fichero, anotando cuándo se ha archivado la tarea. Es la manera de mantener ficheros de agenda pequeños sin perder el histórico de las cosas que has ido haciendo.
Esos son los nombres de los ficheros que se pueden ver en el código y su utilidad.
Además se me han presentado dos aspectos más que he tenido que sortear como he podido. Principalmente dos cosas:
- ¿Cómo sincronizar mis agendas en los dos ordenadores?
- ¿Cómo mantener ordenadas las notas y las tareas?
Sincronización de equipos
¡Uff! Aquí he tenido que chapucear un poco. Trabajo en dos ordenadores y me gusta que si introduzco una tarea en uno no tenga que repetir el apunte en el otro. Cosas que tiene el ser un poco ajustado de esfuerzos.
La opción chapucera que he encontrado es colocar los ficheros en un directorio sincronizado con un servicio de owncloud privado. Supongo que a través de Internet se podría hacer con lo que viene a llamarse la nube (y que en algunos sitios se califica de el ordenador de otro). De todas maneras, y como sólo me interesa estar sincronizado conmigo mismo y mis ordenadores, no necesito más.
Capturar notas y tareas
Para mantener un poco el orden en las notas no hay nada como
automatizarlo todo. Encontré una forma que era utilizar el comando
org-capture
para que automáticamente sólo haya que pulsar unas pocas
teclas, escribir una cabecera y la anotación se guarde en su sitio. Y
por sitio, léase: fichero + cabecera y además ordenadas y que añada la
fecha para mostrarse. Teniendo en cuenta, que cada anotación puede ir
en un momento dado a un fichero distinto o a una cabecera concreta. Y
encontré por ahí lo que llamaban las plantillas de captura2 y una
breve explicación de cómo funcionaban y sobre todo el orden que
producían y mantenían.
Había leído la documentación y trataba de ponerlo en práctica pero no
terminaba de entender el «concepto» de Template y cómo
utilizarlo. Hice varias pruebas todas catastróficas hasta que encontré
un blog
donde lo explicaban claro y conciso. El código que hice yo, es una
adaptación de esas notas a mi modo de trabajo. Y además añadí una
combinación de teclas para el comando org-capture
para no tener que
estar tecleando el más largo M-x org-capture
, lo puse en C-c c
que
es la combinación de teclas recomendada en la propia documentación.
(setq org-capture-templates
'(("s" "Tarea Simple" entry (file+headline "~/owncloud/agenda/agenda.org" "Notas")
"** TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("i" "Idea genial :-P" entry (file+headline "~/owncloud/agenda/agenda.org" "Ideas")
"** TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("b" "Entrada para el blog personal" entry (file+headline "~/owncloud/agenda/agenda.org" "Entradas Blog personal")
"** TODO %? \n:PROPERTIES:\n:CREATED: %U\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
))
;
(setq org-capture-templates
(append org-capture-templates
'(("p" "Tareas para PICA")
("pg" "General" entry (file+headline "~/owncloud/agenda/cal_pica.org" "General")
"** TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n")
("pw" "Web" entry (file+headline "~/owncloud/agenda/cal_pica.org" "Web")
"** TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("pb" "Entrada para el blog" entry (file+headline "~/owncloud/agenda/cal_pica.org" "Blog")
"** TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("pp" "PICA psicología" entry (file+headline "~/owncloud/agenda/cal_pica.org" "Psicología")
"** TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\nSCHEDUKED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
)))
;
(global-set-key (kbd "C-c c") 'org-capture)
Lo último el código completo
El contenido completo de mi fichero de configuración de emacs (el
famoso fichero .emacs
).
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(calendar-date-style (quote iso))
'(calendar-day-header-array ["Do" "Lu" "Ma" "Mi" "Ju" "Vi" "Sa"])
'(calendar-day-name-array
["Domingo" "Lunes" "Martes" "Miércoles" "Jueves" "Viernes" "Sábado"])
'(calendar-month-abbrev-array
["Ene" "Feb" "Mar" "Abr" "May" "Jun" "Jul" "Ago" "Sep" "Oct" "Nov" "Dic"])
'(calendar-month-name-array
["enero" "febrero" "marzo" "abril" "mayo" "junio" "julio" "agosto" "septiembre" "octubre" "noviembre" "diciembre"])
'(calendar-week-start-day 1)
'(column-number-mode t)
'(custom-enabled-themes (quote (tsdh-dark)))
'(delete-selection-mode nil)
'(diary-file "~/owncloud/agenda/diario.org")
'(html-mode-hook nil)
'(inhibit-startup-screen t)
'(ispell-program-name "aspell")
'(make-backup-files nil)
'(org-agenda-diary-file "~/owncloud/agenda/diario.org")
'(org-agenda-files (quote ("~/owncloud/agenda/cal_pica.org" "~/owncloud/agenda/agenda.org")))
'(org-agenda-include-diary t)
'(org-archive-location "~/owncloud/agenda/archive.org::* Desde %s")
'(truncate-lines t)
'(word-wrap t))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
;;; packages
(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
("marmalade" . "https://marmalade-repo.org/packages/")
("org" . "http://orgmode.org/elpa/")
("melpa" . "http://melpa.milkbox.net/packages/")))
;
(setq org-capture-templates
'(("s" "Tarea Simple" entry (file+headline "~/owncloud/agenda/agenda.org" "Notas")
"** TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("i" "Idea genial :-P" entry (file+headline "~/owncloud/agenda/agenda.org" "Ideas")
"** TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("b" "Entrada para el blog personal" entry (file+headline "~/owncloud/agenda/agenda.org" "Entradas Blog personal")
"** TODO %? \n:PROPERTIES:\n:CREATED: %U\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
))
;
(setq org-capture-templates
(append org-capture-templates
'(("p" "Tareas para PICA")
("pg" "General" entry (file+headline "~/owncloud/agenda/cal_pica.org" "General")
"** TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n")
("pw" "Web" entry (file+headline "~/owncloud/agenda/cal_pica.org" "Web")
"** TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("pb" "Entrada para el blog" entry (file+headline "~/owncloud/agenda/cal_pica.org" "Blog")
"** TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
("pp" "PICA psicología" entry (file+headline "~/owncloud/agenda/cal_pica.org" "Psicología")
"** TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\nSCHEDUKED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")
)))
;
(global-set-key (kbd "C-c c") 'org-capture)
-
Pondría la referencia si me acordara, pero hace días que lo hice y entonces no pensaba en ponerlo todo detallado en el blog. Si alguien está seguro que lo copié de él y no de la documentación le pido mil disculpas. ↩
-
Tampoco recuerdo dónde leí por primera vez eso de plantillas de captura. Si alguien piensa que ese término lo puedo haber leído en su blog y no lo enlazo, le pido humildemente disculpas. ↩