Mi configuración de GNU Emacs, y otros ficheros en Lisp

Índice

(

Emacs es un sistema para trabajar con texto. Es parte de GNU y lo veo una muestra de programa que respeta a los usuarios: hay enorme libertad de uso, hay acceso a todo el código (C y Lisp), estás invitado a configurarlo, y al configurarlo lo estás expandiendo (porque la configuración es código en Lisp), y por último puedes distribuirlo o crear una variante de Emacs. Vale la pena aprender un editor (cualquiera que no te restrinja), y Emacs es bueno y duradero y [tras sufrir un tiempo domándolo] da mucha libertad.

Publicado en 2020, reexportado el 20.m03.2023; Daniel Clemente. Batallando Emacs desde 2007. Casi sin darme cuenta llevo escritas 15800 líneas, 712 Kb de Emacs Lisp.

)


1. ~/.emacs (configuración principal)

Ésta es la configuración principal que he ido acumulando durante años. Mi „punto emacs“. Se carga al arrancar.

;; -*- mode: emacs-lisp; mode:outline-minor; hs-minor-mode: nil; outline-regexp:";;;;* [^   \n]" -*-
;;
;; Mi configuración de GNU Emacs
;; 2007 a 2023 (etc.), Daniel Clemente
;; Todo esto va a acabar publicado (ej. en https://www.danielclemente.com/emacs/confi.html o por ahí)
;; Considéralo dominio público; puedes reusarlo.
;; Le he quitado las partes privadas, pero avísame si hay algo que sobra (o falta…)
;; El código es malo y no lo he preparado para ser útil a otros, sino para usarlo yo. Posiblemente mezclo idiomas, propalabras (palabras que me invento), signos de puntuación „raros“ o inventados (ẽ esto), o referencias a otros ficheros y programitas privados; también hay mucha configuración vieja que ya no uso. ¡Ayúdame a publicar otros programas que uso! Igualmente puedes aconsejarme sobre el formato.
;;
;; Lo de los comentarios con ;;; y ;;;; y ;;;;; etc. es porque empecé a organizarlo en forma de árbol, con outline-minor, pero funciona mal (no es tan potente como org) y no uso el árbol. Falta revisar estructura. Al menos aún está agrupado todo por tema
;; BONUS usar outline-cycle-minor-mode

;;; Sobre mi Emacs, y cosas por hacer

;; instalado mi .emacs en Mayo de 2007; usado continuamente desde entonces
;; arrancar en modo texto: TERMCAP=/w/emacs/etc/termcap.src TERM=linux emacs -nw
;; contar líneas de este fichero (¡vaya pérdida de tiempo!):  cat .emacs | grep -v '^\s*\;' | grep -v '^\s*$' |wc

;; Inspirarme en:
;; (mucho) http://doc.norang.ca/org-mode.html
;; (mucho; rápidamente)     http://www.enigmacurry.com/blog-post-files/Ryan-McGuire-Emacs-Environment-05-09-2008.tar.gz
;; - http://www.mygooglest.com/fni/.emacs ← intenta ser demasiado genérico
;; - [ ] http://156.35.138.29/tips/Emacs/mydotemacs.html
;; - https://github.com/itsjeyd/.emacs.d/blob/emacs24/init.el
;;
;; Ya sacada mucha información útil de:
;; http://www.emacswiki.org/emacs/EmacsCrashCode
;; http://en.wikipedia.org/wiki/User:Gwern/.emacs

;;;; MALFAR: usar org-babel para cargar mi .emacs (¡.emacs literario)!
;; Esto me va a ayudar mucho a gestionar tareas, etc. ¡Incluso a exportarlo! Ver en org-babel.org de Worg; lo explica todo. http://orgmode.org/worg/org-contrib/babel/intro.php ← muy fácil
;; ∴ Mejor por ahora no hacerlo, pues me gusta ya el .emacs tal como está (y está bastante organizado). No necesito más burocracia (dos ficheros con contenido, un paso extra, procesos nuevos de sincronización, …)

;; Algunos usan org-babel-load-file, no sé si aún existe. Parece que sí.

;; me hará falta en .emacs sólo:
(ignore '( ; aún no… Esto es para cuando active babel y pase todo emacs.el a emacs.org
          (progn; esto carga mi org. Ejecutarlo cuando pruebo cosas de emacs
            (add-to-list 'load-path "/w/org-mode/lisp")
            (add-to-list 'load-path "/w/org-mode/contrib/lisp")
            (require 'org-install)
            (require 'ob-tangle)
            )
          (org-babel-load-file "~/wiki/emacs.org")
          ))

;;; Inicial (cosas importantes para cargar al principio). Y sobre el arranque
;; estuvo mucho tiempo a t pero quizás puedo desactivarlo ahora que todo va más o menos bien. No sé si es bueno eso o me perderá errores grandes…
;; (setq debug-on-error t)
(setq debug-on-error nil)
;;(setq debug-on-signal t)
(setq stack-trace-on-error nil) ; no sé qué es; no está definida, pero ECB va a buscarla y no la encuentra; con ella, se abre bien

;; Instrumentación
(require 'elp)
;; Paquetes a vigilar. Ej: font-lock, vc, org, …
;;(elp-instrument-package "vc")
;;(elp-instrument-package "org")
;; Luego, para ver tabla de resultados, usar: (elp-results)
;; Y para reiniciar: (elp-reset-all)

;; Para perfilar todo el .emacs, usar ~/.emacs.d/profile/arranca
;; ejecutar de vez en cuando. La 1ª vez (12.m10.2011, ali) bajé 15 segundos (de 36 a 21)


;; para que arranque en 1s: http://www.emacswiki.org/cgi-bin/wiki.pl?DumpingEmacs y http://emacs.kldp.net/~jay/emacs/ . Pero pruebo : dc; ~ ; emacs --batch --eval '(dump-emacs "/tmp/elema" "/opt/dc/bin/emacs")' y dice „segmentation fault“

;;;; Autocompilado

;;;;; Prueba con byte-code-cache.el, que me ha dado muchos dolores de cabeza y que ralentiza todo realmente
;; Todo esto es para hacer autocompilación 
;; Esto es absurdo del todo. Va muchísimo más rápido si no compilo que si lo hago... :-( ¡Emacs!  6.11.2008
;; En 2023 lo borro, ver cdv para notas y configuración que tuve en .emacs


;;;;; Prueba con elisp-cache.el
;; El 25.11.2008 lo probé un poco, y vi que compila la primera vez que se arranca: todo y bastante bien (aunque con bastantes errores en sitios problemáticos, ej: „inversion“ en „semantic-util“). Pero las siguientes veces no arranca más rápido; de hecho sigue cogiendo todo del sitio .el en vez del .elc. Tengo que configurarlo mejor... Aunque no sé si es para mi caso.
;; De momento lo desactivo porque usando los .el ya me va muy rápido
;; En 2023 lo borro, ver cdv para notas y configuración que tuve en .emacs



;;;; Compatibilidad con otros Emacs

;;;;; Para Emacs21
;; Borrado pues desfado. Ver cdv (prepara_en_emacs21)

;;;;; Para Emacs22
;; Borrado pues anticuado. Ver cdv.

;;;;; Para Emacs23.1…
;; borrado pues estaba anticuado. Ver cdv.

;;;;; Para Emacs23.2 y superior…
;; lo de prepara_en_emacs23.algo: borrado pues anticuado. Ver cdv.
;; carga_cedet_de_w: Borrado pues no lo necesito más, y probablemente hasn cambiado las cosas. Ver cdv

;;;;; Para Emacs27, 28, 29: nada especial

;;;; Cosas comunes que se iban a incluir igual
(require 'cl) ; Common Lisp extensions for Emacs
;;;; Carga de paquetes de ELPA/MELPA
(require 'package)
;; Dice mi emacs que esto es innecesario:
;; Pero m10.2022 veo que sí, si estoy evaluando a mano el fichero. En cambio no me hace falta desde demacs. Por tanto lo dejaré descomentado
(package-initialize) ;; „Load Emacs Lisp packages, and activate them.“
;;
;; Por cierto, para instalar todo lo que uso, (package-install-selected-packages)

;;;; Velocidad de carga de emacs y demacs
;; Usar:
;;   time emacs --eval '(kill-emacs)'
;;
;; En „lovic“ tardaba unos 19 ó 20 segundos
;; yasnippet aportaba 6s → desactivado
;; icicles aporta 2s
;; nxhtml unos 2s
;;
;; En „ali“ tardaba 28, 14, 15, 17, 17 segundos (eso porque le quité ECB y JDE y CEDET …)
;; icicles aportaba 2s (justo aquí lo desactivé y lo cambié por Anything)
;; anything ¡ni se notaba! Aporte=0s. Es maravilloso. ¡Y eso que estaba sin compilar! Compilándolo tampoco se notaba (claro) e iba aún más rápido.
;;
;; En „2d2“ me tardó 70 segundos… ¡Necesita mejorar! Pero no me vale la pena invertir mucho tiempo ni aunque me ahorre 1 minuto (para eso máximo 4h)
;;

;;;; Uso de memoria
(setq garbage-collection-messages t) ; me gusta enterarme de estas cosas

;;; Teclas
;; NOTA, 31.10.2007: no hay que citar el lambda [ '(lambda () ...) ]. Ver http://www.emacswiki.org/cgi-bin/emacs-en/QuotedLambda
;;;; teclas para que „emacs -nw“ (xterm/urxvt/terminal) funcione bien y de forma parecida/idéntica a las X

;; no me van bien estas teclas:
;; C-TAB (detecta TAB)
;; C-/ (detecta DEL)
;; M-< (no detecta nada)
;; M-: (no detecta nada)
;; S-F12 (no detecta nada)
;; MALFAR: investigar y corregir… aunque faltan tantas cosas en -nw que no me apetece hasta que vea una necesidad importante

;;;; teclas globales

;;;;; teclas para cambiar de búfer

;;;;;; ibuffer (antes: switch-to-buffer, ido-switch-buffer)
;; F7 en vez de C-x b
;; (global-set-key [f7] 'switch-to-buffer)
;;(global-set-key [f7] 'ido-switch-buffer)
;; Para cambiar de búfer:
;; switch-to-buffer es el inicial y es incómodo. Con icicles es mejor.
;; iswitchb-mode es raro y poco práctico
;; ido-switch-buffer se ve limitado y subóptimo
;; buffer-menu es ya bastante avanzado pero no da mucha información
;; ibuffer parece mejor; es una mejora de buffer-menu
;;(global-set-key [f7] 'ibuffer) ; ← nunca toco f7 para esto

;; venga, también para C-x b  (es lo que acabo usando...)
;;(global-set-key (kbd "C-x b") 'ibuffer)

;; lo que realmente necesito es poder usar los dos: lista de búfers, y selector que me permita teclear
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-x b") 'switch-to-buffer)
;; Y el list-buffers (antiguo C-x C-b) no me sirve de nada teniendo ibuffer


;;;;;; layout-restore, para guardar y cargar distribución de ventanas
;; permite acordarse de la configuración de ventanas
;; No tengo distribuciones favoritas, ni quiero dar nombre o grabar manualmente ninguna de ellas. Quiero un enfoque más automático en el que Emacs elija por mí la configuración más adecuada, y sin equivocarse. Por tanto no uso mucho layout-restore.

;;(add-to-list 'load-path "~/.emacs.d/ventanas/")
;;(require 'layout-restore)
;;(global-set-key [?\C-c ?v ?g] 'layout-save-current)   ; Configuración de Ventanas Guarda
;;(global-set-key [?\C-c ?v ?p] 'layout-restore)        ; Configuración de Ventanas Pon
;;(global-set-key [?\C-c ?v ?b] 'layout-delete-current) ; Configuración de Ventanas Borra

;; ¿Cómo soluciono, por ejemplo, esto? Estoy programando en un proyecto grande y tengo ECB abierto con sus ventanas. Entonces compilo y quiero depurar; para eso abro „M-x gdb“ (que ya abre sus ventanitas en otra disposición). No combinan bien (gdb no abre bien sus ventanitas si ECB estaba activo), y de hecho es mejor que no se abran 4+4+1 ventanas...
;; Quizás elscreen ayuda con esto, quizás otros programas
;; Necesidad real de 18.11.2008 (¡ya empiezo a prograsar usando Emacs efectivamente!)


;;;;;; Estas teclas son anticuadas; no las uso nada. Las comento
(ignore '(
          ;; F7 es incómoda de alcanzar; Alt+F12 es mejor:
          (global-set-key [\M-f12] 'kill-this-buffer)
          ;; teclas para tabbar: cambiar de pestaña
          (global-set-key [\C-prior] 'tabbar-backward)
          (global-set-key [\C-next] 'tabbar-forward)
          (global-set-key [\C-\S-prior] 'tabbar-backward-group)
          (global-set-key [\C-\S-next] 'tabbar-forward-group)

          ;; cambiar entre 2 búfers rápidamente
          (global-set-key [\S-f7] 'joc-toggle-buffer)
          ;; cerrar búfer
          (global-set-key [\M-f7] 'kill-this-buffer)

          )) ;ignore

;;;;;; otras formas de circular por búfers, que no uso
;; Esto no lo uso mucho...
;; ver m y http://www-cdf.fnal.gov/~sthrlnd/emacs/wcy-swbuff.el es mejor
;; switch buffers
;;(global-set-key [f11] 'cyclebuffer-forward)
;;(global-set-key [\S-f11] 'cyclebuffer-backward)



;;;;;; panel de la mano derecha para cambiar de búfers (uso continuo)

;; Esto es de cuando usaba tabbar:
;; intento usar el panel mano derecha (PMD), igual que para stumpwm.
;; ahora está, usando M- como prefijo:
;; K: M-t transpose-words
;; L: M-n -
;; I: M-c capitalize-word
;; O: M-r move-to-window-line (pone cursor en centro del búfer)
;; Creo que nunca uso lo de transponer o mayusculizar palabras. Me va bien desactivarlo.
;; Además:
;; V: M-k kill-sentence (como kill-line pero borra líneas posteriores del mismo párrafo...)

;; Al abandonar tabbar recuperé todas estas teclas tan valiosas

;; Por tanto:

;; los 4 primeros están desactivados pues ya no uso tabbar. 28.m9.2009
;;¬tabbar←;(global-set-key "\M-t" 'tabbar-backward)
;;¬tabbar←;(global-set-key "\M-n" 'tabbar-forward)
;;¬tabbar←;(global-set-key "\M-c" 'tabbar-backward-group)
;;¬tabbar←;(global-set-key "\M-r" 'tabbar-forward-group)
(global-set-key "\M-k" 'kill-this-buffer--pero-de-verdad) ; durante unos años usé kill-this-buffer
(global-set-key "\M-K" 'bury-buffer) ; variante no violenta de M-k: no mata, sólo rechaza temporalmente. Con esto puedo circular por todos los búfers. Por cierto, si no tengo Kinesis, ESC S-k (Ctrl,Alt+v) va bien. O en un acorde: Alt+5+v

(defun kill-this-buffer--pero-de-verdad ()
  "Kill the current buffer.
Pero de verdad. No me da miedo el fallo 8184 (http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8184) por el que mira algo de la barra de menús, pues no la uso. Así que cojo kill-this-buffer y le quito esa comprobación rara."
  (interactive)
  (kill-buffer (current-buffer)))


;; El PMD (panel de la mano derecha) es ahora:
;; M-t y M-n: cambiar pestaña
;; M-c y M-r: cambiar grupo de pestañas
;; Otras convenciones:
;; M-k: cerrar búfer
;; E incluso, si es posible:
;; M-p y M-u: avanzar/retroceder por el historial de comandos



;; hay muchas teclas que no funcionan en algunos modos porque éstos las han redefinido.
;; No sé cómo cambiar esto; creo que no hay forma mágica de definir una tecla con preferencia.
;; Chapuza: redefiniciones para cada modo afectado:


;;;;;; otras básicas de movimiento
;; palante y patrás. Esto es cómodo porque mi .Xmodmap puso Scroll_Lock donde otros tienen Caps_Locks. Mi mayúsculas está ahora en donde estaba Scroll_Lock
(global-set-key (kbd "<Scroll_Lock>")
                ;;'icicle-other-window-or-frame
                'other-window
                )
(global-set-key (kbd "<S-Scroll_Lock>") (lambda () (interactive)
                                          ;;(icicle-other-window-or-frame -1)
                                          (other-window -1)
                                          ))


;; estoy usando  como carácter de control especial que introduce códigos para Emacs mandados desde urxvt. Ver .Xresources
(global-set-key (kbd "1")
                'other-window
                )
(global-set-key (kbd "2") (lambda () (interactive)
                              (other-window -1)
                              ))


;;;;; teclas especiales, como Mod3, que han de ser ignoradas
;; ion3 usa esta tecla como modificador pero sin embargo aún pasa la pulsación a los programas. La ignoro

;; Así es como está ahora, y da mensajes de „is undefined“ todo el rato
;;(global-set-key (kbd "<XF86ModeLock>") nil)
;;(global-unset-key (kbd "<XF86ModeLock>"))

;; La trato para no hacer nada
(global-set-key (kbd "<XF86ModeLock>") 'ignore)
;; No me gusta pues Emacs aún interpreta demasiado esta tecla, y C-c XF86ModeLock por ejemplo da avisos cuando debería equivaler a C-c sin más. También me cancela cosas que no quiero, etc.
;; No sé ignorarla de verdad. No me molesta

;; También está XF86Display, que creo que puedo ignorar mediante xbindkeys. Ya no me pasa desde hace tiempo

;; Y: XF86MonBrightnessUp, que en trasc pasa de vez cuando, cuando la batería se conecta/desconecta. Pruebo 'ignore pues no es suficiente pues esto me cancela las búsquedas (me cierra minibúfer) → he de probar xbindkeys
(global-set-key (kbd "<XF86MonBrightnessUp>") 'ignore)
(global-set-key (kbd "<C-XF86MonBrightnessUp>") 'ignore)
(global-set-key (kbd "<M-XF86MonBrightnessUp>") 'ignore)

;;(defun ignore-key ()  "interactive version of ignore"  (interactive)  (ignore))  (global-set-key (kbd "<XF86ModeLock>") 'ignore-key) ; ← esto no aporta nada sobre el ignore normal, creo

;; Modnúm+espacio con el Ctrl apretado (que escribe el 0) ha de poner el espacio normal, sin darse cuenta de que el Ctrl (el 0) estaba apretado
(global-set-key (kbd "<C-kp-space>") (lambda () (interactive) (insert-char ?  1)))


;;;;; teclas que quiero desfasar y que trato aquí con un mensaje
;; un mensajito para tecla difícil de apretar; es un acostumbrador
(if (equal (global-key-binding "\C-_") 'undo)
    ;;(global-set-key "\C-_" (lambda () (interactive) (beep) (message "Usa C-/ envez.")))
    ;; tengo entonces el problema siguiente: en modo texto (-nw), la tecla para / envía / (bien) pero con Ctrl envía C-_ misteriosamente. Por eso voy a hacer la función funcional aunque un poco molestosa
    (global-set-key "\C-_" (lambda () (interactive) (call-interactively 'undo) (message "Hago undo por esta vez, pero mejor usa C-/ en vez de C-_")))
  )

;;;;; teclas de control esenciales y muy usadas, como C-x 

;; Sigo idea de Xah Lee y otros: C-t en dvorak es mucho más fácil que C-x     ← ∴ pero no. No uso mucho C-x, y en cambio uso bastante C-t. Así que ya me va bien dejar C-x como estaba

;; Esto no va porque traducirá también un „C-c C-t“ a „C-c C-x“
;;(keyboard-translate ?\C-t ?\C-x)

;; Esto va... a medias, pues C-t siguen interceptándolo algunos modos (ej: wl)
;;(global-set-key "\C-t" 'Control-X-prefix)
;;(global-unset-key "\C-x") ; Desactivo el antiguo C-x

;; y para cambiar M-x; aunque el actual no es tan malo… Y no tengo muchas propuestas mejores (¿C-= quizás en ¬Kinesis?)
;; no va: (keyboard-translate ?\C-= ?\M-x) (global-set-key (kbd "C-=") 'Meta-X-prefix)
;; MALFAR buscar atajo mejor que el actual (que no es tan malo). C-= en Kinesis sería peor.

;; La puse un tiempo en el ENTER de qwerty, pero una tecla tan grande pierde mucho al tener una función tan poco usada como M-x. Luego la cambié para hacer de anything; ver abajo
;; (global-set-key (kbd "<f35>") #'icicle-execute-extended-command)

;; muevo ayuda de C-h a C-M-h...
(global-set-key "\C-\M-h" 'help-command) ; antes era mark-defun
;; ...porque quiero C-h para retroceso



;; mi uzu ĉi tiun pli ol C-x 2, sed mi ŝatus eble alian klavaĵon pli facilan
(global-set-key (kbd "C-x 9") 'clone-indirect-buffer)


;;;;; teclas de acceso rápido a funciones

;; acceso rápido siempre a la misma terminal

;; v1:
;; (global-set-key [f8] 'eshell)

;; he intentado preferir eshell pero aún me cuesta (ẽ porque no me carga las funciones que definí en bash/zsh). Pero más gente usa „shell“ que „eshell“, creo, así que intentaré probar más „shell“
;;(global-set-key [(control f8)] 'eshell)
;;(global-set-key [f8] 'shell)
;; Un coloreador („highlight“) se liaba aquí, así que reescribo. He mandado aviso a https://gitlab.com/saalen/highlight/-/issues/150
(global-set-key (kbd "C-<f8>") 'eshell)
(global-set-key (kbd "<f8>") 'shell)

;; Da la siguiente ocurrencia de la última búsqueda 
;;De #emacs en 6.5.2008. "search again"
;; Aaaaaah… esto evita el:   C-s C-s … Enter
(global-set-key (kbd "<f6>")
                (lambda () (interactive) (search-forward isearch-string)))


;; f12: para tomar notas, ir a mensajes, … → cambiar a búfer típico
(global-set-key [f12] 'cambia-a-búfer-para-notas)
(global-set-key [(control f12)] 'cambia-a-búfer-de-mensajes)
(global-set-key [\S-f12] 'cambia-al-búfer-anterior)
;; es curioso, pero C-f12 en consola (-nw) se recibe como C-S-f2. Bueno, pues la defino también
(global-set-key [(control shift f2)] 'cambia-a-búfer-de-mensajes)

(global-set-key [(control f11)] #'(lambda () (interactive) (find-file "~/org/idp.org"))) ; „intraday planner“

(defun cambia-a-búfer-para-notas ()
  "Va al búfer *scratch*"
  (interactive) ; no sé qué hace
  (switch-to-buffer "*scratch*")
  )

(defun cambia-a-búfer-de-mensajes ()
  "Va al búfer *Messages*"
  (interactive)
  (switch-to-buffer "*Messages*")
  (end-of-buffer) ; pues siempre me interesa lo último
  )

(defun cambia-al-búfer-anterior ()
  "Vuelve al último búfer en el que se estaba trabajando antes de cambiar de búfer"
  (interactive) 
  (switch-to-buffer (other-buffer)))


(defun graba-todos-búfers-sin-preguntar ()
  (interactive)
  (save-some-buffers 'sin-preguntar)
  ;; (message "%i grabé: %s" núm-grabados …)
  )
(global-set-key [f13] 'graba-todos-búfers-sin-preguntar)
;; Me toca usar dedo anular izquierdo; espero que esto no me duela mucho ← no
;; En ¬kinesis, usaré la tecla „mayúsculas izquierda“, que estaba libre


;; 28.m1.2012: por lo visto a partir de ahora tengo que definir el prefijo C-x C-j. Si no… → el global-set-key me da (error "Key sequence C-x C-j C-s starts with non-prefix key C-x C-j")
(define-prefix-command 'acceso-funciones-varias-map)

;; Hay una opción elegante y gradual:
;; (define-key ctl-x-map (kbd "C-j") acceso-funciones-varias-map)
;; Pero ésta (más bestia) funciona igual:
(global-set-key (kbd "C-x C-j") 'acceso-funciones-varias-map)


;; así ya me va en todos lados

;; Entonces toca traducir:
;; malo:       (global-set-key (kbd "C-x C-j C-s") 'emms-playlist-mode-go)
;; bueno:      (define-key acceso-funciones-varias-map "C-s" 'emms-playlist-mode-go)

;; comprobar si me he cargado algo; parece que no



;;;;; teclas para edición
;; Quiero „ “ con AltGr+9 bzw. +0 tal como en X
;; por ahora están con Alt. Me iría mejor con AltGr

;;(global-set-key [0] "„")
;;(global-set-key [\C-9] "“")
(global-set-key "\M-9" "„")
(global-set-key "\M-0" "“")
;; ¿hyper? ¿super?

(global-set-key "\C-h" 'backward-delete-char-untabify) ; antes era help-command


;; Original idea from
;; http://www.opensubscriber.com/message/emacs-devel@gnu.org/10971693.html
(defun comment-dwim-line (&optional arg)
  "Replacement for the comment-dwim command.
If no region is selected and current line is not blank and we are not at the end of the line,
then comment current line.
Replaces default behaviour of comment-dwim, when it inserts comment at the end of the line."
  (interactive "*P")
  (comment-normalize-vars)
  (if (and (not (region-active-p)) (not (looking-at "[ \t]*$")))
      (comment-or-uncomment-region (line-beginning-position) (line-end-position))
    (comment-dwim arg)))

;;(global-set-key "\M-#" 'comment-or-uncomment-region) ; ← lo malo es que siempre necesita seleccionar una región aunque sea de 1 línea
(global-set-key "\M-#" 'comment-dwim-line)


;; sobre comment-style:
;; No me gustan mucho: indent-or-triple plain aligned
;; Bonitos pero duros de catar: box (demasiados extras, que luego ni sabe quitar)
;; Bonitos pero algo duros: box-multi (pero efectivo)
;; Bueno: multi-line extra-line (hace lo que me esperaba, sufiĉa, aunque no me gusta el prefijo en cada línea → ver comment-continue)
;; Quizás encuentro mejores. ¿Por qué no hay ninguno que use varias líneas pero sin prefijo? → ∴ poner comment-continue
(setq comment-style 'multi-line)
;;(setq comment-style 'extra-line)
(setq comment-empty-lines t) ; era nil. Pero si pido comentar bloque que tiene blancos, quiero comentarios en *cada* línea, incluidos los blancos
(setq comment-continue "* ")
(setq comment-continue " *") ; el que ponía por defecto. Es "/*" cambiando "/" por " "
(setq comment-continue nil) ; por defecto, equivale a " *"
;;(setq comment-continue "  ") ; me gusta más, creo, pero probaré el recomendado durante un tiempo pues quizás ya me va bien

;; curioso, pero en un ordenador („pecelero“), backspace y delete estaban cambiados. Los corrijo:
(global-set-key [C-backspace] 'backward-kill-word)
(global-set-key [delete] 'delete-char)
(global-set-key [C-delete] 'kill-word)




;; C-w para borrar palabra, igual que en consola (en emacs era C-Retro)
;; Es preferible „C-w y volver a escribir la palabra“  a „mover la mano hasta "Retroceso"“
(global-set-key "\C-w" 'backward-kill-word)
;; pero para no perderme C-w=kill-region (borrar desde la marca hasta aquí), lo cambio
(global-set-key "\C-c\C-k" 'kill-region)
;; También sugerían C-x C-k, pero está ocupado
;;(global-set-key "\C-x\C-k" 'kill-region)
;; Como el C-c C-k lo necesito en algunos modos, me sobreescribe la función kill-region. A ver si queda mejor en el antiguo lugar del backward-kill-word
(global-set-key [C-backspace] 'kill-region)
;; ¿Cómo identificar el C-retroceso?
;; "To bind the key C-DEL, use [?\\C-\\d], not [C-DEL]"
;; Pero no va. Así que pruebo:
;;(keyboard-translate (kbd "4") [C-backspace])
;; Pero es es para 1tecla → 1tecla, parece, y yo he puesto dos
;; Así que:
(global-set-key (kbd "4") 'kill-region)

(global-set-key "\C-c\C-k" (lambda ()
                             (interactive)
                             (beep)
                             (message "ahora he de usar C-retroceso")
                             )
                )
;; ya me he ido acostumbrando

;; C-S-y para pegar desde X, C-y para pegar de forma normal
;; Parece que C-y tras C-S-y pone el valor del C-S-y recordándolo. Qué lío
(global-set-key (kbd "C-S-y") 'x-clipboard-yank)
;; El 29.m7.2010 cambio esta implementación porque ha dejado de funcionar, no sé por qué (si por Emacs o por X). La tecla me ponía la selección propia de Emacs. No era lo mismo el botón central que C-S-y. Con la nueva implementación ya se arregla.
(global-set-key (kbd "C-S-y") 
                (lambda () 
                  (interactive)
                  (let ((primary 
                         ;; (x-get-selection 'PRIMARY)
                         (x-get-selection 'PRIMARY 'UTF8_STRING)
                         ))
                    (if primary
                        (insert primary)
                      (error "No primary selection"))))
                )

;; por cierto, al cortar desde Emacs, eso tiene que poner el texto disponible para poderlo pegar desde otros programas X. Esto no me hizo falta hasta m8.2010, imagino que porque cambió algo de Emacs. Sin esto a t, es muy molesto.
(setq select-enable-primary t)
;;(setq select-enable-primary nil)
;; 6.m9.2010: me encuentro con que desde urxvt no puedo copiar al portapapeles de X, ni con esto a t ni a nil. Quizás tiene sentido, pero ¡yo quiero!
;; Pero es que esto tampoco va: (set-clipboard-contents-from-string "peo")

;; Esta variable también está bien: (setq select-enable-clipboard t)
;; ¿quizás tengo que usar xclipboard?


;; Cuánto cabe
;; (setq kill-ring-max 6000)
;; Me arrepiento de guardar tanto (6000) pues si le doy texto de 100 Mb y le doy a M-w 50 veces, eso va a requerir 5 Gbs (y luego no los suelta). Ver en emacs.org todo lo que sufrí depurando lo de sweep_conses y la fuga de memoria
;; Por tanto le daré menos. Si copio ẽ cachos de 100 Mb, (* 100 500). Si copio 10 Mb, (* 10 500).  (* 10 200)
(setq kill-ring-max 200)
;; Y además no grabo duplicados, para evitar esa tendencia mía de querer causar fuga de memoria presionando M-w muchas veces seguidas con un texto de muchos Mb
(setq kill-do-not-save-duplicates t)


;; Por cierto, así se vacía (pero emacs no devolverá la memoria al SO. Se la quiere quedar para algún día gestionar todo el SO él mismo)
;;(setq kill-ring nil)
;;(setq kill-ring-yank-pointer nil)
;;(garbage-collect)


;; 15.m6.2009: además le pongo mi tecla nueva XF86Paste, que he colocado en el Retroceso de QWERTY
;; he modificado también GTK y urxvt
;; Coge CLIPBOARD (no me va bien pues la que uso casi siempre es PRIMARY)
(global-set-key (kbd "<XF86Paste>") 'x-clipboard-yank)
;; Coge PRIMARY:
;;(global-set-key (kbd "<XF86Paste>") 'yank)
;; MALFAR: reactivar cuando arregle urxvt. ¡Bah, tampoco me hace tanta falta!


;; Aprovecho para definir funciones que funcionan para copiar/pegar desde terminal hacia X
;; cuidado, esto no va en nw (modo texto)
;; Tengo un lío de búfers aquí: clipboard, primary, secondary, y a esto se junta algún programa que he usado para probar a gestionar el lío (gpaste), que falla de vez en cuando
;; Callback for when user cuts
(defun xsel-cut-function (text &optional push)
  ;; Insert text to temp-buffer, and "send" content to xsel stdin
  (with-temp-buffer
    (insert text)
    ;; I prefer using the "clipboard" selection (the one the
    ;; typically is used by c-c/c-v) before the primary selection
    ;; (that uses mouse-select/middle-button-click)
    (call-process-region (point-min) (point-max) "xsel" nil 0 nil
                         ;; "--clipboard"
                         "--primary"
                         "--input")))
;; Call back for when user pastes
(defun xsel-paste-function()
  ;; Find out what is current selection by xsel. If it is different
  ;; from the top of the kill-ring (car kill-ring), then return
  ;; it. Else, nil is returned, so whatever is in the top of the
  ;; kill-ring will be used.
  (let ((xsel-output (shell-command-to-string
                      ;; "xsel --clipboard --output"
                      "xsel --primary --output"
                      )))
    (unless (string= (car kill-ring) xsel-output)
      xsel-output )))

;; Y las activo cuando creo cada ventana

(ignore '(
          ;; Desactivado porque todo esto de las variables locales a marco (y parámetros de marco) es un lío y me da muchos problemas. Mejor añado un nivel de abstracción: una función mía que dispensa a xsel-cut-function o x-select-text, y llamo siempre a la mía. 8.m9.2010

          (defun configura-el-portapapeles-con-xsel-si-hace-falta  (&optional frame)
            "Elige métodos de X o de xsel para el portapapaeles, en función de si este marco se abre en X o en terminal.
Hago asignaciones de variables internas a marcos para que se puedan combinar marcos („ventanas“ de X) unos en modo X y otros en modo texto; cada uno mantendrá su configuración individual.
"


            ;;(frame-parameters)
            ;;(modify-frame-parameters (selected-frame) '((prueba . 142857) ))
            ;; (frame-parameter (selected-frame) 'prueba)

            ;;(modify-frame-parameters (selected-frame) '((interprogram-cut-function . pita-de-verdad) ))
            ;; (frame-parameter (selected-frame) 'interprogram-cut-function)
            ;; Tengo ya el buen parámetro de marco interprogram-cut-function, pero eso no es lo mismo que la *variable* interprogram-cut-function; ésa no la he modificado.


            ;; (Creo/Espero): no hace falta
            (make-variable-frame-local 'interprogram-cut-function)
            (make-variable-frame-local 'interprogram-paste-function)

            (if
                ;;window-system. ← window-system no es fiable: en -nw, window-system es cierto mientras se está creando el marco (no sé porqué). Luego, cuando lo miro a mano, ya vale nil
                (window-system frame) ; esto sí que va
                (progn
                  ;; Éstos son los valores que encontré; van bien en X
                  ;;  (setq interprogram-cut-function 'gui-select-text)
                  ;;  (setq interprogram-paste-function 'gui-selection-value)
                  (modify-frame-parameters frame '((interprogram-cut-function . gui-select-text) (interprogram-paste-function . gui-selection-value)))
                  ;;(shell-command "pita do re")
                  )
              (progn
                ;; Éstas son las funciones que yo me he definido
                ;;  (setq interprogram-cut-function 'xsel-cut-function)
                ;;  (setq interprogram-paste-function 'xsel-paste-function)
                (modify-frame-parameters frame '((interprogram-cut-function . xsel-cut-function) (interprogram-paste-function . xsel-paste-function)))
                ;;(shell-command "pita sol fa")
                )
              )
            ;;(shell-command "pita la")

            )
          ;;(add-hook 'after-make-frame-functions
          ;;  (lambda () (shell-command "pita")))
          ;;(setq after-make-frame-functions '(w3m-add-w3m-initial-frames x-dnd-init-frame configura-el-portapapeles-con-xsel-si-hace-falta))
          ;; Le quito las llamadas a (w3m-add-w3m-initial-frames x-dnd-init-frame), pues no las uso
          (setq after-make-frame-functions '(configura-el-portapapeles-con-xsel-si-hace-falta))
          ;;(setq after-make-frame-functions '(w3m-add-w3m-initial-frames x-dnd-init-frame ))

          )) ; fin ignore

;; Una solución mejor para copiar/pegar siempre funcionante: función mía dispensadora
;; No penaliza la velocidad; no se nota.

(defun mi-función-para-cortar (text &optional push)
  ;;    (if (window-system (selected-frame)) 
  ;;    (shell-command "pita la")
  ;;    (shell-command "pita la la"))
  (if (window-system (selected-frame))
      (gui-select-text text)
    (xsel-cut-function text) ; ¿no puse nil yo aquí?
    )
  )
(defun mi-función-para-pegar ()
  ;;    (if (window-system (selected-frame)) 
  ;;    (shell-command "pita do")
  ;;    (shell-command "pita do do"))
  ;; En modo gráfico, llamar a x-selection-value, ¿por qué? No es lo que más me interesa…
  (if (window-system (selected-frame))

      (gui-selection-value)
    ;; MALFAR: me está petando esta llamada por error de .elc cuando arranqué Emacs 23 tras haber estado tiempo usando el Emacs 24-bzr
    ;; find-library-name: Can't find library /usr/share/emacs/23.3/lisp/term/x-win.el
    ;; Y da una traza rara:
    ;; Debugger entered--Lisp error: (wrong-number-of-arguments #[(type) "…-select-request-type text request-type (UTF8_STRING COMPOUND_TEXT STRING) nil (byte-code "\303  @\"\303\207" [type request-type text x-get-selection] 3) ((error)) (byte-code "\303   \"\303\207" [type request-type text x-get-selection] 3) ((error)) remove-text-properties 0 (foreign-selection nil)] 6] 0)
    ;;   x-selection-value()
    ;; (Es por x-win.el)
    ;; ∴ Sol: /w/emacs/lisp/term/x-win.el ← evaluar. Usar esto:
    ;; (load-file "/usr/share/emacs/23.4/lisp/term/x-win.elc")
    ;; Lo pongo en cargador de arriba.


    ;; cuidado, no entiendo esta línea, pues xsel no me va en modo texto
    (xsel-paste-function) ; ¿no puse nil yo aquí?
    )
  )

;; Esto lo usé durante años, creo que me hacía falta para usarlo en -nw y en X:
;; BONUS probar a quitarlo del todo, pues me molesta en nw, y quizás no lo noto si lo quito en X
(setq interprogram-cut-function #'mi-función-para-cortar)
(setq interprogram-paste-function #'mi-función-para-pegar)
;; 12.m11.2013: si las pongo a nil, puedo copiar/pegar dentro de emacs, pero no copio hacia ni pego desde programas externos. Así que no me interesa a nil
;; sin embargo es lo apropiado para el modo texto (nw)
;;(setq interprogram-cut-function nil)
;;(setq interprogram-paste-function nil)


;; Y ya que estoy con copiar/pegar: vi el 31.m10.2010 que org no pegaba fragmentos de más de 4000 bytes.
;; No es por magic-mode-regexp-match-limit = 4000, no tiene que ver
;; Es por xsel.
;; ∴ ver emacs.org, sección xsel



;; Luego, con M-y puedo circular por anillo de textos cortados. Pongo esto para poder circular hacia atrás. Me va muy bien esto por si me paso con M-y y quiero retroceder (bueno, C-/ en esos casos también vale). Esto es de: http://www.emacswiki.org/emacs/?action=browse;oldid=DefaultKillingAndYanking;id=KillingAndYanking
(defun yank-pop-forwards (arg)
  (interactive "p")
  (yank-pop (- arg)))

(global-set-key "\M-Y" 'yank-pop-forwards) ; M-Y (Meta-Shift-Y)


;; me gustaría además teclas para hacer kill-ring-save (M-w) del trozo en el que estoy, ẽ del bloque de org-mode
(defun save-org-block-to-kill-ring--o-sea-copiar-bloque-org-al-portapapeles () (interactive)
       "Copia el contenido del bloque org.
Útil ẽ cuando tengo un #+BEGIN_QUOTE … #+END_QUOTE con código python que quiero copiar+pegar hacia ipython.
 Con esto no tengo que ponerme al principio y luego al final.
 Nótese que los #+BEGIN_QUOTE etc. están incluidos, pero cuentan como comentarios Python :-) así que los puedo pegar junto"
       (let ((bloque (org-between-regexps-p "^[ \t]*#\\+begin_.*"
                                            "^[ \t]*#\\+end_.*")))
         (kill-ring-save
          (car bloque)
          (cdr bloque)
          )
         )
       )




;;;;; teclas desdefinidas
(global-set-key (kbd "C-z") nil) ; era: suspend-frame, que lo único que hace es bloquearme el cursor en wmii; nada útil
;; En algún momento le encontraré un uso. Aunque no es cómoda
;; ¿quizás ibuffer? ¿o helm-wiki?
;; ¿bury-buffer?
;; Puedo poner una función como: C-u C-z me marca este búfer como „el actual“, y C-z me cambia al „búfer actual“

;;;; Teclas para modos
;; el add-hook no es destructivo (antes hacía setq directamente)
;;;;; w3m
;; (setq w3m-mode-hook nil)
(add-hook 'w3m-mode-hook
          (lambda ()
            ;;  (local-unset-key "\M-n")    ;; desactivo, creo que no me hace falta
            ;; (local-unset-key "\M-k")   ;; desactivo, también petaba. Añadir (kdb…) si me hace falta
            (local-unset-key "t") ; me pierdo „desactivar imagen actual“; para eso ya tengo T (global)
            ;; Esto lo añado porque si no, M-n y M-t ejecutan tabbar-forward y tabbar-backward, y no sé por qué, pero se hacen un lío increíble con el orden que usa w3m para las pestañas
            (define-key w3m-mode-map "n" 'w3m-next-buffer)
            (define-key w3m-mode-map "t" 'w3m-previous-buffer)
            ;; Abrir nueva pestaña vacía
            (define-key w3m-mode-map "/" 'w3m-new-buffer)
            (define-key w3m-mode-map "W" 'w3m-search-wiktionary) ; la definí yo
            (define-key w3m-mode-map "w" 'w3m-search-wikipedia) ; y ésta
            (define-key w3m-mode-map ":" 'w3m-lnum-mode) ; muy cómodo. ¡Hay que requerir w3m-lnum!   Antes 'w3m-link-numbering-mode

            (define-key w3m-mode-map "e" 'w3m-scroll-up-or-next-url)
            (define-key w3m-mode-map "o" 'w3m-scroll-down-or-previous-url)

            (define-key w3m-mode-map (kbd "M-n") 'w3m-next-anchor) ; como TAB
            (define-key w3m-mode-map (kbd "M-p") 'w3m-previous-anchor) ; como S-TAB
            (define-key w3m-mode-map "m" 'w3m-view-this-url) ; como C-m

            ;; otras teclas que quiero recuperar
            (local-unset-key "\M-a") ; era w3m-bookmark-add-this-url (anotarse enlace apuntado)
            (local-unset-key [tab]) ; era w3m-next-anchor, ya está en n y en <down>
            (local-unset-key "\t") ; (porsiaca). Es para „TAB“, que quizás difiera de „tab“
            (local-unset-key [S-tab]) ; simile. Así me queda libre para icicles
            (local-unset-key [S-iso-lefttab]) ; (porsiaca)

            (define-key w3m-mode-map [tab] 'desliza-arriba-1) ; porque lo uso mucho

            (local-unset-key "T") ; era w3m-toggle-inline-images, pero quiero la T para otra cosa
            (define-key w3m-mode-map "i" 'w3m-toggle-inline-images) ; mejor aquí

            (define-key w3m-mode-map "T" 'w3m-abre-en-pestaña-trasera)


            (define-key w3m-mode-map "k" 'kill-this-buffer)

            ))

;;;;; rcirc
(add-hook 'rcirc-mode-hook
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-n")
            ;;¬tabbar←;(local-unset-key "\M-p")
            ;; no es cierto: me pierdo backward-list etc. para navegar por paréntesis
            ;;(define-key rcirc-mode-map "\C-\M-n" 'rcirc-insert-next-input)
            ;;(define-key rcirc-mode-map "\C-\M-p" 'rcirc-insert-prev-input)
            ;;¬tabbar←;(define-key rcirc-mode-map "\M-p" 'rcirc-insert-prev-input)
            ;;¬tabbar←;(define-key rcirc-mode-map "\M-u" 'rcirc-insert-next-input) ; me pierdo upcase-word
            (local-unset-key "\C-c\C-x") ; era rcirc-cmd-quit

            ;; y ya que estoy le activo esto, por probar
            (rcirc-omit-mode 1)

            ))

;;;;; eshell
(add-hook 'eshell-mode-hook ; También hay eshell-mode-hook. Uso add-hook en vez de setq eshell-mode-hook.
          ;; talcomovino:
          ;; M-p, M-n:  buscan el comando actual en la historia de comandos
          ;; arriba, abajo: lo mismo
          ;; M-r, M-s:  pregunta una expregu y busca atrás o adelante (una vez) en la historia de comandos
          ;; C-c M-p, C-c M-n: va al comando anterior o al siguiente, sin buscar
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-r") ; la necesito para otras cosas
            ;;¬tabbar←;(local-unset-key "\M-n") ; la necesito para otras cosas
            ;;¬tabbar←;(define-key eshell-mode-map "\M-p" 'eshell-previous-matching-input-from-input)
            ;;¬tabbar←;(define-key eshell-mode-map "\M-u" 'eshell-next-matching-input-from-input) ; me pierdo upcase-word
            ;; No quiero que arriba/abajo busquen (para eso tengo M-p M-u), sino que vayan como en bash:
            (local-unset-key (kbd "<up>")) (local-unset-key (kbd "<down>"))
            (define-key eshell-mode-map (kbd "<up>") 'eshell-previous-input)
            (define-key eshell-mode-map (kbd "<down>") 'eshell-next-input)

            (local-unset-key "\C-c\C-x") ; era: eshell-get-next-from-history, para seguir buscando dentro de historia (no lo uso)

            ))

;;;;; sh-mode (al editar *.sh)
(add-hook 'sh-mode-hook ;no es ni shell-script-mode-hook ni shell-mode-hook
          (lambda ()
            (local-unset-key "\C-c\C-x") ; era: executable-interpret. Nunca lo he necesitado (aunque es útil) y en cambio sí que necesito los org-clock de org-mode
            ))

;;;;; diff
(add-hook 'diff-mode-hook
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-n")
            ;;¬tabbar←;(local-unset-key "\M-p")
            ;;¬tabbar←;(local-unset-key "\M-u")
            ;;¬tabbar←;(define-key diff-mode-map "\M-u" 'diff-hunk-next)
            ;;¬tabbar←;(define-key diff-mode-map "\M-p" 'diff-hunk-prev)
            ;; otra opción es C-M-n / C-M-p, pero me pierdo backward-list etc. para navegar por paréntesis
            (local-unset-key "\M-k") ; era: diff-hunk-kill
            (local-unset-key "\M-K") ; era: diff-file-kill
            ))
;;;;; occur
(add-hook 'occur-mode-hook
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-n")
            ;;¬tabbar←;(local-unset-key "\M-p")
            ;; me pierdo occur-next, occur-prev, que ya puedo hacer con C-n C-p
            ))
;;;;; compilation
(add-hook 'compilation-mode-hook
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-n")
            ;;¬tabbar←;(local-unset-key "\M-p")
            ;; me pierdo compilation-previous-error etc., que ya puedo hacer con C-p y C-n
            ))
;;;;; c y c++
(add-hook 'c-mode-hook
          (lambda ()
            (local-unset-key "\C-\M-h") ; era: c-mark-function
            ))
(add-hook 'c++-mode-hook
          (lambda ()
            (local-unset-key "\C-\M-h") ; era: c-mark-function
            ))
;;;;; java
(add-hook 'java-mode-hook
          (lambda ()
            (local-unset-key "\C-\M-h") ; era: c-mark-function
            ))
;;;;; perl
(add-hook 'perl-mode-hook
          (lambda ()
            (local-unset-key "\C-\M-h") ; era: perl-mark-function
            ))
;;;;; prolog
(add-hook 'prolog-mode-hook
          (lambda ()
            (local-unset-key "\C-\M-h") ; era: prolog-mark-predicate
            ))
;;;;; python
(add-hook 'python-mode-hook
          (lambda ()
            ;; antes C-c C-n y C-c C-p eran para pasar a la siguiente línea, ¡qué triste!
            (define-key python-mode-map "\C-c\C-n" 'senator-next-tag) ; también en „C-c , n“, pero nunca me acuerdo
            (define-key python-mode-map "\C-c\C-p" 'senator-previous-tag) ; también en „C-c , p“, pero nunca me acuerdo

            ))
;;;;; calc
;; Para calc; me está costando...:
;;  (setq 
;;  ; calc-window-hook
;;  ; calc-mode-hook ; no va
;;  ; calc-trail-mode-hook
;;   calc-edit-mode-hook
;;        (lambda ()
;;  (local-unset-key "\M-k") ; era: calc-copy-as-kill
;;  ))

;; 16:06 <kstt> clemente: usually, unless you have specific need, it is
;;             safer to use (add-hook 'hook (lambda () ...)) rather than
;;             setq hook
;;(add-hook 'calc-trail-mode-hook (lambda () (local-unset-key "\M-k")))
;;(add-hook 'calc-edit-mode-hook (lambda () (local-unset-key "\M-k")))
;;(add-hook 'calc-window-hook (lambda () (local-unset-key "\M-k")))
;;(add-hook 'calc-mode-hook (lambda () (local-unset-key "\M-k")))

;;(add-hook 'calc-trail-mode-hook (lambda () (local-unset-key "\M-k")))
;;(add-hook 'calc-edit-mode-hook (lambda () (local-unset-key "\M-k")))
;;(add-hook 'calc-window-hook (lambda () (local-unset-key "\M-k")))
;;(add-hook 'calc-mode-hook (lambda () (local-unset-key "\M-k")))

(add-hook 'calc-mode-hook (lambda () (local-unset-key "\M-k")))
(add-hook 'calc-start-hook (lambda () (local-unset-key "\M-k")))
(add-hook 'calc-load-hook (lambda () (local-unset-key "\M-k")))
;; he aprendido a no matar tanto las ventanas, y el inmortal calc ha dejado de ser un problema

;; Hacer: M-x apropos  calc.*mode         <===== ¡no es lo mismo que C-M-h a!


;; El comando está en calc-mode-map. Es:    27.........    (107 . calc-copy-as-kill)
;; Lo puso calc-ext.el en la función calc-init-extensions

;; pues si no puede *des*definir, defino:
(eval-after-load "calc" ; parece necesario algo así porque si no es nulo
  '(define-key calc-mode-map "\M-k" 'kill-this-buffer)
  ;;'(message "esto va")
  )

;;;;; wanderlust
;; M-t es para moverse, no para conectar/desconectar
(add-hook 'wl-folder-mode-hook ; lista de carpetas
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-t") ; era wl-toggle-plugged
            ;;¬tabbar←;(define-key wl-folder-mode-map "\C-\M-t" 'wl-toggle-plugged) ; lo cambio de sitio

            (local-unset-key [tab]) ; era: (wl-folder-revisit-last-visited-folder &optional ARG) Revisit last visited folder.  Poco útil
            (define-key wl-folder-mode-map [tab] 'wl-folder-open-close) ; más cómodo

            (define-key wl-folder-mode-map "O" 'offlineimap)

            ))
(add-hook 'wl-summary-mode-hook ; lista de mensajes
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-t") ; era wl-toggle-plugged
            ;;¬tabbar←;(define-key wl-summary-mode-map "\C-\M-t" 'wl-toggle-plugged) ; lo cambio de sitio
            ;;
            (local-unset-key "\M-k") ; era wl-summary-toggle-persistent-mark
            ;; ¿en serio quiero matar con M-k…?
            (define-key wl-summary-mode-map "\C-\M-k" 'wl-summary-toggle-persistent-mark) ; lo cambio de sitio
            (local-unset-key "\C-cm") ; era wl-summary-toggle-mime-buttons, pero lo quiero para remember
            ))
(add-hook 'wl-draft-mode-hook ; escribiendo el borrador
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-t") ; era wl-toggle-plugged
            ;;¬tabbar←;(define-key wl-draft-mode-map "\C-\M-t" 'wl-toggle-plugged) ; lo cambio de sitio
            ;; éstos los pierdo; no sé qué hacían:
            ;;¬tabbar←;(local-unset-key "\M-n") ; era wl-draft-next-history-element
            ;;¬tabbar←;(local-unset-key "\M-p") ; era wl-draft-previous-history-element
            ))
;;;;; comint
(add-hook 'comint-mode-hook ; el de „*JDEE bsh*“
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-r") ; era comint-previous-matching-input
            ;;¬tabbar←;(local-unset-key "\M-n") ; era comint-next-input
            ;; los pierdo sin rencor porque no los necesito
            ;; Me ha costado desactivar M-n en „*JDEE bsh*“. Era por el orden: EL GANCHO HA DE ESTAR DEFINIDO ANTES DE CARGAR JDEE, no después. Ahora ya va todo normal.

            ;; espero que esto afecte a todos los derivados de comint, pero no sé si es así
            ;;¬tabbar←;(local-unset-key "\M-u") ; era upcase-word; lo pierdo
            ;;¬tabbar←;(define-key comint-mode-map "\M-u" 'comint-next-input) ; así concuerda con M-p. Además va como en eshell

            (local-unset-key "\C-c\C-x") ; era: C-c C-x runs the command comint-get-next-from-history, que no necesito

            ))
;;;;; ielm
(add-hook 'ielm-mode-hook ; ielm (evaluación de LISP). Se parece a eshell
          (lambda ()
            ;; ielm llama también a comint-mode-hook. Ya puse ahí mis cambios (M-u) pero parece que tengo que repetirlos.
            ;;¬tabbar←;(local-unset-key "\M-u") ; era upcase-word; lo pierdo
            ;;¬tabbar←;(define-key ielm-map "\M-u" 'comint-next-input) ; así concuerda con M-p. Además va como en eshell

            ))
;;;;; emms
(setq emms-stream-hook
      (lambda ()
        ;;¬tabbar←;(local-unset-key "\M-n")
        ;;¬tabbar←;(local-unset-key "\M-p")
        ;;¬tabbar←;(define-key emms-stream-mode-map "\C-\M-n" 'emms-playlist-mode-next)
        ;;¬tabbar←;(define-key emms-stream-mode-map "\C-\M-p" 'emms-playlist-mode-previous)
        ;; me pierdo backward-list etc. para navegar por paréntesis
        ))
(add-hook 'emms-playlist-mode-hook
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-n")
            ;;¬tabbar←;(local-unset-key "\M-p")
            ;;¬tabbar←;(define-key emms-playlist-mode-map "\C-\M-n" 'emms-playlist-mode-next)
            ;;¬tabbar←;(define-key emms-playlist-mode-map "\C-\M-p" 'emms-playlist-mode-previous)
            ;; me pierdo backward-list etc. para navegar por paréntesis

            ;; mplayer me ha creado este vicio, que lo encuentro mejor que el -/+ de emms. Pues le puedo dar con una pulsación
            (define-key emms-playlist-mode-map "*" 'emms-volume-raise)
            (define-key emms-playlist-mode-map "/" 'emms-volume-lower)
            (define-key emms-playlist-mode-map "+" #'(lambda () (interactive) (message "uzu bone „*“-on kvazaŭ mplayer-e")))
            (define-key emms-playlist-mode-map "-" #'(lambda () (interactive) (message "uzu bone „/“-on kvazaŭ mplayer-e")))
            ;; muestra el tiempo, y lo hace muy mal
            (define-key emms-playlist-mode-map "." #'(lambda () (interactive) (let ((emms-playing-time-display-p t) (emms-playing-time-display-short-p nil) (emms-playing-time-style 'time)) (emms-playing-time-display)
                                                                                  ;; a veces no va por culpa de esto, que da nil:
                                                                                  ;;(emms-track-get (emms-playlist-current-selected-track) 'info-playing-time)

                                                                                  )))
            ;; Falta: tecla „1“ que me toque una canción y luego pare (en vez de seguir por la lista). Quizás puedo hacer que la ponga en una nueva lista de 1 solo fichero y que la toque ahí

            (define-key emms-playlist-sort-map (kbd "s") 'emms-shuffle)

            ))
;;;;; files.el, y cosas sueltas

;; Algo raro: m2.2023: se queja mucho de executable-find, en general
;; Ejemplo: magit-auto-revert-mode-enable-in-buffers: Symbol’s value as variable is void: executable-find
;; ¿por haber tomado .elc viejos compilados en otro lado, creo?. Instalé magit más nuevo
;; ver 

;;;;; dired
(add-hook 'dired-mode-hook
          (lambda ()
            ;; antes era ' pero luego TAB; en realidad lo que quiero es que esté en la Q qwertyiana
            ;;(define-key dired-mode-map (kbd "<tab>") 'dired-up-directory)
            ;; parece que (kbd "<tab>") ha dejado de funcionar y ahora es sólo "\t"
            (define-key dired-mode-map "\t" 'dired-up-directory) ; como el ^, pero más accesible
            ))
;;;;; ibuffer
(add-hook 'ibuffer-mode-hook
          (lambda ()
            ;; me va bien tener q para escaparme del búfer pero sin matarlo
            ;;(local-unset-key "q")
            ;;¬tabbar←;(local-unset-key "\M-u") ; me pierdo upcase-word. Hago sitio
            ;;¬tabbar←;(local-unset-key "\M-n") ; la uso para navegación entre búfers
            ;;¬tabbar←;(define-key ibuffer-mode-map "\M-u" 'ibuffer-forward-filter-group) ; antes en M-n. Par con M-p
            (local-unset-key "\C-xv") ; era ibuffer-do-view-horizontally, que se parece mucho a „v“ y que podría tener en „C-u v“ si lo necesitare
            ))
;;;;; info
(add-hook 'Info-mode-hook ; ¡recórcholis! Se llama Info, no info
          (lambda ()
            (local-unset-key "\M-n") ; era clone-buffer
            (define-key Info-mode-map "q" 'kill-this-buffer) ; q no esconde, sino cierra de verdad
            ))
;;;;; conf (para ficheros .properties, etc)
(add-hook 'conf-mode-hook
          (lambda ()
            (local-unset-key "\C-c\C-x") ; era: C-c C-x runs the command conf-xdefaults-mode

            ))

;;;;; gnus
;; Ahora las teclas para GNUs, que son muchas

;;;;;; Para la lista de mensajes (una vez seleccionado un grupo)
(add-hook 'gnus-summary-mode-hook (lambda () ; (add-hook es mejor que setq aquí)
                                    ;; C-M-h runs the command gnus-summary-hide-thread
                                    (local-unset-key "\C-\M-h")
                                    (define-key gnus-summary-mode-map "\C-\M-y" 'gnus-summary-hide-thread)

                                    ;; Muevo M-p y M-n a C-M-p y C-M-n

                                    ;; hago sitio:
                                    ;;¬tabbar←;(local-unset-key "\C-\M-n") ; me pierdo gnus-summary-next-same-subject
                                    ;;¬tabbar←;(local-unset-key "\C-\M-p") ; me pierdo gnus-summary-prev-same-subject
                                    ;; borro viejas:
                                    ;;¬tabbar←;(local-unset-key "\M-n") ; me pierdo gnus-summary-next-unread-subject
                                    ;;¬tabbar←;(local-unset-key "\M-p") ; me pierdo gnus-summary-prev-unread-subject
                                    ;; pongo nuevas:
                                    ;;¬tabbar←;(define-key gnus-summary-mode-map "\C-\M-n" 'gnus-summary-next-unread-subject)
                                    ;;¬tabbar←;(define-key gnus-summary-mode-map "\C-\M-p" 'gnus-summary-prev-unread-subject)

                                    (local-unset-key "\M-k") ; me pierdo gnus-group-edit-local-kill o similar. Si lo necesito, recolocarlo
                                    ;;¬tabbar←;(local-unset-key "\M-r") ; me pierdo gnus-summary-search-article-backward, muy rara

                                    ;;¬tabbar←;(local-unset-key "\M-t") ; me pierdo gnus-summary-toggle-display-buttonized (no lo veo útil)

                                    ))

;;;;;; Para la lista de grupos (correos, RSS, NNTP, ...)
(add-hook 'gnus-group-mode-hook (lambda () ; (add-hook es mejor que setq aquí)

                                  ;; M-n M-p me molestan y no las uso:
                                  ;;¬tabbar←;(local-unset-key "\M-n") ; me pierdo gnus-group-next-unread-group-same-level
                                  ;;¬tabbar←;(local-unset-key "\M-p") ; me pierdo gnus-group-prev-unread-group-same-level

                                  ;;¬tabbar←;(local-unset-key "\M-c") ; me pierdo gnus-group-clear-data
                                  ;; La podría poner en \M-\C-c (quitando de ahí exit-recursive-edit) si lo necesito

                                  (local-unset-key "\M-k") ; me pierdo gnus-group-edit-local-kill. Si lo necesito, recolocarlo
                                  (define-key gnus-group-mode-map "\M-k" 'gnus-group-exit) ; hace como la q (salir amigablemente, grabando todo) pero no permite matar búfer a lo bestia como si fuera normal

                                  (local-unset-key [tab]) ; me „pierdo“ gnus-topic-indent; no sé quién la puso ahí
                                  (define-key gnus-group-mode-map [tab] (lambda () (interactive) (gnus-topic-fold))) ; en vez de eso, la dejo para expandir/contraer grupo
                                  ;; probar gnus-topic con esto, con el tab

                                  (local-unset-key "\C-c\C-x") ; me pierdo gnus-group-expire-articles pero mantengo los prefijos de temporización de org

                                  ))

;;;;;; Para la lista de carpetas dentro del servidor
(add-hook 'gnus-browse-mode-hook (lambda () ; (add-hook es mejor que setq aquí)

                                   ;; M-n M-p me molestan y no las uso:
                                   ;;¬tabbar←;(local-unset-key "\M-n") ; me pierdo gnus-browse-next-group, que ya es n
                                   ;;¬tabbar←;(local-unset-key "\M-p") ; me pierdo gnus-browse-prev-group, que no lo necesito

                                   ))

;;;;;; Para la lista de servidores
(add-hook 'gnus-server-mode-hook (lambda () ; (add-hook es mejor que setq aquí)

                                   ;;¬tabbar←;(local-unset-key "\M-c") ; me pierdo gnus-server-close-all-servers

                                   ))

;;;;;; Para la redacción de un correo (no es parte de Gnus; es genérica)
(add-hook 'message-mode-hook (lambda ()

                               ;;¬tabbar←;(local-unset-key "\M-n") ; me pierdo message-display-abbrev, que acaba usando ecomplete. Yo ya uso bbdb

                               ))


;;;;; view-mode
;; pues me pongo algunas cómodas para leer
(add-hook 'view-mode-hook
          (lambda ()

            ;; En realidad ya tengo teclas para deslizarme, y prefiero Tab para moverme entre enlaces…
            ;;(unless (equalp major-mode 'help-mode)  ; tab me mueve entre enlaces en help-mode
            ;;  (define-key view-mode-map (kbd "<tab>") 'desliza-arriba-1) ; en el resto lo redefino
            ;;)
            ;;(define-key view-mode-map (kbd "<C-tab>") 'desliza-abajo-1)

            (define-key view-mode-map "b" 'scroll-down) ; M-v
            (define-key view-mode-map "v" 'scroll-up) ; como C-v
            (local-unset-key "h") ; era ¡describe-mode!
            (define-key view-mode-map "h" 'hl-line-mode) ; remarca línea actual
            (local-unset-key "n")
            (local-unset-key "p") ; eran algo para circular por búsquedas de expregus o algo así
            (define-key view-mode-map "p" 'previous-line)
            (define-key view-mode-map "n" 'next-line)
            ;;(message "estoy en view-mode")
            ))
;;;;; help-mode (ej. al describir funciones y variables)
(add-hook 'help-mode-hook
          (lambda ()

            ;; moverme más fácil atrás/alante
            (define-key help-mode-map [backspace] 'help-go-back) ; también C-c C-b
            (define-key help-mode-map [S-backspace] 'help-go-forward) ; también C-c C-f
            ;;(message "estoy en help-mode")
            ))

;;;;; hexl-mode
(add-hook 'hexl-mode-hook
          (lambda ()
            (local-unset-key "\M-k") ; era undefined
            ))
;;;;; scroll-lock-mode
;; Es muy parecido a view-mode (me facilita la lectura y el desplazamiento simultáneo) pero me sigue dejando editar; además ofrece menos cosas
;; Lo quiero conmutar; le pongo F1 sin pensar mucho
(global-set-key [f1] 'scroll-lock-mode)
;; MALFAR: El cursor salta bastante; en concreto baja de dos en dos (aunque sube 1-ope); arreglar porque es molesto

;;;;; org-mode
(add-hook 'org-mode-hook
          (lambda ()

            ;; m10.2012: desactivo estas chapucitas para ver qué tal va ahora
            (ignore '(

                      (define-key org-mode-map (kbd "C-M-x") 'eval-defun) ;igual que en lisp-interaction-mode. Me la quedo en org pues nadie úsala
                      ;; .... mmmm..... está fallando con un a.org como éste:
                      ;; ;;;;;;;;;;;;;;;;;;;;;;;
                      ;; (defun a nil          ;;
                      ;; (insert "#'(beep)") ;;
                      ;; )             ;;
                      ;;               ;;
                      ;; (+ 2 3)           ;;
                      ;; ;;;;;;;;;;;;;;;;;;;;;;;
                      ;; 15.11.2008. Pues no tengo ganas de arreglar este fallo en eval-defun. Creo que tiene que ver con el error 135 de emacs, así que hay trabajo
                      (define-key org-mode-map (kbd "C-M-x") (lambda nil (interactive) (message "Usa org-edit-src-code o arregla el „FARU“ del C-M-x")))
                      ))

            (define-key org-mode-map (kbd "5") 'org-force-cycle-archived) ; mi equivalente en consola al C-tab

            ;; no quiero los org-beginning-of-line etc. sino mis desplazadores
            (local-unset-key [home])
            (local-unset-key [end])


            ;; m2.2017 tras actualizar a org 9.1 encuentro que C-c C-m hace…:
            ;; (org-defkey org-mode-map "\C-c\C-m" 'org-ctrl-c-ret)
            ;;  "Call `org-table-hline-and-move' or `org-insert-heading' dep. on context."
            ;; … cuando lo que yo quiero es:
            ;; (org-defkey org-mode-map [(meta return)]       'org-meta-return)
            ;;   "Insert a new heading or wrap a region in a table.
            ;; Calls `org-insert-heading', `org-insert-item' or
            ;; `org-table-wrap-region', depending on context.  When called with
            ;; an argument, unconditionally call `org-insert-heading'."
            ;; Así que lo cambio:
            (org-defkey org-mode-map "\C-c\C-m" 'org-meta-return)
            ;; Tras un org-reload me toca ejecutar esa línea también
            ))

;;;;; slime
;; me quería quitar M-n
(add-hook 'slime-mode-hook
          (lambda ()
            ;;¬tabbar←;(local-unset-key "\M-n") ; era slime-next-note
            ;;¬tabbar←;(local-unset-key "\M-p") ; era slime-previous-note; la quito por consistencia
            ;;¬tabbar←;(define-key slime-mode-map "\S-\M-n" 'slime-next-note)
            ;;¬tabbar←;(define-key slime-mode-map "\S-\M-p" 'slime-previous-note)
            ))
;;(setq slime-mode-hook nil)
;; Si el local-unset-key falla es quizás porque no encuentra el (current-local-map) bueno


;;;;; nxhtml (y nxml)
(add-hook 'nxhtml-mode-hook
          (lambda ()
            (local-unset-key (kbd "C-c C-x")) ; era nxml-insert-xml-declaration pero lo quiero para org-mode (C-c C-x C-j etc)
            ))
;;;;; rst
(add-hook 'rst-mode-hook
          (lambda ()
            (local-unset-key "\C-\M-h") ; era rst-mark-section
            ))

;; nxhtml y nxml van por separado y necesito igualarlos:
(setq nxml-mode-hook nxhtml-mode-hook)

;;; Aspecto gráfico
;;;; color-theme: Esquema de colores
(add-to-list 'load-path "~/.emacs.d/color-theme-6.6.0")
;; lo tengo local para no tener que instalar emacs-goodies-el

(require 'color-theme)
;; En vez de cargar toda la biblioteca (todos los temas), cargo sólo mi preferido, y así va más rápido.
;;(color-theme-initialize)

;; lo moví yo ahí, a mano, para aligerar la carga (está compilado)
(load "color-theme-hober")

;; Ahora cargo el tema que me gusta
(color-theme-hober)  ; negro de fondo
;;(color-theme-gray30) ; gris oscuro de fondo
;;(color-theme-montz)   ; gris claro de fondo

;;;; colores de elementos de la interfaz

;; las barras de desplazamiento, me gustan negras con marcos grises. Así no duelen a la vista
(set-face-background 'scroll-bar "black") ; era: grey75

;; El menú con opciones que se muestra arriba
(set-face-background 'menu "#000")
(set-face-foreground 'menu "#060")

;; scroll-bar ni menu no iban con mis colores en Emacs 22.1.1 o 23 en CPU109
;; Luego me acostumbré a tener todo esto desactivado; me va mejor
(menu-bar-mode -1) ;; y luego hay algo de tmm-menubar
(scroll-bar-mode -1)
;; si no va, usar toggle-scroll-bar

;; Ver colores de tabbar más abajo


;; Línea que contiene hora, modo actual, ...
(set-face-background 'mode-line "#036") ; era darkslateblue
(set-face-foreground 'mode-line "#999") ; era white

;; lo mismo, pero la de una ventana que no tiene el foco
(set-face-background 'mode-line-inactive "grey10") ; era grey30
(set-face-foreground 'mode-line-inactive "grey60") ; era grey80
;;(set-face-attribute 'mode-line-inactive nil :weight 'light) ; era light
(set-face-attribute 'mode-line-inactive nil :box '(:line-width -1 :color "grey30" :style nil)) ; era grey40

;; para el trocito que muestra el nombre del búfer (a la izquierda)
(set-face-background 'mode-line-buffer-id "#53a") ; era darkslateblue
(set-face-foreground 'mode-line-buffer-id "orange") ; era white

;;;; colores básicos usados en textos por todos lados

;;;;; texto normal y enlaces

;; ¡BRILLA MUCHO! Al menos en mi pantalla plana de ali, que ya tiene un brillo excesivo per se.
;; Intento corregirlo:
;;(set-face-foreground 'default "#999") ; me gustó para LCD de ali, pero en CPU107 era muy flojo
(set-face-foreground 'default "#bbb") ; me gustó para CPU107; se ve un gris suave
;;(set-face-foreground 'default "#ccc")
;;(set-face-foreground 'default "#fff")
;; lo mismo para enlaces (ej: info, w3m)
(set-face-foreground 'link "cyan3")
;;(set-face-foreground 'link "cyan1")

;;;;; colores de otras secciones
(set-face-foreground 'widget-inactive "black") ; era: "dim gray", que no combina para nada con el fondo "red"

;;;;; selección primaria y secundaria

;; selección primaria: esto se ajusta para cada nuevo marco → ver ajusta-colores-para-nuevo-marco

;; selección secundaria; se usa además extrañamente para otras cosas; ej. tras C-c C-v en .org
(set-face-background 'secondary-selection "#00e") ; era 'paleturquoise


;;;; colores para modos de resaltado de sintaxis

(set-face-foreground 'font-lock-comment-face "#ff1a00") ; era #ff0000 („red“), demasiado oscuro
(set-face-foreground 'font-lock-function-name-face "#61a6ee") ; era #4186be
(set-face-foreground 'font-lock-string-face "#dddd00") ; era #ffff00
(set-face-foreground 'font-lock-constant-face "#00dd00") ; era #00ff00
(set-face-foreground 'font-lock-variable-name-face "#eee") ; era white
(set-face-foreground 'font-lock-keyword-face "#ff9e7b") ; era #00ffff, que brillaba un poco. Yo le he puesto el que usaba Org-mode, por consistencia
;;(set-face-foreground 'font-lock-keyword-face "#00ffff") ; MALFAR ¿lo vuelvo a dejar azul? (Destaca un poco más, aunque /molesta/ y en realidad se diferencia poco del gris normal.). También puedo poner faces distintas para -keyword- y para org-special-keyword
(set-face-attribute 'font-lock-type-face nil :weight 'normal :foreground "coral2") ; para que se diferencie un poco de „font-lock-keyword-face“ (#ff9e7b). Como se ve muy oscuro coral4, +lo pongo negrita+ pongo coral2 (pues 3 también es muy oscuro)



;;;; resaltado de la línea actual


;;(highlight-current-line-on t)
;;(highlight-current-line-set-bg-color "#008")
;; Esto me da el siguiente fallo:
;; Do M-x highlight-current-line-on, and then type fast on blank line:  [3]4  (without RET).  Result: cursor jumps to the next line. (After the "]", it goes to "[" for a moment; you must type "4" just then). Emacs 21.4a+1-5; only happens in graphical session.
;; El fallo está probablemente en /usr/share/emacs/site-lisp/emacs-goodies-el/highlight-current-line.el

;; Parece que eso o (global-hl-line-mode 1) o (hl-line-mode t) no iba; por eso mandé un informe de error el 20-5-2007

;; Por eso pruebo este otro modo:
;;(global-hl-line-mode 1)
;; En realidad intentaré evitar lo de resaltar línea actual, pues:
;; - hace que las búsquedas (C-s C-s etc.) dejen de funcionar: entran en ciclo, etc. Es un fallo, sí
;; - hace que la línea actual no tenga resaltado sintáctico (pues se ve toda del mismo color)
;; - genera mucho parpadeo de pantalla, notable sobre todo en cosas como emacs-w3m con imágenes
;; - no me hace falta para identificar la línea actual

;; En realidad lo del resaltado de línea me va bien en algunos modos
(add-hook 'org-agenda-mode-hook #'(lambda () (hl-line-mode 1)))

;; El modo columnas dentro de agenda es el que no va bien; lo deja todo destrozado
;; probando a desactivarlo:
;; (remove-hook 'org-agenda-mode-hook #'(lambda () (hl-line-mode 1)))
;; De momento lo dejaré desactivado; ya que miraré la agenda más desde columnas, no me hace tanta falta. Claro que me gustaría… pero no se puede fácilmente.

(add-hook 'gnus-summary-mode-hook #'(lambda () (hl-line-mode 1)))


;; Esto afecta al resaltado de línea actual
;; Creo que no molesta mucho si lo activo
(set-face-background 'highlight "#008")
(set-face-foreground 'highlight "#ccc")


;;;; cursor

;; color del curso: esto se ajusta para cada nuevo marco → ver ajusta-colores-para-nuevo-marco

;; Y no quiero parpadeo en cursor, pues pone nervioso. Así queda como urxvt
(blink-cursor-mode -1)

;; Dice también la columna del cursor
(column-number-mode t)

;;;; Muestra fecha y hora en barra de estado
;; Lo activo a menos que tenga algo en gdv que me lo muestre (RATPOISON+„a“, ion, …). Lo ideal es si lo hace el gdv, pues no hace falta ver hora en cada marco. Como con wmii no tengo nada, lo usaré
(display-time-mode 1) ; -1: desactivado, 1: activado

;;(setq display-time-24hr-format t)
;;(setq display-time-day-and-date t)

;;;; barra de herramientas y „mode-line“

;; Quitar barra con iconos básicos; ya están en el menú
(tool-bar-mode -1)
;;;; barra de modo (mode-line)
;; quitar la barra si no hace falta
(add-to-list 'load-path "~/.emacs.d/hide-mode-line") (require 'hide-mode-line)
;; En realidad no me interesa activarlo en general. Sólo tenerlo para algunas ocasiones (ej. eshell)
;;(hide-mode-line)
;; (setq hide-mode-line t)  (hide-mode-line-update)

;; De hecho, quiero que no me moleste poniendo/quitando esa barra cada vez que hago algo
(hide-mode-line-remove-hooks)

;; Parece que si dejo los ganchos, las barras vuelven a aparecer cuando se abre el minibúfer (o cuando se abre en otra ventana)… a veces (es impredecible). Eso no me gusta

;; Para el búfer actual:
;; (hide-mode-line-in (current-buffer))
;; (show-mode-line-in (current-buffer))
;;
;; He usado esto en eshell (Mod3+b en wmii); ver en .wmiirc

;; no sirve mucho esto.
(defun conmuta-la-barra-de-modo--mode-line nil
  (interactive)
  (if hide-mode-line (show-mode-lines) (hide-mode-lines))
  (setq hide-mode-line (not hide-mode-line))
  (message (if hide-mode-line "ahora oculté barra de modo" "ahora mostré barra de modo"))
  )
;; encontré esto también, ya de paso. Funciona:
(defun toggle-mode-line () "toggles the modeline on and off"
       (interactive) 
       (setq mode-line-format
             (if (equal mode-line-format nil)
                 (default-value 'mode-line-format)) )
       (redraw-display))
;; probar: (toggle-mode-line)


;;;; líneas de marcos (entre ventanas)
;; Ver faz vertical-border
;; window-divider-last-pixel, window-divider etc.: no noto la diferencia

;; Quiero que en nw (¬X) cambie la barra. Con esto lo consigo:
;;(setq copia-de-tabla standard-display-table)
;;(set-display-table-slot standard-display-table 'vertical-border (make-glyph-code ?┃))
;; Mejor, según http://emacs.stackexchange.com/questions/7228/nice-tty-window-borders-in-24-4: 
(let ((display-table (or standard-display-table (make-display-table))))
  (set-display-table-slot display-table 'vertical-border (make-glyph-code ?┃))
  (setq standard-display-table display-table))

;;;; mensajes de bienvenida
;; Quitar mensaje de bienvenida molesto
(setq inhibit-startup-message t)
;; el de gnus lo quitará gnus.el

;;;; fuentes
;;;;; pruebo a elegir fuentes de X en vez de XFT sólo porque son más rápidas (eso dicen)

;; Decía Kenichi:
;; > Thanks very much!  The XFT support is great and beautiful but sometimes the speed in rendering of the plain old X fonts is best.
;;I too prefer well-designed X bitmap fonts.  So, I put `x' font-backend higher priority as this:
;;(setq default-frame-alist `((font-backend . "x, xft")))
;;Then if the same font is provided both by X and XFT, Emacs selects the X font.

;; Lo pruebo:
;; (set-alist 'default-frame-alist 'font-backend "x, xft")
;; (set-alist 'default-frame-alist 'font-backend "xft, x")
;; (set-alist 'default-frame-alist 'font-backend nil)
;; ¿qué otros valores hay? ¿cairo? → https://www.gnu.org/software/emacs/manual/html_node/elisp/Font-and-Color-Parameters.html
;;
;; Con harfbuzz (pero es el que está haciendo todas las guarradas mezclando fuentes que no combinan bien):
;; (set-alist 'default-frame-alist 'font-backend "xfthb")
;; xft con harfbuzz:
;; xfthb
;; (set-alist 'default-frame-alist 'font-backend "xfthb")
;; ¿Qué diferencia hay entre xft y xfthb?
;; freetype, cairo, sin harfbuzz
;; (set-alist 'default-frame-alist 'font-backend "ftcr")
;; freetype, cairo, con harfbuzz
;; (set-alist 'default-frame-alist 'font-backend "ftcrhb")
;; (pero sigue mostrándome mal el árabe…)

;; Tras m11.2021 y actualizar a Devuan Chimaera y compilando Emacs con Cairo+HarfBuzz, encontré problema con la fuente Terminus, pues a tamaños grandes no la mostraba (usaba otra). Quizás porque la Terminus que uso es otb (de tipo „bitmap“). La solución (tras horas investigando) fue pedir usar "x" antes que "xft"
;; Otros también lo hacen: https://www.reddit.com/r/emacs/comments/ljak57/otb_bitmap_fonts_not_working/
;;
;; ∴ En total: he ido probando algunos backend de fuentes (aunque muy poquito) y creo que los prefiero en este orden:
;; (set-alist 'default-frame-alist 'font-backend "x, xft, ftcr")
;; set-alist no va. Pruebo esto, sin entenderlo
;; (setf (alist-get 'font-backend 'default-frame-alist) "x, xft, ftcr")
(add-to-list 'default-frame-alist '(font-backend . "x, xft, ftcr"))



;; Me encuentro con que no me usa las mismas fuentes en „emacs“ y en „emacsclient“. Ver notas en donde apunté lo de la oblícua de „terminus“ (pues no me sale debido a esto).
;; La solución que ofrecen es:
;; (add-to-list 'default-frame-alist '(font . "terminus-bold-14")) ;; es efectivo
;; (set-alist 'default-frame-alist 'font "terminus-bold-14") ;; eficaz
;; (set-alist 'default-frame-alist 'font "terminus-14")
;; (set-alist 'default-frame-alist 'font "-xos4-terminus-bold-o-normal--14-140-72-72-c-80-iso10646-1") ; sí, todo sale en cursiva
;; (set-alist 'default-frame-alist 'font nil) ;  esto lo rompe
;; Oh no, qué absurdo, entonces para cada tamaño de letra se usa una fuente distinta

;; Por cierto, probé por curiosidad esto de opacidad pero no va:
;; (set-alist 'default-frame-alist 'alpha 100)


;;;;; tipo de letra inicial (y tamaño)
;; está definido en ~/.Xresources
;; Si se cambia hay que usar xrdb
;;
;; Esto parece activar/desactivar el .Xresources
;; (setq inhibit-x-resources nil)
;; (por defecto estaba a t)
;; pero lo pongo a nil y no veo cambios

;; prueba:
;; (set-default-font "Terminus-14")
;;(set-default-font "lucidasans-8")
;;(set-default-font "6x13")
;;(set-default-font "5x8")

;; ahora se llama set-frame-font
;; (set-frame-font "Terminus-14")
;; (set-frame-font "Terminus")
;; (set-frame-font "5x8")
;; (set-frame-font "lucidasans-8") ;; el 8 tiene barriga gorda
;; Por cierto, mejor interactivamente: (call-interactively #'set-frame-font)
;; más detalles:
;; (set-frame-font "-PfEd-Terminus-medium-normal-normal-*-12-*-*-*-c-*-iso10646-1")
;; (set-frame-font "-PfEd-Terminus (TTF)-medium-normal-normal-*-*-*-*-*-m-0-iso10646-1")
;; la 2ª queda fea. Ver notas

;; por ahora (m11.2021), mientras investigo y arreglo falla que impide usar Terminus en grande, uso:
(set-frame-font "terminus")

;;;;; herramientas para cambiar tamaño de letra: ver más abajo
;;;;; cambio tipos de letra de algunas faces por motivos muy concretos
;; ej. porque con Terminus, la cursiva es muy fea.
;; Un ej. de org-agenda-date-today, lo hago por customize
;; Cambiar faz 'italic. Debería ser tan grande como la normal, ej. para tablas; por eso le pongo :height 100 y ya mejora. 100 para letra pequeña, 120 para mi tamaño normal… Esto tengo que mejorarlo para encontrar un solo valor apto para todos
;;(set-face-attribute 'italic nil :foundry "FreeMono" :family "FreeMono")
;;(set-face-attribute 'italic nil :foundry "Nimbus Mono L" :family "Nimbus Mono L")
;;(set-face-attribute 'italic nil :foundry "Liberation Mono" :family "Liberation Mono" :height 100)
;;(set-face-attribute 'italic nil :foundry "Liberation Mono" :family "Liberation Mono" :height 120)
;; Estuve usando esto durante años:
;;(set-face-attribute 'italic nil :foundry "Liberation Mono" :family "Liberation Mono" :height 0.8)

;; ∴ Pero al final me doy cuenta de que: 1) la nueva que estaba usando también es fea. 2) me es más importante el hecho de ser ancho fijo que no el antialias etc. ∴ Por tanto sigo usando Terminus, y mucho más contente

;; lo mismo para algunas que deberían heredar de italic y no lo hacen: w3m-italic (más abajo)


;;;; otras faces (de modos concretos)
;; las defino más abajo, en el modo al que pertenecen, o en el custom-set-faces del final
;;;; aspectos de la interfaz que hay que ajustar para cada nuevo marco
(defun ajusta-colores-para-nuevo-marco (marco)
  ;;(with-selected-frame marco ← no hace falta

  ;; Quiero el cursor en rojo, como en urxvt. Así se ve mejor.
  (set-face-background 'cursor "red")
  ;; qué raro, a partir del 20.m10.2010 el cursor me sale blanco, y en cada marco nuevo he de cambiarlo a otro color (¬"red") y luego a "red" otra vez
  (set-face-background 'cursor "blue")
  (set-face-background 'cursor "red")

  ;; selección primaria
  ;; esto se usa en transient-mark-mode y al seleccionar con el ratón
  ;; un fondo azul oscuro que no molesta mucho
  ;; #191970=MidnightBlue
  ;; (set-face-attribute 'region nil :foreground nil :background "MidnightBlue")
  ;; Warning: setting attribute ‘:foreground’ of face ‘region’: nil value is invalid, use ‘unspecified’ instead.
  (set-face-attribute 'region nil :foreground 'unspecified :background "MidnightBlue")
  ;;(set-face-attribute 'region nil :foreground nil :background "#101040") ; quizás tan oscuro que no se ven los límites laterales
  ;; esto es feo porque cambia el color del primer plano (como si esto fuera Windows...)
  ;;(set-face-attribute 'region nil :foreground "white" :background "darkslateblue") ;hober
  ;;(set-face-attribute 'region nil :foreground "goldenrod2" :background "MidnightBlue")

  ;; Ya no → No sé porqué, pero al hacer C-SPC C-SPC C-p C-p M-x, se ve la región blanca (con Background: #E666E666E666). Es por transient-mark-mode
  ;;)
  )
(add-to-list 'after-make-frame-functions #'ajusta-colores-para-nuevo-marco)

;;; Indentación (muchas cosas)
;;;; al indentar código, pon sólo un espacio detrás de un punto y seguido
;; Así. Queda. Más. Bonito.  Que.  De.  Esta.  Otra.  Forma.
(setq sentence-end-double-space nil)

;;;; cuántos espacios ha de poner el tabulador
(setq tab-width 4) ; era 8. Creo que esto sólo afecta al actual, por tanto es innecesario en ~/.emacs
;;(setq default-tab-width 4) ; era 8, creo. Así lo cambio de verdad para búfer nuevos   ← esta variable la han quitado
(set-default 'tab-width 4) ; parece forma nueva de decir el default-*. Esto afecta a todos búfers
;; quizás 3 también va bien

;; indent-tabs-mode: me va bien a t pues me gustan los TABs

;; Y eso de adivinar si uso TABs o espacios: … dtrt-indent-mode
;; Por reactivar

(defun indenta-todo-el-fichero ()
  "Equivalente a C-x h C-M-\  (que es muy largo de teclear)"
  (interactive)
  (indent-region (buffer-end -1) (buffer-end 1))
  )


;; Lo que no tiene que indentar

;; No, esto es para auto-fill, que no me gusta y no uso
;;(setq auto-fill-inhibit-regexp "^/\\\*\\\*")
;;(setq auto-fill-inhibit-regexp "^/")


;;;; los espacios en blanco saldrán resaltados para que los pueda ver
;; Para eso uso: whitespace.el (oficial)

;; La configuración se cambia mucho mejor con „customize“. Está más abajo
;; MALFAR: cambiar colores para poder usarlo siempre ← no, no lo necesito siempre
;; MALFAR: quiero que un espacio entre letras normales no sea resaltado, pues es muy común

;; uso ␤ al final de las líneas; para ello hubo que corregir (24.3.2009) el error: http://emacsbugs.donarmstrong.com/cgi-bin/bugreport.cgi?bug=2689
;; abajo está toda la configuración

;;;; Truncado de líneas
;; NO quiero desplazamiento horizontal; quiero ver todo en MI pantalla física
(setq truncate-lines nil)
(setq truncate-partial-width-windows nil) ; ¡tampoco en subventanas!
;; Aviso: además está la función toggle-truncate-lines para cambiar „en directo“

(global-set-key [f7] 'toggle-truncate-lines)
;; (global-set-key (kbd "<XF86Mail>") 'toggle-truncate-lines) ; extraño en trasc con Kinesis, no sé por qué f7 manda eso. No tengo xbindkeys. Quizás es por placa base mala. Dejó de pasar

;; Algo nuevo: permitir ventanas que tienen un número de píxels no múltiplo de la anchura/altura del caráctecr
(setq window-resize-pixelwise t)
;; No noto diferencia (será porque uso fuente de tamaño fijo…) pero a ver si me soluciona el problema del ¬refresco al cambiar de ventana.

;;;; estilo de indentación que quiero para cada modo
(defun pon-mi-estilo-de-indentación-sintabs ()
  ;;  (message "Poniende mi estilo de indentación sin TABS")
  (setq indent-tabs-mode nil)
  )
(defun pon-mi-estilo-de-indentación-para-php ()
  ;; usado ẽ en Laravel
  ;; (c-set-style "bsd") ; sí, bsd==allman
  (c-set-style "java") ; Funciona mejor… Qué se le va a hacer
  ;; A espera de encontrar otro mejor
  )
;; probando. Lo pongo debido a Laravel
(add-hook 'php-mode-hook 'pon-mi-estilo-de-indentación-para-php)
(add-hook 'html-mode-hook 'pon-mi-estilo-de-indentación-sintabs)
;; (add-hook 'css-mode-hook 'pon-mi-estilo-de-indentación-sintabs)
;; lo pruebo en org también. ¡Parece que va bien!
(add-hook 'org-mode-hook 'pon-mi-estilo-de-indentación-sintabs)

;;;; detectar estilo de indentación (guess-style)
;; http://nschum.de/src/emacs/guess-style/, https://github.com/nschum/guess-style
(let ((d "/w/guess-style/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (autoload 'guess-style-set-variable "guess-style" nil t)
    (autoload 'guess-style-guess-variable "guess-style")
    (autoload 'guess-style-guess-all "guess-style" nil t)
    ;; Lo activo para varios modos de prueba
    (add-hook 'php-mode-common-hook 'guess-style-guess-all)

    ;; Mostrar información en barra de abajo
    (require 'guess-style)
    (global-guess-style-info-mode 1)
    ;; puedo ir aprendiendo con esto. Lista de valores que veo:
    ;; t4
    ;; >4 spc
    ))

;;;; ¿reindentar líneas anteriores? Parece que es el electric-indent-mode
;; 14.m4.2015: lo pruebo un tiempo a nil… pues me está hartando tanto movimiento de líneas. Si lo encuentro odioso, volverlo a poner a t
(setq electric-indent-mode nil)

;;; Ajustes en el funcionamiento interno, para más comodidad
;;;; Copias de seguridad

;; Hace copias de seguridad
(setq make-backup-files t)
;; Guarda unas cuantas versiones de las copias
(setq version-control t)
;; Usa este directorio central para todas las copias
(setq backup-directory-alist (quote ((".*" . "~/.emacs.d/cosiegu/"))))
;; versiones „viejas“ y „nuevas“ de copias que se guardarán (pred=2)
(setq kept-old-versions 3)
(setq kept-new-versions 3)
;; no preguntes cada vez que si quiero borrar copias viejas
(setq delete-old-versions t)


;; al usar enlaces duros, no me rompas el enlace, por favor.
(setq backup-by-copying-when-linked t) 

;;;; Detectar ficheros que cambian fuera de Emacs

;; Cuando un fi cambia en disco, recárgalo /sin preguntar/.
;;(global-auto-revert-mode)
;; Desactivo <== al cambiar un fi modificado, pregunta si hay que revertir. Es mejor.
;;;; Revertir búfers que han cambiado fuera de Emacs, manualmente
(add-to-list 'load-path "~/.emacs.d/revbufs") (require 'revbufs)
;; Y luego M-x revbufs
(defalias 'revertir-los-búfers-cambiados 'revbufs)

;; Además quiero: revertir todos los dired. Me la hago
(defun revert-all-dired-buffers ()
  "Refreshes all open buffers …………………………… o algo así"
  (interactive)
  (dolist (buf (buffer-list))
    (with-current-buffer buf
      (when 
          ;; borrar o incorporar→ (and (buffer-file-name) (file-exists-p (buffer-file-name)) (not (buffer-modified-p)))
          (eq major-mode 'dired-mode)
        ;; Esto es para evitar fallos como: apply: Setting current directory: No such file or directory, ~/opencraft/edx-theme/lms/templates/emails/
        (if (file-exists-p default-directory)
            (progn
              (message "Actualizando búfer dired: %s" (buffer-name))
              (revert-buffer t t t)
              )
          (progn
            (message "Cerrando búfer dired de directorio que parece que ya no existe: %s" (buffer-name))
            (kill-buffer)
            )
          
          ))))
  (message "Revertidos búfers dired (no muy eficientemente).")
  )

;;;; Abre ficheros comprimidos
;; abrir contenido de .gz, etc.
(auto-compression-mode 1)

;;;; Ficheros temporales dónde
(setq temporary-file-directory "~/.emacs.d/tmp/") ; va bien, es privado

;;;; grep: cómo buscar ocurrencias dentro de ficheros

(require 'grep)
;; Me dio problemas porque modifiqué inexplicablemente el de /w. Parecía dar estos problemas
;; - grep-mode ¬variable: había que usar # en vez de #'
;; - también otras funciones como grep-read-regexp que no estaban definidas; sólo había que C-x C-e
;; Pero la solución buena fue denove make && make install

;; no sé si quiero esto; de momento no lo necesito:
;;(setq grep-command "grep -i -nH -e ")


;; Y para el rgrep y otros
;; Así puedo buscar más cómodamente en ficheros de cierto tipo
(add-to-list 'grep-files-aliases '("javas" . "*.java *.jsp *.jspf"))
(add-to-list 'grep-files-aliases '("todos" . "*.*"))

;; IS: elegir entre rgrep lgrep anything etc → rgrep es recursivo, lgrep es local (./*), grep es en fichero concreto ~

;;;; occur: busca muchas ocurrencias dentro de 1 fichero
;; Títulos para occur, rgrep, org con „C-a / a“, …
;; Lo aumento para ver más grande el nombre de los ficheros

(defface título-de-resultados-de-búsqueda
  '((t (:foreground "blue" :height 1.3 :weight bold :inherit variable-pitch)))
  "Títulos con nombre de fichero concordante tras rgrep, occur, búsqueda en agenda, …"
  :group 'matching)
;; otras:
;; org-document-title: muy grande
;; emms-browser-year/genre-face; igual de grande, y azul
;; keywiz-command-face: mejor, aunque muy azul

(setq list-matching-lines-buffer-name-face 'título-de-resultados-de-búsqueda) ; era: 'underline

;;;; al buscar, que siempre ignore mayúsculas/minúsculas
;; Esto afecta también a multi-occur, que es usado por el „C-c a /“ de org. Me molesta buscar „OpenVZ“ y no encontrar „openVZ“;
;; eso pasa porque search-upper-case era 'not-yanks y por ser non-nil dice que al salir una mayúscula se activa el modo fiel.
;; Lo dejo a nil para que siempre sean irrelevantes las úsculas. Funciona. Es mejor así, por consistencia.
(setq search-upper-case nil)

;;;; Ver el código fuente de Emacs
;; dónde ir a buscar el código fuente de Emacs. Es para M-C-h f. Normalmente lo pongo aquí:
(setq find-function-C-source-directory "/w/emacs/src")

;;;; conexión de Emacs con el bus de sistema (dbus)
;; ∴ compilar emacs --without-dbus y todo va mucho mejor y deja de colgarse. Con dbus me ha dado bastantes problemas (m10.2010)
;; Luego empecé a usarlo. Para notificaciones hay que arrancar notification-daemon, ej. poniendo esto en ~/.xsession_local:
;; /usr/lib/notification-daemon/notification-daemon &
;;
;; Siempre me dice: peculiar error: "Emacs not compiled with dbus support", esto lo prodIce emacs

;;;; Caché de líneas largas
;;(setq cache-long-scans t)
;; No noto diferencia entre t y nil; quizás me falta probra mejor
;; Lo pusieron a t en m11.2013
;; Dicen (ej. en lista de org) que mejor a nil; acelera mucho (ẽ de 33'3s a 0'2s) el cálculo de las tablas, etc.

;; Mejor que es es longlines.el, que está en „obsolete“
(require 'longlines)
;; Activarlo a mano

;; Además uso esto, que mira las ~500 primeras líneas y si ~alguna pasa de 10k activa un modo de texto menos sofisticado
;; No me cubre todos los casos, pero en algunos me ayudará
(global-so-long-mode 1)
;; Además puedo: M-x so-long, manualmente
;; Aún así es lento cuando tengo líneas de ẽ 130k (ẽ plotly me ha generado líneas así en HTML)

;;;; ¿moverse por líneas visuales o lógicas? Hay una gran controversia sobre esto
(setq line-move-visual t) ; por un tiempo volveré a probar esto… 27.m8.2009
;; Pues ya me va muy bien; no quiero cambiar
;; Idealmente querría los dos: C-n lógico, pero C-¿S?-n visual. Pero en la práctica no me hace falta; para saltos grandes uso C-s/C-r


;;;; Bidireccional, texto de derecha a izquierda (ej. para árabe)
;; En m7.2011 ya va.
;; Los primeros días aún falla (ej en „*Folder*“), por eso me creo esto:
(defun desactiva-bidi-en-este-búfer ()
  (interactive)
  (setq bidi-display-reordering nil))

;;;; quiero poder seguir escribiendo el número siete
;; En m4.2022 después de actualizar, me quedé sin poder teclear el número siete (7). Los otros van. Ver hacer/emacs.org en web para detalles
(defun siete ()
  "Escribe el nº 7 (marginado desde m4.2022, porque el método que usaba para teclearlo dejó de funcionar en Emacs)"
  (interactive)
  (insert "7")
)
;; ¿Cuál será la siguiente víctima?…

;;;; codificación de caracteres: unicode, utf-8, etc.
(defun recode-region--de-iso-8859-1-a-utf-8 (start end new-coding coding)
  "Re-decode the region (previously decoded by CODING) by NEW-CODING. De iso-8859-1 a utf-8 directamente."
  (interactive
   (list (region-beginning) (region-end)
         'utf-8 ; (read-coding-system "Text was really in: ")
         'iso-8859-1
         ))
  (or (and new-coding coding)
      (error "Coding system not specified"))
  ;; Check it before we encode the region.
  (check-coding-system new-coding)
  (save-restriction
    (narrow-to-region start end)
    (encode-coding-region (point-min) (point-max) coding)
    (decode-coding-region (point-min) (point-max) new-coding))
  (if (region-active-p)
      (deactivate-mark)))

;; de http://andrewcoxtech.civet-labs.com/2009/11/inserting-bom-into-file.html
(defun insert-BOM-UTF8--por-ahora-peta-excepto-si-quiero-utf16 ()
  (interactive)
  (goto-char (point-min))
  (ucs-insert
   ;;(string-to-number "FEFF" 16) ; UTF-16
   (string-to-number "EFBBBF" 16)
   ) 
  )

;;;; modificaciones al cómo se muestran las letras tras teclearlas
;;;;; chorradita: girar letras arriba-abajo

;; sacado el 21.10.2008, 13:19, después de estar un rato por IRC con snogglethorpe
;; aún le fallan cosas; lo de remap no está muy claro, y el alfabeto se lo ha buscado a mano.
;; mirar en su página en EmacsWiki

;; twisted-mode, Miles Bader <miles /at/ gnu.org>

(defvar twisted-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [remap self-insert-command] 'self-insert-twisted)
    (define-key map [remap delete-backward-char] 'delete-char)
    (define-key map [remap backward-delete-char] 'delete-char)
    (define-key map [remap backward-delete-char-untabify] 'delete-char)
    map)
  "Keymap for `twisted-mode'.")

(define-minor-mode twisted-mode
  "When enabled, self-inserting characters are inserted in \"twisted\" form
   See the variable `twisted-mapping' for the mapping used."
  :lighter " pǝʇsᴉʍT")

(defvar twisted-mapping
  '((?a . ?ɐ) (?b . ?q) (?c . ?ɔ) (?d . ?p)
    (?e . ?ǝ)           (?g . ?ᵷ) (?h . ?ɥ)
    (?i . ?ᴉ)           (?k . ?ʞ) ;(?l . ?ꞁ)
    (?m . ?ɯ) (?n . ?u)            (?p . ?d)
    (?q . ?b) (?r . ?ɹ)           (?t . ?ʇ)
    (?u . ?n) (?v . ?ʌ) (?w . ?ʍ)
    (?y . ?ʎ)
    (?, . ?‘) (?' . ?‚)
    (?. . ?˙) (?? . ?¿) (?! . ?¡)
    (?( . ?)) (?) . ?() (?[ . ?]) (?] . ?[)
    (?< . ?>) (?> . ?<)
    (?“ . ?„)
    )
  "Mapping from normal characters to twisted characters used by `self-insert-twisted'.")

(defun self-insert-twisted (arg)
  "Like `self-insert-command', but try to insert a twisted variant.
   The mapping from normal character to twisted characters is taken
   from `twisted-mapping'."
  (interactive "p")
  (setq last-command-char
        (or (cdr (assq last-command-char twisted-mapping))
            last-command-char))
  (self-insert-command arg)
  (backward-char arg))

;; En algún ordenador veía todos excepto (?g . ?ᵷ) (?i . ?ᴉ). Emacs decía „no font available“.
;; Tampoco podía ver ~e qué fuente contiene ᴉ
;; 19.m5.2009: pues la he encontrado, porque en CPU107 sí que se me ven todos bien. La de ᴉ es:     xft:-unknown-DejaVu Sans-normal-normal-normal-*-16-*-*-*-*-0-iso10646-1 (#x83A)
;; 7.m12.2009: En lòvic ya se ve bien todo el alfabeto. Debian con muchos paquetes


;; Ciertamente, la fuente que pongo aquí abajo no tiene el carácter „ʍ“ por ejemplo. Aunque emacs dice que sí, en xterm no se ve, y con xfd tampoco lo veo (el #x28d)
;; xterm -fn "-xos4-Terminus-Medium-R-Normal--16-160-72-72-C-80-ISO10646-1"
;; 21.12.2008: con esta fuente veo bien ʍ (es como una W al revés) en Emacs y urxvt:
;; xft:-unknown-FreeMono-normal-normal-normal-*-16-*-*-*-m-0-iso10646-1 (#x22F)


;;;;; prueba para poder ver letras en alfabeto mío (pero internamente grabar el normal)
;; nombre clave: „lagá“. Basado en toggle-rot13-mode. Ver en Privacidad.org

;; usar „display-table“

(defun obtén-display-table-cambiando-unas-letras-por-otras (originales reemplazos &rest extrapola-mayúsculas)

  (let ((table (make-display-table))
        (i 0)
        )
    (assert (= (length originales) (length reemplazos)))
    ;;(ignore '(
    (while (< i (length originales))
      (aset table 
            (string-to-char (substring originales i (+ i 1)))
            (vector (string-to-char (substring reemplazos i (+ i 1))))
            )
      (if extrapola-mayúsculas
          (aset table 
                (upcase (string-to-char (substring originales i (+ i 1))))
                (vector (string-to-char (substring reemplazos i (+ i 1))))
                )
        )
      (setq i (1+ i)))
    ;;))
    ;; prueba: (aset table ?b (vector ?u))

    table)
  )

;; Lo de lagá etc. → ver en privado-nocable.el


;;;; buscar con C-s
;; Está isearch-lazy-highlight, que es útil, pero no sé si me ralentiza demasiado. Pruebo a hacerlo más lento (pero sigue activo). Si no lo necesito, quitarlo por completo
;; (setq isearch-lazy-highlight nil)
;; (setq isearch-lazy-highlight t)
;;(setq lazy-highlight-initial-delay 0.25) ;; ← el original
;; (setq lazy-highlight-initial-delay 1.0)
(setq lazy-highlight-initial-delay 0.5)

;;;; juntar líneas
;; equivalente al J de vim. Resulta ser C-u M-^, ¡complicadísimo!
;; quizás el M-j me va bien
;; Como es tan lioso no lo uso mucho…

;;;; mover líneas arriba/abajo
;; sacado de http://www.emacswiki.org/emacs/MoveText

(defun move-text-internal (arg)
  (cond
   ((and mark-active transient-mark-mode)
    (if (> (point) (mark))
        (exchange-point-and-mark))
    (let ((column (current-column))
          (text (delete-and-extract-region (point) (mark))))
      (forward-line arg)
      (move-to-column column t)
      (set-mark (point))
      (insert text)
      (exchange-point-and-mark)
      (setq deactivate-mark nil)))
   (t
    (let ((column (current-column)))
      (beginning-of-line)
      (when (or (> arg 0) (not (bobp)))
        (forward-line)
        (when (or (< arg 0) (not (eobp)))
          (transpose-lines arg))
        (forward-line -1))
      (move-to-column column t)))))

(defun move-text-down (arg)
  "Move region (transient-mark-mode active) or current line
  arg lines down."
  (interactive "*p")
  (move-text-internal arg)
  ;;  (next-line)
  ;;  (forward-line)
  )

(defun move-text-up (arg)
  "Move region (transient-mark-mode active) or current line
  arg lines up."
  (interactive "*p")
  (move-text-internal (- arg))
  ;;  (forward-line -1) ; MALFAR: ¿por qué en compilación de 13.m1.2013 me ha empezado a ser necesario mover el cursor arriba? En todo caso, en m11.2017 veo que no me hace falta, así que lo quito
  )

;; Pero no las quiero en todos lados… ¿o sí? Parece que no molestan a org
;; Aplicable es esto también a emms-playlist-mode-map y similares
(global-set-key [M-up] 'move-text-up)
(global-set-key [M-down] 'move-text-down)
;; y esto me hizo falta en -nw. Me lo detectaba como Escape-up, Escape-down
(global-set-key (kbd "\e <up>") 'move-text-up)
(global-set-key (kbd "\e <down>") 'move-text-down)

;; ver también org-transpose-paragraphs para una mejora de esto en org


;;;; duplicar líneas; también duplicarlas comentando la original

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (open-line 1)
  (next-line 1)
  (yank)
  )
(defun duplica-línea-y-comenta-la-primera nil
  (interactive)
  (duplicate-line)
  (previous-line)
  (move-beginning-of-line 1)
  (comment-dwim-line)
  (next-line)
  (move-end-of-line 1)
  )
(global-set-key (kbd "<C-M-S-up>") 'duplicate-line)
(global-set-key (kbd "<C-M-S-down>") 'duplica-línea-y-comenta-la-primera)

;;;; borrar líneas enteras sin mover el cursor
;; La quería poner en C-S-k… pero veo que ya existe, precisamente en C-S-retroceso
;; Hago que me deje el cursor en la misma columna en que estaba
(defun borra-línea-pero-mantén-columna ()
  (interactive)
  (let (nuevapos)
    (save-excursion (next-line) (setq nuevapos (point-marker)))
    (kill-whole-line)
    (goto-char nuevapos)
    ))
;; sustituyo la antigua, quiero sólo la mía
(define-key global-map [C-S-backspace]  'borra-línea-pero-mantén-columna)


;;;; Información de depuración

;; ya activé debug-on-error al principio. Pero se desactiva de vez en cuando

;; como no funciona, me hago una yo
(defun activa-depuración ()
  "Hace que en el próximo error se muestre la pila Lisp"
  (interactive)
  (setq debug-on-error t)
  )
(defun desactiva-depuración ()
  "Deja de entrar en depurador cuando encuentra errores"
  (interactive)
  (setq debug-on-error nil)
  )

;; y también una más verborreica (con más verbosidad)
(defun activa-depuración-en-señal ()
  "Hace que en la próxima señal se muestre la pila Lisp. Va bien para depurar porque es un estado recuperable en el que aún se puede depurar bien."
  (interactive)
  (setq debug-on-signal t)
  )

;; Probando:
;; (activa-depuración-en-señal)
;; (activa-depuración)


;;;; Evaluación de código con C-M-x
;; para que C-M-x (eval-defun) funcione también cuando una línea está pegada a la columna 0
;; Qué pena que hagan esto en vez de corregir el fallo en Emacs
(setq defun-prompt-regexp nil open-paren-in-column-0-is-defun-start nil)


;;;; parada de vez en cuando para descansar
;; MALFAR: yo necesito una parada de pantalla, no de teclado

;; foje tajpadon mian haltigu
;; (type-break-mode) ; Es bastante malo. Con errores, modo manual, no molesta lo suficiente, no deja claro qué quiere que haga, no justifica las decisiones, …
;; (call-interactively 'type-break-statistics)
;; desactivar: (type-break-mode -1) ;  ¡workrave es mejor!

;; ĝi aperigis ujon „.type-break“ kiu malagrabligas min; tial mi malfunkciigu type-break :-(
;; MALFAR: korektu kaj aktivigu. Eble jeno helpas:
(setq type-break-file-name nil) ; „If this is nil, no data will be saved across sessions.“
;; otras variables interesantes:
;; type-break-good-break-interval
;; type-break-good-rest-interval ; 600

;; type-break-interval ; 3600 segundos ¡1 hora! Me parece mucho para pausa de pantalla… Pero para pausa de teclado está bien.
(setq type-break-interval 3600)

;;;; forma de hacer el desplazamiento por páginas (C-v y M-v)
;; quiero mantener el cursor donde yo lo puse, no irlo arrastrando por ahí al cambiar páginas. De esta forma, M-v M-v C-v C-v me deja justo donde estaba antes :-)
;; (setq scroll-preserve-screen-position nil)  ; ← probado, y es molesto y no me gusta
(setq scroll-preserve-screen-position t) ; ← va mucho mejor

;; no entiendo qué hace ésta:
;; (setq scroll-conservatively 0) ; por defecto
;; (setq scroll-conservatively 2)
;; (setq scroll-conservatively 1000)

;;;; desplazamiento sin mover el cursor
;; (lo que esperé de BloqDespl, pero no va)
(defun desliza-arriba-1 () "Desplaza todo un poco hacia arriba para ver la parte de abajo" (interactive) (scroll-up 1))
(defun desliza-abajo-1 () "Desplaza todo un poco hacia abajo para ver la parte de arriba" (interactive) (scroll-down 1))
;; Mejor que estas combinaciones de 2 teclas......
;;(global-set-key [\S-prior] 'desliza-abajo-1)
;;(global-set-key [\S-next] 'desliza-arriba-1)
;; .... son estas teclas que ya no uso para su función original:
;; esto va bien en emacs24
(defun cambia-teclas-de-desplazamiento (&optional marco) 
  (global-set-key [home] 'desliza-abajo-1)
  (global-set-key [end] 'desliza-arriba-1)
  "puestas teclas de desplazamiento nuevas"
  )
;; la llamo ahora, y esto en emacs24 debería hacer el efecto que toca… pero ni en 24.3.1 ni en 24.4.1 me hace nada si la llamo ahora. Cuando funciona es si la llamo mientras se crea un „frame“
(cambia-teclas-de-desplazamiento)

;; Por eso → la llamo con cada „frame“ nuevo
;; en emacs23…    NO es esto: „me hace falta usar <home> (no va [home])“, sino: „tengo que evaluar la definición anterior una vez abierto el marco, no antes“. ¿quizás tengo que añadir a after-make-frame-functions?
(if (version<= emacs-version "24.4.1")
    (add-to-list 'after-make-frame-functions #'cambia-teclas-de-desplazamiento) ; probando
  )

;; chapuza para que lo mismo vaya también en Emacs -nw. Chapuza pero esto es lo que han transmitido unos códigos desde .urxvt.pl. No he conseguido transmitir [home] ni [end] pues urxvt se embucla. Espero que estos „M-O …“ no molesten a nada importante
(global-set-key (kbd "M-O n") 'desliza-abajo-1)
(global-set-key (kbd "M-O o") 'desliza-arriba-1)

;;;; desplazamiento de la otra ventana
;; ∴ ya está bien el M-prior y M-next, y tengo que usarlas más
;; ¡Hay otras!
;; desplazar para arriba: C-M-S-v
;; desplazar para abajo: C-M-v
;; Pero son muchas teclas a la vez. Más fácil es cambiar de ventana.
;; También estaría bien S-C-v y S-M-v…
;;;; ajustes para desplazamiento con el ratón

;; Para ordenadores con roedor
;; (mouse-wheel-mode t)
;; En trasc, con una rueda tan mala, me he cansado. Como en realidad uso el teclado… desactivo la rueda
(mouse-wheel-mode -1)
;; Rueda: desplaza 3 líneas en vez de 5. Con Shift, de 1 en 1. Con Control: por páginas
(setq mouse-wheel-scroll-amount (quote (3 ((shift) . 1) ((control)))))

;; Interesante ajuste. Hace que al subir o bajar demasiado y cruzar el borde, se desplaza casi una página entera en vez de media página. Así se ahorran cambios de contexto; me gusta más.
(let ((x 0.9)) (setq scroll-down-aggressively x) (setq scroll-up-aggressively x))

;; Como no uso mucho el ratón, probaré a hacer que sólo moverlo ya cambie el foco a una ventana (de Emacs)
;;(setq mouse-autoselect-window t)
;; focus-follows-mouse: t
;; Eso lo activé en 2009; pero en 2012 me di cuenta de que me molesta mucho, en concreto cuando se abre helm, porque entonces el ratón se mueve a la parte superior derecha de la pantalla, y cuando paso a conkeror, el puntero le queda justo encima de la flechita de desplazamiento de pestañas, y se empiezan a mover. Por tanto:
(setq mouse-autoselect-window nil)

;;;; desplazamiento horizontal, con ratón y teclado
;; Pues además le añado esto: → ∴ no, nunca lo uso y en trasc esto va muy mal debido a „touchpad“ malo
(ignore '(
          (global-set-key [M-mouse-5] 'scroll-right)
          (global-set-key [M-mouse-4] 'scroll-left) ; rueda arriba, va más a la derecha del búfer
          ))

;; con el teclado se hace C-x < y C-x >. He cambiado las direcciones porque estaban invertidas. Ya las entiendo como „mover el marco visor“, no „mover el texto y quietar el visor“
(global-set-key (kbd "C-x <") 'scroll-right) ; era left
(global-set-key (kbd "C-x >") 'scroll-left) ; era right

(put 'scroll-left 'disabled nil) ; porque me lo preguntaba

;;;; ratón en „emacs -nw“ en xterm
;; Así, desde „emacs -nw“ se puede hacer clic
;;(xterm-mouse-mode 1)
;; MALFAR: desactivado pues me impide arrancar demonio. Reactivar si valepena ← no pues ni uso -nw ni ratón

;;;; copiar+pegar con el ratón
;; al hacer clic con rueda, me irá mejor pegar en el punto para no tener que apuntar otra vez
;; ambas opciones son molestas, pero creo que mover el punto por el teclado me va mejor
(setq mouse-yank-at-point t)

;;;; herramientas para cambiar el tamaño de fuente
;; Esto tiene que estar tras mouse-wheel-mode, si no no tiene efecto
;;;;; cambiar tamaño: versión más manual y que no va
;; 13.m4.2010: ignoro porque en mi Emacs no tienen efecto; las de abajo en cambio sí
(ignore '( 
          ;; por Sacha Chua; gracias.
          (defun increase-font-size ()
            (interactive)
            (set-face-attribute 'default
                                nil
                                :height
                                (ceiling (* 1.10
                                            (face-attribute 'default :height)))))
          (defun decrease-font-size ()
            (interactive)
            (set-face-attribute 'default
                                nil
                                :height
                                (floor (* 0.9
                                          (face-attribute 'default :height)))))
          (global-set-key (kbd "<C-kp-add>") 'increase-font-size)
          (global-set-key (kbd "<C-kp-subtract>") 'decrease-font-size)
          ))

;;;;; cambiar tamaño: versión automática

;; esta ya va en Emacs 23
(global-set-key (kbd "<C-kp-add>") 'text-scale-increase)
(global-set-key (kbd "<C-kp-subtract>") 'text-scale-decrease)

;; como no en todos lados tengo teclado numérico, usaré Control+rueda:
;; ∴ no, mejor lo desactivo porque en trasc toco el touchpad sin querer y se mueve mucho
(ignore '(
          (global-set-key (kbd "<C-mouse-4>") 'text-scale-increase)
          (global-set-key (kbd "<C-mouse-5>") 'text-scale-decrease)
          ))
;; Esto no iba en ningún lado hasta que lo volví a evaluar. Me pasó 2 veces, también en agenda de org. Quizás mouse-wheel-mode lo chafa. Lo he cambiado de orden y parece que ya va

;; pruebo a cambiar algo para hacer *todos* los búfers más grandes o pequeños. Ya me va bien pues siempre necesito todos a la vez
;; Es de https://www.emacswiki.org/emacs/GlobalTextScaleMode
(defadvice text-scale-increase (around all-buffers (arg) activate)
  (dolist (buffer (buffer-list))
    (with-current-buffer buffer
      ad-do-it)))
;; Si sólo lo quiero en uno… Pues no sé. Ahora no tengo forma. Tengo que encontrar una forma de llamar a la función sin ese „defadvice“
;; (ad-deactivate #'text-scale-increase)
;; (ad-activate #'text-scale-increase)

;; si hago muchas pruebas, luego me toca esto para dejarlo normal otra vez
(defun text-scale-restaura-mismo-tamaño-de-letra-en-todos nil
  (interactive)
  (dolist (buffer (buffer-list))
    (with-current-buffer buffer
      ;; curiosamente, si le pongo 1, queda todo muy grande
      (text-scale-set 0.4)
      ))
  )

;; Para tipo de letra inicial: ver más abajo



;;;; poder restringirse a un búfer (evitar que se cierre)
;; Así puedo, por ejemplo, abrir un marco dedicado sólo a ver un fichero de registro, sabiendo que no voy a empezar a abrir otras cosas. Y uno para Gnus, etc.

;; emacs-lock.el (que tiene problemas)
;;(require 'emacs-lock)
;; Esto funciona. Con (toggle-emacs-lock) protejo un búfer contra futuros intentos de matarlo. Lo único que hace es usar una variable (local a búfer), emacs-lock-from-exiting, y añadir a kill-emacs-hook y kill-buffer-hook
;; Pero no es lo que quiero

;; - El 22.m9.2009 Juanma B. propuso integrar algo parecido: http://lists.gnu.org/archive/html/emacs-devel/2009-09/msg00580.html

;; protbuf.el (Noah Friedman) ← no está en Emacs. No sé qué hace

;; Creo que es mejor que me lo haga yo mismo:
(defun quéjate-pues-el-búfer-está-bloqueado () (interactive) (message "Sesión bloqueada a este búfer"))
(defvar teclas-de-cambio-de-búfer (list
                                   "\C-x\C-b" "\C-x\C-f"
                                   (kbd "<f35>") (kbd "<S-f35>") (kbd "<M-f35>") (kbd "<C-f35>")
                                   (kbd "3n") (kbd "3S") (kbd "3M") (kbd "3C")
                                   )
  "Teclas mediante las cuales es posible escaparse del búfer actual, y que serán bloqueadas por restringe-a-búfer")
(defun restringe-a-búfer ()
  "Evita que puedas abandonar este búfer. Para ello se desactivan las teclas usadas habitualmente para cambiar de búfer.
Esto ha de servir para centrarme en algunas ventanas cliente que abro durante un momentito (ej. eshell) y que no quiero olvidar abiertas.
Funciona. 11.m9.2010 Daniel Clemente."
  (interactive)
  ;; Versión simple pero repetitiva: (local-set-key "\C-x\C-b" 'quéjate-pues-el-búfer-está-bloqueado)
  ;; Versión abreviada:
  (mapc (lambda (arg) (buffer-local-set-key arg #'quéjate-pues-el-búfer-está-bloqueado)) teclas-de-cambio-de-búfer)

  ;; No puedo usar local-set-key por esto:
  ;; The binding goes in the current buffer's local map, which in most cases is shared with all other buffers in the same major mode.
  ;; Solución: ver buffer-local-set-key, más abajo

  )
(defun desrestringe-búfer ()
  "Permite otra vez escapar de este búfer. Deshace restringe-a-búfer"
  (interactive)
  (mapc (lambda (arg) (buffer-local-set-key arg nil)) teclas-de-cambio-de-búfer)
  )

;;;; autocompleción, autocompletado genérico
;; Busco no del tipo de „autocompleción para teclear menos“, sino „autocompleción para entender el código“

;;;;; auto-complete
;; m8.2017 lo ignoro totalmente pues no lo uso, y me cambia tecla TAB
(ignore '(
          ;; La carga: Ver en cdv notas sobre 1.3.1 y anteriores, y el de /w/. Borradas notas aquí. Ahora (ẽ 2022) uso el de Elpa. 

          (require 'auto-complete-config) ; si esto falla, instalar auto-complete por ELPA
          (ac-config-default) ; esto activa a.c. para emacs c ruby css y en global

          ;; que no pase automáticamente sino al apretar tecla:
          (setq ac-auto-start nil)
          (ac-set-trigger-key "TAB")

          ;; C-n y C-p: si he sido yo quien ha activado autocompleción, entonces quiero que me sirvan para moverme. Pero si me ha abierto solo el cuadro (ẽ por jedi), quizás mejor que C-n/C-p hagan su función habitual (moverse entre líneas)
          (define-key ac-completing-map "\C-n" 'ac-next)
          (define-key ac-completing-map "\C-p" 'ac-previous)


          ;;(setq ac-menu-height 10)
          ;; ac-use-fuzzy t
          (setq ac-fuzzy-cursor-color "blue") ; qué bueno

          ;; poner ayuda a la derecha; con ac-help o ac-persist-help
          (setq ac-quick-help-delay 0.5)
          ;; desactivarlo: (setq ac-quick-help-delay -1)
          ;; pruebas: (setq ac-quick-help-delay 1)
          ;; pruebas: (setq ac-quick-help-delay 0)
          (setq ac-quick-help-prefer-x nil) ; no he probado mucho pero en general no me gusta X

          ;; fuentes
          ;; además se pueden definir fuentes: http://cx4a.org/software/auto-complete/manual.html#Extend


          ;; fuente „diccionario“: meto varias palabras (en lista o en fichero) y las mostrará como candidatas
          ;; ver: http://cx4a.org/software/auto-complete/manual.html#Completion_by_Dictionary
          (add-to-list 'ac-dictionary-directories "~/.emacs.d/dict")
          ;; de momento no lo necesito


          ;; esto lo iré habilitando si es que sigue haciendo falta
          (ignore '(

                    ;;Probar para todos los modos: (setq-default ac-sources '(ac-source-semantic-raw))
                    ;; (default-value 'ac-sources)

                    ;; probando a añadir ac-source-semantic
                    ;; por ejemplo sólo esto:   (setq-default ac-sources '(ac-source-semantic-raw))
                    (defun ac-emacs-lisp-mode-setup ()
                      (setq ac-sources (append
                                        '(
                                          ac-source-features
                                          ac-source-functions
                                          ;; desactivado yasnippet porque ya no lo uso
                                          ;;  ac-source-yasnippet
                                          ac-source-variables ac-source-symbols
                                          ac-source-semantic
                                          ;; ac-source-semantic-raw
                                          ) ac-sources)))

                    

                    ;; Añadir a Python ropemacs; lo hace solo si se carga primer ropemacs y luego auto-complete. Pero si cargo 1º ac y luego ropemacs… Pruebo con esto:
                    (add-hook 'python-mode-hook
                              (lambda ()
                                (add-to-list 'ac-sources 'ac-source-ropemacs)

                                ;; probando sólo       (setq ac-sources (remove 'ac-source-yasnippet ac-sources))
                                ;; Mejor lo activo (con auto-complete >1.3.1 va todo bien)
                                ;; m9.2013: Lo desactivo porque no uso yasnippet
                                ;;        (add-to-list 'ac-sources 'ac-source-yasnippet)
                                ;; Con auto-complete 1.3.1, ac-source-yasnippet me petaba:
                                ;; ac-yasnippet-candidates: Symbol's function definition is void: yas/current-snippet-table
                                ;; Eso es: http://stackoverflow.com/questions/10059893/rope-and-yasnippet-in-emacs
                                ;; Con >1.3.1 no pasa

                                ))
                    ;; Parece que no aporta compleciones (Ej: con M-/ veo más que con tab)
                    ;; me pasa que al darle a TAB no me indenta. Pero esto es por yas pues si lo desactivo ya indenta bien
                    ;; Y puede ser porque: (ac-fallback-command 'ac-trigger-key-command) dice al evaluarse: „tramp-completion-file-name-handler: Variable binding depth exceeds max-specpdl-size“ ← ¿¿eh??
                    ;; Y tiene que ver con:
                    ;; 1.  (ac-fallback-command 'ac-trigger-key-command)
                    ;; 2. ac-trigger-key-command is an interactive compiled Lisp function… It is bound to TAB.
                    ;; Por tanto TAB→TAB→TAB→…
                    ;; mirar: yas-fallback-behavior (sin u, y con -)
                    (setq yas-fallback-behavior 'call-other-command)
                    ;; (setq yas-fallback-behavior nil)
                    ;; (setq yas-fallback-behavior '(apply message . ("hola")))
                    ;; (setq yas-fallback-behavior '(apply ac-complete)) ; ← no
                    ;; (setq yas-fallback-behavior '(apply ac-trigger-key-command)) ; ← *bueno*
                    ;; (setq yas-fallback-behavior '(apply indent-for-tab-command)) ; ← *bueno* aunque ignoro ac(+rope), pero indenta; eso me gusta. ¡Lo malo es que en org también quiere /indentar/! (en vez de contraer)
                    ;; MALFAR: ¿quizás el problema es que ac quiere incluir los yasnippet? O mejor dicho: si ac está incluyendo las plantillas de yasnippet, entonces ¿no debería dejar de llamar a yasnippet al apretar TAB? Probé a quitar yasnippet de ac (con ac en TAB), ahora he de probar a quitar yasnippet del TAB
                    ;; IS: ∴ con auto-complete > 1.3.1 ya no pasa, y TODO va bien junto y en TAB (indentación + yasnippet + rope)
                    ;; 



                    ;; ¡¡cuidado!!! ac-mode es „anything complete“, pero se supone que he desactivado anything. DESACTIVARLO DE VERDAD
                    ;; MALFAR: compleciones en correle (ej. para plantillas; plantillas de correle, claro)
                    ;; m9.2013: lo desactivo porque no uso yasnippet (nunca me ha ido)
                    ;;(add-hook 'wl-draft-mode-hook
                    ;;          (lambda ()
                    ;;        (add-to-list 'ac-sources 'ac-source-yasnippet)
                    ;;))


                    ;; acaba lo de ac
                    ))
          ;; acabo de ignorarlo entero
          ))


;;;; ilumina paréntesis contrario al situarse en uno
(show-paren-mode t)
;; (show-paren-mode -1)

;;(setq show-paren-style 'parenthesis)
;; Con esto se puede hacer que lo que se ilumine sea la expresión contenida. Me va muy bien
(setq show-paren-style 'expression)

;; entonces es muy importante el color de fondo
(set-face-background 'show-paren-match "#146") ;era steelblue3. Lista de opciones probadas:
;; luego „dark slate blue“ (muy brillante)
;; „dark cyan“ aún más;  feísimo
;; „dark blue“ muy ilegible;  no duele tanto pero molesta
;; „bright black“ ← un azul más oscuro que el „dark blue“ (en -nw). Me gusta para -nw pero en X no lo puedo ver (es negro).
;; „SteelBlue4“ bonito pero muy brillante
;; „LightSteelBlue4“ aún más brillante
;; white, ilegible
;; #146 me gusta. Es lo suficientemente fuerte como para notar dónde acaba
;; #035 molesta aún menos pero no es tan bonito
;; #024 es muy invisible y no molesta; PERO es tan flojo que no me queda claro el ámbito de un paréntesis → no lo quiero
;; Es difícil encontrar un valor que vaya en X y en -nw. Para -nw me va bien „bright black“ pero para X algo como drak blue

;; estaría bien también iluminar los «xxx» o „xxx“ pero no sé cómo se hace. Bueno, la verdad es que no hace falta

;; copiado de http://www.emacswiki.org/cgi-bin/wiki/ParenthesisMatching
(defun goto-match-paren (arg)
  "Go to the matching parenthesis if on parenthesis, otherwise insert %.
vi style of % jumping to matching brace."
  (interactive "p")
  (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
        ((looking-at "\\s\)") (forward-char 1) (backward-list 1))
        ;;        (t (self-insert-command (or arg 1)))))
        (t (message "Sólo funciono encima de paréntesis"))))
;; lo asigno a C-% por parecido con el % de vim
(global-set-key [(control %)] 'goto-match-paren)


;;;; no quiero ajustes para novatos, por ejemplo que se ilumine la selección
;; En Emacs23 lo activaron por defecto
(transient-mark-mode -1)

;;;; me muestra las secuencias teclas abajo rápidamente mientras las tecleo
(setq echo-keystrokes 0.1) ; era 1
;; No sé por qué, pero 0 no va; creo que no está implementado. Pero me da igual… No quiero hacer perder tiempo por esto

;;;; ccrypt (abre ficheros cifrados automáticamente)
;; Abre ficheros cifrados, y también comprimidos
;; 26.8.2007: malŝaltata ĉar ĝi malfunkciigas la malfermon de .gz-datumoj
;;(setq load-path (cons "/usr/share/emacs/site-lisp/ccrypt" load-path))
;;(require 'jka-compr-ccrypt "jka-compr-ccrypt.el")

;;;; epa: EasyPG, para abrir ficheros .gpg que se grabarán cifrados automáticamente
;; (epa-file-enable) ya viene activado en Emacs23
;; Ya se puede abrir (C-x C-f) un fichero.gpg
;; Emacs los abrirá también transparentemente. Lo uso en Gnus


;; Nota mía que puse en Wiki:
;; I found the cause for it. The graphical window appears if you run <code>gpg</code> with the <code>--use-agent</code> option. EasyPG adds it (see <code>epg.el</code>) if it sees an environment variable like this one:
;; <code>GPG_AGENT_INFO=/tmp/seahorse-nDQm50/S.gpg-agent:6321:1</code> (check that with the <code>env</code> command).
;; And you have this variable if for instance you have the program <code>seahorse</code> installed and running (which is the case in Ubuntu).
;; If you uninstall Seahorse, the prompt will always be text instead of graphical. You may have to relogin to X to force Seahorse to close.
;; --[[DanielClemente]]
;;

;; Ejemplo de comando bueno
;; /usr/bin/gpg --no-tty --status-fd 1 --yes --enable-progress-filter --command-fd 0 --output /tmp/epg-output14502Fiv --decrypt -- /home/dc/.emacs.d/gnus/imap-authinfo.gpg


;; si no pongo esto, me pregunta 3 veces (1 por cuenta) al abrir IMAP, y 1 más al enviar cada correo
(setq epa-file-cache-passphrase-for-symmetric-encryption t)
;; MALFAR: dicen (la descripción) que no está recomendado. Buscar por qué. Emacs >20.m9.2009 ← ahora ya no hay ni documentación
;; Esto tiene que va también con lo del use-agent; ver arriba

;; Esto no vo y no tiene sentido; me falta el --pinentry y no sé por qué. Supongo que necesito un „gpg“ mejor → ver en „gpg“, es por versión vieja
(setq epg-gpg-program  
      ;;"gpg-agent" ;; tiene --pinentry
      ;; "gpg1" ;; pruebo a afinar para que ẽ wl también me vaya y encuentre mi clave (pues v1 y v2 son incompatibles en esto; ver notas)
      ;; en m11.2019 migré gpg1→gpg2, así que puedo cambiar:
      "gpg2"
      ;;"gpg" ; en Devuan testing me hizo falta así (no gpgv2)
      ;;"gpgv2" ;; es la 2.1 en Devuan („gpg2“ es 2.0), en Devuan testing es 2.1.18
      )

;; Probando:
;;(get 'epg-gpg-program 'saved-value)
;;(get 'epg-gpg-program 'customized-value)
;;(symbol-value 'epg-gpg-program)

;; (put 'epg-gpg-program 'saved-value epg-gpg-program) ; simulo ser el „customize“. Buscar en notas el fallo 24229. Esta línea es mágica y esquivadora
;; (put 'epg-gpg-program 'customized-value epg-gpg-program)  ; probando (pero no hace falta)
;; en vez de esto, lo pongo en custom-set-variables, que creo que hace lo mismo

;; Y además le borro la caché (si no, lo sigue tomando de aquí, y tomaría gpg2)
;; espero que ya no me haga más falta
(ignore '(
          (if (boundp 'epg--configurations)
              (setq epg--configurations  (assq-delete-all 'OpenPGP epg--configurations) )
            )
          ))

;; aparte está esto, que también me ha dado guerra
;; (setq epg-gpgconf-program
;;  "gpgconf" ;; así estaba, así lo encontré
;; )

;; Para desactivar gpgconf… puedo forzarlo así (tras leer código de EPG): (fmakunbound 'pinentry-start)
;; Prueba: (fboundp 'pinentry-start)
;; ¿Deberé hacer permanente esto? Espero un poco al siguiente reinicio

;; Tras este fmakunbound mejora pero vuelve a llamar a gpg2 → ver otra vez notas, donde lo de versiones, „tras fmakunbound“ → era por 24229, ya corregido.

;; Usé esto de pinentry durante un tiempo…
(setq epa-pinentry-mode 'loopback)
;;(setq epa-pinentry-mode 'error)
;;(setq epa-pinentry-mode 'ask)
;;(setq epa-pinentry-mode 'cancel)
;; … pero me fue mejor desactivarlo (así me va con gpg 2.0 también)
;; m11.2017 quitaron pinentry.el
;; m9.2019: se cuelga si lo pongo a nil → pero la solución cuando se cuelga parece ser matar gpg-agent. Es bastante molesto. Ver emacs.org. → parece que loopback va mejor, lo dejaré a loopback
;; (setq epa-pinentry-mode nil)
;; epa→epg
;;(setq epg-pinentry-mode nil)


;; (setq epg-debug nil) ;era nil, no me ayudó a t


;;;; temas de cifrado y de SSL, y GnuTLS/starttls

;; No sé qué es, pero al menos le pongo un directorio que existe (en vez que "~/.w3/certs")
(setq ssl-certificate-directory "~/.emacs.d/datos-w3m/")
;; „Directory to store CA certificates in“. Pues yo siempre lo he visto vacío

(setq ssl-certificate-verification-policy 1) ; era 0 (sin verificar). 1: „verification required“. El 25.m4.2011 descubrí que a 0 me causaba problemas; ver emacs.org lo de elmo-network-initialize-session


;; lo pruebo, pero no veo más datos
;; (setq gnutls-log-level 1)
;; Me empieza a ser útil en 2. ẽ para ghub/forge. Pero quizás debido a esto se cuelga wl al enviar (no cierra el borrador) ← no, parece que esto falla también con 1
;;(setq gnutls-log-level 2)
;; En realidad ponerlo a 1 sí que causa cambios: ahora genera basura inútil tipo „non-fatal error: Resource temporarily unavailable, try again“ (ẽ pasa en eww mucho). No lo quiero, y molesta y no puedo arreglarlo, así que lo bajo a 0 otra vez:
(setq gnutls-log-level 0)

;; :-( A la cuenta de oT de jabber no conecta si pongo el -no_ssl2 en tls-program. 12.3.2009

;; era:
;;(setq tls-program '("gnutls-cli -p %p %h" "gnutls-cli -p %p %h --protocols ssl3" "openssl s_client -connect %h:%p -no_ssl2 -ign_eof"))
;; pruebo otro:
;; Lista de programas a probar *uno tras otro* para hacer conexión mediante función open-tls-stream
(setq tls-program
      '(
        ;; he quitado el gnutls-cli de aquí para forzar a usar sólo openssl. A ver cómo resulta
        ;;"zenity --info --text '%p'; xeyes; openssl s_client -connect %h:%p -no_ssl2 -ign_eof" ; ¡esto va!
        ;;"openssl s_client -connect %h:%p -no_ssl2 -ign_eof"                
        ;;"openssl s_client -connect %h:%p -no_ssl2 -ign_eof -starttls xmpp" ; importante que esté esta opción; *CON ESTO, JABBER VA CIFRADO*, pero sólo si esta línea está al principio. Mas si la pongo al principio, wl conecta a gmail pasándole lo de XMPP y se cuelga ahí. ¡¡¡¡Horror!!!! ¿No puedo instruirle sobre cuándo usar cuál? (ẽ con %P igual que %h/%p pero para protocolo) → ∴ ver abajo el trozo bash
        ;; Por cierto, sería mejor si puedo „probar XMPP → probar SMTP → sin nada“, pero openssl se cuelga al 100% en la primera y no avanza
        ;;"openssl s_client -connect %h:%p -no_ssl2 -ign_eof -starttls smtp"

        ;;"openssl s_client -connect %h:%p -ign_eof"
        ;; ∴ solución genérica que hace que todo vaya: quiero que sea ésta. Parece que está funcionando → con gmail (smtp) va, con xmpp… parece que no del todo
        ;; "P=%p; if false; then zenity --info --text \"$P\"; fi; if [ $P -eq 5222 \]; then EXTRA='-starttls xmpp'; elif [ $P -eq 587 ]; then EXTRA='-starttls smtp'; else EXTRA=''; fi;  openssl s_client -connect %h:%p -no_ssl2 -ign_eof $EXTRA" # parece que funcionará… pero el strace me demuestra que no pasa bien parámetros: „execve("/usr/bin/openssl", ["openssl", "s_client", "-connect", "jabberes.org:5222", "-no_ssl2", "-ign_eof", "-starttls xmpp"], [/* 50 vars */])“ → por eso uso EXTRA1 y EXTRA2
        ;; "P=%p; if false; then zenity --info --text \"$P\"; fi; if [ $P -eq 5222 \]; then EXTRA1='-starttls'; EXTRA2='xmpp'; elif [ $P -eq 587 ]; then EXTRA1='-starttls'; EXTRA2='smtp'; else EXTRA1=''; EXTRA2=''; fi;  strace openssl s_client -connect %h:%p -no_ssl2 -ign_eof $EXTRA1 $EXTRA2 2>/home/dc/n/salida_strace.txt"    ; con strace
        ;;      "P=%p; if false; then zenity --info --text \"$P\"; fi; if [ $P -eq 5222 \]; then EXTRA1='-starttls'; EXTRA2='xmpp'; elif [ $P -eq 587 ]; then EXTRA1='-starttls'; EXTRA2='smtp'; else EXTRA1=''; EXTRA2=''; fi;  openssl s_client -connect %h:%p -no_ssl2 -ign_eof $EXTRA1 $EXTRA2" ; ∴ parece que esto es lo que funciona en todos los casos, y va cifrado

        ;; (más pruebas, en m4.2017, tras dejar de ir emacs-jabber; ver notas):
        ;; "gnutls-cli --x509cafile %t -p %p %h" "gnutls-cli --x509cafile %t -p %p %h --protocols ssl3" "openssl s_client -connect %h:%p -no_ssl2 -ign_eof"
        ;; pero sigue fallando:
        ;;"gnutls-cli --x509cafile %t -p %p %h --starttls" "gnutls-cli --x509cafile %t -p %p %h --protocols ssl3 --starttls" "openssl s_client -connect %h:%p -no_ssl2 -ign_eof"
        ;; "gnutls-cli --x509cafile %t -p %p %h" "gnutls-cli --x509cafile %t -p %p %h --protocols ssl3"
        ;; vi: „s_client: Option unknown option -no_ssl2“
        ;; "gnutls-cli --x509cafile %t -p %p %h --starttls" "gnutls-cli --x509cafile %t -p %p %h --protocols ssl3 --starttls" "openssl s_client -connect %h:%p -ign_eof"
        ;;"openssl s_client -connect %h:%p -ign_eof"
        ;; esto va, pero por lo visto emacs-jabber no lo entiende y se cuelga:       openssl s_client -connect jabberes.org:5222 -ign_eof -starttls xmpp
        ;;"openssl s_client -connect %h:%p -ign_eof -starttls xmpp"
        ;; esto también va pero se cuelga, creo que emacs-jabber no manda nada
        ;;"gnutls-cli --x509cafile /etc/ssl/certs/ca-certificates.crt -p %p %h  --starttls"

        ;; por defecto en m8.2017; da „connection lost: nil“
        "gnutls-cli --x509cafile %t -p %p %h"      "gnutls-cli --x509cafile %t -p %p %h --protocols ssl3"

        ;; en m5.2019 sigo la saga, y pruebo (no sé si ayuda; se cuelga y dice algo del <proceed>); ver notas sobre el „starttls-proto“
        ;; "gnutls-cli --x509cafile %t -p %p %h --starttls-proto=xmpp"
        ;; "gnutls-cli --x509cafile %t -p %p %h --starttls-proto=xmpp --protocols ssl3"
        ;;
        ;; ∴ aaaaaaaah… ¡Corregí el fallo! Ver https://gitlab.com/gnutls/gnutls/issues/766 y notas. Uso mi versión corregida
        ;; "/w/gnutls28-3.6.6/src/gnutls-cli --x509cafile %t -p %p %h --starttls-proto=xmpp"
        ;; en 3.6.7 ya está corregido:
        ;;"/w/gnutls/src/gnutls-cli --x509cafile %t -p %p %h --starttls-proto=xmpp"
        "gnutls-cli --x509cafile %t -p %p %h --starttls-proto=xmpp"

        )
      )


;; ;;;; Problema:
;; veo „The hostname in the certificate does NOT match 'mail.yubay.com'“
;; ;;;; Pruebas:
;;(setq elmo-imap4-default-stream-type 'starttls)

;; (setq starttls-use-gnutls t) ; esto está bien a t y siempre lo ha estado. Dice que se usará gnutls-cli en vez de starttls
;; Estoy probando a cambiar gnutls → starttls ya que gnutls no me gusta mucho (poca seguridad, necesita --insecure, …). Si funcionare sin gnutls me iría mejor. Lo malo es que ¬gnutls==starttls es peor que gnutls
(setq starttls-use-gnutls t)
;;(setq starttls-use-gnutls nil) ; 28.m7.2014: tras ver que gnutls parece no entender respuesta XML de jabberes.org (pues se espera protocolo SSL) decido dejar de usar gnutls
;; Mejor será cambiar a openssl. O sea: ¬starttls, ¬gnutls, sino openssl. Lo haré pero para emacs-jabber sólo

;; ssl-program-arguments '("-p" service host))   ← no sé si cambiar esto serviría de algo
;; ;;;; Para salir del paso
;;(setq starttls-extra-arguments '("--insecure")) ; si pongo esto, ya va… ¡Pero no quiero dejarlo activo!
;; ∴ Solución mejor: seguir proceso explicado en http://groups.google.com/group/gnu.emacs.gnus/browse_thread/thread/fe2ab7facf4a0149
;; MALFAR: pero para el SMTP no me va; se queda colgado y tengo que poner el --insecure temporalmente ← solución: http://lists.gnu.org/archive/html/info-gnus-english/2012-04/msg00001.html (hay que conectarse una vez desde consola con: „gnutls-cli -p 587 -s smtp.gmail.com --tofu“, luego poner HELO, poner „starttls“, C-d y contestar que „y“, entonces queda grabado al estilo known-hosts
(setq starttls-extra-arguments '("--tofu")) ; „tofu“: „Enable trust on first use authentication“
;; hablan de algo nuevo con esto: http://lists.gnu.org/archive/html/emacs-devel/2014-10/threads.html

;; ; Solución final
;; (setq starttls-program  "starttls") ; así lo tengo en ali y me funciona
;; Es este programa:
;; Architecture: i386
;; Version: 0.10-3
;; Depends: libc6 (>= 2.3.5-1), libssl0.9.8 (>= 0.9.8a-1)
;; Description: TLS encryption helper program
;;  This program is necessary to establish STARTTLS connections
;;  from emacs (e.g., an encrypted IMAP session with Gnus).
;;
;; ∴ En ali tenía el programa (me da /usr/share/man/man1/starttls.1.gz, /usr/bin/starttls, …), en 2d2 no. Hay que instalarlo en 2d2 (bajándolo de web de Debian pues en apt-get no está) y entonces va.
;; ¿en qué web de Debian? https://packages.debian.org/sid/starttls lo tiene sólo para m68k

;; Intento usar openssl como si fuera el binario „starttls“
;;(setq starttls-program  "openssl s_client -connect")
;;(setq starttls-extra-arguments '("--starttls"))
;; Mi objetivo es usar openssl para XMPP, pero no sé cómo contarle eso a emacs-jabber…

;; era nil. Lo activo tras https://glyph.twistedmatrix.com/2015/11/editor-malware.html
;; Por lo visto va a usar una BD, creo que /etc/ssl/certs/ca-certificates.crt
(setq tls-checktrust 'ask)

;;;; cosas de mime, en general
;; ¿esto tiene que estar arriba o abajo?. De momento, con esto abajo (tras carga de un montón de cosas de correo) no me fue suficiente.
(setq mime-view-mailcap-files '("~/.mailcap"))

;; estoy cansado de ver ficheros adjuntos como =?ISO-8859-1?Q?20100130=5FN=F2mina_Dani_gener_2010=2Epdf?= (sí, ése es el nombre real con que se graba en disco. Con esto lo soluciono
(setq mime-header-accept-quoted-encoded-words t)

;; pero me sigue pasando, ej:
;; [3 =?ISO-8859-1?Q?Dise=F1os_definitivos_20_Agosto.pdf?= <application/pdf (base64)>]


;;;; Modo servidor
;; Ahora uso siempre Emacs (>22) en modo --daemon, y emacsclient. Ver cdv para notas anteriores
(defun mata-emacsclient () ; otro nombre: kill-emacs-client. Pero mejor en español para saber que esta función es mía
  "Mata al emacsclient actual del servidor, sin preguntar.
Es como C-xC-c pero sin pedir confirmación sobre búfers a grabar o procesos.
Hay que usarlo con cuidado precisamente por eso: se puede salir y puede quedar el demonio solo con búfers por grabar. Tampoco es muy grave."
  (interactive)
  ;; Basado en server-save-buffers-kill-terminal de server.el
  (let ((proc (frame-parameter (selected-frame) 'client)))
    (server-delete-client proc))
  )
(defun mata-este-búfer-y-emacsclient-sin-preguntar ()
  "Pues eso. ¡Usar con mucho cuidado! Tiene sentido para procesos como eshell, etc."
  (interactive)
  (kill-this-buffer)
  (mata-emacsclient)
  )

;;;; las preguntas se responden con y/n
(fset 'yes-or-no-p 'y-or-n-p)

;;;; Pregunta antes de salir, porque a veces aprieto C-x C-c por error
(add-to-list 'kill-emacs-query-functions
             (lambda ()
               (let ((use-dialog-box nil))
                 (y-or-n-p "Ĉu mi fermu Emakson? (j/n): ")
                 )
               ))
;; Aparentemente esto haría lo mismo:
;; (setq confirm-kill-emacs yes-or-no-p)          ; Confirm quit


;;;; ejecutar comandos externos sin liarse
;; con esto me evito el „A command is running - kill it?“ y similar. ¿Cómo?: haciendo que cada comando use un búfer de salida  distinta. A cambio consigo que se me vaya llenando la lista de búfers de un montón inútiles que no uso para nada. Bueno, no debería pasar mucho…
(defadvice shell-command (after shell-in-new-buffer (command &optional output-buffer error-buffer))
  (when (get-buffer "*Async Shell Command*")
    (with-current-buffer "*Async Shell Command*"
      (rename-uniquely))))
(ad-activate 'shell-command)

(setq async-shell-command-buffer 'new-buffer) ; era: confirm-new-buffer, pero no quiero que pregunte tanto

;;;; Nombres de búfers referentes al mismo nombre de fichero usan parte del directorio para desambiguar
(require 'uniquify)
(setq uniquify-buffer-name-style 'post-forward-angle-brackets)
;; Si ¬nil, de „prueba<uno>“ y „prueba<tres>“ al cerrar el 3 pasa a „prueba“ pero el búfer „prueba<uno>“ queda vacío colgando. A mí no me gusta; yo prefiero que se siga llamando „prueba<tres>“ aunque sólo haya uno
(setq uniquify-after-kill-buffer-p nil)
;; Si lo anulaba me petaba de formas raras... Habrá que corregirlo si vuelve a pasar.

;;;; usar un título descriptivo en el gestor de ventanas

;; pruebas:
;;(setq frame-title-format "%b - emacs") ; Use buffer name as frame title
;;(setq frame-title-format "%b%n, %p, %F")
;; sencillo, y por defecto, y lo dejo así:
;;(setq frame-title-format "%b")
;; pruebo esto otro:
;; (setq frame-title-format "E: %b")
(setq frame-title-format "*E* %b")
;; Curioso, se va el "*E* " (y se queda el nombre del fichero) cuando la ventana deja de verse → ∴ reiniciar wmii y ya va como toca. Bueno, casi…

;;;; ido (que ya no lo uso. Se ha ido)
;; hace cómodo el cuadro de cambiar y abrir búfer.
;; 18.7.2008: no lo uso porque intento cambiarlo por Icicles
;;(ido-mode t)
;; ...y otras solicitudes de fichero en minibúfer, aparte del C-x C-f
;;(ido-everywhere 1)
;; 2014: está en emacs
;; Para quitarlo, M-x ido-mode

;;;; permíteme hacer más cosas en el minibúfer
;; Con esto, M-x dentro de un M-x funciona :-)
(setq enable-recursive-minibuffers t)
;; ¿Lo quiero? En general no, pero para el caso puntual en que lo necesito, sí… → activado
;; Si está a nil, da un error y se cancelan ambos minibúfers. Es excesivamente molesto
;; Aunque me iría mejor un mensaje „no va, haz C-u M-x para que vaya“

(minibuffer-depth-indicate-mode 1)

;;;; sistema genérico de compleción ofrecido por Emacs: completion-styles
;; MALFAR no lo uso pues ya tengo helm, que es mejor
;; Quería añadir substring a completion-styles para completar contactos de org-contacts

;;;; Pitidos
;; Que deje de pitar (me gustaría también cambiar el tono)
(setq visible-bell 1)
;;(setq visible-bell nil)
;;(beep)
;;(ding)

(defun pita-de-verdad ()
  "Hace pitido audible, sin depender del cómo estén configuradas beep y ding"
  (interactive)
  (let ((visible-bell nil)) (beep))
  1
  )

(defun pita-de-verdad-pero-flojito ()
  "Hace pitido audible pero agudo y corto. Como no sé cambiar el tono en emacs, uso el programa externo „beep“."
  (interactive)
  (shell-command "beep -f 12000 -l 50")
  )
(defun pita-de-verdad-con-tono-medio ()
  "Se oye en un ambiente algo ruidoso pero es muy cortito"
  (interactive) (shell-command "beep -f 9000 -l 10")
  )
(defun pita-de-verdad-cortito ()
  "El normal en tono, pero más corto"
  (interactive) (shell-command "beep -l 50")
  )

(defun pita-n-tonos-aleatorios (n)
  "Pita n veces, con frecuencia aleatoria (pero duración fija) pero dentro de unos límites razonables"
  ;;"Pita n veces, con frecuencia y duración aleatoria pero dentro de unos límites razonables"

  (shell-command
   (apply 'concat 
          "beep "
          (cl-loop for i from 1 upto n ;5 ;n
                collect (format "%s -l 100 -f %s " (if (= i 1) "" "-n") 

                                ;; normal
                                ;;(+ 50 (random 4000))
                                ;; pero quiero que los números bajos salgan con más probabilidad. Pruebo a superponer dos distribuciones uniformes (voy construyendo yo una curva de probabilidad ◝.
                                ;; (/ (+ (+ 50 (random 4000)) (+ 50 (random 1500))) 2)
                                ;; Y la refuerzo más:
                                (/ (+ (+ 50 (random 4000)) (+ 50 (random 1500)) (+ 50 (random 500)) (+ 50 (random 250)) ) 4)

                                ))
          )
   )
  "Pitado"
  )
;;(pita-n-tonos-aleatorios 2)
;;(pita-n-tonos-aleatorios 10)

;; En realidad quiero que pite para algunas cosas y para otras no
;; Por eso copio esta función de algún lado:
;; Emacs does not beep or flash anymore, on hit C-g in the minibuffer or during  an isearch.
(setq ring-bell-function 
      (lambda ()
        (unless (memq this-command
                      '(isearch-abort abort-recursive-edit 
                                      exit-minibuffer
                                      keyboard-quit))
          (ding))))
;; pruebo:
;; (setq ring-bell-function 'pita-de-verdad)
;; (setq ring-bell-function nil)
;; para desactivar de verdad:
(setq ring-bell-function 'ignore) ; ¡pues parece que va mucho mejor! Parpadea menos; ya me va bien. Y parece que no me he perdido nada
;; Tanto con 'ignore como con nil, el C-g me sigue haciendo cosas raras en helm y en minibúfer (no cierra todo lo que toca)

;; MALFAR: al apretar un rato C-g, ¡me cambia de ventana! occur→.emacs me ha pasado; al revés no. Creo que con el 'ignore, pasará menos

;;;;; Ya de paso: otros chivatos
;; Uso los pitidos de chivato. Pero necesito otros.
;; 
(set 'un-contador-global-para-un-chivato 1)
(defun chivato-que-aumenta-un-contador-global ()
  "Va cambiando un fichero en /home/dc/n/chivato1: pone un número distinto en cada llamada"
  (interactive)
  (shell-command (concat "echo " (number-to-string un-contador-global-para-un-chivato) " >/home/dc/n/chivato1"))
  (setq un-contador-global-para-un-chivato (1+ un-contador-global-para-un-chivato))
  )
;; (chivato-que-aumenta-un-contador-global)
;; Y usa luego: watch -n0 /home/dc/n/chivato1


;;;; Deshacer/Rehacer

;; Evita deshacer cambios de árboles no visibles
(defadvice undo (after org-undo-reveal activate)
  "Make point and context visible after an undo command in Org-mode."
  (and (eq major-mode 'org-mode) 
       ;; (org-reveal) ;; primero que usé. Pero: Aún le falta el que no me cierre los :CLOCK:. Si edito un :CLOCK: por dentro y deshago, se cierra solo y me molesta mucho.
       ;; (org-show-context) ; no ayuda, hace lo mismo que org-reveal
       (show-subtree) ;; ∴ éste no tiene los problemas de org-reveal, pues éste me despliega todos los cajones internos, incluyendo los :CLOCK:. Pero sólo los de la entrada que toca (eso es lo que quiero)
       ))
;; probando:
;;(ad-remove-advice #'undo 'after 'org-undo-reveal)

;;;; tag tables (es lo de etags, ctags, …), no me hace mucha falta y nunca lo uso
;; MALFAR: probar de una vez todo esto para que los comandos que ECB (y otros comandos) funcione bien
;;(setq tags-file-name "~/.emacs.d/tags/TAGS")
;; (setq tags-file-name nil)
;; No planeo usar un solo fichero de etiquetas. En vez de eso, usar visit-tags-table y darle el fichero TAGS

;; de momento uso esto de prueba
;;(setq tags-file-name "~/ptop/eclipse/TAGS")
;; uso esta otra.  Es exclusiva →  (setq tags-file-name nil)
;; desactivo esto pues ya no existe. Por lo visto se usa al hacer ESC .
;;(setq tags-table-list '("~/ptop/eclipse/TAGS"))
;;(setq tags-table-list nil) ; ← me la preguntará
(setq tags-table-list '("~/n/tabla-TAGS-global-noséparaquéseusa"))

;; ¿tengo que cargar esta lista a mano cada vez que arranco?

;; Para crear el fichero TAGS he usado cosas como:
;; : ~/ptop/eclipse ; find  /home/dc/ptop/eclipse/ -print | grep '\.java$' | etags -l java -
;; Para no incluir tantos proyectos, sino sólo los interesantes:
;; : ~ ; cd /home/dc/ptop/eclipse/; find open{ajax,alert,…} xisco-2.0_ext_opentrends/ portal/ ptop_theme -name '*.java' -print | etags -l java -
;; MALFAR poner en un prita para poder llamarlo de vez en cuando
;; MALFAR: probar con exuberant-ctags: comando ctags-exuberant -e -R

;; MALFAR Arrancar ECB para ver cómo lo aprovecha
;; MALFAR Leer las intrucciones de http://www.emacswiki.org/emacs/EmacsTags, en concreto las de M-* 


;;;; Refresco de pantalla (y cantidad de parpadeo y temblores).

;;;;; refresco de pantalla descontrolado. En Gnus tengo un „Summary superrefrescante“

;; m2.2010: aún sufro de demasiado parpadeo de pantalla con Emacs compilado por mí
;; Me parece que el hecho de poner los minutos+segundos en emms-mode-line y actualizarse cada segundo hace que se refresque la pantalla entera continuamente (cada segunda), al menos en búfers como el de artículos de Gnus. Investigar si realmente es de esto (lo parece)
;; MALFAR: ¡¡he de solucionar este parpadeo de la pantalla!! (venga de donde venga). Lo noto mucho en gnus. Instrucciones para reproducir: entrar en grupo (ej. Bazaar) y abrir artículo aún no visto (ej. 2º) para que la pantalla quede partida en dos. Entonces se pone a parpadear continuamente (muchas veces por segundo), sin tocar nada. Sólo es esa ventana; puedo cambiar a otra y la de Summary sigue temblando. Así durante unos 10 segundos. Luego, para cada pulsación de teclas se ve temblar varias veces la de Summary. Pasa también tras (emms-mode-line 0)

;;;;; velocidad de renderización lenta
;; m2.2010: es irritante ver cómo al cambiar de ventana Emacs se va dibujando poco a poco, de arriba abajo, como en una terminal antigua de película. Aún más irritante es ver que cuando ha acabado, una segunda actualización recorre otra vez la pantalla de arriba a abajo. Veo eso cientos de veces al día.
;; MALFAR: ¿quejarme? ¿leer el código? ← mi solución ha sido empezar a usar -nw (modo texto)

;; Dicen que quizás así se solucionan algunos problemas, pero no noto ninguna diferencia al usar esto:
;; Esto parece que es para „caracteres compuestos“, pero no sé qué es
;; ẽ   h̶o̶l̶a̶   ← esto debería salir tachado (4 letras, no 8)
;; ẽ везё́т
(global-auto-composition-mode -1) ; ← curioso, es éste el que hace que combinen „más o menos“ bien
;;(global-auto-composition-mode 1) ; ← con esto hay algunos que combinan mejor

;; y también dicen:
(setq font-lock-verbose nil)
;; aunque no creo que esto diferencie
;; dicen: „It's a variable not a function.  I think it controls how much stuff is written out via (message ...) calls in the implementation of font lock code on your mac version of emacs lisp.  Calls to message are slow and there are lots of them in this implementation.  This is just making it skip these calls.“
;; Pues lo activo el 30.m8.2010, a ver qué pasa.



;;;; lenguaje del calendario
(setq
 ;; calendar-day-name-array ["diumenge" "dilluns" "dimarts" "dimecres" "dijous" "divendres" "dissabte"]
 calendar-day-name-array ["dg" "dll" "dm" "dx" "dj" "dv" "ds"]
 calendar-month-name-array ["gener" "febrer" "març" "abril" "maig" "juny" "juliol" "agost" "setembre" "octubre" "novembre" "desembre"]
 calendar-week-start-day 1
 )

;; en ruso. Pero me es más difícil teclearlo, por eso lo desactivo
;; hay más en http://www.emacswiki.org/emacs/CalendarLocalization
(ignore '(
          (setq calendar-week-start-day 1
                calendar-day-name-array ["Вс" "Пн" "Вт" "Ср" "Чт" "Пт" "Сб"]
                calendar-month-name-array ["Январь" "Февраль" "Март" "Апрель" "Май" 
                                           "Июнь" "Июль" "Август" "Сентябрь"
                                           "Октябрь" "Ноябрь" "Декабрь"])
          ))

;; que me salga marcado el actual. Afecta a org al agendar tarea y me ayuda mucho (si no, muchas veces me pierdo y me pienso que es otro día)
(add-hook 'calendar-today-visible-hook 'calendar-mark-today)
(add-hook 'calendar-today-visible-hook 'calendar-mark-holidays) ; probando

;;;; latitud y longitud de donde estoy
;; Creo que se usa para mostrar horas de eclipses etc.
;; Gavà:
(setq calendar-latitude 41.302)
(setq calendar-longitude 2.003)

;;;; procesos y temporizadores
(defun run-at-time-exceptosiyaexiste (unate tiempo funci)
  "Como run-at-time pero sólo añade reloj si no existe ya"
  (unless (member funci (map 'list (lambda (ti) (nth 5 (append ti nil))) timer-list))
    (run-at-time unate tiempo funci)
    )
  )
;;;; ibuffer, para cambiar de búfers rápidamente
(require 'ibuffer) ; para que defina variables que necesito luego
;; teclas ya definidas arriba

;; ordenar por ruta
;; Solución copiada de: http://www.emacswiki.org/emacs/IbufferMode
(define-ibuffer-sorter path
  "Sort the buffers by their pathname."
  (:description "path (filenames plus dired)")
  (string-lessp 
   (with-current-buffer (car a)
     (or buffer-file-name
         (if (eq major-mode 'dired-mode)
             (expand-file-name dired-directory))
         ;; so that all non pathnames are at the end
         "~"))
   (with-current-buffer (car b)
     (or buffer-file-name
         (if (eq major-mode 'dired-mode)
             (expand-file-name dired-directory))
         ;; so that all non pathnames are at the end
         "~"))))
(define-key ibuffer-mode-map (kbd "s p")     'ibuffer-do-sort-by-path)

;;; Modos y componentes
;;;; Edición y gestión de texto
;;;;; nxhtml: Para HTML, XHTML, SGML, XML, JSP, PHP, CSS, JS, ...

;;;;;; ¿me interesa? No. Cargo sólo lo que me interesa
;; nxhtml es (m12.2010) muy lento, muy lastrado, y me causa bastantes problemas y pocos beneficios (¿ninguno?); desde siempre ha sido molestia.
;; Yo de Emacs sólo quiero que coloree el .html. El mumamo me da igual pues el .js y .css debería llevármelos fuera del .html, …
;; De nxhtml me quedo sólo con php-mode, que mejora un poco ŭ3 el php-mode original. Si no tengo no salen colores

;; (load "~/.emacs.d/nxhtml/related/php-mode.el")
;; o en vez de load directamente, algo más elegante (y sobre todo, más rápido en el arranque):
(add-to-list 'load-path "~/.emacs.d/nxhtml/related")
(autoload 'php-mode "php-mode" "PHP editing mode" t)
(add-to-list 'auto-mode-alist '("\\.php3\\'" . php-mode))
(add-to-list 'auto-mode-alist '("\\.php\\'" . php-mode))


;;(autoload 'jde-maven2 "jde-maven2")
;; y también con smarty-mode, para plantillas de Smarty (PHP)
;;(load "~/.emacs.d/nxhtml/related/smarty-mode.el")
(autoload 'smarty-mode "smarty-mode" "Editar plantillas PHP de Smarty (.tpl)" t)
(setq auto-mode-alist (append '(("\.tpl$" . smarty-mode)) auto-mode-alist))
;; el HTML no queda iluminado, pero eso ya me va bien

;;;;;; MozRepl (para evaluar JavaScript mediante un Conkeror por puerto 4242)
;; nxhtml ya cargó javascript-mozlab.el y moz.el buenos :-)
;; Además configuró javascript-mode para que activare MozREPL:
;; No lo uso mucho
;; C-c C-s abre proceso
;; C-c C-l le manda el búfer actual
;; etc. (ver C-c ...)
;; http://www.emacswiki.org/emacs/MozRepl#toc2

;; ∴ m9.2019: aunque funcionaba, es bastante complejidad para muy poca cosa. No me importa darle a „r“ 1000 veces para recargar en conkeror…

(defun recarga-firefox-remoto ()
  (interactive)
  (comint-send-string (inferior-moz-process)
                      "setTimeout(BrowserReload(), \"1000\");"))
(add-hook 'php-mode-hook (lambda () (define-key php-mode-map [f5] 'recarga-firefox-remoto)))
(add-hook 'js-mode-hook (lambda () (define-key js-mode-map [f5] 'recarga-firefox-remoto)))
(add-hook 'html-mode-hook (lambda () (define-key html-mode-map [f5] 'recarga-firefox-remoto)))
(add-hook 'python-mode-hook (lambda () (define-key python-mode-map [f5] 'recarga-firefox-remoto)))


;; El resto lo ignoro. Lo he probado y estoy muy bien sin nxhtml

(ignore '(
;;;;;; carga

          ;; antes hacía falta cargar nxml (incluído dentro de nxhtml), pero Emacs23 ya lo incluye. Está todo en mi cdv

          ;; ahora el fichero PRINCIPAL:
          (load "~/.emacs.d/nxhtml/autostart.el")
          ;; Es curioso que si esto va después del (require 'ido), entonces ido no se carga bien. Ha de ir antes.
          ;; Creo que este fallo se corrigió entre 1.33 y 1.43
;;;;;; le desactivo unas teclas que quiero para mí: C-c ?
          ;; En realidad le estoy desactivando todo el menú, pero no lo usaba igualmente
          (nxhtml-menu-mode -1)
          ;; Me aportaba éstas, que están bien para HTML pero mal para Emacs ene general. Si quisiere usarlas en HTML, debería activar nxhtml-menu-mode en esa sesión.
          ;; C-c ? c        xhtml-help-show-css-ref
          ;; C-c ? x        nxhtml-short-tag-help

;;;;;; Para poder tocar ajustes de mumamo, antes he de cargarlo
          (require 'mumamo)

;;;;;; Para lo del subrayado en rojo, y otro marcado de errores. Afecta a NXML/NXHTML


          ;; creo que ahora todo esto se hace o complementa con mumamo-margin-info-mode. Investigar


          ;; Con todo esto se consigue que los <script> aparezcan en otro color. A voluntad se puede hacer que el fichero entero (excepto estos <script> también tenga otro color de fondo).

          ;; Si no se hace esto, al abrir ciertos ficheros (ej: JSP) el fondo aparece todo de color.
          ;; submode: así no destaca todo el fichero, sino sólo ciertas zonas
          ;; no-chunks-colored: nada de colores para marcar secciones
          (setq mumamo-chunk-coloring (quote submode))
          ;;(setq mumamo-chunk-coloring (quote no-chunks-colored))

          ;; Así no queda muy molesto e indica el cambio entre secciones
          ;;(set-face-background 'mumamo-background-chunk-submode "#002020") ; VIEJO. #020 es muy verde. Me gusta más algo grisáceo como #002020
          (set-face-background 'mumamo-background-chunk-submode1 "#202020") ; #020 es muy verde. Me gusta más algo grisáceo como #002020; lo malo es que sale azulísimo en -nw y es molesto como fondo. Como se supone que quería gris, pongo #202020, que ya lo veo gris en -nw

          ;; revisaré estos tres colores cuando me los encuentre juntos
          (set-face-background 'mumamo-background-chunk-submode2 "#ff2020") ; #020 es muy verde. Me gusta más algo grisáceo como #002020
          (set-face-background 'mumamo-background-chunk-submode3 "#ff2020") ; #020 es muy verde. Me gusta más algo grisáceo como #002020
          (set-face-background 'mumamo-background-chunk-submode4 "#ff2020") ; #020 es muy verde. Me gusta más algo grisáceo como #002020

          ;;(set-face-background 'mumamo-background-chunk-major "midnight blue etc.") ; el modo mayor
          ;; y esto es un puntero a faz
          ;;(setq mumamo-background-chunk-major 'default) ; ninguna faz especial para el modo mayor. No va pues default está definiendo un color de primer plano :-( Sustituto:
          (setq mumamo-background-chunk-major 'mumamo-background-chunk-major)
          (set-face-background 'mumamo-background-chunk-major nil) ; ya le va bien el fondo negro

          ;; Preferiría estos colores:
          ;; El fichero NO con fondo azul, sino negro. Los <script> con fondo verde clarito. El cuerpo bien iluminado. El <script> también iluminado. Tanto en páginas sencillas como no.


          ;; Pruebo a quitarle lo de que me subraya en rojo. Dicen que hay fallo „with overlays in Emacs 22“ que enrojece más de la cuenta
          ;;(nxhtml-toggle-visible-warnings) ; debería dar: nil
          ;; no va.


;;;;;; error: invalid function mumamo-save-buffer-state

          ;; Al entrar en .jsp me decía (17.10.2008) que:
          ;;Debugger entered--Lisp error: (error "Invalid function: mumamo-save-buffer-state")
          ;;  signal(error ("Invalid function: mumamo-save-buffer-state"))
          ;;  error("%s" "Invalid function: mumamo-save-buffer-state")
          ;;  byte-code("............." [orig-buff act-on-choice icicle-try-switch-buffer error "%s" error-message-string] 4)
          ;;  icicle-find-file()
          ;; Útil:
          ;;    normal-mode uses condition-case around the call to the major mode function, so errors are caught and reported as a
          ;;    `File mode specification error', followed by the original error message.
          ;; MALFAR. Si esto me vuelve a pasar, mirar: https://answers.launchpad.net/nxhtml/+question/42407
          ;;
          ;; mumamo-save-buffer-state está definida aquí:
          ;;.emacs.d/nxhtml/util/mumamo.el:(defmacro mumamo-save-buffer-state (varlist &rest body)
          ;; El problema es que no es una función sino una macro, y no se puede por ejemplo usar funcall en una macro
          ;;
          ;;ELISP> (defmacro pedoo (a b c) "des" (beep))
          ;;pedoo
          ;;ELISP> (funcall 'pedoo)
          ;;*** Eval error ***  Invalid function: pedoo

          ;; por ahora, la solución es en mumamo.el:
          ;; -*- no-byte-compile: t -*-
          ;; ^por 142857, para solucionar esto:
          ;; ;Debugger entered--Lisp error: (error "Invalid function: mumamo-save-buffer-state")
          ;; 27.10.2008
          ;;
          ;; y ya no pasa este error
          ;;

;;;;;; error raro: symbol's function definition is void: <

          ;;  nxhtml me fallaba con: (no sé por qué)
          ;; and: Symbol's function definition is void: <

;;;;;; error de nxhtml con 'jde-run-applet-document
          ;; 28.10.2008; pasa con últimas versiones. MALFAR

          ;; 
          ;; mumamo-idle-set-major-mode: cb=edit_configuration.jsp, err=(wrong-type-argument listp jde-run-applet-document)
          ;; MuMaMo error, please look in the *Message* buffer
          ;; MuMaMo error, please look in the *Message* buffer
          ;; mumamo-set-major-pre-command: Wrong type argument: listp, jde-run-applet-document
          ;; ** In buffer edit_configuration.jsp
          ;;   backtrace()
          ;;   (let ((standard-output standard-output)) (backtrace))
          ;;   (let ((standard-output ...)) (let (...) (backtrace)) (with-current-buffer standard-output (prog1 ... ...)))
          ;;   (with-output-to-string (backtrace))
          ;;   (let ((format-string2 ...) (bt ...)) (mumamo-message-with-face (concat ... "
          ;; " ... bt) (quote highlight)) (apply (quote message) format-string2 lwarn-type args) (run-with-idle-timer 1 nil (quote mumamo-show-report-message)) (when mumamo-display-error-stop (setq font-lock-mode nil) (when ... ...) (when ... ...) (apply ... format-string2 lwarn-type args)))
          ;;   mumamo-display-error(mumamo-set-major-pre-command "%s" "Wrong type argument: listp, jde-run-applet-document")
          ;;   (condition-case err (let* (... ... ...) (if ... ... ...)) (error (mumamo-display-error ... "%s" ...)))
          ;;   (if (not mumamo-use-condition-case) (let* (... ...) (let* ... ...)) (condition-case err (let* ... ...) (error ...)))
          ;;   (mumamo-condition-case err (let* (... ... ...) (if ... ... ...)) (error (mumamo-display-error ... "%s" ...)))
          ;;   mumamo-set-major-pre-command()
          ;;   run-hooks(pre-command-hook)
          ;; 
          ;; mumamo-set-major-pre-command: Wrong type argument: listp, jde-run-applet-document
          ;; Mark set [2 times]
          ;; MuMaMo error, please look in the *Message* buffer
          ;; 
          ;; 
          ;;
          ;; Curioso, pero existe jde-run-applet-doc (¡no document!)
          ;;jde-run-applet-doc is a variable defined in `/home/dc/.emacs.d/jde-2.3.5.1/lisp/jde-run.el'.
          ;;Its value is ""
          ;;

          ;; El error real lo descubrí más tarde al ver esto:
          ;;Debugger entered--Lisp error: (wrong-type-argument listp jde-run-applet-document)
          ;;  car(jde-run-applet-document)
          ;;  (memq (car local) mumamo-buffer-locals-dont-set)


          ;; Es problema de:
          ;; (buffer-local-variables)
          ;; cuando se ejecuta mientras se ve una JSP:
          ;; 
          ;;  (jit-lock-after-change-extend-region-functions font-lock-extend-jit-lock-region-after-change t)
          ;;  (change-major-mode-hook mumamo-change-major-function t)
          ;;  (jde-project-name . "default")
          ;;  jde-run-applet-document
          ;;  (jde-buffer-project-file . "")
          ;;  (post-command-hook mumamo-post-command jde-detect-java-buffer-activation t)
          ;;  (tags-table-format-functions jde-etags-recognize-tags-table etags-recognize-tags-table tags-recognize-empty-tags-table)
          ;; 

          ;;Pero es que la docu dice:
          ;;For a symbol that is locally unbound, just the symbol appears in the value.
          ;;
          ;; Así que pruebo:
          (setq jde-run-applet-document nil)
          ;; Por ver si esto funciona (y deja de fallar toda JSP)


;;;;;; error con turn-on-font-lock-if-enabled
          ;; básicamente: no existía, pero /jde-java-font-lock.el la usaba (exclusivamente)
          ;; Yo la activo...
          (defun turn-on-font-lock-if-enabled nil (turn-on-font-lock))

;;;;;; error con nxml-ensure-scan-up-to-date. 29.10.2008

          ;; (wrong-type-argument markerp 1)

          ;; esto ya falla:
          ;;(nxml-ensure-scan-up-to-date)


          ;; Dos problemas:
          ;; 1. si nxml-scan-end es nil, esto falla:
          ;;(defun nxml-ensure-scan-up-to-date ()
          ;;  (let ((pos (point)))
          ;;    (when (< nxml-scan-end pos)
          ;;      (save-excursion
          ;;
          ;; 2. si es un número (ej: 1), esto falla: (final de función anterior)
          ;;      (set-marker nxml-scan-end pos))))))
          ;;Debugger entered--Lisp error: (wrong-type-argument markerp 1)
          ;;  set-marker(1 7383)
          ;; ¿Quizás se han dejado un '? O el tipo no es el correcto

;;;;;; fin de ignore
          ))
;;;;; mmm-mode, para varios modos mayores; parecido a mumamo
;; Quizás útil para ẽ jinja

;;;;; más cosas para edición de webs; modos sueltos
;; Para vue.js mientras lo pruebo. Tras instalarlo por ELPA:
(add-to-list 'auto-mode-alist '("\\.vue$" . vue-html-mode))

;;;;; org-mode
;;;;;; carga básica

;; ¿Módulos? Por reactivar si me hacen falta. Poco a poco
;; (setq org-modules '(org-bbdb org-bibtex org-info org-irc org-w3m org-choose))


;; Aaaaaaaaaah cuidado, esta llamada a (org-release) que yo hacía para ver „qué versión de org tengo cargada antes de cargar la mía“ tiene una consecuencia muy mala: me carga la versión vieja de org (que yo no quiero). Es mucho mejor no hacer esta llamada a (org-release)
;; (message "Versión de org, según org-release: %s" (org-release))

;; uso el de Emacs-CVS; por tanto no necesito cargarlo de ~/.emacs.d/
;; pero con esto cargo el de desarrollo (ultimísima versión):
(add-to-list 'load-path "/w/org-mode/lisp") ; ya no: (require 'org-install)
;; (add-to-list 'load-path "/w/org-mode/contrib/lisp") ; para otros como org-choose
;; m5.2021: cambió
(add-to-list 'load-path "/w/org-contrib/lisp") ; para otros como org-choose

;; Precarga de org-mode al empezar, junto con sus requisitos. Al menos es lo que intento
;;(require 'vc) (require 'vc-svn)
(require 'org)

(message "Versión de org (tras require 'org), según org-release: %s" (org-release))

;; Por lo visto algunas cosas necesitan ciertos paquetes. Creo que no debería pasar, pero no me importa cargarlos a mano
(require 'org-macs) ; para org-string-nw-p (para remember)
(require 'org-table) ; para org-table-set-constants

;; Para poder correr juegos de prueba
(add-to-list 'load-path "/w/org-mode/testing/")
(require 'org-test)
;; Usar: (con: org-test-run-all-tests)
;; o mejor, con:
(defun org-test-run-all-tests--pero-sin-pararse nil "" (interactive) (let ((org-confirm-babel-evaluate nil)) (org-test-run-all-tests)))

;;;;;; configuraciones de tareas y sintaxis
;;;;;;; configuraciones básicas (teclas globales, ...)
;; Esto es para toda versión
(add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
(define-key global-map "\C-cl" 'org-store-link)
(define-key global-map "\C-ca" 'org-agenda)

(setq org-startup-truncated nil) ; ¡que org no me toque el truncado de líneas!

;; un segundo C-a me lleva al principio del texto de la cabecera
(setq org-special-ctrl-a/e 'reversed)
;; C-e a veces es muy lento porque org-element intenta regenerar una caché o algo así; debe de ser un problema temporal

(setq org-support-shift-select t) ; en principio nil, pero sí que me interesa poder seleccionar cosas (¡y además usar Shift+flechas para las cosas especiales de org!)
;;;;;;; le desactivo cosas intentando que vaya más rápido.

;; No necesito ver los menús (F10). Con „profiler-“ veo que esto me ahorra unos 10 Mb de memoria
(defun org-install-agenda-files-menu () 
  ;; (message "No ejecuto org-install-agenda-files-menu")
  nil
  )

;; Creo que no afecta
;; (defun org-check-agenda-file (file) 
;; ;; (message "No ejecuto org-check-agenda-file")
;; nil
;; )


;; Veo que es una gran parte del esfuerzo al abrir un fichero. En m6.2015, con perfilador „profiler-report“ vi que de un 57% gastado en (org-mode), un 43% era de (org-set-startup-visibility). Así que lo desactivo
(setq org-inhibit-startup-visibility-stuff t) ;; era nil. Compruebo que a t me funciona todo mucho más rápido

;;
;; org-refresh-effort-properties tampoco me gusta (consume bastante CPU al abrir), y me gustaría desactivarla.
;; Parece que añade „propiedades“ (de texto) a las zonas que tienen un esfuerzo asignado. Ej:
;; There are text properties here:
;;  effort               "3:00"
;;  effort-minutes       180
;;
;; Añadida en m4.2014 por Bastien, sin explicpaciones.
;;
;; No lo necesito y podría quitarlo…
;; 27.m6.2015: Pruebo a quitarlo, y nada se estropea (en m5.2017 sigue bien todo). Lo dejo quitado. Me va mucho más rápido así
;; Ya lo tengo en org-agenda-ignore-properties, así que no me la va a llamar. ¿Sin embargo la llama? (ẽ al cambiar la estimación)
;; Se llama muchas veces, parece que al cerrar cronómetros o al empezarlos también
(defun org-refresh-effort-properties () 
  (message "No ejecuto org-refresh-effort-properties")
  nil
  )

;; org-id-update-id-locations es excesivamente lento (>10min) excepto si está activo esto:
(setq org-element-use-cache t)  ; era nil
;;  Pero ya me estoy cansando de que montones de cosas vayan mucho más lentas con caché que sin. Y de los errores y quejas continuas de org-element. Y de org-persist bloqueando y ralentizando cosas como la salida de emacs. Y de latencia de ~400 ms al apretar cada letra al teclear en org de >3'5 Mb. Así que probaré a desactivar org-element, a ver qué pasa
;; (setq org-element-use-cache nil)  ; probando
;; Aaaaaaay… Sin caché, el abrir ficheros y moverse y teclear va MUCHO más rápido (qué irónico), pero la agenda va más lenta
;; Hay problemas graves en org-mode debido a org-element, la caché, y org-persist. Hay aún bastante trabajo a hacer. Entiendo que es muy difícil

;; probando
(setq org-element--cache-self-verify 'backtrace)
;; Creo que todo esto es lo de org-persist

;; Para ajustar cómo funciona la caché. No debería hacer falta todo esto. Viene mal implementada, y habría que corregir eso


;; Esto era 0.6 segundos
;; org-element-cache-sync-idle-time

;; Era 0.04 ¿segundos?
;; org-element-cache-sync-duration

;; Era 0.3 segundos
;; org-element-cache-sync-break

;; Era 0.03, supongo que esto significa un 3%
;; org-element--cache-self-verify-frequency
;; Pero veo muy chapucero el tener que bajar esto para acelerar org-mode. Es un parche. No soluciona el problema, pero hace que se vea menos. De vez en cuando aún se ve. Habrá que corregirlo en algún momento
;; Aaaaaaaah, mensaje de Ihor:
;;
;;     For some context, self-verify staff will only be enabled during pretest. It is an equivalent of ./configure --enable-checking in Emacs. We do it, because we absolutely need to catch all issues with org-element cache ASAP, before the code goes into Emacs release.
;;     […] What about setting org-element--cache-self-verify to nil? That's what we will do once we finish the test.

;; 
;; Alternatively, you can reduce the value of
;; org-element--cache-self-verify-frequency. By default, 5% of all the
;; cache queries are double-checked, which is expensive in your use case.
;;

;;
;; Me parece poco segura esta forma de probar el código, pues esto tendría que probarse mediante juegos de prueba, no en los ordenadores de la gente. Pero entiendo que las cachés son muy difíciles de programar y de probar
;; Pruebo así. Sí, esto acelera todo, hasta las tablas
(setq org-element--cache-self-verify-frequency 0.001)

;; Era nil
;;(setq org-element--cache-diagnostics nil)
;; (setq org-element--cache-diagnostics t)
;; ésta era 2
;; org-element--cache-diagnostics-level

;; Ésta es para trazar org-element-cache-map
;; Era nil
;; (setq org-element--cache-map-statistics t)
;; (setq org-element--cache-map-statistics nil)


;; Esto parece ser de org-persist
;; Me da mucho asco todo esto. Las cosas más importantes (abrir/cerrar emacs, teclear) van mucho más rápido sin caché que con esta implementación de caché. Toda esta implementación ha añadido mucha burocracia y molestias.
;; Esto, en concreto, muchas veces me impide cerrar Emacs (porque falla al salir), o lo ralentiza muchos segundos (¿para qué? Ni lo dice, ni lo noto ni aprecio). Lo desactivo
(setq org-element-cache-persistent nil)  ;; era t
;;;;;;; configuración de listas
;; En m9.2010 hay un sistema nuevo de listas que las deja con más indentación. Ver inda.org para ambas opciones
;; Tengo que reconocer que el nuevo sistema, aunque presenta un cambio rompedor, se lee mejor y hace que quede más claro.
;; Por tanto cambio de opinión y en vez de desactivarlo, lo dejaré y empezaré a usarlo.

;;;;;;; configuración de palabras clave

;; esto permite la selección rápida con p.ej. „C-u C-c C-t i“
(setq org-todo-keywords
      '(
        ;; Si lees esto en HTML y te preguntas qué quieren decir estos estados… Mira un poco por https://danielclemente.com/hacer/org.html
        (sequence "FARU(f)" "BONUS(b)" "ATENDAS(a)" "|" "IS(i)" "MALFAR(m)")
        ;; Éstos ya no los uso pero estaban en pruebas viejas:
        (sequence "TODO(t)" "|" "DONE(d)")
        ;; Por lo visto el orden no importa mucho para la agenda. Si quiero otro orden, ver: org-agenda-sorting-strategy

        ;; ésto es para org-choose:
        ;; #+CHOOSE_TODO: REJECTED(r) NOT_CHOSEN(n,-) MAYBE(,0) LEANING_TOWARDS(l) CHOSEN(c,+) 
        ;;   (sequence "RECHAZADO(r)" "ÉSTE_NO(n,-)" "QUIZÁS(,0)" "PROBABLE(p)" "ELEGIDO(e,+)")
        ;; Necesito un palabraro mejor para decisiones que represente los estados intermedios acertando, no quedando cerca. He pensado en:
        ;; NO CASI_QUE_NO PUEDE PROBABLE DECIDIDO
        ;; DESCARTADO MALO PUEDE BUENO ELEGIDO
        ;; y pruebo otro; 4.m5.2010
        ;; ;; (sequence "DESCARTADO(r)" "MALO(n,-)" "PUEDE(p,0)" "BUENO(s)" "ELEGIDO(e,+)")
        ;; problema: PUEDE y BUENO son igual de largos ← poca información visual
        ;; soluciones: DESCARTAT LLEIG POTSER BO ESCOLLIT
        ;;             DESCARTADO MALO PUEDE ¡BUENO! ¡ELEGIDO!
        ;;   (sequence "DESCARTADO(r)" "MALO(n,-)" "PUEDE(p,0)" "¡BUENO!(s)" "¡ELEGIDO!(e,+)") ; ← org lo pone pero no lo lee bien
        ;; 26.m5.2010: veo que no me hace falta DESCARTADO pues no es lo opuesto de ELEGIDO (pues no lleva el signo -) y lo puedo expresar con MALFAR (he tenido dudas al elegir entre poner MALFAR y poner DESCARTADO: son lo mismo)
        (sequence "MALO(n,-)" "PUEDE(p,0)" "BUENO(s)" "ELEGIDO(e,+)")

        ;; BONUS: comprobar que esos signos están bien puestos y que org-choose los coge bien

        ) )

(setq org-todo-repeat-to-state "ATENDAS") ; al intentar cerrar uno con repetición se pone éste



;;;;;;; configuración de marcas textuales (resaltado, código, borrado, ...)
;; le pongo <strong> y <em>:
(setq org-emphasis-alist
      '(
        ("*" bold "<strong>" "</strong>") ; era b
        ("/" italic "<em>" "</em>") ; era i
        ("_" underline "<span style=\"text-decoration:underline;\">" "</span>")
        ("=" org-code "<code>" "</code>" verbatim)
        ("~" org-verbatim "<code>" "</code>" verbatim)
        ("+" (:strike-through t) "<del>" "</del>")
        )
      )
;; y nueva variable en org 8:
(setq org-html-text-markup-alist
      '((bold . "<strong>%s</strong>")
        (code . "<code>%s</code>")
        (italic . "<em>%s</em>")
        (strike-through . "<del>%s</del>")
        (underline . "<span class=\"underline\">%s</span>")
        (verbatim . "<code>%s</code>")))


;; faces que antes eran grises y no se veían
(set-face-foreground 'org-verbatim "#3b3")
(set-face-background 'org-verbatim "black")
(set-face-underline 'org-verbatim nil)
(set-face-background 'org-code "#222") ; #141 era un poco ilegible. Mmm… pero hasta #010 es un fondo muy verde en -nw. Algo como #222 es mucho mejor en ambos y también se aprecia un poquito verde
(set-face-foreground 'org-code "#1f1")
(set-face-underline 'org-code nil)
;; más abajo le defino otras

;;;;;;; configuración de radios (los < < < algo > > >)
;; el 27.m5.2015 en trasc: 5:30 cargar toda mi agenda con radios, 0:55 sin.
;; en 27.m6.2015 en trasc tras optimizaciones: „profiler“ dice que un ~96% del tiempo de (org-mode) se gastó en org-update-radio-target-regexp. En efecto, si lo desactivo, lo que antes era un ~~~96% de algo ahora es un ~3%
;; Si lo desactivo, ¡pierdo la posibilidad de ver y seguir enlaces radio! ∴ Por ahora no me sale a cuenta. Lo que iría bien es hacerlo asíncrono… o rápido
;; BONUS informar o org, protestar. O mandar mi parche para nuevo parámetro, ver abajo
;; En m11.2016 reactivo el desactive pues nunca lo he usado durante meses, y porque al exportar se queja de „expregu demasiado grande“. Parece que gracias a esto emacs abre todos mis .org en 20'5s (hace unos meses eran >6 minutos…)
;; (ignore '(
(defun org-update-radio-target-regexp ()
  (setq org-target-link-regexp nil) ; borrar abusos anteriores
  (message "No haré org-update-radio-target-regexp pues es lentísimo; me pierdo los subrayados azules en radios y la posibilidad de seguir enlaces radio.")
  nil
  )
;;))
;; Me invento en nuevo parámetro, y modifico org.el. Esto me obliga a actualizar manualmente yo los <<<…, poniéndome en uno y haciendo C-c C-c. Lo prefiero
;; En pruebas. Si va bien, mandarlo a org.
(setq org-inhibit-startup-radio-refresh t)
;; El parche es en org.el:
;;     ;; Initialize radio targets.
;;     (unless org-inhibit-startup-radio-refresh (org-update-radio-target-regexp))
;; y un defvar arriba junto a otros


;;;;;;; configuración de marcas de tiempo (fecha y hora)

;; Esto sólo funciona si hay un #+STARTUP: customtime o si se configura globalmente
;; En realidad no lo uso.
;; La alternativa que uso es: activarlo sólo al exportar, mediante:
;; #+BIND: org-time-stamp-custom-formats ("<%d.m%m.%Y>" . "<%d.m%m.%Y %H:%M>")
;; #+BIND: org-display-custom-times t
;; (usado en opc_publicar.org)
;;
;; El que me gusta:
(setq org-time-stamp-custom-formats '("<%d.m%m.%Y>" . "<%d.m%m.%Y %H:%M>"))
;; el mismo pero con el nombre del día
;; (setq org-time-stamp-custom-formats '("<%d.m%m.%Y %a>" . "<%d.m%m.%Y %a %H:%M>"))
;; Uno más tradicional:
;;(setq org-time-stamp-custom-formats '("<%d-%m-%Y>" . "<%d-%m-%Y %H:%M>"))


;;;;;;; configuración de bloques (ejemplos, citas, …)
(setq org-src-fontify-natively t) ; quiero ver los trozos de código de colores sin tener que hacer C-c '
;; me va bien

;; IS: comprobar que queda bien en todos lados
;;(set-face-background 'org-block-background (if (window-system)  "#222200" "color-80")) ; color-80 es gris oscuro
;; Desactivo lo de color-80 porque: „Unable to load color "color-80"“ ← al menos desde X, cuando org-babel procesa fragmentos (creo)
;;(set-face-background 'org-block-background "#222200")
;; y pongo #111100 porque 222200 es un poco feo
;;(set-face-background 'org-block-background "#111100") ; 29.m7.2014: va bien, pero lo han quitado porque es lento y problemático


;; plantillas para expandir bloques
;; en m11.2017 lo quitaron, no sé por qué
;; Nicolas Goaziou: „I suggested the idea to remove "<s". The idea behind this remove is that many other template systems, e.g., YASnippet, already provides this. I didn't want to re-implement the wheel and let, instead, various parts of Emacs cooperate.“
;; restaurarlo: https://github.com/kaushalmodi/.emacs.d/commit/9aa3be89a2f8dce3f2aa57f98e0a2f38fdca4c6b
;; ∴ lo pasé a yasnippet. No he probado aún el nuevo sistema de org. Por lo visto permite envolver unas líneas hacia dentro de un bloque.

;;;;;;; configuración de elipsis

;; Cuando una sección está contraída (Título...) quiero que los „...“ aparezcan remarcados para darme cuenta de que contienen mucha información. Le asigno una fez (esto lo implementó Carsten en org-mode 5.07 a petición mía).
(setq org-ellipsis (quote org-column))


;; Una solución más cutre...
;; (setq org-ellipsis "〖〜SIGUE〜〗")

;; otros caracteres que están bien:
;; lápiz: ✎
;; (setq org-ellipsis "〖 ✎ 〗") ; no queda mal

;; Otra forma más rebuscada: Gran super-hack de Tassilo Horn como respuesta a una pregunta mía el 26.8.2007 en emacs-orgmode@gnu.org
;; Making fold markers ("...")  more visible
;; (defface elipsis-de-org-mode
;;   '((default :background "lightgrey")
;;     (((supports :underline "red")) :underline "red"))
;;   "Face used for fold markers like ...")
;; (unless standard-display-table
;;   (setq standard-display-table (make-display-table)))
;; (set-display-table-slot standard-display-table 'selective-display
;;                         (vconcat (mapcar
;;                                   (lambda (c)
;;                                     (make-glyph-code c 'elipsis-de-org-mode))
;;                                   "...")))
;; 



;;;;;;; configuración de cambios de estado

;; Al cerrar tarea, da la opción a escribir una nota (ésta incluye la hora)
(setq org-log-done 'note)
;;(setq org-log-into-drawer "CAMBIOS") ; para probarlo
;;(setq org-log-into-drawer nil) ; habitual

(setq org-log-note-headings  '((done . "CONCLUSIÓN escrita el %t") (state . "State %-12s %t") (clock-out . "")))
;; Me falla siempre:
;; Error in post-command-hook (org-add-log-note): (wrong-type-argument stringp nil)
;; ¿me falla por org-log-note-headings? No lo parece:
(ignore '(
          (setq org-log-note-headings ; restauro original
                '((done . "CLOSING NOTE %t")
                  (state . "State %-12s from %-12S %t")
                  (note . "Note taken on %t")
                  (reschedule . "Rescheduled from %S on %t")
                  (delschedule . "Not scheduled, was %S on %t")
                  (redeadline . "New deadline from %S on %t")
                  (deldeadline . "Removed deadline, was %S on %t")
                  (refile . "Refiled on %t")
                  (clock-out . ""))
                )
          ))


(setq org-use-fast-todo-selection t) ; siempre me va bien C-c C-t LETRA
;; Tal como está, C-c C-t: autom.  C-u C-c C-t: manual
;; Problemita: muchas veces hago C-c C-t y no sale automático, y eso que está a t.
;; Es por esto; se activa cuando no toca:
;;        In all cases, the special interface is only used if access keys have actually been assigned by the user, i.e. if keywords in the configuration are followed by a letter in parenthesis, like TODO(t).
;; Y pasa por ejemplo cuando he puesto arriba: #+SEQ_TODO: HACER ENVIAR ESPERAR | CORREGIDO HECHO
;; o peor aún: cuando he puesto: # +SEQ_TODO: HACER ENVIAR ESPERAR | CORREGIDO HECHO
;; (lo acepta)


;; No se puede cerrar una tarea que tenga hijos abiertos
(setq org-enforce-todo-dependencies t)
;; Aunque esto no me interesa especialmente, me interesa la 2ª cosa que ofrece: la propiedad ORDERED (conmutable por C-c C-x o) impide cerrar una tarea con hermanos menores abiertos. C-u C-u C-u C-c C-t la puede cerrar igual
;; Estas tareas „bloqueadas“ salen en gris en la agenda
;; Lo mismo para casillas:
(setq org-enforce-checkbox-dependencies t)
;; esto no lo noto mucho, pero tampoco molesta; lo dejo

;; Non-nil means TODO statistics covers just direct children.
;; When nil, all entries in the subtree are considered.
(setq org-hierarchical-todo-statistics nil) ; incluir todo en estadísticass
;; Me gusta más así

;;;;;;; configuración de enlaces
;; los enlaces interwiki se abren en el mismo sitio, para no desfigurar la configuración de ventanas. Entiendo que a veces va bien poder ver el sitio antiguo y el nuevo a la vez, pero en general es peor la confusión que esa visión doblada

;; (require 'assoc) ; para aput    ← quitado de Emacs en junio de 2022, en 17b3f8d56e254f8f0478ce583451f02e6034ed48 
;; (aput 'org-link-frame-setup 'file #'find-file)
;; Creo que sin aput se hace así:
;; (set-alist 'org-link-frame-setup 'file #'find-file)
;; Vaya, también han quitado set-alist
;; (setf (cdr (rassoc 'file org-link-frame-setup)) #'find-file)
;;
;; Esto es confuso pero funciona
(setf (alist-get 'file org-link-frame-setup) #'find-file)
;; Parece que va de: „You can use ‘alist-get’ in "place expressions"; i.e., as a generalized variable.“
;; Es algo así como: el alist-get devuelve la variable por referencia (no por valor), y el setf la cambia. Pero no está bien explicado en la documentación

;; MALFAR estaría bien una forma de abrir en otra ventana, algo como C-u C-x C-o, o darle con el botón central del ratón

(setq org-url-hexify-p nil) ; quizás no quedan URLs estándar, pero lo prefiero; se leen bien

(setq org-return-follows-link t) ; Ahora que tengo tantos, me va bien

;; atajo para añadir los signos de etiqueta global (<<<aaa>>>), me va muy bien
(defun pon-etiqueta-global-en-org (beginning end)
  "Pone <<<…>>> rodeando la región"
  (interactive "r")
  (if (= (line-number-at-pos beginning) (line-number-at-pos end))
      (progn
        (goto-char end) (insert ">>>")
        (goto-char beginning) (insert "<<<")
        (goto-char (+ end 6))
        )
    (message "La región es de más de 1 línea → peligro, mejor no hago nada"))
  )
(define-key org-mode-map (kbd "C-<") 'pon-etiqueta-global-en-org)

;; crear siempre IDs… si no tiene ya, y sólo si estoy lllamando directamente (no desde capture)
;; (setq org-link-to-org-use-id 'create-if-interactive-and-no-custom-id) ; por lo visto nombre desfasado
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) ; nuevo nombre m2.2017

;;;;;;; configuración de etiquetas
;; ¿Las etiquetas se heredan?
;; Pues de momento veo semánticamente correcto que sí, aunque en realidad lo necesito muy muy poco y siempre lo descativo
;;
;; Veo dos opciones:
;; - decir que no 
;; - decir que sí pero poner org-tags-match-list-sublevels a nil para ver sólo los encuentros directos
;; 28.m11.2010: lo desactivaré, pues nunca lo he necesitado (más bien al contrario)
(setq org-use-tag-inheritance nil)
;; Para propiedades: ver org-use-property-inheritance
(setq org-agenda-use-tag-inheritance nil) ; era '(todo search timeline agenda), pero dicen que a nil va mucho más rápido

;;;;;;; configuración de „categorías“

;; Iconos en agenda. Lo pruebo un tiempo → no me gusta porque quedan de diferente tamaño
;; Pruebo más pequeños… y del mismo tamaño… Pruebo a generar otros mejores, con esto:
"
gm convert -geometry 20x20 xc:black -fill '#eded00' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_fútil.png
gm convert -geometry 20x20 xc:black -fill 'green' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_idiomas.png
gm convert -geometry 20x20 xc:black -fill '#2740ff' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_descanso.png
gm convert -geometry 20x20 xc:black -fill 'white' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_empresa.png
gm convert -geometry 20x20 xc:black -fill '#bd6600' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_paraotros.png
gm convert -geometry 20x20 xc:black -fill '#00ebeb' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_aprendizaje.png
gm convert -geometry 20x20 xc:black -fill '#dd0000' -draw 'circle 10,10 15,15' ~/wiki/docu/bolita_g_miweb.png
"

;; org-agenda-category-icon-alist → ver privado-nocable.el


;;;;;; sobre el esquemador (estructurado)
;;;;;;; faces para el esquemado de org
;; el de nivel 2 salía en negrita y es molesto (aunque se veía bastante)
;; (set-face-attribute 'outline-2 nil :weight 'normal :foreground "#eee" :inherit nil)
;; En X: Creo que ya se distingue bien del texto normal. Si no, puedo poner negrita pero oscuro
;; Pero: como en -nw no lo veo diferente al texto normal, prefiero ponerlo negrita pero más flojo. Se ve fuerte en nw y X, y no molesta ni brilla mucho
;; (set-face-attribute 'outline-2 nil :weight 'bold :foreground "#ccc" :inherit nil)
(set-face-attribute 'outline-2 nil :weight 'normal :foreground "#eee" :inherit nil) ; como no uso -nw ya, repongo ¬negrita
(set-face-attribute 'outline-3 nil :foreground "#0ff" :inherit nil)

;; esto está en pruebas. Pruebo a colorear las cabeceras para detectarlas también si miro el centro o la parte de la derecha de la pantalla
;; ¡Qué bonito! ¿Cómo no se me había ocurrido antes?
;;(ignore '(
(progn

  (set-face-attribute 'org-level-1 nil :background "#014") ; #026 bien
  (set-face-attribute 'org-level-2 nil :background "#111") ; eee
  (set-face-attribute 'org-level-3 nil :background "#001515") ; 0ff
  (set-face-attribute 'org-level-4 nil :background "#1f0800") ; ff1a00
  ;; etc.

  )
;;))
;; Y me hace falta algo para contrarrestarlo y que no aplique en modo texto. Por ahora guarreo esto para ejecutarlo a mano:
(ignore '(
          (set-face-attribute 'org-level-1 nil :background nil)
          (set-face-attribute 'org-level-2 nil :background nil)
          (set-face-attribute 'org-level-3 nil :background nil)
          (set-face-attribute 'org-level-4 nil :background nil)
          ))


;; y faces para las prioridades de cada sección
(setq org-priority-faces '(
                           (?A (
                                ;;:weight 'bold :foreground "cyan"
                                :box '(:line-width 1 :color "dark red" ; :style released-button
                                                   )
                                ;;:height 1
                                ))
                           (?B (
                                ;;:foreground "cyan"
                                :box '(:line-width 1 :color "dark red"; :style released-button
                                                   )
                                :height 0.7

                                ))
                           (?C (
                                ;;:foreground "cyan"
                                :box '(:line-width 1 :color "dark red"; :style released-button
                                                   )
                                :height 0.4
                                ))
                           ))


;; Como he cambiado esto, el modo de columnas no irá bien pues aplica los estilos de la cabecera a toda la línea. Creo que es fallo de org, pero lo puedo esquivar yo restaurando lo normal (¬caja, tamaño estándar) en org-column
;; (set-face-attribute 'org-column nil :box nil :height 168) ; 168: normal
(set-face-attribute 'org-column nil :box nil)
;; mmm… ya que estoy, lo hago más pequeño. Siempre va bien
;; (Tras varios meses): Cambio de opinión: mejor no meterme con estas cosas pues fallan, luego me salen cosas aparentemente iguales a otras pero que ocupan menos espacio
;;(set-face-attribute 'org-column nil :box nil :height 142)
;;(set-face-attribute 'org-column-title nil :height 142) ; lo mismo que arriba
(set-face-attribute 'org-column-title nil :height (face-attribute 'org-column :height)) ; al menos pongo el mismo en título que en texto; así cuadran las columnas
;; → Si quiero cambiar tamaños, hacerlo con C-x C-- (es fácil)

;;;;;;; estructurado („outline“) en otros modos (como en éste, emacs-lisp)

;; se puede usar outline-minor-mode
;; El 16.10.2008 empecé a usarlo para mi .emacs
(add-hook 'outline-minor-mode-hook
          (lambda ()
            (define-key outline-minor-mode-map (kbd "<C-tab>") 'org-cycle)
            (define-key outline-minor-mode-map (kbd "5") 'org-cycle) ; versión para emacs -nw
            (define-key outline-minor-mode-map (kbd "<backtab>") 'org-global-cycle) ; en -nw recibo <backtab> al apretar S-Tab y C-S-Tab. Me interesa C-S-Tab para org-global-cycle; con esto me pierdo S-Tab pero no me importa mucho pues no lo uso. Estaría bien poner 6 pero no me va
            (define-key outline-minor-mode-map (kbd "<C-S-iso-lefttab>") 'org-global-cycle)))
(add-hook 'outline-mode-hook
          (lambda ()
            (define-key outline-mode-map (kbd "<C-tab>") 'org-cycle)
            (define-key outline-mode-map (kbd "<C-S-iso-lefttab>") 'org-global-cycle)))

;; eso sí, las cabeceras empiezan por ;;;, luego sigue ;;;;, ;;;;;, ...[
;; Ya va bien, así queda ; y ;; para comentarios

;;;;;;; hideshow (hs-minor-mode), otro tipo de estructurado estilo org pero para cualquier modo

(setq hs-global-activado nil)
(make-variable-buffer-local 'hs-global-activado)
(defun hs-global-toggle-hiding ()
  ;; ésta es de mi cosecha; la podría mandar a wiki o tronco. Pero es fea
  "Toggle hiding/showing of all blocks.
See `hs-hide-all' and `hs-show-all'."
  (interactive)
  (hs-life-goes-on
   (if hs-global-activado ;(hs-already-hidden-p)
       (hs-hide-all)
     (hs-show-all))
   (setq hs-global-activado (not hs-global-activado))
   ))

;; creo que esto me salió solo, sin tener que configurar nada. Quizás era otro modo…
(defun display-code-line-counts (ov)
  (when (eq 'code (overlay-get ov 'hs))
    (overlay-put ov 'display
                 (format "⋯〖〜%d〜〗"
                         (count-lines (overlay-start ov)
                                      (overlay-end ov))))))

(setq hs-set-up-overlay 'display-code-line-counts)

(add-hook 'hs-minor-mode-hook
          (lambda ()
            (define-key hs-minor-mode-map (kbd "<C-tab>") 'hs-toggle-hiding)
            (define-key hs-minor-mode-map (kbd "5") 'hs-toggle-hiding) ; versión para emacs -nw
            (define-key hs-minor-mode-map (kbd "<backtab>") 'hs-global-toggle-hiding)
            (define-key hs-minor-mode-map (kbd "<C-S-iso-lefttab>") 'hs-global-toggle-hiding)))

;; adaptar su funcionamiento a algunos modos; no lo activa aún

(add-to-list 'hs-special-modes-alist
             ;;'(sgml-mode
             '(nxml-mode
               "<!--\\|<[^/>]*[^/]>"                    ;; regexp for start block
               "-->\\|</[^/>]*[^/]>"                    ;; regexp for end block

               "<!--"                                   ;; regexp for comment start. (need this??)
               ;; sgml-skip-tag-forward
               nxml-forward-element
               nil))

;; para editar plantillas de Django
(add-to-list 'hs-special-modes-alist
             '(html-mode
               "{% comment %}"                    ;; regexp for start block
               "{% endcomment %}"                    ;; regexp for end block

               "<!--"                                   ;; regexp for comment start. (need this??)
               ;;forward-line
               nil
               nil)
             )
;; para pruebas vaciarla antes: (setq 'hs-special-modes-alist nil)



;; añadir a varios modos
(add-hook 'perl-mode-hook       'hs-minor-mode)
(add-hook 'python-mode-hook       'hs-minor-mode)
(add-hook 'emacs-lisp-mode-hook       'hs-minor-mode)

;; etc.

;; MALFAR: controlar lo del cierre de ramas internas (if, else, for, …), no sólo de funciones de primer nivel

;;;;;;; estructurado: org-fold. Desde m5.2022
;; Ya está a 'text-properties (en vez de 'overlays). Lo probaré un tiempo. Parece que va bien
;; Dice que se puede mirar org-fold-core--optimise-for-huge-buffers; me iría bien para probar el todo.org de 75 Mb

;; Parece que eso impide editar enlaces a mano. Por mirar org-catch-invisible-edits

;;;;;;; estructurado: movimiento de nodos (recolocación)
;; esto es para org-refile
;; Es para enviar una entrada a cualquier lado. Es C-c C-w. No lo uso porque no me es útil.
(setq org-refile-use-outline-path t)

;; creo que por usar icicles, me va mejor esto a nil (estaba a t)
(setq org-outline-path-complete-in-steps nil)

;; si no, sólo muestra cabeceras de nivel 1 del fichero actual
(setq org-refile-targets '((org-agenda-files . (:maxlevel . 2))
                           (nil . (:maxlevel . 3))))


(setq org-adapt-indentation t)
;; Probando mientras lucho contra Nicolas Goaziou:
;;(setq org-adapt-indentation nil)
;; Pero quiero valores nuevos

;;;;;;; estructurado: gestión de secciones embebidas (org-inlinetask)
;; fantástico; está desde el 30.3.2009. Siempre lo había querido
(require 'org-inlinetask)
;; y luego usar secciones de nivel 15 o más

(setq org-inlinetask-export nil) ; al exportar, no pongas el título, sólo el contenido
(setq org-inlinetask-show-first-star t)

;;;;;;; estructurado: moverse a la cabecera actual

;; IS: acostumbrarme a usar C-c C-p, pues es justo lo que quiero
;; Bernt me dijo en lista que se hace con C-c C-p. Yo quería asociarlo a C-c C-h, pero me daba problemas debido al C-h que aún hacíá cosas de aydua.

;;;;;;; estructurado: movimiento MUY rápido entre secciones
;; ~ „org-speed-commands“
(setq org-use-speed-commands t)

;; me gustaría quitar algunos, como „k“, que mata mucho. Es org-cut-subtree
(defun org-cut-subtree ()
(message "He desactivado esta función. Era para quitar una sección entera. Ahora no hace/hago nada")
)

;; org-goto-interface ahora es 'outline
;; C-c C-j
;; Es algo lento.

;; podría añadirle uno „E“ (ahora org-inc-effort), para exportar la cabecera actual. 

;;;;;;; ver cuán grande es cada sección
;;;;;;;; con org-wc, es rápido; cuenta palabras (no es lo más entendible)
;; Deseo muy antiguo; ver emacs.org
(add-to-list 'load-path "~/.emacs.d/org-wc")
(autoload 'org-wc "org-wc" nil t)
;;(require 'org-wc)
(define-key org-mode-map "\C-c\C-xw" 'org-wc-display)
;; me pide región, eso no me gusta mucho

;; Malo: está contando :PROPERTIES: etc. como palabras
;; Además no va en todas las cabeceras


;;;;;;;; con org-weights, algo lento pero más sofisticado
;; ¿Dónde vive? https://github.com/pinard/org-weights
;; En 2023 veo que es de 2013
(add-to-list 'load-path "/w/org-weights")
(autoload 'org-weights-mode "org-weights" nil t)
(define-key org-mode-map "\C-c\C-xw" 'org-weights-mode)

;;;;;;;; contar número de cabeceras hijas
;; org-count o algo así tendría que haber
;; No sé si hay. No encontré
;; quizás org-element
;;;;;;; filtrar dentro de un árbol y crear así otro árbol de resultados („sparse tree“)
;; C-c F me hace árbol filtrado por „FARU“; lo uso mucho. El atajo estaba libre
(define-key org-mode-map (kbd "C-c F") (lambda nil (interactive) (org-show-todo-tree "FARU")))

;;;;;;; no estropear el contenido de un árbol sin darme cuenta
(setq org-catch-invisible-edits 'error) ; era nil.
;;;;;;; enlazar y buscar retroenlaces (en:backlinks)
(defun org-busca-retroenlaces--que-por-cierto-en-inglés-son-llamados-backlinks----ay-ay-ay--espero-que-este-nombre-de-función-no-quede-demasiado-largo…___de-momento-parece-que-lo-acepta…____¡qué-bueno-que-es-emacs! ()
  "Mostrar retroenlaces a la cabecera actual (o al primer padre con ID)."
  (interactive)
  (org-search-view nil (org-entry-get nil "ID" t))
  )

;;;;;; agenda y citas
;;;;;;; agenda separada por bloques, ẽ „comida“, „poco importante“, …
;; ver y hacer lo de https://github.com/alphapapa/org-super-agenda

;;;;;;; „sticky agenda“
(setq org-agenda-sticky t) ; desde m4.2012. ¡Muy rápido! Un poco lioso
(defun org-toggle-sticky-agenda (a) (message "Me han llamado a la org-toggle-sticky-agenda falsa. No pasa nada mientras luego funcione todo.")) ; debido a fallo de 17.m4.2012

;;;;;;; agenda: configuración de ficheros agendados
;; Delegado todo a fichero aparte pues me hace falta reusarlo
(load-file "~/.org-ficheros-agenda.el")

;;;;;;; agenda: pequeños ajustes de visualización

;; La agenda (C-c a a w) no empieza mostrando el lunes, sino el día actual al principio
(setq org-agenda-start-on-weekday nil)

;; En vez de mostrarme agenda semanal, que es muy larga y no me aclaro, coge menos días
;; Dice que ha de ser 1 ó 7, pero yo quiero 3. Así es más rápida la vista
;; Parece que no va, pues „C-c a a“ me muestra 7
;; (setq org-agenda-span 3)
;; m5.2021 lo reduzco 3→1 porque la información de „hace 3 días“ o „en 3 días“ suele estar ya envejecida. Si quiero la agenda de otro día, moverme a esa día
(setq org-agenda-span 1)

;; yo realmente acabo mi día a las 3:00 (más que a las 0:00), pero los cambios que esto trae no me acaban de gustar del todo
;; (setq org-extend-today-until 3)
;; (setq org-extend-today-until 0)

;; org-agenda-date y org-agenda-date-weekend se definen abajo

;; Entre día y día pon una barrita. Ajusta también la forma de decir el día actual
;; Antes era: Monday     17 May 2010 W20
;; Yo prefiero algo como: lunes 17/05/10 (semana 20, mayo)

;; Esto lo da:
;;(setq org-agenda-format-date "%A %x (semana %W, %B)
;;===========================================")

;; Pero prefiero añadir nombres a los días:
(defun org-agenda-format-date--con-mi-comentario (fecha)
  "Dependiendo del día de la semana pone un nombre mío al día. Ver en „tema del día“"
  ;; ej: Пт 28.m7.2017 (setmana 142857, Июль) «miso»

  ;; fecha: „a calendar-style date list like (month day year).“
  ;; pero necesito „(high low), as returned by current-time“

  ;; (format (format-time-string "%A %x (semana %W, %B) «%%s»
  ;; ==========================================="
  ;; (encode-time 0 0 0 (nth 1 fecha) (nth 0 fecha) (nth 2 fecha)))
  ;; ;fecha)
  ;; "prueba")

  (format "\n%s %i.m%i.%i (setmana %i, %s) «%s»
==========================================="
          (calendar-day-name fecha) (nth 1 fecha) (nth 0 fecha) (nth 2 fecha) 142857 (calendar-month-name (nth 0 fecha))
          ;;"pruebita"
          (nth (calendar-day-of-week fecha) '("ripoze"  "retpaĝe" "agendon" "retpoŝte" "FARU [#A]" "miso" "lingvoj"))
          )

  )
;; Desactivo porque no me hace falta y porque este comentario no me ayuda en nada; los días para mí no tienen tema asignado; y si deben tenerlo ha de ser mediante otro sistema (estricto)
;;(setq org-agenda-format-date #'org-agenda-format-date--con-mi-comentario)
;;
;; El por defecto me muestra „Пн         31 Июль 2017 W31“ que ya es suficiente para mí
;; El por defecto es org-agenda-format-date-aligned
;; (setq org-agenda-format-date 'org-agenda-format-date-aligned)

;; ¿Y si sólo quiero un salto de línea entre días?
(defun org-agenda-format-date-aligned--con-línea-preterior (fecha)
  "Da la fecho normal pero le añade una línea en blanco al principio. Bueno, y un espacio"
  (concat " \n" (org-agenda-format-date-aligned fecha))
)
(setq org-agenda-format-date 'org-agenda-format-date-aligned--con-línea-preterior)


;; se ve mucho mejor así, parece una especie de tabla
(add-hook 'org-agenda-mode-hook 
          (lambda () (setq truncate-lines t)))


;; cómo se ve cada línea
;; m8.2018 pruebo a desactivarlo porque org-compile-prefix-format se queja
(ignore '(
          (setq org-agenda-prefix-format
                '(
                  ;; No se me ocurre nada más útil
                  ;;(agenda . " %i %-8e %?-12t%-12s [%-18:c]%l")
                  ;;(agenda . " %i %-12:c%?-12t% s") ; con icono
                  (agenda . " + %-12.12:c%?-12t% s")
                  (timeline . "  % s")
                  (todo . " %i %-12:c")
                  (tags . " %i %-12:c")
                  (search . " %i %-12:c")
                  ))
          ))
;; una vez vi que el %t me mostraba unicodes raros → ver emacs.org


(setq org-agenda-dim-blocked-tasks nil) ;era t pero t la hace lenta (~1 segundo en mi caso)
(setq org-agenda-inhibit-startup t) ; ATENDAS: dicen que esto acelera la carga pero que no abre los ficheros .org con todos sus parámetros; supongo que eso me va bien. Comprobar

;; y mi propiedad que acelera bastante, ej. (- 13.5 11.8), la agenda normal. Me pierdo cosas pero que no uso
;; (setq org-agenda-ignore-drawer-properties '(effort appt category)) ;; viejo
(setq org-agenda-ignore-properties '(effort appt category))

;; los valores por defecto me van bien
(setq org-agenda-skip-scheduled-if-done nil)
(setq org-agenda-skip-deadline-if-done nil)

(setq org-agenda-skip-additional-timestamps-same-entry nil) ; no me gusta que pierda información

;; Evita repetidos → t…  Pero mejor no: Los repetidos me van bien en general; pues no quiero perder la información de hora asignada sólo porque se me ha pasado. O sea: tengo una tarea para ayer agendada para hoy a las 17:00, y quiero ver la hora 17:00 en mi agenda.
;;(setq org-agenda-skip-scheduled-if-deadline-is-shown nil)
;; Pensándolo mejor, ese caso es extraño y sí que me gustaría evitar repetidos. Quiero que la „cantidad de líneas“ ←→ „cantidad de trabajo“
(setq org-agenda-skip-scheduled-if-deadline-is-shown t)

;; Orden de los elementos dentro de la agenda (org-agenda-sorting-strategy)
;; original (que me encontré el 13.m9.2010 y que sigue en 24.m9.2022); lo dejo reactivable:
(ignore (setq org-agenda-sorting-strategy
              '((agenda habit-down time-up priority-down category-keep)
                (todo priority-down category-keep)
                (tags priority-down category-keep)
                (search category-keep))
              ))

;; Mis criterios:
;; - hábitos primero, para que no se me pasen. ¡Pero tengo que definir todo lo repetitivo como hábito! Así veré si me paso. ← no me gusta mucho esto de los hábitos primero, pues al final acabo viendo siempre lo mismo y me pongo demasiadas cosas como hábito → los he de bajar
;; - me interesan bastante los ATENDAS agendados para hoy, pues suelen indicar comunicación externa, y no me interesa despistarme olvidándome de eso ← ¡no! Para comunicación externa, usaré :cita:. Un ATENDAS es simplemente algo que no puedo hacer cuando yo quiera sino sólo a partir de una fecha
;; - primero FARU, luego BONUS. Y las tareas hechas, al final
;;  - lo malo es que entonces los que no tienen estado quedan al final. Bueno, está bien. Al menos quedan juntos
;; - ¿cómo hago que las citas (de calendario) queden al principio? No son FARU, no son BONUS, no son ATENDAS, … pero no las quiero al final. Por eso las marco con :cita: y me hago una función de comparación que las deja al principio de la agenda. Obviamente tendré que marcar con etiqueta „cita“ toda cita imperdible.
;; - creo que me interesa más la prioridad que la fecha (o retraso) de las cosas ← probando
;; - m3.2020: no estoy muy contento con este orden ni con la agenda de org. Me gestiona muchas tareas pero no son exactamente las que necesito o las que ocupan mi día. Tengo ya otros sistemas para intentar recolectar todas las tareas (incluyendo 100% de las de org, y más) y asignarles otro orden más sensato. Ej. tfn (taskfontonura)
(setq org-agenda-sorting-strategy
      '((agenda deadline-up user-defined-up habit-up time-up priority-down todo-state-up timestamp-up category-keep)
        (todo priority-down category-keep)
        (tags priority-down category-keep)
        (search category-keep))
      )

(defun orden-en-agenda-favorito-para-mí (a b)
  ;;(debug)
  "Primero lo de este equipo, y citas." ; Ya no: primero „ATENDAS“
  (setq etiqueta-correspondiente-a-este-equipo
        (concat ":ĉe_"
                (replace-regexp-in-string "\\\(\\..*\\\)" "" (system-name)) ; hasta el primer punto
                ":"))
  (cond
   ((string-match etiqueta-correspondiente-a-este-equipo a) -1) ; a prioritaria
   ((string-match etiqueta-correspondiente-a-este-equipo b) 1) ; b prioritaria
   ((string-match ":cita:" a) -1 ) ;a es cita, por tanto va antes
   ((string-match ":cita:" b) 1 ) ;b es cita, por tanto va antes
   ;;((string-match " ATENDAS " a) -1 ) ;a es „ATENDAS“, por tanto va antes
   ;;((string-match " ATENDAS " b) 1 ) ;b es „ATENDAS“, por tanto va antes
   (t nil) ; a←→b
   )
  )
(setq org-agenda-cmp-user-defined #'orden-en-agenda-favorito-para-mí)




;; más información sobre cuánto tiempo ya he gastado
;; Se accede con R desde la agenda
(setq org-agenda-start-with-clockreport-mode nil)
;; pues no; no lo uso nunca porque no lo entiendo; tampoco me hace falta. En nil carga más rápido
;;(setq org-agenda-start-with-clockreport-mode t)

;; Otro tipo de información, bonito pero no lo quiero siempre:
;;(setq org-agenda-start-with-log-mode 'clockcheck)

(setq org-agenda-clockreport-parameter-plist
      '(:link t
              ;; para que muestre más niveles:
              :maxlevel 4
              ;; para que diga el tanto por ciento de tiempo gastado por fichero:
              :formula %
              ;; prueba, se puede poner cualquier línea de #+TBLFM: de abajo
              ;;:formula "$1=2"

              ;; Que no me muestre los ficheros en los que he trabajado un 0%, pues son mayoría
              :fileskip0 t

              ;; destacar ciertas cabeceras: no, me hace una cursiva rara
              ;; :emphasize t
              )
      )
;; esto me puede servir para vista de repaso semanal → ver ahí

;; mostrar rayitas de tiempo. Lo tenía a t, pero nunca lo he considerado buena representación del tiempo (prefiero mi cronometrados_org), y me crea un hueco grande. Yo ya me hago una idea viendo una lista de nº de hora, así que no me hace falta. En m8.2017 empiezo a necesitarlo más
;; (setq org-agenda-use-time-grid nil)
(setq org-agenda-use-time-grid t)


;;unue: (setq org-agenda-window-setup 'reorganize-frame)
;; pero eso llama a org-agenda-fit-window-to-buffer, que en general es rápido (0'05 segundos) pero alguna vez me ha sido muy lento (3'4s)
;; Por tanto para evitar la lentitud (y porque ya me va bien) cambio:
(setq org-agenda-window-setup 'current-window)

;; para que „C-a a … q“ no me pierda las ventanas
(setq org-agenda-restore-windows-after-quit t)

;; que me muestre la ruta de cada elemento apuntado
;; BONUS: me está fallando un poco con esto:
;; (  org-format-outline-path '("Projectes encara per començar i altres idees" "Plataforma de geoposicionament de flotes, per inspectors" "parts del projecte" "REC: receptor de posicions enviades pel seguidors que les guardi al servidor" "d'alguna manera s'han de rebre i guardar els nous punts al servidor" "arquitectures possibles (per gravar)") 140 nil)
;; pues me da una cadena más larga que ese 140 que le he pasado
;; sí, 6 elementos
;; 303
;; 140-6 = 134
;; 134/6 = 22
;; me da: #("Projectes encara per../Plataforma de geopos../parts del projecte/REC: receptor de pos../d'alguna manera s'ha../arquitectures possibles (per gravar)" 0 22 (face org-level-1) 23 45 (face org-level-2) 46 64 (face org-level-3) 65 87 (face org-level-4) 88 110 (face org-level-5) 111 147 (face org-level-6))
;; „Projectes encara per“=20. +„..“=22. Bé.
;; Problema: l'últim no s'està abreujant!
;; El error está en cambiar maxwidth para el último. Le da 303-112=191 en vez del 22 que tenía antes
;;       (if (and (= n nsteps) (< maxwidth 10000))
;;           (setq maxwidth (- total-width total)))
;; Es de commit 63fb485e

;; repito la función sólo para corregir eso. Mejor así
(defun org-format-outline-path (path &optional width prefix separator)
  "Format the outline path PATH for display.
Width is the maximum number of characters that is available.
Prefix is a prefix to be included in the returned string,
such as the file name."
  (setq width (or width 79))
  (if prefix (setq width (- width (length prefix))))
  (if (not path)
      (or prefix "")
    (let* ((nsteps (length path))
           (total-width (+ nsteps (apply '+ (mapcar 'length path))))
           (maxwidth (if (<= total-width width)
                         10000  ;; everything fits
                       ;; we need to shorten the level headings
                       (/ (- width nsteps) nsteps)))
           (org-odd-levels-only nil)
           (n 0)
           (total (1+ (length prefix))))
      (setq maxwidth (max maxwidth 10))
      (concat prefix
              (mapconcat
               (lambda (h)
                 (setq n (1+ n))
                 ;; dclemente: quitadas estas dos líneas para que me abrevie también el último
                 ;;      (if (and (= n nsteps) (< maxwidth 10000))
                 ;;          (setq maxwidth (- total-width total)))
                 (if (< (length h) maxwidth)
                     (progn (setq total (+ total (length h) 1)) h)
                   (setq h (substring h 0 (- maxwidth 2))
                         total (+ total maxwidth 1))
                   (if (string-match "[ \t]+\\'" h)
                       (setq h (substring h 0 (match-beginning 0))))
                   (setq h (concat  h "..")))
                 (org-add-props h nil 'face
                                (nth (% (1- n) org-n-level-faces)
                                     org-level-faces))
                 h)
               path (or separator "/"))))))

;; Cosas raras con una versión muy cortita ← parece que ya va
;; „Ĵonglado.org/Laboro ĵongla/Spektakloj+konvencioj+labore../<<<EJC>>>/EJC 2011 (Münich), de <2010-..“
;; (org-format-outline-path '("First" "This is the second level of the tree, with a very long text" "Third level" "Fourth level here") 100 nil)
;; (org-format-outline-path '("First" "This is the second level of the tree, with a very long text" "Third" "Fourth") 100 nil)

;; de todas maneras temporalmente lo desactivo (no para poder ir más rápido, sino porque *no me hace falta* porque los nombres ya son claros):
(setq org-agenda-show-outline-path nil)
;;(setq org-agenda-show-outline-path t)


;;;;;;; agenda: definición de búsquedas personales

;; Así és cómodo para aprender y practicar:
;; M-x customize-variable RET org-agenda-custom-commands RET
;; Pero las pongo a mano para escribirlas mejor y con comentarios
(setq org-agenda-custom-commands
      '(
        ;;JA NO: ("o" "FARU de openTrends: tareas importantes" todo "FARU" ((org-agenda-files '("~/org/openTrends.org"))))
        ;;("f" "FARU de Lòvic: úniques tasques importants" todo "FARU" ((org-agenda-files '("~/org/lòvic.org"))))

        ;; Intentaré minimizar esta lista. Y evitar meter todo como „FARU“, sino más como „BONUS“
        ;; Dejo los „FARU“ #C, pues al fin y al cabo son „FARU“s, y si no los quiero ver los pondría como „BONUS“
        ;; He de recordar: „FARU“: obligación fuerte (el no hacerlo me causará estrés). „BONUS“: „estaría bien hacerlo/saberlo“
        ;; ∴ desactivo esto pues ya tengo muy pocos „FARU“

        ;; ("F" "Sólo FARUs personales: lo que no puedo dejar sin hacer. #A, #B y #C. Excluye lo publicado en web" todo "FARU" (
        ;; (org-agenda-files (list-difference org-agenda-files componentes-agenda--repoweb-hacer) )
        ;; ))


        ;; ∴ desactivo pues nunca lo he usado; no me agendo fechas para lo de mi web
        ;; ("w" "Sólo tareas de web" agenda "" (
        ;; (org-agenda-files  componentes-agenda--repoweb-hacer )
        ;; ))


        ;; ~~~~ No puedo dejarla a 0, pero si pasa de 20 debería acelerigar cosas
        ("A" "ATENDAS de todos lados, incluyendo web" todo "ATENDAS"
         (
          ))

        ("B" "ATENDAS de dentro de la agenda. Suelen ser cosas repetitivas o hábitos" agenda "ATENDAS"
         (
          (org-agenda-skip-function (lambda () (org-agenda-skip-entry-if 'nottodo '("ATENDAS"))  ))
          ))

        ;; BONUS: excluir atrasados
        ("d" "Intradía, da sólo lo importante para hoy. Excluye BONUS." agenda ""
         (
          (org-agenda-overriding-header "Lo importante para hoy. ¡No sobrecargarla!")
          ;; Saltarme „BONUS“:
          ;;(org-agenda-files (list-difference org-agenda-files componentes-agenda--repoweb-hacer) )
          ;;(org-todo-keywords-for-agenda '("FARU" "TODO" "HACER" "ENVIAR" "ESPERAR"))
          ;;(org-todo-keywords '( (sequence "FARU(f)""ATENDAS(a)" )))
          ;;(org-agenda-skip-regexp "BONUS")
          (org-agenda-skip-function (lambda () (ignore '(nil (org-end-of-subtree t))) (org-agenda-skip-entry-if 'todo '("BONUS" "IS" "MALFAR"))  ))
          ))


        ;; No me gusta mucho esta vista, porque la visualización en forma de tabla es mala. Quiero gráfico de sectores con subsectores
        ;; Sobre esto, ver „revisión semanal“
        ("S" "Revisión semanal. β. Con tabla de horas debajo, que dice cuánto he trabajado por día" agenda ""
         (
          ;; ya no hace falta; ¡que salgan todos!  (org-agenda-files org-agenda--con-laboral)
          (org-agenda-start-on-weekday 1)
          (org-agenda-span 7) ; se supone que es semanal. BONUS: asegurarse de que sale la semana *actual*, de lunes a domingo (no ẽ de jueves a jueves)

          ;; Lo de las columnas no me ayuda (no lo entiendo)
          ;;  (org-agenda-view-columns-initially t)
          ;; En cambio la tabla de abajo sí
          (org-agenda-start-with-clockreport-mode t)
          ;; Parece que truncate-lines no va, pero org-startup-truncated sí
          ;;  (truncate-lines t)
          (org-startup-truncated t)

          )
         )

        ("l" "Laboreja, con clock-report, para ver en qué he trabajado en el día (ẽ opencraft)" agenda ""
         (
          (org-agenda-overriding-header "Esto es para ir pasándolo a Tempo")
          ;;  (org-agenda-start-on-weekday 1)
          ;; Me aclaro mucho más con 1 día, y yendo 1 a 1 me va más rápido
          ;; no me está haciendo caso a esto, me muestra 7 → org-agenda-ndays cambió de nombre a org-agenda-span
          ;; (org-agenda-span 2)
          (org-agenda-span 1)

          ;; lo pruebo de vez en cuando pero no me ayuda del todo, y es lento
          ;;(org-agenda-start-with-clockreport-mode t)

          (org-agenda-start-with-log-mode t)
          (org-startup-truncated t)
          )
         )

        ;; Más sobre esto: ver „malgastar tiempo“
        ("U" "malutilaĵe. Intento ver en qué he gastado todo el tiempo fútil. Quiero ver cabeceras concretas" agenda ""
         (
          (org-agenda-span 1)
          ;;(org-agenda-start-with-clockreport-mode t)

          (org-agenda-start-with-log-mode t)
          (org-startup-truncated t)
          ;; Para varias categorías (una u otra), parece que no va. Para una sí
          ;; (org-agenda-category-filter-preset '("+semana" "+malgrave" "+global" "+Personas" "+pruebas" "+proj" "+idp" "+megaidp"))
          ;; (org-agenda-category-filter-preset '("+semana"))
          ;; (org-agenda-category-filter-preset '("+semana" "+malgrave"))
          ;; Lista copiada de cronometraso_org..py
          (org-agenda-files '("~/org/semana.org" "~/org/malgrave.org" "~/wiki/global.org" "~/wiki/Personas.org" "~/org/pruebas.org" "~/org/proj.org" "~/org/idp.org"))

          )
         )
        ;; ;¬oT; ; esto me va bien, mejor que C-c a a. Así ignora cosas donde no estoy. Lo uso realmente.
        ;; ;¬oT; ; cambié de p a P cuando dejé oT
        ;; ;¬oT; ("P" "Agenda que ignora los proyectos de oT donde no trabajo en este período. β." agenda "" (
        ;; ;¬oT; ; ya no hace falta; ¡que salgan todos! ; (org-agenda-files org-agenda--con-laboral)
        ;; ;¬oT; ;falla un poco por lo de next-line: (org-agenda-skip-function '(if (member "ctti" (org-get-tags-at)) (next-line))) 
        ;; ;¬oT; ; esto funciona pero quita sólo *1* etiqueta (org-agenda-skip-function '(my-skip-by-tags "ctti"))
        ;; ;¬oT; ; esto lo metió Carsten en 6.23trans; lo soluciona todo
        ;; ;¬oT; (org-agenda-filter-preset '("-ctti" "-imi" "-openpdf"))
        ;; ;¬oT; 
        ;; ;¬oT; ))

        ;; similar a la anterior (P). Pero además se excluyen ciertas páginas de wiki (definidas en .org-ficheros-agenda.el)
        ;; Me he olvidado del sentido que tiene esto, o de si es mejor que C-aa
        ;; Idealmente no ha de salir nada que me distraiga.
        ;; Puede irme bien como una para quitar lo distrayente. Centrada en mi trabajo principal
        ("p" "*Agenda principal/seria*: excluye trabajo para otros y distracciones" agenda "" 
         (
          ;; ya no hace falta; ¡que salgan todos! ; (org-agenda-files org-agenda--con-laboral)
          (org-agenda-files (list-difference org-agenda-files componentes-agenda--distrayentes-inapropiados-para-trabajo))
          (org-agenda-filter-preset '("-besteentzat"))
          ;; dicen que va más rápido así. Yo no noto diferencia
          (org-agenda-entry-types '(:scheduled))

          ))


        ;; desde 6.m10.2009:
        ;; Éste es mi lanzador de tareas comunes; buscado desde hace tiempo. Yo marco las tareas „de destino“ con la etiqueta TIPA, y luego un „C-c a c“ me abre la lista. Ahí puedo hacer C-c C-x C-i
        ;; Además está lo proyectos „actuales“ (:nuna:), pero no lo uso aquí
        ("c" "Tipaj taskoj komunaj facile atingeblaj." tags "+TIPA"
         (
          ;; variables
          ;;ej; (org-agenda-files org-agenda--con-laboral)
          ;; ya no hace falta pues desactivé la herencia en general
          ;;(org-tags-exclude-from-inheritance '("TIPA"))

          ))

        ;;("v" "Por montri al VG" tags "+vicenç" (
        ;; variables
        ;; ya no hace falta pues desactivé la herencia en general
        ;;(org-tags-exclude-from-inheritance '("vicenç"))
        ;;))
        ;;("k" "Por montri al C" tags "+carlos" ())


        ;;("P" "Projektoj ĉiaj (blokitaj aŭ ne)" tags "+proj" ())
        ;;("ĵ" "Projektoj nunaj (maks. N)" tags "+proj+nuna" ())
        ;; Mejor es combinar ambas:
        ("ĵ" "Projektoj ĉiaj (nunaj kaj poste malnunaj)" ((tags "+proj+nuna") (tags "+proj-nuna"))
         (
          ;; que salgan proyectos de todos lados, sin importar el ordenador en que estoy
          ;; BONUS: pasar a org-ficheros-agenda, crear concepto de „todos“
          (org-agenda-files (delete-dups (append org-agenda-files '("~/org/yubay.org" "~/org/jam.org"))))

          ))


        ("u" "Todos los cursos para publicar y vender en udemy." tags "+curso" ())



        ;; Quería llamarla „l“ de „limpia“ pero veo que lo que me interesan son las citas (eventos con otras personas)
        ;; ("z" "Agenda de citas: eventos y encuentros en el espaciotiempo" tags "cita" ())
        ("z" "Agenda de citas: eventos y encuentros en el espaciotiempo esta semana" agenda "cita"
         (
          (org-agenda-filter-preset '("+cita"))
          (org-agenda-span 14) ; 7 es poco
          (org-agenda-start-on-weekday 1)
          ;; incluir todos aunque no esté en el ordenador que toca
          ;; esto lo puedo definir esto en org-ficheros-agenda.el
          (org-agenda-files (append org-agenda-files '("~/org/yubay.org")))

          ))


        ("ĉ" "Lista de la compra y la ¬compra; también lista de la venta" 
         (
          ;; Lista de lo comprable (pero aún sin comprar):
          ;; Los comentados no van
          ;; (tags "+aĉetebla" (
          ;; (tags-todo "" (
          ;; (tags-todo "+aĉetebla+TODO={FARU\|BONUS\|ATENDAS}" (
          ;; (tags-todo "+aĉetebla+TODO={\"FARU\"\|\"BONUS\"\|\"ATENDAS\"}" (
          ;; (tags-todo "+aĉetebla+TODO=\"BONUS\"|+aĉetebla+TODO=\"FARU\"|+aĉetebla+TODO=\"ATENDAS\"" (
          ;; (tags-todo "aĉetebla/BONUS|aĉetebla/FARU|aĉetebla/ATENDAS" (
          (tags-todo "aĉetebla/BONUS|FARU|ATENDAS" (
                                                    (org-agenda-overriding-header "Me interesa comprar esto")
                                                    ))
          ;; Lista de lo vendible:
          (tags-todo "+vendebla/BONUS|FARU|ATENDAS" (
                                                     (org-agenda-overriding-header "Me interesa vender esto")
                                                     ))
          ;; Lista de lo comprado:
          (tags "+aĉetebla/IS|MALFAR" (
                                       (org-agenda-overriding-header "Ya compré esto")
                                       ))
          ;; MALFAR Lista de lo vendido: no hace falta
          ;;(tags-todo "+vendebla/IS|MALFAR" (
          ;;(org-agenda-overriding-header "Ya vendí todo esto")
          ;;))
          )
         )


        ("k" "Todo lo publicable en web, separado por estados"
         ;; basada en „ĉ“
         (
          (tags-todo "cable/BONUS|FARU|ATENDAS" (
                                                 (org-agenda-overriding-header "He de acabar esto para poder publicarlo:")
                                                 ))
          (tags "cable/-BONUS-FARU-ATENDAS-IS-MALFAR" (
                                                       (org-agenda-overriding-header "Esto también es acabable, pero ponle BONUS:")
                                                       ))
          (tags-todo "cable/IS" (
                                 (org-agenda-overriding-header "Esto YA es publicable, sin cambios:")
                                 ))
          (tags-todo "cable/MALFAR" (
                                     (org-agenda-overriding-header "¡Incongruencia! Si no lo hice/haré, ¿cómo es publicable? Arréglalos:")
                                     ))
          )
         )

        )
      )
;; ; No hace falta ya pues el método de Carsten es mejor
;; (defun my-skip-by-tags (tag)
;;   "Skip tasks that contain tag (with inheritance!). Manuel Hermenegildo "
;;   (let ((line-end (save-excursion (progn (end-of-line) (point))))) ;; return pos
;;     (if (or 
;;   (member tag (org-get-local-tags)) ;; check first if only local (speed)
;;   (member tag (org-get-tags-at (point)))) ;; also inherited
;;       line-end  ; skip, continue after that
;;  nil ; do not skip
;; )))
;; 

;; BONUS: inspirarme leyendo  http://orgmode.org/worg/org-tutorials/org-custom-agenda-commands.php

;;;;;;; appt (recordatorios para citas de la agenda)
;;: las citas de la agenda las añado como recordatorios; así emacs me avisa cuando hay algo para hoy.
;; Aunque no me gusta mucho el paquete „appt“... pues le faltan cosas.

;; por Carsten; 31.1.2009
(defun añade-tareas-para-aviso-pero-no-las-ya-hechas ()
  "Añade a appt las tareas de mi agenda que aún no están completadas."
  (interactive)
  (let ((org-agenda-skip-deadline-if-done t)
        (org-agenda-skip-scheduled-if-done t)
        ;; para probar:
        ;; (org-agenda-files '("~/org/semana.org"))
        )
    ;; (org-agenda-to-appt )))
    ;; nota: category no puede ser nil, ha de ser "" al menos
    (org-agenda-to-appt t '((headline ":cita:") (category "")) )))


;;(org-agenda-to-appt)
;; mejor esto: lo ejecuta al arrancar emacs, y a medianoche. Por Warnong Lin en emacs-orgmode@gnu.org
;;(run-at-time-exceptosiyaexiste "0:30am" (* 24 3600) 'org-agenda-to-appt) ; todas (también las que están en estado IS/MALFAR)
;;--- 4.m2.2010: me he cansado de su semifuncionamiento, su molestia, y su intromisión parcial (sí para lo que no toca, no para lo importante), así que lo desactivo hasta encontrar forma *alternativa*
;; 5.m10.2011: debería intentar reactivarlo
;; 4.m5.2012: no usaré esto sino org-notify
(ignore '(
          (run-at-time-exceptosiyaexiste "0:30am" (* 24 3600) 'añade-tareas-para-aviso-pero-no-las-ya-hechas)
          (appt-activate 1) ; activo el recibo de avisos
          ))
;; nota: esto sólo funciona si la lista de ficheros „agenda“ se ha definido arriba. No va si se ha definido más abajo

;; Avisa 15' antes
(setq appt-message-warning-time '15)

;; Esto quita la ventana por defecto y usa otro programa gráfico
(setq appt-display-format 'window)
(setq appt-disp-window-function (function my-appt-disp-window))
(defun my-appt-disp-window (min-to-app new-time msg)
  (save-window-excursion 

    ;; pita raramente
    (dotimes (a 8)
      (pita-de-verdad)
      (pita-de-verdad-con-tono-medio))

    (shell-command (concat
                    ;; el normal: ;  "/usr/bin/zenity --info --title='Appointment' --text='" msg "' &"
                    ;; oculto (se ve con Mod3+m window-info RET):
                    "/usr/bin/zenity --info --text='' --title='" msg "' &"
                    ) nil nil)
    ))


;;;;;;; org-notify (mejor que appt), por Peter Münster; le di algún comentario
(ignore '( ; lo ignoro porque no lo uso mucho y me intenta hacer cosas raras con dbus

          ;; antes: https://github.com/p-m/org-notify… Pero ya está en org-mode

          (require 'notifications) ; creo que hace falta
          ;; quizás hay que arrancar a mano: /usr/lib/notification-daemon/notification-daemon
          ;; Lo vi en: /etc/xdg/autostart/notification-daemon.desktop
          (require 'org-notify)
          ;; (org-notify-start)
          (org-notify-start -300) ; cada 5 minutos comprobar citas, así no me bloquea tanto
          ;; ATENDAS: si me molesta, ponerle número negativo; entonces sólo lo mira si Emacs está inactivo durante ese rato

          ;; (org-notify-process) ; ← creo que así se lo llama normalmente

          ;; Dice: „Para las tareas que tienen propiedad :notify: igual a X (o que no tengan esta propiedad, si se puso 'default) : Cuando falten (o te pases) :time respecto a la fecha límite, haz :actions (son funciones o sufijos de org-notify-action-*) y repítelas cada :period durante :duration segundos, audiblemente si está :audible“
          ;; acciones: ej. -ding → hace org-notify-action-ding
          ;; lo de la propiedad :notify: permite tipos de notificación. ¿Cuáles necesito?
          ;; - „iliaten“ (cosas para las que me esperan).  No, mejor describir el tipo de notificación, no el porqué.
          ;; - „aviso_urgente“. Mejor
          ;; - „aviso_inactividad“, ej. para „tienes que dar algún signo de vida pronto“
          (org-notify-add 'aviso_urgente
                          '(:time "-1s" :period "20s" :duration 10
                                  :actions (-message -ding))
                          '(:time "15m" :period "2m" :duration 100
                                  :actions -notify)
                          '(:time "2h" :period "5m" :actions -message)
                          ;;                '(:time "3d" :actions -email)
                          '(:time "3d" :actions -message)
                          )
          ;; Por defecto (tipo 'default) ya añade algo, eso aplica a todo lo que tiene DEADLINE.

          ;; probando métodos de notificación que ofrece
          ;; (notifications-notify :title "¡eh!" :body "Un dos, probando, probando") ← (void-function dbus-call-method) ← es por compilarc con ¬dbus. Pero al compilarlo con, veo: (dbus-error "Failed to connect to socket /…tmp/dbus-eFIvciWz6q: В соединении отказано") ← esto es porque arranqué emacs dentro de screen, con información vieja de entorno. Funciona si pongo la buena a mano
          ;; (org-notify-action-ding '(:time "-1s" :period "20s" :duration 10 :actions (-message -ding)))
          ;; (org-notify-action-message '(:time "-1s" :period "20s" :duration 10 :actions (-message -ding)))
          ;; (org-notify-action-notify '(:time "-1s" :period "20s" :duration 10 :actions (-message -ding)))
          ;; (org-notify-action-notify/window '(:time "-1s" :period "20s" :duration 10 :actions (-message -ding)))
          ;; (org-notify-action-email '(:time "-1s" :period "20s" :duration 10 :actions (-message -ding)))

          )) ; fin de ignore

;; Otra forma es con paquete „notify-osd“, ver ahí notas

;; Ah… algo mejor es pedirle que use „message“
;; (setq org-show-notification-handler #'message)
;; O con esto: (lo probaré un tiempo)
(setq org-show-notification-handler "notify-send")
;; (setq org-show-notification-handler nil)
;; (org-show-notification "ja")
;; (org-notify "hola2")


;;;;;;; exportación de agenda a fichero que pueda ver desde bash
;; m1.2010: Ya lo tengo activo; ver ~/.org-muestra-agenda.pl
;; Quizás me va bien llamarlo desde run-with-timer del demacs principal, pero eso me bloquearía Emacs (igual que si lo hiciere desde emacsclient)

;;;;;;; exportación de citas a formato iCalendar (.ics)
;; BONUS: poner org-combined-agenda-icalendar-file
;; Ver Zeitmanagement
;;;;;;; inclusión de agenda en calendario (M-x calendar y M-x diary)
;; BONUS probar más
;; BONUS: configurar calendario para mostrarme las fiestas buenas
;; BONUS: tecla para acceder a calendario (M-x calendar)
(require 'calendar)
(require 'cal-move) ; para calendar-cursor-to-visible-date; org dejó de encontrarla un día al hacer C-c .


(setq diary-file "~/.emacs.d/diary/diario")
;;;;;;; calfw, para hacer calendario en tabla, independiente o combinado con org. ¡Muy útil!
;;;;;;;; instalar y cargar el normal
;; (add-to-list 'load-path "~/.emacs.d/calfw")
;; m10.2022: paso al de melpa, pues me interesa mantenerlo actualizado. Borro el de cdv
(require 'calfw)
;; Usable con M-x cfw:open-calendar-buffer
;; ¡Qué bueno!
(defalias 'calendario 'cfw:open-calendar-buffer)

;;;;;;;; integración con org
(require 'calfw-org) ; atención: a fecha 17.m4.2012, peta si no se ha cargado antes org-agenda
;; Usable con M-x cfw:open-org-calendar
;; ¡Buenísimo!

;;(defalias 'calendario-org 'cfw:open-org-calendar)
;; me defino una función que me lo carga más pequeñito
(defun calendario-org nil
  (interactive)
  (let* ((source1 (cfw:org-create-source))
         (cfw:org-agenda-schedule-args '(
                                         :scheduled ; original
                                         ;;:timestamp ; Con timestamp me gusta más, pero no es justo lo que necesito
                                         ))
         (date nil)
         ;; (buffer (find-file "/home/dc/n/cale")) ;; va pero luego intenta grabarlo y añadirle salto de línea al final
         ;; (cfw:calendar-buffer-name "*-calendario-org-uno*") ; probando, no va
         (buffer (get-buffer-create "*-calendario-org-agenda-*")) ;; va pero lo tengo que hacer activo yo al final
         ;; (contents-sources nil)
         (contents-sources (list source1))
         (annotation-sources nil)
         ;; (sorter nil)
         (sorter 'cfw:org-schedule-sorter)
         ;; (view nil)
         (custom-map cfw:org-schedule-map)
         (view 'month)
         ;; (width nil)
         (width 135) ;; no 170. En noad 135.
         ;; (height nil)
         (height 55)
         (dest  (cfw:dest-init-buffer buffer width height custom-map))
         (model (cfw:model-abstract-new date contents-sources annotation-sources sorter))
         (cp (cfw:cp-new dest model view date)))
    ;; (progn
    ;;   (switch-to-buffer (cfw:dest-buffer dest))
    (with-current-buffer (cfw:dest-buffer dest)
      (set (make-local-variable 'cfw:component) cp)
      )
    ;; cp
    ;; Sólo falta cambiar
    (switch-to-buffer (get-buffer-create "*-calendario-org-agenda-*"))
    ;;  )
    )
  )

(defun calendario-org-desde-ics ()
  "Toma fichero .ics que he exportado con un prita Python (o como sea) y lo muestra en calfw; es interfaz alternativa a ẽ thunderbird"
  (interactive)
  (setq cfw:ical-data-cache nil) ; me quito caché que me daba problemas
  (cfw:open-ical-calendar "/home/dc/n/citas-de-org.ics")
  )



;; prueba; sólo quiero los „FARU“
;; (let ((org-todo-keywords-for-agenda '("FARU"))) (cfw:open-org-calendar)) ; no va
;; (let ((cfw:org-todo-keywords-regexp "FARU")) (cfw:open-org-calendar)) ; no va

(setq cfw:org-agenda-schedule-args '(:scheduled)) ; Hago que cuente sólo lo agendado, y no una simple mención de una fecha o un fin de plazo. Ver en org-agenda-entry-types la explicación de los 4 valores permitidos. En principo mostraba los 4

;; Es algo lento al cambiar de mes
;; mirar: http://lists.gnu.org/archive/html/emacs-orgmode/2011-07/msg00228.html


;;;;;;;; Caracteres Unicode, queda más bonito
(setq cfw:fchar-junction ?╋
      cfw:fchar-vertical-line ?┃
      cfw:fchar-horizontal-line ?━
      cfw:fchar-left-junction ?┣
      cfw:fchar-right-junction ?┫
      cfw:fchar-top-junction ?┯
      cfw:fchar-top-left-corner ?┏
      cfw:fchar-top-right-corner ?┓)
;;;;;;;; calfw-gcal, para Google Claendar
(require 'calfw-gcal)
;; por probar. Quizás ya no va, por burocracia oauth

;;;;;;;; gestión de festivos (M-x holidays); se usa en calfw
;; Teoría: ver Zeitmanagement
;; Va bien.
;;;;;;;;; lista de fiestas, por categoría

(setq holiday-bahai-holidays nil)
(setq holiday-oriental-holidays nil)
(setq holiday-islamic-holidays nil)
(setq holiday-hebrew-holidays nil)
(setq holiday-christian-holidays nil) ; Navidad etc. las definiré yo. Adviento ¿crea fiestas? no sé. Ver en locales
(setq holiday-local-holidays '(
                               (holiday-fixed 1 1 "Año nuevo")
                               (holiday-fixed 9 11 "Diada de Catalunya")
                               ;; etc.
                               ))

(setq holiday-general-holidays '(
                                 ;; Poner las curiosidades sólo; dejar alguna de EEUU como información. Las locales (fiesta obligada) van en otro lado
                                 ;; (holiday-fixed 1 1 "New Year's Day")
                                 ;; (holiday-float 1 1 3 "Martin Luther King Day")
                                 ;; (holiday-fixed 2 2 "Groundhog Day")
                                 (holiday-fixed 2 14 "Valentine's Day")
                                 ;; (holiday-float 2 1 3 "President's Day")
                                 (holiday-fixed 3 17 "St. Patrick's Day")
                                 (holiday-fixed 4 1 "April Fools' Day")
                                 (holiday-float 5 0 2 "Mother's Day")
                                 ;; (holiday-float 5 1 -1 "Memorial Day")
                                 ;; (holiday-fixed 6 14 "Flag Day")
                                 (holiday-float 6 0 3 "Father's Day")
                                 ;; (holiday-fixed 7 4 "Independence Day")
                                 (holiday-float 9 1 1 "Labor Day")
                                 ;; (holiday-float 10 1 2 "Columbus Day")
                                 (holiday-fixed 10 31 "Halloween")
                                 ;; (holiday-fixed 11 11 "Veteran's Day")
                                 (holiday-float 11 4 4 "Thanksgiving"))
      )

(setq holiday-other-holidays
      '(
        ;; ¿hay algo mejor para poner cumpleaños? No importa, no lo uso
        (holiday-fixed 1 17 "Mi cumpleaños")
        ;; de Cataluña y por aquí cerca: ver „locales“

        ))

;;;;;;;;; actualizar la lista global, etc. Otros ajustes
;; No se actualiza sola la variable calendar-holidays. Pasa al arrancar emacs… o al ejecutar esto sin el ignore. Veo que me hace falta, así que lo activo
;;(ignore '(
(setq calendar-holidays
      (append holiday-general-holidays holiday-local-holidays
              holiday-other-holidays holiday-christian-holidays
              holiday-hebrew-holidays holiday-islamic-holidays
              holiday-bahai-holidays holiday-oriental-holidays
              holiday-solar-holidays))
;;))
;; BONUS: comprobar que se ven los míos
;;;;;; gestión de horas y tiempos
;;;;;;; gestión de esfuerzo y tiempos (horas)

;; MALFAR: (setq org-effort-property "esfuerzo") ; y reemplazar en org/*

;; Equivale a: #+PROPERTY: Effort_ALL 0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 12:00 18:00 24:00 30:00
(add-to-list 'org-global-properties '("Effort_ALL" . "0 0:10 0:30 0:45 1:00 1:30 2:00 3:00 4:00 5:00 6:00 8:00 10:00 12:00 18:00 24:00 30:00 36:00 42:00 84:00 126:00 168:00"))
;; Lo dejo así, con todos esos, porque apretando espacio me da un menú cómodo
;; reiniciar: (setq org-global-properties nil)


;; obligatorio poner un esfuerzo al empezar a cronometrar algo
;; Lo desactivo porque cada día cronometro muchísimas tareas, y pocas tienen una definición de esfuerzo. Poner definiciones de esfuerzo es largo y complejo, y no me sirve de mucho, pues luego me las salto. Me hace falta mejorar mi gestión de tiempo en otros niveles, no en éste (ahora).
;; Además lo quito para hacer que „iniciar cronómetro“ sea siempre el mismo número de teclas.

;;(add-hook 'org-clock-in-prepare-hook 'my-org-mode-ask-effort)
;; (setq org-clock-in-prepare-hook nil)


;; de http://orgmode.org/worg/org-hacks.html
;; Falta que funcione bien cuando no estaba situado en el búfer que toca (ej. porque he hecho C-u C-c C-x C-i)
;; El problema es que (point) entonces se refiere al b. actual y el (org-entry-get (point) "Effort") da nil
(defun my-org-mode-ask-effort ()
  "Ask for an effort estimate when clocking in."
  (unless (org-entry-get (point) "Effort")
    (let ((effort
           (completing-read
            "Est: "
            (org-entry-get-multivalued-property (point) "Effort"))))
      (unless (equal effort "")
        (org-set-property "Effort" effort)))))


(defun org-clock-get-effort-of-clocked-task ()
  "Me he hecho esta función porque no la encontré en org. Devuelve nil si no hay. La uso en todobien"
                                        ;; Ver en „org-element“ otras formas de sacar datos de la cronometrada actual
  (unless (not (org-clocking-buffer))
    (cdr
     (car
      (save-excursion 
        (save-restriction
          (set-buffer (org-clocking-buffer))
          (org-entry-properties (marker-position org-clock-marker) "Effort")
          )
        ))
     )
    )
  )
;; (org-clock-get-effort-of-clocked-task)
;; He metido una comprobación de esto en todobien


;;;;;;; org-clock-budget, para paquetes de tiempo
(let ((d "/w/org-clock-budget"))
  (when (file-directory-p d) 

    (add-to-list 'load-path "/w/org-clock-budget")
    (require 'org-clock-budget)
    ;; ¿esto hace petar el font-lock? Ver en Lisp.org
    (setq org-clock-budget-intervals
          '(
            ("BUDGET_MONTH" org-clock-budget-interval-this-month)
            ("BUDGET_WEEK" org-clock-budget-interval-this-week)
            )
          )
    ))

;;;;;;; tabla de tiempos (ej. para facturar)
;; org-clock-clocktable-language-setup: es ← pero no me sale en español, sale vacío

(defun filtro-limpia-región-quitando-etiquetas-y-prioridades (ini fin)
  "Quita etiquetas de la región. Útil para aplicar a un „clocktable“ de org, pues no veo opción de desactivar el que salgan"
  (interactive "r")
  (if (region-active-p)
      ;; (call-interactively #'replace-string)
      ;; (call-interactively (lambda (ini2 fin2) (interactive "r") (replace-regexp "a" "")))
      (replace-regexp  "\\(FARU\\|BONUS\\|IS\\|MALFAR\\|ATENDAS\\|\\[#A\\]\\|\\[#B\\]\\|\\[#C\\]\\) " "" nil ini fin)
    (message "Error: región no activa")
    )
  )

;;;;;;; forma de sumar tiempos: quiero „28h“ en vez de „1d 24h“
(ignore '( ; desfasado en 9.1
          (setq org-time-clocksum-format
                ;; original  (:days "%dd " :hours "%d" :require-hours t :minutes ":%02d" :require-minutes t)
                ;;(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t)
                ;; "%02d:%02d" ; horas:minutos
                ;;"%2d:%02d" ; sin ceros, horas:minutos. Aún así, me salen un 0:00… Supongo que no es malo. Pero debe de haber otro error que me redondea todo a horas
                '(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t) ; va bien, no redondea, no usa días, no usa „0:00“
                )
          ))
;; nuevo de m2.2017 (org 9.1): Consider setting `org-duration-units' instead.
(setq org-duration-format 'h:mm) ; era:  (("d") (special . h:mm))

;;;;;; temporización de tareas (reloj) (cronometrado)
;;;;;;; cómo se apuntan las temporizaciones en cada entrada
(setq org-clock-into-drawer "CLOCK") ; al viejo estilo
;; también está org-log-into-drawer (para el resto de cosas) pero creo que no me hace falta registrar cambios de estado


;; así me atrevo a empezar algo y rectificar en un momento (idealmente para temporizar subtarea, no para procrastinar)
(setq org-clock-out-remove-zero-time-clocks t)

;;;;;;; cómo se calculan luego las tablas de tiempos

;; When non-nil, include the current clocking task time in clock reports.
;; pero aún así, no me lo cuenta en „CLOCKS“
(setq org-clock-report-include-clocking-task t)

;;;;;;; cómo se muestra en la barra de abajo  el reloj

;; el reloj abajo
(set-face-background 'org-mode-line-clock "#000") ; era #036
(set-face-foreground 'org-mode-line-clock "#07f") ; era #999

;; ¿por qué tengo que ver este reloj 1 vez por ventana aunque tenga >1 ventanas? Me gustaría verlo 1 vez por marco:
;;(setq org-clock-clocked-in-display 'frame-title) ; era: mode-line
;; Pero no me gusta mucho cómo queda; queda muy público

;; Quizás puedo grabarlo en fichero… ← mucho trabajo.

;; Me puede ir bien esconder el reloj, en general.
;; Con  org-clock-clocked-in-display nil lo hago, pero entonces queda muy escondido…

;; De momento uso esto, que no esconde mucho…:
;; (setq org-clock-string-limit 9)
;; m10.2017: intento trabajar más y más públicamente, así que esconderé menos
(setq org-clock-string-limit 0)



;; en la línea de abajo, mostrar no el tiempo total, sino el de esta cronometración
;;(setq org-clock-modeline-total 'current)
;; mmm… aunque no está muy mal, le falta poder ver el total. Lo restauro
(setq org-clock-modeline-total 'all)

;; Le pido también que en ciertas tareas (como procrastinar) me muestre el tiempo perdido hoy, no el total (ej: 70h). Para eso uso una propiedad:
;;   :PROPERTIES:
;;   :CLOCK_MODELINE_TOTAL: today
;;   :END:
;; Pero ya que la aplico en cabeceras como „tareas comunes, típicas o globales“, me interesa heredarla:
(setq org-use-property-inheritance '("CLOCK_MODELINE_TOTAL"))
;; Para etiquetas: ver org-use-tag-inheritance


;; BONUS: en realidad necesito algo más potente, como „0:10 (tot: 1:10/2:00)“ donde 1:10 es el total (incluyendo esos 0:10) y 2:00 la estimación total. Puesto en emacs.org

;;;;;;; cierre automático de relojes y detección de inactividad

;; tras 10 minutos de inactividad, „resolver“ relojes (¿?)
;; http://orgmode.org/manual/Resolving-idle-time.html
;; - mejorar la descripción de la página anterior; no se entiende
;; - me lo pregunta en un marco distinto al que estoy; me confunde mucho
;;  (setq org-clock-idle-time 15) ; con 10 minutos me lo pregunta mucho
;; m7.2013: lo desactivo pues siempre lo cancelo y nunca me ayuda; ya estimo yo más o menos el tiempo que he estado fuera. Así no me molestará robándome el minibúfer
(setq org-clock-idle-time nil)
;; Para que todo eso funcione en X:
;; # /w/org-mode/UTILITIES ; gcc -l Xss x11idle.c -o x11idle -lX11
;; Lo he puesto en instala.sh por tanto ya me funcionará en todos lados


;;;;;;; continuidad del cronometrado para que no queden huecos

;; Esto es bueno pero no suficiente y no se adapta al cómo trabajo, así que lo desactivo para no liarme 
;;(setq org-clock-continuously t)
;; „You can temporarily activate continuous clocking with C-u C-u C-u M-x org-clock-in RET (three universal prefix arguments) and C-u C-u M-x org-clock-in-last RET (two universal prefix arguments). “
;; BONUS: probar

;;;;;;; acceso a funciones del reloj desde todos lados

;; acceder al reloj desde doquier con C-cC-xC-o j x i …
(global-set-key [(control c) (control x) (control o)] 'org-clock-out)
(global-set-key [(control c) (control x) (control i)] 'org-clock-in) ; sólo útil con C-u C-c C-x C-i si el búfer es ¬org
(global-set-key [(control c) (control x) (control j)] 'org-clock-goto)
(global-set-key [(control c) (control x) (control x)] 'org-clock-cancel)


;;;;;;; cuántos cronometrados me recuerda y cómo

(setq org-clock-history-length 16) ; era 5. Es para C-u C-c C-x C-j. Demasiado grande → ventana no se ve bien ← pero puedo usar C-v/M-v

;;(require 'org-exp) ; irrelevante es cargar esto aquí, pero org-clock-persistence-insinuate está mal y me necesita org-export-default-language; así ahora va. 11.m1.2014: pruebo a comentarlo

(require 'org-clock) ; si no, no va el org-clock-persistence-insinuate (empezó a pasar en m6.2011)
;; Persistir esa historia (y reloj actual) al cerrar Emacs. Esto me puede ir bien, pero en la práctica me da más problemas que ventajas: no graba bien el historial (graba otro), y hace el arranque no interactivo → así que lo desactivo
;;(org-clock-persistence-insinuate)
;;(setq org-clock-persist-file "~/.emacs.d/.org-clock-save.el") ; Puede quedar información privada, pero tanto como el resto de ~/
;;(setq org-clock-persist t)


;;;;;;; otras formas de aprovechar lo del reloj y cronometrado

;; Tareas en cualquier cabecera (nuevo en m8.2009). Probar. Ver línea de abajo:
;; http://orgmode.org/manual/Countdown-timer.html
;; org-timer-set-timer: bound to `C-c C-x ;' in Org buffers and to `;' in Org agenda buffers.  This function sets a timer for the headline the cursor is currently it.  Up to three timers can be used at any time.
;; 


;;;;;;; dar lista de todos los cronómetros
;; Son pruebas, pero las cargo:
(load-file "~/.emacs.d/lisp/org-cronometrados_org.el")

;;;;;; ayudas que me ayudan a centrarme en el trabajo. (modo jefe, org-boss)
;;;;;;; aviso cuando no estoy cronometrando ninguna tarea
;; komencis 14.m9.2009 eksperimenti kun tiu frenezeta utilega avizego eknovega por mi sed delonge planita
(defun plendi-se-malkronometras () "Memorigi min ke mi kronometru iun taskon ĉiam. Tio utilegas ĉar helpos vidi kiel mi organizas la tempon ĉe mallaborejo (precize kie mi plej malbone laboras kaj organizas)."  
       (interactive)
       (unless (marker-buffer org-clock-marker)

         ;; ĉar eble mi mallegas tiajn mesaĝojn, mi sonigas; sed nur miadome:
         (if (equal "ali.danielclemente.com" (system-name))   (pita-n-tonos-aleatorios 2) )

         ;; mesaĝe ankaŭ. Gravas la ordo fina ĉar mi ne volas vidi jenon: „(Shell command succeeded with no output)“
         (message
          ;; "Kiun taskon kronometras?"
          (nth (random (length laboremigaj-avizoj-kiam-malkronometris)) laboremigaj-avizoj-kiam-malkronometris)
          )

         ))

(run-at-time-exceptosiyaexiste t (* 15 60) 'plendi-se-malkronometras)


(defvar laboremigaj-avizoj-kiam-malkronometris '(
                                                 "Kiun taskon kronometras?"
                                                 "Kronometru iun taskon, malgravas kiun; elektu unu el malgrave.org se necese"
                                                 "Pete kronometru taskojn eĉ ĉe mallaborejo"
                                                 "Kronometrado helpegas! Bonvole elektu iun taskon"
                                                 "Tro da tempo sen kronometri forpasis ← Teĥnike, vi ne laboris. Tio malbonas!"
                                                 "Por pli bona organizo kaj statistikaĵoj, ĉiam kronometru, facilas."
                                                 "En kio laboras vi? Bonvole kronometru per Org"
                                                 "Mi/Vi ŝatus koni kiu estas la nuna tasko via, do uzu Org"
                                                 )
  "Frazoj kiuj memorigu al mi la gravon de ĉiam kronometru per Org la nunan taskon"
  )

;;;;;;; recordatorio de que procrastinar es perder el tiempo de forma „en que no me gusta“ (también de fora que me gusta y es útil; pero quiero resaltar la parte mala porque es la que me interesa evitar)
(defun plendi-kiam-prokrastinas () "Memorigi min ke prokrastino ankaŭ malbonas kaj mi evitu ĝin. Tio ekutilas kiam mi ekkronometras la taskon „procrastinar“ (malgrave.org), alie nenias"
       (interactive)
       (if (and (marker-buffer org-clock-marker) (string= org-clock-heading "procrastinar"))
           (progn

             ;; ĉar eble mi mallegas tiajn mesaĝojn, mi sonigas; sed nur miadome:
             (if (equal "ali.danielclemente.com" (system-name))
                 (pita-n-tonos-aleatorios 10)  ; ĉe domo, ĝena pli ol la memorigo malkronometra
               (pita-n-tonos-aleatorios 1) ; ĉe laborejo; ĜENU ĜENU ĜENEGU! Mi tute ne prokrastrinu. 1 tono jam sufiĉas por memorigo.
               )
             ;; mesaĝe
             (message "Prokrastino ankaŭ malbonas kaj estas evitenda")

             )
         ))
(run-at-time-exceptosiyaexiste t (* 5 60) 'plendi-kiam-prokrastinas) ; 5 minutoj de prokrastino jam malbonas


;;;;;;; recordatorio de que he de hacer las tareas agendadas, no otras
(defun plendi-kiam-faras-aliajn-taskojn-ol-la-agenditajn () "Memorigi min ke se mi volas malkreskigi mian liston de farendaĵoj, mi laboru en *tiuj* farendaĵoj, ne en aliaj"
       (interactive)
       ;; cronom ∩ sched → no pita
       ;; cronom ∩ ¬sched → pita
       ;; ¬cronom ∩ sched → ¬ pita

       (if (and 
            (marker-buffer org-clock-marker)
            (not (org-get-scheduled-time org-clock-marker
                                         ;; t ; ¿permitir obtener el SCHEDULED de un padre? BONUS: decidir. Puedo usar org-element-lineage para obtener todos los padres
                                         ;; Creo que es mejor que mueva el SCHEDULED del padre al hijo. Así las tareas agendadas serán bien concretas.
                                         ))
            ;; excluyo ciertas tareas que sí que me permito hacer aunque no estén agendadas
            (not (string-match "\\\(lejos del ordenador\\\|películas\\\)" org-clock-heading))
            )
           (progn 
             ;;(set-background-color "#223344") (ding) (set-background-color "#000000")
             ;; esto me bloquea mucho. Como ya tengo mensaje, me quedo con esto sólo:
             (ding)

             ;; MALFAR ¿Me programo aquí otras normas, como „si no trabajo en yubay.org, quejarse? → no, ver /todobien/ para esto. Ahí miro la media durante los últimos días/horas y el pronóstico futuro, que es menos criticón que sólo mirar el momento actual
             (if (equal (system-name) "ali.danielclemente.com")
                 (save-window-excursion ; que no me mueva todo el rato al búfer de salida
                   (async-shell-command "beep; wihack -type dialog xeyes 2>/dev/null" "*Async Shell Command xeyes*")
                   (bury-buffer "*Async Shell Command xeyes*") ; así no me reemplaza lo que estaba viendo
                   )
               )
             (if (not (file-exists-p "~/.nota1.txt"))
                 (with-temp-buffer
                   ;; (insert "лаворо ен таско не ел агендо")
                   (insert "prenuelagnur") ; prenu el agendo nur
                   (insert " | ")
                   (insert (ciriliza (substring org-clock-heading 0 8)))
                   (insert " ·" 
                           (ciriliza
                            (substring
                             (file-name-nondirectory (buffer-file-name (marker-buffer org-clock-marker)))
                             0 4)
                            )
                           "")

                   (write-file "~/.nota1.txt"))
               )
             (message "¡¬a!") ; el „message“ es necesario
             )
         ))
;;(run-at-time-exceptosiyaexiste t (* 10 60) 'plendi-kiam-faras-aliajn-taskojn-ol-la-agenditajn) ; nur kelkfoje; 5 minutoj farinte aliaĵojn ne tute malbones, sed 10 ja jes
;; 6.m12.2014: mi provas malŝalti tion ĉar eble tio malrapidigas ĉion ĉe emakso

;; por malŝalti:    (cancel-timer   (nth 5 timer-list)   )  ; (uzu numeron bonan)
;; aŭ per helm (C-…)

;;;;;;; recordatorio de que he de trabajar en un proyecto concreto, no en otros (agendados o no)
(defun plendi-kiam-faras-alian-projekton-ol-la-ĉefan () "Memorigi min la gravon de la projekto nuna kaj eviti mian prokrastinon tra aliaj ankaŭ-gravaj projektetoj malĉefaj."
       (interactive)
       (if (and 
            (marker-buffer org-clock-marker) 
            (not (member
                  (file-name-nondirectory (buffer-file-name (marker-buffer org-clock-marker)))
                  '("yubay.org" "Zeitmanagement.org")) ;nur tiujn permesas
                 ;; poste: se havas proj+nuna, estas bona kaj permesas mi
                 )
            (equal (system-name) "ali.danielclemente.com")
            )
           (progn 
             (set-background-color "#223344") (ding) (set-background-color "#000000")
             (save-window-excursion ; que no me mueva todo el rato al búfer de salida
               (async-shell-command "beep -f 150 -n -f 100; wihack -type dialog display ~/.miw/lanzadera-yubay/logo.png"))
             "¡¬a!"
             )
         ))
;; laŭ epoko povas ŝalti mi aŭ malŝalti tion
;; en m11.2011 Yubay bezonas mian helpon. En m1.2012 ne plu la tutan tempon
;;(run-at-time-exceptosiyaexiste t (* 12 60) 'plendi-kiam-faras-alian-projekton-ol-la-ĉefan)


;;;;;;; recordatorio de que hay que ir a dormir a según qué horas

;; (setq fojoj-kiuj-sonis-la-avizo-de-dormi 0) ; ne, mi volas malsamajn mesaĝojn

(defun avizu-estas-horo-de-dormo (&optional avizegu) "…"
       (interactive "P")


       ;; Ne provu esti tro inteligenta: ĉiam montru avizon. Mi ekforigos ĝin kiam malnecesitas

       ;;(if
       ;; (and
       ;; (> (nth 2 (decode-time (current-time))) 6)
       ;; (< (nth 2 (decode-time (current-time))) 23)
       ;; )
       ;;   ; Ĉi tiu fojo tempego pasis kaj ne estas jam horo por dormi
       ;;   (message "mi jam dormis")
       ;;   (cancel-timer tempilo-por-dormejigi)


       ;; va bien
       (progn (pita-de-verdad) (pita-de-verdad-pero-flojito) (pita-de-verdad) )
       (if avizegu (progn (pita-de-verdad-con-tono-medio) (pita-n-tonos-aleatorios 15) (pita-de-verdad-con-tono-medio)))

       ;; se ne.
       ;; Unue mi uzis: (async-shell-command "zenity --info --text  \"`date`: mesaĝon\" 2>/dev/null")
       ;; Sed tio kreas buferon ĉiun fojon…
       (progn
         (if (not avizegu) 
             (call-process-shell-command "zenity --info --text  \"`date`: mesaĝon\"" nil 0)
           (call-process-shell-command "zenity --info --text  \"`date`: ¡¡¡¡¡¡¡¡¡¡¡!!!!!!!!! Lasta (horo por d.)\"" nil 0)
           )
         (message "Estas horo malfrua jam")
         )
       ;;  )

       ;; nur 1 fojo jam bonas
       ;; ne ĉi tie; mi poste maldonas tion
       ;;(cancel-timer tempilo-por-dormejigi)


       )

(defvar tempilo-por-dormejigi nil)
(when (timerp tempilo-por-dormejigi) (cancel-timer tempilo-por-dormejigi))
;;  dua
;; (defvar tempilo-por-dormejigi-2 nil)
;; (when (timerp tempilo-por-dormejigi-2) (cancel-timer tempilo-por-dormejigi-2))


;; Atentu: ĉi tiu kodo estas tre malbona kaj ne funkcias:
;; - Horloĝoj en emakso estas absolutaj, do se mi komencas emakson 11:00, 02:50 estas pasita kaj emakso montras la avizon
;; - Mi unue uzis „cancel-timer“-n ene de funkcio. Sed ne necesas ĉar mi volas avizon ĉiun tagon (24*60*60 s.)
;; - Krome, run-at-time-exceptosiyaexiste eble ne necesas
;; m2.2023: Pro ĉio ĉi, mi maluzos tempileton tian. Unue mi komprenu aŭ bonigu emakson
(ignore '(
(setq tempilo-por-dormejigi
      ;; va: (run-at-time-exceptosiyaexiste "23:10" (* 5 60) 'avizu-estas-horo-de-dormo) ; 5 minutoj

      (run-at-time-exceptosiyaexiste "02:50" (* 24 60 60) (lambda ()
                                                        (call-interactively #'avizu-estas-horo-de-dormo)
                                                        ;; (cancel-timer tempilo-por-dormejigi)
                                                        ))
      ;;(run-at-time-exceptosiyaexiste "19:25" (* 5 60) 'avizu-estas-horo-de-dormo) ; nur provo! mi ne volas 19:25 sed 23:10. Sed mi provetemas
      )
))

;; (setq tempilo-por-dormejigi-2
;;    (run-at-time-exceptosiyaexiste "03:30" (* 24 60 60) (lambda ()
;;                                                      (call-interactively #'avizu-estas-horo-de-dormo 'fortege)
;;                                                      ;; (cancel-timer tempilo-por-dormejigi-2)
;;                                                      ))
;;    )

;; ankoraŭ provonte



;; prueba: (run-at-time "18:34" 60 'calc)

;;;;;;; hábitos (org-habit): cosas que no sólo se deben hacer, sino hacer regularmente

;; http://orgmode.org/worg/org-tutorials/tracking-habits.php
;; Manual: http://orgmode.org/manual/Tracking-your-habits.html
;; ¡Con colorines y gráficos (en texto)!
;; Parece que la propiedad STYLE=habit lo declara.

;; Lo desactivo temporalmente pues no me ayuda mucho; tengo todo siempre atrasado, y todos estos dibujitos y colorines me confunden. Lo desactivo sencillamente porque no me ayuda. Además no combina bien con vista en columnasa.  Quizás más adelante me sirve más…
(ignore '(
          (require 'org-habit) ; está en ¬contrib

          ;;  If non-nil, only show habits in today's agenda view. This is set to true by default. 
          (setq org-habit-show-habits-only-for-today nil)
          (setq org-habit-graph-column 80) ; bastante más a la derecha, que no tape

          ;; Empiezo a entenderlo: día=carácter. 21 días antes, „!“, 7 días después. Cada día tiene un color.
          ;; 
          ;; Blue
          ;;     If the task wasn't to be done yet on that day.
          ;; Green
          ;;     If the task could have been done on that day.
          ;; Yellow
          ;;     If the task was going to be overdue the next day.
          ;; Red
          ;;     If the task was overdue on that day. 
          )) ; fin ignore

;;;;;;; ideas para un paquete global, org-boss (o org-secretario, …)
;; Ver mi hilo en lista: Productiviy tools
;; Fueron muy útiles los comentarios de Dave Täht en lista

;;;;;;; para centrarme en la agenda facilito el primer paso: decidir siguiente tarea a hacer
;; C-c C-x C-d ha de empezar a cronometrar el „decidiendo lo siguiente a hacer“ (malgrave.org)
;; De momento lo que he hecho es:
;; - Aprieto C-uC-uC-cC-xC-i para marcarla como tarea por defecto.
;; - ya puedo usar C-uC-cC-xC-id para empezar a cronometrarla
;; Formas de obtener esa tarea:
;; - (org-id-find "decidiendo_lo_siguiente_a_hacer") ; porque le puse ID yo. Da: ("~/org/malgrave.org" . 43993)
;; - org-clock-default-task ; da #<marker at 43993 in malgrave.org>
;; MALFAR: poner C-cC-xC-d como atajo a C-uC-cC-xC-id; preguntar en lista cómo se hace

;; 24.m3.2010: esto no me es muy útil…
;; m12.2020: sigue sin serlo. En realidad tengo varias cabeceras en donde cronometro habitualmente. Ya he montado algo con helm para elegirlas rápidamente (ver los TIPA)

;;;;;;; mostrar agenda al volver después de haber pasado un rato lejos del ordenador

;;(defun jump-to-org-agenda ()
;; De John Wiegley, mensaje suyo a lista el 18.m3.2010.
(defun jump-to-org-agenda ()
  (interactive)
  (let ((buf (get-buffer "*Org Agenda*"))
        wind)
    (if buf
        (if (setq wind (get-buffer-window buf))
            (select-window wind)
          (if (called-interactively-p ; … no sé si es necesario pasarle parámetro'interactive
               )
              (progn
                (select-window (display-buffer buf t t))
                (org-fit-window-to-buffer)
                ;; (org-agenda-redo)
                )
            (with-selected-window (display-buffer buf)
              (org-fit-window-to-buffer)
              ;; (org-agenda-redo)
              )))
      (call-interactively 'org-agenda-list)))
  ;;(let ((buf (get-buffer "*Calendar*")))
  ;;  (unless (get-buffer-window buf)
  ;;    (org-agenda-goto-calendar)))
  )

(defun muéstrame-agenda-si-no-molestará-mucho nil
  (interactive)
  (if (= 1 (length (window-list)))
      (jump-to-org-agenda)
    (message "Tempo multa sen fari ion… Ĉu agendon ne vidis?")
    )
  )

;; por privacidad sólo lo haré en casa
(if (equal "ali.danielclemente.com" (system-name))
    (run-with-idle-timer 300 t 'muéstrame-agenda-si-no-molestará-mucho)
  )
;; Me va bien


;;;;;;; calculador del cuánto (del cuánto tiempo he de dedicar a cada tarea)

(defun calcula-cuánto ()
  "Método cuántico de resolución de tareas, ideal para trabajar mucho en todo sin acabar nada.
Dime hasta qué hora trabajarás hoy y cuántas tareas te quedan, y te diré cuántos minutos has de trabajar en cada tarea para hacerlas todas hoy.
Va bien usar entonces ~/ut/avisa_cada_N_minutos
O vertareasporbloques.py --dur 20  ← o el cuánto que toque

Ver más sobre esto en /circular entre tareas/.

6.m5.2010 Daniel Clemente"
  (interactive)
  (let*
      (
       ;;(hora-final (if (yes-or-no-p "¿hoy trabajaré también por la tarde? ") '(0 30 19) '(0 00 15))) 
       (hora-final `(0 0 ,(string-to-number (read-from-minibuffer "Hora de acabar de trabajar (ej. 15, 19, 20, 23): " "20"))))
       (inicio-decodif (decode-time (current-time)))
       ;; (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE).
       (final-decodif (append hora-final (sublist inicio-decodif 3)))
       (diferencia-codif
        (time-subtract
         (apply 'encode-time final-decodif)
         (apply 'encode-time inicio-decodif)
         )
        )
       (segundos-que-quedan (nth 1 diferencia-codif))
       (minutos-que-quedan (/ segundos-que-quedan 60))

       (les-quatre-d-avui '(0 00 16))
       (les-quatre-d-avui (apply 'encode-time (append les-quatre-d-avui (sublist (decode-time (current-time)) 3))))
       (antes-de-las-16-p (time-less-p (current-time) les-quatre-d-avui))
       (minutos-a-descontar 
        (+ 30 ; pequeña pausa en un día
           (if antes-de-las-16-p 60 0) ; comida
           )
        )
       (minutos-netos-que-quedan (- minutos-que-quedan minutos-a-descontar))

       (núm-tareas (string-to-number (read-from-minibuffer "Tareas: ")))
       (cuánto (/ minutos-netos-que-quedan núm-tareas))
       )
    (message (format "A %s por tarea hasta las 19h (habiendo descontado 1h para comida y 30m de descanso)" cuánto))
    ))
;; BONUS: comprobar que los valores que da son correctos
;; BONUS: añadir de alguna forma un tiempo de descanso y de comida; coger automáticamente el número de tareas por hacer. → no, esto es el arma_temporalmente_idp

;;;;;; exportación, publicación y vistas
;;;;;;; vista en columnas

;; poco a poco voy entendiendo la vista en columnas… y le veo utilidad. Por eso la quiero al empezar
;;(setq org-agenda-view-columns-initially t)
;; ATENDAS: De momento más bien me molesta: es muuucho más lenta al crearse y moverse, se activa sola tras pequeños cambios, y no siempre la necesito. Por eso lo activaré manualmente. Cuando org lo corrija sí que la querré
(setq org-agenda-view-columns-initially nil)

;; se hace en búfer con: #+COLUMNS: %40ITEM(Task) %9Effort(Previsión){:} %5CLOCKSUM %6TODO
;;(setq org-columns-default-format "%60ITEM(Task) %9Effort(Previsión){:} %5CLOCKSUM %6TODO")
;; (setq org-columns-default-format "%60ITEM(Task) %9Effort(Previsión){:} %5CLOCKSUM %6TODO %6STYLE %5BLOCKED(bloqui) %20SCHEDULED %20DEADLINE")
;; no me incluye el actual → ver org-clock-report-include-clocking-task
(setq org-columns-default-format "%60ITEM(Task) %6CLOCKSUM %5CLOCKSUM_T(hoy) %9Effort(Previsión){:} %6TODO %6STYLE %5BLOCKED(bloqui) %20SCHEDULED %20DEADLINE")

;; esto se usa también en agenda.
;; Si sólo quiero cambiar el tipo de letra, usar C-rueda

;; Para configurar la vista en columnas que sale en la agenda: Está en org-columns-current-fmt pero no hay que tocarla. Quizás tengo que hacerlo en „vista de agenda“.  De momento, con tocar org-columns-default-format ya vale

;; Varios estilos otros:
;; (setq org-columns-default-format "%50ITEM(Task) %17Effort(Estimated Effort){:} %CLOCKSUM %20SCHEDULED %20DEADLINE")

;; era: "%25ITEM %TODO %3PRIORITY %TAGS"

;; Muy interesante pero no tengo muchas citas con duración
;; org-agenda-columns-add-appointments-to-effort-sum
;; Hasta esto está…: org-agenda-default-appointment-duration

(set-face-background 'org-column "grey10") ; era grey30; demasiado brillante y poco contrastante con el 1r plano


;;;;;;; exportación (HTML y LaTeX y otros)
(setq org-export-html-coding-system (quote utf-8))
;; (setq org-export-html-divs '("preamble" "content" "postamble"))
(setq org-export-html-divs '("menu" "content" "postamble"))

;; no frenar la exportación si encuentra cosas raritas tipo [[uno:dos]] (que cree que es enlace pero no entiende). Poner 'mark los dejará con la cadena de texto ~ „BROKEN LINK: dos“ o algo así
(setq org-export-with-broken-links 'mark)
(setq org-export-with-archived-trees nil) ; no exportar los archivados. Si alguna vez los quiero, cambiar a 'headline. Creo que con ==nil me evito que tenga que buscar en _archive.org cada fichero

;; no preguntar si exportar babel o no, simplemente no ejecutarlo. Esto me evita montones de errores relacionados con babel (nombres de bloque, lenguajes sin configurar, …), me evita destrucción de los .org (me borra „RESULTS“, me quita nombres, …), me acelera la exportación, y me evita preguntas durante el proceso de exportación. A cambio de tener que exportar yo los babel a mano. Perfecto
(setq org-export-babel-evaluate nil)
;; pruebo a t: (setq org-export-babel-evaluate t)
;; Ver más en pruebas.org, sobre cómo exportar contenido de bloques

;; cuando hacía el Diplomarbeit puse esto:
(setq org-export-latex-title-command "%% 142857: \\maketitle")

(setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i")
(setq org-export-docbook-xsl-fo-proc-command "fop %i %o")
(setq org-export-docbook-xslt-stylesheet "fo/docbook.xsl") ; /usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl ← ¿poner ruta entera?
;; Por acertar en valores buenos. Aún no he probado esta exportación


;; nuevo exportador (org-export), anunciado en m8.2012 en 7.9
;;(require 'org-export)
;; luego (m2.2013) cambió y parece que no hace falta. org-export → ox      Instrucciones: http://lists.gnu.org/archive/html/emacs-orgmode/2013-02/msg00268.html
;;(require 'org-e-html)

;; M-x org-export-dispatch
;; escribir exportador: http://orgmode.org/worg/dev/org-export-reference.html

;; exportación asíncrona:
;; Para probar: con M-x org-export-stack para ver. C-c C-e para iniciar
;; „exportar en 2º plano“ consiste en abrir otra instancia de emacs, cargando todo el .emacs; eso lo veo bastante chapucero (bueno, „chapucero+elegante“). Pero es más rápido hacerlo síncronamente, y si tarda, esperar. ∴ Por eso, nil
(setq org-export-in-background nil)

;;;;;;; pasar árbol a JSON para asintarlo después
;; Es como si fuera ox-json
;; De ~ http://lists.gnu.org/archive/html/emacs-orgmode/2013-12/msg00415.html
;; Ej. ponerse en uno y hacer (org-exporta-árbol-a-fichero-json "/n/fi.json"), o usar org-exporta-árbol-con-id-concreto-a-fichero-json
(defun org-exporta-árbol-a-fichero-json (nombre-fichero)
  (require 'json)
  (let* ((tree 
          (save-restriction
            (org-narrow-to-subtree)
            (org-element-parse-buffer 'object nil)
            
            )
          ))
    (org-element-map tree (append org-element-all-elements
                                  org-element-all-objects '(plain-text))
      (lambda (x) 
        (if (org-element-property :parent x)
            (org-element-put-property x :parent "none"))
        (if (org-element-property :structure x)
            (org-element-put-property x :structure "none"))
        ))
    (write-region
     (let ((json-encoding-pretty-print t))
       (json-encode tree) 
       )
     nil nombre-fichero))
  )
;; probar: (org-exporta-árbol-con-id-concreto-a-fichero-json "curso-de-emacs-básico" "/home/dc/n/exporcurso.json")
(defun org-exporta-árbol-con-id-concreto-a-fichero-json (id-concreto nombre-fichero)
  "Dame un ID de árbol (definido en cajón de org) y lo exportaré a ese fichero"
  ;;(interactive)

  (ignore '( ;; ya no hace falta estoy pues ya va gracias a set-buffer
            (if (and 1 (equalp (buffer-name) " *server*") )
                (progn
                  (message "Detecto que estoy en *server*, no quiero ni estar ahí ni volver ahí")
                  ;;(previous-buffer) ;; no va
                  ;;(previous-buffer) ;; 2 veces no va
                  ;;(bury-buffer " *server*") ;; no va
                  (kill-buffer " *server*") ;; muy bestia
                  (message "Ahora estoy en %s" (current-buffer))
                  )
              )
            ))
  
  ;; ¡¡¡¡¿Por qué nada de esto funciona?!!!! Me sigue cambiando el búfer    ← ∴ era debido a org-id-goto. Hay que evitarlo y usar otra cosa. Ya va
  (save-selected-window
    (save-selected-frame
     (save-current-buffer
       (save-excursion
         (save-restriction
           (let ( ;no uso todo esto
                 (bu-orig (current-buffer))
                 ;; si este org-id-find falla…:  (org-id-find "curso-de-emacs-básico"), (org-id-find "curso-de-pronombres")
                 (dónde-está (org-id-find id-concreto))
                 )
             (assert dónde-está t "Si esto falla es que no ha encontrado el ID → ∴ quizás has de hacer org-id-update-id-locations")
             ;;(org-id-goto id-concreto) ;; *problema*, me cambia todo. No es cancelable.   HAY QUE EVITARLO. En vez de esto, usar set-buffer
             (set-buffer (find-buffer-visiting (car dónde-está)))
             (goto-char (cdr dónde-está))
             
             
             
             (org-exporta-árbol-a-fichero-json nombre-fichero)
             ;;(bury-buffer)
             (ignore '(
                       (message "Volviendo a búfer %s desde %s (no debería quedar yo a este 2º pues estaba usando save-current-buffer…)" bu-orig (current-buffer))
                       ;;(if (equalp (buffer-name) " *server*") (kill-buffer " *server*")) ;; cuidado conmigo
                       ;;(if (get-buffer " *server*") (kill-buffer " *server*")) ;; cuidadito
                       ;;(switch-to-buffer bu-orig) ;; extra
                       ))

             (message "Exportado a %s" nombre-fichero)

             )
           )))))  ; los save-
  )
;; ej. de uso: (org-exporta-árbol-con-id-concreto-a-fichero-json "curso-de-pronombres" "~/n/curpron.json")
;; o para probarlo desde ventana cualquiera: (global-set-key (kbd "<f9>") (lambda () (interactive) (org-exporta-árbol-con-id-concreto-a-fichero-json "curso-de-pronombres" "~/n/curpron.json")))


;;;;;;; publicación (org-publish)
;; 1.m7.2010: movido ahí para poder reusarlo en otros exportadores
(load-file "~/.org-defproyectos.el")

;; Y parecido: poder exportar los :cable:
(load-file "~/.org-publicable.el")

;;;;;;; vista de imágenes directamente dentro del búfer
;; De http://orgmode.org/worg/org-configs/org-config-examples.php#sec-2.2
(require 'iimage) ; si no lo hago, no encuentra iimage-mode-image-filename-regex
(add-to-list 'iimage-mode-image-regex-alist
             (cons (concat "\\[\\[file:\\(~?" iimage-mode-image-filename-regex
                           "\\)\\]")  1))

(defun org-toggle-iimage-in-org ()
  "display images in your org file"
  (interactive)
  (if (face-underline-p 'org-link)
      (set-face-underline 'org-link nil)
    (set-face-underline 'org-link t))
  (iimage-mode))

;;;;;;; ajustes para que los enlaces apunten a donde toca al exportar

;; org-link-file-path-type: supongo que está bien a 'adaptive; no me hace falta 'relative


;; fallito relacionado raro tras actualizar en m2.2017:    org-link-set-parameters: Symbol’s function definition is void: org-element-update-syntax. Por tanto me toca requerir org-element aquí:
(require 'org-element)


;; Esta guarradilla es para NNTP, que en m5.2015 se exportaban mal (quedaban sin protocol, parecían ficheros locales)
;; Es para tipo de enlace [[news:…]] (no [[nntp:…]])
(defun no-sigas-enlace-org (tag) (message "No implementado"))
(defun exporta-enlace-org-nntp (path desc format)
  "Esto permite usar news:hola.com que se exporta a nntp://…
Por cierto, falla patéticamente si incluyo algo como /etc/passwd que tiene líneas como:
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
(se cree que eso es un enlace)"
  (cond (
         (equalp format 'html)
         (concat "<a href=\"nntp://" path "\"\>" desc "</a>")
         )
        (t
         (concat "→→→→SIN IMPLEMENTAR ENLACE NNTP A: " path " (" desc ")←←←←")
         )
        )
  ;; (assert 
  ;;  (or 
  ;;    (equalp format 'html)
  ;;    (equalp format 'ascii) ;; con org v9 me pasaba
  ;;    )
  ;;  )
  ;; (concat "<a href=\"nntp://" path "\"\>" desc "</a>") ;; supongo que es nntp://algo, no nntp:algo

  )
;; versión desfasada (es de antes de org9.0):    (require 'org-element)   (org-add-link-type  "news" 'no-sigas-enlace-org 'exporta-enlace-org-nntp )
(org-link-set-parameters "news" :follow #'no-sigas-enlace-org :export #'exporta-enlace-org-nntp)

;; y me haría falta algo para exportar javascript:… Esto va, pero lo desactivo porque me complica cosas (y ẽ exportar a LaTeX):
(ignore '(
          (defun exporta-enlace-org-javascript (path desc format)
            "Esto permite exportar los javascript:alert('aa'); etc. Esto es algo feo y evitable; creo que es mejor dejar las partes de JS como HTML metido a mano con #+HTML, en vez de exigir a org que tome y exporte bien código JS."
            (assert 
             (or 
              (equalp format 'html)
              (equalp format 'ascii) ;; con org v9 me pasaba
              )
             )
            ;;(message path desc)
            (concat "<a href=\"javascript:" path "\"\>" (or desc path) "</a>")
            )
          (org-link-set-parameters "javascript" :export #'exporta-enlace-org-javascript)
          ))


(require 'org-id) ; Para gestionar IDs globalmente y poder enlazar entre ficheros. Esto lo pongo por claridad, pero no hace falta pues ya se estaba cargando.
;; Le digo explícitamente donde grabar esto para evitar que me lo ponga donde no toca („Its value is "/w/org-mode/testing/.test-org-id-locations"“, me pasó)
(setq org-id-locations-file "~/.emacs.d/.org-id-locations")
;; Por cierto, me apareció ~/.emacs.d/.test-org-id-locations, no sé porqué, pero me va bien

;; Los enlaces internos, exportarlos como #nombre-de-la-cabecera-destino, en vez de cosas como #org42c6660 o números al azar
;; Esto está basado en https://tecosaur.github.io/emacs-config/config.html#nicer-generated-heading y https://github.com/alphapapa/unpackaged.el#export-to-html-with-useful-anchors pero lo he adaptado y corregido
;; Si lo estás viendo en https://www.danielclemente.com/emacs/confi.html: el código está abajo en su sección
(load-file "~/.emacs.d/lisp/org-exportar-mejores-ids.el")

;; Comprobar con: (featurep 'org-id)
;;;;;;; no exportar enlaces radio (los < < < así > > >) a HTML

;; Prueba; esto cambia el enlazado, NO EL ENLAZANTE
(ignore '(
          (defun org-html-radio-target (a b c)
            (message "No exporto radio a HTML")
            "NOOOOOOOO"
            )
          ))

;;;;;; comunicación con otros programas, integración, …
;;;;;;; para que org abra ficheros como toca al hacer C-c C-o

;; Me estaba abriendo los .ods dentro de Emacs debido a que  ("\\.\\(sx[dmicw]\\|od[fgpst]\\|oxt\\)\\'" . archive-mode)  sale dentro de auto-mode-alist.

;; Por eso esto da 'emacs y no debería:
;; (assoc-default   "/home/dc/ptop/docu/intnet-01348-incidències-20090811.ods"   '(            ("[xX]modmap\\(rc\\)?\\'" . emacs)      ("\\.\\(sx[dmicw]\\|od[fgpst]\\|oxt\\)\\'" . emacs)    )   'string-match)

;; Prueba de que eso falla:
;; (org-open-file #("~/ptop/docu/INTNET-01348-Incidències-20090811.ods" 0 49 (org-attr nil)) nil nil nil)

;; En vez de quitar de ahí el .ods, lo añado a org-file-apps
(add-to-list 'org-file-apps '( "\\.\\(sx[dmicw]\\|od[fgpst]\\|oxt\\)\\'" . default))
;; Ahora, C-c C-o lo abre en OOo y C-u C-c C-o en emacs

;;;;;;; poder copiar texto con formato HTML desde w3m a sintaxis org
;;no es necesario, ya está en org-modules:
;;(require 'org-w3m)
;; Uso: Or press “C-c C-x M-w” in w3m buffer.
;; Que vaya en gnus también:
;; Puedo usar: org-w3m-copy-for-org-mode a mano; eso va

;;;;;;; poder tomar notas capture/remember desde conkeror (y otros programas)
(require 'org-protocol)
;; uso el protocolo „remember“ o „capture“

;; org-protocol://capture://p/blablabla ← usará la plantilla ?p


;;;;;;; para recargar todos los ficheros de org (todos los que han cambiado)
;; Esto antes estaba en repoooo_trae pero lo traje aquí (y desde repoooo_trae la invoco a través de emacsclient)
(defun org-revert-changed-org-buffers ()
  "Esto es mi versión de org-revert-all-org-buffers (la llamé org-revert-changed-org-buffers) pero sin el yes-or-no-p (que se ejecutaba siempre, no sólo cuando detectaba búfers sin guardar"
  (interactive)
  (save-excursion
    (save-window-excursion
      (mapc
       (lambda (b)
         (when (and (with-current-buffer b (eq major-mode (quote org-mode)))
                    (with-current-buffer b buffer-file-name)
                    (not (verify-visited-file-modtime b)))
           (switch-to-buffer b)
           (revert-buffer t (quote no-confirm))))
       (buffer-list))
      (when (and (featurep (quote org-id)) org-id-track-globally)
        (org-id-locations-load))))
  "Búfers de Org revertidos (sin preguntar)")


;; Experimento para revertir todo. ¿No tiene Emacs algo así? No debería hacer falta, pues ya tenemos auto-revert-mode etc, pero en la práctica a veces no funcionan
;; No sé si va bien del todo. Aún he visto un:  tramp-error: Wrong type argument: "integer-or-marker-p nil"
;;
;; Y de vez en cuando veo más problemas de tramp, como esto (sí, todo seguido):
;; Tramp: Inserting ‘/su:so@ocrb:/home/so/billing/src/steps/….py’...failed
;; Wrong type argument: "Wrong type argument", "integer-or-marker-p nil" [2 times]
;; tramp-error: Wrong type argument: "integer-or-marker-p nil"
;; error: "Can’t find a suitable init function"
;; Scan error: "Scan error", "Containing expression ends prematurely 1265 1266"
;; Wrong type argument: "Wrong type argument", "integer-or-marker-p nil"
;; Error during redisplay: (jit-lock-function 401) signaled (wrong-type-argument "integer-or-marker-p nil")
;; 
(defun revert-all-changed-buffers ()
  "Experimento basado en lo anterior (org-revert-changed-org-buffers), pero para cualquier fichero"
  (interactive)
  (save-excursion
    (save-window-excursion
      (mapc
       (lambda (b)
         (when (and 
                (with-current-buffer b buffer-file-name)
                (file-exists-p (with-current-buffer b buffer-file-name))
                (not (verify-visited-file-modtime b)))
           (message "Revirtiendo búfer de fichero %s" (with-current-buffer b buffer-file-name))
           (switch-to-buffer b)
           (revert-buffer t (quote no-confirm))
           (message "Revertido búfer de fichero %s" (with-current-buffer b buffer-file-name))
           ))
       (buffer-list))
      ))
  "Todos búfers ficherantes revertidos (sin preguntar)")

;;;;;; complementos útiles y paquetes
;;;;;;; otras búsquedas: de proyectos parados
;; Esto es para: C-c a #
;; No me ayuda mucho pues ya conozco bien que tengo muchos proyectos atrasados
( setq org-stuck-projects
       '(
         ;;"+LEVEL=2/-IS-MALFAR-HECHO-DONE-CORREGIDO" ; qué se considera „proyecto“. Los ya acabados no lo son
         "proj"
         ("FARU" "HACER" "TODO") ; lista de claves que identifican proyectos no parados. No pongo „BONUS“ pues considero que si sólo hay „BONUS“ y ningún „FARU“, está parado
         ("nuna") ; etiquetas de proyectos no parados
         nil ; expre de proyectos no parados
         )
       )
;;;;;;; org-mouse
;; mmm… esto proporciona varias cosas:
;; - hacer clic en estrellitas a la izquierda de la cabecera para expandir/contraer → bueno
;; - hacer clic con botón derecho en el fondo para tener un gran menú → malo; no me gusta mucho. Demasiadas cosas privadas al alcance
;; Así que por ahora lo desactivo; tampoco tengo mucha necesidad… 4.m2.2010
;;(require 'org-mouse)

;;;;;;; notas a pie de página, referencias, org-footnote
;; Eso de las referencias ([1], luego C-c C-c, …) no lo uso mucho
(setq org-footnote-section "Referencias")
;;;;;;; gestión de ficheros adjuntos
;; Básicamente: lo quiero
(require 'org-attach)
;;;;;;; remember (para notas rápidas de org)
;; Desde 25.m6.2010 uso org-capture y ya no necesito org-remember
;; Usé: org-capture-import-remember-templates
;; Configuración vieja (para remember) en cdv

;;;;;;; org-capture (sucesor de org-remember). Para notas rápidas de org
(require 'org-capture) ; por lo visto necesario cargarlo así desde m6.2011

;;;;;;;; configuración básica, no sé si necesaria
(setq org-directory "~/org")
(setq org-default-notes-file (concat org-directory "/malgrave.org"))
;; C-c m es para org-capture, igual que antes era para org-remember
(define-key global-map "\C-cm" 'org-capture)
;; Dijo Carsten en primer aviso:
;;      You may also use `C-c r' once you have decided to move over to
;;      the new implementation.

;;;;;;;; plantillas para capture

(setq org-capture-templates
      '(
        ;; ¿quizás añadir DEADLINE 15 días automáticamente al responder correos?
        ;; ¿versión resumida con título=enlace?
        ("c" "Correo (para responder)" entry
         ;; (file+headline "~/wiki/Correle.org" "responder bien algunos correos largos")
         (id "responder_correo")
         "*** \BONUS «%:subject», de «%:from», del %u\n    DEADLINE: %^{¿Cuándo le habré respondido? (máx. 15 días)}t\n%a\n%?")
        ;; probar éste ← nunca lo he usado
        ;; ("r" "Correo sobre ruidos que he de incluir en mi página (para responder)" item
        ;;  (id "cosas-de-ruido-para-mi-web")
        ;;  "- [ ] %a (del %u)\n")

        ;; ver en /momentos concretos/ sobre éstos
        ("o" "Momentos puntuales")
        ;; medir „mis interrupciones“ (ver ahí)
        ("oi" "Interrupción" item
         (id "341af785-ed30-4f11-abd2-e62b4e25f7ad")
         "- %U %^{Motivo de la interrupción}\n"
         :immediate-finish t
         )
        ("od" "Distracción" item
         (id "13934b83-740f-45d2-854d-8684c5dd960b")
         "- %U %^{Qué pasa y cómo me siento}\n"
         :immediate-finish t
         )
        ("oe" "Ahora quiero empezar a trabajar. Check-in (ẽ opencraft)" item
         (id "e72230d2-9164-4e0b-abb1-297fb8acb437")
         "- %U\n"
         :immediate-finish t
         )
        ("oa" "Ahora quiero acabar de trabajar. Check-out (ẽ opencraft)" item
         (id "f56968e8-b061-4f24-b406-6553f40c5dbd")
         "- %U\n"
         :immediate-finish t
         )

        ;; Esto va de medir el /nivel de felicidad/, y en concreto de /medir la productividad/. He intentado muchas formas automáticas (y más de 20 para medir la antiproductividad y el estrés) pero las manuales son más fáciles. Ésta es manual
        ;; Hago copiar+pegar aunque quizás hay forma mejor
        ;; „o“ de mOmento“, „p“ de „productividad“. Luego números (11 en total). El 10 es como A
        ("op" "Productividad (nivel de felicidad respecto a mi pr.)")
        ("op0" "Mi opinión sobre mi productividad es: 0/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 0/10\n" :immediate-finish t )
        ("op1" "Mi opinión sobre mi productividad es: 1/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 1/10\n" :immediate-finish t )
        ("op2" "Mi opinión sobre mi productividad es: 2/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 2/10\n" :immediate-finish t )
        ("op3" "Mi opinión sobre mi productividad es: 3/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 3/10\n" :immediate-finish t )
        ("op4" "Mi opinión sobre mi productividad es: 4/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 4/10\n" :immediate-finish t )
        ("op5" "Mi opinión sobre mi productividad es: 5/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 5/10\n" :immediate-finish t )
        ("op6" "Mi opinión sobre mi productividad es: 6/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 6/10\n" :immediate-finish t )
        ("op7" "Mi opinión sobre mi productividad es: 7/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 7/10\n" :immediate-finish t )
        ("op8" "Mi opinión sobre mi productividad es: 8/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 8/10\n" :immediate-finish t )
        ("op9" "Mi opinión sobre mi productividad es: 9/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 9/10\n" :immediate-finish t )
        ("opA" "Mi opinión sobre mi productividad es: 10/10" item (id "af9f55d2-c45f-4c49-8c9c-297a9ad55488") "- %U: 10/10\n" :immediate-finish t )

        ;; era: mejorar tareas comunes y mi entorno de trabajo
        ("e" "Tarea sobre mejorar entorno (toma lugar actual y portapapeles y lo pone en miso.org)" entry
         ;;  (file+headline "~/wiki/miso.org" "las que no sé clasificar en otros ficheros")
         (id "tareas-de-entorno-sin-clasificar")
         "*** \BONUS %^{Título}\n    SCHEDULED: %t\n%?\n\n %a\n")
        ;; para cosas sueltas (ej. notas que no puedo procesar porque tengo mucho trabajo cuando me la dicen)
        ;; Quizás cambiarlo por „l“ de „lo que sea“
        ("m" "malgrave (para lo que sea, notas de cualquier tipo)" entry
         ;;viejo: (file+headline "~/org/malgrave.org" "Notas sueltas, tomadas con „remember“")
         (id "notas-sueltas-de-lo-que-sea")
         ;; creo que va bien que lo pregunte en línea de modo porque así me obligo a escribir algo corto
         ;; no necesito ni marca de tarea ni tiempo agendado, pues el contenedor lo tiene. Quiero 1 estrés, no 6
         ;; "** [#C] %^{Notilla retardarble}\n%?"   ; ← demasiado difícil escribir título Y texto
         "** [#C] %?")
        ("u" "URL para mirar más adelante" entry  ; puede venir de conkeror
         (id "notas-sueltas-de-lo-que-sea")
         ;; "** \BONUS [#C] URL para mirar, del %U\n   SCHEDULED: %t\n   %a\n%?«%i»\n"
         ;; y más simple, sin cargarme de trabajo
         "** [#C] URL para mirar, del %U\n- %a\n%?"
         )
;;      ("p" "Persona (contacto) que ha enviado un correle" entry
;;       (id "056e4865-ffc7-4171-ab6f-133dd538ddb1")
;;       "** %?%(org-contacts-template-wl-name) %^g
;;    :PROPERTIES:
;;    :EMAIL: %(org-contacts-template-wl-email)
;;    :END:
;; "
;;       )

        )
      )

;;;;;;;; ideas para nuevas plantillas
;; MALFAR: pues no necesito buscar ideas; ya me vendrán solas si hace falta.
;; - para apuntar valor de EP (añadiendo a tabla) ← no, bc
;; - para llevar la contabilidad; ver org-ledger~~ ← no, bc
;; - para cualquier idea que me distraiga ← ya tengo
;; - para añadir un hijo a *cualquier* cabecera de mi wiki global ← no, quiero hacerlo mirando

;;;;;;; org-choose (para gestión de elecciones - toma de decisiones)

;; ya he definido sus palabras clave (arriba) y he cargado org-choose (abajo), para eso había que poner el load-path bueno (con contrib)

;; pues no me va, ni siquiera con:
;; #+CHOOSE_TODO: REJECTED(r) NOT_CHOSEN(n,-) MAYBE(,0) LEANING_TOWARDS(l) CHOSEN(c,+) 
;;
;; MALFAR: No me hace falta, uso „∴“ y poco más

;;;;;;; org-invoice: para hacer facturas
;; MALFAR: burocracia añadida donde no hace falta. Mejor me lo hago yo mismo

;;;;;;; org-R: para hacer gráficos con R. ¡No es babel! Sino versión previa, menos potente pero más especializada
;;(require 'org-R)
;; 25.m2.2010: justo ahora que había conseguido configurarlo bien para mi borde1px.org, ¡lo han quitado de org! Dicen que hay que usar org-babel envez.

;;;;;;; algunos lenguajes de org-babel que están en contrib
;; (add-to-list 'load-path "/w/org-mode/contrib/babel/langs")
;; (require 'ob-fomus)


;;;;;;; org-babel (para todo): programación literaria, documentos completos, …
;; Formas viejas de cargarlo: ver en cdv
;;;;;;;; Le cargo lenguajes
(org-babel-do-load-languages
 'org-babel-load-languages
 '((R . t)
   (C . t)
   (ditaa . t)
   (dot . t) ; graphviz
   (emacs-lisp . t)
   ;;   (fomus . t)
   (gnuplot . t)
   ;;   (haskell . t) ; ← no lo uso mucho y me molesta al exportar
   (js . t) ; con node.js
   ;; (ledger . t)  ; ← ya no va
   (lilypond . t)
   (ocaml . nil)
   (perl . t)
   ;; estaría bien: prolog. Pero en m1.2023 aún no hay ob-prolog, creo
   ;; (prolog . t)
   (plantuml . t)
   (python . t)
   (ruby . t)
   (screen . nil)
   (shell . t) ; no es „sh“ sino „shell“, y sí que va
   (sql . t)
   (sqlite . t)))
;;;;;;;; cargar la biblioteca de babel; por lo visto no se hace solo
;; Para hacer llamadas usa: #+call (or synonymously #+function or #+lob) 
(ignore '(
          ;; lo desactivo porque tarda mucho (más de 3 segundos en cada arranque) y no la uso; ni sé bien qué es
          (org-babel-lob-ingest "/w/org-mode/contrib/babel/library-of-babel.org")
          ))

;; Normalmente quiero que „#+begin_src perl“ se exporte, no ejecute
;; Usar org-babel-default-inline-header-args
;;;;;;;; algunos ajustes para algún lenguaje
;; (setq org-plantuml-jar-path "/w/plantuml.jar") ; ¿por qué?
;; (setq org-plantuml-jar-path "/usr/share/plantuml/plantuml.jar") ; instalado por paquete „plantuml“
;; Con esto le engaño: le digo que uso mi comando „plantuml“ que en realidad no es un comando plantuml sino uno de java. Lo haga para pasarle el -mx512m. Si no lo paso, peta tontamente con „Exception in thread "Thread-0" java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached“ debido a correr bajo mi „ulimit -v 6000123“. Con el -mx512m (¡o con -mx64m!) ya no peta
(setq org-plantuml-exec-mode 'plantuml)
(setq org-plantuml-executable-path "java -mx512m -jar /usr/share/plantuml/plantuml.jar")

(setq org-babel-js-cmd "nodejs")
;; No funciona o no me hace caso (parece que hay que reiniciar org de algún modo):
;;(setq org-babel-python-cmd "python")
;;(setq org-babel-python-cmd "python3")
;;(setq org-babel-python-cmd "pypy")

;;;;;;;; Nuevos lenguajes que le defino
(defun org-babel-execute:php (body params)
  "Ejecutar PHP. Basado en una de SASS.
Esto me permite poner bloques que son una línea de código (no hace falta el <?…)
Más sencillo que el de https://github.com/steckerhalter/ob-php/blob/master/ob-php.el"
  (let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
         (file (cdr (assoc :file params)))
         (out-file (or file (org-babel-temp-file "phpob-out-")))
         (cmdline (cdr (assoc :cmdline params)))
         (in-file (org-babel-temp-file "phpob-in-"))
         (cmd (concat "php " (or cmdline "")
                      " " (org-babel-process-file-name in-file)
                      " >" (org-babel-process-file-name out-file))))
    (with-temp-file in-file
      (insert "<?php\n")
      (insert (org-babel-expand-body:generic body params))
      (insert "\n?>")
      )
    (org-babel-eval cmd "")
    (if file
        nil ;; signal that output has already been written to file
      (with-temp-buffer (insert-file-contents out-file) (buffer-string)))))

;;;;;;; org-depend, para expresar dependencias entre tareas
;; BONUS: leer y usar; http://orgmode.org/worg/org-contrib/org-depend.php
;; Ponerlo en org-modules

;;;;;;; org-crypt, para cabeceras cifradas dentro de un fichero sin cifrar
(require 'org-crypt)
(setq org-tags-exclude-from-inheritance (quote ("crypt"))) ; En realidad da igual porque no uso esto

;;(org-crypt-use-before-save-magic)
;; org-crypt-use-before-save-magic hace que el grabado de cualquier .org sea muy lento (aunque no use org-crypt). Como yo sé dónde lo uso y dónde no, puedo optimizar. Igualmente es lento, por eso lo ignoro temporalmente y me ahorra varios segundos al día
(ignore '(
          (add-hook
           'org-mode-hook
           (lambda () 
             (if (and buffer-file-truename (string-match-p "\\(~\\|/home/dc/.mirp1?\\|/home/dc/\\)/org/" buffer-file-truename))
                 (add-hook 'before-save-hook 'org-encrypt-entries nil t)
               (message "No usaré org-encrypt en este búfer")
               )
             ))
          ))


;;(setq org-crypt-key "ABCDEF01") ; o algo así. Una clave pública GPG. Si no se pone, se usa cifrado simétrico

;; coordinación con auto-save-mode. Le pido que en cada auto-save que haga me lo cifre
(setq org-crypt-disable-auto-save 'encrypt)
;; Esto me molestará pidiendo la clave sólo cuando he dejado descifrada alguna sección. Si no, no. Está muy bien

;; para descifrar: C-c C-r
;; para cifrar: se cifra solo al grabar

;; BONUS: ¿cómo lo hace al grabar para no tener que preguntarme la clave? Muy fácil: si la entrada no ha cambiado, ya sabe cómo estaba cifrada y no ha de repedir clave. Si cambió, sí que ha de repedirla.

;;;;;;; añadir la previsión meteorológica a la agenda
;; http://julien.danjou.info/google-weather-el.html

;;;;;;; transponer párrafos
(defun org-transpose-paragraphs (arg)
  (interactive)
  (when (and (not (or (org-at-table-p) (org-on-heading-p) (org-at-item-p)))
             (thing-at-point 'sentence))
    (transpose-paragraphs arg)
    (backward-paragraph)
    (re-search-forward "[[:graph:]]")
    (goto-char (match-beginning 0))
    t))

;; En realidad no me gusta; lo lía mucho. Puedo perder rápidamente un párrafo o mezclarlo con lo que no toca si hago esto.
;;(add-to-list 'org-metaup-hook    (lambda () (interactive) (org-transpose-paragraphs -1)))
;;(add-to-list 'org-metadown-hook   (lambda () (interactive) (org-transpose-paragraphs 1)))

;;;;;;; org-velocity, es para buscar cabeceras con una tecla + expregu, ir hacia ellas o añadir una en caso de no encontrarla
;; (require 'org-velocity)
;; Pero… con anything+capture tengo ya suficiente para eso. Y es más cómodo

;;;;;;; org-contacts, gestor de personas
;; https://repo.or.cz/org-contacts.git
(add-to-list 'load-path "/w/org-contacts")
(require 'org-contacts)
(setq org-contacts-files '("~/wiki/Personas.org"))

(defun org-contacts-insinúate-a-wl nil
  (require 'mailabbrev) ; usar ~/.mailrc. Sólo lo necesito para que defina (mail-abbrev-in-expansion-header-p) pues org-contacts la usa
  (add-hook 'wl-draft-mode-hook
            (lambda ()

              ;;(setq completion-at-point-functions (remove completion-at-point-functions 'tags-completion-at-point-function)) ; por lo visto  ← error, parámetros al revés
              (setq completion-at-point-functions (remove 'tags-completion-at-point-function completion-at-point-functions)) ; ← ¿pero esto para qué es?
              ;; (setq completion-at-point-functions '()) ; más bestia
              
              (add-to-list 'completion-at-point-functions
                           'org-contacts-message-complete-function)
              
              ;;forma violenta (perdiendo bbdb):   (define-key wl-draft-mode-map "\M-\t" nil) ; esencial para que M-tab no sea capturado por bbdb
              ;; forma en que conviven bbdb (M-tab) y org-contacts (tab):
              ;; Pero no quiero BBDB ya.
              (define-key wl-draft-mode-map "\t" 'complete-symbol)
              ))
  ;; probando: (setq wl-draft-mode-hook nil)

  )
(org-contacts-insinúate-a-wl) ;; ← aparentemente funciona

;;;;; Muse
;; ignoro Muse pues ya migré todo a .org y no lo uso. Lo usaba en 2007 (¿y algo antes?), hasta 2010 o así, cuando cambié a org
;; Además en m3.2020 lo quité de .emacs. Ver cdv para recuperarlo

;;;;; Planner-mode (no lo uso)
;; . Se integra más con muse pero es básicamente un muse con un poco de estructura para la gestión de tareas. org-mode es mucho más completo: exportación, agenda, publicador, ... No necesito planner por ahora (03.2008) porque con Muse ya me basta
;;(add-to-list 'load-path "~/.emacs.d/planner")
;;(setq planner-project "WikiPlanner")
;;     (setq muse-project-alist
;;           '(("WikiPlanner"
;;             ("~/plans"   ;; Or wherever you want your planner files to be
;;             :default "index"
;;             :major-mode planner-mode
;;             :visit-link planner-visit-link))))
;;(require 'planner) 







;;;;; una cosa rara: „enriched-text“
;; Intento desactivarlo
;; esto peta:
;; (unload-feature 'enriched)
(define-minor-mode enriched-mode
  "Desactivo una cosa con vulnerabilidad"
  :group 'enriched
  :lighter " Enriched")
(defun enriched-decode (from to) (message "Desactivado enriched. Páralo con C-g pues se cuelga") nil)


;;;;; yaml-mode
;; Lo quiero usar para megaidp.yaml
;; Esto no es del todo bueno pero es inicio:
(add-hook 'yaml-mode-hook
          (lambda ()
            (define-key yaml-mode-map (kbd "C-c !") 'org-time-stamp-inactive)
            ))

;;;; Comunicaciones (chat, jabber, correo)
;;;;; jabber
;;;;;; carga de emacs-jabber

;; temporalmente desactivado
;;(ignore '(

;; Vaya, le hace falta hexrgb a jabber-muc-nick-coloring.el, al menos el m9.2010. Pues lo cargo. Lo provee emacs-jabber también pero es el mismo
;; (add-to-list 'load-path "~/.emacs.d/icicles/") (require 'hexrgb)    ; ← confío en que en 2016 ya carga el suyo propio

;; m9.2022 comento pues cargaré por MELPA
(ignore '(
(if (file-directory-p "/w/emacs-jabber/") ; probando a cargar de /w
    (progn
      (message "Cargando emacs-jabber de /w/")
      (setq load-path (cons (expand-file-name "/w/emacs-jabber/") load-path))
      (load "jabber-autoloads")
      (require 'jabber) ; si tengo autoloads, creo que no me hace falta esto otro → pero tengo que usar más eval-after-load → más trabajo
      )

  ;; Para la versión de desarrollo (la 0.7.1 ya no la uso) ← ver cdv

  ;; Falla en m3.2021: jabber-activity.el:45:1: Error: Wrong number of arguments: (3 . 3), 2
  ;; Creo que es por: make-obsolete
  ;; Es por esto en jabber-menu.el:   (make-obsolete 'jabber-menu "set the variable `jabber-display-menu' instead.")
  ;; Da: (wrong-number-of-arguments (3 . 3) 2)
  ;; Les falta parámetro WHEN
  ;; Los comento
  
  )
))

;; m9.2022: lo cargo por ELPA (bueno, MELPA) pues es más nuevo:
(require 'jabber)

;;;;;; arreglo algunas teclas
;; Esto me ha comido el C-x C-j. Lo restauro
(define-key ctl-x-map "\C-j" acceso-funciones-varias-map)
;; Y le añado varias funciones útiles; adaptado de ~/.emacs.d/emacs-jabber/jabber-keymap.el
(progn 
  (define-key acceso-funciones-varias-map "\C-c" 'jabber-connect-all)
  (define-key acceso-funciones-varias-map "\C-d" 'jabber-disconnect)
  (define-key acceso-funciones-varias-map "\C-r" 'jabber-switch-to-roster-buffer)
  (define-key acceso-funciones-varias-map "\C-j" 'jabber-chat-with)
  (define-key acceso-funciones-varias-map "\C-l" 'jabber-activity-switch-to)
  (define-key acceso-funciones-varias-map "\C-a" 'jabber-send-away-presence)
  (define-key acceso-funciones-varias-map "\C-o" 'jabber-send-default-presence)
  (define-key acceso-funciones-varias-map "\C-x" 'jabber-send-xa-presence)
  (define-key acceso-funciones-varias-map "\C-p" 'jabber-send-presence)
  )


;;;;;; elegir qué avisos quiero ver y cuáles no
;; BONUS: definir una función como jabber-presence-default-message pero que devuelva nil en ciertos casos, y ponérsela en jabber-alert-presence-message-function. O pedir. O buscar hecho

;;;;;; intento que pite tras ciertos eventos

;; Quiero que de alguna forma avise cuando pasen cosas
(add-hook 'jabber-alert-message-hooks 'jabber-message-beep)
;; En presence-hooks ha de ser jabber-presence-beep, con *presence*
(add-hook 'jabber-alert-presence-hooks 'jabber-presence-beep)
;; Y que pite de verdad, sin usar (beep)
;;(eval-after-load "jabber" 
(define-jabber-alert beep "Beep on event"
  (lambda (&rest ignore) (pita-de-verdad-con-tono-medio)))
;;)

;;;;;; ficheros de registro y caché
;; sacado de confi de 0.7.1; falta ajustar
(set 'jabber-avatar-cache-directory "~/.emacs.d/jabber-avatars/")
(set 'jabber-debug-log-xml t)
(set 'jabber-debug-keep-process-buffers t) ; mientras depuro lo de TLS lo necesito, pues si no no veo nada (http://sourceforge.net/p/emacs-jabber/bugs/64/)
(set 'jabber-global-history-filename "~/.emacs.d/jabber_global-log")
(set 'jabber-history-dir "~/.emacs.d/jabber-log")
(set 'jabber-history-enabled t)
(set 'jabber-use-global-history nil)

;;;;;; lista de cuentas y de formas de conexión

;; Esto me está impidiendo conectarme a oT
;;(setq jabber-use-sasl nil) ; esto es para la cuenta 142857@jabber.com
;; Pues con jabber.com acaba diciendo:  Authentication failure: no suitable SASL mechanism found
;; Después de un: receive (stream:features nil)
;; Dice Magnus que puede ser error de jabber.el
;;
;;(setq jabber-use-sasl t) ; y esto creo que es para la oT desde casa (para ¬ desde casa ya va bien nil)
;; cosas de ssl → ver en otra sección

(setq jabber-use-sasl t) ; como no uso oT, vuelvo a dejarlo como estaba. 29.m7.2014: Parece que ya no me entra en jabberes.org, probar a nil de nuevo si sigue pasando

;;(setq jabber-connection-ssl-program 'openssl) ; probando, no sé si hace algo. Supongo que lo que defina en cada cuenta individual ya va.
;; (setq jabber-connection-ssl-program nil) ; va bien

;; también me hizo falta esto una vez: (defalias 'open-ssl-stream 'open-tls-stream), no sé si es muy viejo


;; Toda la configuración de cuentas, con claves etc. → ver privado.el

;;;;;; sistema de envío de mensajes para que la conexión no se corte

;; Quizás va bien QUITAR esto. Es lo anterior al jabber-whitespace-ping-start que programó
;; m10.2022: lo quito
;; (require 'jabber-keepalive)
;; (setq jabber-keepalive-interval 30)

(add-hook 'jabber-post-connect-hooks 'jabber-keepalive-start)
;; esto de arriba es la clave para que funcione con OpenFire, creo

;;;;;; colores para jabber

;; colores para jabber
(set-face-foreground 'jabber-chat-prompt-local "#77f")
(set-face-foreground 'jabber-roster-user-online "#77f")
(set-face-foreground 'jabber-chat-prompt-foreign "#f22") ; no tan rojo

;; y aspecto
(set-face-attribute 'jabber-title-large nil :height 1.0) ; títol de dalt (inútil)
(set-face-attribute 'jabber-title-medium nil :height 1.0) ; nom del meu compte

;;;;;; forma de mostrar el texto de las conversaciones
(setq jabber-chat-fill-long-lines nil) ; ¡no quiero limitarme a 80 letras por fila!

;;;;;; algo de registro de cambios de estado (que marque la hora)
;; esto es útil para que quede registrado en „*Messages*“
(defun mi-jabber-presence-default-message--que-añade-hora (who oldstatus newstatus statustext)
  "Encapsula jabber-presence-default-message y añade hora"
  (let ((texto (jabber-presence-default-message who oldstatus newstatus statustext)))
    (if texto (concat texto " [" (format-time-string "%H:%M:%S" (current-time)) "]") nil)
    ))

(setq jabber-alert-presence-message-function  'mi-jabber-presence-default-message--que-añade-hora) ; era jabber-presence-default-message

;;)) ; fin de ignore

;;;;; gnus

;; Probé GNUS para correo hace tiempo y me pareció poco apropiado (más bien era para NNTP). Ahora que lo uso, me empieza a gustar. Cada vez lo personalizo más
;; En m9.2011 ya hace tiempo que no lo uso, pues Wanderlust me vale para todo. Sólo usaba gnus en Lòvic para cuenta mala, y me daba varios problemas. Mejor sólo Wanderlust (hasta que le toque el turno a gnus otra vez para superarlo). Por tanto ignoro gnus:
(ignore '(
;;;;;; carga

          ;; Preferir la versión de desarrollo. Al menos al ser fijo me preocuparé de que funcione 1 vez, no 1 en cada actualización de Emacs
          ;; 28.m9.2009: creo que esto es mala idea pues: 1) Los de Emacs saben mejor que yo cómo hacer funcionar Gnus. 2) La novedad en CVS no será muy grande; de hecho está quieto desde hace años.  → ignoro esta preferencia de CVS
          (ignore '(
                    (if (file-directory-p "/w/gnus/lisp/")
                        (progn
                          (message "Cargando Gnus de /w/")
                          (setq load-path (cons (expand-file-name "/w/gnus/lisp") load-path))
                          ;; si esto falla es que hace falta hacer ./configure && make
                          (require 'gnus-load)
                          )
                      )
                    ))


          (require 'gnus) ; en teoría no hace falta, pero es para que las definiciones de abajo no fallen por no existir
          (require 'message) ; lo da gnus y es para la faz message-header-name

          (setq gnus-init-file "~/.emacs.d/gnus/gnus.el")
          (setq gnus-startup-file "~/.emacs.d/gnus/newsrc")
          (setq gnus-directory "~/.emacs.d/gnus/datos/") ; para cosas temporales (cabeceras, ~caché, etc) pero también algunos ficheros de configuración (ej. para RSS)
          (setq gnus-cache-directory (concat gnus-directory "caché"))
          (setq gnus-article-save-directory (concat gnus-directory "artículos"))
          (setq gnus-kill-files-directory (concat gnus-directory "ficheros-kill"))
          (setq gnus-agent-directory (concat gnus-directory "agente"))
          (setq gnus-dribble-directory (concat gnus-directory "dribble"))

          ;; me lo asigno para Gnus
          (setq mail-user-agent 'gnus-user-agent)

;;;;;; sus faces (de gnus)
;;;;;;; Listado de grupos
          ;; los grupos nnimap salen así
          (set-face-foreground 'gnus-group-mail-3-empty "magenta3") ; era magenta4, muy oscuro
          (set-face-foreground 'gnus-group-mail-3 "magenta2") ; era magenta4, muy oscuro
          ;; Ya van bien

;;;;;;; Al redactar mensaje nuevo
          ;; (No confundirme: message es de gnus, no es genérico)
          ;; al redactar un mensaje nuevo, sale arriba para nombres de cabecera
          (set-face-foreground 'message-header-name "LightGreen") ;era DarkGreen
          (set-face-foreground 'message-header-other "#fe6") ;era #b00000
          ;; línea que separa cabeceras de cuerpo
          (set-face-foreground 'message-separator "white") ;era blu3
          (set-face-background 'message-separator "blue4") ;era unspecified
          ;; al anexar un fichero sale un texto así
          (set-face-foreground 'message-mml "white") ; era ForestGreen
          (set-face-background 'message-mml "ForestGreen") ; era unspecified
;;;;;;; Sumario (lista de mensajes)
          ;; los marcados con !
          ;; Una vez me los encontré algo cambiados (después de trastear). Pero ya va bien
          (set-face-foreground 'gnus-summary-normal-ticked "#f00") ; era firebrick
          (set-face-foreground 'gnus-summary-normal-read "#0b0") ; era DarkGreen, muy oscuro

;;;;;;; Al responder mensaje citándolo
          (require 'gnus-cite) ; si no, falla y ni arranca Emacs
          (set-face-foreground 'gnus-cite-1 "#dd0") ; era light blue, muy invisible. Y „yellow“ brilla mucho
          (set-face-foreground 'gnus-cite-2 "green")
          (set-face-foreground 'gnus-cite-3 "orange")

;;;;;;;; Al responder mensaje cualquiera
          (require 'gnus-art) ; por si acaso
          (set-face-foreground 'gnus-signature "#444") ; esconde un poco la firma (¡si la detecta!)

;;;;;; fin de comentario para ignorar todo
          ))
;;;;; wanderlust (es muy bueno; buen competidor para Gnus)
;;;;;; carga de wanderlust
;; 10.10.2008: lo desactivo, porque ya uso Gnus... :-) No sé si eso es bueno o malo.
;; 8.m6.2010: vuelvo a probarlo porque no estoy muy contento con Gnus: no mejora (mi configuración tampoco), es lento, … Hay que hacer: Ai wl
;; 18.m6.2010: paso de 2.14 (wl) a 2.15.9 (wl-beta) pues 2.14 falla un poco. Hay que hacer:   Ai wl-beta
;; m12.2017 sigo con 2.15.9
;; m12.2018 con 2.15.9. Pero algunos directorios han cambiado
;; m9.2020: emacs ha desfasado algunas cosas (ẽ make-coding-system, etc.) que hacen que 2.15.9 no vaya.  Pruebo 2.15.9+0.20200822-1 (en vez de 2.15.9+0.20190919-1) → ∴ actualicé flim también, era por esto (mel.el)
;; m3.2021: tras actualizar emacs, falla por eof-block-branches (flim)

;; No cargar de /usr/share/emacs/site-lisp sino de /usr/share/emacs23/site-lisp (o 24… o 25…) pues el primero es versión sin compilar y causa problemas gordos (ej. con eshell); ver mensaje de Glenn Morris sobre fallo eshell-Wanderlust

(if (file-directory-p "/w/wanderlust/")
    (progn
      (message "Cargando wanderlust de /w/")
      (setq load-path (cons (expand-file-name "/w/wanderlust/wl") load-path))
      ;; y compañeros
      (setq load-path (cons (expand-file-name "/w/wanderlust/elmo") load-path))
      ;; flim==std11. apel==pccl
      (setq load-path (cons (expand-file-name "/w/apel") load-path))
      (setq load-path (cons (expand-file-name "/w/flim") load-path))
      (setq load-path (cons (expand-file-name "/w/semi") load-path))

      ;; problemilla al ver mensaje:
      ;; (load-file "/w/flim/mel-q-ccl.el")
      ;; (defvar eof-block-branches)
      ;; (setq eof-block-branches nil)
      ;; (setq eof-block-reg nil)

      ;; sigue pasando esto:
      ;; Scoring...done
      ;; Eager macro-expansion failure: (void-variable eof-block-branches) [2 times]
      ;; let: Symbol’s value as variable is void: eof-block-branches
      ;; Ver Correle.org

      )
  )
;; O si no es de /w/::
;; (add-to-list 'load-path "/usr/share/wl/wl/")
;; (add-to-list 'load-path "/usr/share/wl/elmo/")
;; (add-to-list 'load-path "/usr/share/emacs/site-lisp/flim/")
;; (add-to-list 'load-path "/usr/share/emacs/site-lisp/apel/")
;; (add-to-list 'load-path "/usr/share/semi/")

;; esta línea hace falta en m2.2017 para cargar wl debido a que en emacs m11.2016 quitaron los default-*
;; m3.2021: parece que ya no
;; (setq default-truncate-lines nil)

;; esto hace falta desde ~m12.2017 porque lo quitaron en oficial
;; m3.2021: parece que ya no
;; (setq mail-yank-hooks nil)

(require 'wl)
(require 'sasl-xoauth2)

;; No sé si lo tengo que hacer a mano, o hay forma mejor. A mano me iba, así que lo haré aquí
(progn
  (add-to-list 'sasl-mechanism-alist '("XOAUTH2" sasl-xoauth2))
  (add-to-list 'sasl-mechanisms "XOAUTH2")
)


;; si falla wl-news toca hacer esto:
;;root@lovic:/usr/share/emacs/site-lisp/wl/wl# ln -s wl-news.el.in wl-news.el
;; Me pasa tanto con .el como con .elc
(defconst wl-news-news-alist nil)


;;;;;; activo wanderlust como correlador por defecto en algunos lados
;; De momento sé que no quiero Wanderlust en trabajo pues es correo personal
(unless (equal "lovic" (system-name))

  (if (boundp 'mail-user-agent)
      (setq mail-user-agent 'wl-user-agent))
  (if (fboundp 'define-mail-user-agent)
      (define-mail-user-agent
        'wl-user-agent
        'wl-user-agent-compose
        'wl-draft-send
        'wl-draft-kill
        'mail-send-hook))
  )


;;;;;; configuración de IMAP y SMTP

;; IMAP
(setq elmo-imap4-default-server "imap.gmail.com")
;; elmo-imap4-default-user → ver privado-nocable.l
(setq elmo-imap4-default-authenticate-type 'clear) 
(setq elmo-imap4-default-port '993)
(setq elmo-imap4-default-stream-type 'ssl)

;;(setq elmo-imap4-debug t)  ; „Debug information is inserted in the buffer "*IMAP4 DEBUG*"“
;; ATENDAS probar eso de „debug“; afecta a Gmail pero no a Yubay
;; Este búfer se hace muy grande pues contiene todo el volcado de adjuntos en base64. Como nunca lo miro, lo desactivaré
(setq elmo-imap4-debug nil)

(setq elmo-network-session-idle-timeout 300) ; durante cuánto rato vale la caché
;; No sé si es por eso, pero desde que lo puse me va mucho mejor el correo de Yubay. No se me cuelga y ya no tengo que matar continuamente a starttls. Ni tengo que matar la 1ª conexión a gmail para que la 2ª vaya.

;; temas de SSL: ver por otra sección

(setq elmo-imap4-use-modified-utf7 t) 

;; SMTP

;; Esto ya se pondrá en wl-template-alist. Si lo ignoro y no lo ejecuto, va todo, pero aparece esto:
;;   Warning (elmo): Domain portion of `wl-from' seems to be a local hostname.
;;   Warning (elmo): `wl-from' address is used to make Message-ID string.
;; Así que mejor activo el wl-from al menos; los otros los dejo desactivados
;; (setq wl-smtp-connection-type 'starttls)
;; (setq wl-smtp-posting-port 587)
;; (setq wl-smtp-authenticate-type "plain")
;; (setq wl-smtp-posting-user "…@gmail.com")
;; (setq wl-smtp-posting-server "smtp.gmail.com")
;; (setq wl-local-domain "gmail.com")
;;
;; wl-from → ver privado-nocable.el
;;probando: (setq wl-from nil)

;; lista de mis direcciones para que detecte quién soy yo y me quite de CC
;; Por probar
;; wl-user-mail-address-list → ver privado-nocable.el


;; No sé qué poner:
;; no lo pongo: wl-message-id-domain
(setq wl-message-id-domain "gmail.com")
;; no lo pongo; wl-local-domain

;;;;;; integración con offlineimap (ver notas)
;; https://github.com/jd/offlineimap.el
(let ((d "/w/offlineimap/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'offlineimap)
    ))
;; Y: M-x offlineimap
;; Y añadí tecla „O“ a vista de carpetas

;;;;;; configuración del fichero de carpetas (.folders)
;; Lista de carpetas distinta en algunos equipos
(cond ((equal "danvi" (system-name)) 
       (setq wl-folders-file "~/.folders-v"))
      (t (setq wl-folders-file "~/.folders")) ; predeterminado, ya iba bien. Es mi principal
      )

;;;;;; configuración de plantillas para cada cuenta y para redactar mensajes
;; wl-template-alist es la clave

;; he ido tomando configuración de http://www.mail-archive.com/emacs-orgmode@gnu.org/msg20250/wlconfiguration.org

;; ∴ wl-template-alist → ver privado-nocable.el


;; Automatically select the correct template based on which folder I'm visiting
(setq wl-draft-config-matchone t) ;; If non-nil, applied only one element of `wl-draft-config-alist'.
;; ¿cómo sería sin esto?


;; Cosas que se pueden mirar en filtros:
;; La carpeta  padre es «%INBOX:"dani+yubay.com"/clear@mail.yubay.com:143!!» ← Yubay
;; La carpeta  padre es «%inbox» ← Gmail
;; La carpeta  padre es «» ← C-x m

;; Para probar va bien: ;;;;; (progn (message "La carpeta  padre es «%s»" wl-draft-parent-folder)

;; ∴ wl-draft-config-alist → ver privado-nocable.el

;; Apply wl-draft-config-alist as soon as you enter in a draft buffer. Without
;; this wanderlust would apply it only when actually sending the e-mail.
(add-hook 'wl-mail-setup-hook 'wl-draft-config-exec)
;; para deshacerlo: (remove-hook 'wl-mail-setup-hook 'wl-draft-config-exec)
;; IS: atención, al darle a „A“ con ciertos mensajes me está fastidiando el búfer; sale sin color y es por mi uso de wl-draft-config-alist (comprobado pues si nil, bien). Curiosamente no pasa con „a“ con el mismo mensaje. El error debe de estar en wl-draft-config-exec. Creo que les pasa a otros

;; Al hacer C-c C-c para enviar, me vuelve a cambiar todo en función de la plantilla.
;; ¿Quiero el cambio de plantilla al entrar en el borrador o al enviarlo?
;; - ∴ Imagino que en ambos
;; - Al empezar, en realidad no ← pruebo a desactivarlo un tiempo
;; - Si lo quiero al empezar, es sólo *al empezar uno nuevo*, no partiendo de uno existente (respondiendo)

;; [#A] IS: por supuesto NO quiero el cambio al RESPONDER un correo. Ni al empezar ni al ir a enviarlo.  Podría hacer que: si no es un correo nuevo, no me aplique ninguna plantilla automáticamente
;; La función es: (defun wl-summary-reply (&optional arg without-setup-hook)
;; Podría llamarla activando el without-setup-hook y ya haría lo que quiero
;; Ponía:   (define-key wl-summary-mode-map "a"    'wl-summary-reply)
;; Sí, *esto funciona*:
;;(define-key wl-summary-mode-map "a"   (lambda nil (interactive) (wl-summary-reply nil t)))
;; Pero no importa pues luego, al hacer C-c C-c para enviar, me vuelve a escoger plantilla para CPF → ∴ es un problema de plantillas; tengo que corregir las plantillas
;; O pedir que la plantilla no se aplique al enviar sino sólo al principio… ← malo
;; ∴ definí mejor las plantillas y ya no pasa. Sólo para „C-x m“ quiero preescribir el campo „destino“.



;; If you want to manually change the template use C-c C-j in a draft buffer
;; (wl-template-select). The four lines below allow changint the template with
;; the arrow keys
(define-key wl-template-mode-map (kbd "<right>") 'wl-template-next)
(define-key wl-template-mode-map (kbd "<left>") 'wl-template-prev)
(define-key wl-template-mode-map (kbd "<up>") 'wl-template-next)
(define-key wl-template-mode-map (kbd "<down>") 'wl-template-prev)


;; BONUS: añadir comprobación para que si envío un e-mail a @yubay.com desde mi @gmail.com, dé un aviso


;;;;;; configuración interna de carpetas

(setq wl-default-folder "%inbox")
(setq wl-default-spec "%")
;; (setq wl-draft-folder "%[Gmail]/Drafts") ; Gmail IMAP
;; Creo que poner una carpeta IMAP aquí da problemas
(setq wl-draft-folder "+draft") ; Gmail IMAP

;; BONUS: ver qué es wl-folder-get-elmo-folder, parece que me da rutas locales como ~/Mail

;; Al borrar algo con „d“ me interesa no que vaya a papelera, pues Gmail me la vacía de vez en cuando, sino que se quede archivado en la carpeta que contiene todos los correos. Por tanto hago equivalente el „dispose“ (tecla d) de wl y el „Archivar“ de Google
(setq wl-trash-folder "+trash") ; era así. Esto me asegura borrado rápido en local (ẽ cuando uso offlineimap necesito esto)
;; (setq wl-trash-folder "%[Gmail]/Trash") ; Esto hace que „d“ envíe a papelera
;; (setq wl-trash-folder "%[Gmail]/All Mail") ; Esto hace que „d“ le quite TODAS las etiquetas al correo. No es justo lo que quiero.   ← Esto usé durante años… pero tras empezar a usar offlineimap y tras Zocko me cansé de mover TODO a Gmail, así que volví a +trash
;; En realidad es más complejo: „archivar“ quiere decir „quitar la etiqueta Inbox“. Pero no „quitar las etiquetas“
;; Puedo acostumbrarme a: sólo archivar correos de Inbox, nunca de otras carpetas. Esto haré. Más info en Correle.org

;; ¡¡¡¡¡¡¡¡¡ esto me está MOVIENDO todos los correos borrados hacia Gmail !!!!!!!!!! Aunque sean de Yahoo/Yubay
;; Por eso es tan lento
;; tengo que buscar si a más gente le pasa y qué han hecho
;; No encuentro resultados para: wanderlust "trash folders" -"are created by default"
;; Evaluar:
;; - borrar directamente sin mover a „all mail“
;; - mover a local ← pero tendría que descargar también
;; - mejor: mirar wl-dispose-folder-alist
;; - http://www.emacswiki.org/emacs-en/WlMultipleAccounts
;; De momento no me molesta mucho mover todo lo borrado hacia Gmail pues me fío más de la perdurabilidad de Gmail que de la de otros
;;

;; aquí le digo cómo quiero que borre cada tipo de mensaje. En cada caso es distinto
;; Está en pruebas aún. Más ejemplos en http://www.emacswiki.org/emacs/WlMultipleAccounts
;; Se me ocurre que iría muy bien dejar los borrados en una carpeta local que luego se sincronice mediante offlineimap. Así el borrado siempre sería rápido
;; Se lee en wl-summary-get-dispose-folder
;; m8.2015: lo desactivo para ver qué pasa. Ahora uso offlineimap y quiero acelerarlo todo al máximo; para eso evito /mover a Gmail/ al borrar en local
(ignore '(
          (setq wl-dispose-folder-alist
                '(
                  ;;("^%.*company\\.com" . "%INBOX.Trash:\"myname@company.com\"/clear@mail.company.com")

                  ;; son de dani@zocko.com en local. No sé qué quiere decir „remove“, espero que esto lo destruya. Creo que con esto pido que no los mueva a Gmail (por tanto no tendré copia); bien
                  ("^.~/.Maildir/" . 'remove)
                  ;;("^.~/.Maildir/" . "+trash") ; prueba, no sé qué hace

                  ("^%inbox" . "%[Gmail]/All Mail")

                  ;; ésta tiene que ser rápida
                  ("^+trash" . 'remove)

                  ))
          )) ; ignore




;;;;;; configuración de reglas para catalogar mensajes por temas

(setq wl-refile-rule-alist
      '(("From"
         ("oficina.tecnica@punttic.cat" . "+prueba1punto")) ; si no coincide es porque:    From: Oficina tècnica de la Xarxa Punt TIC <oficina.tecnica@punttic.cat>
        ("To"
         ("setmanari@punttic.cat" . "+prueba2punto"))      ; To: setmanari@punttic.cat

        ;;  ("x-ml-name"
        ;;   ("^Wanderlust"    . "+wl")
        ;;   ("^Elips" . "+elips"))
        )
      )
;; BONUS: probar y aprender wl-refile-rule-alist

;;;;;; directorios de datos internos

(setq wl-temporary-file-directory "~/n/tempi-WL")
;; BONUS: creo que puedo poner ~ pues es donde descargará adjuntos etc.

;; No sé por qué no sabe esto él solo
;; (setq wl-icon-directory "/usr/share/emacs/site-lisp/wl/etc/icons")
;; MALFAR: volver a probar ← no, no me gustan sus iconos

;;;;;; caché de correo
;;days since last access, i.e atime. (default: 50)
(elmo-cache-expire-by-age 14)
;;kilobytes (default 30000)
(elmo-cache-expire-by-size 1024)
;; Esto me pasó (la 1ª vez que lo ejecuté) de 434 Mb → 115 Mb → 81 Mb en ~/.elmo


;;;;;; privacidad y seguridad. Contraseñas
;;
;; Renuncio a ellas a cambio de la comodidad:
;; „If a connection has been established, you can enter the password. ‘M-x elmo-passwd-alist-save’ lets you save your passwords to ~/.elmo/passwd, so that you don’t have to enter them every time.“

;;;;;; pequeños ajustes para hacerlo más cómodo
(setq wl-folder-check-async t) 
;; No preguntar al darle a „s“ (actualizar):
(setq wl-ask-range nil)
;; No preguntar al abrir correo grande
;;(setq wl-prefetch-confirm nil)
;; En realidad sí que quiero confirmación pero para mensajes muy grandes. Estaba a 30000
(setq wl-prefetch-threshold 10123000)
(setq wl-message-buffer-prefetch-threshold 10123000) ; era 30000 también
(setq elmo-message-fetch-threshold 800123) ; para cuando le doy a Enter en un mensaje en el sumario; era 30000 también

;; probando
(setq wl-message-buffer-prefetch-debug t)

(setq wl-summary-auto-sync-marks nil) ; era t, eso actualiza en directo las marcas de „importante“, „no leído“. A otras marcas no afecta.

;; https://www.emacswiki.org/emacs/WlFaq#toc23
;;don't remember "n"/"p" direction when flagging messages:
(setq wl-summary-move-direction-toggle nil)


;; me estaba dando problemas cuando lo probé a nil: los mensajes borrados no dejaban de verse. Lo repongo a t
(setq wl-summary-auto-sync-marks t)

;; „How do I force Wanderlust to pre-fetch all messages in a folder for offline access?“
(setq wl-summary-incorporate-marks '("N" "U" "!" "A" "F" "$")) ; era ("N" "U"), y la verdad es que veía que precargaba poca cosa


;; browse url key
;; Esto no va en general pues me tomar url escrita, no enlazada
(ignore '(
          (add-hook 'mime-view-mode-hook
                    (lambda ()
                      (local-set-key "f" 'browse-url)))
          ))

;; quiero que al tocar „espacio“ en wl, no me avance al siguiente mensaje
;; Esto me va, pero sólo cuando toco espacio dentro del mensaje (en la ventana que lo muestra), no fuera (en lista de mensajes)
(setq mime-preview-over-to-next-method-alist nil) ;; era:  '((wl-original-message-mode . wl-message-exit))
;; Lo cambié pero parece que se reseteó.
;; Parece que wl.el en wl-mime-combine-message/partial-pieces lo añade…
;; ¿o es wl-mime-setup?

;; Otro intento:
(ignore '(
          (defun mime-preview-move-to-next ()
            "No hace nada"
            (message "Ignorando mime-preview-move-to-next")
            )
          ))

;; Otro intento, creo que irá mejor:
;; (define-key wl-summary-mode-map " " nil) ;; ← en realidad no lo quiero, pues me va bien „ “ para ir bajando, lo que no quiero es que salte tras el final
;;  (define-key wl-summary-mode-map " "    'wl-summary-read)

;; (define-key mime-view-mode-map " " nil)
(define-key mime-view-mode-default-map " " nil)



;;;;;; exportador de número de correos para mostrarlo en terminal
(defun graba-resumen-de-wl-en-fichero nil
  (when (get-buffer "Folder")
    (with-temp-buffer
      (insert
       (strip-text-properties
        (with-current-buffer "Folder"
          (buffer-string))
        )
       )
      (write-region (point-min) (point-max) "~/.org-resumen-de-wl.txt")
      )
    )


  )
(add-hook 'wl-auto-check-folder-hook #'graba-resumen-de-wl-en-fichero)


(defun graba-en-fichero-lista-de-correos-por-responder nil
  (let ((slug-cuenta
         (and (get-buffer "Summary")
              (remove ?- (transliterate ".~/%" "----"
                                        (car (member wl-summary-buffer-folder-name '(
                                                                                     "%inbox"
                                                                                     ".~/.Maildir/cuentaz2/INBOX"
                                                                                     ".~/.Maildir/cuentac2/INBOX"
                                                                                     ".~/.Maildir/cuentagm/INBOX"
                                                                                     ".~/.Maildir/cuentao2/INBOX"
                                                                                     )))))
              
              )))
    (when (and slug-cuenta (not (string= slug-cuenta "")))
      (with-temp-buffer
        (insert
         (strip-text-properties
          (with-current-buffer "Summary"
            (buffer-string))
          )
         )
        (replace-regexp "
.*" "…" nil (point-min) (point-max))
        (write-region (point-min) (point-max)

                      (format 
                       "~/.org-correos-por-responder-%s.txt"
                       slug-cuenta
                       )
                      )
        )
      )
    )
  )
;;no(add-hook 'wl-summary-mode-hook #'graba-en-fichero-lista-de-correos-por-responder)
(add-hook 'wl-summary-sync-updated-hook #'graba-en-fichero-lista-de-correos-por-responder)
;; ¡perfecto! Se actualiza al entrar por 1ª vez, y luego

;;;;;; cómo se ve la lista de carpetas
;; (modo „folder“)
(setq wl-highlight-folder-by-numbers 142857) ; no colorear la línea entera (t) sino sólo los números. Los tantos colores cambiantes no me decían nada; quizás ahora empiezo a entenderlos

;;;;;; cómo se ven los mensajes
;;;;;;; cabeceras mostradas
;; ignore  all fields
(setq wl-message-ignored-field-list '("^.*:"))

;; ..but these five
(setq wl-message-visible-field-list
      '("^To:"
        "^Cc:"
        "^From:"
        "^Subject:"
        "^Date:"))
;; Las otras no me interesan.
;; y siempre tengo la tecla „H“ para conmutar entre ver cabeceras o no

(setq wl-message-sort-field-list
      '(
        "^From:"
        "^Subject:"
        "^Date:"
        "^To:"
        "^Cc:"
        ))


;;;;;;; correos en HTML
;; más abajo (después de cargar w3m) hago el (require 'mime-w3m)

;; Esto decide si se usa w3m o shr:
;; (setq mime-view-text/html-previewer 'shr)
;; (setq mime-view-text/html-previewer 'w3m)
;; Pero parece que no noto diferencia (siempre usa w3m)
;; ¿Cómo ver cuál uso? … Mmm… ŭ1 mirando faces del mensaje, para ver si tienen w3m-* o no
;; shr vs w3m: shr parece que sea más bonito, pero no lo es: colores feos, contenido mal puesto, y es más lento
;; ∴ prefiero w3m

;; Y a ver si me hace caso con esto
(setq mm-inline-large-images t) ; era nil. A ver si me muestra algo…

;; (setq mm-inline-text-html-with-images nil) ; ¿hacer caso de <img>? No, porque son para vigilarme
(setq mm-inline-text-html-with-images t) ; probando. Poner resize
;; mime-w3m-safe-url-regexp: ahora vale "\\`cid:", no lo entiendo. ¡Pero éste es el motivo por el que no van!
(setq mime-w3m-safe-url-regexp "^cid:") ; probando a ver si va mejor


;; Mandar mensajes en HTML cuesta más (mucho más)
;; http://orgmode.org/worg/org-hacks.html, hay algo

;;;;;;; lista de mensajes (sumario)
(setq wl-summary-width 95) ;era 80
(setq wl-summary-width nil) ; nil: no truncar
;; Seguía cortándose en 80. Luego lo arreglé y ya va.
;; Quizás cambiando también wl-summary-line-format
;; Funciones por investigar:
;; - wl-summary-create-line: ¿¿¿??? Sólo se llama una vez
;; - wl-set-string-width
;;  - veo que hay cosas de   (not (featurep 'xemacs))), espero que no sea por eso
;;  -     (setq line (funcall wl-summary-buffer-line-formatter))
;; ¡Pero esto es inconsistente con t!:
;; wl-summary-buffer-line-formatter is a variable defined in `wl-summary.el'.
;; Its value is t
;; Local in buffer Summary; global value is nil
;;

;; ; cómo se muestra cada línea
;; wl-folder-summary-line-format-alist manda. Pero si no se encuentra ahí la información, se usa wl-summary-line-format

;; wl-summary-format era, antes de meterle mano: "%n%T%P%M/%D(%W)%h:%m %t%[%17(%c %f%) %] %s" 
;; no lo toco pues el por defecto me va bien. ; pruebas; (setq wl-summary-format "%T%P %D.m%M(%W)%h:%m <%S> %t%[%17(%c %f%) %] %s") ; ← no tocar
;; El que tocaré es wl-folder-summary-line-format-alist 
(setq wl-folder-summary-line-format-alist
      '(

        ;; Esto funciona. Voy probando diferentes variantes. Me es muy importante resaltar la fecha (DD.mMM) y el tamaño (para ver si hay adjuntos malos)
        ;; Uso el mismo formato en todas mis cuentas, por consistencia
        ;; BONUS: me gustaría mostrar el „hace cuántos días lo he recibido“, pero no sé cómo.
        ;;     ("^%" . "%n%T%P%M/%D(%W)%h:%m %t%[%14(%c %f%) %](%S) %s")
        ;; ("^%" . "%T%P %D.m%M(%W)%h:%m, %-4S, %t%[%17(%c %f%) %] %s")
        ("^[%.]" . "%T%P %W%h:%m, %-4S, %t%[%17(%c %f%) %] ¡%D.m%M! %s")

        ("^@2ch" . "%n%T%P%M%/%D/%h:%m %t[%9(%c %f%) ]%s")))



;; No quiero vista anidada en „Inbox“ porque entonces no me entero de nuevos correos llamados p.ej. „Hola“ porque en vez de salir al final salen arriba escondidos bajo otra „Hola“ de otra persona
(setq wl-summary-default-view (quote sequence))
;; no me hace caso. Me conformaría con que si salen hilos, salieran todos desplegados…

(set-face-foreground 'wl-highlight-summary-disposed-face "#88d") ; no de un azul tan oscuro. En -nw #55e ahora brilla más, está bien. Pero pongo #88d para que se pueda leer en X (pues #55e es muy oscuro). Supongo que tendré que elegir un intermedio.

(set-face-foreground 'wl-highlight-message-cited-text-2 "cyan") ; era blue pero era ilegible en -nw. Con „cyan“ es mucho más agradable y no molesta ni lía aunque ya se use para otras cosas


;; no quiero que me agrupo por temas pues a dos que me han dicho „Hola“ me los pone juntos
(setq wl-summary-search-parent-by-subject-regexp nil) ; era: "^[    ]*\\(\\[[^:]+[,: ][0-9]+\\]\\)?[    ]*re[\\^[:> ]"

;; mostrar „thread“ ya abierto para no tener que hacer „[[“ (ẽ en listas de correo como orgmode)
;; Parece que ya va
(setq wl-thread-open-reading-thread t)
(setq wl-thread-insert-opened t)
;; lo que hace „[[“ es (wl-thread-open-all)


;;;;;; cómo se generan las respuestas

(defun wl-crea-cita ()
  "basada en wl-default-draft-cite pero en catalánico"
  (let ((mail-yank-ignored-headers "[^:]+:")
        (mail-yank-prefix "> ")
        date from cite-title)
    (save-restriction
      (if (< (mark t) (point))
          (exchange-point-and-mark))
      (narrow-to-region (point)(point-max))
      (setq date (std11-field-body "date")
            from (std11-field-body "from")))
    (when (or date from)
      (insert (format "El %s %s va%s escriure:\n"
                      (or date "que") ; „El que vas escriure“ queda bé
                      (if wl-default-draft-cite-decorate-author
                          (funcall wl-summary-from-function
                                   (or from "")
                                   ;;(if from (concat from " va escriure") "vas escriure" )
                                   )
                        ;;(or from "you")
                        (or from "")
                        )
                      (if from "" "s")
                      )))
    (mail-indent-citation)))

(setq wl-draft-cite-function (function wl-crea-cita)) ; era wl-default-draft-cite

(setq wl-draft-reply-buffer-style 'full) ; era 'split, que me deja demasiadas ventanas abiertas. full me abre ventana nueva y me quedan varias; creo que no me hace falta → pruebo full

(setq wl-draft-always-delete-myself t) ; ¡no me pongas en Cc al responder! Ya conservo las respuestas en carpeta de enviados. Funciona

(setq wl-draft-send-confirm-with-preview t) ; A t me muestra varios parámetros que ahora que uso plantillas me son algo útiles

;; (setq wl-draft-verbose-send t) ; ← ya es t. No parece que dé mucha información, pero also es algo.     No usar wl-draft-verbose-msg (es interna)

(setq wl-draft-use-cache t) ; con esto quiero que me grabe mensajes enviados en ~/.elmo/cache, así los podré recuperar en caso de necesitarlo

(setq wl-forward-subject-prefix "Rv: ") ; por cierto, se reenvían con „f“

(setq wl-auto-save-drafts-interval nil) ; para no estar grabando cada segundo

(defalias 'wl-attach-file--la-creo-para-adjuntar-ficheros-fácilmente 'mime-edit-insert-file) ; „mime-insert-encoded-file: Symbol's function definition is void: nil“ cuando la llamo con mi alias… Debe de ser por una introspección guarra:    (mel-find-function 'mime-insert-encoded-file encoding)   

;; De: http://www.emacswiki.org/emacs/WlFaq
;; (defun mime-edit-insert-multiple-files ()
(defun wl-attach-multiple-files--probando () ; si va, quitarle el „--probando“
  "Insert MIME parts from multiple files."
  (interactive)
  (let ((dir default-directory))
    (let ((next-file (expand-file-name
                      (read-file-name "Insert file as MIME message: "
                                      dir))))
      (setq file-list (file-expand-wildcards next-file))
      (while (car file-list)
        (mime-edit-insert-file (car file-list))
        (setq file-list (cdr file-list))))))


;;;;;; cómo se envían los mensajes
;; Intento registrar mensajito al enviar bien el correo; pues a veces tengo dudas

;; BONUS probar un poco
;;(setq mail-send-actions '(
;;(lambda nil (message "correo enviado"))
;;))

;; era: (setq mail-send-actions nil)
;;;;; mu y mu4e
;;;;;; cargarlo, y ejecutar todo sólo si está
;; (require 'mu4e)
(let ((d "/usr/share/emacs25/site-lisp/mu4e/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'mu4e)

;;;;;; variables
    (setq mu4e-maildir "/home/dc/.Maildir/cuentaz2/") ; ¿una lista? Ver notas
    (setq mu4e-get-mail-command "offlineimap")

    ;; de http://www.djcbsoftware.nl/code/mu/mu4e/HV-Overview.html#HV-Overview:
    ;; mu4e-headers-date-format and mu4e-headers-time-format

    ;; copiado+pegado de wl-…
    ;; mu4e-user-mail-address-list → ver privado-nocable.el

    ;;(setq mu4e-use-fancy-chars nil) ; si los mostrare bien, vale, pero no lo hace

;;;;;; añadirle columnas
    ;; copiado de http://www.djcbsoftware.nl/code/mu/mu4e/HV-Custom-headers.html#HV-Custom-headers: calcula nº de receptores
    (add-to-list 'mu4e-header-info-custom
                 '(:recipnum .
                             ( :name "Number of recipients"  ;; long name, as seen in the message-view
                                     :shortname "Recip#"           ;; short name, as seen in the headers view
                                     :help "Number of recipients for this message" ;; tooltip
                                     :function
                                     (lambda (msg)
                                       (format "%d"
                                               (+ (length (mu4e-message-field msg :to))
                                                  (length (mu4e-message-field msg :cc))))))))

    ;; lo añado. Na va… aún
    ;; (add-to-list 'mu4e-header-info mu4e-header-info-custom)

    ;; fin de sección mu4e
    ))

;;;;; varias variables/funciones genéricas para cualquier programa de correo
;;;;;; para especificar y arreglar el nombre de equipo que se muestra
;; Para evitar el  vh08fe81bge0@CPU107.i-did-not-set--mail-host-address--so-tickle-me

;;(setq mail-host-address ...)
;; MALFAR: probar si esto arregla generación de IDs en org-mode y si no estropea el envío en Gnus (sobre todo cuando Gnus no se cargó aún)
;; MALFAR: probar simplemente a poner en /etc/resolv.conf una entrada con „domain“
;;tonto: (setq mail-host-address (message-make-host-name))
;;user-mail-address está bien
;;user-domain ¡NO! No está definida
;; MALFAR: creo que todo se ha de solucionar cuando mi „correo“ no sea „dc@CPU107“ sino „dc@CPU107.opentrends.net“, por ejemplo. Si no, una función como message-user-mail-address va a dar nil todo el tiempo.
;; Puse en /etc/hosts:  127.0.1.1       CPU107.opentrends.net CPU107
;; (importante que el primero tenga el dominio)

;; MALFAR: al componer mensajes quiero dirección buena
;;(setq user-mail-address "…@gmail.com") ; mejor esto que dc@CPU107.opentrends.net
;; Esto ya se establecerá desde gnus o wanderlust, donde toque

;; MALFAR: C-x m  no ha de usar nunca sendmail. Bah, ya va bien.


;;;;;; Línia que s'usa per citar el missatge

;; por defecto:
;;(setq message-citation-line-format "On %a, %b %d %Y, %N wrote:\n")
;; message-citation-line-function → message-insert-citation-line
;; Pues si no lo cambio, no irá…
(setq message-citation-line-function #'message-insert-formatted-citation-line)

;; doncs vinga, en català! I sense salt de línia al final. I amb hora (important; ho necessito per saber quant de temps ha passat fins la meva resposta)
(setq message-citation-line-format "El %a, %b %d %Y a les %H:%M, %N va escriure:")

;; Wanderlust tiene una función propia para esto; ver ahí

;;;;;; Para firmar el mensaje poniendo al final un texto

;; luego esto lo puedo sobreescribir mediante plantillas
(setq signature-file-name "~/.emacs.d/gnus/firma-normal")
;; Puedo poner alguna referencia a escribir sin faltas.
;; Otras variables:
;;      signature-insert-at-eof t  ← no sé qué hace; no sirve para ponerla siempre. Creo que es para evitar ponerla al principio

;;      signature-delete-blank-lines-at-eof t



;;;;;; No usar lo de limitar a 80 columnas
;; No confundirme: message-fill-column es de gnus y lo defino ahí. Creo que no hay nada genérico para esto

;;;;;; para que no me trocee los ficheros adjuntos

;; no trocear los ficheros adjuntos. Que no vuelva a pasar eso de „¿te ha llegado mi correo con el fichero? Sí, me han llegado 40 correos tuyos, todos ellos indescifrables y con basura“
(setq mime-edit-split-message nil)

;;;;;; para procesar el mensaje corrigiendo faltas
;; (¡Las de otro! Qué irónico)
(defun comprobar_buen_equilibrio_de_signos  (ini fin) ; otros de antes: detecta_buen_balance_de_signos
  "Avisa si hay errores de signos de exclamación y de interrogación en el búfer actual.
Comprueba por ejemplo que si hay 3 ? también hay 3 ¿, y si hay 1 ! también hay 1 ¡
¡Hola! es válido, mientras que Hello! no.
Se puede aplicar a una región o a todo el búfer.
En una siguiente versión puedo hacer que corrija automáticamente el mensaje citado."
  (interactive "r")

  ;; ¿expregu recursiva que detecte signos emparejados?
  ;; ¿uso los métodos tipo forward-list reconfigurados para trabajar con „[¿¡]“?
  ;; [#A] sugiero convertir ¿? a () y ¡! a () y luego comprobar que los *paréntesis* están bien balanceados (cosa más fácil en Emacs)
  ;; BONUS: ver si puedo engañar al comprobador de paréntesis para decirle que me tome [] y otros

  ;; cutrecillo para cuando no hay región; seguro que hay mejor forma de hacer esto
  (if (not (region-active-p)) (setq ini (point-min) fin (point-max)))
  ;; de momento, sólo contar
  (let (
        (núm-¿ (count-matches "¿" ini fin))
        (núm-? (count-matches "?" ini fin))
        (núm-¡ (count-matches "¡" ini fin))
        (núm-! (count-matches "!" ini fin))
        )
    (message "En %s: ¿? %d %d  --  ¡! %d %d"
             (if (region-active-p) "región" "búfer")
             núm-¿ núm-? núm-¡ núm-!)
    )
  )

;;;;;; algunas faces tanto para gnus como para otros
;; no confundirme. Cosas como message-header-name (la faz) las da gnus y no son genéricas.





;;;;;; tecla para abrir mi correo (eligiendo el sistema que toca)

;; tecla para reabrir gnus; se parece a C-x C-j C-r que me abre el listín de Jabber
;; pongo C-x C-j g para ir al de la empresa (gnus), y C-x C-j C-g para ira al personal
;; antes de 22.m8.2010 tenía C-x C-j C-g y C-x C-j C-S-g
;; el 25.m9.2011 desactivo gnus pues no lo uso
(ignore '(
          (define-key acceso-funciones-varias-map (kbd "g") (lambda () (interactive) 
                                                              (if (get-buffer "*Group*")
                                                                  (switch-to-buffer "*Group*")
                                                                (gnus) ; si no está abierto, lo abre
                                                                )
                                                              ))
          ))
;; De la misma forma, me asigno una tecla para ir al correo personal
(define-key acceso-funciones-varias-map (kbd "C-g") (lambda () (interactive) (wl)))


;;;;; bbdb (base de datos de personas)
;; Primera impresión (dic'2007): No lo uso porque está pensado para quienes usan mucho el correo (gnus, mh, ...), no tanto para la entrada manual de datos.
;; En 17.10.2008 empecé a usarlo y quité ecomplete
;;(add-to-list 'load-path "~/.emacs.d/bbdb-2.35/lisp")
;; En 10.12.2008 uso la de CVS
;; En 24.m12.2011 paso a usar org-contacts pues es como decidí yo por mi cuenta gestionar contactos. Y BBDB3 es sólo para Gnus.
;; En 7.m2.2014 desactivo bbdb pues no me hace falta y peta un poquito el arranque de emacs

(ignore '(
;;;;;; carga

          (let ((d "/w/bbdb/"))
            (if nil ; (file-exists-p d)
                (progn
                  (message "Cargo bbdb de /w/ (quizás es el bbdb3…)")
                  (add-to-list 'load-path "/w/bbdb/lisp/")
                  )
              (progn
                (message "Cargo bbdb mío (seguro pero viejo)")
                (add-to-list 'load-path "~/.emacs.d/bbdb-cvs/lisp")
                )
              ))

          (require 'bbdb)

;;;;;; configuraciones genéricas de bbdb
          ;;(bbdb-initialize)
          ;;(bbdb-initialize 'gnus 'message) ; nota: no poner w3 pues no lo uso
          (bbdb-initialize 'message) ; y le quito gnus pues no lo uso

          (setq bbdb-file "~/.emacs.d/bbdb-datos/.bbdb")
          (setq bbdb-buffer-name "*BBDB*") ; extraño; ¿por qué hace falta? Ya es el valor por defecto. Peta si no está esto.


          ;; creo que permite definir nuevos tipos de campo. Aprovecharlo

          ;; probando; quiero que añada al destino de un correo recién enviado
          (setq bbdb-offer-to-create t)

          ;; Al menos esto empieza a funcionar
          (ignore '( ; lo desactivo porque ya no uso gnus
                    (load-file "~/.emacs.d/bbdb-cvs/contrib/moy-bbdb.el")
                    (add-hook 'message-send-hook 'bbdb/send-hook) ; If you use Gnus
                    ))


          ;; mail-send-hook no afecta; es message-
          ;;(add-hook 'mail-send-hook 'bbdb-force-record-create) ; pues tampoco va
          ;;(add-hook 'message-send-hook 'bbdb-force-record-create) ; pues tampoco va
          ;; esto de arriba no va, probar con lo de abajo (que tampoco va)
          ;;(defadvice gnus-summary-reply (before registra-en-bbdb-la-persona-respondida activate)
          ;;"Force the creation of a BBDB record when you reply to a message."
          ;;(bbdb-force-record-create))


          ;;  estudiar el poner bbdb-get-only-first-address-p a nil


          ;; quiero que se creen contactos para cada correo/noticia recibido.
          ;; Estoy decidiendo aún si me gusta
          ;; ver en Correle.org. Creo que me puede ir bien una función aquí
          ;;(setq bbdb/mail-auto-create-p t)
          (setq bbdb/news-auto-create-p nil)

          ;; alias para bbdb

          ;; noséqués:
          ;;(add-hook 'message-setup-hook 'bbdb-define-all-aliases)

          ;; no quiero todo el rato ver la ventanita en Gnus... hasta que BBDB haga algo útil. Entonces ya le pondré 'horizontal
          (setq bbdb-use-pop-up nil)


;;;;;; bbdb para gnus
          (ignore '( ;desactivado pues no uso ya Gnus

                    (require 'bbdb-gnus) ; ¡es que si no no va!
                    ;; lo pruebo en Gnus
                    (add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus)

                    ;;(defvar message-mode-map) ; ¿para que no pete lo siguiente? No, no va
                    ;; y en modo mensaje (ejemplo: C-x m); supongo que esto es para todos. Pero no, parece que no va al dejar de usar Gnus
                    (bbdb-insinuate-message)
                    ))



;;;;;; bbdb para Wanderlust
          ;; usar con wl según http://www.gohome.org/wl/doc/wl_164.html
          ;; Importante: autoconf && ./configure && make. Si no se hace, tarda 2'35 segundos (si se hace, insignificante)
          ;; otra cosa: al probar bbdb3, bbdb-wl se sacaba de /usr/share/emacs23/site-lisp/wl/bbdb-wl.el, que no es muy reciente. Y es que bbdb3 no incluía nada para wl
          (require 'bbdb-wl)
          (bbdb-wl-setup)

          ;; I want bbdb to grab email address from outgoing email
          (defun my-bbdb-mail-send-function ()
            (bbdb-update-records 
             (delete-if (lambda (item) 
                          (string= "" (caaddr item)))
                        (bbdb-wl-get-addresses bbdb-get-only-first-address-p))
             t t))
          ;;¿? (add-hook 'mail-send-hook 'my-bbdb-mail-send-function t)

          ;; que no moleste tanto. No sé bien qué hace
          (remove-hook 'wl-message-redisplay-hook 'bbdb-wl-get-update-record)

;;;;;; fin de ignore
          ))

;;;;; rcirc
;; Chat: rcirc es mejor porque funciona bien con tabbar (y ERC no)
;; Parece que se hizo a ERC funcionar con Tabbar. http://lists.gnu.org/archive/html/erc-discuss/2008-12/msg00008.html
;; BONUS 9.m4.2010: ahora que ya no uso tabbar, debería comparar rcirc y ERC por méritos propios. Aunque ya estoy contento con rcirc

(defun erc ()
  "Avisa de que rcirc es mejor :-)"
  (interactive)
  (beep)
  (message "¡rcirc pli bonas!")
  )

;; para mayor productividad
;;(set 'rcirc-startup-channels-alist '(("^irc.freenode.net$" . ("#emacs" "#gnus" "#bzr" "#liferay" "#netbeans"))))
;;(set 'rcirc-startup-channels rcirc-startup-channels-alist) ; para emacs23
;; Parece que en emacs23 es esta lista la que va:
(setq rcirc-server-alist (quote (
                                 ;; ("irc.freenode.net"
                                 ;; m5.2021
                                 ("irc.libera.chat"
                                  :channels (
                                             "#emacs"
                                             ;; Opcional, para cuando tenga que refrescarlo o preguntar
                                             ;; "#django"
                                             ;; m5.2021: „for Breezy, we're moving over to #breezy on irc.oftc.net“
                                             ;; "#bzr"
                                             ;; "#tikiwiki" ; mmm… esto me dejará muy registrado. Si quiero estar al tanto de tikiwiki, mejor las listas de correo
                                             )))))

(setq rcirc-fill-column 'frame-width) ; y no 'window-width

;; otra configuración
;; rcirc-authinfo → ver en fichero de claves
(setq rcirc-default-nick "clemente")
(setq rcirc-default-user-full-name "Daniel Clemente")
(setq rcirc-default-user-name "Daniel 142857")
(rcirc-track-minor-mode 1) ; actívase mediante función, no variable
;; MALFAR: al activar rcirc-track-minor-mode, ¡no me va el menú (F10)! Debe de ser por los ganchos

;; pero que no me robe teclas
(define-key rcirc-track-minor-mode-map (kbd "C-c `") nil) ; era rcirc-next-active-buffer, que también está en C-c C-espacio. Quiero la tecla para Org

;; mientras pruebo y busco los pequeños errores (ẽ líneas partidas, …)
;; Esto escribe a „*rcirc debug*“ (búfer)
(setq rcirc-debug-flag t)

;; Está en elpa
;; (require 'rcirc-color)
;; Atención, debería añadirlo al entrar. Si lo hago fuera, el demonio de emacs peta
;; Mmmm… peta igualmente con esta línea:
;; (eval-after-load 'rcirc '(require 'rcirc-color))
;;
;; Lo que da es: Wrong type argument: number-or-marker-p, nil
;; Depuro:
;; (load-file "/home/dc/.emacs.d/elpa/rcirc-color-0.4.2/rcirc-color.el")
;; Es por el: defvar rcirc-colors
;; Es por el cómo llama a: rcirc-color-distance
;; Es por: (rcirc-color-distance color (face-background 'rcirc-my-nick))
;; Ya falla: (rcirc-color-distance 'snow (face-background 'rcirc-my-nick))
;; Ya falla: (rcirc-color-distance 'snow 'snow)
;; El problema es esta resta: acaba en (- nil nil), y esa operación no se puede
;;(message (- (nth 0 (color-values 'snow)) (nth 0 (color-values 'snow))   ))
;; Parece que habrá que añadir el comprobador de nulo a rcirc-color…
;; Qué raro que sólo con --daemon falla
;; Quizás he usado mal 'snow y debería ser "snow". Por investigar
;; De momento me salto rcirc-color


;;;;; para acceder a diferentes webs
;; Pero mi conkeror es tan bueno que no creo que emacs me ayude.

;; sx-mode, para „stack overflow“ etc.
;; https://github.com/vermiculus/sx.el/blob/master/README.org, https://news.ycombinator.com/item?id=9407364
;;;; Programación y entornos
;;;;; CEDET: lo necesito para JDEE. CEDET incluye: base (eieio, semantic) y herramientas (Speedbar, EDE, COGRE)

;;;;;; errores muchos que tuve con CEDET-1.0pre4, sobre todo al usar byte-code-cache.el
;; El 19.12.2008 quité de aquí las chapuzas porque eran demasiadas. Ver git/bzr de esa fecha.
;; Y para otra vez: ¡no empezar a chapucear! Quejarme a byte-code-cache.el o a CEDET ante cada problema, ahora que uso su tope.

;;;;;; ajustes de rutas que tienen que ir antes de cargar CEDET :-(
;; si no se pone esto aquí, se empeña en usar ~/.srecode/ al abrir Emacs
(setq srecode-map-save-file "~/.emacs.d/cedet-caché/srecode-map")


;;;;;; cargar CEDET (de verdad) ¡esto tiene que ir al principio!

;; Load CEDET

;;(add-to-list 'load-path "~/.emacs.d/cedet-1.0pre4/common")
;;(load-file "~/.emacs.d/cedet-1.0pre4/common/cedet.el")

;; El de CVS
;;(add-to-list 'load-path "~/.emacs.d/cedet-cvs/common")

;; El de Bazaar (de Eric Ludlam, no el que viene en Emacs. Es más nuevo que el de Emacs)
;; bzr checkout bzr://cedet.bzr.sourceforge.net/bzrroot/cedet/code/trunk cedet
;; Si quiero cargarlo yo a mano: ver prepara_en_emacs23.algo (cdv)

;; El que viene con Emacs 23.2
;;(if (not (functionp #'semantic-mode)) (defun semantic-mode (peo) (message "ATENCIÓN: no tengo semantic-mode. Quizás es que estoy aplicando configuración CEDET-de-tronco a un CEDET-de-Eric que he cargado antes. No pasa nada malo con eso.")))
(setq cedet-de-Eric-ya-cargado (if (functionp #'cedet-version) t nil))

;;(require 'cedet)
(unless cedet-de-Eric-ya-cargado (progn
                                   (require 'semantic)
                                   (semantic-mode 1) ; creo que esto es lo único necesario para activar CEDET de tronco. No sé si hay que ejecutarlo en cada búfer, o vale 1 vez para todos
                                   ;; …y hay quitar los (semantic-load-enable-…)

                                   ;;o sinó: (load-file "~/.emacs.d/cedet-cvs/common/cedet.el")
                                   ;; pero el require es mucho mejor que el load-file puse el load-file sólo se puede hacer una vez

                                   ;; le añado srecode que sólo está en el de CVS según dicen
                                   (require 'srecode)
                                   ;;(add-to-list 'load-path (expand-file-name "~/.emacs.d/cedet-cvs/srecode")) (require 'srecode-load)
                                   ))


;;;;;; definiciones de ayudas de semantic (han de ser una vez ya cargado CEDET)

;; Enabling various SEMANTIC minor modes.  See semantic/INSTALL for more ideas.
;; Select one of the following:
;; 142857: parece que se pueden activar varios a la vez; por si acaso dejo 1 sólo


;; Leer semantic/semantic-load.el e ir copiando cosas del cuerpo de las funciones en vez de llamarlas (pues creo que no están en tronco de Emacs)

;; * This enables the database and idle reparse engines
;;(semantic-load-enable-minimum-features)

;; * This enables some tools useful for coding, such as summary mode
;;   imenu support, and the semantic navigator
;; (semantic-load-enable-code-helpers)
;;Noentronco: (require 'semantic-fw)


;; * This enables even more coding tools such as the nascent intellisense mode
;;   decoration mode, and stickyfunc mode (plus regular code helpers)
;;(semantic-load-enable-gaudy-code-helpers)
;; nota: ¡no es guady, es gaudy! Lo cambiaron y el viejo falla


;; De éstas me ocupo en otro lado:
;; semantic-stickyfunc-name
;;
(global-semantic-decoration-mode 1)
;; Lo pruebo sin y a ver qué me pierdo:
;;(global-semantic-decoration-mode -1)
;; Por lo visto me da: líneas horizontales en las clases, colores en los import

;; esto me ayuda a completar con TAB. Es a lo que se refiere el „intellisense“
;; No lo quiero; me salen cosas por encima al posicionarme y me borra el texto actual
;;(global-semantic-idle-completions-mode -1)
;; Como peta… pues mejor no pongo nada
;; m9.2012: me ralentiza mucho la carga de ficheros .py grandes (aunque sea sólo para ver), así que lo desactivaré para ver qué me pierdo:
(global-semantic-idle-completions-mode -1)
;; Para probar de nuevo:
;;(global-semantic-idle-completions-mode 1)

;; BONUS: hacer que el . complete; ahora va a medias y mal. Poner para cada modo:
;;(define-key jde-mode-map "." 'semantic-complete-self-insert)

;; * This turns on which-func support (Plus all other code helpers)
;; 142857: which-func está bien pero no me es necesaria
;;(semantic-load-enable-excessive-code-helpers)
;; la activo sueltamente. 23.m4.2012: veo que esto causa bastante refresco. No me hace mucha falta, así que lo quito temporalmente. ATENDAS: ¿lo echaré en falta?
;; (which-func-mode 1)
;; (which-func-mode 0)
;; Creo que ahora (2022) lo llaman which-function-mode

;; This turns on modes that aid in grammar writing and semantic tool
;; development.  It does not enable any other features such as code
;; helpers above.
;; 142857: no son las tareas que yo hago; no quiero algo tan avanzado
;;(semantic-load-enable-semantic-debugging-helpers)


;; ahora cargo ayudantes sueltos; arriba se cargaron conjuntos de ayudantes
;; No; mejor voy a ir cambiando las cargas de grupos por cargas de capacidades individuales


;; Enable SRecode (Template management) minor-mode.
;; ya he puesto el srecode-map-save-file arriba
;; Pero ya tengo yasnippet, que me gusta
;;
;; (global-srecode-minor-mode 1)
;; m6.2019 Lo desactivo
(global-srecode-minor-mode -1)
;; Lo pruebo:
;; M-x srecode-insert
;; ∴ No me aporta nada. Por eso lo desactivo

;; creo que esto dicen que esto va bien para ECB; pero no sé para qué exactamente
;; creo que esto estaba anticuado. Lo comento
;; (setq semantic-load-turn-everything-on t)

;; ilumina ocurrencias de la etiqueta apuntada actualmente, igual que hace Eclipse
(unless cedet-de-Eric-ya-cargado (progn
                                   (require 'semantic/idle)
                                   ))
;; en 24.m9.2010 veo que la renombraron
;; BONUS: en 10.m12.2012 voy a probar a desactivarlo porque todo lo de semantic me retrasa mucho, y creo que no es imprescindible
;; (global-semantic-idle-local-symbol-highlight-mode 1)
(global-semantic-idle-local-symbol-highlight-mode -1)
;; Para probar sólo en etiqueta bajo el cursor (esto no va mucho): (semantic-idle-local-symbol-highlight-mode)
;; Para activar en búfer actual: M-x semantic-idle-local-symbol-highlight-mode
;;
;; Pero siempre me dice: semantic-idle-local-symbol-highlight-mode: Buffer trabajo.el was not set up for parsing → ver muchas notas en org, en /semantic/.

;; Tardaba 3 segundos (o un poco más) en iluminar ocurrencias, y lo quiero más rápido → puse 1
;; Pues la verdad es que sí tiene efectos secundarios: se bloquea mucho y muy pronto. Así que lo dejo otra vez en 3
;; ATENDAS: a ver con 3…
;; aún se me cuelga un poco… Probaré 6, y no sé si es mucho Así al menos notaré mejor si esto es lo que causa cuelgues
;; (setq semantic-idle-scheduler-idle-time 1)
;; m8.2017: lo vuelvo a dejar a 1 pues tengo ordenador mucho más rápido y mucha RAM
;; m10.2019: noto que a veces se bloquea en esto:
;; ẽ:
;; #7274 0x0000557ff172e684 in command_loop_2 (ignore=ignore@entry=XIL(0)) at lisp.h:1032
;; #7275 0x0000557ff17bf44c in internal_catch (tag=tag@entry=XIL(0xc9f0), func=func@entry=0x557ff172e660 <command_loop_2>, arg=arg@entry=XIL(0)) at eval.c:1116
;; #7276 0x0000557ff172e62b in command_loop () at lisp.h:1032
;; #7277 0x0000557ff17344d6 in recursive_edit_1 () at keyboard.c:714
;; #7278 0x0000557ff17347f2 in Frecursive_edit () at keyboard.c:786
;; #7279 0x0000557ff16344b6 in main (argc=2, argv=<optimized out>) at emacs.c:2055
;; 
;; Lisp Backtrace:
;; "Automatic GC" (0x0)
;; "garbage-collect" (0x25e01320)
;; "semantic-fetch-tags" (0x25e01720)
;; "semantic-idle-scheduler-refresh-tags" (0x25e01ac0)
;; "semantic-idle-core-handler" (0x25e020a0)
;; "semantic-idle-scheduler-function" (0x25e024c0)
;; "apply" (0x25e024b8)
;; "timer-event-handler" (0x25e02848)
;; 
;; Por eso lo vuelvo a poner tarde (a 5), y quiero ver qué me pierdo con ello
(setq semantic-idle-scheduler-idle-time 5)

;; (setq semantic-idle-scheduler-max-buffer-size 80123) ; desactivo lo de idle-scheduler para búfers grandes (número en bytes). Con esto, (semantic-idle-scheduler-enabled-p) me dará nil para muchos búfers. ← ATENDAS: ver si así es más rápido (esto afectará a la deshibernación también). En m8.2017 lo desactivo pues tengo 16 Gb de RAM ya
;; (setq semantic-idle-scheduler-max-buffer-size 0)

(setq semantic-idle-scheduler-verbose-flag nil) ; probando. Me molestan los „IDLE: Core handler...done“ así que lo pongo a nil
;;(setq semantic-idle-scheduler-verbose-flag t)

;; Aún, cuando deshiberno ordenador, emacs está colgado en:
;; (gdb) xbacktrace 
;; "Automatic GC" (0x0)
;; "garbage-collect" (0x10700d30)
;; "semantic-fetch-tags" (0x10701260)
;; "semantic-idle-scheduler-refresh-tags" (0x10701780)
;; "semantic-idle-core-handler" (0x10701cc0)
;; "semantic-idle-scheduler-function" (0x10702318)
;; "apply" (0x10702310)
;; "timer-event-handler" (0x10702848)
;; Así que intentaré desactivar eso de „tags“ por probar; quizás tiene algo que ver. Quizás no, y todo el cuelge viene por el GC
;;
;; Por cierto, esto me ha pasado en 2015 y en 2020… Quizás no es por semantic. (semantic-fetch-tags) llama a (garbage-collect) con ciertos parámetros, y es el garbage-collect el que falla. Quizás es por emacs. Quizás es porque ha habido una fuga de memoria antes (por cualquier otra cosa) y emacs estaba consumiendo ẽ 10 Gb y por eso tarda tanto en procesar la memoria
;; Ver en emacs.org; le limitaré la memoria


;; Además me dice mucho: Error running timer ‘semantic-idle-scheduler-function’: (error "No support found to parse buffer \"digest-email.html\"")
;; En esos casos me toca cerrar el búfer


;; sustituye el cuadro de evaluar expresión con uno más útil
;; Probar más Ej: se supone que esto da mucha salida: (semantic-get-local-variables) 
;;(require 'data-debug)
;;(global-set-key "\M-:" 'data-debug-eval-expression) ; era: eval-expression
;; 23.m4.2012: lo desactivo temporalmente pues no me aporta nada; sólo unos cuantos errores de coloreado

;; a ver, le pido que en la línea de abajo me dé algo de información
;; (global-semantic-show-parser-state-mode 1)
;; Eso me causa molestias tipo:
;;     Error running timer ‘semantic-idle-scheduler-function’: (scan-error "Unbalanced parentheses" 29487 856661)
;; Por tanto lo desactivaré, ya que no me hace falta. ∴ Comento
;; 
;; (¿no va esto?):
;; (global-semantic-show-parser-state-mode 0)

;;;;;; Desactivo algunas ayudas y herramientas de CEDET

;; ¿debería desactivar directamente global-semantic-idle-scheduler-mode?
;; A veces me cuelga emacs (bueno, es por garbage-collect), ver hacer/emacs.org
;;  (setq global-semantic-idle-scheduler-mode nil)
;; por si acaso, la pongo en customize, para que ~~~~ se cargue antes
;; Por apuntar: ¿qué me pierdo, debido a haberlo desactivado?

;; Pero esto no me gusta; lo pone todo en rojo. Lo desactivo. ¡nil=conmutar!
;; (set 'global-semantic-show-unmatched-syntax-mode 1)
(set 'global-semantic-show-unmatched-syntax-mode -1)

;; probando: (set 'global-semantic-show-unmatched-syntax-mode 1)

;; esto promete poner en cabecera (¡donde tengo tabbar!) el nombre de función actual. Prefiero tabbar.
(set 'global-semantic-stickyfunc-mode nil) ; parece que esto no la desactiva
(global-semantic-stickyfunc-mode -1) ; esto sí



;;;;;; Ficheros de semanticdb (los quiero grabar separados del fuente)
;; Esto hace que los ficheros semantic.cache no estén desperdigados por ahí en muchos directorios
(setq semanticdb-default-save-directory "~/.emacs.d/cedet-caché/")
;; cuando se abre un 2º emacs (cosa poco común) se empeña en usar .emacs.d/semanticdb, no sé por qué

;; Aún por comprobar
(defun semanticdb-kill-emacs-hook ()
"Redefino esto porque no quiero que se pase minutos grabando cosas inútiles cuande quiero para Emacs y tengo >1k búfers abiertos"
(message "Me salto el semanticdb-kill-emacs-hook")
)

;;;;;;; Qué hacer si Emacs no sale (pues lo de arriba puede dar problemas)
;;I found that after making the change you suggest, emacs would not exit
;; at all.
;; I set the path to “/tmp/semantic.cache”
;; it would fail because it would not find the path “/tmp/semantic.cache/!SOME!FILE!I!CREATE.semantic.cache”
;;I added this to my .emacs and then emacs would exit cleanly. ‘(semanticdb-persistent-path nil)

;;;;;;; fallo con semanticdb: (wrong-type-argument arrayp semanticdb-project-database-file)
;; pasa al evaluar esto: (semanticdb-project-database-file "/home/dc/")
;; 16.11.2008 con Emacs23-bzr
;; Pasa cuando abrí mi ~/.emacs

;; El problema era que mi semanticdb-project-database-file no terminaba en /


;;;;;; faces de CEDET que quiero cambiar
;;;;;;; Para el subrayado rojo: (Semantic)
;; al menos hago que en vez de salir subrayado, salga con el fondo un poquillo resaltado pero sin subrayar; así molesta menos.
(set-face-background 'semantic-unmatched-syntax-face "#311")
(set-face-underline 'semantic-unmatched-syntax-face nil)
;; venga, no tan oscuro, que no se nota
(set-face-background 'semantic-unmatched-syntax-face "#811")


;; Esto es para resaltar los cambios hechos a un fichero desde que se abrió.
;; Ahora sale en grisáceo. No se ve mucho... Pero no lo toco.
;;(set-face-background 'semantic-highlight-edits-face "#000072")




;;;;;;; Para el resaltado de etiquetas al ponerme encima de una, entre otras cosas
;; se usa en semantic-idle-tag-highlight-mode
(set-face-background 'pulse-highlight-start-face "#062") ; era #aa3
(setq pulse-flag nil) ; CEDET sin efectos especiales al marcar ámbito; sólo ilumina el bloque seleccionado, pero no lo deja desvanecerse

;;;;;;; para información sobre la función apuntada

;; pone en la línea modal la función actualmente apuntada (aprox.); antes era azul sobre azul
;; 2022: por reactivar. Quizás ahora se llama which-function, no sé
;; (set-face-background 'which-func "Gray20")
;; (set-face-foreground 'which-func "Green")

;;;;;;; y en general usa imágenes
;; ¿dónde las usa? ¿UML en COGRE?
(setq semantic-format-use-images-flag t)

;;;;;; Para Speedbar (parte de Cedet)
;; Si Speedbar peta una vez, luego no deja cerrar búfers con M-k. Entonces hay que hacer:
;; (setq menu-updating-frame nil)
;; Ver abajo, donde hablo de esta variable. También pasa con ECB.

;;;;;; Para EDE (parte de Cedet)

;; http://cedet.sourceforge.net/info/ede.html
;; (require 'ede)  ; 11.m11.2013: nunca lo he usado, así que lo desactivo

;; A ver… ¿me interesa Ede? De momento (m10.2010) creo que no tengo ninguna necesidad, así que -tras años activado- lo desactivo, porque me está molestando con sus prefijos que empiezan por C-c .
;;(global-ede-mode t) ; (global-ede-mode nil)


;;;;;;; me da error lo de arriba:
;; Debugger entered--Lisp error: (wrong-type-argument symbolp [object ede-project-autoload "edeproject-makefile" "Make" ede-proj "Project.ede" nil ede-proj-load ede-proj-project t])
;;   get([object ede-project-autoload "edeproject-makefile" "Make" ede-proj "Project.ede" nil ede-proj-load ede-proj-project t] eieio-class-definition)
;;   (class-v obj)
;;   (aref (class-v obj) 0)
;; 
;; Probando:
;;;;(defmacro class-v (class) "Internal: Return the class vector from the CLASS symbol."
;;  (unless (symbolp class) (debug))
;; Pues parece que cuando no es símbolo (sino lista de 3) también va bien
;;;;  `(get ,class `eieio-class-definition))

;; MALFAR: otro error con clase nula
(ignore '(
          (defadvice eieiomt-method-list-DESACT (before avisa-si-fallará activate)
            ".......probando."

            (let ((class (ad-get-arg 2)))
              (unless class 
                (progn (pita-de-verdad)(pita-de-verdad) (concat "Me han pasado nil como clase" (debug)))
                )
              )
            )
          ))

;; Descubierto aquí
(ignore '(
          (defun ede-rescan-toplevel ()
            "Rescan all project files."
            (interactive)
            (let* ((toppath (ede-toplevel-project default-directory))
                   (ede-deep-rescan t)
                   (loadedproject (ede-load-project-file toppath))
                   )
              ;;    (unless loadedproject (debug))
              (project-rescan loadedproject)))
          ;; (ede-load-project-file (ede-toplevel-project default-directory)) ; va
          ;; (ede-load-project-file "/home/dc/suma/cli/openPDF cliente (Justicia)/work/src15/net/opentrends/signature/") ; ¿nil?  ede-load-project-file puede devolver nil; está claro. Luego el fallo está en project-rescan no aceptándolo
          ))



;;;;;; Para srecode (parte de Cedet), es para plantillas

;; las plantillas son más interactivas así. Se acceden con C-c / /
(setq
 srecode-insert-ask-variable-method
 'field)
;; Si no me gusta, poner 'ask otra vez para que me pregunte todo


;;;;;; Configuraciones de CEDET y Semantic para cada lenguaje

;;;;;;; CEDET para Python
;; los „include“ seguían saliendo en rojo en CEDET 1.0; luego se añadió código para entenderlos

(setq semantic-python-dependency-system-include-path '(
                                                       ;; no sé qué puede haber aquí
                                                       "/usr/lib/python2.6"
                                                       ;; datetime etc.
                                                       ;; el 2.5 lo ignoro… o no, pues en cada ordenador tengo uno distinto. ¿Me puede perjudicar?
                                                       "/usr/lib/python2.5/lib-dynload/"
                                                       ;; django, etc. están aquí. Debian
                                                       "/usr/lib/pymodules/python2.6/"
                                                       "/usr/lib/pymodules/python2.6" ;porsiaca
                                                       ;; django y otros están por aquí ← no, no, no; en Debian no, al menos.
                                                       "/usr/share/python-support/python-django"
                                                       ;; aquí está django-registration y django_extensions
                                                       "/usr/local/lib/python2.6/dist-packages/"
                                                       "/usr/local/lib/python2.6/dist-packages"
                                                       "/usr/share/pyshared"
                                                       "/usr/share/pyshared/"
                                                       ;; esto lo añado aquí pero obviamente estaría mejor en una definición de proyecto con Ede…
                                                       "/home/dc/.mirp/.miw/yubay/"

                                                       ))

;;;;;;; CEDET para Java
(setq semantic-java-dependency-system-include-path
      ;; '("/home/dc/ptop/eclipse/portal" …)

      (concatenate 'list
                   ;; pruebo esto para Liferay. 19.m5.2009: ¡he conseguido que los „import com.liferay.portal.service.GroupLocalServiceUtil;“ salgan en verde!
                   (map 'list (lambda (arg) (concat 
                                             "/home/dc/ptop/eclipse/portal/" arg "/src")
                                ) (list
                                "counter-impl"
                                "documentlibrary-impl"
                                "lock-impl"
                                "mail-impl"
                                "portal-impl"
                                "portal-kernel"
                                "portal-service"
                                "support-tomcat"
                                "test"
                                "util-bridges"
                                "util-java"
                                "util-taglib"
                                "util-wsrp"
                                ))

                   ;; Quería descomprir los rt.jar etc. para que pueda encontrarlos todos
                   ;; 19.m5.2009
                   ;;   cd /usr/java/latest/jre/lib;
                   ;;   mkdir jardescomp
                   ;;   for a in *.jar; do unzip -d jardescomp/$a $a; done
                   ;; Pero esto no funciona pues tengo sólo los .class, no los .java :-(
                   ;;(map 'list (lambda (arg) (concat 
                   ;;"/usr/java/latest/jre/lib/jardescomp/" arg "/")
                   ;; ) (list
                   ;; descomentar si alguna vez las necesito:
                   ;;"charsets.jar"
                   ;;"deploy.jar"
                   ;;"javaws.jar"
                   ;;"jce.jar"
                   ;;"jsse.jar"
                   ;;"management-agent.jar"
                   ;;"plugin.jar"
                   ;;"resources.jar"
                   ;;"rt.jar"
                   ;;))

                   ;; 19.m5.2009:
                   ;; En vez de eso, instalar paquete sun-java6-source y descomprimir:
                   ;;   root@CPU107:/usr/lib/jvm/java-6-sun# unzip src.zip -d descompsrc
                   ;; Con esto salen los java.*, javax.* etc. en verde.
                   (list "/usr/lib/jvm/java-6-sun/descompsrc")

                   ;; prueba para ver si tengo que hacer esto para cada proyecto cuyos imports no quiera ver en rojo. Funcionó.
                   (list "/w/trakkcor/src")

                   ))

;; no sé qué era esto pero hace que pete la carga de Emacs de tronco (con CEDET integrado). Desactivado.
;;(defcustom-mode-local-semantic-dependency-system-include-path
;;  jde-mode semantic-jde-dependency-system-include-path
;; ;  nil
;;semantic-java-dependency-system-include-path
;;  "Una copia del valor que tiene el modo de Java")
;; ;por si me hace falta manualmente: (setq semantic-jde-dependency-system-include-path semantic-java-dependency-system-include-path)

;;;;;;; CEDET para C++


;;;;;;;; qt3 (no, el Scribus 1.3.5 usa qt4)
;;(setq qt3-base-dir "/usr/include/qt3/")
;;(semantic-add-system-include qt3-base-dir 'c++-mode)

;;;;;;;; qt4

;; con esto veo (con semantic-analyze-debug-assist y por colores de #include) que /w/Scribus/trunk/Scribus/scribus/bookmwin.cpp por ejemplo ya carga bien


(setq qt4-base-dir "/usr/include/qt4")
(setq qt4-gui-dir (concat qt4-base-dir "/QtGui"))
(setq qt4-core-dir (concat qt4-base-dir "/QtCore")) ; QString etc.
(setq qt4-xml-dir (concat qt4-base-dir "/QtXml")) ; QDomDocument

(semantic-add-system-include qt4-base-dir 'c++-mode)
(semantic-add-system-include qt4-base-dir 'c-mode)

(semantic-add-system-include qt4-gui-dir 'c++-mode)
(semantic-add-system-include qt4-gui-dir 'c-mode)

(semantic-add-system-include qt4-core-dir 'c++-mode)
(semantic-add-system-include qt4-core-dir 'c-mode)

(semantic-add-system-include qt4-xml-dir 'c++-mode)
(semantic-add-system-include qt4-xml-dir 'c-mode)

;; lo del c-mode es para los .h, que no se abren en c++-mode

(add-to-list 'auto-mode-alist (cons qt4-base-dir 'c++-mode)) ; esto es porque hay ciertos ficheros (ej: /usr/include/qt4/QtGui/QWidget) que deben interpretarse como C/C++ para que CEDET los cargue, y la falta de extensión .cpp lo impide


;; Esto también es de un correo de Luca Pamparana.
;;(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat
;;qt4-base-dir "/Qt/qconfig.h"))
;;(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat
;;qt4-base-dir "/Qt/qconfig-dist.h"))
;;(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat
;;qt4-base-dir "/Qt/qglobal.h"))

;;;;;;;;; stdarg.h

(semantic-add-system-include "/usr/lib/gcc/i486-linux-gnu/4.3/include/" 'c-mode)
(semantic-add-system-include "/usr/lib/gcc/i486-linux-gnu/4.3/include/" 'c++-mode)

;;;;;;; CEDET para C

;; Por probar este consejo de en la lista, hasta conseguir que sea *cómodo* y que ayude *mucho* (en muchas ocasiones, no sólo al completar cierto tipo de cosa)

;; Bind semantic code completion to useful keys

;; Uncomment next line to have "." start autocompletion in C++ mode
;; (define-key c-mode-map "." 'semantic-complete-self-insert)
;; Uncomment next line to cycle through autocompletions on ctrl-tab
;; (define-key c-mode-map (kbd "C-<tab>") 'semantic-ia-complete-symbol-menu)

;; ¿Esto va? Parece que sólo va si lo aplico desde „customize“. Quizás es por el orden y necesito algún (require) antes
;; Aún sale en rojo → Usar semantic-decoration-unknown-include-describe para ver los porqués
(setq semantic-c-dependency-system-include-path '(
                                                  ;; así puedo editar .xs, ẽ de Net::Bluetooth
                                                  "/usr/lib/perl/5.12/CORE/"
                                                  "/usr/lib/include/" ; ya salía
                                                  "/usr/include/" ; aquí están stdio.h, etc
                                                  ))
;; quizás es ésta la forma de hacerlo… Sí, eso parece
(semantic-add-system-include "/usr/lib/include/" 'c-mode)
(semantic-add-system-include "/usr/include/" 'c-mode)
;; actualizar ¿cómo? C-u M-x bovinate RET, quizás
;; El semantic-add-system-include seguido de un C-u bovinate me ha quitado los rojos al momento :-) El resto de pruebas, no.




;;;;;;; CEDET para PHP
;; por probar. Es de cedet-contrib
;; (require 'wisent-php) 

;;;;;;; CEDET para Ruby
;; En contrib hay algo

;;;;;; Autocompletado (para todos los lenguajes)
;; 19.m5.2009: por primera vez consigo algo muy útil: después de haber configurado el java-system-include-path~, me puedo poner detrás del punto en:
;;        List groups = GroupLocalServiceUtil.
;; y apretar C-c , ESPACIO  (o senator-completion-menu-popup), ¡y me sale un menú con compleciones!
;; No hay que hacer nada más

;; → por ahora ver auto-complete


;;;;;; Definición de proyectos (colecciones de ficheros de código)
;; Con files.el (el de Ede)
;; MALFAR [#C]: probar
;;;;;;; con projectile
;; creo que no me hace falta eval-after-load
;;(eval-after-load "projectile" '(progn
(require 'projectile)
(projectile-mode)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
;;))

;;;;; ECB (Emacs Code Browsing): pone varias ventanitas útiles
;;;;;; lo ignoro pues hace años que no lo uso. El último código que tengo en m9.2016 es de hace >6 años
;; si reactivo, no meter en cdv, sino en /w/
(ignore '(
;;;;;; carga

          (add-to-list 'load-path "~/.emacs.d/ecb-snap/") ;; m11.2017 lo quité


          (require 'ecb-autoloads)
          ;; Poner...:
          ;;(require 'ecb)
          ;; ...si se quiere que cargue TODO al principio: más lento, pero más útil.
          ;; Como prefiero „un poco de rapidez en un 95% de los casos“ antes que „mucha rapidez en el 5% de los casos“, no lo precargo

;;;;;; colores
          (eval-after-load "ecb" '(progn
                                    ;; Le quito el color magenta brillante cursi de fondo que viene por defecto
                                    (set-face-background 'ecb-default-highlight-face "#700")
                                    ;; y el verde brillante de fondo también. Se usa para remarcar la función clicada
                                    (set-face-background 'ecb-tag-header-face "#051")
                                    ))
;;;;;; ajustes
          ;; Cambio la locura del botón2 (rueda) por el cómodo botón1 (izquierdo) para ECB.
          ;; Queda: izq normal, rueda apuntar, S-izq recargar/~ver_esquema_rápido/restringir_a_función (¡muy útil!), C-izq para abrir en otra ventana (Que no marco);
          ;; Nota: con teclado, RET ~es el primario y C-RET ~ el secundario
          ;; Ah, el botón derecho queda para un menú
          (set 'ecb-primary-secondary-mouse-buttons (quote mouse-1--C-mouse-1))


          ;; la parte izquierda de la ventana no ocupa tanto
          (setq ecb-windows-width 0.20) ; era 0.33

          ;; pues me gusta que abra un marco nuevo al activarlo, porque siempre que abría ECB me dejaba otro marco para el resto de cosas. Así ECB se parece más a una aplicación externa
          (setq ecb-new-ecb-frame t)

;;;;;; fallo al cerrar ventanas

          ;; 18.2.2009. Reproduir: ecb-active, ecb-deactive, kill-this-buffer
          ;; ∴ Solución: (setq menu-updating-frame nil)
          ;;menu-bar-non-minibuffer-window-p: Wrong type argument: frame-live-p, #<dead frame puc 0xb846188>
          ;;o:
          ;;Debugger entered--Lisp error: (wrong-type-argument frame-live-p #<dead frame  *Minibuf-1* 0xcf00da0>)
          ;;  frame-selected-window(#<dead frame  *Minibuf-1* 0xcf00da0>)
          ;;  menu-bar-non-minibuffer-window-p()
          ;;  kill-this-buffer()
          ;;  call-interactively(kill-this-buffer nil nil)

          ;; I és perquè:
          ;;menu-updating-frame is a variable defined in `C source code'.
          ;;Its value is 
          ;;#<dead frame  *Minibuf-1* 0xcf00da0>

          ;; Solución:
          ;; (setq menu-updating-frame nil)

          ;; Entro más en detalles: creo que esto pasa tras haber abierto un emacsclient con parámetros (ej. „ec .“); eso confunde ya a ese mismo ec, y le cuesta cerrar su propio búfer

          ;; Ver arriba porque también afecta a Speedbar.
          ;;llamar: (dead-frame-lo-corrijo)
          (defun dead-frame-lo-corrijo ()
            "Corrige ese error de #<dead frame Algo.org 0xb650da8> [5 times]
Wrong type argument: frame-live-p, #<dead frame Algo.org 0xb650da8>
"
            (interactive)
            (setq menu-updating-frame nil)
            )


          ;; por cierto, un error muy parecido:
          ;; calendar-generate-window: Symbol's function definition is void: window-combination-p
          ;; ∴ abrir calendar.el.gz mediante anything, y eval-buffer, y ya va

;;;;;; fin del ignore
          ))
;;;;; elib: un paquete antiguo requerido por JDE (por avltree, creo)
(add-to-list 'load-path "~/.emacs.d/elib-1.0")

;;;;; BeanShell (bsh), terminal para Java
;; bsh es usado por eieio (de Cedet), y hay que definir dónde está el jar.
;; O se instala „bsh“ en Debian, o se usa el de JDE
;; Ambos me han dado algún problema; ej:                Error: // Error: EvalError: Undefined variable or class name while evaluating: bsh.system.icons.eye.image : at Line: 20 : in file: /bsh/commands/classBrowser.bsh : bsh .system .icons .eye .image 

;;(setq bsh-jar "/usr/share/java/bsh.jar")
;;(setq bsh-jar "~/.emacs.d/jde-2.3.5.1/java/lib/bsh.jar")
;;(setq bsh-jar "~/.emacs.d/jde-svn/java/lib/bsh.jar")
;;(setq bsh-jar "~/.emacs.d/jde-2.3.6-svn/java/lib/bsh.jar")
(setq bsh-jar "~/.emacs.d/jde-2.4-svn/dist/java/lib/bsh.jar")

;; (No sé si es necesario; JDE ya sabe dónde encontrar su BSH)

;; Pues no lo parece, porque…:
;;  Error: // Error: EvalError: Class or variable not found: jde.util.JdeUtilities : at Line: 1 : in file: <unknown file> : jde .util .JdeUtilities .setProjectValues ( "" , "" ); Por ello:
;;(add-to-list 'bsh-classpath "/home/dc/.emacs.d/jde-2.4-svn/dist/classes/")
;; No sé si es necesario. (setq bsh-classpath ())

;; Probando con: System.out.println(jde.util.ClassInfo.START_PAREN);
;; Al final ha ido eso

;; Pero el mensaje me lo da igual; no encuentra JdeUtilities


;; Sobre el error:
;; Debugger entered--Lisp error: (error "Specified BeanShell jar filed does not exist: /home/dc/.emacs.d/jde-2.4-svn/build/java/lib/bsh.jar")
;;
;; Enviado a jdee-devel@lists.sourceforge.net el 19.m8.2009
;; Y sugiero:
;;- 1. either JDEE should look for bsh.jar in the correct path, /home/dc/.emacs.d/jde-2.4;-svn/java/lib/bsh.jar
;;- 2. or java/ should be copied to build/
;;- 3. something else is failing for me
;; Viene de initialize-instance

;; Como esquive usé uso un enlace a java/. Creo que después lo corrigieron.


;;;;; JDEE: entiende y ayuda con el código Java
;; también llamado: JDE
;; Necesita: CEDET, elib. Recomienda: ECB
;;;;;; antes de cargar, me preparo
;; en vez de defconst uso defcustom, a ver si carga bien
(defcustom jde-xemacsp (string-match "XEmacs" (emacs-version))
  "Non-nil if we are running in the XEmacs environment.")
;; quizás es debido a jde-bug.el (línea 84 de jde.el)

;;;;;; carga
;;(add-to-list 'load-path "~/.emacs.d/jde-2.3.5.1/lisp") ; 2.3.5.1 es del 2007
;;(add-to-list 'load-path "~/.emacs.d/jde-svn/lisp")
;;(add-to-list 'load-path "~/.emacs.d/jde-2.3.6-svn/lisp")
;; Hay que cargar dist/, no build/, comprobado
;;(add-to-list 'load-path "~/.emacs.d/jde-2.4-svn/dist/lisp")
(add-to-list 'load-path "~/.emacs.d/jde-2.4-svn/dist/jdee-2.4.0.1/lisp")
;;(load "jde-autoload")
;; más chapucero: sin compilar
;;(add-to-list 'load-path "~/.emacs.d/jde-2.4-svn/lisp")

;;DESACTIVÉJDÉ:; (require 'jde)
;; 24.m3.2010: desactivo jde (muy a disgusto) porque parece que no puede ir con el Emacs actual (>=23.2), tal como explico en http://www.emacswiki.org/emacs/JavaDevelopmentEnvironment#toc5 un poco
;;
;; Puedo contar en emacs.org el porqué y quejarme a Emacs, o explicar en algún lado
;; lo de convertir a 8+3 para favorecer a un ¿cuánto? ¿5%? de usuarios y complicar la vida al 95% fue una decisión estúpida




;; para esto hay que compilar antes JDE
;; Para ello hace falta algo como:
;; - instalar ant-contrib desde http://sourceforge.net/projects/ant-contrib/files/
;; - cp /n/ant-contrib/ant-contrib-1.0b3.jar /usr/share/ant/lib/
;; - bajar (si no se tiene) JDEE:
;;  - todo:  svn co https://jdee.svn.sourceforge.net/svnroot/jdee jdee 
;;  - mejor: svn co https://jdee.svn.sourceforge.net/svnroot/jdee/branches/2.4.0 jdee-2.4-svn
;; - simplemente ejecutar ant
;; - si no va…:
;;  - imagino que algo así hay que hacer: ant  -Delib.dir=~/.emacs.d/elib-1.0 -Dcedet.dir=~/.emacs.d/cedet-cvs -Dbuild.bin.emacs=emacs-snapshot -v
;;  - pero a veces falla
;;  - … En caso de que quiera sacar todo de otra ruta, cambiar el build.el generado (mal generado)
;; - hay que cargar desde dist/ y no build/
;;
;; 24.m3.2010: Ai apt-contrib y lo deja en /usr/share/java/ant-contrib.jar
;; Por tanto ∴ hay que hacer: ln -s /usr/share/java/ant-contrib.jar /usr/share/ant/lib/
;; y funciona.

;;(message "no cargo jde")

;;;;;; Defino mi versión de JDK (y evito problema cuando a JDE no le gusta la mía)
;; 
;; Debugger entered--Lisp error: (wrong-type-argument integerp nil)
;;   substring("java-latest" nil nil)
;;   (string-to-int (substring version (match-beginning 2) (match-end 2)))
;;   (let ((version ...)) (string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" version) (string-to-int (substring version ... ...)))
;;   jde-java-minor-version()
;; ...

;; (jde-java-version) es "java-latest". Pero esta función, (jde-java-minor-version), no lo aceptará:
;; (defun jde-java-minor-version () "Returns an integer representing the minor version of the JDK being used by the current project."
;;  (let ((version (jde-java-version)))
;;    (string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" version)
;;    (string-to-int (substring version (match-beginning 2) (match-end 2)))))

;; Pues defino yo mi JDK con "latest-1.6" en vez de "java-latest". No hace falta cambiar directorios
(setq jde-jdk (quote ("latest-1.6")))
(setq jde-jdk-registry (quote (("latest-1.6" . "/usr/java/latest/") ("java6-sun-ubuntu" . "/usr/lib/jvm/java-6-sun/") ("java-1.5.0-sun" . "/usr/lib/jvm/java-1.5.0-sun/"))))



;;;;;; He de definir las rutas, supongo
;; se hace con jde-global-classpath, pero no sé cómo ponerlo

;;;;;; problema: no van las teclas C-c C-v .

;; BONUS: que funcionen las teclas como C-c C-v . para completar (ahora el C-c C-v ya falla)
;; Se definen en jde.el:
;;(defcustom jde-key-bindings
;;  (list
;;   (cons "[?\C-c ?\C-v ?\C-a]" 'jde-run-menu-run-applet)
;;   (cons "[?\C-c ?\C-v ?\C-b]" 'jde-build)
;; ...
;; jde-key-bindings se define y usa en jde.el
;; jde-mode-keymap no lo tengo
;; Veo esto:
;;
;;        ;; Reset the key bindings in case jde-mode-keymap
;;        ;; was not bound at startup.
;;        (custom-initialize-reset 'jde-key-bindings nil)
;;
;; 15.10.2008: me funcionó una vez porque lo llamé a mano...

;;;;;; notas sobre la carga de BeanShell
;;---
;;
;; Nota: el (require 'jde) hace un (jde-bsh "JDEE BeanShell") que va a entrar en un comint-mode que me redefinirá por ej. M-n. Aunque yo le haya definido comint-mode-hook, sólo me lo va a ejecutar SI EL GANCHO HA SIDO DEFINIDO ANTES DEL (require 'jde). Si no, lo que hará es primero entrar en el modo y luego definir el gancho (que no se ejecutará a menos que lo haga yo manualmente una vez arrancado).
;; Así que el orden de las declaraciones es importante: el gancho ha de ser puesto ANTES de esta línea.
;; Esto me llevó muchos muchos días de pruebas y aprendizaje con Lisp, y al final el 13.9.2008 4:49 AM lo descubrí.
;;
;; Útiles que probé:
;;
;; (debug-on-entry jde-bsh)
;;(debug-on-entry eieio-generic-call)
;;(progn (debug) (require 'jde) (pita-de-verdad) )
;;     (defadvice jde-bsh (after asegurarse-de-que-bsh-esté-en-comint-mode (newname &rest fields)) ..... )
;;(jde-bsh "JDEE BeanShell") ; Y por si acaso, la rellamo
;;
;; comint-mode-map incluye esto:
;;(keymap
;; (27 keymap
;;     (110 . comint-next-input)))
;; ... lo que equivale a M-n. Lo vi con: (let ((k (make-sparse-keymap))) (define-key k "\M-n" 'previous-line) (prin1 k))
;;
;;---

;; Nota: se puede usar jde-launch-beanshell-on-demand-p = nil para que cargue la conchita nada más abrir un .java; en vez de cuando la necesita


;;;;;; Ajustes para la edición de código
;; En el funcionamiento normal, aún veo bastante subrayado rojo cuando no es XHTML perfecto; ej: JSP, HTML, ...
;;(set-face-underline 'rng-error-face "#c00") ; al menos, que el subrayado no sea tan rojo :-)
;; En diciembre de 2008 ya no recuerdo que falle esto.

;;;;;; importación de proyectos desde Eclipse

;;;;;;; Objetivo Maven2 para crear prj.el

;; Usar Maven2 para crear prj.el y luego ponerlo en Wiki
;; http://www.credmp.org/2006/11/18/maven2-plugins/

;; 11.12.2008: lo probé e iba bien :-)
;; 1. Lo bajé de http://server.apnet.cz/~benzin/maven-emacs-plugin/
;; 2. Modifiqué un poco el Pojo para quitar la clase Messages
;; 3. mvn install
;; 4. mvn org.apache.maven.plugin:maven-emacs-plugin:1.2.2:jdee
;; 5. Creó 2 prj.el y petó por algo de Javadoc
;; 6. El prj usaba funciones de los .el que yo tuve que instalar en mi emacs

(add-to-list 'load-path "~/.emacs.d/jde-maven2")

;;;;;;; Una función que valoriza variables

;; cogido de http://www.emacswiki.org/emacs/SurajAcharya#ReadJdeVarsFromEclipseConfig
;; Falta probar bien con proyectos pequeños

(defun jde-load-project-values-from-eclipse-config-file (cp)
  "Read jde project values from eclipse .classpath config file"
  (interactive "s")
  (setq cp (xml-parse-file cp))
  
  (let (src-path class-path)
    (walk-classpath-xml (lambda (type path ex) 
                          (setq path (if (file-name-absolute-p path)
                                         path
                                       (concat "./" path)))
                          (if (not ex)
                              (cond 
                               ((equal type "src")
                                (setq src-path (cons path src-path)))
                               ((or (equal type "lib") (equal type "output"))
                                (setq class-path (cons path class-path)))
                               )))
                        cp)
    (setq jde-global-classpath class-path)
    (setq jde-sourcepath src-path)))

(defun walk-classpath-xml (f e) 
  (if (listp e)
      (if  (eq (car e) 'classpathentry)
          (let ((entry (cadr e)))
            (funcall f (cdr (assoc 'kind entry)) (cdr (assoc 'path entry)) (assoc 'excluding entry)))
        (mapc (lambda (x) (walk-classpath-xml f x)) e))))

;;;;;; Descompilar código Java
;;;;;;; mediante jde-decompile y JAD
;; uso Jad+decompile.el ( http://www.emacswiki.org/emacs/JdeeDecompile )
;; Luego descubrí: pero mediante jdc.el, no hace falta tener JDEE para usar esto
;; En 2023 veo que desde 2006 JAD está desfasado. Pero aún funciona en bastante código
;; m3.2023: de todas formas lo borraré, he pasado a procyon, ver abajo
(ignore '(
          ;; Me ayudaron estas instrucciones antiguas: http://www.skybert.nu/cgi-bin/viewpage.py.cgi?computers+emacs+java_decompiling
          (add-to-list 'load-path "~/.emacs.d/jde-decompile/")
          (require 'decompile)
          ;; Si no me fuere JDE podría cambiar el require por esto: ;(autoload 'decompile "decompile")

          ;; Algún día lo puedo borrar del repositorio
          (setq jdc-command "~/ut/jad")

          ;; también cuando se abre un .class de dentro de un .jar/.war/.ear/… / paquete. De EW
          (add-hook
           'archive-extract-hooks
           (lambda () 
             ;; con copiar+pegar se perdió y quedó "\312\376\272\276"; lo restauré
             (cond ((string-match (string 4194250 4194302 4194234 4194238) (buffer-substring-no-properties 1 5)) ;;CAFEBABE
                    ;; lo obtuve con: (string-to-list (buffer-substring-no-properties 1 5))
                    ;; así no va…:
                    ;;   (cond ((string-match  (string #xCA #xFE #xBA #xBE) (buffer-substring-no-properties 1 5)) ;;CAFEBABE
                    (jdc-buffer)))))
          ;; quitarlo: (setq archive-extract-hooks nil)

          ))
;;;;;;; mediante jdecomp y procyon
;; https://github.com/xiongtx/jdecomp
(customize-set-variable 'jdecomp-decompiler-type 'procyon)
(customize-set-variable 'jdecomp-decompiler-paths
                        '(
                          ;;(cfr . "~/Downloads/cfr_0_118.jar")
                          ;;(fernflower . "~/idea-IC-162.1628.40/plugins/java-decompiler/lib/java-decompiler.jar")
                          (procyon . "/usr/share/java/procyon-decompiler.jar")))

(jdecomp-mode)

;; mmmmm… pero me da:
;; JavaClassFileReadException: can't open input file on `~/.emacs.d/tmp/jdcMVk4Ba.class'
;; JavaClassFileReadException: can't open input file on `~/.emacs.d/tmp/jdcfWztwS.class'
;; aaaah, era por seguir teniendo cargado jde-decompile

;;;;;; Depurar Java
;; MALFAR: Probar distintos métodos de (viejo): http://www.skybert.nu/cgi-bin/viewpage.py.cgi?computers+emacs+java_debugging .... entre otros JDIBUG

;;;;;; probar jde-usages
;; Dicen que eso acerca JDEE a Eclipse; junto con Flymake

;;;;;; que me muestre los errores mientras tecleo. flymake, etc.

;; (require 'flymake) ;  ← comentado pues decidí usar el de /w/emacs-flymake, lo cargo abajo. Si hay algún problema con orden de carga… pues reordenar hasta que vaya

;; alguna configuración genérica de flymake: ver donde está el flymake-log-level y etc.


;; Uso compilador de Eclipse

;;;;;;; solución de credmp usando ecj.jar; *no va*
(ignore '(
          (defun flymake-java-ecj-init ()
            (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                                 'jde-ecj-create-temp-file))
                   (local-file  (file-relative-name
                                 temp-file
                                 (file-name-directory buffer-file-name))))
              ;; Ai ecj
              ;; Change your ecj.jar location here
              (list "java" (list "-jar" "/usr/share/java/ecj.jar" "-Xemacs" "-d" "/dev/null"
                                 "-source" "1.5" "-target" "1.5" "-proceedOnError"
                                 "-sourcepath" (car jde-sourcepath) "-classpath"
                                 (jde-build-classpath jde-global-classpath) local-file))))

          (defun flymake-java-ecj-cleanup ()
            "Cleanup after `flymake-java-ecj-init' -- delete temp file and dirs."
            (flymake-safe-delete-file flymake-temp-source-file-name)
            (when flymake-temp-source-file-name
              (flymake-safe-delete-directory (file-name-directory flymake-temp-source-file-name))))

          (defun jde-ecj-create-temp-file (file-name prefix)
            "Create the file FILE-NAME in a unique directory in the temp directory."
            (file-truename (expand-file-name (file-name-nondirectory file-name)
                                             (expand-file-name  (int-to-string (random)) (flymake-get-temp-dir)))))
          
          (push '(".+\\.java$" flymake-java-ecj-init flymake-java-ecj-cleanup) flymake-allowed-file-name-masks)
          
          (push '("\\(.*?\\):\\([0-9]+\\): error: \\(.*?\\)\n" 1 2 nil 2 3 (6 compilation-error-face)) compilation-error-regexp-alist)
          
          (push '("\\(.*?\\):\\([0-9]+\\): warning: \\(.*?\\)\n" 1 2 nil 1 3 (6 compilation-warning-face)) compilation-error-regexp-alist)


          ;; y su función para usar minibúfer para mostrar el error: borrada pues no me hace falta (ya lo tengo, no recuerdo cómo)

          ))

;;;;;;; 2ª versión basada en la de credmp pero corrigiendo cosas; ésta funciona (18.m3.2010)
(ignore '( ; m2.2015 por reprobar con flymake de illusori
          
          ;;(defconst ecj-jar-path "/path/to/ecj-3.4M4.jar")
          ;;(defconst ecj-jar-path "/usr/share/java/ecj.jar")
          ;; ∴ Tengo que usar el de Eclipse pues el de Debian no va bien (da error de configuración o algo así). Otros también lo aconsejan
          ;; ¿De dónde saco ecj.jar?
          ;; Since 3.2, it is also available as a separate download. The name of the file is ecj.jar. Its corresponding source is also available. To get them, go to the download page and search for the section JDT Core Batch Compiler. This jar contains the batch compiler and the javac ant adapter.
          ;; JDT/Core está en http://www.eclipse.org/jdt/core/dev.php
          ;; También en:
          ;; /opt/dc/eclipse/plugins/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar
          ;; En org/eclipse/jdt/internal/compiler/batch/Main.class aparentemente
          ;; → Esto va:    java -classpath /opt/dc/eclipse/plugins/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar org.eclipse.jdt.internal.compiler.batch.Main
          ;; Y ejecuto: Eclipse Compiler for Java (TM) 0.981_R35x, 3.5.2 release. Copyright IBM Corp 2000, 2009. All rights reserved.
          ;; Frente al „ecj“ normal: Eclipse Java Compiler 0.972_R35x, 3.5.1 release. Copyright IBM Corp 2000, 2009. All rights reserved.
          ;; Bueno, defino este jar y luego lo usaré como -classpath (18.m3.2010: eso me funcionó):
          ;;(defconst ecj-jar-path "/opt/dc/eclipse/plugins/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar")
          ;;(if (not (file-exists-p ecj-jar-path)) (setq ecj-jar-path "/usr/lib/eclipse/plugins/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar")) ; para cuando lo instalé por apt-get

          ;; m9.2011: no tengo Eclipse y por tanto no tengo ECJ, pero veo que está en Debian el paquete „ecj“, así que lo saco de ahí
          (defconst ecj-jar-path "/usr/share/java/ecj.jar")
          (if (not (file-exists-p ecj-jar-path)) (message "¡instala el paquete ecj para tener flymake en java!"))


          (defvar flymake-java-version "1.5")

          ;;(defvar flymake-java-classpath ".;/path/to/elsewhere")
          ;;(defvar flymake-java-classpath "/w/phoneme_feature/midp/src/highlevelui/lcdui/reference/classes/"…)
          ;; empiezo con CLDC 1.1 y MIDP 2.1; éstos ya contienen Form etc.
          (defvar flymake-java-classpath "/opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/cldcapi11.jar:/opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/midpapi21.jar")
          ;; Mejor sería: evitar hacer esto aquí así; se supone que flymake tiene que evaluar todo usando el classpath del proyecto actual (según dice JDE). Sólo que JDE no lo sabe decir bien aún…
          ;; para org.apache.commons.logging.Log → instalar paquete libcommons-logging-java y luego usar esto
          (setq flymake-java-classpath (concat flymake-java-classpath ":/usr/share/java/commons-logging-api.jar"))
          ;; para javax.servlet.http.HttpServletRequest → instalar paquete libservlet2.5-java y luego:
          (setq flymake-java-classpath (concat flymake-java-classpath ":/usr/share/java/servlet-api-2.5.jar"))
          ;; para que encuentre clases presentes en mismo directorio ← no, esto no va. Supongo que mejor usar EDE o similar
          ;; (setq flymake-java-classpath (concat flymake-java-classpath ":.")) ; chapuza y no va


          (defun flymake-java-ecj-init ()
            (let* ((temp-file (flymake-init-create-temp-buffer-copy
                               'flymake-ecj-create-temp-file))
                   (local-file (file-relative-name
                                temp-file
                                (file-name-directory buffer-file-name)))
                   ;; dclemente: Me ha llevado unas 6 horas descubrir que el uso de rutas relativas no funciona debido a un pequeñísimo detalle con las particiones de disco . Ver en proj.org „se ha estropeado flymake en lòvic“. Sobreescribo el valor anterior (relativizado) de local-file
                   (local-file temp-file)
                   )
              (list "java" (list 
                            ;;"-jar" ecj-jar-path
                            ;; dclemente: tengo que ejecutar esta clase de dentro del jar ecj-jar-path
                            "-classpath" ecj-jar-path "org.eclipse.jdt.internal.compiler.batch.Main"
                            "-Xemacs" "-d" "none" ; "-warn:none"
                            "-source" flymake-java-version "-target" flymake-java-version "-proceedOnError"
                            "-classpath" flymake-java-classpath
                            ;; "-log" "e:/temp/foo.xml"
                            local-file))))

          ;; probar: (flymake-java-ecj-init)
          ;; Para probar, aquí va un ejemplo real de cadena generada (la he hecho a mano):
          ;; java -classpath /opt/dc/eclipse/plugins/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar org.eclipse.jdt.internal.compiler.batch.Main -Xemacs -d none -source 1.5 -target 1.5 -proceedOnError -classpath /opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/cldcapi11.jar:/opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/midpapi21.jar:/w/gpsmid-nomésant/build/real/Generic/full/en/classes:/opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/jsr179.jar /w/gpsmid-repo-bzr/personalització/src/de/ueller/midlet/gps/Splash.java 
          ;; Esto va.
          ;; Pero a veces que falla ha usado ficheros de „/ tmp“:
          ;; Flymake: Configuration error has occurred while running (java -classpath /opt/dc/eclipse/plugins/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar org.eclipse.jdt.internal.compiler.batch.Main -Xemacs -d none -source 1.5 -target 1.5 -proceedOnError -classpath /opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/cldcapi11.jar:/opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/midpapi21.jar:/w/gpsmid-nomésant/build/real/Generic/full/en/classes:/opt/dc/netbeans-6.8/mobility8/WTK2.5.2/lib/jsr179.jar ../../../../../../../../tmp/230611125/Splash.java). Flymake will be switched OFF
          ;;


          (defun flymake-java-ecj-cleanup ()
            "Cleanup after `flymake-java-ecj-init' -- delete temp file and dirs."
            ;;)
            (flymake-safe-delete-file flymake-temp-source-file-name)
            (when flymake-temp-source-file-name
              (flymake-safe-delete-directory (file-name-directory flymake-temp-source-file-name))))

          ;; esto va bien. Sólo devuelve un nombre
          (defun flymake-ecj-create-temp-file (file-name prefix)
            "Create the file FILE-NAME in a unique directory in the temp directory."
            (file-truename (expand-file-name (file-name-nondirectory file-name)
                                             (expand-file-name (int-to-string (abs (random))) (flymake-get-temp-dir)))))

          (push '(".+\\.java$" flymake-java-ecj-init flymake-java-ecj-cleanup) flymake-allowed-file-name-masks)

          (push '("\\(.*?\\):\\([0-9]+\\): error: \\(.*?\\)\n" 1 2 nil 2 3 (6 compilation-error-face)) compilation-error-regexp-alist)

          (push '("\\(.*?\\):\\([0-9]+\\): warning: \\(.*?\\)\n" 1 2 nil 1 3 (6 compilation-warning-face)) compilation-error-regexp-alist)

          ;; ¿esto hace falta?: …provide 'flymake-java

;;;;;;; activar siempre flymake en java
          (add-hook 'java-mode-hook 'flymake-mode-on)
          ))

;;;;;; sus faces (cambio algunas pocas que no me gustan)
;; para enlaces {@link …} en JavaDoc
;;DESACTIVÉJDÉ:;(set-face-foreground 'jde-java-font-lock-link-face "#09f") ; era blue, muy oscuro

;;;;; Alternativa a JDEE para Java: malabar-mode
;; BONUS: probar. http://www.emacswiki.org/emacs/MalabarMode

;;;;; Slime (entorno para Common Lisp)
(ignore '( ; lo desactivo el 13.m10.2010 porque no lo estoy usando y porque no me carga en Emacs de hoy. Cuando lo reúse, mejor actualizarlo, pues es de m1.2009
          (add-to-list 'load-path "~/.emacs.d/slime-cvs/")  ; your SLIME directory  ← no usar éste, no poner en cdv; ponerlo en /w/ todo. Ya lo borré de cdv en 20.m9.2016
          ;;(setq inferior-lisp-program "/usr/bin/clisp") ; your Lisp system
          (setq inferior-lisp-program "/usr/bin/sbcl") ; your Lisp system
          (require 'slime)
          (slime-setup '(slime-repl)) ; Setup Emacs so that lisp-mode buffers always use SLIME.
          ;; entonces usar M-x slime
          )) ; fignore


;; Probar esto; no va el completar
;; ESC-TAB iretas
(setq slime-complete-symbol-function 'slime-fuzzy-complete-symbol)
(setq slime-complete-symbol-function 'slime-simple-complete-symbol) ; normal

;; para que vaya la coma (,), hay que cargar el contrib slime-repl.el en el slime-setup; hecho y ya va.

;;;;; todo lo de tree-sitter
;; Dicen que mejora cosas externas pero no explican el qué; parece que es sólo interno
;; Probé a activarlo, por si es más rápido o por si delega trabajo (de Emacs a tree-sitter)
;; Es muy guarrillo eso de X-mode y X-ts-mode, para modos que tienen las mismas funciones de cara al usuario (sólo la implementación cambia). Faltan unos años para que se den cuenta y los vuelvan a unir a un solo modo. Pero veo arrogancia y peleas personales entre quienes defienden tener los modos separados (ej. https://lists.gnu.org/archive/html/emacs-devel/2023-02/msg00460.html) y alguno dice que está mal pero que las alternativas también son malas (https://lists.gnu.org/archive/html/emacs-devel/2023-02/msg00643.html). Drama de película.
;; Debido a esa decisión chapucera de tenerlos separados, hay que redefinir muchas cosas, por ejemplo yasnippet, para decir „has de funcionar en python-mode y en python-ts-mode“, cuando a yasnippet le da igual qué implementación (ts/¬ts) se usa. ∴ Arreglo esto con enlace, pero es chapucilla
;; Por todo eso, no voy a meterme en los ts-mode aún.
(ignore '(
          ;; Para C
          (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
          (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
          (add-to-list 'major-mode-remap-alist
                       '(c-or-c++-mode . c-or-c++-ts-mode))

          ;; Python
          (add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))

          ;; ¿qué más? ¿Y realmente me sirve de algo todo esto?
))


;;;;; Ayudas para Emacs Lisp
;; (require 'lisp-mode)
;; eldoc-mode da la información de toda función y variable en la línea de modo. Es muy rápido y funciona bien. Qué pena que sólo lo haya descubierto en m7.2010, tan tarde…

;; lo desactivo porque no lo aprovecho mucho y es sospechoso de retardarme todo. Si lo echo en falta, reactivar
(ignore '(
          (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
          (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode)
          (add-hook 'ielm-mode-hook 'turn-on-eldoc-mode)
          (add-hook 'python-mode-hook 'turn-on-eldoc-mode)
          ;; eldoc error: (error Eldoc needs an inferior Python process running)

          ))

;; Parece que eglot lo activa


;; BONUS: probar y acostumbrarme a usarlo
;;(global-set-key (kbd "C-c f")
(define-key emacs-lisp-mode-map (kbd "C-c f")
  (lambda ()
    (interactive)
    (require 'finder)
    (let ((thing (intern (thing-at-point 'symbol))))
      (if (functionp thing)
          (find-function thing)
        (find-variable thing)))))


;; otros; aporta C-x F  y C-x V
;;(require 'find-func)
;;(find-function-setup-keys)

;;;;; Modos para Python
;;;;;; pymacs, y ropemacs

;;;;;;; versión muy vieja con mi pymacs modificado y mi ropemacs
;; En 2021 la borré de mi cdv, pues era de 2009
;; Borré la configuración de aquí también.

;;;;;;; versión de apt-get (ambos), tampoco la quiero
;; versión aún más fácil, con menos riesgo de equivocarse: la de apt-get.  Éste funciona. Seguir con éste e ir probando de vez en cuando el último (de cdv)
(ignore '(
          (let ((d "/usr/share/emacs25/site-lisp/pymacs/"))
            (when (file-exists-p d) 
              (add-to-list 'load-path d)
              (autoload 'pymacs-apply "pymacs")
              (autoload 'pymacs-call "pymacs")
              (autoload 'pymacs-eval "pymacs" nil t)
              (autoload 'pymacs-exec "pymacs" nil t)
              (autoload 'pymacs-load "pymacs" nil t)
              ;; para probar: M-x pymacs-eval RET repr(2L**111) RET
              ;; 19.m6.2009: le tuve que aplicar una corrección a pymacs.el seria para establecer PYTHONPATH; avisé al autor. Luego ya no falló


              ;; Instalarlo con Ai python-ropemacs. http://stackoverflow.com/questions/2855378/ropemacs-usage-tutorial
              (pymacs-load "ropemacs" "rope-") ; Esto me dio problemas al cargar, algo de incompatibilidad de versiones. Ver cdv. Ya no.

              ;; MALFAR: se cuelga mucho y se embucla. En concreto leyendo /usr/lib/python2.7/dist-packages/django/db/models/fields/related.py , se está un rato y vuelve a entrar en otros y luego al mismo
              ;; al grabar hace rope-after-save-actions; no me gusta; quitar
              ;; Investigar desde: /usr/lib/python2.7/dist-packages/ropemacs/__init__.py

              ;; Otro: „Object vanished when the Pymacs helper was killed“


              ;; otro error sale al apretar M-/:
              ;; pymacs-report-error: Python: UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 25: ordinal not in range(128)
              ;; Y esto es porque está en ruta con „ñ“. Curioso que si el nombre tiene tildes no pasa, pero con eñe sí.
              ;; Me voy mirando: /usr/local/lib/python2.7/dist-packages/Pymacs.py, en concreto los dos .encode() que tiene. He añadido chivatos
              ;; Parece que no es de Pymacs sino de ropemacs, por algún sitio cercano a un: (make-progress-reporter (decode-coding-string "Opening [/…n/t\303\251] project ... " 'utf-8) 0 100)
              ;; Yo diría que ya el ropemode/interface.py cuando llama a:         progress = self.env.create_progress('Opening [%s] project' % root)   ya lo está haciendo mal. Coge mal root ó address
              ;; BONUS: escribir a la lista que sale al final de http://rope.sourceforge.net/ropemacs.html y sugerir usar unicode dentro y utf8 fuera
              ;; 

              ))
          ))

;;;;;;; versión ultimísima de pymacs de cdv (instalada con pip) y de ropemacs por pip
;; Nota: lo he instalado mediante pip, con:   pip install .     (y luego: pip install ropemacs)
;; ∴ No, instalé el 0.25 bajado de web en .tar.gz ← creo que luego con „pip install .“
;; git://github.com/pinard/Pymacs.git
;; docu: http://pymacs.progiciels-bpi.ca/pymacs.html
;;(ignore '(
(if (file-directory-p "/w/Pymacs")
    (progn
      (message "cargo Pymacs de /w/")
      (setq load-path (cons (expand-file-name "/w/Pymacs/") load-path))

      ;; copiado de 0.25
      (autoload 'pymacs-apply "pymacs")
      (autoload 'pymacs-call "pymacs")
      (autoload 'pymacs-eval "pymacs" nil t)
      (autoload 'pymacs-exec "pymacs" nil t)
      (autoload 'pymacs-load "pymacs" nil t)
      (autoload 'pymacs-autoload "pymacs")

      (eval-after-load "pymacs"
        '(add-to-list 'pymacs-load-path "/w/Pymacs"))

      ;; dicen que esto soluciona una petada, pero a mí no:
      ;;(setenv "PYMACS_PYTHON" "python2.7")

      (pymacs-load "ropemacs" "rope-")

      ;; aún me dice: Pymacs helper did not start within 30 seconds

      ;;Traceback (most recent call last):
      ;;  File "<string>", line 1, in <module>
      ;;ImportError: cannot import name main
      ;; Llamar con: pymacs-start-services
      ;; IS: arreglado instalando de otro lado

      ;; luego:
      ;; ImportError: No module named Pymacs
      ;; Eso el (pymacs-start-services)
      ;; Sin embargo desde python hago un „import Pymacs“ y va
      ;; BONUS: arreglar éste

      ))
;;))

;;;;;;; configuración de ropemacs (sea cual sea la versión cargada)
(eval-after-load "pymacs"
  '(progn
     (message "configurando pymacs")
     (setq ropemacs-guess-project t)
     ;; (setq ropemacs-enable-autoimport t)

     ;; luego para que el grabado vaya rápido:
     ;; prefs['automatic_soa'] = False
     ;; en config.py. Visto en https://groups.google.com/forum/?fromgroups=#!topic/rope-dev/egXoYowa1T4
     ;; Si me pasa, usarlo

     ;; ropemacs me retrasa todo porque me pone (rope-before-save-actions) en before-save-hook Y (rope-after-save-actions) en el otro.
     ;; Una vez vi que era muy lento grabar un .org (sí, org) y entre medio el xbacktrace decía:
     ;;   "accept-process-output" (0xbf9090ec)
     ;;   "if" (0xbf909274)
     ;;   "while" (0xbf9093e4)
     ;;   "progn" (0xbf909514)
     ;;   "unwind-protect" (0xbf909644)
     ;;   "let" (0xbf909814)
     ;;   "save-excursion" (0xbf909974)
     ;;   "let*" (0xbf909b04)
     ;;   "save-current-buffer" (0xbf909c64)
     ;;   "pymacs-round-trip" (0xbf909d50)
     ;;   "let" (0xbf90a014)
     ;;   "while" (0xbf90a184)
     ;;   "let" (0xbf90a354)
     ;;   "pymacs-serve-until-reply" (0xbf90a440)
     ;;   "pymacs-apply" (0xbf90a650)
     ;;   "rope-before-save-actions" (0xbf90a98c)
     ;;   "run-hooks" (0xbf90aa58)
     ;;   "basic-save-buffer" (0xbf90ad58)
     ;;   "save-buffer" (0xbf90b0a4)
     ;;   "call-interactively" (0xbf90b2d4)
     ;;
     ;; Quiero que SÓLO ponga esos ganchos en python-mode; nunca en org-mode ni en otros (ahora me los pone en todos). O sea: que nunca lo cambie globalmente; sólo localmente en los búfers Python
     ;; Creo que ha de ser ropemacs el encargado de esto (no ropemode/pymacs)
     ;; O puedo hacer algo especial para los .org… Pero eso es cutre.

     ;; Do momento borro ganchos; destrozaré algo ropemacs, pero se lo merece :-) Me parece que lo único que hace es marcar que cierto fichero ha cambiado para poder reanalizar el resto. No pierdo mucho
     (remove-hook 'before-save-hook #'rope-before-save-actions)
     (remove-hook 'after-save-hook #'rope-after-save-actions)
     ;; Cuando necesite esto que he desactivado, hacer: que el gancho llame a una función que hace: si estoy en modo ¬python, no hago nada. En vez de poner como gancho una función Python directamente

     )
  )





;;;;;; flymake para Python. flymake-python
;; IS http://www.emacswiki.org/emacs/PythonProgrammingInEmacs#toc6
;; con epylint o pyflakes
;; Ya me va muy bien con pyflakes; es muy útil

(ignore '( ; m2.2015 porque usaré el de illusori (ver abajo)
          (when (load "flymake" t) 
            (defun flymake-pyflakes-init () 
              ;; Make sure it's not a remote buffer or flymake would not work
              (when
                  ;; esto es de tramp pero no va:    (not (subsetp (list (current-buffer)) (tramp-list-remote-buffers)))
                  (not (file-remote-p (buffer-file-name (current-buffer))))
                (let* ((temp-file (flymake-init-create-temp-buffer-copy 
                                   ;; sobre elección entre with-folder-structure o inplace: ver el comentario en flymake-c-init
                                   ;; 'flymake-create-temp-inplace)) 
                                   'flymake-create-temp-with-folder-structure)) 
                       (local-file (file-relative-name 
                                    temp-file 
                                    (file-name-directory buffer-file-name)))) 
                  (list "pyflakes" (list local-file))
                  ;; para ser MUY estricto, usar esto:
                  ;;(list "~/ut/valida_python.sh" (list local-file))
                  ;; pero prefiero ser „estricto“ y „perfeccionista“ a un nivel más abstracto (arquitectura del código) en vez de a nivel de sintaxis bonita
                  ;; Además parece que valida_python.sh ralentiza más que pyflakes

                  )))
            (add-to-list 'flymake-allowed-file-name-masks 
                         '("\\.py\\'" flymake-pyflakes-init))) 

          (add-hook 'python-mode-hook 'flymake-mode-on) ; me gusta pyflakes, va bien siempre

          ))

;; m2.2015 ésta es para versión de illusori
;; m2.2018 lo desactivo porque ese flymake es muy viejo (5 años)
(ignore '(
          (defun flymake-pyflakes-init-para-el-de-illusori ()

            (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                                 'flymake-create-temp-copy))
                   (local-file  (file-relative-name
                                 temp-file
                                 (file-name-directory buffer-file-name)))
                   )
              (list "pyflakes" (list local-file) )))

          ))

;; el cambiar flymake-allowed-file-name-masks lo tengo que hacer luego tras cargarlo; un poco feo pero tiene que ser en ese orden

(add-hook 'python-mode-hook 'flymake-mode-on)


;; Lo cambio al mío, adaptado para llamar a otros
;; Me va mucho mejor siempre ver los errores, y decidir no corregirlos. Es mejor que no verlos. Además en ẽ opencraft me hace falta verlos siempre
;;(setq python-flymake-command '("pyflakes"))
(setq python-flymake-command '("/home/dc/ut/valida_python_paraflymake.sh"))

;;;;;; jedi.el, para autocompletado e inspección de código
;; No es eglot/lsp
;; Va bien, pero lo desactivo ahora que hay eglot. „pyls“ ya abre „jedi“ como subproceso cuando toca
(ignore '(
          (add-hook 'python-mode-hook 'jedi:setup)
          ;;(remove-hook 'python-mode-hook 'jedi:setup)
          (setq jedi:complete-on-dot t)
          ;; (setq jedi:complete-on-dot nil)
          ))

;;;;;; eglot y lsp-mode
;; ¿Cómo abrirlo automáticamente?
;; De momento lo puedo usar en Python (pyls), C (ccls), …
;; Lo abriré a mano mientras pruebo

;; No va:
;;(add-hook 'python-mode-hook 'eglot)
;;(add-hook 'python-mode-hook 'eglot-mode)
;; Parece que es así:
(add-hook 'python-mode-hook 'eglot-ensure)
(add-hook 'c-mode-hook 'eglot-ensure)
(add-hook 'fortran-mode-hook 'eglot-ensure)
(add-hook 'f90-mode-hook 'eglot-ensure)


;; ¿Quién decide ẽ abrir pyls? Parece que eglot-server-programs



;; „inlay hints“
;; (add-hook 'eglot-managed-mode-hook #'eglot-inlay-hints-mode)
;; Pero me da:
;; [eglot] (warning) No :inlayHintProvider support. Inlay hints will not work.
;; Eso en C, Python, Fortran, …
;; Ah, ahora lo han activado por defecto, así que no me hará falta activarlo


;;;;;; pylookup (para documentación)
;; de https://github.com/tsgates/pylookup
;; Ignorado porque nunca lo uso; para documentación busco en internet o tomo notas
(ignore '(
          (let ((d "/w/pylookup"))
            (when (file-exists-p d) 
              (add-to-list 'load-path d)
              (setq pylookup-dir d)

              ;; prueba, no sé si tiene sentido. Creo que no va
              ;;(autoload 'pylookup "pylookup" "Visor de documentación" t)

              ;; Esto peta cuando no lo tengo
              ;; load pylookup when compile time
              (eval-when-compile (require 'pylookup))

              ;; set executable file and db file
              (setq pylookup-program (concat pylookup-dir "/pylookup.py"))
              (setq pylookup-db-file (concat pylookup-dir "/pylookup.db"))

              ;; set search option if you want
              ;; (setq pylookup-search-options '("--insensitive" "0" "--desc" "0"))

              ;; to speedup, just load it on demand
              (autoload 'pylookup-lookup "pylookup"
                "Lookup SEARCH-TERM in the Python HTML indexes." t)

              (autoload 'pylookup-update "pylookup" 
                "Run pylookup-update and create the database at `pylookup-db-file'." t)

              ))
          ;; y para usar: M-x pylookup-lookup
          ;; y lo abre en conkeror
          ;; BONUS: ¿no lo puedo abrir dentro de emacs?

          )) ; fin de ignore


;;;;; Modos para Django (aparte de todo lo de Python), y para HTML también
;; Información varia en https://code.djangoproject.com/wiki/Emacs

;; Quizás añadir: algo que me dé la documentación oficial para el campo/función/clase apuntada

;;;;;; MALFAR django-html-mumamo-mode → no, no quiero NXHTML ahora, gracias

;;;;;; MALFAR django-html-mode: basado en nxml. manage, yasnippet, saltos, marcar traducciones, …
;; Está en https://github.com/myfreeweb/django-mode

(ignore '( ; no hace nada útil → no lo quiero

          (let ((d "/w/django-mode/"))
            (when (file-exists-p d) 
              (add-to-list 'load-path "/w/django-mode/")
              (require 'django-html-mode)
              (require 'django-mode)
              ;; Ofrece sus plantillas:
              ;;(yas/load-directory "path-to/django-mode/snippets")
              ;; pero no me interesa ninguna; ¡no me aportan nada!
              (add-to-list 'auto-mode-alist '("\\.djhtml$" . django-html-mode))     ; MALFAR: pero yo no uso .djhtml
              ))
          ))
;; MALFAR: probar C-x j para saltar
;; - saltar a plantilla: no va porque busca „templates/“ ← chapucero
;; - en el resto de casos, falla…
;; MALFAR: ¿me colorea las plantillas? ; No, chapucero pues se queja de XHTML no válido en las ¬base (y es que no son XHTML completo). Se queja de ¬cabeceras en fragmentos.html → me perjudica
;; MALFAR: elegir texto y C-t para marcar para traducir → ¡lo único que hace es escribirme _("texto")! Inútil
;; MALFAR: C-c t para pruebas ← peta; inútil

;; ∴ Patético.

;;;;;;; MALFAR [#A] pony-mode: mejor
;; pony-mode provides various Django integration features for working on django projects - management commands, runserver, shell and dbshell within emacs, template syntax highlighting, and more. Github page:  https://github.com/davidmiller/pony-mode
;; Lo he probado y no me convence; es únicamente para cosas muy avanzadas y raras que yo no necesito ahora, como integración con fabric ([C-c C-p f]), trocitos de códigos, … Lo bueno que da (ẽ ishell) prefiero tenerlo suelto. Además las cosas interesantes (ẽ „Jump to template at point or from editing view [C-c C-p g t]“) petan de formas raras
;; ∴ Más adelante quizás le veo la gracia; ahora no.
;; Puedo quedarme sólo con Pony-tpl-minor-mode … si funciona.

(let ((d "/w/pony-mode/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'pony-mode)
    ))

;;(unload-feature 'pony-mode t)



;;;;;;; web-mode, otro que promete. Muy genérico pero entiende Django
;; http://web-mode.org/; 
;; https://github.com/fxbois/web-mode
;; Probarlo en /w/web-mode
(let ((d "/w/web-mode/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path "/w/web-mode/")
    (require 'web-mode)
    (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.jsp\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.blade\\.php\\'" . web-mode))

    ;; y en general (pues es mejor que el sgml-mode estándar):
    (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))

    ))
;; forzar algunos motores, no sé si va
(setq web-mode-engines-alist '(
                               ("smarty" . "\\.smar\\'")
                               ("blade" . "\\.blade\\.")
                               ("go" . "\\.goml\\'")
                               ("django" . "\\.html\\'")
                               ))


;; ¡Es muy bueno! C-c C-f para plegar bloques HTML
;; BONUS: mirar atajos, de: http://web-mode.org/ y aprenderlo más. Y ajustarle más opciones

(setq web-mode-enable-current-element-highlight t) ; parece útil. Probándolo; ¿no va?

;; (setq web-mode-enable-auto-pairing t) ; la verdad, no sé lo que hace. Lo he probado y no cambia nada


;; Con esto me hago un equivalente al yasnippet
(setq web-mode-extra-snippets
      '(
        ;; parece que „nil“==„todos los modos
        (nil . (("script"     . "<script type=\"text/javascript\" src=\"\"></script>")
                ("link"     . "<link rel=\"stylesheet\" type=\"text/css\" href=\"\" />")
                ("input-submit"     . "<input type=\"submit\" value=\"Submit\" />")
                ))
        ;; Éstos son sólo para modos concretos
        ("django" . (("algo1"    . "ALGOUNO")
                     ("algo2"      . "ALGODOS")))
        )
      )




;;;;;;; typescript-mode
;; puesto por ~elpa
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-mode))

;;;;;;; y funciones propias que me hago para tratar con HTML

;; De http://sachachua.com/notebook/emacs/small-functions.el:
(defun strip-html-in-buffer ()
  "Remove HTML tags from the current buffer,
   (this will affect the whole buffer regardless of the restrictions in effect)."
  (interactive "*")
  (save-excursion
    (save-restriction
      (widen)
      (goto-char (point-min))
      (while (re-search-forward "<[^<]*>" (point-max) t)
        (replace-match "\\1"))
      (goto-char (point-min))
      (replace-string "&copy;" "(c)")
      (goto-char (point-min))
      (replace-string "&amp;" "&")
      (goto-char (point-min))
      (replace-string "&lt;" "<")
      (goto-char (point-min))
      (replace-string "&gt;" ">")
      (goto-char (point-min)))))
;; Probar: (with-temp-buffer (insert "<b>hola</b>") (strip-html-in-buffer) (buffer-string))

(defun strip-html-in-string (cadena)
  (with-temp-buffer (insert cadena) (strip-html-in-buffer) (buffer-string))
  )
;; (strip-html-in-string "<b>ho")

;; Probando:
(defun copia-contenido-pero-sin-etiquetas-html (beg end &optional region)
  """
Ej. de esto:
            <li class="item ar"><a href="…warranty" class="brand-link">ز. مسؤولية</a></li>
Copiará esto:
ز. مسؤولية

Aún falla un poco.
Una versión mejor (a intentar) es con filter-buffer-substring
"""


  (interactive (list (mark) (point)
                     (prefix-numeric-value current-prefix-arg)))
  ;;  (copy-region-as-kill beg end region)
  (let* (
         (str (if region
                  (funcall region-extract-function nil)
                (filter-buffer-substring beg end)))
         (modi (string-trim (strip-html-in-string str)))
         )
    ;;  (kill-append (concat "algo más" str) nil)
    ;; pruebo: (kill-append "hola2" t)
    ;; pruebo: (kill-new "hol4" t)
    ;; Ha de ir:
    ;; (kill-new modi)
    (kill-new modi t)
    ;;  (kill-new (concat "algo máse" modi))
    (message "Creo que he copiado (al menos. Aún no va bien del todo de nuevo y hay que apretar C-y M-y…): «%s»" modi)
    )
  
  ;; probrando
  ;; (if (called-interactively-p 'interactive)
  ;;     (indicate-copied-region))

  ;;(kill-new "prueba")
  )


;;;;; Modos para Haskell
(let ((d "/usr/share/emacs25/site-lisp/haskell-mode/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'haskell-mode)

    ;; BONUS: pruebo a añadir a auto-mode-alist. Ver también http://code.haskell.org/haskellmode-emacs/haskell-mode.el
    ;; Se hace con (borrar si no hacen falta):
    (add-to-list 'auto-mode-alist        '("\\.\\(?:[gh]s\\|hi\\)\\'" . haskell-mode))
    (add-to-list 'auto-mode-alist        '("\\.l[gh]s\\'" . literate-haskell-mode))
    (add-to-list 'interpreter-mode-alist '("runghc" . haskell-mode))
    (add-to-list 'interpreter-mode-alist '("runhaskell" . haskell-mode))
    ))


;;;;; Modos para Prolog
;; (let ((d "/usr/share/emacs25/site-lisp/prolog-el/"))
;;   (when (file-exists-p d) 
;;  (add-to-list 'load-path d)
;;  (require 'prolog)
;;  ))
;; En m1.2023 lo veo ya, en Emacs 30

;;;;; Modos para CLIPS
;; instalado clips-mode por ELPA
(setq inferior-clips-program "clips")

;;;;; Modos para Minizinc
;; Instalado abajo. Espero que esto no falle la 1ª vez.
(require 'minizinc-mode)
(add-to-list 'auto-mode-alist '("\\.mzn\\'" . minizinc-mode))
;; No añade ninguna tecla…

;;;;; Modos para Erlang
(let ((d "/usr/share/emacs/site-lisp/erlang/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (autoload 'erlang-mode "erlang" "Erlang mode" t)
    (add-to-list 'auto-mode-alist        '("\\.erl\\'" . erlang-mode))
    ;;(require 'erlang)
    ))
;; o si lo instalo por ELPA:
;; (require 'erlang-start)
;; No sé cómo decir „si está instalado por ELPA, cárgalo“. Quizás no hace falta pues ELPA ya lo carga solo

;; El de apt-get me causa: File mode specification error: (error Given parent class xref-file-location is not a class)
;; Esto no lo arregla:
;; (require 'xref)
;; El error es por: eieio-defclass-internal(erlang-xref-location (xref-file-location) ((arity :type fixnum :initarg :arity :reader erlang-xref-location-arity)) (:documentation "An erlang location is a file location plus arity."))
;; Es por:
;; commit 86da812afb2572c7fead2bb07570b976bffd7c55
;; Date:   Fri Oct 1 00:02:21 2021 +0300
;;     Migrate Xref off EIEIO
;;     To improve performance and flexibility (bug#50777).
;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50777
;; Es por erlang-mode 2.8.4, de 2011
;; ∴ usar el de melpa, es más nuevo


;;;;; Modos para Perl
;; de momento Flymake ya me ayuda algo; detecta bien la ¬compilabilidad en varias casos (no en todos)
(add-hook 'perl-mode-hook 'flymake-mode-on)

;;;;; Modos para Ocaml
;;;;;; Está ocaml-mode
;;;;;; Está tuareg-mode, dicen que mejor que el que viene con ocaml
;; Ai tuareg-mode
;; el .el está en /usr/share/emacs/site-lisp/tuareg-mode/tuareg.el
(let ((d "/usr/share/emacs25/site-lisp/tuareg-mode/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'tuareg)
    (add-to-list 'auto-mode-alist        '("\\.ml\\'" . tuareg-mode))

    ))

;;;;; Modos para PHP
;; Para intentar aliviar el sufrimiento
;; Ver lo de nxhtml antes; eso ya carga un modo PHP
;;;;;; flymake para PHP

(ignore '( ; ignoro porque parece que no me va cuando hay usuarios distintos. Ej. si uso su:peri en tramp, el temporal estaría bajo otro usuario

          (defun flymake-create-temp-in-system-tempdir (filename prefix)
            (let ((temporary-file-directory "/home/dc/n/"))

              (make-temp-file (or prefix "flymake"))
              )
            )

          (defun flymake-php-init ()
            (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                                 ;;                       'flymake-create-temp-inplace
                                 'flymake-create-temp-in-system-tempdir
                                 ))
                   (local-file  (file-relative-name
                                 temp-file
                                 (file-name-directory buffer-file-name))))
              (list "php" (list "-f" local-file "-l"))))
          ))

;; que se active solo. m2.2015 esto le hace falta al flymake de illusori (que por cierto, va bien)
(add-hook 'php-mode-hook 'flymake-mode-on)


;;;;;; geben (depurador/trazador para lenguajes que hablan XDEBUG)
;; Funciona bien. Ver emacs.org
(let ((d "/w/geben-0.26/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (autoload 'geben "geben" "PHP Debugger on Emacs" t)
    ;;(require 'geben-mode)
    ))

;;;;; Modos para Oz (con implementación: Mozart)
(let ((d "/usr/share/emacs25/site-lisp/mozart/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'oz)
    ;;(autoload  'oz-mode "oz-mode" "Oz Mode" t) ; no pues necesito run-oz
    ))
;; Usar: M-x run-oz

;;;;; flymake oficial, para búsqueda de errores al programar. Cosas genéricas para todos los lenguajes
;; lo estoy usando en Java, Perl, Python, … Ver arriba y en cada sección correspondiente.
;; Funciona muy bien.


;; Luego añadir soporte para cada lenguaje, hay información de cada uno en http://www.emacswiki.org/emacs/?action=browse;diff=1;id=FlyMake

(defun flymake-display-warning (warning)
  "Display a warning to user. ← cuando da error gordo y peta flymake"
  (message warning) ; le añado yo esto para saber cuál es el error, porque con message-box no me entero (se ve cortado)
  (message-box warning))

;; Logging level, only messages with level lower or equal will be logged.
;; -1 = NONE, 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
;; esto lo hace lento…
;;(setq flymake-log-level 0) ; no me dice bien por qué falla cuando falla. Pero no molesta ; m2.2015: desactivo porque uso el de illusori
;; ¿y no hay un 0'5?
;; (setq flymake-log-level 1) ; me muestra mensajitos como „deleted dir“ que no quiero
;; (setq flymake-log-level 3) ; todo. Bien para depurar, pero normalmente me muestra una ráfaga de mensajes de distintas alturas en el minibúfer, y confunde
;; Ahora es warning-minimum-log-level
;;(setq warning-minimum-log-level ":debug")
;; Original:
;;(setq warning-minimum-log-level ":warning")
;; Y luego hay que pasar a *flymake log* (hay función para verlo)


;; (setq flymake-gui-warnings-enabled nil) ; estaba a t y el cuadro que salía me molestaba mucho.   En 26.1 está obsoleta


;; Activo esto porque me gusta así. El motivo original (ya no válido >12.m4.2010) era: A veces se cree que estoy compilando y por eso Flymake no se activa (bueno, se activa pero no informa de nada. Para evitarlo le pido que nunca deje de activarse
(setq flymake-compilation-prevents-syntax-check nil);era t


;; tiempo a esperar para analizar sintaxis
;; era: 0'5, y creo que me iba bien. Aunque de vez en cuando muy lento
;; (setq flymake-no-changes-timeout 2) ; lo usé mucho así
;; lo retardo a 4 porque con flymake(python) es lento y me bloquea mucho la igu
(setq flymake-no-changes-timeout 15)
;; ATENDAS: probar; no sé si es esto lo que me ralentiza


;; que se pueda ver el error mediante el teclado, sólo posicionándose encima
(ignore '( ; pruebo a ignorarlo temporalmente pues están cambiando el flymake oficial y flymake-cursor es de 2017
          (add-to-list 'load-path "~/.emacs.d/flymake-cursor/")
          (require 'flymake-cursor)
          ))
;; Entra en conflicto con las ayudas que me muestra CEDET → le puse 1'1 segundos en vez de 0'9
;;(unload-feature 'flymake-cursor t)


;; para cuando se acumulan temporizadores de búfers muertos, y cosas por el estilo
;; m2.2015, creo que no me hace falta ahora que uso el de illusori, porque dice que usa sólo 1 proceso. Pero no parece ser así, aún veo varios. m1.2018 creo que no hace falta más
(defun cancela-todos-los-contadores-de-flymake ()
  (interactive)
  (mapcar
   (lambda (ti) (cancel-timer ti))

   (filter (lambda (ti) 
             (eq 'flymake-on-timer-event (nth 5 (append ti nil)))
             ) timer-list)
   )
  )


;;;;; flymake nuevo, de illusori, con muchas cosas corregidas, mucho mejor, y tiene CSS y JS, funciona bien con Tramp, es rápido, …
;; De https://github.com/illusori/emacs-flymake → 2018 redirige a https://github.com/flymake/emacs-flymake, que lleva 5 años sin actualizar. Por eso desactivo por ahora
(ignore '(
          (let ((d "/w/emacs-flymake/"))
            (when (file-exists-p d)

              ;; descargar el oficial. No me gusta tener que hacer esto; ver https://github.com/illusori/emacs-flymake/issues/26
              ;; Si he usado (require…) en .emacs 1 vez ya no podré descargarlo…  → usar (unload-feature 'flymake 'forzarlo-por-favor)
              (if (featurep 'flymake)    (unload-feature 'flymake)  )
              ;;(unload-feature 'flymake t)
              ;;(void-function flymake-ler-p)
              (makunbound 'flymake-allowed-file-name-masks) ; por si acaso
              ;; por lo visto esto hace falta en Emacs nuevo
              (cl-defstruct (flymake-ler
                             (:constructor nil)
                             (:constructor flymake-ler-make-ler (file line type text &optional full-file)))
                file line type text full-file)

              
              (add-to-list 'load-path d)
              (require 'flymake)
              (load-file "/w/emacs-flymake/flymake.el")
              ;; «…provide 'flymake-de-illusori…» ; guarradilla para causar que los (when (load …)) se activen ← guarradilla, no va

              ;; tengo que hacer ahora los añadidos… no vale haberlos hecho antes
              (add-to-list 'flymake-allowed-file-name-masks 
                           '("\\.py\\'" flymake-pyflakes-init-para-el-de-illusori)) 

              ;;(autoload  'oz-mode "oz-mode" "Oz Mode" t) ; no pues necesito run-oz
              ))

          ;; Estas dos variables parece que sólo están en el de illusori
          (setq flymake-run-in-place nil) ; no poner fichero temporal al  lado del original sino en carpeta temporal
          (setq flymake-number-of-errors-to-display 4) ; era 1


          ))


;;;;; Modos para JavaScript. javascript-mode y js-mode, js2, …
;; No tengo clara la diferencia entre ellos.

;; Por lo visto se abre „javascript-generic“ (malo y no indenta) debido a generic-x. En cambio javascript-mode o js-mode son mejores. ∴ Lo he desactivado para que generic-x no lo cargue

;; Si Emacs peta alguna vez porque javascript-mode no está definido, probar: (defalias 'javascript-mode 'js-mode) ; pero esto ya no hace falta.
;; O al revés: (defalias 'js-mode 'javascript-mode) ← cuando alguien busque js-mode, que use javascript-mode

;; Chapuceramente puedo hacer esto aquí para decidir cuál uso:   (remove-alist 'auto-mode-alist "\\.js\\'") (add-to-list 'auto-mode-alist '("\\.js\\'" . javascript-mode))

;;;;;; usar jslint para decirme errores y mal estilo de JavaScript

;; esto cambia variables pero no activa nada
;; m12.2020: lo desactivo pues llevo 9 años sin usarlo. Si lo reactivo, quizás poner jslint (¿o jshint?) nuevo
;; (add-hook 'js-mode-hook ; no me va si pongo javascript-mode-hook
;;        (lambda ()
;;     ;;; make emacs recognize the error format produced by jslint
;;          (set (make-local-variable 'compilation-error-regexp-alist)
;;               '(("^\\([a-zA-Z.0-9_/-]+\\):\\([0-9]+\\):\\([0-9]+\\)" 1 2 3)))
;;          (if buffer-file-name ; pues en trocitos de org-mode no ha de saltar
;;              (set (make-local-variable 'compile-command)
;;                   (let ((file (file-name-nondirectory buffer-file-name)))
;;                     (concat "~/ut/jslint " file))))
;;          ))

;;(setq js-mode-hook nil)
;; ¡¡¡Esto funciona!!! „M-x compile INTRO INTRO“  y ya veo todo el informe

;; en vez de jslint, usar flymake con jshint. Es mejor que jslint pues jslint es manual, pero flymake automático
;; npm -g install jshint  ← esto va
(add-hook 'js-mode-hook 'flymake-mode-on) ; activarlo solo. Quizás me arrepiento en ficheros enormes…

;;;;; Modos para C (no C++)
;;flymake en C; parece que va bien
(ignore '( ; para reactivar con el flymake de illusori
          (defun activa-flymake-mode-excepto-si-no-hay-fichero ()
            (if buffer-file-name
                (flymake-mode-on)
              (message "Sin fichero válido no activaré modo flymake")
              )
            )

          ;; Bien: (add-hook 'c-mode-hook 'flymake-mode-on)
          ;; Pero mejor esto para que org-mode no pete al exportar trocitos babel de C:
          (add-hook 'c-mode-hook 'activa-flymake-mode-excepto-si-no-hay-fichero)


          ;; copiado de http://www.emacswiki.org/emacs/flymake-extension.el
          ;; Así no se queja de que falta Makefile etc.
          ;; Quizás es malo que falte…
          ;; ¿borrar? O usar directamente esa extensión enteramente
          (defun flymake-c-init ()
            
            (flymake-simple-make-init-impl 

             ;; Dos métodos: (los documento aquí sólo en vez de en todos los flymake-*-init):
             ;;
             ;; ****** Método 1 *******:
             'flymake-create-temp-inplace ; esto falla cuando no hay permisos. Lo que hace flymake-create-temp-inplace es crear un NOMBREDEFICHERO_flymake (ẽ .emacs_flymake para el ~/.emacs) y analizar ése
             ;; Ejemplo en que no hay permisos:
             ;;   File mode specification error: (file-error "Opening output file" "permission denied" "/usr/share/pyshared/dateutil/relativedelta_flymake.py")
             ;; Eso es porque está creando ficheros temporales llamando a flymake-create-temp-inplace cuando podría llamar a flymake-create-temp-intemp (disponible en http://blog.urth.org/2011/06/flymake-versus-the-catalyst-restarter.html) o a flymake-create-temp-with-folder-structure

             ;; ****** Método 2 *******:
             ;;   'flymake-create-temp-with-folder-structure   ; no falla cuando no hay permisos, pero al copiar fichero a otro lado, empiezan a faltar cosas: ej. copia image.c a /…tmp/ y allí no encuentra el image.h

             ;; ¡¡¡Ninguno de los dos métodos es bueno!!!: o quiere crear fichero en su sitio (y no puede si no hay permisos) o en otro (y se desconecta). ¿No hay nada mejor?
             ;; Lo ideal es NO crear fichero temporal. Pero lo hace para asegurarse de que están los últimos cambios. Se me ocurre que podría permitir flymake sólo cuando el fichero está grabado; así no hace falta temporal. Y de hecho yo no necesito saber errores al momento

             t t (file-name-nondirectory buffer-file-name) 'flymake-get-c-cmdline)
            )
          (defun flymake-get-c-cmdline (source base-dir)
            ;;  (list "gcc" (list "-Wall" (concat base-dir source)))
            ;; es muy malo tener que *compilar* de verdad, pues no acertará con bibliotecas, etc. Por eso le digo que pare antes (-S) pero que no me genere un .s (-o…); así consigo que me detecte errores de sintaxis sin tener que acertar con todo eso de -lImlib2 -lX11 etc. Funciona bien.
            (list "gcc" (list "-Wall" "-o" "/dev/null" "-S" (concat base-dir source)))

            )
          (defun flymake-cabeceraCóC++-init ()
            "cutrecillo pero diferencia File.h de file.h"
            ;; BONUS: ¿y si en vez de esto me olvidara de hablar de los .h?
            (if (let ((case-fold-search nil)) 
                  (or
                   (string-match-p "^[A-Z]" (file-name-nondirectory buffer-file-name))
                   (string-match-p "^/usr/include/qt4/" (file-name-directory buffer-file-name)) ; todo son c++
                   )
                  )
                (flymake-cc-init)
              (flymake-c-init)
              )
            )

          (push '(".+\\.c$" flymake-c-init) flymake-allowed-file-name-masks)
          ;; probando; tenía activada esta línea, pero me parece que los .h no deberían entrar a flymake. Si lo hace, los pasa por gcc, me genera .h.gch y se queja de que no los puede compilar. Pruebo a desactivarlo
          ;;(push '(".+\\.h$" flymake-cabeceraCóC++-init) flymake-allowed-file-name-masks)
          ;; ¿y los .h? Ahora me están fallando
          (push '(".+\\.xs$" flymake-c-init) flymake-allowed-file-name-masks) ; no va muy bien … .xs es el .c de Perl
          ;; BONUS: pero: „Flymake: Configuration error has occurred while running (gcc -Wall ./BlueZ_flymake.xs). Flymake will be switched OFF“
          ;; y más: „switched OFF Flymake mode for buffer BreakWindow.cc due to fatal status CFGERR, warning Configuration error has occurred while running (make -s -C ./ CHK_SOURCES=BreakWindow_flymake.cc SYNTAX_CHECK_MODE=1 check-syntax)“

          ;; Corregir el error éste: Se quejaba de un búfer "*C parse algo*", que obviamente no tenía fichero asociado
          ;;Debugger entered--Lisp error: (error "Invalid file-name")
          ;;  signal(error ("Invalid file-name"))
          ;;  error("Invalid file-name")
          ;;  flymake-get-file-name-mode-and-masks(nil)
          ;;  flymake-get-init-function(nil)
          ;;  flymake-can-syntax-check-file(nil)
          ;;  flymake-mode(1)
          ;;  flymake-mode-on()

;;;;; Modos para C++ (no C)
          ;; Parecido a lo de C arriba

          (defun flymake-cc-init () ; o flymake-c++-init
            (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                                 ;; sobre elección entre with-folder-structure o inplace: ver el comentario en flymake-c-init
                                 ;;                       'flymake-create-temp-with-folder-structure
                                 'flymake-create-temp-inplace
                                 ))
                   (local-file  (file-relative-name
                                 temp-file
                                 (file-name-directory buffer-file-name))))
              (list "g++" (list "-Wall" "-Wextra" "-fsyntax-only" local-file))))

          (push '("\\.cc$" flymake-cc-init) flymake-allowed-file-name-masks)
          (push '("\\.cpp$" flymake-cc-init) flymake-allowed-file-name-masks)
          ;; los .h están dichos arriba
          (add-hook 'c++-mode-hook #'(lambda () (flymake-mode t)))

          ;; BONUS me da error en BreakWindow.cc de workrave, en un
          ;; #include <gdk/gdkkeysyms.h>
          ;; pero: libgtk2.0-dev: /usr/include/gtk-2.0/gdk/gdkkeysyms.h
          ;; el comando era:
          ;; g++ -Wall -Wextra -fsyntax-only ../../../../../…tmp/w/workrave-1.9.4/frontend/gtkmm/src/BreakWindow.cc
          ;; y lo puedo reproducir:
          ;; cd /w/workrave-1.9.4/frontend/gtkmm/src ; g++ -Wall -Wextra -fsyntax-only BreakWindow.cc


          ))
;;;; vc- (control de versiones, cdv)
;; MALFAR: conseguir que en CVS no me pida la contraseña todo el rato. ← mejor *evitar* CVS
;; Preguntado en http://www.emacswiki.org/emacs/SshWithEmacs ← esperar respuesta
;; ssh-agent seems not to work in my case (CVS repository, Emacs 23, Ubuntu GNU/Linux). I ran: ssh-agent before starting Emacs, and Emacs can read SSH_AUTH_SOCK and SSH_AGENT_PID (confirmed through env in eshell). However, emacs -Q asks me the password two times for two consecutive C-x v d. A ps shows the call hierarchy emacs→cvs→cvs→ssh→ssh-askpass. That last process has the expected environment variables (confirmed through cat /proc/15228/environ). So I don’t know what is failing here or what else to test. 

;; Tras un „C-x v v“ ∪ „escribir un comentario“, no tiene que cerrarme la ventana, pues tampoco la abrió vc -- ya estaba abierta.
(setq vc-delete-logbuf-window nil)
;; aún iría mejor una opción „matar el búfer pero no la ventana“, pues no quiero mantener una ventana vieja pero funcional. Lo tengo en hacer/emacs.org


;; ver emacs.org para las mejoras que intento
;; Esto lo hice en 2010/2011 y me iba bien. Pero en 2022 lo comento porque parece (y espero) que la versión nueva ya hace lo que toca.
(ignore '(
          (defun vc-git-state (file)
            "`vc-state' para git, reescrita para aprovechar git 1.7.0 y ser más rápida."
            (if (not (vc-git-registered file))
                'unregistered
              (vc-git--call nil "add" "--refresh" "--" (file-relative-name file))
              (let ((diff (vc-git--run-command-string
                           file "status" "-z" "--porcelain" "--")))
                (if (and diff (string-match " \\([ADMUT]\\) [^\0]+\0"
                                            diff))
                    (vc-git--state-code (match-string 1 diff))
                  (if (vc-git--empty-db-p) 'added 'up-to-date)))))
          ))

;;probar:
;; cerrar: con ibuffer, %m org RET D y
;; (org-agenda-list)

;; otra versión más bestia
;; (defun vc-git-state (file) "up-to-date")

;;;; icicles
;;empecé a probarlo el 18.7.2008
;; el 5.m4.2010, después de usarlo ligeramente durante mucho tiempo, decido desactivarlo y sustituirlo por anything, que acabo de descubrir
;; Icicles me ayudó mucho a descubrir teclas posibles en cada situación (cosa que aún no sé hacer con Anything), y tamién al filtrar comandos y ficheros disponibles (en esto sí que me ayudará mucho Anything). Pero Icicles ha sido un gran monstruo que hace que todo vaya más lento (sobre todo el minibúfer) y que aporta muchísimas más cosas de las que necesito. Así que lo despido pero con cariño.
;; Lo borré de ~/.emacs.d/icicles y borré mi código de .emacs. Ver en cdv (de 18.m9.2016) el borrado

;;;; fuentes que sirven tanto como para anything como para helm

;; He quitado alguna más privada. Ver cdv

;; No encuentro cómo hacer esto de ofrecer todos los ficheros de un directorio
(setq anythingyhelm-fuente-páginas-de-wiki
      '(
        ;; „páginas de wiki“
        (name . "страницы ~уйки")
        
        (candidates . (lambda nil (directory-files "~/wiki/" t ".*\.org")))

        ;; real-to-display etc.: ver pruebas en cdv
        ;; El candidate-transformer recibe lista de todos, y devuelve la lista a mostrar de todos. El filtered-candidate-transformer imagino que es para los resultantes de un tecleo → sí

        (action . find-file) ; no sé si es necesario
        ;;(action . 'helm-find-files-actions) ; probando
        (type . file))
      )

(setq anythingyhelm-fuente-todas-tareas-org

      '((name . "Todas las tareas para hacer, precargada")
        (init . (lambda nil
                  (unless (boundp 'lista-tareas-org-precargada-para-anything)
                    (setq lista-tareas-org-precargada-para-anything (anything-org-agenda-all-todo-list))
                    )
                  )
              )
        (candidates . lista-tareas-org-precargada-para-anything)
        ;; (candidates . (lambda nil agenda-org-precargada-para-anything))
        (action
         ("Ir a búfer" . (lambda
                           (x)
                           (anything-org-agenda-switch-to x)))
         ("Cronometrar" . (lambda
                            (x)
                            (anything-org-clock-in x)))
         (delayed)
         ))

      )

(defun precarga-etiquetas-radio-de-wiki-para-helm nil
  (interactive)
  (setq lista-radios-org-precargada-para-anything 
        ;; „repoweb“ no es estrictamente necesario… pero no lo hace más lento tampoco. Como a veces no está, activo „nullglob“ para que zsh no se queje („no matches found“)
        ;; lenguaje.org tampoco es necesario pero lo incluyo hasta que decida qué hacer econ eso. No ampliarlo mucho tampoco…
        ;; inda.org tiene muchos
        ;;
        ;; Atención: problema con shell-command-to-string: si desde búfer tramp con otro usuario ejecuto (shell-command-to-string "echo ~"), ¡me da /home/labx! ¡Se cree que soy otro usuario! → Ver sección en /editar como otro usuario/, ver investigación. La solución es „colocarme“ en /home/dc antes del comando, para que el búfer actual no importe
        (let ((default-directory "/home/dc"))
          (split-string (shell-command-to-string "setopt nullglob; grep -aP '<<<(.*?)>>>' ~/{wiki,org,repoweb/hacer,proj/lenguaje,proj/ejd}/[[:alpha:]]*.org -on | grep -v 'org/celoj.org:'") "\n" t)
          )
        )
  ;; (message "He encontrado %i radios" (length lista-radios-org-precargada-para-anything))
  )
;; Lo pruebo:
;; (precarga-etiquetas-radio-de-wiki-para-helm)
;; Es muy rápida (normalmente menos de 1 segundo. 2 como mucho. Eso es menos que muchas retardos indignantes que Emacs tiene al teclear; algunos añadidos por la caché de org-element…)
;; Sin embargo, usa mucha memoria. El perfilador dice haber procesado 12'6 Gb en una sola llamada. No sé si es cierto o fiable.
;; Podría intentar evitar el split-string y shell-command-to-string, y hacer algo que lea lista más eficientemente. Pero aún no me sale a cuenta optimizar esto.

;; para verla en fichero (no verla en búfer de emacs pues es línea enorme que lo cuelga):
;; (with-temp-file "~/n/pruebo-a-listar-radios" (insert (prin1-to-string lista-radios-org-precargada-para-anything)) (save-buffer))
;; 

;; pruebo a actualizar solo continuamente
(defvar actualizador-de-radios-de-wiki nil)
(when (timerp actualizador-de-radios-de-wiki) (cancel-timer actualizador-de-radios-de-wiki))
(setq actualizador-de-radios-de-wiki
      (run-at-time-exceptosiyaexiste 
       "00:10" 
       (* 15 60)  ;; 15 minutos
       (lambda () (call-interactively #'precarga-etiquetas-radio-de-wiki-para-helm) "Actualizados radios")))


(setq anythingyhelm-fuente-etiquetas-radio-org
      '((name . "Trafvortoj <<<tiaj>>> ĉie uzitaj")
        (init . (lambda nil
                  (unless (boundp 'lista-radios-org-precargada-para-anything)
                    (precarga-etiquetas-radio-de-wiki-para-helm)
                    )
                  )
              )

        (candidates . lista-radios-org-precargada-para-anything)
        (action
         ("Ir a búfer" . (lambda (x)
                           (anythingyhelm-action-buffer-line--con-líneas x)
                           ))
         )

        ;;      (no-matchplugin) ; esto lo acelera muchísimo; de 2 segundos por pulsación pasa a milisegundos.  m11.2017 ya no hace nada, así que lo quito
        (nohighlight) ; no molesta, quizás acelera

        (candidate-number-limit . 50) ; nunca necesito ver más

        (delayed) ; así no revelo montones de información ajena a XYZXYZ mientras tecleo XYZXYZ
        (requires-pattern . 4) ; empieza vacío; no mostrándome todo lo de „alimentación“ (ya que empieza por „a“). En caso de emergencia puedo teclear <<< para llenar y forzar resultados pronto
        )
      )

(setq anythingyhelm-fuente-tareas-TIPA
      ;; MALFAR: coger todos los TIPA, en vez de ir copiando los ID uno a uno ← no pasa nada por ponerlo a mano, pues son muy estáticos
      '((name . "Todas las TIPA-tareas cronometrables")
        (init . (lambda nil
                  (setq lista-tareas-org-TIPA '(
                                                "en casa, lejos del ordenador y encima lo dejo sin hacer nada (ID 4dd7bb47-a3c7-4005-9496-aa776b7050a6)"
                                                "ordenar la mesa, quitar papeles (pasarlos a org), quitar cables, polvo, aparatos, … (ID e10826a4-4a52-4e29-a461-01bb1e383646)"
                                                "procrastinar (ID bb40159b-d93e-42fb-859b-4f34a309e563)"
                                                "kelkajn mesaĝegojn aŭ mesaĝetojn poŝtajn respondu ĉiuj 3 tagoj (ID responder_correo)"
                                                ;; "aprendiendo música por mi cuenta, ej. teoría o varios instrumentos (ID abe91443-5ba6-4c18-af53-f946da16d614)"
                                                "curso de guitarra clásica, de Frederick Noad (ID curso_de_noad)"
                                                "configuraciones genéricas de entorno (ID c4cc9328-3721-41b3-9f01-b093d48b7866)"
                                                "descanso regular de la vista (ID descanso_de_la_vista)"
                                                "preparar mi agenda para *hoy*, cada día por la mañana (ID ys96jpr0eze0)"
                                                ))
                  ))
        (candidates . lista-tareas-org-TIPA)
        (action
         ("Cronometrar" . (lambda (x)
                            (string-match "(ID \\\(.*\\\))$" x)
                            (setq id (match-string 1 x))
                            (save-window-excursion
                              (org-id-goto id)
                              (org-clock-in)
                              )
                            ;;(message x)
                            )))
        ("Ir a tarea" . (lambda (x) (message "sin hacer")))
        (delayed)
        )
      )

(setq helm-fuente-locate-de-ficheros-privados
      '((name . "locatemi (* hejmaj), pro ¬locate.")
        (candidates-process
         . (lambda nil 
             ;; atención: dos veces %s, eso no estaba en anything
             (let (
                   ;;(helm-locate-command "strace -e '' locate %s -d ~/.bd-locate '%s'")
                   ;; fuera guarrada del strace ahora que descubrí lo del setgid:
                   (helm-locate-command "/opt/dc/bin/mlocate %s -d ~/.bd-locate '%s'")
                   ) (helm-locate-init) )
             ))
        ;; (action . find-file) ; ← no sólo no es necesario, sino que lo fastidia todo
        (type . file)
        (delayed . 1) ; probando qué tal va. Ver en otro lado para ajustes
        (requires-pattern . 3) ; Es longitud mínima

        )
      )
;; ¿no hay forma mejor? Veo que existe helm-locate-with-db:
;; (helm-locate-with-db "~/.bd-locate")

;; No funcionará mlocate normal por un tema guarro de setgid → ver en lo de „sólo funciona trazado“. Con esto (+instala.sh) lo soluciono
;; (setq helm-locate-command "/opt/dc/bin/mlocate %s -r %s") ; ← desactivo, pues a ser posible lo cambiaré en cada fuente, no el global
;; original: (setq helm-locate-command "locate %s -r %s")
;; Por lo visto el muy cerdo necesita llamarse „mlocate“ o similar, no le vale „mlocate_sin_setgid“. Así que no cambiar nombre del ejecutable.

;; IS: quiero evitarme los „Process locate-process exited abnormally with code 1“. Es cierto que locate (y grep, justo igual) devuelven un $? 1 cuando no hay resultados/concordanzas y 0 cuando sí, pero a eso no lo llamaría „exited abnormally“. He de tratarlo.
;; Lo corregí en https://github.com/emacs-helm/helm/issues/287

(setq helm-fuente-ficheros-importantes
      '((name . "importantes")
        (candidates-process
         . (lambda nil 
             (let ((helm-locate-command "grep %s '%s' ~/.ficheros-importantes.txt")) (helm-locate-init) )
             )
         )
        ;; (action . find-file) ; ← no necesario
        (type . file)
        (delayed . 1) ; ← ¿qué es? Si lo activo, sólo hace que pete al cabo de un rato de haber CERRADO helm. Parece que si no lo activo, no va
        (requires-pattern . 3)
        )
      )





;; esto (de anything-org) necesita una pequeña corrección
(defun anythingyhelm-action-buffer-line--con-líneas (candidate)
  """Como anything-c-action-buffer-line pero interpreta el „offset“ como número de línea en vez de caracteres.
También se ocupa de no llevarme a un sitio escondido.
"""
  (when (string-match "^\\(.+?\\):\\([0-9]+\\):\\(.*\\)$" candidate)
    (let ((buffer (match-string 1 candidate))
          (lineno (string-to-number (match-string 2 candidate)))
          (content (match-string 3 candidate)))
      ;; El switch-to-buffer supone que el búfer estará abierto… cosa que no siempre pasa. Pero si quiero evitarlo me basta con „C-a a“ para abrir todos… así que no me molesta
      (switch-to-buffer (get-file-buffer buffer))
      (show-all) ; mejor sería abrir sólo esa zona… pero no sé cómo se hace. Igualmente, me va bien así
      (goto-line lineno))))




;; una fuente para git: helm-git-grep
(setq helm-git-grep-candidate-number-limit 1000) ;; era 300
;;(require 'helm-git-grep) ;; Not necessary if installed by package.el
(global-set-key (kbd "C-c g") 'helm-git-grep)
;;Invoke `helm-git-grep' from isearch.
(define-key isearch-mode-map (kbd "C-c g") 'helm-git-grep-from-isearch)
;;Invoke `helm-git-grep' from other helm.
(eval-after-load 'helm
  '(define-key helm-map (kbd "C-c g") 'helm-git-grep-from-helm))
;;For more information, See the following URL: https://github.com/yasuyk/helm-git-grep
;; C-c i helm-git-grep-toggle-ignore-case    ← ya está en ayuda arriba
(global-set-key 
 ;; (kbd "C-c S-g") 
 (kbd "C-c G")  ;; va mejor
 ;; "\C-c \(kbd "C-c S-g") 
 'helm-git-grep-at-point)
;; ¡helm-git-grep es fantástico! Justo lo que quería

;; no me va muy bien el helm-git-grep-at-point porque tengo mark-active a t (no sé por qué, aparentemente no lo noto) y por eso cambia a otro sistema. Es en helm-git-grep-get-input-symbol

;; Ya que no va dentro de eval-after-load, la ejecuto ahora aquí, ¡pero tampoco va! Por eso la puse al final también. Y tampoco va.
;; Supongo que me toca encontrar quién la maldefine.
(defun define-helmgitgrepgetinputsymbol-con-mi-versión-arreglada () (interactive)
       (message "Sobreescribiendo función de helm-git-grep")
       ;; (async-shell-command "beep -f 2000")
       (defun helm-git-grep-get-input-symbol ()
         "Get input symbol. ← Simplificada desde original, para corregir fallo"
         (if (use-region-p)
             (helm-git-grep-get-region-substring)
           (thing-at-point 'symbol)
           ))
       )
;;(define-helmgitgrepgetinputsymbol-con-mi-versión-arreglada)
;; pruebo lo del eval-after-load para que esto sobreescriba la oficial. Si no, tengo que ejecutarlo a mano cada vez. Parece que no va
;; Para comprobar si va o no, mirar: (symbol-function 'helm-git-grep-get-input-symbol)
;;
;; m9.2019: nooooooooooooooooo: +tras arreglar problema de instalación de emacsclient, parece que ya me va bien: al arrancar demonio, C-G+
;; m9.2019 ver en emacs.org

;; m10.2020: encontré quizás por qué era: por tener un .elc del helm-git-grep original. Lo borré, y parece que va → no, no va
;; Creo que es porque con lo de la carga retardada, el helm-git-grep sobreescribe mi sobreescritura. Por tanto pondré la mía tras la suya:
;; Pero no lo consigo bien: parece que mi parche corre antes que el paquete (aunque le pido después)
;; Por eso, fuerzo a cargar yo el suyo, y luego pongo el mío. Qué lío
;; (require 'helm-git-grep)   ; ← no poner, está fuera de orden y me estropea emacs y helm con errores como „(invalid-slot-name #<helm-type-file helm-type-file-15842ec82936> must-match)“ → ver emacs.org (web)
(eval-after-load
    "helm-git-grep" 
    ;;  "helm" 
  (define-helmgitgrepgetinputsymbol-con-mi-versión-arreglada)
)

;; Provas:
;;(unload-feature 'helm-git-grep)
;;(require 'helm-git-grep)

;; Aaaaaaah, me parece que esto puede pasar:
;; 1. por algún motivo, helm-git-grep se medio-carga (bueno, se carga del todo)
;; 2. llega el eval-after-load. Y como ya está cargado, ejecuta mi sobreescritura pero ahora mismo (porque helm-git-grep ya está cargado), y ~~~~~ no se apunta que ha de ejecutarlo luego
;; 3. al presionar las teclas de helm-git-grep, se lee el helm-git-grep.el otra vez. Esto quita mi función
;; 4. ~~~~~~ no ocurre mi función porque ya se ejecutó antes en paso 2

;; ∴ m10.2020: cuesta mucho trazar y entender todo lo que pasa, y no sé mucho del eval-after-load ni los .elc . Así que de momento, comento a mano el código del paquete oficial para que no me [re]defina esa función, y así sólo queda la mía


;; Pruebo a ver qué es. Se activa/desactiva con C-c p, y me limita los ficheros a los que le pido aquí
;; Algo extraño que sea esto manual
;; (setq helm-git-grep-pathspecs '("*.py" "*.js"))
;; (setq helm-git-grep-pathspecs '("*.py"))
;; (setq helm-git-grep-pathspecs '("*.js" "*.jsx"))
;; Mmmmmm… quiero que por defecto no filtre… Así que tengo que dejarlo en blanco.


;; Otra cosa que necesito: que helm-git-grep vaya con tramp
;; Ver sección por https://www.danielclemente.com/hacer/emacs.org
;; Y lo mandé a https://github.com/yasuyk/helm-git-grep/issues/48
;; Probando a definirlo aquí. Es muy chapucero todo esto y no sé la forma buena de hacerlo
(defun define-helmgitgrepprocess-con-mi-versión-arreglada () (interactive)
       (message "Sobreescribiendo helm-git-grep-process para que vaya con tramp")

       (defun helm-git-grep-process ()
         "Usa tramp, o no, en función del directorio. Aún es algo incómodo (muestra más mensajes que los que quiero) pero funciona. Cuidado, *LE FALTA CERRAR EL PROCESO* (ahora quedan procesos „su“ abandonados cada vez que se invoca la búsqueda).
  Atención: parece que esto se ejecuta tras cada tecla apretada. Es muy loco abrir un proceso grep Y NO CERRARLO tras cada tecla. A ver cuándo tengo tiempo para arreglar esto.

  Esta función sobreescribe la helm-git-grep-process original"
         ;; (message "Soy el helm-git-grep-process modificado")
         (helm-aif (helm-attr 'base-directory)
             (let* (
                    (default-directory it)
                    (handler
                     (find-file-name-handler (directory-file-name default-directory)
                                             'make-process))
                    )
               ;; ¿Quizás aquí puedo matar el proceso anterior?
               ;; (stop-process "git-grep-process")
               (message "Proceso: %s" (get-process "git-grep-process"))
               ;; Pero CASI siempre me dice nil. A veces sí que lo encuentra, y entonces me lleva a „Remote file error: Forbidden reentrant call of Tramp“. Así que sí que debería matarlo
               ;; (processp "git-grep-process")
               ;; (processp "server <12>")
               ;; (get-process "server <12>")

               ;; (message handler)
               ;; (debug)
               (make-process
                :name "git-grep-process"
                ;;:buffer nil
                :buffer "*búfpro3*"
                ;; Quizás mejorable
                :command (append '("git") (helm-git-grep-args))
                ;; probando: (así me entero mucho mejor de lo que hace
                ;; :command '("beep" "-f" "2000")
                ;; Y si quiero ver si los mata o no: (veo que SÍ los mata, o sea sólo mantiene un xeyes cada vez)
                ;; :command '("xeyes")
                ;; :file-handler 'tramp-file-name-handler
                :file-handler handler
                ;; Quizás aquí podría pasar algo así, para matarlo al acabar
                ;; :sentinel …
                )) '()))
)
;; v1, intento que cargue. Esto va mal, porque por algún motivo carga *tras cada tecla que aprieto en helm-git-grep* 
(eval-after-load
    "helm-git-grep" 
  #'define-helmgitgrepprocess-con-mi-versión-arreglada
  )
;; Quito v1. Lo INTENTO quitar. Qué asco es esto en Lisp. No es nada elegante y no va:
;; (eval-after-load "helm-git-grep"  nil)
;; (setq after-load-alist (assq-delete-all "\\(\\`\\|/\\)helm-git-grep\\(\\.so\\|\\.elc\\|\\.el\\)?\\(\\.gz\\)?\\'" after-load-alist))
;; (setq after-load-alist (assq-delete-all "helm-git-grep" after-load-alist))

;; v2: probaré a definirlo una vez:
;; (define-helmgitgrepprocess-con-mi-versión-arreglada)


;;;; anything (que ya no lo uso)
;; Me sirve para sustituir a icicles (al abrir fichero y en M-x) y para lanzar aplicaciones y para abrir búfers muy comunes.
;; 5.m4.2010: en efecto, sustituí a Icicles así, y con mucho gusto. Anything no me ralentiza nada Emacs, mientras que Icicles sí
;; ~m9.2012: migrado a helm.
;; Quité anything porque ya uso helm. Ver en cdv (de m8.2013) el borrado

;;;; helm (siguiente versión de „anything“)

;;;;; cargar

(setq dired-bind-jump nil) ; lo pongo aquí para estar antes del require que helm hace

;; intento hacer que helm me vaya en emacs23 ← ver cdv


(if 
    (and
     (file-directory-p "/w/helm/")
     (not (version< emacs-version "24")) ; pues helm requiere 24
     )

    (progn
      (message "Puedo cargar helm de /w/")
      (setq load-path (cons (expand-file-name "/w/helm") load-path))
      (require 'helm-config)
      ;; MALFAR: ir quitando todos los paquetes cuyas fuentes no use
      (require 'helm-eval) ; para helm-source-calculation-result
      (require 'helm-color) ; para helm-source-customize-face, etc.
      (require 'helm-man) ; para helm-source-man-pages, etc.
      (require 'helm-net) ; para helm-google-suggest etc
      ;; (require 'helm-w3m) ; para helm-w3m-bookmarks etc ← no lo uso nunca
      (require 'helm-sys) ; para procesos
      (require 'helm-for-files) ; para recentf etc.
      (require 'helm-elisp) ; para relojes etc
      ;; (require 'helm-apt) 
      (require 'helm-misc)  ; para helm-source-minibuffer-history
      ;; (require 'helm-lib)  ; mmmmmm… no lo supo cargar solo el 14.m10.2020, parece → no, era por prueba mía fallida con helm-git-grep

      (require 'helm-mode)   ; para poder tocar el helm-completing-read-handlers-alist. Creo que no ralentiza y de todas formas iba a hacerlo
      ;; M-x helm-mini

      ;; Antes de activar helm, elijo lo que quiero con helm.
      ;; En m1.2016 dejó de estar activado el M-x por defecto. Pero yo lo quiero:
      ;; probando: assoc 'find-tag helm-completing-read-handlers-alist)
      (assq-delete-all 'execute-extended-command helm-completing-read-handlers-alist)
      (assq-delete-all 'find-file helm-completing-read-handlers-alist)


      ;; Activar helm para muchos sitios
      (helm-mode 1)
      ;;(helm-mode -1)

      ;; Parece que no es suficiente para mejorarme al 100% el C-x C-f, así que redefino esto a mano. Gracias a esto tengo el ffap ya implementado  al hacer C-x C-f   ← m1.2016: lo desactivo y vuelvo a confiar en helm. Si refalla, reactivar
      ;; m9.2017: parece que pone el nuevo en „C-x c C-x C-f“, que encuentro algo largo
      ;; (global-set-key "\C-x\ \C-f" #'helm-find-files)


;;;;; definirle teclas
      ;; ya que no tengo C-w, al menos pongo ésta igual que en el global
      (define-key helm-find-files-map (kbd "C-<backspace>") 'backward-kill-word) ; era: helm-ff-run-toggle-auto-update
      (define-key helm-read-file-map (kbd "C-<backspace>") 'backward-kill-word) ; era: helm-ff-run-toggle-auto-update
      (define-key helm-find-files-map (kbd "M-p") 'previous-history-element) ; era: helm-ff-run-switch-to-history
      (define-key helm-find-files-map (kbd "M-n") 'next-history-element)
;;;;; fin de „quizás cargo helm“
      ))

;;;;; ajustes
;; helm-ff-auto-update-initial-value a t me molesta mucho pues me cambia las rutas mientras escribo
(setq helm-ff-auto-update-initial-value nil)
(setq helm-ff-skip-boring-files nil)
;; (setq helm-ff-skip-boring-files t) ; quizás me quita ficheros como .#Nombre# y cosas raras
;; De momento parece que quita: helm-boring-file-regexp-list, ya va bien
;; Parece que a partir de ahí crea internamente: helm-ff--boring-regexp
;;
;; No quiero activar: helm-ff-skip-git-ignored-files

;; Ah, pero en 2023 helm-boring-file-regexp-list ha cambiado y ahora el find-files es como Windows, listillo: no me muestra ciertos directorios, como si no estuvieran. Todos los que empiezan por punto cuentan como „ocultos“ pero helm decide mostrarme unos sí y otros no. Excluye: .git, .hg, …
;; Esto no me ayuda:
;; (setq helm-walk-ignore-directories '())
;; (setq helm-grep-ignored-directories '())
;; (setq helm-grep-ignored-directories '("SCCS/" "RCS/" "CVS/" "MCVS/" ".svn/" ".git/" ".hg/" ".bzr/" "_MTN/" "_darcs/" "{arch}/" ".gvfs/"))
;; Pruebo: (helm-ff-boring-file-p ".git")
;; ∴ de momento pongo helm-ff-skip-boring-files a nil

;; Temporalmente le pongo esto a nil, porque quizás me está causando una fuga de memoria muy molesta. Ver en emacs.org
;; Llevo usándolo así un tiempo largo (en m10.2020) y no me da problemas (ni de rendimiento)
;; Reactivar en un tiempo para ver si helm ha corregido lo de la caché. Pero no me importa dejarlo a nil por ahora
;; Parece que en m12.2020 desapareció. Lo comento
;; (setq helm-ff-keep-cached-candidates nil)

(setq helm-buffer-max-length 40) ; era 20, muy poco

;; (setq helm-input-idle-delay 0.4) ; era 0.01. Lo retardo para que escribir nunca se me bloquee. 0'5 es un poquito demasiado
(setq helm-input-idle-delay 0.01) ; lo pruebo así de nuevo. ¿En serio se me bloquea? Parece que no mucho. Y la verdad, lo prefiero rápido (0'01) antes que lento (0'4)

;;;;; correcciones a fuentes que ya venían
(setq helm-source-calculation-result--sólo-si-hay-números
      '((name . "Calculation Result")
        (dummy)
        (filtered-candidate-transformer . (lambda (candidates source)
                                            (if (string-match-p "[[:digit:]]" helm-pattern) 
                                                (list
                                                 (condition-case nil
                                                     (calc-eval helm-pattern)
                                                   (error "error"))))))
        (action ("Copy result to kill-ring" . kill-new))))
;;;;; definir abridores (migrados desde anything)

;; por cierto, si me dice „no buffer named helm“ → ver en repoweb/emacs.org


(defun mi-helm-principal ()
  "IS: migrar desde mi-anything-principal"
  (interactive)

  ;; probando (sobre todo, velocidad):
  ;; (helm-other-buffer '(helm-source-buffers-list) "*helm-depruebas1*")
  ;; (helm-other-buffer '(helm-source-files-in-current-dir) "*helm-depruebas1*")
  ;; (helm-other-buffer '(helm-source-recentf) "*helm-depruebas1*")
  ;; (helm-other-buffer '(anythingyhelm-fuente-páginas-de-wiki) "*helm-depruebas1*")
  ;; (helm-other-buffer '(anythingyhelm-fuente-tareas-TIPA) "*helm-depruebas1*")
  ;; (helm-other-buffer '(helm-source-calculation-result--sólo-si-hay-números) "*helm-depruebas1*")
  ;; diría yo que el más lento de ésos es recentf ← sí, 9 segundos (tras deshibernar) mientras que los demás son instantáneos en ese mismo mmomento


  ;; Por lo visto hay que hacer esto a mano si uso helm-source-buffers-list; si no, es nil
  (unless helm-source-buffers-list
    (setq helm-source-buffers-list
          (helm-make-source "Buffers" 'helm-source-buffers)))

  (helm-other-buffer 
   '(
     ;;helm-source-ffap-line ; lo quitaron, ver https://github.com/emacs-helm/helm/issues/191
     ;;helm-(setq  )ource-ffap-guesser ; quitado también
     helm-source-buffers-list ; ¿por qué no aparece? Hay algo raro en helm-buffers-list, algo que lo crea ahí mismo. He acabado haciendo lo mismo (lo hago en la línea de arriba)

     ;; find-files: no, eso en C-x C-f
     ;;helm-source-ff-file-name-history ; mucho mejor que helm-source-file-name-history, que no incluye rutas. MALFAR: tras ver errores raros (no abre ficheros y luego se cierra rápidamente, me dice Thierry: „This is a source that should run from `helm-find-files'. Use `helm-source-file-name-history' instead.“ → https://github.com/emacs-helm/helm/issues/398 ) renuncio a ver rutas ahí. Todo lo que él me (point)ropuso (lo del C-c h, …) ya no incluye rutas
     ;; IS 27.m6.2015: pruebo a desactivarlo para ver si así va más rápido, y para ver si echo algo en falta (pues ya tengo recentf activado) → 26.m3.2018 no lo echo en falta y ya me va bien todo
     ;; helm-source-file-name-history

     anythingyhelm-fuente-páginas-de-wiki ; ← en pruebas

     anythingyhelm-fuente-tareas-TIPA
     ;; MALFAR: reañadir helm-fuente-ficheros-importantes y helm-fuente-locate-de-ficheros-privados pero con mucho cuidado, porque creo que estropean la función entera ← de momento no las necesito.
     ;; helm-fuente-ficheros-importantes
     ;; helm-fuente-locate-de-ficheros-privados

     ;; me gustaría esto pero no va. Ver notas en emacs.org de hacer
     ;; helm-source-multi-occur
     ;; va pero de forma rara, de momento lo tengo limitado a un búfer, no sé por qué → ~~~~∴ (setq 'helm-source-moccur nil)
     ;; helm-source-moccur
     ;; ∴ parece que la nueva forma (alternativa) es C-s dentro de find-files. Va pero no como quiero

     helm-source-files-in-current-dir ;; falla

     ;; gracias a comentarlo, se hace instantáneo. Rara vez quiero ir a ficheros muy lejanos, así que lo dejo comentado
     ;;helm-source-locate

     ;; recentf lo hace un poquito más lento… pero poco
     helm-source-recentf
     ;; helm-source-bookmarks ; ← no lo uso

     ;; helm-source-calculation-result ; de helm-eval
     ;; Ésta la he tenido unos años y no la uso, pero parece que no molesta mucho
     helm-source-calculation-result--sólo-si-hay-números

     ;;helm-source-buffer-not-found ; nunca lo he usado para crear búfers, y más bien molesta


     ;; IS: añadir un cambiador de ventanas de wmii. Ofrecerlas aquí todas (listarlas) y al elegirla mover la vista ahí. Esto es importante porque el sistema anything es mejor que el de „ir buscando entre espacios y pestañas“ de wmii (al menos cuando no hay una organización)
     ;; probar con: for a in `wmiir ls /client |grep -v sel/`; do echo $a; wmiir read /client/$a/tags; echo; wmiir read /client/$a/props | cut -d: -f1,2; wmiir read /client/$a/label; echo; done     # ←  (sacado de „ve_a_ventana“)
     ;; No sé, no parece muy buena idea… Será más lento que tocando teclas de wmii, y además no me será útil si veo „urxvt“ en todos ← no pasa nada, tengo título)
     ;;((name . "wmii")
     ;; (candidates . (…))
     ;; (action . find-file)
     ;;) 
     ;; ∴ no me hace falta, ya he descubierto: „rofi -show window“


     )
   "*helm-principal*"))

(defun mi-helm-menor ()
  "IS: migrar desde mi-anything-menor"
  (interactive)
  (helm-other-buffer
   '(
     ;; anything-c-source-org-headline ; ← no, da igual
     ;; anythingyhelm-fuente-todas-tareas-org ← es muy bestia y no la uso; además creo que require anything
     ;; helm-source-kill-ring ← no me apetece
     ;; helm-source-minibuffer-history ; ← no lo uso
     ;;anything-c-source-emacs-commands ; ← no, está M-x
     helm-source-info-pages
     helm-source-man-pages ; ← no lo uso mucho (me olvido de que existe)
     helm-source-colors
     helm-source-customize-face
     )
   "*helm-menor*"))

(defun mi-helm-hacia-www ()
  "IS: migrar desde mi-anything-hacia-www"
  (interactive)
  (helm-other-buffer
   '(
     ;; helm-source-google-suggest ; lento y poco fiable, mejor usar la web de Google para mirar estas tendencias

     ;; helm-source-wikipedia-suggest

     ;; Mmmmm… yo quería sólo Wikipedia, no Google. Pero parece que ahora hace pasar por la autocompleción de Google, y luego hay que apretar TAB para abrir la misma cosa en Wikipedia. Extraño. De momento lo pongo, pero hay que configurar helm-google-suggest-actions para quitar Google y poner otros
     helm-source-google-suggest
     ;; Por cierto, llama a helm-google-suggest-fetch, que luego acaba llamando a: https://encrypted.google.com/complete/search?output=toolbar&q=%s

     helm-source-bookmark-w3m
     )
   "*helm-www*"))

(defun mi-helm-técnico ()
  "IS: migrar desde mi-anything-técnico"
  (interactive)
  (helm-other-buffer
   '(
     helm-source-emacs-process
     ;; m4.2017 no iba:    In ‘Absolute Time Timers’ source: ‘timer-list’ must be a list, a symbol bound to a list, or a function returning a list  → arreglado
     helm-source-absolute-time-timers
     helm-source-idle-time-timers
     ;; helm-source-apt
     )
   "*helm-técnico*"))

(defun mi-helm-sólo-wiki ()
  "IS: migrar desde mi-anything-sólo-wiki"
  (interactive)
  (helm-other-buffer
   '(
     anythingyhelm-fuente-etiquetas-radio-org
     )
   "*helm-wiki*"))


;;;;; asignar teclas para lanzadores de helm
;; copiados desde los de anything
(global-set-key (kbd "<f35>") #'mi-helm-principal)     (global-set-key (kbd "3n") #'mi-helm-principal)
(global-set-key (kbd "<S-f35>") #'mi-helm-sólo-wiki)       (global-set-key (kbd "3S") #'mi-helm-sólo-wiki)
(global-set-key (kbd "<M-f35>") #'mi-helm-hacia-www)   (global-set-key (kbd "3M") #'mi-helm-hacia-www)
(global-set-key (kbd "<C-f35>") #'mi-helm-técnico)     (global-set-key (kbd "3C") #'mi-helm-técnico)
(global-set-key (kbd "<M-S-f35>") #'mi-helm-menor)


;;;;; usar helm en otros sitios

;; en eshell
(add-hook 'eshell-mode-hook
          #'(lambda ()
              (define-key eshell-mode-map 
                [remap pcomplete]
                'helm-esh-pcomplete)))
;; y también se puede para el historial (con M-p); es útil
(add-hook 'eshell-mode-hook
          #'(lambda ()
              (define-key eshell-mode-map 
                (kbd "M-p")
                'helm-eshell-history)))

;;;; pequeños modos (que está bien tener, pero que uso en pocas ocasiones)
;;;;; paleta de colores; aún va lento y es incómodo, pero quizás útil

;; Me daba problemas al cargar en „emacs -nw“, pero Drew Adams lo corrigió muy veloz. 17.10.2008. http://www.emacswiki.org/emacs/ColorPalette#toc8
;; MALFAR. 27.10.2008. Me daba problemas al arrancar con caché b-c-c vacía, porque .emacs require palette, palette requiere icicles, e icicles requiere palette.
;;
;; 5.m4.2010: lo desactivo pues ya no uso icicles. No sé si se puede usar sin activar Icicles. Supongo que sí. Pero de todas formas… ¡¡¡usa agave envez!!!
(ignore '(
          (add-to-list 'load-path "~/.emacs.d/icicles/") (require 'hexrgb) ; esto le hace falta primero.  ← por usar otra ruta, o tomarlo de otro lado
          (add-to-list 'load-path "~/.emacs.d/palette")
          (require 'palette)
          ))
;; ¿esto es necesario?
;;(setq palette-font "-outline-Courier-normal-i-normal-normal-3-37-96-96-c-*-iso8859-1")
(setq palette-font "terminus-12")


;;;;; minimapa, „vista de pájaro“
;; http://www.emacswiki.org/emacs/MiniMap
;; (add-to-list 'load-path "~/.emacs.d/minimap/")
;; (require 'minimap)
;; Para hacer el texto muy pequeño tengo que usar fuentes como lucidasans-8 o 5x8 o 6x13

;; no lo uso y por eso lo desactivo
;; si lo necesito, probar también este otro:
;; http://www.emacswiki.org/emacs/Sublimity

;;;;; Subversion
;; m9.2022: quité este código de mi cdv; si lo reactivo, al menos que sea por elpa
;; https://www.emacswiki.org/emacs/psvn.el
;; https://alexott.net/en/writings/emacs-vcs/EmacsPSVN.html
;; (ignore '( ; Esto tarda bastante (~0'6 segundos) y no lo uso nunca; uso vc. Así que lo desactivo hasta que vuelva a recordar que esto existe
;;        (add-to-list 'load-path "~/.emacs.d/psvn")
;;        (require 'psvn)
;;        ))

;;;;; txt2tags-mode

;; veo que se cuelga mucho (¡mucho!) al editarlo…
;; Mmm… es versión que añadí hace 13 años. Quizás actualizarla… Quizás es porque es ISO-8859-1
;; Oh no, la maldición de Google (bueno, StartPage): busco „txt2tags-mode emacs“, y hay sólo 3 resultados, y 1 es mi página. Poca ayuda. Busco „t2t-mode emacs“ y encuentro 2 (1 mi página)

(add-to-list 'load-path "~/.emacs.d/txt2tags/")
(setq auto-mode-alist (append (list
                               '("\\.t2t$" . t2t-mode)
                               )
                              (if (boundp 'auto-mode-alist) auto-mode-alist)
                              ))
(autoload  't2t-mode "txt2tags-mode" "Txt2tags Mode" t)

;;;;; chuck-mode (para chuck, sistema de generación de sonido y música)
;; hay tres modos: 2004, 2006, 2009. Explicado en http://wiki.cs.princeton.edu/index.php/ChucKWithEmacs
;; Puse el 2004, luego el 2009 (Kao's)

(add-to-list 'load-path "~/.emacs.d/chuck/")
(setq auto-mode-alist (append (list
                               '("\\.ck$" . chuck-mode)
                               ;; mío
                               '("\\.chuck$" . chuck-mode)
                               )
                              (if (boundp 'auto-mode-alist) auto-mode-alist)
                              ))
;;v2004: (autoload 'chuck-mode "chuck" "ChucK editing mode" t)
(require 'chuck-mode) ; v2009

(setq chuck-exec "chuck.alsa") ; ejecutable. „chuck“ solo no toca.
;; parece que status no va
;; BONUS: parece que el modo nuevo (v2009) no colorea tanto :-(

;;;;;; Extensiones que le hago a chuck-mode
(define-key chuck-mode-map (kbd "C-c C-p") 'chuck-panic)
(defun chuck-panic ()
  "Desactiva todos los sonidos que Chuck emite"
  ;; Se parece mucho a C-c C-k (chuck-kill-chuck ~) pero lo mata poco y la próxima vez aún funciona
  (interactive)
  (chuck-cmd "--removeall"))

(define-key chuck-mode-map (kbd "C-c C-s") 'chuck-toca-sólo-el-búfer-actual)
(defun chuck-toca-sólo-el-búfer-actual ()
  "Para todos los sonidos y empieza a reproducir el código del búfer actual, sin preguntar nada. Lo graba en disco para que suene la versión actual."
  (interactive)
  (chuck-panic)
  ;;  (save-current-buffer
  (save-buffer)
  (chuck-add-code (buffer-name (current-buffer))))


;;;;; lilypond-mode, para editar musiquillas en lenguaje lilypond (.ly)

(add-to-list 'load-path "/usr/share/emacs/site-lisp/") ; BONUS: me gustaría  evitar esto pues tiene demasiados efectos secundarios

(autoload 'LilyPond-mode "lilypond-mode" nil t)
(setq auto-mode-alist (cons '("\\.ly$" . LilyPond-mode) auto-mode-alist))
(add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))

;;;;; lyqi, para mejorar lilypond-mode con entrada rápida (y sonora) de teclas, y reproducción rápida. Muy bueno

(add-to-list 'load-path "~/.emacs.d/lyqi-0.2.5/") 

;; when loading LilyPond-mode, lyqi-mode library will also be loaded.
;; type `C-c q' in LilyPond-mode to switch to lyqi-mode.
(eval-after-load "lilypond-mode" 
  '(progn
     (load-library "lyqi-mode")
     (define-key LilyPond-mode-map "\C-cq" 'lyqi-mode)))
;;;;; mma-mode (para mma, generador de fondos musicales de acompañamiento)
(add-to-list 'load-path "~/.emacs.d/mma/") 
(add-to-list 'auto-mode-alist '("\\.mma$" . mma-mode))
(autoload 'mma-mode "mma" "MMA mode" t)
(setq mma-command "/usr/bin/mma")
(setq mma-timidity-default-options "")
(setq mma-midi-player-arg "")
;;;;; timidity-mode
(let ((d "/usr/share/emacs25/site-lisp/timidity-el/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'timidity)
    ))

;;;;; midge-mode
;; quizás algo cutre esto de buscar y cargar el .elc directamente
(let ((d "/usr/share/emacs25/site-lisp/midge-mode.elc"))
  (when (file-exists-p d) 
    (load-file d)
    (add-to-list 'auto-mode-alist '("\\.mg$" . midge-mode))
    
    ;; De: http://stackoverflow.com/questions/23099972/how-do-i-replace-compile-internal-with-compilation-start
    (defun compile-internal (command mensajillo-no-sé-de-qué)
      (message "compile-internal está desfasado, uso mi sucedáneo")
      (message mensajillo-no-sé-de-qué)
      (compilation-start command nil (lambda (mode-name) "*res-de-compile-internal*"))
      )

    ))

;;;;; markdown-mode
;; /usr/share/emacs/site-lisp/emacs-goodies-el/markdown-mode.el

(let ((d "/usr/share/emacs25/site-lisp/emacs-goodies-el/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    ))
;; instalar desde ELPA si este require falla
;;(ignore '(
(require 'markdown-mode)
(add-to-list 'auto-mode-alist '("\\.md$" . markdown-mode))
;;))

;;;;; tsv-mode (para valores separados por tabulador)
;; de: http://www.emacswiki.org/emacs/tsv-mode.el

(add-to-list 'load-path "~/.emacs.d/tsv-mode")
(autoload 'tsv-mode "tsv-mode" "A mode to edit table like file" t)
(autoload 'tsv-normal-mode "tsv-mode" "A minor mode to edit table like file" t)

;;;;; velocity-mode
(add-to-list 'load-path "~/.emacs.d/velocity/")
(add-to-list 'auto-mode-alist '("\\.vm$" . vtl-mode))
;; no carga bien
(autoload 'vtl-mode "vtl" "Velocity mode" t)
;;;;; tt-mode (para Template Toolkit, ej. los .tt del marrollo Dancer en Perl)
(add-to-list 'load-path "~/.emacs.d/tt-mode/")
(require 'tt-mode)
(setq auto-mode-alist (append '(("\\.tt$" . tt-mode)) auto-mode-alist ))
(setq auto-mode-alist (append '(("\\.tt2$" . tt-mode)) auto-mode-alist ))
;; Por lo visto no es el sistema de plantillas que estoy usando o necesito…  Es porque Dancer usa <% %> en vez de [% %]. Tendría que retocar tt-mode.el para permitir eso
;; De todas formas, prefiero ver esas plantillas como HTML en vez de como texto plano → html-mode me es mucho mejor.
;; Claro que un mumamo lo arreglaría todo…

;;;;; lua-mode
;; si lo tengo instalado en Debian, cargarlo
;; pero ya lo tomo de elpa así que no importa mucho
(let ((d "/usr/share/emacs25/site-lisp/lua-mode/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'lua-mode)
    ))

;;;;; keywiz (quiz): hace preguntas sobre combinaciones de teclas
(add-to-list 'load-path "~/.emacs.d/keywiz")
(require 'keywiz)

;;;;; flashcard/fc: mediante tarjetas ayuda a memorizar cosas

;; es mejor fc que flashcard. fc.el→  http://ichi2.net/flashcard/

;;;;;; flashcard original (interfaz difícil)


(add-to-list 'load-path "~/.emacs.d/flashcard")
(autoload 'flashcard-mode "flashcard" "flashcard major mode" t)

(add-to-list 'auto-mode-alist '("\\.deck\\'" . flashcard-mode))

(setq flashcard-coding-system 'utf-8) ;estamos en 2009

;; flashcard no es muy intuitivo, pero es algo usable
;; Va con:
;; C-x C-f *.deck: empieza a preguntar
;; Se añaden preguntas con M-x flashcard-add-card. Lo malo es que hay que ejecutarlo desde el búfer de destino; no es muy amigable.

;; Una forma manual incómoda de editar la lista es:
;; flashcard-edit-current-deck: edita
;; flashcard-edit-save-and-return: grabar el fichero realmente (C-x C-s no va)
;; Puedo añadir a mano algo como   PALABRA : descripción,  pero si me deja, pues está en modo sólo-lectura y no me deja tocar ciertas teclas (no sé porqué). 

;; Es mucho más fácil usar fc (configurado abajo).


;;;;;; fc (igu más fácil, muy orientado a japonés)
(setq fc-base "~/.emacs.d/flashcard")
(setq fc-default-lang 'en)
;;(add-to-list 'load-path "~/.emacs.d/flaschard")
(load "~/.emacs.d/flashcard/fc")

;; no quiero teclas F7 ni F8 ni F9. Me puede ir bien: S-F6 para empezar la prueba, M-F6 para añadir pregunta, y C-S-F6 para ver y editar la lista
(global-set-key (kbd "<S-f6>") 'fc-import) ;empezar
(global-set-key (kbd "<M-f6>") 'fc-add-entry-euskara) ;añadir pregunta
(global-set-key (kbd "<C-S-f6>") 'fc-edit) ;editar lista


;;;;;;; mi función de entrada de palabras
(defun fc-add-entry-euskara ()
  "Añade palabra a `fc-deck'. Basado en fc-add-entry. La traducción está entre paréntesis."
  (interactive)
  (save-excursion
    (let ((coding-system-for-read 'utf-8)
          (coding-system-for-write 'utf-8)
          euska erdera)
      (find-file fc-pending)
      (goto-char (point-max))
      (setq euska (read-string "Euskaraz: "))
      (setq erdera (read-string "Itzulpena erderaz: "))
      (insert (format "%s : (%s)\n(%s) : %s\n"
                      euska erdera
                      erdera euska))
      (save-buffer)
      (message "¡Hitza erantsi da!"))))



;;;;;;; vocabulario y distintas listas
;; necesito crear yo el vocabulario, o importarlo mediante algo parecido a flashcard-import-from-colon-file

;;;;;; mejor usar org-learn (en concreto org-drill) en vez de esto

;;;;; imenu

;; Intenté implementarlo para muse, pero creo que imenú no es muy apropiado, porque el esquema es una lista y no un árbol
;; Este ejemplo no funciona como yo quiero

;; (setq expresión-imenú-para-muse
;;       '(
;;         ("Tit1"  "^\\*\\{1\\} \\(.*\\)" 1)
;;         ("Tit2"  "^\\*\\{2\\} \\(.*\\)" 1)
;;         ("Tit3"  "^\\*\\{3\\} \\(.*\\)" 1)
;;         ("Tit4"  "^\\*\\{4\\} \\(.*\\)" 1)
;;         ("Tit5"  "^\\*\\{5\\} \\(.*\\)" 1)
;;         ("Tit6"  "^\\*\\{6\\} \\(.*\\)" 1)
;;         ("Tit7"  "^\\*\\{7\\} \\(.*\\)" 1)
;;  )
;;       )

;; (add-hook 'muse-mode-hook
;;    (lambda ()
;;      (setq imenu-generic-expression expresión-imenú-para-muse)))




;;;;; doc-view. Algo cómodo, pero mupdf es mejor
;; Para ver PDF/PostScript/DVI dentro de Emacs convirtiendo a PNG

;; Emacs anterior a 23, y un poco los posteriores
;; (if (not (featurep 'doc-view)) ; pues en Emacs23 ya viene incluido uno
;;  (progn
;;    (add-to-list 'load-path "~/.emacs.d/doc-view/")
;;    (require 'doc-view)
;;    )
;;   )
;; El mío tiene la adaptación de poder negar colores de PDF. No sé si el oficial ya lo tiene
;; m10.2022 veo que ha cambiado mucho, y mi añadido no es reusable, así que lo descarto (borro de cdv) y paso a versión oficial integrada:
(require 'doc-view)

;;;;; nov, para leer epub
;;(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

;;;;; magit
(require 'magit)
;; Si veo que fallan cosas al cargar (ẽ magit-menu-item), quizás es porque tengo versiones viejas en ~/.emacs.d/elpa que se están cargando en vez de las nuevas
;;(require 'magit-section)  ;; creo que hace falta a mano, porque llama a magit-menu-item
;;(require 'magit-diff)  ;; creo que hace falta a mano, porque llama a magit-menu-item
;; Probablemente no me hace falta a mano:
;; (require 'magit-git)
;; (require 'magit-process)

;; de fichero actual a vista git
(global-set-key (kbd "C-x g") 'magit-status)

;; https://emacs.stackexchange.com/questions/2890/how-to-make-truncate-lines-nil-and-auto-fill-mode-off-in-magit-buffers
(add-hook 'git-commit-mode-hook 'turn-off-auto-fill)

;; me va bien porque magit se cuelga bastante con tramp. Pero parece que no me ayuda en casos en los que lo necesito, mas me molesta en casos en que no lo quiero
;; (setq magit-process-extreme-logging t)

;;;;; „forge“, un añadido para magit
;; Lo instalé desde melpa y no sé si hace falta
;; (with-eval-after-load 'magit
;;   (require 'forge))

;; (ignore '(
;; (let ((d "/w/forge/"))
;;   (when (file-exists-p d)
;;  (add-to-list 'load-path d)
;;  (with-eval-after-load 'magit
;;       (require 'forge))
;;  ))
;; ))


;;;;; tramp

;; En teoría ya viene activado con emacs nuevos
;;(message "Bien voy")
;; Desactivado temporalmente para permitir arranque de demonio en 9.12.2008
;; (require 'tramp) ; ¿Tiene alguna utilidad?

;; Dicen que esto va mejor porque cargar tramp es lento. En realidad no hace falta, pero a ver si hace algo…
(autoload 'tramp "tramp" "Remotely access files." t)

;;(message "Mal voy")

;; cómo usarlo → ver org

;; Por defecto era 3
;; (setq tramp-verbose 5)
(setq tramp-verbose 6)

(setq tramp-default-method "ssh") ; Pero imagino que eso no excluye otros

;; m6.2014: muy misteriosamente, org-babel dejó de interpretar bien los valores de salida Python tras usar los últimos cambios de Emacs hechos a tramp-cache (a saber cuál es la conexión…). Así que lo desactivo temporalmente
;; (require 'tramp-cache)

(setq tramp-persistency-file-name "~/.emacs.d/auto-save-list/tramp") ; mejor que ~/.emacs.d/tramp


(defun edit-as-root ()
  "Edita el fichero actual como root, con su"
  (interactive)
  (find-file (concat "/su::" buffer-file-name))
  )

;; desactivar vc-mode para tramp. Está bien… pero en realidad lo quiero
;; m8.2017: voy a ignorar la desactivación y probar a tenerlo otra vez
(ignore '(
          (setq vc-ignore-dir-regexp
                (format "\\(%s\\)\\|\\(%s\\)"
                        vc-ignore-dir-regexp ; malo, recursivo
                        tramp-file-name-regexp))
          ))

;; para restaurar valor original (y así reactivar vc-mode en tramp):   (setq vc-ignore-dir-regexp "\\`\\(?:[\\/][\\/][^\\/]+[\\/]\\|/\\(?:net\\|afs\\|\\.\\.\\.\\)/\\)\\'")
;; Si restauro, toca reabrir

;; era: (RCS CVS SVN SCCS SRC Bzr Git Hg Mtn)
;; lo ordeno según me gusta
(setq vc-handled-backends '(Hg Bzr Git Mtn))
;; ahora esto ya va bien: (vc-responsible-backend "/home/dc/repoweb")

;;;;; bookmark (no sé bien qué hace, no lo uso mucho pues tengo org)
;;(setq bookmark-default-file "~/.emacs.d/auto-save-list/bookmarks") ; mejor que ~/.emacs.d/bookmarks
(setq bookmark-default-file "~/.emacs.d/bookmarks") ; en realidad me gusta más, y lo quiero en git
;; Para pedir que lo relea: (bookmark-load bookmark-default-file 'overwrite)
;; Es muy confuso, tiene nombres confusos, no hace lo que espero, etc. Me gustaria usarlo más si fuere bueno
;; más notas: ver /bookmarks/

;;;;; oddmuse (para editar páginas Wiki como Emacswiki)
(add-to-list 'load-path "~/.emacs.d/oddmuse/")
(require 'oddmuse)
(oddmuse-mode-initialize)
(setq oddmuse-username "DanielClemente")
(setq oddmuse-directory "~/.emacs.d/oddmuse-caché")

;; para evitar el catpcha de Emacswiki
(add-hook 'oddmuse-mode-hook
          (lambda ()
            (unless (string-match "question" oddmuse-post)
              (setq oddmuse-post (concat "uihnscuskc=1;" oddmuse-post)))))


(setq oddmuse-wiki "EmacsWiki") ; así pregunta pero lo da relleno

;;;;; log4j (para seguir ficheros de registro); incluye: auto-revert-mode
;;;;;; carga y configuración
(add-to-list 'load-path "~/.emacs.d/log")

;; voy a cargar autorevert porque si no no le podré redefinir variables (a autorevert)
(require 'autorevert)

;; Diría que tengo que requerirlo (no autocargarlo) porque quiero redefinirle cosas ahora mismo... pero no estoy seguro
(require 'log4j-mode)
;;(autoload 'log4j-mode "log4j-mode" "Major mode for viewing log files." t)



(add-to-list 'auto-mode-alist '("\\.log\\'" . log4j-mode))
(add-to-list 'auto-mode-alist '("\\.out\\'" . log4j-mode))

;; no me va a poner colores en ficheros muy grandes a menos que haga esto:
;; (setq font-lock-maximum-size 100123123) ; es demasiado; se cuelga pronto al abrir un fichero tan grande (ej. un .c de 2 Mb).
(setq font-lock-maximum-size 300123) ; lo dejo cercano a como estaba. Ir ajustando pero no pasarse.
;; ¡Hacer M-x font-lock-mode es muy fácil! Lo puedo hacer a mano una vez al mes sin problemas.

;; ¡Se le puede pedir también que fontifique en segundo plano! Ver jit-lock
;; Lo pruebo. No sé si es buena idea. Tiene potencial de colgarlo todo ← tras meses de uso: no, no lo cuelga
(setq jit-lock-stealth-time 2) ; era: never. Pongo que se active tras pocos segundos de inactividad. Así estoy activando una especie de „caché“ de fontificado, y es más rápido moverse.
;; Obviamente gasta más memoria, pero vale la pena ← *¿en serio?* Hice una medición el 12.m2.2016 y vi que son unos ~150 Mb más. En mi portátil trasc, eso es mucho. Así que voy ∴ lo desactivo. Esto me ahorró mucha memoria.
;;(setq jit-lock-stealth-time nil)
;; Lo malo de tenerlo activado es que nada más grabar un fichero, ha de volverlo a fontificar todo (bueno, quizás sólo desde el cambio hasta el final)
;; m1.2023: vuelvo a poner 2 segundos, pues tengo más RAM (¡16 Gb! en vez de 1 Gb de trasc), y no me importa usar ~150 Mb más
;; Creo que noto la diferencia así: aquí mismo, teclear () y luego un espacio. Al estar en 2º paréntesis, ambos se iluminan; al apretar espacio me alejo y se apagan. Pero se apagan con retardo

;; ¿me conviene poner jit-lock-defer-time para retardar el resaltado? Es bastante lioso. Pero puede acelerar todo haciendo que los colores se „solidifiquen“ a los pocos segundos de haber escrito algo, en vez de inmediatamente. Me molesta para los <<<a>>> en org; ahí necesito directo.
;; nil: nada más escribir sale todo con el color que toca. Es lo „normal“, lo que todo el mundo espera. Ej: al poner „;“ en Lisp, sale el ; ya en rojo
;; Pruebo a 1s; se me hace raro y no veo que vaya todo más rápido (hay algo en mi emacs que lo ralentiza). De hecho con font-lock-mode desactivado va todo igual de lento
;; Por eso lo pongo a nil (=directo), que es más cómodo
;;(setq jit-lock-defer-time nil)
;; Parece más atractivo el deferirlo si aún hay tecleo; parece que el 0 hará eso
(setq jit-lock-defer-time 0)
;; BONUS: diferencia entre jit-lock-stealth-time y jit-lock-defer-time

;; para probar:
;;(setq jit-lock-stealth-verbose t) ; de momento me va bien para saber que está haciendo algo
(setq jit-lock-stealth-verbose nil) ; ya me lo conozco y no me aporta mucho. Si alguna vez me falla o ralentiza, volver a hacer verborreico

(setq jit-lock-chunk-size 9000) ; que vaya cogiendo trocitos de varios Kbs, creo que no es mucho. Era: 500 (luego subido a 1500)
;; „The optimum value is a little over the typical number of buffer characters which fit in a typical window.“. Gracias por el consejo. En mi pantalla, (* 140 25) es una página. Así que pondré 9 Kb


;; Pone „JIT stealth lock“ y se cuelga mucho (varios segundos, y no lo puedo parar) al abrir ficheros grandes, como awstats.pl ← parece que es por rainbow-delimiters (1.2.1), pues sin él va muy bien y muy suave → Con la 1.3.3 ya va bien.

;; me parece que se actualiza muy lento; estaba a 5 segundos y le pongo menos
(setq auto-revert-interval 1)
;; no quiero PODER interrumpir a auto-revert si eso va a causar que pierda actualizaciones. Creo que en realidad no se pierden, así que sigo dejando como prioritarias mis acciones
;;(setq auto-revert-stop-on-user-input nil)
(setq auto-revert-stop-on-user-input t)
;; m5.2019, m10.2021 etc.: tengo que revisar todo esto pues emacs se pasa demasiado tiempo (ciclos de CPU vistos con M-x profile-start) en auto-revert-buffers. Es comprobabl: abrir fichero largo como xdisp.c, y hacer C-v continuamente. Va a saltos y se para cada segundo
;; (auto-revert--buffer-candidates) me devuelve todso los .org (y más); son muchos
;;
;; ¿No podría usar algún mecanismo de Linux, en vez de tener que consultar continuamente el estado cientos de miles de veces con faccessat newfstatat?
;; Sí:
(setq auto-revert-avoid-polling t)
;; funciona bien (evita todos los faccessat etc.) pero *es directo* y no pregunta si quiero mantener mis cambios. ẽ dice „Reverting buffer ‘Árabe.org’.“ directamente, y pierdo tanto los cambios que hice y grabé como los que hice y no grabé.
;; No lo entiendo. Parece que eso ya lo hacía antes (aún con auto-revert-avoid-polling a nil). Me molesta bastante pues me pierde cambios sin confirmármelo
;; Como parece que no es debido a auto-revert-avoid-polling, lo dejaré a t

;; Además auto-revert-use-notify ya está a t


;; E intento esto también, para que ẽ al cambiar de rama, cno tramp, magit sepa revertir todo. No sé si irá
(setq auto-revert-remote-files t)

;; Parece que eso sólo no va. Pruebo además:
;; (magit-auto-revert-mode 1)
;;
;; Mmmmmmm… eso causa (m2.2023):
;; Debugger entered--Lisp error: (void-variable executable-find)
;;   magit-turn-on-auto-revert-mode-if-desired()
;;   magit-auto-revert-mode(1)
;;   elisp--eval-last-sexp(nil)
;; 
;; Es por: (compat-call executable-find (magit-git-executable) t)
;; Borro versión vieja de compat que tenía instalada. A ver si va
;; Entonces la llamada va. Pero magit-auto-revert-mode se sigue quejando de *variable* no existente, no de función

;; ¿Hace falta esto?: Parece que no 
;; (require 'compat)
;; Pruebo:
;; (require 'magit-autorevert)
;; No va. Aaaaaaah, ver el texto ahí que dice:
;; […]
;; - Unfortunately `:init-value t' only sets the value of the mode
;;   variable but does not cause the mode function to be called.
;; […]

(ignore '(

;; Es guarro, pero pruebo yo aquí:
(define-globalized-minor-mode magit-auto-revert-mode auto-revert-mode
  magit-turn-on-auto-revert-mode-if-desired
  :package-version '(magit . "2.4.0")
  :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
  :group 'magit-auto-revert
  :group 'magit-essentials
  ;; - When `global-auto-revert-mode' is enabled, then this mode is
  ;;   redundant.
  ;; - In all other cases enable the mode because if buffers are not
  ;;   automatically reverted that would make many very common tasks
  ;;   much more cumbersome.
  ;; Comento:
  ;; :init-value (not (or global-auto-revert-mode
  ;;                     noninteractive))
  :init-value t
  )

;; Y entonces:
(require 'compat)
(magit-auto-revert-mode 1)

))
;; Desisto por ahora
;; De hecho, por ahora pongo:
(magit-auto-revert-mode 0)
;; Y ver notas sobre qué es el /compat-call/. Me falla en otros lados

;; Veo que a esto de revertir, a otros les fue, ẽ https://github.com/doublep/logview/issues/30

;;;;;; ajuste para que me pise mis cambios si otro modifica el fichero desde fuera

;; m11.2022 lo desactivo porque llevo años sin necesitarlo
(ignore '(

;; lo quiero en modo lectura, porque si escribo luego ya no me lo actualiza :-(
;;(add-hook 'log4j-mode-hook #'(lambda () (toggle-read-only 1)))

;; En realidad necesito que cuando yo añada texto al búfer, siga revirtiendo (y con ello borrando mi texto).
;; Resumiendo: al activar auto-revert-mode en un fichero, en el momento en que lo modifico en emacs deja de revertir. Quiero que revierta automáticamente perdiendo mis cambios
;; Puse esta pregunta en http://www.emacswiki.org/emacs/RevertBuffer

;; ¡¡¡¡¡!!!!!!! Es por esto:
;;   (when (or auto-revert-tail-mode (not (buffer-modified-p)))
;; ¡no lo había visto! Lo desactivo

;; cogido de autorevert.el.gz de Emacs 23
(defun mi-auto-revert-handler-que-también-revierte-si-has-cambiado-el-búfer ()
  "Revert current buffer, if appropriate.
This is an internal function used by Auto-Revert Mode."

  ;; (when (or auto-revert-tail-mode (not (buffer-modified-p)))
  ;; 142857: quiero que se siga ejecutando aunque yo haya modificado el búfer; por algo es auto-revert
  (when (or auto-revert-tail-mode auto-revert-mode)
    ;;           (progn (shell-command "beep -f 2000 -l 10") t)
    (let* ((buffer (current-buffer)) size
           (revert
            (or (and buffer-file-name
                     (not (file-remote-p buffer-file-name))
                     (file-readable-p buffer-file-name)
                     (if auto-revert-tail-mode
                         (/= auto-revert-tail-pos
                             (setq size
                                   (nth 7 (file-attributes buffer-file-name))))
                       (not (verify-visited-file-modtime buffer)))
                     ;;          (progn (pita-de-verdad) t)
                     )
                (and (or auto-revert-mode
                         global-auto-revert-non-file-buffers)
                     revert-buffer-function
                     (boundp 'buffer-stale-function)
                     (functionp buffer-stale-function)
                     (funcall buffer-stale-function t))))
           eob eoblist)
      (when revert
        (when (and auto-revert-verbose
                   (not (eq revert 'fast)))
          (message "Reverting buffer `%s'." (buffer-name)))
        ;; If point (or a window point) is at the end of the buffer,
        ;; we want to keep it at the end after reverting.  This allows
        ;; to tail a file.
        (when buffer-file-name
          (setq eob (eobp))
          (walk-windows
           #'(lambda (window)
               (and (eq (window-buffer window) buffer)
                    (= (window-point window) (point-max))
                    (push window eoblist)))
           'no-mini t))
        (if auto-revert-tail-mode
            (auto-revert-tail-handler size)
          ;; Bind buffer-read-only in case user has done C-x C-q,
          ;; so as not to forget that.  This gives undesirable results
          ;; when the file's mode changes, but that is less common.
          (let ((buffer-read-only buffer-read-only))
            (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)))
        (when buffer-file-name
          (when eob (goto-char (point-max)))
          (dolist (window eoblist)
            (set-window-point window (point-max)))))
      ;; `preserve-modes' avoids changing the (minor) modes.  But we
      ;; do want to reset the mode for VC, so we do it manually.
      (when (or revert auto-revert-check-vc-info)
        (vc-find-file-hook)))))


(defalias 'auto-revert-handler 'mi-auto-revert-handler-que-también-revierte-si-has-cambiado-el-búfer)

;; Lo he activado para todos. Si va mal, usar esto de abajo (ponerle el defalias)
;;(add-hook 'log4j-mode-hook #'(lambda ()
;;(pita-de-verdad)
;;(set (make-local-variable 'auto-revert-handler) 'mi-auto-revert-handler-que-también-revierte-si-has-cambiado-el-búfer)
;;))


;; ¡Cuidado!: si abro catalina.out, añado, y grabo, entonces Tomcat dejará de usar ese fichero... hasta que lo reinicie

;; fin del ignore
))

;;;;; colores de log4j

;; DEBUG INFO WARN ERROR FATAL
;; si hayautoload:;   (eval-after-load 'log4j-mode '(progn
(set-face-attribute 'log4j-font-lock-debug-face nil :foreground "Gray90") ; era Gray45
(set-face-attribute 'log4j-font-lock-info-face nil :foreground "#0c0") ; era ForestGreen
(set-face-attribute 'log4j-font-lock-warn-face nil :foreground "#9ef") ; era DodgerBlue
(set-face-attribute 'log4j-font-lock-error-face nil :foreground "#faa") ; era Red
(set-face-attribute 'log4j-font-lock-fatal-face nil :foreground "#f00" :weight 'bold) ; era Red + bold
;; si hayautoload:;  ))

;;;;; htmlize (colorea cualquier búfer hacia fichero HTML); lo usa org-mode
;; qué bonito; paso a tener un HTML que se ve igual que lo que yo veía en Emacs, ¡y funciona con cualquier modo!
(add-to-list 'load-path "~/.emacs.d/htmlize")
;; a la 1.34 le hace falta esto; lo saqué de contrib/ de Muse. 17.11.2008
(require 'htmlize-hack)

;;;;; rainbow-mode (colorea los nombres de colores)
(add-to-list 'load-path "~/.emacs.d/rainbow")
(require 'rainbow-mode)
(add-hook 'css-mode-hook 'rainbow-turn-on) ; ¡gran ayuda en CSS!

;; pero ¿y los rgb(6,86,131)?

;;;;; paredit: para editar cosas de paréntesis
;;(add-to-list 'load-path "~/.emacs.d/paredit")
;;(require 'paredit)
;; Lo puse porque rainbow-delimiters lo necesitaba, pero ya no es así, por eso lo desactivé. No lo necesito

;;;;; rainbow-delimiters (colorea pares de paréntesis)
(add-to-list 'load-path "~/.emacs.d/rainbow-delimiters")
(require 'rainbow-delimiters)

;; La versión 1ª ralentizaba mucho, pero ahora ya no; no es molesto activarlo mucho
(add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)
(add-hook 'perl-mode-hook 'rainbow-delimiters-mode)

(ignore '( ; ya no hace falta definir faces 10~16 pues a partir del 9 se vuelven a repetir los colores. Ver rainbow-delimiters-max-face-count


          ;; defino unos cuantos niveles más, más allá del 12. No poner colores aquí, sino luego
          (defface rainbow-delimiters-depth-_13-face
            '((t (:foreground "#e0c7c7")))
            "Rainbow-delimiters nested delimiter face, depth 13."
            :group 'rainbow-delimiters-faces)
          (defface rainbow-delimiters-depth-_14-face
            '((t (:foreground "#e0c7c7")))
            "Rainbow-delimiters nested delimiter face, depth 14."
            :group 'rainbow-delimiters-faces)
          (defface rainbow-delimiters-depth-_15-face
            '((t (:foreground "#e0c7c7")))
            "Rainbow-delimiters nested delimiter face, depth 15."
            :group 'rainbow-delimiters-faces)
          (defface rainbow-delimiters-depth-_16-face
            '((t (:foreground "#e0c7c7")))
            "Rainbow-delimiters nested delimiter face, depth 16."
            :group 'rainbow-delimiters-faces)
          (put 'rainbow-delimiters-depth-13-face
               'face-alias
               'rainbow-delimiters-depth-_13-face)
          (put 'rainbow-delimiters-depth-14-face
               'face-alias
               'rainbow-delimiters-depth-_14-face)
          (put 'rainbow-delimiters-depth-15-face
               'face-alias
               'rainbow-delimiters-depth-_15-face)
          (put 'rainbow-delimiters-depth-16-face
               'face-alias
               'rainbow-delimiters-depth-_16-face)
          ))


;; Configurar colores buenos para paréntesis
;; M-x customize-group rainbow-delimiters

;; ((((((((((()))))))))))
;; [[[[[[[[[[[]]]]]]]]]]]
;; pruebas con M-(
;; Pruebas más largas: ← borradas de aquí, pues me fastidian la exportación etc.


;; ¡Festival multicolor!
(set-face-attribute 'rainbow-delimiters-depth-1-face nil :foreground "white")
(set-face-attribute 'rainbow-delimiters-depth-2-face nil :foreground "cyan")
(set-face-attribute 'rainbow-delimiters-depth-3-face nil :foreground "#f33")
(set-face-attribute 'rainbow-delimiters-depth-4-face nil :foreground "#8f8")
(set-face-attribute 'rainbow-delimiters-depth-5-face nil :foreground "#88f")
(set-face-attribute 'rainbow-delimiters-depth-6-face nil :foreground "#f8f")
(set-face-attribute 'rainbow-delimiters-depth-7-face nil :foreground "#07e")
(set-face-attribute 'rainbow-delimiters-depth-8-face nil :foreground "#f80")
(set-face-attribute 'rainbow-delimiters-depth-9-face nil :foreground "#ff1")
(ignore '( ; ver arriba; ya no hacen falta
          (set-face-attribute 'rainbow-delimiters-depth-10-face nil :foreground "#966")
          (set-face-attribute 'rainbow-delimiters-depth-11-face nil :foreground "#2f0")
          (set-face-attribute 'rainbow-delimiters-depth-12-face nil :foreground "#f0f")
          (set-face-attribute 'rainbow-delimiters-depth-13-face nil :foreground "#0ba")
          (set-face-attribute 'rainbow-delimiters-depth-14-face nil :foreground "#a20")
          (set-face-attribute 'rainbow-delimiters-depth-15-face nil :foreground "#10f")
          (set-face-attribute 'rainbow-delimiters-depth-16-face nil :foreground "#fbe")
          ))

;; para los que no concuerdan
(set-face-attribute 'rainbow-delimiters-unmatched-face nil :foreground "white" :background "#f22")

;; probando a ponerlos en negrita todos, así se ven mucho más. Ayudan a ver la estructura (en Lisp)
(progn
  (set-face-bold-p 'rainbow-delimiters-depth-1-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-2-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-3-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-4-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-5-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-6-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-7-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-8-face t)
  (set-face-bold-p 'rainbow-delimiters-depth-9-face t)
  (ignore '( ; ver arriba; ya no hacen falta
            (set-face-bold-p 'rainbow-delimiters-depth-10-face t)
            (set-face-bold-p 'rainbow-delimiters-depth-11-face t)
            (set-face-bold-p 'rainbow-delimiters-depth-12-face t)
            (set-face-bold-p 'rainbow-delimiters-depth-13-face t)
            (set-face-bold-p 'rainbow-delimiters-depth-14-face t)
            (set-face-bold-p 'rainbow-delimiters-depth-15-face t)
            (set-face-bold-p 'rainbow-delimiters-depth-16-face t)
            ))

  )

;; BONUS: ¡¡usarlo para etiquetas de XML imbricadas!!

;;;;; boxquote (rodea un trozo de región con un borde; útil para citas y firmas)

;; Lo tenía en cdv desde ~2007
;; (add-to-list 'load-path "~/.emacs.d/boxquote")
;; En m10.2022 lo borré de mi cdv (1.21) y tomé 20220919.714 de melpa
(require 'boxquote)

;; Defino este estilo:
;; ┏━━━━┫ título ┃
;; ┃ texto
;; ┃ bla ble bli blo blu
;; ┗━━━━
(setq boxquote-side "┃ ")
(setq boxquote-top-corner "┏")
(setq boxquote-bottom-corner "┗")
(setq boxquote-top-and-tail "━━━━")
(setq boxquote-title-format "━┫ %s ┃")

(defalias 'cajita 'boxquote-region)

;;;;; varios modos genéricos para editar ciertos tipos de fichero
;; Es importante tener esto (generic-x) para editar /etc/fstab, /etc/hosts, apache.conf, …
;; Seguro que hay formas menos guarras de modificar esta lista, sin tener que incluir toda la ristra de modos que venían por defecto
(setq generic-extras-enable-list 
      '(
        alias-generic-mode ansible-inventory-generic-mode apache-conf-generic-mode apache-log-generic-mode
        etc-fstab-generic-mode etc-modules-conf-generic-mode etc-passwd-generic-mode etc-services-generic-mode etc-sudoers-generic-mode fvwm-generic-mode hosts-generic-mode inetd-conf-generic-mode
        java-manifest-generic-mode java-properties-generic-mode mailagent-rules-generic-mode mailrc-generic-mode named-boot-generic-mode named-database-generic-mode prototype-generic-mode resolve-conf-generic-mode samba-generic-mode
        show-tabs-generic-mode vrml-generic-mode x-resource-generic-mode xmodmap-generic-mode
        ))

(require 'generic-x)
;; Como no quiero alguno (como javascript-generic-mode), lo he quitado mediante „customize“ (muy cómodo como interfaz) y lo he movido aquí arriba

;;;;; xmodmap-mode
;; Ver en proj.org la tarea de integrar esto en Emacs
(define-generic-mode 'xmodmap-mode
  '(?!)
  '("add" "clear" "keycode" "keysym" "remove" "pointer")
  nil
  '("[xX]modmap\\(rc\\)?\\'")
  nil
  "Simple mode for xmodmap files.")
;;;;; htaccess-mode
;; lo copié de http://www.emacswiki.org/emacs/GenericMode pero no va bien, no ilumina nada, ni Files ni nada que use yo. Además busca .htaccess\\' y eso no me convence
;; Mejor editarlos así:
(add-to-list 'auto-mode-alist '("\\.htaccess$"   . apache-conf-generic-mode))
(add-to-list 'auto-mode-alist '("httpd\\.conf$"  . apache-conf-generic-mode))
(add-to-list 'auto-mode-alist '("srm\\.conf$"    . apache-conf-generic-mode))
(add-to-list 'auto-mode-alist '("access\\.conf$" . apache-conf-generic-mode))
(add-to-list 'auto-mode-alist '("website\\..+\\.conf$" . apache-conf-generic-mode))

;;;;; yasnippet (plantillas para texto en general)
;;;;;; antes de cargar, le redefino tecla

;; pruebo a cambiar la tecla:
;; era por defecto: (setq yas/trigger-key "<tab>")
;;(setq yas/trigger-key nil)
;;(setq yas/trigger-key "<f9>") ; probando
;; en realidad no hace falta, todo va bien ahora

;;;;;; carga, si es que lo quiero cargar
;; ¿lo activo o no? Veo que es muy útil para el HTML; me hace mucho más productivo → ∴ lo quiero

;; 4.m2.2010: lo ignoro temporalmente… pues no me aporta mucho; sólo problemas. Además me enlentece 6 segundos el arranque de Emacs
;; m4.2012: evito versión vieja (estaba metida en mi cdv); cargaré la nueva (/w/)

;; m4.2012: Lo cojo de https://github.com/capitaomorte/yasnippet
;; y luego (creo): rake compile

;; m9.2013: lo desactivo otra vez porque creo que me ralentiza mucho y no me aporta nada (creo que ni funciona…). Nunca lo he usado
;; (ignore '(
;;        (if (file-directory-p "/w/yasnippet/")
;;            (progn
;;              (message "Cargando Yasnippet de /w/")
;;              (setq load-path (cons (expand-file-name "/w/yasnippet") load-path))
;;              ))
;;        ))

;; m8.2017: lo instalo por elpa y lo activo siempre:
(require 'yasnippet)
(yas-global-mode 1)


;; IS: no me va en wl-draft-mode, quizás porque estoy usando org-contacts o algo así que redefine TAB → no, es porque no estoy en yas/minor-mode. No pasa ni por el yas/minor-mode-on (cuando para otros búfers sí lo hace). → ∴ chapucilla, pero esto lo arregla (en m8.2017 aún utila):
(add-hook 'wl-draft-mode-hook #'yas-minor-mode-on)


;;;;;; configuración básica
;; pre-m8.2017: lo tenía desactivado. Ahora lo iré activando poco a poco, y recuperando esta configuración (la mantengo comentada)
(ignore '(
          ;; MALFAR me hace falta tecla para „expandir“/completar. El TAB ya es para contraer+indentar.

          ;; m9.2012: empiezo a usar nombres buenos yas-algo, en vez de yas/algo (cambiado en cdv el 19.m6)

          ;; ordenado a mi gusto
          (setq yas-prompt-functions (quote (yas/dropdown-prompt yas/completing-prompt yas/x-prompt yas/ido-prompt yas/no-prompt)))

          ;; MALFAR dic.2009: al poner un paréntesis ( en python me sale un preguntón; peta cuando aprieto ) por ejemplo, cosa muy molesta al teclear rápido

;;;;;; quitarle teclas que no quiero  ← m8.2017 ¡¡¡¡¡no!!!! Son útiles, para editar plantillas
          (define-key yas-minor-mode-map "\C-c&\C-s" nil)
          (define-key yas-minor-mode-map "\C-c&\C-n" nil)
          (define-key yas-minor-mode-map "\C-c&\C-v" nil)
          (define-key yas-minor-mode-map "\C-c&\C-f" nil)
          (define-key yas-minor-mode-map "\C-c&" nil) ; ← ŝajne ĉi tio nepris

          ;; intento recuperar ésta en org
          (org-defkey org-mode-map "\C-c&"    'org-mark-ring-goto)
          ;; tampoco basta: (define-key org-mode-map "\C-c&"    'org-mark-ring-goto)


;;;;;; algunas plantillas en message-mode
          ;; ∴ mejor definir las plantillas en ficherillos sueltos en ~/.emacs.d/snippets, parece más cómodo


;;;;;; fin de trozo condicional (sólo para cuando tiene yasnippet)
          ))


;;;;; emmet, para HTML y CSS escribiendo poco
;; lo cargo de melpa

(add-hook 'sgml-mode-hook 'emmet-mode) ;; Auto-start on any markup modes
(add-hook 'css-mode-hook  'emmet-mode) ;; enable Emmet's css abbreviation.
;; usable con C-j

;;;;; tempo.el (otro para plantillas)
;; http://www.gnu.franken.de/ke/emacs/tempo.html

;;;;; taskjuggler-mode (para colorear ficheros .tjp)
(add-to-list 'load-path "~/.emacs.d/taskjuggler")
(require 'taskjuggler-mode)

;;;;; cosas para integración con JIRA (ẽ para opencraft
;;;;;; helm-jira (están en melpa)
;; va bien
;;(ignore '(
(setq
 ;; URL of your JIRA instance (should not end in a slash)
 helm-jira-url "https://tasks.opencraft.com"      

 ;; The ID of the board you want to interact with
 helm-jira-board-id 24

 ;; The username to use to log in to JIRA
 helm-jira-username "clemente"

 ;; The JIRA-project you want to interact with
 helm-jira-project "Serenity"


 ;; URL of the stash/bitbucket API (should not end in a slash)
 helm-jira-stash-url "https://src.yourcompany.com"

 ;; The stash/bitbucket repo you want to interact with
 helm-jira-repo "myRepo")

;;))
;;;;;; org-jira (está en melpa)
;; (setq jiralib-url "https://tasks.opencraft.com")
;; (setq org-jira-worklog-sync-p nil)


;;;;; binview-mode, extensión para hexl-mode que cuadra la ristra de bytes con estructuras de datos definidas
(add-to-list 'load-path "~/.emacs.d/binview/")
(require 'binview)

;;;;; ledger-mode (para editar los ficheros de contabilidad)
(let ((f "/usr/share/emacs/site-lisp/ledger.el"))
  (when (file-exists-p f) 
    (load-file f)
    (require 'ledger)
    ))
;; lo uso también para hledger pues la sintaxis es la misma
(add-to-list 'auto-mode-alist '("\\.hledger\\.journal$" . ledger-mode))

;;;;; beancount
(let ((f "/w/beancount/editors/emacs/beancount.el"))
  (when (file-exists-p f) 
    (load-file f)
    (require 'beancount)
    (setq beancount-install-dir "/w/beancount")
    ))
;; No hace falta porque ya lo pone en cabecera de los que uso… junto con org
;; Pero como a veces abro .beancount de otros, lo pongo
(add-to-list 'auto-mode-alist '("\\.beancount$" . beancount-mode))
;; Pero no sé cómo hacer que se activen los dos: org y beancount, en ese orden. Ver https://lists.gnu.org/archive/html/help-gnu-emacs/2007-10/msg00244.html etc.
;; Pruebo pero no va (no van ambos a la vez):
;; (add-to-list 'auto-mode-alist '("\\.beancount$" . org-mode))


;;;;; google-maps: ver mapas de Google dentro de Emacs
;; de http://git.naquadah.org/?p=google-maps.git;a=summary
(add-to-list 'load-path "~/.emacs.d/google-maps")
(require 'google-maps)
;; Ahora esto va muy bien: M-x google-maps
(setq google-maps-cache-ttl (* (* 3600 24) 30)) ; 1 mes en caché

;; Además:
(require 'org-location-google-maps)
;; Entonces:
;; C-c M-L: definir lugar para una tarea
;; C-c M-l: ver mapa con el lugar para una tarea

;;;;; json-mode o algo así para editar JSON cómodamente
;; esto es para hablar o entender JSON; no es lo que busco: http://cvs.savannah.gnu.org/viewvc/*checkout*/emacs/lisp/json.el?root=emacs

;; http://stackoverflow.com/questions/435847/emacs-mode-to-edit-json

;;;;; mongodb-mode o algo así para mandar búfer JS a mongo

(defun manda-búfer-a-mongodb ()
  (interactive)
  (compile "mongo vihotel /home/dc/n/serĉos.js")
  ;; elegir ventana de „compilation“ y apuntar abajo del todo
  (select-window (get-buffer-window "*compilation*"))
  (end-of-buffer)

  )
(defvar mimongodb-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-c\C-c" 'manda-búfer-a-mongodb)
    map)
  "Mapa de teclas con poca cosa.")

;; estaría bien activar esto automáticamente en algún caso, pero no sé detectarlo. Es .js normal
(define-minor-mode mimongodb-mode
  "Para poder mandar JS a mongo."
  :lighter " mimongodb")


;;;;; wget, para bajar cosas de Internet por wget
;; muy viejo: http://lists.gnu.org/archive/html/gnu-emacs-sources/2001-10/msg00018.html
;; para el viejo: (add-to-list 'load-path "~/.emacs.d/wget") (require 'wget)
;;
;; mejor: http://packages.debian.org/squeeze/wget-el
;; (¡hay que instalarlo a mano pues no está en apt!)
;;
;; .el en: /usr/share/emacs/site-lisp/wget-el
(let ((d "/usr/share/emacs25/site-lisp/wget-el/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'wget)
    ))
;; MALFAR: probar ← no lo necesito



;;;;; xml-rpc, requerido por weblogger.el
;; http://bzr.savannah.gnu.org/lh/emacsweblogs/annotate/head%3A/lisp/xml-rpc.el
;; rama: http://bzr.savannah.gnu.org/r/emacsweblogs/
;; bajar a mano o copiar de ahí

(if (file-directory-p "/w/xml-rpc/")
    (progn
      (setq load-path (cons (expand-file-name "/w/xml-rpc") load-path))
      ;;(autoload 'xml-rpc "xml-rpc" "xml-rpc" t) ; ← no pues no hay interactivas
      (require 'xml-rpc)
      )
  )
;; para probar va bien:
(setq xml-rpc-debug 1) ; era 0. Se puede subir a >1 para más info en *Messages*

;;;;; weblogger-mode, por XML editar blogs Drupal etc.
(if (file-directory-p "/w/weblogger-el/")
    (progn
      (setq load-path (cons (expand-file-name "/w/weblogger-el") load-path))
      (require 'weblogger)
      ;;(autoload 'weblogger "weblogger" "modo para editar blogs" t)
      

      )
  )
(setq weblogger-ping-urls '()) ; era: ("http://rpc.weblogs.com/RPC2")

;;;;; o-blog, para exportar a HTML („blogs“, dice) desde org
;; Aún en pruebas
(let ((d "/w/o-blog/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'o-blog)
    ))

;;;;; sisu
(let ((d "/usr/share/sisu/conf/editor-syntax-etc/emacs/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    ;;(require 'sisu-mode)
    (autoload 'sisu-mode "sisu-mode" "Sisu mode" t)
    (add-to-list 'auto-mode-alist '("\\.sst$" . sisu-mode))
    (add-to-list 'auto-mode-alist '("\\.ssi$" . sisu-mode))

    ))

;;;; Tabbar (Jul2009: ya no lo uso)
;; Ya no lo uso, ver más abajo. 28.m9.2009: también le he desactivado las teclas que me hice
;; Por cierto, m10.2019 han aportado esto al Emacs oficial de manera nativa. Por probar
(ignore '(
;;;;; Antes de cargar, le desactivo los botones

          ;; quito las 3 imágenes de los botones; en su lugar saldrá texto
          (setq tabbar-scroll-left-button 
                '((" <" nil )
                  " =" nil )
                )

          (setq tabbar-scroll-right-button
                '((" >" nil)
                  " =" nil)
                )

          (setq tabbar-home-button
                '(("[o]" nil)
                  "[x]" nil)
                )

;;;;; Carga
          (add-to-list 'load-path "~/.emacs.d/tabbar")
          (require 'tabbar)
          ;; 17.m7.2009: ha llegado la hora de dejar de usar tabbar-mode, pues sospecho  que hace ir todo más lento, no me ayuda mucho, me roba pantalla y distrae, y quiero acostumbrarme a usar C-x C-b.
          ;;(tabbar-mode t)
          ;; De vez en cuando puedo usarlo para comparar si perdí algo.
          ;; Sin tabbar me estoy perdiendo todo el panel de la mano derecha (M-t M-n M-c M-r) que quizás echo en falta. Pero en conkeror y en wmii ya me muevo de esta forma y es un lío; tengo que estar moviéndome por todos lados hasta encontrar lo que busco.


          ;; ésta es la solución a lo de que en erc,info,w3m,emacs-jabber no se vean las pestañas y en vez de eso se vea la barra propia del modo („header-line“)
          ;;No va así:
          ;; (tabbar-local-mode t)
          ;;(setq tabbar-local-mode t)
          ;;Así sí que va, pero es incómodo:
          ;;(global-set-key [(control f12)] 'tabbar-local-mode)
          ;; 18.m8.2009: lo he desactivado (aunque era útil) porque ya no uso tabbar y quiero C-f12 para ir a *Messages*


;;;;; Función de lista de búfers (para elegir el orden)
          ;; MALFAR: veo que se actualiza demasiado (¡a cada tecla de inserción/movimiento/mensaje!) para redibujar búfers. Mejorarlo
          ;; Probándolo con:
          (ignore '(
                    (defadvice tabbar-buffer-update-groups (before pita-cada-vez-que-redibujes-búfers activate)
                      "¡pi!"
                      ;;(pita-de-verdad-cortito)
                      (beep)
                      )
                    (ad-disable-advice 'tabbar-buffer-update-groups 'before 'pita-cada-vez-que-redibujes-búfers)
                    (ad-enable-advice 'tabbar-buffer-update-groups 'before 'pita-cada-vez-que-redibujes-búfers)

                    ))


          ;; MALFAR: me gustaría poder ordenar los búfers. Ver (tabbar-buffer-list) (los da con orden distinto al mostrado)

;;;;; Función de agrupado de búfers

;;;;;; explicación

          ;; sólo cambia entre el grupo actual
          (setq tabbar-cycling-scope (quote tabs))
          ;; Agrupar los búfers:
          ;; grupo "grave": lo importante: editores...
          ;; grupo "alio": el resto: basura, depuración, ...
          ;; grupo "webo": w3m
          ;; grupo "sifi": dired y acceso al sistema ficheral
          ;; grupo "chat": rcirc
          ;; grupo "conĉ": intérpretes de comandos: eshell, shell
          ;;
          ;; Idea: ¿me iría bien directamente usar un grupo por modo? Así es como funciona tabbar 2.0 sin tabbar-buffer-groups. Ventajas: las pestañas intergrupales están muy relacionadas. Desventajas: muchos grupos; grupos con pocas pestañas. Lo descarto por tener muchos grupos (con más de 5 me lío).
          ;;
          ;; Función basada en http://www.ficml.org/jemimap/wordpress/2004/10/11/tabbar/
          ;; (Aún no la entiendo bastante...)
          (defun tabbar-buffer-groups (buffer)
            "Da la lista de nombre de grupo a los que pertenece „buffer“.
Return only one group for each buffer."
            (with-current-buffer (get-buffer buffer)
              (cond

;;;;;; Grupo ĉefa, por editoroj normalaj
               (
                (or
                 (memq major-mode
                       ;; Ne ĉio text-mode-a estas grava!
                       '(tex-mode latex-mode xml-mode))
                 (member (buffer-name)
                         '("*scratch*"))
                 )
                '("grave")
                )

;;;;;; Grupo chat por paroladaĵoj (gnus kaj rcirc)

               ((or
                 ;; rcirc
                 (string-match "@irc.freenode.net" (buffer-name))
                 (string-match "^gnus-.*-mode$"   (symbol-name (symbol-value 'major-mode)))
                 ;; quizás me he complicado bastante... pero es que no sé mucho de Elisp.
                 ;;     ((string-match "^gnus-.*-mode$"   'major-mode)
                 (string-match ".*:\.KILL" (buffer-name))

                 ;; "*Group*" hace falta porque „M-x gnus“ empieza creando un búfer en modo fundamental
                 ;; "*-jabber-*" es la lista de contactos
                 (member (buffer-name)
                         '("newsrc-dribble" "*Group*" "*-jabber-*"))
                 (memq major-mode '(message-mode))

                 )
                '("chat")
                )
;;;;;; Grupo por retpaĝoj
               ((or (memq major-mode '(w3m-mode))
                    (member (buffer-name)   '("*w3m form textarea*"))
                    )
                '("webo")
                )

;;;;;; Grupo por komandejiloj/igiloj
               ((memq major-mode
                      '(eshell-mode shell-mode))
                '("conĉ")
                )

;;;;;; Grupo por krozado de dosieroj ĉe la disko; sed ne por la igilo
               ((memq major-mode
                      '(dired-mode))
                '("sifi")
                )

;;;;;; Grupo por malgravaĵoj malrigardindaj
               ((or (get-buffer-process (current-buffer))
                    (memq major-mode
                          '(comint-mode compilation-mode buffer-menu-mode help-mode))
                    ;; 9.2.2009: esto incluye todos los nombres que empiezan y acaban en asterisco; excepto los que ya han encontrado destino en reglas de arriba
                    (string-match "^\\*.*\\*$" (buffer-name))
                    ;; Antes los listaba a mano y recopilé éstos:
                    ;; "*Messages*"
                    ;; "*Completions*"
                    ;; "*Backtrace*"
                    ;; "*Apropos*"
                    ;; "*tramp output*"
                    ;; "*Calculator*" "*Calc Trail*"
                    ;; "*Calendar*"
                    ;; "*irc.freenode.net*"
                    ;; "*trace of SMTP session to smtp.gmail.com*"
                    ;; "*-jabber-xml-log-*" ; pero el "*-jabber-*" es la lista de contactos
                    ;; "*fsm-debug*"
                    ;; "*doc-view conversion output*"
                    ;; "*Ibuffer*"
                    ;; "*Pp Eval Output*" ; noséqués
                    ;; "*Async Shell Command*"
                    ;; "*Shell Command Output*"
                    ;; "*Warnings*"
                    ;; "*Buffer List*" ; no es ibuffer, es el malo
                    ;; "*vc*" ; el mensajito de éxito después de un C-x v v
                    ;; "*vc-diff*" ; y el que muestra las diferencias al C-x v =
                    ;; "*vc-change-log*"
                    ;; "*Org Agenda*"
                    ;; "*etags tmp*"
                    ;; "*Compile-Log*"
                    ;; "*jde-log*"
                    ;; "*slime-events*"

                    ;; Kelkaj datumoj ankaŭ estas malatentotaj
                    (member (buffer-name)
                            '(
                              ".type-break"
                              "newsrc-dribble"
                              ".bbdb"

                              ))

                    ;; Extensiones:
                    ;; .moc es de Qt y lo genera a partir de los .h; me molesta
                    ;; Mejor implementar algo más eficiente; ej. un diccionario extensión--modo
                    (and (buffer-file-name) (string-match "\\.moc$" (buffer-file-name)))


                    )
                '("alio")
                )


;;;;;; Estas la lastŝanca okazo: ĉio ne ignorita gravas
               (t
                '("grave")
                )
               ))
            )

;;;;; Y colores
          ;; c1= configuración bonita durante un tiempo, con pestañas desactivadas gris oscuro, la iluminada en fondo amarillo (color negro), las otras con texto amarillo, y todo sobre una banda gris clara... que brilla mucho. La usé desde hace mucho y hasta el 18.10.2008
          (set-face-attribute 'tabbar-default-face nil
                              :background "gray10") ; c1=gray60
          (set-face-attribute 'tabbar-unselected-face nil
                              :background "#440" ; c1=gray40
                              :foreground "#aa3" ; c1=#cccc30
                              :box nil)
          (set-face-attribute 'tabbar-selected-face nil
                              :background "#883" ; c1=f2f256
                              :foreground "black" ; c1=black
                              :box 1)
          (set-face-attribute 'tabbar-button-face nil
                              :box '(:line-width 1 :color "dark red"; :style released-button
                                                 )
                              :foreground "dark red"
                              ) ; c1=gray72
          (set-face-attribute 'tabbar-separator-face nil
                              :height 0.7)


;;;;; fin del sánduich
          ))
;;;; eshell (la ¿„econcha“?)

;;;;; carga de eshell y compañía
(require 'em-term) ;hace falta para eshell-visual-commands

;;(ignore '(
;;;;; colores en econcha, y comandos visuales
;; para eshell: tiene en cuenta las secuencias ANSI para que en vez de códigos salgan colores
;; Parece que por defecto era: (eshell-postoutput-scroll-to-bottom eshell-handle-control-codes eshell-handle-ansi-color eshell-watch-for-password-prompt)

(setq eshell-output-filter-functions (list
                                      'eshell-handle-ansi-color
                                      ;; me está fallando al incluir esto y hacer ls, cuando antes no me fallaba. 28.m7.2010 → era por cargar wanderlust desde .el en vez de .elc
                                      ;;
                                      ;; Debugger entered--Lisp error: (wrong-type-argument overlayp nil)
                                      ;;   overlay-put(nil face ((foreground-color . "blue") bold))
                                      ;;   ansi-color-set-extent-face(nil ((foreground-color . "blue") bold))
                                      ;;   ansi-color-apply-on-region(#<marker at 632 in *eshellcortita*> #<marker at 2397 in *eshellcortita*>)
                                      ;;   eshell-handle-ansi-color()
                                      ;;   run-hooks(eshell-output-filter-functions)
                                      ;;   eshell-run-output-filters()
                                      ;;   eshell-output-filter(#<process ls> "Bla…

                                      'eshell-handle-control-codes
                                      'eshell-watch-for-password-prompt))

;; Y parece que esto hace falta
;; Comentario original: couleur dans le shell (j'ai ajouté dumb dans /etc/LS_COLOR egalement)
(autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
;; Con esto funcionan cosas con colores, como „git status“
;; Otros comandos necesitan ser añadidos aquí:
(add-to-list 'eshell-visual-commands "vim")

;;))

;;;;; pedidor de la econcha
;; El pedidor es ¬sobreescribible
(setq comint-prompt-read-only t)
;;;;; ficheros de extensión y nuevos comandos estilo .bashrc
;; para que grabe los alias
(setq eshell-aliases-file "~/.emacs.d/eshell/alias")

;;;;; tecla para ir al principio de la línea de comandos o de la línea del búfer
;; de EmacsWiki (http://www.emacswiki.org/emacs/EshellFunctions)

(defun eshell-maybe-bol ()
  "C-a en eshell conmuta entre principio de comando o principio del búfer"
  (interactive)
  (let ((p (point)))
    (eshell-bol)
    (if (= p (point))
        (beginning-of-line))))

(add-hook 'eshell-mode-hook
          #'(lambda () (define-key eshell-mode-map "\C-a" 'eshell-maybe-bol)))


;;;;; desplazamiento raro y posición de las cosas
;; No sé por qué, pero el pedidor se queda en medio de la pantalla en vez de ir abajo cuando hay mucha salida. Esto lo corrige... pero no sé por qué no viene ya corregido.

;; scroll to bottom for eshell

(defun eshell-scroll-to-bottom (window display-start)
  (if (and window (window-live-p window))
      (let ((resize-mini-windows nil))
        (save-selected-window
          (select-window window)
          (save-restriction
            (widen)
            (when (> (point) eshell-last-output-start) ; we're editing a line. Scroll.
              (save-excursion
                (recenter -1)
                (sit-for 0))))))))

(defun eshell-add-scroll-to-bottom ()
  (interactive)
  (add-hook 'window-scroll-functions 'eshell-scroll-to-bottom nil t))

(add-hook 'eshell-mode-hook 'eshell-add-scroll-to-bottom)

;;;;; Mejoras del ls

;; también sacado del wiki; permite hacer clic medio / enter en resultados de un ls
(eval-after-load "em-ls"
  '(progn
     (defun ted-eshell-ls-find-file-at-point (point)
       "RET on Eshell's `ls' output to open files."
       (interactive "d")
       (find-file (buffer-substring-no-properties
                   (previous-single-property-change point 'help-echo)
                   (next-single-property-change point 'help-echo))))

     (defun pat-eshell-ls-find-file-at-mouse-click (event)
       "Middle click on Eshell's `ls' output to open files.
 From Patrick Anderson via the wiki."
       (interactive "e")
       (ted-eshell-ls-find-file-at-point (posn-point (event-end event))))

     (let ((map (make-sparse-keymap)))
       (define-key map (kbd "RET")      'ted-eshell-ls-find-file-at-point)
       (define-key map (kbd "<return>") 'ted-eshell-ls-find-file-at-point)
       (define-key map (kbd "<mouse-2>") 'pat-eshell-ls-find-file-at-mouse-click)
       (defvar ted-eshell-ls-keymap map))

     (defadvice eshell-ls-decorated-name (after ted-electrify-ls activate)
       "Eshell's `ls' now lets you click or RET on file names to open them."
       (add-text-properties 0 (length ad-return-value)
                            (list 'help-echo "RET, mouse-2: visit this file"
                                  'mouse-face 'highlight
                                  'keymap ted-eshell-ls-keymap)
                            ad-return-value)
       ad-return-value)))

;;;;; Gestión de varios procesos

;; Suspender tareas con C-c C-z: no hace falta; en vez de eso abriré otra econcha: „C-u F8“


;;;; recentf: cuadro para abrir rápidamente los últimos ficheros abiertos
;; Me va muy bien usarlo en helm; de hecho prácticamente lo uso sólo ahí
(require 'recentf)
(setq recentf-max-menu-items 1000) ; a lo grande; quiero muchísimos
(setq recentf-max-saved-items nil) ; y los ha de grabar todos a disco

(setq recentf-exclude '(
                        "^/home/dc/\\.emacs.d/cedet-caché/"  ; los semantic.cache. Ignara bien
                        "^/home/dc/\\(\\.mirp1?/\\)?wiki/" ; todo lo de wiki pues siempre será reciente
                        ))


(setq recentf-save-file "~/.emacs.d/auto-save-list/ficheros_recientes")
;; ¡pero ese fichero es muy viejo!
;; Además, no sé por qué, parece usar ~/.recentf para algo…
;; (recentf-load-list)
;; (recentf-save-list)

;; Se graba casi nunca (sólo cuando muere emacs) → toca grabarla (recentf-save-list) de vez en cuando
;;(run-with-timer 0 (* 120 60) 'recentf-save-list) ; cada 120 minutos. Veo que va; interrumpe un poco cuando pasa, pero pasa poco
(run-with-idle-timer (* 15 60) t 'recentf-save-list) ; esto la graba a los X segundos de inactivo. Sobre el número: 15 segundos es demasiada frecuencia, así que pongo 15 minutos. En realidad lo que busco es „cada vez que esté libre por 15s, comprueba si la última vez que hice save fue hace >59 min.; si así es, rehazla ahora“.
;; otra opción es: cada 30 minutos, si está inactivo graba, si no no hagas nada.
;; algo hay que hacer, pues recentf me está ralentizando mucho algunas cosas, como el deshibernar

;; C-x C-r me va bien pues si no, sería ido-find-file-read-only
(global-set-key "\C-x\ \C-r" 'recentf-open-files)
;; Por último lo activa, ya con la configuración buena
(message "Activando recentf-mode")
(recentf-mode 1)
(message "He activado recentf")

;;;; session.el: para grabar datos de entorno de Emacs y cargarlos al rearrancar (también restaura cosas de ficheros usados hace poco)
;; En realidad no necesito esto mucho… pues lo único que yo quiero al arrancar Emacs es poder tener una lista de los N000 ficheros abiertos „recientemente“, y eso lo puedo hacer con recentf.  ∴ Por eso lo ignoro (2017)
(ignore '(

          (add-to-list 'load-path "~/.emacs.d/session/lisp/")
          (require 'session)
          (setq session-save-file "~/.emacs.d/auto-save-list/sesión")
          ;; Parece que el 9.12.2008 falla porque el fichero de sesión contiene al final de una lista larga la cadena ... que hace que pete al cargar. Borrando el fichero de sesión se arregla, pero vuelve a pasar.
          ;; No reactivo session.el porque de momento (m12.2009) no veo la necesidad; tampoco lo conozco mucho
          ;;(add-hook 'after-init-hook 'session-initialize)
          ;; esto ha añadido al menú „File“ dos entradas: „Open...recently changed“ y „Open...recently visited“. Y crea C-x C-/ para saltar a posición anterior. Y M-? en minibúfer hace algo raro

          ;; No me gusta mucho porque lo añade al menú (inaccesible fácilmente)

          ;; Fin de ignoración
          ))

;;;; desktop-save-mode (otro más que hace lo de session y más que recentf, pero éste es más oficial)

;; 25.m8.2009: No me gusta desktop. Lo único que hace es inportunarme con preguntas absurdas que no puedo responder (hasta en modo --batch), y no consigo ninguna utilidad a cambio. Está mal diseñado por muchos motivos, y no controla cosas como el cierre brusco de Emacs, el grabado periódico, o el hecho de abrir varias instancias a la vez.
;; Por tanto, *no quiero usarlo más* hasta que no lo arregle(n).

(ignore '(
          (require 'desktop)
          (setq desktop-dirname "~/.emacs.d/auto-save-list/") ; para que lo grabe 
          (setq desktop-path '("~/.emacs.d/auto-save-list/")) ; para que lo lea.
          ;; Podría enviar informerro a Emacs; ¿por qué hay dos variables para casi lo mismo?

          ;; probado desde 31.1.2009
          (desktop-save-mode 1)

          ))

;; MALFAR: buscar alternativas a desktop, en http://www.emacswiki.org/emacs/SessionManagement ← no lo necesito; mi organización de ventanas es muy flexible
;; Y me toca: criticar a desktop para evitar que otros lo usen

;;;; window-configuration, no es ningún modo pero es alternativa a desktop-save y session
;; MALFAR mucha burocracia y no lo necesito

;; para que no me diga „.emacs:7224:7:Warning: assignment to free variable `confiventá'“
(defvar confiventá)
(defun confiventá-graba () (interactive)
       (setq confiventá (current-window-configuration)) (message "grabada"))
(defun confiventá () (interactive) ; mejor este nombre que confiventá-pon pues tecleo menos
       (set-window-configuration confiventá) (message "puesta"))

;;;; winner-mode
;; http://www.emacswiki.org/emacs/WinnerMode
;; Permite deshacer operaciones de cambios de ventana (partir, escalar, …). No lo necesito por ahora.

;;;; por cierto, tontería: „zone“
;; https://www.emacswiki.org/emacs/ZoneMode
(require 'zone)

;; Lo desactivo, pues tiene fallos que me molestan (ẽ no combina con helm); ver emacs.org
;; (zone-when-idle 120)
;; Lo pruebo otra vez en 2022 pero sigue comportándose chapuceramente
;; (zone-when-idle 0)

;; Instalé zone-select para añadir pritas
;; Para probarlos:
;; M-x zone-select, y con v

;; Añado otro:
(zone-select-add-program #'zone-rainbow)

(zone-select-add-program #'zone-sl)
(zone-select-add-program #'zone-pgm-random-life)

;; Y más:
;; (zone-nyan-preview)

;; Cosas malillas, por mejorarle → ver emacs.org en hacer

;;;; emacs-w3m

;;;;; inicio de ignore de emacs-w3m (para probar, ẽ probar cómo afecta a wl)
;; (ignore '(

;;;;; carga de w3m

;; m9.2012: espero que ya no hará falta, pues algo arreglaron:
(ignore '(
          ;; a fecha de 1.11.2008, veo que Emacs 23 no carga el emacs-w3m de CVS porque falta función charset-id. La defino:
          (defun charset-id (a) 0)
          ;; el problema está en w3m-ccl.el
          ;; por si acaso pongo esto también
          (eval-when-compile
            (defun charset-id (a) 0)
            )
          ;; el problema viene más bien de su uso en:
          ;;  (defconst w3m-ccl-write-euc-japan-character
          ;;    (when (fboundp 'ccl-compile-read-multibyte-character)
          ;;      `((read-multibyte-character r1 r0)
          ;;    (if (r1 == ,(charset-id 'ascii))
          (defun a (pará) 0)
          (a "pedo")
          (a 'símb)

          )) ; fin de ignore

;;(add-to-list 'load-path "~/.emacs.d/emacs-w3m-1.4.4")
;;(require 'w3m-load)
;; Para la versión CVS (pre-2019):
;;(add-to-list 'load-path "~/.emacs.d/emacs-w3m-cvs")
;; En m10.2020 lo borré de mi git

;; Desde ~ m1.2019 el desarrollo ocurre en git. La bajo
(add-to-list 'load-path "/w/emacs-w3m")
(require 'w3m)
;; En emacs 23 no se puede usar emacs-1.4.4; hay que usar CVS.

(defun precarga-w3m-al-arrancar nil
  "Precarga de w3m al empezar, junto con sus requisitos. Al menos es lo que intento"
  (require 'ffap) (require 'w3m-tabmenu) (require 'w3m-bookmark) (require 'w3m-symbol) (require 'w3m-form) (require 'mule-util))
;; (precarga-w3m-al-arrancar) ; desactivado pues hace tiempo que no lo uso

;; para que funcione lo de numerar enlaces con f
(require 'w3m-lnum)

;;;;; activación de w3m como visor de elementos MIME en MUAs como Wanderlust
;; MALFAR: peta un (require 'apel-ver) por fallo en product.el por el 100605 de Emacs; ver emacs.org

;; 28.m7.2010: me está petando wl/ssl.el por lo mismo. Intento corregirlo
;; IS lo he enviado a Wanderlust (ver index.org de hacer); el 4.m8.2010 está en CVS. 
;; 14.m1.2014: lo quito pues parece que en Emacs 24 y wl que uso ya está solucionado. Ver cdv el open-ssl-stream

;; Simplemente:
(require 'mime-w3m)
;; Esto funciona.

;; Esto se pone a nil y no deja salir de Emacs. Lo pongo en un sitio ignorado
(setq mime-situation-examples-file "~/.emacs.d/auto-save-list/mime-example")
;; Esta configuración de Wanderlust hace que mime-acting-condition tenga un valor raro y la apertura de adjuntos sea dolorosa
;; BONUS Ver: http://www.google.com/search?q=%22mime-acting-condition%22&ie=utf-8&oe=utf-8&aq=t

;; Por defecto era esto:
;; (setq mime-view-mailcap-files '("/etc/mailcap" "/usr/etc/mailcap" "~/.mailcap"))
;; Pero no quiero que una lista de sistma corrompa la mía. Prefiero que falle con „no sé abrir esto“ antes que sea muy listo y adivine el programa a usar
(setq mime-view-mailcap-files '("~/.mailcap"))
;; Recargar mailcap:
;;  M-: (mime-view-read-mailcap-files)
;; Entonces mime-acting-condition se actualiza
;; Esto es un poco bruto… (setq mime-acting-condition nil)


;; que salgan botoncillos para bajar cada adjunto, etc. Importante porque le quito la tecla C-cm que hacía eso en sumario de Wl
(setq mime-view-buttons-visible t)

;;;;; configuraciones internas de w3m
;;;;;; directorios y ficheros de perfil, sesión, etc.
(setq w3m-arrived-file "~/.emacs.d/datos-w3m/arrived")
(setq w3m-bookmark-file "~/.emacs.d/datos-w3m/bookmark.html")

(setq w3m-default-directory "~/")
(setq w3m-default-save-directory "~/")

(setq w3m-favicon-cache-file "~/.emacs.d/datos-w3m/favicon")
(setq w3m-favicon-use-cache-file t)

(setq w3m-home-page "about://bookmark/")
(setq w3m-init-file "~/.emacs.d/datos-w3m/empieza")

(setq w3m-profile-directory "~/.emacs.d/datos-w3m")
(setq w3m-session-file "~/.emacs.d/datos-w3m/sessions")

;;;;;; codificación y tipos de contenido
;; esto hace que al abrir eo.wikipedia.org/wiki/Ĵonglado funcione.
(setq w3m-default-coding-system (quote utf-8))

;; viene de „customize“, no sé quién lo puso
(setq w3m-content-type-alist (quote (
                                     ;; importantes
                                     ("text/plain" "\\.\\(?:txt\\|tex\\|el\\)\\'" nil nil)
                                     ;;("text/html" "\\.s?html?\\'" browse-url-kde nil) ; ¿quién puso KDE?
                                     ;;("text/html" "\\.s?html?\\'" browse-url-default-browser nil) ; no, esto busca él solo Mozilla, Firefox, …
                                     ("text/html" "\\.s?html?\\'" browse-url-generic nil)
                                     ;; resto
                                     ("text/sgml" "\\.sgml?\\'" nil "text/plain") ("text/xml" "\\.xml\\'" nil "text/plain")
                                     ("image/jpeg" "\\.jpe?g\\'" ("/usr/bin/display" file) nil) ("image/png" "\\.png\\'" ("/usr/bin/display" file) nil) ("image/gif" "\\.gif\\'" ("/usr/bin/display" file) nil)
                                     ("image/tiff" "\\.tif?f\\'" ("/usr/bin/display" file) nil) ("image/x-xwd" "\\.xwd\\'" ("/usr/bin/display" file) nil) ("image/x-xbm" "\\.xbm\\'" ("/usr/bin/display" file) nil) ("image/x-xpm" "\\.xpm\\'" ("/usr/bin/display" file) nil)
                                     ("image/x-bmp" "\\.bmp\\'" ("/usr/bin/display" file) nil)
                                     ("video/mpeg" "\\.mpe?g\\'" nil nil) ("video/quicktime" "\\.mov\\'" nil nil)
                                     ("application/postscript" "\\.e?ps\\'" ("gs" file) nil) ("application/pdf" "\\.pdf\\'" nil nil)
                                     ("application/xml" "\\.xml\\'" nil w3m-detect-xml-type) ("application/rdf+xml" "\\.rdf\\'" nil "text/plain")
                                     ("application/rss+xml" "\\.rss\\'" nil "text/plain")
                                     ("application/xhtml+xml" nil nil "text/html"))))

;;;;;; configurar w3m como predeterminado
;; creo que es al hacer clic desde modos externos
(setq browse-url-browser-function 'w3m-browse-url browse-url-new-window-flag t)



;; 2.3.2009: decido empezar a usar conkeror para abrir los enlaces, pues es más cómodo que w3m. Aunque no se integra tan bien.
(setq browse-url-generic-program (executable-find "conkeror")
      browse-url-browser-function 'browse-url-generic)
;; además uso ~/.mailcap para especificar mis programas favoritos


;;;;;; protocolo HTTP y forma de pedir las páginas
;; importante pero me identifica. Bueno, el hecho de usar emacs-w3m también me identifica :-)
(setq w3m-accept-languages (quote ("eo;q=1.0" "de;q=0.9" "ca;q=0.8" "es;q=0.7" "en;q=0.6")))
;; eso equivale a cadena Accept-Language: eo;q=1.0, de;q=0.9, ca;q=0.8, es;q=0.7, en;q=0.6
;; lo actualizo:  eu;q=1.0, eo;q=0.9; de;q=0.8, ca;q=0.7, es;q=0.6, en;q=0.5
;; esto lo puedo poner en Mozilla/Conkeror: intl.accept_languages (about:config), por defecto: "en-us, en" (qué personas tan agradables las que pusieron eso…)

(setq w3m-enable-google-feeling-lucky nil)

;;;;;; información de depuración de w3m
;; esto hace que w3m muestre menos mensajes mientras se está cargando la página. ¡Así es mucho más rápido!

;;(defalias 'w3m-message 'ignore)
;; Esta solución es guarra y me pierdo algunos mensajes importantes (ej: los que dicen que un enlace no se abre por no ser seguro). He de buscar alguna forma de quitar sólo los triviales

;; prueba:
;;(defun w3m-message (&rest args) "Registra el mensaje para saber qué tipo de cosas se escriben mediante esta función"
;;(message "%s" (mapconcat 'identity (cons "Un mensaje por w3m-message" args) ":: ")) )

;;;;;; al editar campos de texto
(setq w3m-form-input-textarea-buffer-lines 15)
(setq w3m-form-textarea-edit-mode (quote orgstruct-mode))

;;;;; cookies
;; Esto funciona
(setq w3m-use-cookies t)

(setq w3m-cookie-accept-bad-cookies t)
(setq w3m-cookie-accept-domains (quote ("gmail.com" ".gmail.com" "google.com" ".google.com" "google.de" ".google.de" "google.es" ".google.es" "www.google.com" "mail.google.com")))
(setq w3m-cookie-file "~/.emacs.d/datos-w3m/cookie")
(setq w3m-cookie-reject-domains nil)


;; Pero el w3m estaba recibiendo el parámetro -no-cookie, que no sé qué es (quizás emacs-w3m lo pasa para adjudicarse la gestión de las galletas evitando que sea w3m el gestor).
;; Encontré este código, pero esto genera -cookie -no-cookie
;;(when w3m-use-cookies
;;  (setq w3m-command-arguments (append '("-cookie") w3m-command-arguments)))
;; y no sé de qué sirve esto:
;;(add-hook 'kill-emacs-hook
;;          #'(lambda ()
;;             (when w3m-use-cookies
;;               (w3m-cookie-shutdown))))
;; ¡esas dos cosas no deberían hacer falta! Alguien dijo 24.6.2008 que las ponía a mano


;;;;; proxy 
;; Usando proxy, gmail.com no detecta cookies. Pongo google.com por necesidad
(setq w3m-no-proxy-domains (quote ("gmail.com" "mail.google.com" "google.com")))


;;;;; navegación más rápida por enlaces

;; y esto para ir más rápido, al estilo „f“ en conkeror.
(defun jao-w3m-go-to-linknum ()
  "Turn on link numbers and ask for one to go to."
  (interactive)
  (let ((active w3m-link-numbering-mode))
    (when (not active) (w3m-link-numbering-mode))
    (unwind-protect
        (w3m-move-numbered-anchor (read-number "Anchor number: "))
      (when (not active) (w3m-link-numbering-mode)))))

(define-key w3m-mode-map "f" 'jao-w3m-go-to-linknum)


;;;;; faces para enlaces

;; faces para enlaces. Va bien que sea suave proque si no brilla mucho. Va bien que esté subrayado para reconocerlos rápido y saber su alcance. Así resulta mucho más cómodo leer.
(set-face-foreground 'w3m-anchor "light sea green")
(set-face-underline 'w3m-anchor t)

;; Los visitados quedan del mismo color pero sin subrayar. Así no molestan mucho pero se reconocen cuando hace falta
(set-face-foreground 'w3m-arrived-anchor "light sea green") ; era "LightSkyBlue", muy brillante


;;;;; configuración de imágenes

;; Me gustaría ver las imágenes grandes en un editor externo
;; (o que emacs-w3m me permita desplazar la página)
;; Pero no sé cómo hacerlo
;; En realidad puedo hacer , . y C-n C-p para desplazarme. Y M-[ para reducir
;;Esto no existe:  (setq mm-inline-large-images 0)

;; Por defecto quiero imágenes; se conmuta con „T“
(setq w3m-default-display-inline-images t)


;;;;; usar barra de pestañas

;; No sé qué es la „toolbar“; quizás lo que hace que arriba se vean menús „w3m - Bookmark - Tab“
;; (setq w3m-use-toolbar t)
;; Pero esta línea quita la de pestañas y deja sólo un título
;; (setq w3m-use-tab nil)
(setq w3m-use-tab t)
;; Y ésta hace que no se parta la pantalla en dos sino que se abra un búfer nuevo
(setq w3m-pop-up-windows nil)
;;;;;; colores para barra de pestañas
(set-face-attribute 'w3m-tab-background nil :background "gray10") ; era: LightSteelBlue
(set-face-attribute 'w3m-tab-selected nil :background "#883" ; era: Gray90
                    )
(set-face-attribute 'w3m-tab-unselected nil :background "#440" ; era: ... no sé
                    :foreground "#aa3" ; era ... no sé
                    )
(set-face-attribute 'w3m-tab-mouse nil :background "gray10" ; era: gray75
                    :foreground "gray80" ; era white
                    )
(set-face-attribute 'w3m-tab-selected-retrieving nil :background "orange" ; era: gray90
                    :foreground "black" ; era red
                    )
(set-face-attribute 'w3m-tab-unselected-retrieving nil :background "#d50" ; era: gray70
                    :foreground "black" ; era OrangeRed
                    )
;; ésta es la parte derecha inocupada de la barra de pestañas, pero sólo cuando se pasa el ratón por encima
(set-face-attribute 'w3m-tab-selected-background nil :background "black" ; era: LightSteelBlue
                    :foreground "yellow" ; era black. No veo dónde se usa
                    )
;; Están todas las faces.

;;;;; funciones para abrir pestañas

;; esto me permite abrir una pestaña con una sola tecla („t“, definida arriba)
(defun w3m-new-buffer nil
  "Opens a new, empty w3m buffer.
   As opposed to `w3m-copy-buffer', which opens a non-empty buffer.
 This ought to be snappier, as the old buffer needs not to be rendered.
 To be quite honest, this new function doesn't open a buffer completely
 empty, but visits the about: pseudo-URI that is going to have to
 suffice for now."
  (interactive)
  (w3m-goto-url-new-session "about://"))

;; se lo asignaré a T. Es como S-RETURN pero no me lleva a la pestaña nueva
(defun w3m-abre-en-pestaña-trasera nil
  "Abre el enlace actual en una pestaña nueva pero sin conmutar hacia allá. La pestaña queda en 2º plano."
  (interactive)
  (let ((w3m-new-session-in-background t))
    (w3m-view-this-url-new-session))
  )


;;;;; funciones de búsqueda (S)

;; lo añado para buscar en Wiktionary con W
(defun w3m-search-wiktionary  nil
  "Pregunta palabra y hace w3m-search pasando „wiktionary“ como parámetro"
  (interactive)
  (w3m-search "wiktionary" 
              (w3m-search-read-query
               "Suche in Wikiwörterbuch: "
               "Suche in Wikiwörterbuch (leer = %%s): " )
              )
  )
(defun w3m-search-wikipedia  nil
  "Pregunta palabra y hace w3m-search pasando „wikipedia“ como parámetro"
  (interactive)
  (w3m-search "wikipedia" 
              (w3m-search-read-query
               "Name des Wikipedia-Artikels: "
               "Wikipedia-Artikel (leer = %%s): " )
              )
  )

;; Lista de buscadores. Viene de „customize“.  Por unir 
(setq w3m-search-engine-alist (quote (("yahoo" "http://search.yahoo.com/bin/search?p=%s" nil)  ("google" "http://www.google.com/search?q=%s" nil)  ("google groups" "http://groups.google.com/groups?q=%s" nil)  ("wiktionary" "http://de.wiktionary.org/wiki/Spezial:Suche/%s" utf-8) ("wikipedia" "http://de.wikipedia.org/wiki/%s" utf-8) ("Reta vortaro" "http://reta-vortaro.de/cgi-bin/sercxu.pl?sercxata=%s" utf-8))))

;;;;; fin de ignore de emacs-w3m (para probar)
;; ))

;;;; emms
;; Tengo que aprenderlo más; es muy bueno porque es Emacs ← ¡pero hay otros que también son Emacs y son mejores!
(ignore '(  ; 4.m5.2013: ya no lo uso; ver mingus etc.
;;;;; carga inicial
          ;; si uso el de debian no me hace falta estas 2 cosas:
          (add-to-list 'load-path "~/.emacs.d/emms-git/")
          (require 'emms-setup)

          (emms-all) ; así vienen más cosas que con (emms-standard)

          (require 'emms-volume) ; ¿por qué se lo dejó?

          
          (require 'emms-player-mpg321-remote)                                                              
          ;; (require 'emms-player-mpd)
          
;;;;; Sitio para los ficheros
          (setq emms-cache-file "~/.emacs.d/emms-listas/cache")
          (setq emms-history-file "~/.emacs.d/emms-listas/history")
          (setq emms-score-file "~/.emacs.d/emms-listas/scores")

          (setq emms-stream-bookmarks-file "~/.emacs.d/emms-listas/radios")

          (setq emms-directory "~/.emacs.d/emms-listas/") ; pues parece que me las graba en otro lado

;;;;; Reproductores a usar (mplayer, mpg321, …) 
          (setq emms-player-list 
                ;;'(emms-player-mpg321-remote emms-player-ogg123 emms-player-mplayer-playlist emms-player-mplayer))
                ;;'(emms-player-mpd emms-player-mplayer-playlist emms-player-mplayer))
                ;;'(emms-player-mpg321-remote emms-player-mplayer-playlist emms-player-mplayer)) ; ogg123 malestas ĉar ne salteblas; do mplayer plibonas
                ;; ĉar mpd malfunkcias („*** glibc detected *** /usr/bin/mpd: free(): invalid pointer: 0x09445e74 ***“,   vidu Música.org) mi maluzos ĝin
                ;;'(emms-player-mplayer-playlist emms-player-mplayer emms-player-mpg321-remote))
                ;; Otra opción es: (emms-default-players)
                ;; aniŋ mpg321 maŋ taa kendeke; a maŋ beteyaa :-( bari nte a lafita. Wulatinna mplayer fisiyaata fanaŋ.

                ;; MALFAR: configurar bien para mpd. Se hace con emms-player-mpd-connect
                '(emms-player-mpd emms-player-mplayer-playlist emms-player-mplayer emms-player-mpg321-remote)
                )


;;;;; Directorios de música
          ;; La música viene de aquí
          (setq emms-source-file-default-directory "/142857")

;;;;; Listas de reproducción
          ;; no quiero que al grabar me pregunte el tipo de lista; muy pocas veces usaré m3u/pls, así que el nativo me va bien
          (setq emms-source-playlist-default-format 'native)

          ;; Entre canción y canción quiero que se espere un ratito
          (setq emms-player-delay  2)
          ;; Puedo poner un  ruididito aquí que me indique que ha habido un cambio
          ;; ¡¡¡¿me está bloqueando emacs todo ese rato?!!! (2 segundos)

;;;;; Información que se muestra
          (setq emms-show-format "EMMS: %s")
          ;;Any "%s" is replaced by what `emms-track-description-function' returns
          ;;for the currently playing track.

          ;; Qué línea se muestra en lista de reproducción
          ;;(setq   emms-track-description-function #'emms-info-track-description)
          ;; De momento uso el nombre de fichero debido a los problemas UTF-8 que tiene emms-info-track-description
          (setq   emms-track-description-function #'emms-track-simple-description)
          ;; Falta encontrar la forma de representación buena, análaga a emms-info-track-description. Eso es:
          ;; - Si la canción tiene metadatos para título y artista, y son completos (no vacíos, no „Unknown) y además válidos (UTF-8), usar éstos
          ;; - Si no, fabricar un nombre basado en el nombre de fichero


          ;; Ya está en „all“, creo...:
          ;; (require 'emms-mode-line)


          ;; Quiero que muestre el nombre de la canción tocada en la barra de abajo (penúltima fila)

          ;; Yo le defino cómo se tiene que mostrar
          ;; Original:
          ;;(defun emms-mode-line-playlist-current ()  "Format the currently playing song."
          ;;  (format emms-mode-line-format (emms-track-description (emms-playlist-current-selected-track))))
          (defun emms-mode-line--muestra-nombre-corto () 
            "muestra la información necesaria pero no más; sin ruta ni extesión"
            (let* (
                   (nombre-entero (emms-track-description (emms-playlist-current-selected-track)))
                   (título-canción (file-name-sans-extension (file-name-nondirectory nombre-entero)))
                   )
              (if (equal "lovic" (system-name))
                  ;; algo más discreto en trabajo
                  (format "⊰%s⊱" (substring (file-name-nondirectory (emms-track-simple-description (emms-playlist-current-selected-track))) 0 2))

                ;; en casa, más bonito
                (format
                 ;; "⊰ ·♬%s ⊱"
                 ;; Interesante también: ͼ  ͽ, Ͼ    Ͽ, ᑽ ᒀ, ᕳ ᕲ, ⋐  ⋑, ❨    ❩, ♬
                 ;; "·♬%s·"
                 " ⊰%s♬⊱ "
                 (emms-abrevia-título título-canción)
                 )
                )
              ))
          ;; Esto afecta sólo al nombre, no al indicador de posición de detrás
          (setq emms-mode-line-mode-line-function 'emms-mode-line--muestra-nombre-corto)

          (defun emms-abrevia-título (título)
            "Reduce la longitud del nombre de una canción, usando acrónimos de artistas si hace falta"

            (let* ((case-fold-search t)
                   (título (replace-regexp-in-string "jean.michel.jarre" "JMJ" título))
                   (título (replace-regexp-in-string "tangerine.dream" "TD" título))
                   (título (replace-regexp-in-string "kraftwerk" "KRA" título))
                   (título (replace-regexp-in-string "mike.oldfield" "MO" título))

                   )
              título

              )
            )

          ;; Activar este modo. Desactivar: (emms-mode-line 0)
          (emms-mode-line 1)
          ;; Sospecho que esto puede causar el problema del „Summary superrefrescante“ (buscar eso aquí), aunque no tengo pruebas…

          ;; Lo que hay ahí en la línea de modos es emms-playing-time-string; pero no consigo quitarlo más. Ver variable global-mode-string
          ;; No quiero que muestre el contador de segundos en toda ventana en la barra de abajo
          ;; De momento lo desactivo.
          ;;(if (equal "lovic" (system-name))
          (setq emms-playing-time-display-p nil)
          ;;)
          ;; IS Activar a veces:
          ;; - no → pero quizás sólo en la ventana de EMMS (pues es importante), pero no en todas.  (setq emms-playing-time-display-p t)
          ;;- IS: Me he puesto tecla „.“ para verlo temporalmente

          ;; De todas formas, cuando se muestra, lo quiero completo, tipo „01:30/4:20“. ← Ah, creo que ya va

          ;; Lo muestra patéticamente mal. Ej. manteniendo „.“ apretado un rato, ¡corre!

;;;;; Flujos y canales de radio
          (setq emms-stream-default-action "play") ; en vez de "add", que se hace con „a“ y lo añade a la lista
          (require 'emms-stream-info)

;;;;; Interfaz completa

          ;; Describir cómo se accede al „cuadro de mandos“ completo de EMMS, si es que tiene. O buscar una otra interfaz. Está en mi ~/hacer/

          ;; De momento, las funciones útiles son (o parecen ser):
          ;; emms-show
          ;; emms-player-mpd-show
          ;; emms-browser ← sí que es una interfaz para explorar los artistas, álbumes, buscar en Wikipedia, … Pero es patética, incompleta, fallante y poco apropiada para mí. En concreto, sólo funciona si todas las canciones están bien etiquetadas, cosa que para mí no es importante y no lo hago.

          (defun emms-con-interfaz ()
            "Mi entrada a emms"
            (interactive)
            (if (or (null emms-playlist-buffer)
                    (not (buffer-live-p emms-playlist-buffer)))
                ;; quizás puedo dejar la lista grabada
                (emms-add-directory-tree "/142857"))
            (emms-playlist-mode-go)
            )


          (define-key acceso-funciones-varias-map (kbd "C-s") 'emms-playlist-mode-go)

          ;; hasta que no entienda lo de las varias listas, mejor no activo esto
          ;;(define-key acceso-funciones-varias-map (kbd "C-s") 'emms-con-interfaz)

          ;; esto lo necesito yo mucho:
          (define-key acceso-funciones-varias-map (kbd "C-/") 'emms-pause)
          (define-key acceso-funciones-varias-map (kbd "C-_") 'emms-pause) ; para terminal


          ;; Las teclas < y > se mueven alante y atrás, y muestran un poco de información temporalmente
          (defun emms-seek-forward ()
            "Seek ten seconds forward."
            (interactive)
            (when emms-player-playing-p
              (emms-player-seek emms-seek-seconds)
              (let ((emms-playing-time-display-p t)) (emms-playing-time-display))
              ;;(message "palante")
              ))

          (defun emms-seek-backward ()
            "Seek ten seconds backward."
            (interactive)
            (when emms-player-playing-p
              (emms-player-seek (- emms-seek-seconds))
              (let ((emms-playing-time-display-p t)) (emms-playing-time-display))
              ;;(message "patrás")
              ))



;;;;;; emms-browser
          ;; Lo he usado un poco pero no lo suficiente
;;;;;; fin del ignore
          ))
;;;; bongo (otro reproductor multimedia)
;; https://github.com/dbrock/bongo, git://github.com/dbrock/bongo.git
;; http://www.emacswiki.org/cgi-bin/wiki/Bongo

;; Probar bongo para sustituir a emms, que no me gusta mucho. Ver música.org

;;;;; desactivado bongo porque mingus me va mejor; además volume.el requería aumix mas uso OSS4
(ignore '(

;;;;; requisitos: volume.el
          ;; https://github.com/dbrock/volume.el
          (add-to-list 'load-path "~/.emacs.d/volume")
          (require 'volume) ; interesante

;;;;; carga
          ;; # /w ; git clone git://github.com/dbrock/bongo.git
          (if (file-directory-p "/w/bongo/")
              (progn
                (message "Cargando Bongo de /w/")
                (setq load-path (cons (expand-file-name "/w/bongo") load-path))
                ;;   (require 'bongo) ; lento hacerlo siempre
                (autoload 'bongo "bongo" "Start Bongo by switching to a Bongo buffer." t)

                )
            (message "No cargo Bongo porque no está en /w/bongo")
            )

;;;;; ajustes de bongo
          (setq bongo-mode-line-indicator-mode nil) ; ¿no tiene efecto?.  „Display a Bongo playback status indicator in the global mode line.“
          (setq bongo-mode-line-indicator-format nil) ; quizás así me hace caso…
          (setq bongo-display-track-icons nil) ; así no cargará ningún icono
          (setq bongo-track-mark-icon-file-name nil) ; así no lo cargará y usará un "*" o algo así, creo
          ;; (bongo-header-line-mode 0) ; „Toggle display of Bongo mode line indicator on or off.“

;;;;; le configuro teclas
          ;; sobreescribo las de emms pues veo a bongo más preparado para lo que quiero
          (define-key acceso-funciones-varias-map (kbd "C-s") 'bongo)
          (define-key acceso-funciones-varias-map (kbd "C-/") 'bongo-pause/resume)
          (define-key acceso-funciones-varias-map (kbd "C-_") 'bongo-pause/resume) ; para terminal

;;;;; fin de ignore
          ))

;;;; mingus (para conectar a mpd)

;; 29.m7.2014: desactivado porque peta (con traza) el demonio de emacs nada más arrancarlo
;; 8.m2.2023: vuelvo a probarlo, pero por ELPA, así que ignoro esto
(ignore '(
(if (and nil (file-directory-p "/w/mingus/"))
    (progn
      (message "Cargando mingus de /w/")
      (setq load-path (cons (expand-file-name "/w/mingus") load-path))
      ;;(autoload 'mingus "mingus" "mingus" t)
      (require 'mingus)
      )
  (message "No cargo mingus porque no está en /w/mingus")
  )
))

(define-key acceso-funciones-varias-map (kbd "C-s") 'mingus)
(define-key acceso-funciones-varias-map (kbd "C-/") 'mingus-pause)
(define-key acceso-funciones-varias-map (kbd "C-_") 'mingus-pause) ; para terminal

(defadvice mingus-crop (around pregunta-antes-de-aislar activate)
  "Pregunta de seguridad"
  (if
      (yes-or-no-p "¿Seguro que quieres aislar esta canción?")
      (ad-do-it)
    )
  )
(ad-enable-advice 'mingus-crop 'around 'pregunta-antes-de-aislar)



(add-hook 'mingus-playlist-hooks
          (lambda ()
            (toggle-truncate-lines 1)
            )         
          )
;;(setq mingus-playlist-hooks nil)

;;;; dired
;;;;; operaciones básicas (copiar/mover/borrar)
;; no hay mucho que cambiar
(setq
 dired-recursive-copies 'always
 dired-recursive-deletes 'top)

;; para pasar de un lado al otro cuando hay ventanas abiertas
(setq dired-dwim-target t)

;; quiero mejor sugerencia al C/R; ver hacer

;;;;; sugerencias al abrir ficheros
;; Quiero mejor sugerencia al hacer ! (para abrir un fichero con programa externo). 
;; De hecho una sola tecla me bastaría, sin sugerencia ni nada, para /abrir/ el fichero con el programa que diga mailcap
;;
;; Copio dired-guess-shell-alist-default pero con mis programas y comandos
(setq dired-guess-shell-alist-user '(
                                     ("\\.pdf$" "evince")
                                     ;;("\\.pdf$" "mupdf")

                                     ;; ("\\.wmv$" "gmplayer")
                                     ("\\.wmv$" "mpv")
                                     ("\\.wmv$" "mpv")
                                     ("\\.webm$" "mpv")
                                     ("\\.avi$" "mpv")
                                     ("\\.mov$" "mpv")
                                     ("\\.mp4$" "mpv")

                                     ("\\.jpe?g$" "sxiv")
                                     ("\\.png$" "sxiv")
                                     ("\\.gp[345]$" "tuxguitar")
                                     ;;("\\.html$" "conkeror") ; no va, abre www.index.html
                                     ("\\.html$" (concat "conkeror file://" (expand-file-name file) ";#")) ; el #; ignora el parámetro pasado. Va
                                     ))
;; todos fallan con nombres con espacios; creo que no es culpa mía




;;;;; dired-x ofrece varias cosas necesarias (¡que deberían estar en dired!)
;;;;;; no acepto que me quite C-x C-j
;; qué bien, hay opción para esto
;; (setq dired-bind-jump nil)
;; :-( parece que no va, porque en este punto dired-x ya está cargado por otros → lo pongo antes (en concreto antes de anything-config)

;;;;;; carga
;;(message "¿Dired-x cargado?: «%s»" (featurep 'dired-x))
;; mmm… anything-config lo ha cargado ya antes que yo
(require 'dired-x)

;; Eso aporta varias cosas:
;; dired-omit-mode, …

;;;;;; pero sí que quiero dired-jump (lo que había en C-x C-j) para abrir un dired apuntando al búfer actual
(define-key acceso-funciones-varias-map (kbd "C-m") 'dired-jump)
;; Si me falla, probar también (kbd "RET") ← es lo mismo, parece

;;;;; omitir ficheros (ej: ficheros ocultos). Lo hace dired-x

;; Omitir .ocultos
(setq dired-omit-files
      (concat dired-omit-files "\\|^\\..+$"))
;; le asocio C-c C-o (estaba libre) porque lo voy a usar mucho
(define-key dired-mode-map (kbd "C-c C-o") 'dired-omit-mode)


;;;;; extensiones gnus-dired para hacer cosas como „abrir con el programa por defecto“, adjuntar, …
(require 'gnus-dired) ;, isn't needed due to autoload cookies
(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)

;; esto aporta
;; C-cC-mC-a (adjuntar), C-cC-mC-l (abrir en externo), C-cC-mC-p (¡imprimir!¡no usar!)
;; acostumbrarme a C-cC-mC-l

;;;;; dired-tar para comprimir directorio a .tar.gz
;; algo viejo pero va. „T“ en dired normal
(setq load-path (append (list "~/.emacs.d/dired-tar") load-path))
(require 'dired-tar)
;;;;; dired-filetype-face para ver ejecutables en verde
;; De: http://www.emacswiki.org/emacs/dired-filetype-face.el
(setq load-path (append (list "~/.emacs.d/dired-filetype-face") load-path))
;;(require 'dired-filetype-face)
(eval-after-load 'dired '(progn (require 'dired-filetype-face)))
;; falta configurar colores

;;;;; image-dired, para ver fotos, miniaturas, …
;; Es el visor de imágenes más prometedor que tengo. Ver Imagen.org
(require 'image-dired) ; ya lo cargo para poder sobreescribirle funciones

(setq image-dired-external-viewer "/usr/bin/sxiv") ; era display


;;;;;; forma de verse las miniaturas
(setq image-dired-thumb-size 130) ; era 100

(setq image-dired-line-up-method 'fixed) ; en forma de tabla. Así tiene mucho sentido el C-p y C-n, pues sé de antemano a dónde me llevarán. El original ('dynamic) me pierde el cursor sólo tras hacer arriba+abajo repetidamente → no monotónico. Y el ~'no causa que estén en una sola línea, por tanto no hay C-n/C-p posible
(setq image-dired-thumbs-per-row 5) ; era 3; voy probando

;;;;;; el forward-line me ha de dejar en la misma columna de la siguiente fila
;; MALFAR: esto no me hace falta, pues previous-line/next-line ya iban bien. Era forward-line la que me dio problemas
(ignore '(
          ;; Necesito estas dos funciones (qué raro que las necesite, pues previous-line/next-line en general lo hacen bien)
          (defun previous-line--pero-sin-cambiar-de-columna ()
            (interactive)
            (let ((col-inicial (current-column)))
              (forward-line -1)
              (move-to-column col-inicial)))
          (defun forward-line--pero-sin-cambiar-de-columna ()
            (interactive)
            (let ((col-inicial (current-column)))
              (forward-line)
              (move-to-column col-inicial)))
          ))

;; sobreeescribo dos funciones para usar next-line/previous-line en vez de forward-line. Las primeras me mantienen columna, la 2ª no
(defun image-dired-next-line ()
  "Move to next line and display properties."
  (interactive)
  (next-line) ;; era: (forward-line 1)
  ;; If we end up in an empty spot, back up to the next thumbnail.
  (if (not (image-dired-image-at-point-p))
      (image-dired-backward-image))
  (if image-dired-track-movement
      (image-dired-track-original-file))
  (image-dired-display-thumb-properties))
(defun image-dired-previous-line ()
  "Move to previous line and display properties."
  (interactive)
  (previous-line) ;; era: (forward-line -1)
  ;; If we end up in an empty spot, back up to the next
  ;; thumbnail. This should only happen if the user deleted a
  ;; thumbnail and did not refresh, so it is not very common. But we
  ;; can handle it in a good manner, so why not?
  (if (not (image-dired-image-at-point-p))
      (image-dired-backward-image))
  (if image-dired-track-movement
      (image-dired-track-original-file))
  (image-dired-display-thumb-properties))

;;;; gnuplot
;; También hay otro en MELPA. Me da igual cuál usar por ahora… Prefiero el que controlo yo
;; Pero pruebo el de MELPA pues el mío me dejó de ir
(ignore '(

          ;;--------------------------------------------------------------------
          ;; Lines enabling gnuplot-mode

          ;; move the files gnuplot.el to someplace in your lisp load-path or
          ;; use a line like
          (setq load-path (append (list "~/.emacs.d/gnuplot-mode.0.6.0") load-path))

          ;; these lines enable the use of gnuplot mode
          (autoload 'gnuplot-mode "gnuplot" "gnuplot major mode" t)
          (autoload 'gnuplot-make-buffer "gnuplot" "open a buffer in gnuplot mode" t)

          ;; this line automatically causes all files with the .gp extension to
          ;; be loaded into gnuplot mode
          (setq auto-mode-alist (append '(("\\.gp$" . gnuplot-mode)) auto-mode-alist))

          ;; This line binds the function-9 key so that it opens a buffer into
          ;; gnuplot mode 
          ;;  (global-set-key [(f9)] 'gnuplot-make-buffer)

          ;; end of line for gnuplot-mode
          ;;--------------------------------------------------------------------
          ;; fin de ignore
          ))

;;;; ESS («Emacs speaks statistics», para hacer de interfaz con R y otros programas de estadísticas)

;; Hace falta: Ai ess
(ignore '( ; de momento no quiero cargarlo siempre, pues me hace lento el inicio (en 1'20 segundos mín)
          (add-to-list 'load-path "/usr/share/emacs/site-lisp/ess/")
          (require 'ess-site)
          ))
;; Esto me proporciona M-x R RET, etc. No lo uso mucho
;; plot(sin,-pi,pi)


;;;; Lanzador de aplicaciones y de acciones
;; 8.2.2009. Hay acciones comunes que repito con frecuencia, como:
;; - desplegar un fichero .war a un servidor de aplicaciones
;; - actualizar mi conkeror/bzr/emacs
;; 
;; - ver cómo puedo automatizar esto de forma integral, en vez de tener que hacerme funciones individuales y asignarlas a teclas.
;; - probar paquete „action groups“ para ver qué es exactamente. No entiendo nada; la documentación parece filosofía escrita en Lisp
;; MALFAR: Puedo usar org-mode en una vista de agenda; ver esa sección ← no, mala idea
;; mejor anything para esto

;;;; Instalador de paquetes: ELPA
;; Parece que la lista de paquetes está en: http://tromey.com/elpa/archive-contents
;; Por ahora (20.m5.2009) me interesa: find-file-in-project, findr, fringe-helper javascript sudoku bubbles
;; y que ya tengo pero puedo migrar: muse emms lua-mode css-mode
;; En m8.2010 ya está integrado en Emacs y en repo oficial veo paquetes: bubbles company erc js2-mode nxml package rainbow-mode url
;; M-x package-…

;; Creo que después me hace falta código como: (sacado de config. de usuario Gwern)
;; esto sirve para activar los paquetes instalados
;;¿? (setq load-path (push "~/.emacs.d/elpa" load-path))
;;(when (require 'package)
;;  (if (fboundp 'package-initialize) (package-initialize)))

(require 'package)

;; Está elpa
;; Está melpa y melpa-stable. Ver en „melpa“

(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/") t)


;;;; remembrance agent
;; Ver notas en org

;;;;; eldav, parecido a tramp pero para WebDav
;; http://www.emacswiki.org/emacs/ElDav

;;; LISP: pruebas con lisp, funciones que intentan hacer algo útil, ejercicios, etc.
;;;; ayudas para al programar y depurar Elisp


(defun párate-aquí nil
  "Se para y deja vía libre para investigar otras cosas.
Va bien para bloquear un proceso; equivale a algo como (debug) pero es más sencilla y chapucera.
"
  (call-interactively 'find-file)

  )

(defun pregunta-si-seguir nil
  "Hace la pregunta de si seguir.
Es una función a la que llamar para ver si la llamada funciona.
También va bien poner un punto de parada aquí, con:
(debug-on-entry 'párate-aquí)
"
  (interactive)
  (y-or-n-p "Estoy parado en párate-aquí. ¿Seguir? ")
  )

;;;; experimento: bustrofedon
;;(load-file "~/.emacs.d/lisp/bustrofedon.el")
(add-to-list 'load-path "~/.emacs.d/lisp/")
(require 'bustrofedon)

(global-set-key (kbd "\C-x <f10>") 'bustrofedon-en-búfer-nuevo)
;; aún tengo que corregirlo un poquillo

;;;; básico: incrementar números
;; Para sumar/restar a un número. ¡Útil para macros!
;; Lo saqué de http://www.blik.it/2008/2/12/emacs-change-number-at-point y retoqué un poco
(load-file "~/.emacs.d/lisp/inc-number-at-point.el")

;;;; básico: anular variable rápidamente
(defun anular-apuntada () "Pone a nil la variable apuntada por el cursor"
       ;;(interactive "vDime cuál variable: ")
       (interactive)
       (let ((varapunt (symbol-at-point)))
         (if varapunt (progn
                        (set varapunt nil)
                        (message (concat (symbol-name varapunt) " puesta a nil"))
                        )
           (message "No encuentro ningún símbolo bajo el cursor.")
           )
         ))
;; ej: muse-project-alist

;;;; conmutar variable
(defun conmuta-variable (x val1 val2)
  "Ej. 'unbooleano 1 0 la hace circular en esos valores."
  (set x (if (equal (eval x) val1) val2 val1))
  )

;;;; básico: transliterar cadena de texto (cambiar unas letras por otras)
(defun transliterate (from to string)
  (let (transliteration-table)

    (setq transliteration-table (make-hash-table))
    (cl-loop for 1from in (string-to-list from)
          for 1to in (string-to-list to)
          do (puthash 1from 1to transliteration-table))
    (dcl--char-list-to-string (mapcar (lambda (ch) 
                                   (or (gethash ch transliteration-table) ch))
                                 (string-to-list string)))
    )
  )
;; esta función faltaba (en m3.2021) y por eso la añadí, para que „transliterate“ vaya
(defsubst dcl--char-list-to-string (charlist)
  "Return the string of CHARLIST.
If CHARLIST is not a list, this function just returns CHARLIST."
  (if (listp charlist) (mapconcat 'char-to-string charlist "") charlist))

;; Probando: (transliterate "aeiou" "AEIOU" "Las vocales ahora son más grandes")
;; más: ver emacs.org

;;;; aprendizaje: función para contar palabras
;; Contar palabras, copiado de un tutorial
(defun count-words-region (beginning end)
  "Print number of words in the region."
  (interactive "r")
  (message "Counting words in region ... ")

  ;; 1. Set up appropriate conditions.
  (save-excursion
    (let ((count 0))
      (goto-char beginning)

      ;; 2. Run the while loop.
      (while (and (< (point) end)
                  (re-search-forward "\\w+\\W*" end t))
        (setq count (1+ count)))

      ;; 3. Send a message to the user.
      (cond ((zerop count)
             (message
              "The region does NOT have any words."))
            ((= 1 count)
             (message
              "The region has 1 word."))
            (t
             (message
              "The region has %d words." count))))))


;;;; cambiar palabras unas por otras
;; de https://www.emacswiki.org/emacs/SwappingText, renombrada
(defun swap-text-in-region (str1 str2 beg end)
  "Changes all STR1 to STR2 and all STR2 to STR1 in beg/end region."
  (interactive "sString A: \nsString B: \nr")
  (if mark-active
      (setq deactivate-mark t)
    (setq beg (point-min) end (point-max))) 
  (goto-char beg)
  (while (re-search-forward
          (concat "\\(?:\\b\\(" (regexp-quote str1) "\\)\\|\\("
                  (regexp-quote str2) "\\)\\b\\)") end t)
    (if (match-string 1)
        (replace-match str2 t t)
      (replace-match str1 t t))))

;;;; aprendizaje: sumar las cifras de un número
(defun suma-cifras (núm)
  (interactive)
  ;; un poco patético lo del -48…
  ;;(cl-loop for l in (string-to-list "333") sum (- l 48))
  (cl-loop for l in (string-to-list (number-to-string núm)) sum (- l 48))
  )
;;(suma-cifras 123)


(defun media-aritmética (lista)
  (/ 
   (apply '+ lista)
   (float (length lista))
   )
  )
;;(media-aritmética '(1 2 3))
;;(media-aritmética '(1 2 3.1))
;;(media-aritmética '(1 2 4))


;;;; una para cambiar el portapapeles
(defun set-clipboard-contents-from-string (str)
  "Copy the value of string STR into the clipboard."
  (let ((select-enable-clipboard t))
    (gui-select-text str)))


;;;; función que da sublista
;; ¡que esto se integre en algún paquete de Emacs → puesto en „hacer“
;; Encontrado por ahí, en http://osdir.com/ml/help-gnu-emacs-gnu/2009-11/msg00484.html
(defun sublist (list from &optional to)
  "Return a sublist of LIST, from FROM to TO.
If END is omitted, it defaults to the length of the sequence.
Counting starts at 0. Like `subseq' and `substring' but solely for
lists."
  (let ((start (nthcdr from list))) ;start reference
    (if to (butlast start
                    (- (+ from (length start)) ;if extract list at the end this makes it much faster
                       to))
      start)))

;;;; función para definir teclas locales a búfer (¡a búfer!, no al modo mayor del búfer)
;; Sacada de http://www.emacswiki.org/emacs/BufferLocalKeys
(defun buffer-local-set-key (key func)
  (interactive "KSet key on this buffer: \naCommand: ")
  (let ((name (format "%s-magic" (buffer-name))))
    (eval
     `(define-minor-mode ,(intern name)
        "Automagically built minor mode to define buffer-local keys."))
    (let* ((mapname (format "%s-map" name))
           (map (intern mapname)))
      (unless (boundp (intern mapname))
        (set map (make-sparse-keymap)))
      (eval
       `(define-key ,map ,key func)))
    (funcall (intern name) t)))

;;;; copiar la ruta actual del fichero editado
(defun copia-ruta-actual-del-fitxer ()
  "Quan al búfer actual s'està visitant un fitxer, troba la ruta completa al disc dur d'aquest fitxer, i la copia al portapapers d'X. A més la copia a l'anella normal de retalls"
  (interactive)
  (if (buffer-file-name)
      (progn 
        (kill-new (buffer-file-name)) ; extra: el copia també a l'anella normal (¬X)
        (message (set-clipboard-contents-from-string (buffer-file-name)))
        )
    (message "No hi ha associat un nom de fitxer de disc")
    )
  )
(define-key acceso-funciones-varias-map (kbd "m") 'copia-ruta-actual-del-fitxer) ; parecido a C-x C-j C-m, que me va a directorio padre, pues es lo que uso a veces para ver dónde estoy
;; a veces esta asociación se pierde, creo que es por evaluar dos veces el .emacs

;; en dired hay algo parecido:
;;   w: copia nombre
;;   C-u 0 w: copia ruta entera
;; Iría mejor algo como simplemente „c“ para copiar el nombre. Lo pongo:
(define-key dired-mode-map "c" (lambda nil (interactive) (dired-copy-filename-as-kill 0)))

;;;; renombrar el fichero editado actualmente

;; Yo lo saqué de http://en.wikipedia.org/wiki/User:Gwern/.emacs
;; http://www.cabochon.com/~stevey/blog-rants/my-dot-emacs-file.html
(defun rename-file-and-buffer (new-name)
  "Renames both current buffer and file it is visiting to NEW-NAME."
  (interactive "sNew name: ")
  (let ((name (buffer-name))
        (filename (buffer-file-name)))
    (if (not filename)
        (message "Buffer '%s' is not visiting a file!" name)
      (if (get-buffer new-name)
          (message "A buffer named '%s' already exists!" new-name)
        (progn
          (rename-file name new-name 1)
          (rename-buffer new-name)
          (set-visited-file-name new-name)
          (set-buffer-modified-p nil))))))
(global-set-key "\C-x\ W" 'rename-file-and-buffer)
;; me falta acostumbrarme a usarlo

;;;; reevaluar fichero .el (desevaluando antes los defcustom etc.)
;; ¡Qué bueno! Justo lo que quería. Usa (makunbound 'variable) y (fmakunbound 'función) para desvincular variables.
;; https://github.com/davep/nukneval.el
(add-to-list 'load-path "~/.emacs.d/lisp")
(require 'nukneval)

;;;; completado de palabras (con M-/) y abreviaciones
;;;;; usar helm para esto. Vale la pena, es mucho más útil
(define-key global-map [remap dabbrev-expand] 'helm-dabbrev)
;; BONUS ¿por qué no me completa cosas Lisp cuando estoy en .py?
;; Ej. (helm-dabbrev--get-candidates "org-expor") ← va desde .emacs, pero no va desde .py.
;; Por lo visto desde el .py está limitado a cosas que aparecen en los .py
;; Curioso pues helm-dabbrev-always-search-all es t
;; la línea „(if (and (not helm-dabbrev-always-search-all)“ me intriga. Supongo que (funcall dabbrev-get abbrev helm-dabbrev-always-search-all) ya debía haber hecho todo el trabajo
;; [ ] por tanto fijarme en helm-dabbrev--collect al depurar. Depurar esa función, y fijarme en el parámetro „all“ (que es t, como debe ser)

;;;;; qué se considera una palabra completable
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_\\|+") ; según docu, "\\sw\\|\\s_" es recomendado
;; el + lo quiero fuera de mis compleciones.
;; Probar aquí: pizarra casita paraguas+pizar  (ha de completar ra en vez de quejarse

;;;;; copiar palabras que siguen al hallazgo (con M-/)

;; 18.7.2007: cosa muy útil pero que aún me gustaría mejorar más
(defun copia-palabra-que-sigue-al-hallazgo (arg)
  "Como M-/ pero ampliado. Busca la palabra que estaba a medio escribir, por el documento actual (y otros), la completa, y entonces si se vuelve a llamar a esta función sigue copiando palabras que están adyacentes por la derecha a la palabra que se encontró"
  (interactive "*P") (progn  (dabbrev-expand t)(insert " ")))
;; Me parece que esto funcionaba solo, haciendo M-/ M-espacio M-espacio M-espacio… (o algo así). Pero dejó de funcionar cuando instalé helm, pues helm mejora (y bastante) el M-/

;; Lo tenía en M-?, pero M-¿ es mucho más fácil de teclear. Además M-? es para xref-find-references
(global-set-key (kbd "M-¿") 'copia-palabra-que-sigue-al-hallazgo)

;; está hippie-expand, que hace cosas de éstas, pero creo que con yasnippet ya me vale

;;;;; abreviaciones (una palabra se expande a algo más largo)
;; pues no hace falta nada especial, por ahora. Tengo que aprender más pero.
;; funcionamiento de abbrev-mode:
;; Escribir línea, C-x a i g, y luego entrar en abbrev-mode. Al teclear la palabrita se expande a la línea.

;; si quiero abreviaciones globales (tipo: mi web) → yasnippet
;; O mejor: usar abbrev-mode con „skeleton“
;; Por ejemplo:

(define-skeleton skel-org-block
  "Insert an org block, querying for type."
  "Type: "
  "#+begin_" str "\n"
  _ - \n
  "#+end_" str "\n")

(define-abbrev org-mode-abbrev-table "sblk" "" 'skel-org-block)
;; hay que activar M-x abbrev-mode entonces

(define-skeleton skel-wl-miweb
  "Miweb"
  nil
  "http://www.danielclemente.com/")

(define-abbrev wl-draft-mode-abbrev-table "miweb" "" 'skel-wl-miweb)
;; lo mismo, hay que activar ese modo


;;;; unfill-paragraph: pasar de „líneas rotas“ a párrafos normales

;; esto es incluíble en Emacs; lo propuso Lennart Borgman en 5.m8.2009. Pero no es tarea mía

;; ¿qué es este maldito „fill“/„unfill“? Ver org

;; Unfilling
;;
;; The idea is from
;;   http://interglacial.com/~sburke/pub/emacs/sburke_dot_emacs.config

;; ;;;###autoload
(defun unfill-paragraph ()
  "Unfill the current paragraph."
  (interactive) (with-unfilling 'fill-paragraph))
;;(defalias 'unwrap-paragraph 'unfill-paragraph)

;; ;;;###autoload
(defun unfill-region ()
  "Unfill the current region."
  (interactive) (with-unfilling 'fill-region))
;;(defalias 'unwrap-region 'unfill-region)

;; ;;;###autoload
(defun unfill-individual-paragraphs ()
  "Unfill individual paragraphs in the current region."
  (interactive) (with-unfilling 'fill-individual-paragraphs))
;;(defalias 'unwrap-individual-paragraphs 'unfill-individual-paragraphs)

(defun with-unfilling (fn)
  "Unfill using the fill function FN."
  (let ((fill-column 10000000)) (call-interactively fn)))

;;;; quitar propiedades a texto
;; De: http://stackoverflow.com/questions/8372722/print-only-text-discarding-text-properties
(defun strip-text-properties(txt)
  (set-text-properties 0 (length txt) nil txt)
  txt)
;;;; kill-until-end-of-buffer, útil para hacer búsquedas dicotómicas de algo en fichero
(defun kill-until-end-of-buffer (&optional arg)
  (interactive "P")
  (kill-region (point) (point-max))
  )

;;;; cargar otros ajustes que dependen del proyecto en el que esté
;; Ajustes que dependen de mi proyecto actual
;; Es sobre todo un:   (global-set-key [f11] #'(lambda () (interactive) (find-file "~/org/miproyectoactual.org")))
(load-file "~/.emacs.d/lisp/trabajo.el")

;; Ajustes privados (ẽ claves). No las quiero en .emacs porque este .emacs quizás lo pongo en ordenadores que no son míos
;; Si te interesan, has de colarte en mi ordenador. Pero por favor, si entras ¿puedes mirar la lista de artículos que tengo a medio escribir, y ayudar a acabar alguno y a publicarlo? Serán más interesantes que estos ficheros Lisp
(load-file "~/.emacs.d/lisp/privado-nocable.el") ;; nivel de privacidad 2 („nolom“)
(load-file "~/.emacs.d/lisp/privado-claves.el") ;; nivel de privacidad 3 („priv“)
;; (este fichero .emacs es nivel 1 („miaj“))


;;;; funciones para temas matemáticos, financieros y estadísticos

(defun calcula-tantoporciento ()
  "Dados dos valores A y B, calcula la diferencia en % desde A hasta B y desde B hasta A.
Ej. para 2 y 3:   De A a B: 50.000000%.  De B a A: -33.333333%
Útil para saber cuán grande es un movimiento concreto entre 2 puntos. 
"
  (interactive)
  (let*
      (
       (núm1 (float (string-to-number (read-from-minibuffer "Núm1 (ẽ cantidad en monedas, en positivo): "))))
       (núm2 (float (string-to-number (read-from-minibuffer "Núm2 (ídem): "))))
       )
    (message "De A a B: %f%%.  De B a A: %f%%. Además, A es us %f%% de B, y B es un %f%% de A. Y por cierto la dif.abs. es %f."
             ;;  Y si aplico A y luego B al nº 100: 100→%f%%→%f%%. Y si B y luego A: 100→%f%%→%f%%  → ver en Economía.org tabla org
             (* 100 (/ (- núm2 núm1) núm1))
             (* 100 (/ (- núm1 núm2) núm2))
             (* 100 (/ núm1 núm2))
             (* 100 (/ núm2 núm1))
             (abs (- núm1 núm2))
             )
    ))
;; prueba (calcula-tantoporciento 0.15 -0.17)


(defun aplica-serie-de-variaciones (a-qué-número lista-variaciones)
  "Aplica sucesivamente las variaciones dadas al número dado.
Ej. aplicando a 100 un +10% -50% = da 110 55.
La lista devuelta no incluye el parámetro pasado.
"

  (cl-loop for tpc in lista-variaciones
        with valor = a-qué-número
        ;;do (print (* (1+ (/ tpc 100.0)) valor))
        ;;do (print (setq valor (* (1+ (/ tpc 100.0)) valor)))
        collect (string-to-number (format "%.2f" (setq valor (* (1+ (/ tpc 100.0)) valor))))
        )
  )
;;(aplica-serie-de-variaciones 100 '(0 -11 -38))
;;(aplica-serie-de-variaciones 100 '(0 -11 -38 6 1 19 1 -9 -44))

;; Impuesto escalonado
(defun impuesto-progresivo-iin-en-letonia (importe)
  ;; ienākumam līdz 20 004 euro – 20 %;
  ;; ienākumam no 20 004 eiro līdz 55 000 euro – 23 %;
  ;; ienākuma daļai, kas pārsniedz 55 000 euro – 31,4 %.
  ;; o sea, (/ 20004 12.0)1667.0, (/ (- 55000 20004) 12.0)2916

  ;; > We have the progressive rate (20%, 23% and 31,4%)
  ;; > 20% x 1667 = 333,40 eur
  ;; > 23% x 2916 = 670,68 eur
  ;; > 31,4% x 50 = 15,70 eur      ← el 50 es (/ 5000 12.0)416.6666666666667
  ;; 
  "da igual"
  "∴ He hecho esto en Python; ver /impuesto progresivo/"
  )


;;;; funciones para fechas

(defun fecha-en-mi-formato () "Da la fecha actual al estilo 18.m9.2009" (format-time-string "%-d.m%-m.%Y" (current-time)))

(defun entiende-fecha-y-hora-en-mi-formato (texto) "Devuelve objeto ~datetime (el usado por emacs) a partir de fecha escrita en mi formato, con hora"
       (let ((cadena 
              ;; "1.m9.2016 20:45"
              ;; "1.m9.2016"
              texto
              ))
         (string-match "^\\\([[:digit:]]+\\\)\\\.m\\\([[:digit:]]+\\\)\\\.\\\([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\\\)\\\( \\\([[:digit:]][[:digit:]]\\\):\\\([[:digit:]][[:digit:]]\\\)\\\)?$" cadena)
         (list ;; prueba
          (match-string 1 cadena)
          (match-string 2 cadena)
          (match-string 3 cadena)
          (match-string 4 cadena)
          (match-string 5 cadena)
          )
         ;; (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE)
         (encode-time
          00
          (string-to-int (or (match-string 6 cadena) "0"))
          (string-to-int (or (match-string 5 cadena) "0"))
          (string-to-int (match-string 1 cadena))
          (string-to-int (match-string 2 cadena))
          (string-to-int (match-string 3 cadena))
          )
         )

       )
;; (entiende-fecha-y-hora-en-mi-formato "17.m1.1985 22:10")
;; Pruebo idempotencia:
;; (format-time-string "%d.m%m.%Y %H:%M" (entiende-fecha-y-hora-en-mi-formato "17.m1.1985 22:10"))
;;
;; Pruebo además sin hora:
;; (entiende-fecha-y-hora-en-mi-formato "17.m1.1985")
;; (format-time-string "%d.m%m.%Y %H:%M" (entiende-fecha-y-hora-en-mi-formato "17.m1.1985"))


(defun diferencia-en-días-entre-dos-fechas-en-mi-formato (fa fb)
  "Dame dos „11.m1.2015 23:00“ y digo cuántos días pasaron. Cuando han pasado „días más largos“ (25h) o „días más cortos“ (23h) por cambio de hora pasan cosas raras, así que has de redondear el resultado tú luego."
  (/
   (/ (float-time (time-subtract
                   (entiende-fecha-y-hora-en-mi-formato fa)
                   (entiende-fecha-y-hora-en-mi-formato fb)
                   )) 3600) ; esto da la diferencia en horas
   24.0) ; en días
  )
;; Probando
;;(diferencia-en-días-entre-dos-fechas-en-mi-formato "11.m1.2015" "10.m1.2015")
;;(diferencia-en-días-entre-dos-fechas-en-mi-formato "11.m1.2015 12:00" "10.m1.2015 11:00")

;; Oh, no, qué guarradas:
;; (diferencia-en-días-entre-dos-fechas-en-mi-formato "11.m6.2015" "11.m1.2013") ;; → 880.9583333333334
;; quizás es por años bisiestos ← no
;; ∴ es por cambio de hora
;;
;; Investigo y encuentro dónde sale:
;; (diferencia-en-días-entre-dos-fechas-en-mi-formato "30.m3.2014" "11.m1.2014") → 78.0
;; (diferencia-en-días-entre-dos-fechas-en-mi-formato "31.m3.2014" "11.m1.2014") → 78.95833333333333



;;;; filtro para cambiar el formato de números
(defun filtro-para-cambiar-comas-a-puntos-en-números (ini fin)
  """Pasa los números de 12,51 a 12.51 (y sólo los números). Útil para aplicar a una tabla de org que viene de otro lado."""
  ;; prueba: (replace-regexp-in-string "\\\([[:digit:]]\\\),\\\([[:digit:]]\\\)" "\\1.\\2" "hola, 25,2 1, 23 1,0")
  (interactive "r")
  (if (region-active-p)
      ;; (call-interactively #'replace-string)
      ;; (call-interactively (lambda (ini2 fin2) (interactive "r") (replace-regexp "a" "")))
      (replace-regexp   "\\\([[:digit:]]\\\),\\\([[:digit:]]\\\)" "\\1.\\2" nil ini fin)
    (message "Error: región no activa")
    )
  )

;;;; configurar varias cosas que hacen más cómodo escribir en varios idiomas (ruso, griego, polaco)
(defun rusigi ()
  "Prepara un entorno agradable para escribir palabras en ruso"
  (interactive)
  (with-current-buffer (switch-to-buffer "puc")

    (set-input-method "cyrillic-translit")
    (ispell-change-dictionary "russian")
    (flyspell-mode 1)
    (message "¡готовый!")
    )
  )

;; hunspell es mejor

;; para griego:
;; falta activar corrector, con myspell si es que se puede
;; Ai myspell-el-gr
;; creo que también viene aspell. Pero ispell no
;; Para todo esto prefiero usar aspell pues parece más avanzado
(setq ispell-program-name "/usr/bin/aspell")
;; (setq ispell-list-command "--list") ← no hace falta nada de esto ya

(defun grekigi ()
  "Prepara un entorno agradable para escribir palabras en griego"
  (interactive)
  (with-current-buffer (switch-to-buffer "hel")

    (set-input-method "greek")
    ;; (ispell-change-dictionary "greek")
    ;; (flyspell-mode 1)
    (message "¡έτοιμοι!")
    )
  )

(defun poligi ()
  "Prepara un entorno agradable para escribir palabras en polaco"
  (interactive)
  (with-current-buffer (switch-to-buffer "pol")

    (set-input-method "polish-slash")
    (ispell-change-dictionary "polish")
    (flyspell-mode 1)
    (message "¡~~prepiwadó!")
    )
  )
(defun latvigi ()
  "Prepara un entorno agradable para escribir palabras en letón"
  (interactive)
  (with-current-buffer (switch-to-buffer "latv")

    ;; (set-input-method "latvian-keyboard") ; no sé si es bueno
    (set-input-method "latva-mia-postfix") ; mejor
    ;; ¿diccionario? Está aspell-lv
    (message "gatavs")
    )
  )

;; por la latva
(quail-define-package
 "latva-mia-postfix" "Latvian" "L<" t
 "Latvian standard keyboard input method.
" ; nil t t t t nil nil nil nil nil t
 nil t nil nil nil nil nil nil nil nil t
 )

(quail-define-rules
 ("ee" ?ē)
 ("EE" ?Ē)
 ("r," ?ŗ)
 ("R," ?Ŗ)
 ("uu" ?ū)
 ("UU" ?Ū)
 ("ii" ?ī)
 ("II" ?Ī)
 ("oo" ?ō)
 ("OO" ?Ō)
 ("aa" ?ā)
 ("AA" ?Ā)
 ("s^" ?š)
 ("S^" ?Š)
 ("g," ?ģ)
 ("G," ?Ģ)
 ("k," ?ķ)
 ("K," ?Ķ)
 ("l," ?ļ)
 ("L," ?Ļ)
 ("z^" ?ž)
 ("Z^" ?Ž)
 ("c^" ?č)
 ("C^" ?Č)
 ("n," ?ņ)
 ("N," ?Ņ))

;; por la hebrea
;;(require 'quail)
;; el https://emacs.stackexchange.com/questions/3558/how-to-switch-keyboard-layouts-for-different-languages/3574#3574
;; ankaŭ el https://github.com/hlissner/doom-emacs/issues/767
(add-to-list 'quail-keyboard-layout-alist
             `("dvorak" . ,(concat "                              "
                                   "  1!2@3#4$5%6^7&8*9(0)[{]}`~  "
                                   "  '\",<.>pPyYfFgGcCrRlL/?=+    "
                                   "  aAoOeEuUiIdDhHtTnNsS-_\\|    "
                                   "  ;:qQjJkKxXbBmMwWvVzZ        "
                                   "                              ")))
;; Funkcias bone por la hebrea. Sed malfunkciigas la rusan
;; Mi faru ŝanĝon lokan anstataŭ tion ĉi
;; (quail-set-keyboard-layout "dvorak")
;; Estis:
;; (quail-set-keyboard-layout "standard")

(defun hebreigi ()
  "Prepara un entorno agradable para escribir palabras en hebreo. Por retocar para hacer que funcione bien en Dvorak sin estropear el resto"
  (interactive)
  (with-current-buffer (switch-to-buffer "hebr")
    (set-input-method "hebrew")
    ;; Aquí faltaría un quail-set-keyboard-layout que lo cambie sólo en este búfer. Ver arriba
    (message "בתהליך בנייה")
    )
  )


(defun portugaligi ()
  "Prepara un entorno agradable para escribir palabras en portugués"
  (interactive)
  (with-current-buffer (switch-to-buffer "por")

    (set-input-method "portuguese-prefix")
    (message "¡Preto!")
    )
  )
(defun ĉinigi-cangjie ()
  "Prepara un entorno agradable para escribir palabras en chino (Cangjie)"
  (interactive)
  (with-current-buffer (switch-to-buffer "ĉin-cangjie")
    ;; (text-scale-adjust 10) ; ← si hago esto dos veces, peta emacs (se cuelga)
    (text-scale-set 10)
    (set-input-method "chinese-cns-tsangchi")
    (message "好!")
    )
  )
(defun ĉinigi-pinyin ()
  "Prepara un entorno agradable para escribir palabras en chino (Pinyin)"
  (interactive)
  (with-current-buffer (switch-to-buffer "ĉin-pinyin")
    (text-scale-set 10)
    (set-input-method "chinese-tonepy")
    (message "好!")
    )
  )
(defun japanigi ()
  "Prepara un entorno agradable para escribir palabras en japonés"
  (interactive)
  (with-current-buffer (switch-to-buffer "jap")
    (text-scale-set 10)
    (set-input-method "japanese")
    (message "はい.")
    )
  )
(defun arabigi ()
  "Prepara un entorno agradable para escribir palabras en árabe"
  (interactive)
  (with-current-buffer (switch-to-buffer "arab")

    (set-input-method "arabic")
    (text-scale-set 4)
    (message "اااااااااااااااااااااااا")
    )
  )
;; Ankaŭ provas:
;; (when window-system (set-fontset-font "fontset-default" '(#x600 . #x6ff) "clearlyu arabic"))

(defun turkigi ()
  "Prepara un entorno agradable para escribir palabras en turco"
  (interactive)
  (with-current-buffer (switch-to-buffer "tur")
    (text-scale-set 4)
    (set-input-method "turkish-postfix")
    (message "hazır!")
    )
  )

(defun norvegigi ()
  "Prepara un entorno agradable para escribir palabras en noruego"
  (interactive)
  (with-current-buffer (switch-to-buffer "norsk")
    (set-input-method "norwegian-postfix")
    (ispell-change-dictionary "norsk") ; En ispell: "nynorsk", "bokmål", "bokmaal", ∴"norsk" (apunta a "nb"), "nb", …   Lo estoy eligiendo para aspell pues lo prefiero sobre ispell. En aspell: "norwegian", no hay „norsk“
    ;; Atención: he tenido que hacer esto para que vaya flyspell+aspell:      cd /usr/lib/aspell; ln -s norwegian.alias norsk.alias
    (flyspell-mode 1) ; 1 == activar
    (message "¡parat!")
    )
  )

;;;; buscar caracteres ¬ASCII (útil para probar programas mal hechos)
;; Más: ver Unicode.org
(defun occur-non-ascii ()
  "Find any non-ascii characters in the current buffer."
  (interactive)
  (occur "[^[:ascii:]]"))
(defun occur-non-ascii-excepto-las-letras-que-uso-habitualmente ()
  "Esto me da los caracteres muy extraños, bueno, los ¬ascii extraños. En realidad no me da los códigos feos (códigos de control) pues ésos están en ASCII, ẽ tuve un tal „INFORMATION SEPARATOR TWO“ (0x1E, to input: type „C-x 8 RET 1e“ or „C-x 8 RET INFORMATION SEPARATOR TWO“)."
  (interactive)
  (occur "[^[:ascii:]áéíóúàèòñçĉĝĥŝĵŭẽ¿¡→←¬…∴„“«»ºª]")
  ;; Y extendiéndolo un poco más: (esto es para experimento de campus)
  ;; (occur "[^[:ascii:]áéíóúàèòñçĉĝĥŝĵŭẽ¿¡→←¬…∴„“«»ºªابتثجحخدذرزسشصضطظعغفقكلمنهويßßאבגדהוזחטיכלמנסעפצקרשתךםןףץ]")
  ;; como no me pilla todos los árabes, le añado a mano varios
  ;; (occur "[^[:ascii:]áéíóúàèòñçĉĝĥŝĵŭẽ¿¡→←¬…∴„“«»ºªابتثجحخدذرزسشصضطظعغفقكلمنهويßإالىسغييßאבגדהוזחטיכלמנסעפצקרשתךםןףץ]")
  )
(defun delete-non-ascii ()
  "Cambia cosas UTF-8 a ascii sin perder mucha información. Hecho para complacer a programas mal diseñados que no van bien con UTF-8"
  (interactive)
  (replace-string "“" "\"" nil (point-min) (point-max))
  (replace-string "”" "\"" nil (point-min) (point-max))
  (replace-string "∼" "~" nil (point-min) (point-max))
  (replace-string "±" "+/-" nil (point-min) (point-max))
  (replace-string "¿" "??" nil (point-min) (point-max))
  (replace-string "á" "AA" nil (point-min) (point-max))
  (replace-string "à" "AA" nil (point-min) (point-max))
  (replace-string "é" "EE" nil (point-min) (point-max))
  (replace-string "í" "II" nil (point-min) (point-max))
  (replace-string "ó" "OO" nil (point-min) (point-max))
  (replace-string "ú" "UU" nil (point-min) (point-max))
  (replace-string "ñ" "NY" nil (point-min) (point-max))
  )

;;; Algunas cosas que han de ir al final necesariamente

;; Aún no sé por qué, o si esto funcionará
;; (define-helmgitgrepgetinputsymbol-con-mi-versión-arreglada)
;; No funciona, así que lo puedo borrar

;;; Ajustes automáticos

;; la faz rst-level-2-face se sobreescribe y no sé quién es culpable

;; Puestos por la igu, en „Save options“.
(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.
 '(async-shell-command-display-buffer nil)
 '(auto-save-list-file-prefix ".emacs.d/auto-save-list/saves-")
 '(bubbles-graphics-theme 'balls)
 '(case-fold-search t)
 '(completions-detailed t)
 '(current-language-environment "UTF-8")
 '(default-input-method "rfc1345")
 '(describe-char-unidata-list
   '(name old-name general-category canonical-combining-class bidi-class decomposition decimal-digit-value digit-value numeric-value mirrored iso-10646-comment uppercase lowercase titlecase))
 '(diff-switches "-u")
 '(dired-do-revert-buffer t)
 '(display-time-mail-file 'none)
 '(ecb-layout-window-sizes nil)
 '(ecb-options-version "2.40")
 '(ediff-window-setup-function 'ediff-setup-windows-plain)
 '(enwc-wired-device "eth2")
 '(enwc-wireless-device "wlan4")
 '(erc-kill-queries-on-quit t)
 '(erc-modules
   '(autojoin button completion fill irccontrols match menu netsplit noncommands readonly ring services stamp track))
 '(european-calendar-style t)
 '(fill-column 100)
 '(flymake-start-syntax-check-on-newline nil)
 '(global-semantic-idle-scheduler-mode nil)
 '(gnutls-min-prime-bits 1024)
 '(google-translate-default-source-language "auto")
 '(google-translate-default-target-language "en")
 '(google-translate-listen-program "/usr/bin/mpv")
 '(helm-ff-fuzzy-matching nil)
 '(helm-locate-project-list '("/home/dc/.wpriv/vounua/"))
 '(helm-ls-git-default-sources '(helm-source-ls-git))
 '(helm-mode-fuzzy-match t)
 '(helm-quick-update t)
 '(history-length 571)
 '(home-end-enable t)
 '(ibuffer-formats
   '((mark modified read-only " "
           (name 26 26 :left :elide)
           " "
           (size 9 -1 :right)
           " "
           (mode 16 16 :left :elide)
           " " filename-and-process)
     (mark " "
           (name 16 -1)
           " " filename)))
 '(image-dired-line-up-method 'dynamic)
 '(image-dired-show-all-from-dir-max-files 250)
 '(image-dired-thumb-margin 8)
 '(image-dired-thumb-size 150)
 '(imap-store-password t)
 '(jabber-auto-reconnect t)
 '(jde-complete-function 'jde-complete-minibuf)
 '(line-number-display-limit-width 5000)
 '(longlines-show-hard-newlines t)
 '(magit-clone-set-remote.pushDefault t)
 '(magit-diff-refine-hunk t)
 '(message-log-max 1000)
 '(minimap-dedicated-window t)
 '(minimap-width-fraction 0.15)
 '(minimap-window-location 'right)
 '(nxhtml-skip-welcome t)
 '(org-agenda-time-grid
   '((daily today require-timed)
     (800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 0 100 200)
     "......" "----------------"))
 '(org-blank-before-new-entry '((heading) (plain-list-item . auto)))
 '(org-drill-optimal-factor-matrix
   '((2
      (2.6 . 2.588))
     (1
      (2.6 . 4.14)
      (1.7000000000000002 . 3.44)
      (2.28 . 4.14)
      (1.4000000000000001 . 4.14)
      (2.06 . 4.14))))
 '(org-export-backends '(ascii html icalendar latex odt texinfo))
 '(org-insert-heading-respect-content t)
 '(org-jira-worklog-sync-p nil)
 '(org-table-electric-header-p t)
 '(package-native-compile t)
 '(package-selected-packages
   '(jdecomp magit-section magit mingus libmpdee vimrc-mode popup jedi jsonian mmm-jinja2 mmm-mode jinja2-mode calfw-gcal calfw-org calfw-ical calfw boxquote feature-mode helm-sql-connect emacsql-psql jabber oauth2 vue-html-mode terraform-mode memory-usage go-mode clips-mode package-lint read-aloud zone-sl request tree-mode json-navigator zone-select zone-rainbow zone-nyan eimp lua-mode google-translate csv-mode minizinc-mode groovy-mode yaml-mode typescript-mode ag emmet-mode helm-ls-git ibuffer-vc git-link helm-git-grep helm-cscope helm-swoop string-utils s async auto-complete edbi-sqlite markdown-mode poker))
 '(rcirc-fill-flag nil)
 '(rcirc-reconnect-delay 120)
 '(redisplay-skip-fontification-on-input t t)
 '(require-final-newline 'ask)
 '(safe-local-variable-values
   '((diff-add-log-use-relative-names . t)
     (vc-git-annotate-switches . "-w")
     (hs-minor-mode)))
 '(send-mail-function 'mailclient-send-it)
 '(sql-connection-alist
   '(("yubay1"
      (sql-product 'postgres)
      (sql-user "perico")
      (sql-password "palotes")
      (sql-server "localhost")
      (sql-database "yubay1"))
     ("ejd"
      (sql-product 'sqlite)
      (sql-database "~/.niw/entornoejd/ejd/datosbd.sqlite3"))
     ("anki"
      (sql-product 'sqlite)
      (sql-database "~/.anki2/User 1/collection.anki2"))
     ("vhadmin"
      (sql-product 'sqlite)
      (sql-database "~/vhadmin-b/vhadmin"))))
 '(sql-sqlite-program "sqlite3")
 '(svn-status-svn-executable "svn")
 '(tramp-syntax 'default nil (tramp))
 '(truncate-lines nil)
 '(use-dialog-box nil)
 '(warning-suppress-types '((emacs)))
 '(wget-download-directory "~/baja/")
 '(whitespace-display-mappings
   '((space-mark 32
                 [183]
                 [46])
     (space-mark 160
                 [164]
                 [95])
     (space-mark 2208
                 [2212]
                 [95])
     (space-mark 2336
                 [2340]
                 [95])
     (space-mark 3616
                 [3620]
                 [95])
     (space-mark 3872
                 [3876]
                 [95])
     (newline-mark 10
                   [9252 10])
     (tab-mark 9
               [8250 9]
               [92 9])))
 '(whitespace-style
   '(tabs trailing space-before-tab newline indentation empty space-after-tab space-mark tab-mark newline-mark))
 '(wl-highlight-folder-with-icon nil)
 '(yas-indent-line 'fixed))


(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.
 '(calendar-today ((t (:box (:line-width 2 :color "blue violet" :style released-button) :underline t))))
 '(cfw:face-disable ((t (:inherit cfw:face-day-title :foreground "#444"))))
 '(cfw:face-saturday ((((class color) (background light)) (:background "#d4e5ff" :foreground "Blue" :weight bold)) (((class color) (background light)) (:foreground "Blue" :weight bold)) (t (:foreground "red"))))
 '(cfw:face-toolbar-button-off ((t (:foreground "Gray30" :weight bold))))
 '(diff-added ((t (:background "#060"))))
 '(diff-changed ((nil (:background "black" :foreground "yellow"))))
 '(diff-refine-changed ((t (:background "#883300"))))
 '(diff-removed ((t (:background "#600"))))
 '(ediff-current-diff-C ((t (:background "#552"))))
 '(ediff-even-diff-A ((t (:background "#414"))))
 '(ediff-even-diff-B ((t (:background "#434"))))
 '(ediff-even-diff-C ((t (:background "#454"))))
 '(ediff-fine-diff-A ((t (:background "#220000" :box (:line-width (3 . 3) :color "#aa2222" :style flat-button)))))
 '(ediff-fine-diff-B ((t (:background "#002200" :box (:line-width (3 . 3) :color "#22aa22" :style flat-button)))))
 '(ediff-fine-diff-C ((t (:background "#883" :foreground "#000"))))
 '(ediff-odd-diff-A ((t (:background "#221"))))
 '(ediff-odd-diff-B ((t (:background "#223"))))
 '(ediff-odd-diff-C ((t (:background "#225"))))
 '(fixed-pitch ((t (:height 120 :family "Monospace"))))
 '(flymake-error ((t (:underline (:color "dark red" :style wave :position nil)))))
 '(helm-ff-directory ((t (:background "DarkRed" :foreground "LightGray"))))
 '(helm-selection ((t (:background "#040" :underline t))))
 '(match ((t (:background "RoyalBlue4"))))
 '(minimap-font-face ((t (:height 0.1 :foundry "misc" :family "normal"))))
 '(minimap-semantic-function-face ((t (:inherit (font-lock-function-name-face minimap-font-face) :background "gray10" :box (:line-width 1 :color "white") :height 100))))
 '(minimap-semantic-type-face ((t (:inherit (font-lock-type-face minimap-font-face) :background "gray10" :box (:line-width 1 :color "white") :height 100))))
 '(minimap-semantic-variable-face ((t (:inherit (font-lock-variable-name-face minimap-font-face) :background "gray10" :box (:line-width 1 :color "white") :height 100))))
 '(muse-verbatim ((((class color) (background dark)) (:foreground "green"))))
 '(org-agenda-date ((t (:inherit org-agenda-structure :underline (:color "#bb0" :style wave) :height 2.0))))
 '(org-agenda-date-today ((t (:inherit org-agenda-date :slant normal :weight bold))))
 '(org-agenda-date-weekend ((t (:background "#c30" :foreground "black" :weight bold))))
 '(org-block-begin-line ((t (:inherit org-meta-line :overline t :slant italic))))
 '(org-block-end-line ((t (:inherit org-meta-line :underline t :slant italic))))
 '(org-drawer ((t (:inherit font-lock-keyword-face))))
 '(org-headline-done ((t (:foreground "dim gray"))))
 '(org-link ((t (:foreground "deep sky blue" :underline (:color "blue" :style wave)))))
 '(org-meta-line ((t (:inherit font-lock-keyword-face))))
 '(org-target ((t (:underline nil))))
 '(rst-level-1-face ((t (:background "#fdd" :foreground "black"))) t)
 '(rst-level-2-face ((t (:background "grey38" :foreground "black"))) t)
 '(rst-level-3-face ((t (:background "gray35" :foreground "#222222"))) t)
 '(rst-level-4-face ((t (:background "grey64" :foreground "#222222"))) t)
 '(semantic-decoration-on-unknown-includes ((t (:background "#401040"))))
 '(smerge-refined-changed ((t (:background "dark goldenrod"))))
 '(t2t-bold-face ((t (:background "black" :foreground "dodger blue" :weight extra-bold :width extra-expanded))))
 '(w3m-italic ((t (:inherit italic))))
 '(whitespace-tab ((((class color) (background dark)) (:background "grey8" :foreground "#052"))))
 '(widget-button ((t (:box (:line-width 2 :color "grey75" :style released-button) :weight bold))))
 '(widget-inactive ((t (:inherit shadow :foreground "dim gray")))))


;; El „a“ en dired
(put 'dired-find-alternate-file 'disabled nil)






;;; Acabar la configuración de todo y empezar visiblemente

;; (insert "El fichero de configuración se ha procesado bien")

;; No; para correo ya uso IMAP
;;(w3m-browse-url "http://mail.google.com/")
;; Intento abrir w3m después de arrancar; sólo para precargarse
;; 1.2.2009: como no siempre lo uso, no siempre lo abriré
;; (unless (w3m-alive-p) (w3m))

2. org-cronometrados_org.el (exportar cronómetros de org-mode)

Esto ya va de org-mode, que es una parte de Emacs. Lo uso para gestionar mis tareas. Esta parte que publico aquí es ya algo avanzado, para poder exportar cronómetros a un fichero y analizarlos luego con Python.

;; Esto es implementación Lisp de lo mismo que hice en cronometrados_org.py (ver notas ahí).
;; Lo que hace es exportar hacia un fichero de salida los datos de todos los cronómetros de org-mode, de toda la agenda
;; Sobre qué es org-mode: https://www.danielclemente.com/hacer/org.html
;;
;; El formato de salida es algo como:
;; FicheroOrg1 2017-03-26 14:00:00 2017-03-26 14:20:00 ["Cabecera padre"]
;; FicheroOrg1 2017-04-26 14:50:00 2017-04-26 14:55:00 ["Cabecera padre", "Subcacecera"]
;; Idiomas 2019-01-26 12:10:00 2019-01-26 12:30:00 ["Idiomas", "Letón", "aprendiendo letón"]
;; 
;; o sea: nombre_de_fichero_org inicio_de_cronómetro final_de_cronómetro lista_de_padres
;; 
;; Este sistema es lento, mucho más lento que cronometrados_org.py (que hace lo mismo, con greps de CLOCK, y es casi instantáneo), pero este sistema es capaz de extraer la ruta a la cabecera de cada cronómetro, o sea los „padres“. Luego analizo todo esto desde Python.
;; También extrae las etiquetas de cada cabecera.
;; Ver en: „cronometrados_org.el“
;; En 2022 pasé a usar otro sistema (en Python) que exporta otra cosa (el árbol de todas mis cabeceras) e incluí ahí el exportar los cronómetros de cada cabecera, a .txt (como éste) y a .pickle. No es mucho más rápido que este código en Lisp, pero me va bien hacerlo ahí porque así lo exporto todo junto en una sola operación. Por tanto ya no me hace falta este org-cronometrados_org.el

;; 2017 en adelante. Daniel Clemente. Código en dominio público. https://www.danielclemente.com/emacs/confi.html

;; Para probar: ver al final

;; Necesito cambiar unas cosas sobre cómo org extrae las cabeceras, para ser capaz de extraer las etiquetas también:
(defun org--get-outline-path-1--y-también-con-etiquetas (&optional use-cache)
  "Versión de org--get-outline-path-1 que además incluye nombre de etiqueta dentro de cabecera.
  Llamado desde org-get-outline-path--y-también-con-etiquetas."
  (or (and use-cache (cdr (assq (point) org-outline-path-cache)))
      (let ((p (point))
        (heading (let ((case-fold-search nil))
               (looking-at org-complex-heading-regexp)
               (if (not (match-end 4)) ""
             ;; Remove statistics cookies.
             (org-trim
              (org-link-display-format
               (replace-regexp-in-string
                "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" ""
                (concat
                 (match-string-no-properties 4)
                 " "
                 (match-string-no-properties 5)
                )
                )))))))
    (if (org-up-heading-safe)
        (let ((path (cons heading (org--get-outline-path-1--y-también-con-etiquetas use-cache))))
          (when use-cache
        (push (cons p path) org-outline-path-cache))
          path)
      ;; This is a new root node.  Since we assume we are moving
      ;; forward, we can drop previous cache so as to limit number
      ;; of associations there.
      (let ((path (list heading)))
        (when use-cache (setq org-outline-path-cache (list (cons p path))))
        path)))))

(defun org-get-outline-path--y-también-con-etiquetas (&optional with-self use-cache)
  "Versión de org-get-outline-path que además incluye etiquetas dentro del nombre de la cabecera"
  (org-with-wide-buffer
   (and (or (and with-self (org-back-to-heading t))
        (org-up-heading-safe))
    (reverse (org--get-outline-path-1--y-también-con-etiquetas use-cache)))))

;; Esto era una prueba y no va. No lo uso → ¿qué uso envez?
;; sobre problema con zona horaria: ver 421f2b48-15c6-40dc-9183-b87339c0c3f7
(defun mi--org-time-string-to-time--que-no-se-lía-con-cambio-de-hora (s)
  ; ver notas
  ; En construcción, no va aún
  ;; (apply #'encode-time (org-parse-time-string s))
  (encode-time (org-parse-time-string s))
)

(defun org-extrae-cronómetros-de-fichero (fichero)
  ;; basada en org-find-open-clocks
  (let ((buf (or (get-file-buffer fichero)
                 (find-file-noselect fichero)))
        (org-clock-re 
         ;; Creo que aquí tengo que añadir algo para detectar el segundo
         ;; le he quitado el $. Le he puesto dos veces el []
         (concat org-clock-string 
                 ;; " \\(\\[.*?\\]\\)"
                 " \\(\\[.*?\\]\\)--\\(\\[.*?\\]\\)"
                 )
         )
        datos-de-un-cronómetro
        clocks)
    (with-current-buffer buf
      (save-excursion
        (goto-char (point-min))
        (while (re-search-forward org-clock-re nil t)
          ;; Se lo prepara
          ;; Aquí incluir ya mucha información interesante (tiempo de inicio, tiempo de final, padres, …). Luego los otros métodos pueden escribir estos datos en el formato bueno
          ;;
          ;; v1, con lista. Borrable
          ;; (setq datos-de-un-cronómetro
          ;;        (cons (copy-marker (match-end 1) t)
          ;;              (org-time-string-to-time (match-string 1))
          ;;              ))
          ;;
          ;; v2, con hash table
          (let* (
                 (marcador (copy-marker (match-end 1) t))
                 (inicio (match-string 1))
                 (fin (match-string 2))
                 ;; v1: Para tomar los padres, (org-get-outline-path 'y-actual) está bien… pero no me toma las etiquetas
                 ;; (padres (org-get-outline-path 'toma-el-actual-también 'con-caché))
                 ;; v2: Necesitaría las etiquetas también… Para eso me hago mi función:        ESTO ya no aplica: +(y va bien, excepto que me toma sólo las etiquetas de la cabecera ACTUAL, no las heredadas de los padres)+
                 (padres (org-get-outline-path--y-también-con-etiquetas 'toma-el-actual-también 'con-caché))
                 datos-de-un-cronómetro
                 )
            (setq datos-de-un-cronómetro (make-hash-table :test 'equal))
            (puthash "marcador" marcador datos-de-un-cronómetro)
            ;; cuidado, (org-time-string-to-time "2020-06-30 Tue 01:t9") debería dar error (por el „t9“) y no lo da. Por mejorar
            (puthash "inicio" (org-time-string-to-time inicio) datos-de-un-cronómetro)
            (puthash "fin" (org-time-string-to-time fin) datos-de-un-cronómetro)
            (puthash "padres" padres datos-de-un-cronómetro)
            (puthash "fichero" (buffer-file-name) datos-de-un-cronómetro)

            ;; Guarda una copia, para probar. Esto es de depuración. Luego puedo inspeccionar y hacer cosas con este reloj fuera de la función
            (setq probando-a-examinar-un-reloj datos-de-un-cronómetro)
            ;; Lo añade a lista
            (push datos-de-un-cronómetro clocks))))
      )

    clocks)
  )
(defun org-lista-cronómetros-de-agenda-VERSIÓNSIMPLE ()
  "Es una prueba pero ya va. Lo dejaré como función simple, y crearé las otras en otras funciones. Cuando funcionen las completas, borrar ésta. Usar un parámetro"
  (interactive)
  ;; basada en org-resolve-clocks
  (with-temp-file "/home/dc/n/cronómetros-desde-el.txt"
    (dolist (file
             ;; (org-files-list)
             org-agenda-files
             )
      (let ((clocks 
             (org-extrae-cronómetros-de-fichero file)   ;;         (org-find-open-clocks file)
             ))
        (dolist (clock clocks)
          (insert 
           ;; v1, con lista
           (prin1-to-string clock)
           ;; v2, con hash-table
           ;; (json-read-from-string
           ;;  (json-encode-hash-table clock)
           ;;  )
           "\n")
          )))
    )
  )

(defun org-lista-cronómetros-de-agenda (&optional sólo-en-estos-ficheros fichero-de-salida)
  """
Lista los cronómetros de la agenda, y da bastante información.
Esta función no extrae/procesa los datos, sólo los imprime en formato bonito.

Lo ha de dar en el formato:
2018-01-03 Wed 10:15 2018-01-03 Wed 10:27 [cabecera, padre, padre, padre, padre, … fichero.org]

Para recibir otros formatos o limitar el funcionamiento, añadirle parámetros a esta función.

Ej. si pasas sólo-en-estos-ficheros, se limita a ciertos ficheros (si no, usa toda agenda).
  """
  (interactive)
  (with-temp-file (or fichero-de-salida "/home/dc/n/cronómetros-desde-el.txt")
    (dolist (file 
             (or
              sólo-en-estos-ficheros
              ;; ¿qué ficheros incluir al exportar cronómetros? Si pongo org-agenda-files, me pierdo ficheros como yubay.org (que ya no está en agenda pero tiene muchos cronómetros)
              ;; org-agenda-files
              ;; Por eso le añado a mano otros
              (append org-agenda-files componentes-agenda--jubilados) 
              ;;(org-files-list)
              )
             )
      (let ((clocks
             (org-extrae-cronómetros-de-fichero file)
             ))
        (dolist (clock clocks)
          ;; Tomo algún dato (ya preparado por org-extrae-cronómetros-de-fichero) y lo pongo en formato bueno
          (insert 
           ;; (prin1-to-string clock) "\n"

           ;; Probando: (format-spec "bash %u %k %ce %m %n" '((?u . "hola") (?k . "adiós") (?c . cerdo) (?m . "?n") (?n . "ene")))
           (format-spec
            ;; "→ Fichero %f,   %i--%n,   padres: %p\n"
            "%f %i %n %p\n"
            `(
              (?f . ,(replace-regexp-in-string 
                      "\.org$" "" 
                      (replace-regexp-in-string
                       "[ \\.]" "_"
                       (file-name-nondirectory (gethash "fichero" clock))
                       )
                      ))
              (?i . ,(format-time-string "%Y-%m-%d %H:%M:00" (gethash "inicio" clock)))
              (?n . ,(format-time-string "%Y-%m-%d %H:%M:00" (gethash "fin" clock)))
              ;; (gethash "padres" clock)
              (?p . ,(format "[%s]"
                             (mapconcat (lambda (x) (format "\"%s\"" (replace-regexp-in-string "\"" "\\\\\"" x))) (gethash "padres" clock) ", ")
                             ))
              )
            )
           )
          )))
    )
  ;; ¿Auto-revertir? Algo como
  ;;      (revert-buffer nil t)

  (message "Acabado. (Escrito a fichero %s)" fichero-de-salida)
  )
;; Para probar:
;; (org-extrae-cronómetros-de-fichero "~/wiki/XML.org")
;; (org-extrae-cronómetros-de-fichero "~/wiki/PDF.org")
;; (org-extrae-cronómetros-de-fichero "~/wiki/Zeitmanagement.org")
;;
;; ∴ Éste es el global. Es lento. Estimo que tardará ~14 minutos sin caché. Pero tarda ~1 min
;; (org-lista-cronómetros-de-agenda)
;;
;; (org-lista-cronómetros-de-agenda '("/home/dc/wiki/XML.org"))
;; (org-lista-cronómetros-de-agenda '("/home/dc/wiki/Invo.org"))
;; (org-lista-cronómetros-de-agenda '("/home/dc/wiki/Paginascos.org"))
;; (org-lista-cronómetros-de-agenda '("/home/dc/wiki/ProyectoWeb.org"))
;; opencraft: tarda 1 minuto. Con caché, 6 segundos
;; (org-lista-cronómetros-de-agenda '("/home/dc/org/opencraft.org"))

3. bustrofedon.el (experimento de lectura)

Para convertir un texto (cualquier búfer, por ejemplo una página web) a bustrofedon.

;; -*- mode: emacs-lisp; coding:utf-8 -*-
;; bustrofedon.el
;; Intenta ser una mejora de la lectura, más bien un experimento, para dar la vuelta a las palabras (no las letras) de una de cada dos líneas. Es importante voltear la frase por palabras y no por letras, porque las mentes están acostumbradas a reconocer palabras enteras. Habitualmente veo el bustrofedon (https://es.wikipedia.org/wiki/Bustrofedon) hecho por letras, pero no sé porqué; por palabras es mejor.
;;
;;
;; 4.m12.2007 Daniel Clemente. Mejorado un poco en: 5.m12.2007, 16.m8.2008. Código en dominio público
;; Creo que éstas son las primeras funciones „serias“ que he programado en ELisp, en 2007, tras empezar a usarlo. Por eso están tan mal :-)
;;
;; Ejemplo del efecto deseado:
;;
;; TEXTO ORIGINAL
;;
;; En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho
;; tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua,
;; rocín flaco y galgo corredor. Una olla de algo más vaca que carnero,
;; salpicón las más noches, duelos y quebrantos los sábados, lantejas los
;; viernes, algún palomino de añadidura los domingos, consumían las tres
;; partes de su hacienda. El resto della concluían sayo de velarte, calzas de
;; velludo para las fiestas, con sus pantuflos de lo mesmo, y los días de
;; entresemana se honraba con su vellorí de lo más fino. Tenía en su casa una
;; ama que pasaba de los cuarenta, y una sobrina que no llegaba a los veinte,
;; y un mozo de campo y plaza, que así ensillaba el rocín como tomaba la
;; podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años; era de
;; complexión recia, seco de carnes, enjuto de rostro, gran madrugador y amigo
;; de la caza. Quieren decir que tenía el sobrenombre de Quijada, o Quesada,
;; que en esto hay alguna diferencia en los autores que deste caso escriben;
;; aunque, por conjeturas verosímiles, se deja entender que se llamaba
;; Quejana. Pero esto importa poco a nuestro cuento; basta que en la narración
;; dél no se salga un punto de la verdad.

;; TEXTO VOLTEADO:
;;
;; En un lugar de la Mancha , de cuyo nombre no quiero acordarme , no ha mucho
;; , antigua adarga , astillero en lanza de los de hidalgo un vivía que tiempo
;; rocín flaco y galgo corredor . Una olla de algo más vaca que carnero ,
;; los lantejas , sábados los quebrantos y duelos , noches más las salpicón
;; viernes , algún palomino de añadidura los domingos , consumían las tres
;; de calzas , velarte de sayo concluían della resto El . hacienda su de partes
;; velludo para las fiestas , con sus pantuflos de lo mesmo , y los días de
;; una casa su en Tenía . fino más lo de vellorí su con honraba se entresemana
;; ama que pasaba de los cuarenta , y una sobrina que no llegaba a los veinte ,
;; la tomaba como rocín el ensillaba así que , plaza y campo de mozo un y
;; podadera . Frisaba la edad de nuestro hidalgo con los cincuenta años ; era de
;; amigo y madrugador gran , rostro de enjuto , carnes de seco , recia complexión
;; de la caza . Quieren decir que tenía el sobrenombre de Quijada , o Quesada ,
;; ; escriben caso deste que autores los en diferencia alguna hay esto en que
;; aunque , por conjeturas verosímiles , se deja entender que se llamaba
;; narración la en que basta ; cuento nuestro a poco importa esto Pero . Quejana
;; dél no se salga un punto de la verdad .


(defun reverse-string-by-characters (cadena)
  "Da la vuelta a los caracteres de CADENA.
Encontrada por ejemplo en: http://ja.doukaku.org/lang/emacslisp/"
  (concat (nreverse (append cadena nil))))

(defun reverse-string-by-words (cadena)
  ".texto de cadena una de palabras las a vuelta la Da
Versión muy muy chapucera, del 5.12.2007"
  (if (not (split-string cadena)) ; es que la cadena es sólo espacios
      cadena  ; entonces la damos igual
    ;; Si no, invertimos palabras
    (substring (format "%s" (reverse     (split-string cadena ) ) ) 1 -1)
    )
  )


(defun dale-la-vuelta-a-la-línea (&optional función-inversora)
  "Invierte el orden de las letras de la línea actual.
4.12.2007, 142857"
  (interactive "P")

  (or función-inversora (setq función-inversora 'reverse-string-by-characters))

  (let
      (
       (línea-actual (buffer-substring (line-beginning-position) (line-end-position)))
       )
    
    (delete-region (line-beginning-position)(line-end-position))

    ;;    (insert(reverse-string-by-characters línea-actual) )
    (insert (funcall función-inversora línea-actual) )

    ;; (combine-and-quote-strings (reverse     (split-string línea-actual "") ) ""
    )
  )

(defun dale-la-vuelta-a-las-líneas-múltiplos-de (ene &optional función-inversora)
  "Invierte una de cada ene líneas.
4.12.2007, 142857
"
  (interactive "p")
  (save-excursion
    ;; (beginning-of-buffer)
    (goto-char (point-min))
    ;;(forward-line 1)

    (while (not (eobp))
      ;;(insert ">>>")
      (funcall 'dale-la-vuelta-a-la-línea función-inversora)
      ;;(dale-la-vuelta-a-la-línea)

      (forward-line ene)
      )
    )
  )


(defun davuelta-pares-caracteres nil
  "Deja el texto
ísa otircse
para todas
.saeníl sal
4.12.2007, 142857
"
  (interactive)
  (dale-la-vuelta-a-las-líneas-múltiplos-de 2 'reverse-string-by-characters)
  )

(defun davuelta-pares-palabras nil
  "Deja el texto
forma esta de escrito
para todas
.líneas las
4.12.2007, 142857
"
  (interactive)
  (dale-la-vuelta-a-las-líneas-múltiplos-de 2 'reverse-string-by-words)
  )


(defun bustrofedon-en-búfer nil
  "...[en construcción]...
- La función ha de elegir la configuración más apropiada para la lectura.
- No usa las funciones anteriores, sino que reescribe el código con los mejores procedimientos.
- La función no toma parámetros.
4.12.2007"
  (interactive)
  ;; Idea:
  ;; Defino „inicio de bloque“ (IDB) como el principio de un párrafo, de un elemento de lista, de un titular, ...
  ;; *Todos* los IDB irán iad (izquierda a derecha). Para las líneas sucesivas se aplicará la alternancia entre iad y dai.

  ;; ¿invertir letras en cadena? Es una mala idea, porque no leemos analizando las letras, sino que reconocemos palabras enteras. Para no tener que aprender nuevas „palabras“, es mejor invertir las palabras dentro de una frase.


  ;; así todos los temas de fill/unfill no estarán sobreescritos
  (text-mode)
  ;; hace falta desactivarlo para que las faces tengan efecto
  (font-lock-mode -1)


  (save-excursion



    ;; El algoritmo es: primero aligerar puntuación y párrafos, entonces reindentar para hacer líneas llenapantallas, y entonces voltear algunas líneas





    (airea-líneas-en-búfer) 

    (airea-puntuación-en-búfer)
    ;; 31.3.2009: en vez de indentar (con fill-region), usaré  (let ((line-move-visual t)) (next-line 1)) para avanzar de línea en línea *visual*; así no hay que hacer fill antes para meter \n duros. Queda mejor respetando el formato original. Ya indentaré yo (el usuario) antes si quiero.
    (make-local-variable 'line-move-visual) (setq line-move-visual t)
    ;; por tanto desactivo fill:
    ;;(set-fill-column (frame-width)) ; BONUS: probar con otros valores que faciliten la lectura más
    ;;(fill-region (point-min) (point-max))


    ;; BONUS: me va a hacer falta esto para que ? etc. no salgan en líneas distintas. Pero es una minucia.
    ;;If you’re French, you might be used to typing a space in front of colons, question marks, exclamation marks, etc. [1] This might lead to the following problem:
    ;;   Where do we write the question marks |
    ;;   ? We use a space in front of them.   |
    ;;To avoid this, add ‘fill-french-nobreak-p’ to ‘fill-nobreak-predicate’.



    ;; Entonces ya sólo hay que dar vuelta a líneas

    ;; (beginning-of-buffer)
    (goto-char (point-min))

    (while (not (eobp))

      ;; El algoritmo es:
      ;; si la línea es en blanco ("" o "   " etc), saltarla
      ;; si la línea anterior existe y tiene la marca de „no-volteada“ al final => voltear ésta y marcar con „volteada“ al principio
      ;; en caso contrario => saltarse ésta, poniéndole marca „no-volteada“ al final

      ;; esto era: dale-la-vuelta-a-la-línea
      (let
          (
           (línea-actual (buffer-substring (line-beginning-position) (line-end-position)))
           ;; esta línea ya tiene los signos aireados

           )


        (cond
         ;;CASO1/3: (blanco => saltarla)
         (
          (not (split-string línea-actual)) ; es que la cadena es sólo espacios
          (forward-line 1) ; saltarla
          )


         ;;CASO2/3: (ant-novolt => voltear,marcar)
         (

          (save-excursion
            (and 
             (not (bobp)) ; la línea anterior existe

             (forward-line -1) ; da 0, bueno, eso es cierto


             ;; BONUS: una posible mejora es hacer que el margen derecho de cada línea volteada empiece justo en la columna donde la línea de arriba (sin voltear) acaba.
             ;; Lo malo es que entonces el borde izquierdo (el final de la frase) no estará justificado... :-( Quizás puedo encontrar un término medio. O QUIZÁS DA IGUAL.
             ;; De todas formas, se haría así:
             ;; - contar cuántos espacios hay desde el final derecho de la línea de arriba hasta el borde derecho de la pantalla
             ;; - contar cuántos espacios en blanco caben al final de la línea actual (volteada)
             ;; - calcular el menor de ambos: nos gustaría añadir todos los espacios de la línea de arriba, pero no podemos pasarnos
             ;; - añadir ese número de espacios por la derecha a la línea volteada
             ;; - justificar esta línea a la derecha



             ;; la línea anterior... „no es vacía (sólo espacios)“
             (split-string (buffer-substring (line-beginning-position) (line-end-position)))
             ;; y la línea anterior... no tiene asignada la faz línea-al-revés
             ;; y
             ;; ... tiene la marca de „no-volteada“ al final
;;;;;;;;;;; Se puede hacer mediante una marca:
;;;;; (and (> (line-end-position) 1) ;; (que no falle en líneas cortas o vacías)
;;;;;  (string-equal "ン"  (buffer-substring (- (line-end-position) 1) (line-end-position))  ))
;;;;;;;;;;; O mediante propiedades en texto:
             ;; nota: mirar la propiedad al principio de la línea, ¡no al final! Pero saltarse la indentación que yo añadí al justificar a la derecha

             (or (beginning-of-line-text) t) ; no quiero que devuelva nil así que hago esta chapuza

             (let ((propi (get-text-property (point) 'face)))
               (not (and (facep propi) (equal propi 'línea-al-revés))
                    )
               )

             ;;(y-or-n-p (concat "¿lant es no-vol? Faz al final es: " (or (get-text-property (line-end-position) 'face) "nula")))
             ;; mejor depurar con ielm

             ) ; fin del and
            ) ; del save-excursion

          ;; entonces: voltear ésta
          
          (delete-region (line-beginning-position)(line-end-position))

          ;; era: reverse-string-by-words
          (insert
;;;;;;;;;; Uso faces en vez de símbolos para marcar las líneas que van hacia atrás
;;;;;;;;;; "ピ "

           (propertize
            (substring (format "%s" (reverse     (split-string línea-actual ) ) ) 1 -1)
            'face 'línea-al-revés
            )

           ;;" plueba "
           )

          ;; justificar a la derecha toda línea volteada
          (justify-current-line 'right)


          ;; y seguir, claro
          (forward-line 1)

          ) ; fin del caso „voltear“

         ;;CASO3/3: (t => no-voltear,marcar)
         (t ; en otro caso...

          ;; No hace falta cambiar por la versión con puntuación aireada; eso era de versión anterior
          ;;(delete-region (line-beginning-position)(line-end-position)) (insert línea-actual)


          ;; ;;;;;; Esto sólo es útil si se usan símbolos en vez de faces
          ;; ;;;;;; (end-of-line) (insert " ン") ;saltada, sigue abajo

          ;; saltársela
          (forward-line 1)
          )

         )

        
        )


      )
    )


  )
(defun bustrofedon-en-búfer-nuevo ()
  "Crea un búfer nuevo *Bustrofedon* que contiene el texto del actual pero con las líneas pares de cada párrafo escritas de derecha a izquierda. Quizás esto facilita la lectura en bustrofedon."
  (interactive)

  ;; Esto no va si se está visitando un fichero
  ;; (clone-buffer "*Bustrofedon*") ; nuevo
  ;; (clone-indirect-buffer "*Bustrofedon*" t) ; esto hace espejo del otro pero no copia independiente

  ;; Esto funciona porque copia todo el texto a un búfer nuevo
  (and (get-buffer "*Bustrofedon*") (kill-buffer "*Bustrofedon*")) ; lo mata si existe
  (copy-to-buffer "*Bustrofedon*" (point-min) (point-max))
  (switch-to-buffer "*Bustrofedon*")

  ;; Hago escribible el búfer y el texto interno (hace falta truco para que no dé error)
  (toggle-read-only -1) ; búfer sea escribible (¡no el texto!)
  (let ((inhibit-read-only t)) (put-text-property (point-min) (point-max) 'read-only nil))

  (bustrofedon-en-búfer)

  (view-mode) ; es cómodo para leer, y lo del bustrofedon lo uso cuando quiero leer algo

  )


(defface línea-al-revés
  '(
    (((background dark)) (
                          ;;:family "Courier"
                          ;;:slant italic
                          :background "#000052"))
    )
  "Faz para líneas que se han de leer de derecha a izquierda; se usa en bustrofedon."
  )



;;Esto separa los signos de puntuación : ejemplo , en esta frase . Va mejor . Así , al voltearlos serán tratados como palabras sueltas . Además facilita la lectura , pues el estar pegados a las palabras las „ contamina “ y dificulta su reconocimiento . Mamá ya lo hacía bien dejando espacios a ambos lados : - )
(defun airea-puntuación-en-búfer ()
  "Cambia, de. este; estilo, de, puntuación, a , este . otro ; en donde - los signos ¿ aparecen ? todos ( separados ) de ` ` las ' ' palabras . Creo que se parece al estilo francés . (Dejan espacio antes de los :).
No arregla el margen derecho de las líneas; para eso llama tú a C-x h + fill-region
16.8.2008 Daniel Clemente"
  (interactive)

  (goto-char (point-min))

  ;;(while (re-search-forward "[[:space:]]*\\([[:punct:]]\\)[[:space:]]*" nil t)
  (while (re-search-forward "\\([[:punct:]]\\)" nil t)
    (replace-match " \\1 " nil nil))

  ;; (setq línea-actual (replace-regexp-in-string "[[:space:]]*\\([[:punct:]]\\)[[:space:]]*" " \\1 " línea-actual-con-puntuación-original))
  )



(defun airea-líneas-en-búfer ()
  "Hace que ciertas líneas empiecen párrafos para que las líneas no queden demasiado juntas.
Trata líneas que empiean por un número, por ejemplo.
31.3.2009 Daniel Clemente"
  (interactive)

  (goto-char (point-min))

  ;;(while (re-search-forward "[[:space:]]*\\([[:punct:]]\\)[[:space:]]*" nil t)
  ;; le quito un null que había (un ^@ real, eso es el 0x00). Aquí estaba: "^\\(     \\|^@\\|[0-9]\\|[^\n]\\{1,14\\}$\\)"
  (while (re-search-forward "^\\(     \\|[0-9]\\|[^\n]\\{1,14\\}$\\)" nil t)
    (beginning-of-line)(insert "\n")(forward-line)))



;; hale, como los profesionales. Aunque esto no es ningún paquete y no respeta las convenciones (ej. defino funciones de fuera del paquete, etc.).
(provide 'bustrofedon)
;; Si haces versión mejor (ej. una donde puedas seguir escribiendo así), avísame, la quiero probar.
;; Por cierto, si quieres escribirme, escribe de arriba a abajo, en espiral, o de alguna otra forma original…

;;; ¿por qué me recomiendan poner esto? No quiero esta burocracia:
;;; bustrofedon.el ends here

4. org-defproyectos.el (pruebas para exportar org-mode)

Burocracia.

;; Ésta era una parte de .emacs pero como se usa en otros lados (ej. ex ~/ut/exporta-org.sh) la he movido a fuera
;; m1.2015: es muy viejo y no lo uso, y no creo que vaya.
;; m3.2020: aún uso funcion alguna función de aquí

;;;;;;; publicación (org-publish)
(setq org-publish-project-alist 
      '(

;;;;;;;; proyecto de pruebas
        ("directorio org"
         :base-directory "~/org/"
         :publishing-directory "~/org/html"
         :section-numbers nil
         :table-of-contents nil
         )

;;;;;;;; Aquí intento una configuración válida para más secciones de mi web
        ;; En m2.2016 la usé (retocada, actualizada) y funciona bien
        ("disk"
         :base-directory "~/proj/disk/"
         ;;local:;
         :publishing-function org-html-publish-to-html
         ;; :publishing-directory "~/proj/disk/html"
         :publishing-directory "~/repoweb/disk"
         ;;remoto: ← muy loco, creo
         ;; :publishing-directory "/dc@glass.dreamhost.com:/home/dc/danielclemente.com/disk/"
         :exclude "index.org" ; dislines
         :preparation-function dislines-disk
         ;; :section-numbers nil
         ;; :table-of-contents nil
         :html-preamble
         "
<script type=\"text/javascript\" src=\"../menu/menubody.js\"></script>
"
         ;;                :auto-preamble nil
         :auto-postamble nil
         ;; ¡atención! El código ha de ser XHTML, no sólo HTML
         :html-head-extra
         "
<link rel=\"stylesheet\" type=\"text/css\" href=\"basic.css\"></link>
<link rel=\"stylesheet\" type=\"text/css\" href=\"../menu/menu.css\"></link>
"
         ;;                                   :auto-index t
         )

;;;;;;;; uno para orgawww
        ("orgawww para miwiki"
         :base-directory "~/wiki/"
         :publishing-directory "~/wiki/html"
         :section-numbers nil
         :table-of-contents nil
         )

;;;;;;;; intento esto, de prueba también
        ("lo de lenguaje (probándolo"
         :base-directory "~/proj/lenguaje"
         :publishing-directory "~/n/leguajehtml"
         :section-numbers nil
         :table-of-contents nil
         :publishing-function org-html-publish-to-html
         :auto-sitemap t
         )


        ))

;; carga el resto de definiciones, que están integradas en mi web

;; Versión para ¬paranoicos:
;; (load-file "~/repoweb/estructura/pagina/mi-org-publish.el")

;; Pero hay que asegurarse, antes de ejecutar, de que sólo es un (setq …) inofensivo y no hay otros (…)
;; Esto parece funcionar. 18.m8.2009 142857, hecho a mano

(let* ((fichi "~/repoweb/pagina/mi-org-publish.el")
       (comprobador (concat "md5sum " fichi " | egrep -c '^("
                            "0b72fc35d3c4e386a51f2ca37caeb041"
                            "|" "617a7397d6fa09e2b2f649c9e04b48f5"
                            "|" "b2ed34d46922501ddf77836b4e0c3ef7"
                            "|" "d7a7a0b6ea7bb2b97a02fb88f2086adc"
                            "|" "81af3c3b178d1d214096cc1684ac9145"
                            "|" "7d78b5829a6bbeb45d9b66e574e3a3e8"
                            "|" "53a8733e71b5ac54d27b7897d79653fa"
                            "|" "b046389800a7bb62d336d7c2ea2e2349"
                            "|" "2e8c77d2bdf9d64f7c315879be9d10cd"
                            "|" "be92493d53bb7f0dc91503050173de94"
                            "|" "b3cc04d99478d6832576a1333269edc0"
                            "|" "2453a3686113aa8f93163c41a48ce1b6"
                            "|" "116177996224af0f993b53a7f1b49c0d"
                            "|" "4ad4bedc7d499829d6fa46578e134701"
                            "|" "94773edeed6f1d5aeb59810a086c2451"
                            "|" "a94c59ed07b42a8e4e1716080071f280"
                            "|" "aquí_irá_el_siguiente) '"))
       (salidaesperada "1
")
       )
  (if (file-exists-p fichi)

      ;; ; Versión anterior al 7.m3.2010; demasiado compleja para mantener
      ;; (with-temp-buffer 
      ;;   (insert-file "~/repoweb/estructura/pagina/mi-org-publish.el")
      ;;   (goto-char (point-min))
      ;;   (while (search-forward-regexp "^\\(\\((\\)\\|[^\n;].*(\\)" nil t)
      ;;    (unless
      ;;        (or
      ;;         (looking-at "add-to-list 'org-publish-project-alist")
      ;;         (looking-back "'(" (- (point) 3))
      ;;         )
      ;;      (error "El fichero mi-org-publish.el tiene código que no parece fiable y por eso me niego a evaluarlo")
      ;;      )
      ;;    )
      ;;   (eval-buffer)
      ;;   (message "cargado mi-org-publish.el sin riesgo")
      ;; )

      ;; Versión más sencilla pero trabajosa: listaré md5sum conocidos
      (if 
          (or nil ; poner a t para no hacer comprobaciones
              (equalp 
               (shell-command-to-string comprobador)
               salidaesperada
               ))
          (progn (load-file fichi) (message "cargado mi-org-publish.el sin riesgo"))
        (error (concat "EL fichero mi-org-publish.el tiene código que no parece fiable y por eso me niego a evaluarlo.
Su MD5 es " 
                       (shell-command-to-string (concat "md5sum " fichi))
                       "
y me ha devuelto: «"
                       (shell-command-to-string comprobador)
                       "»"
                       ))
        )

    (message "no cargo %s porque no lo encuentro" fichi))
  )


;; Exportador más sencillo
;; BONUS: acelerar. Ahora tarda 30s en lovic (¡rapidísimo!)
(defun exporta-lo-que-toca-de-webdcl nil
  "Exporta aquello de mi web donde estoy trabajando en este momento, de forma cómoda. Ej. exporta mi „hacer“"
  (interactive)
  (let ((org-export-allow-bind-keywords t))
    (org-publish-project
     ;; "hacer (sólo directorio „hacer“ de rama „hacer“)"
     ;; (assoc "hacer (sólo directorio „hacer“ de rama „hacer“)" org-publish-project-alist)
     (assoc "exportar mi hacer de repoweb" org-publish-project-alist)
     'sí.fuérzalo.por.favor)
    )
  )
;; Probando:
;; (setq org-export-allow-bind-keywords t)
;; (setq org-export-allow-bind-keywords nil)



;; Si org-publish no detecta bien el proyecto:
;; (ej: algo como esto da nil)
;;(org-publish-get-project-from-filename "/home/dc/repoweb/hacer/hacer/bazaar.org" 'up)
;; El problema es que org-publish-files-alist tiene información anticuada, quizás porque después se han ido creando ficheros nuevos. Y se actualiza con:
;; (org-publish-initialize-files-alist 'sí,refrescar)

;;;;;;;; otras funciones necesarias para generar ficheros
(defun dislines-disk nil
  "dislines index.org sólo para proyecto disk"
  (shell-command "cd ~/proj/disk; ~/ut/dislines.pl ~/proj/disk/index.org")
  )

5. org-publicable.el (gestionar artículos que quiero publicar en mi web)

Burocracia.

;;; Esto son funciones para cargar desde emacs y ejecutar desde emacsclient (no desde prita bash) que exportan las cabeceras marcadas como :cable: a los ficheros apropiados (configurado cada uno en propiedad EXPORT_FILE_NAME)

(require 'cl)
(defun publica-cable-de-esperanto ()
  (interactive)
  (publica-cable-de-varias-fuentes  '("~/wiki/Esperanto.org"))
  )
(defun publica-cable-de-licencias ()
  (interactive)
  (publica-cable-de-varias-fuentes  '("~/wiki/Licencia.org"))
  )
(defun publica-cable-de-todomiwiki ()
  (interactive)
  (publica-cable-de-varias-fuentes  'agenda)
  )

(defun publica-cable-de-varias-fuentes (fuente)

  (org-map-entries (lambda () 
                     ;;  (line-number-at-pos)
                     ;; (org-html-export-as-html nil t nil nil nil) ; lo deja en búfer (no a fichero)
                     ;; (org-html-export-to-html nil t nil nil nil) ; ¿por qué no coge nombre de fichero? No me usa EXPORT_FILE_NAME aunque debería según documentación. Así que tengo que replicar esta función
                     (let ((nombre-fichero
                            (cdr
                             (assoc 
                              "EXPORT_FILE_NAME"
                              (org-entry-properties)
                              ))
                            ))
                       (if nombre-fichero
                           (progn
                             (message "Exportando a %s" nombre-fichero)
                             (org-html-export-as-html ; a búfer
                              nil t nil 
                              nil ; ¿body-only?
                              ;;t
                              )
                             (with-current-buffer "*Org HTML Export*"
                               (write-file 
                                ;; "/home/dc/n/exp.html"
                                nombre-fichero
                                )
                               (kill-buffer)
                               )
                             (format "Exportado a %s" nombre-fichero)


                             )
                         (message "No exportando pues no hay nombre")
                         )
                       
                       )
                     )  "+cable" fuente)

  )




(defun exporta-lista-de-publicables-a-datoscables.txt ()
  "
  Genera datoscables.txt. Esto tarda un rato (ẽ 30s).
  Esta función se llama desde „vercables“ (prita).
  "
  (interactive)
  (with-temp-file "/home/dc/.medidas/datoscables.txt"
    (let* ((lista-datos

            (org-map-entries (lambda () 
                               (let* (
                                      (pr (org-entry-properties))
                                      (estado (cdr (assoc "TODO" pr)))    ;; (substring-no-properties (or (org-get-todo-state) "--"))
                                      (texto (cdr (assoc "ITEM" pr)))   ;; (substring-no-properties (org-get-heading))
                                      (cat (cdr (assoc "CATEGORY" pr))) ;; (buffer-name (current-buffer))
                                      (prio (cdr (assoc "PRIORITY" pr)))
                                      (gradodef (cdr (assoc "GRADO_DE_DEFINICIÓN" pr)))
                                      (fichex (cdr (assoc "EXPORT_FILE_NAME" pr)))
                                      (títex (cdr (assoc "EXPORT_TITLE" pr)))
                                      (horas-usadas (cdr (assoc "CLOCKSUM" pr)))
                                      (horas-estimadas (cdr (assoc "EFFORT" pr)))
                                      (longitud-bytes (length (org-get-entry)))  ; incluye metadatos como CLOCK etc.
                                      )


                                 (list 
                                  :berenjena "DATOS::"
                                  :cat cat
                                  :lín (number-to-string (line-number-at-pos)) ; →texto para que todo sea texto
                                  :estado estado
                                  :texto texto
                                  :prio prio
                                  :gradodef gradodef
                                  :fichex fichex
                                  :títex títex
                                  :horas-usadas horas-usadas
                                  :horas-estimadas horas-estimadas
                                  :longitud-bytes longitud-bytes
                                        ; :datos (org-entry-properties)

                                  )
                                 )
                               )
                             "+cable"

                             (quote agenda)
                             ;; (quote ("~/wiki/Esperanto.org" "~/wiki/SoftwareLibre.org"))

                             )
            )
           (lista-ficheros
            ;; "aaa"
            (sort
             (remove nil
                     (mapcar (lambda (dat) (plist-get dat :fichex ) ) lista-datos)
                     )
             (function string-lessp)
             )
            )
           (resultado-escribible
            (list
             :lista-de-datos
             lista-datos
             :lista-de-los-ficheros-que-se-generarán
             lista-ficheros
             ;; (mapconcat (quote identity) lista-ficheros "\n")
             ;; (prin1 lista-ficheros)
             )
            )
           )

      ;;  Acción a hacer:
      ;; (insert (prin1 resultado-escribible ))
      ;; (insert (mapconcat (quote identity) resultado-escribible "|")))
      (insert (prin1-to-string resultado-escribible))
      ;; (prin1 lista-ficheros)
      ;; (insert (message "a\nb %s c" (number-to-string (+ 2 3))))

      (insert "\nLista de datos\n")
      (cl-loop for línea in lista-datos do 
            (cl-loop for (key value) on línea  by (quote cddr)
                     do ;(message (symbol-name key) (prin1 value))
                     (insert (symbol-name key) ": ")
                     (insert (or value "") "\n")
                     ;; collect value
                     )
            (insert "\n")
            )

      (insert "\nLista de datos en CSV (esto acaba metido en ~/.medidas/datoscables.csv)\n")
      (insert "cat,lín,estado,gradodef,texto,prio,fichex,títex,horasusadas,horasestimadas,longitudbytes\n")
      (cl-loop for línea in lista-datos    do 
            (insert 
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :cat) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :lín) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :estado) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :gradodef) "")) "\""    ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :texto) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :prio) "")) "\""    ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :fichex) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :títex) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :horas-usadas) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (plist-get línea :horas-estimadas) "")) "\""   ","
             "\"" (replace-regexp-in-string "\"" "·" (or (number-to-string (plist-get línea :longitud-bytes)) "")) "\""
             "\n")
            )

      (insert "\nLista de ficheros\n")
      (cl-loop for fi in lista-ficheros do
            (insert fi "\n")
            )

      (insert "\n\nLista de artículos sin fichero asignado:\n")
      (cl-loop for línea in lista-datos when (not (plist-get línea :fichex))   do 
            (insert (plist-get línea :texto) "\n")
            )


      (insert "\n\nLista de artículos sin título de exportación:\n")
      (cl-loop for línea in lista-datos when (not (plist-get línea :títex))   do 
            (insert (plist-get línea :texto) "\n")
            )

      (insert "\n\nLista de artículos sin etiqueta de estado:\n")
      (cl-loop for línea in lista-datos when (not (plist-get línea :estado))   do 
            (insert (plist-get línea :texto) "\n")
            )

      (insert "\n\nLista de artículos sin estimación ← por hacer (con el horas-estimadas de arriba). Y control en todobien:\n")

      )

    )

  (message "Generado ~/.medidas/datoscables.txt")
  )

6. org-muestra-agenda.el (pasar agenda de org-mode a fichero)

Para exportar la agenda de org-mode a un fichero de texto, rápidamente.

;; Exporta agenda de org-mode a fichero, desde modo batch e intentando ir rápido
;; 2009 (etc. hasta 2020) Daniel Clemente. Código en dominio público. https://www.danielclemente.com/emacs/confi.html

;; para ejecutar con:
;; emacs -Q --batch --load .org-muestra-agenda.el --eval '(org-batch-agenda "a")'
;; O redirigiendo (>~/.mi-agenda)
;; Lo estoy usando ya con los pritas ag,ag1,agact, …
;; También lo uso con ẽ (org-lista-cronómetros-de-agenda), para exportarlo desde fuera de mi emacs principal. Por tanto este fichero es encargado de cargar un org-mode eficiente mínimo, con mis mejoras pero sin todas mis particularidas; y este org-mode es usable para varias cosas (todo procesos „batch“).
;; Para usarlo de esa otra forma, simplemente evaluar otra función: : dc; ~ ; time emacs --batch -q -l .org-muestra-agenda.el -l ~/.emacs.d/lisp/org-cronometrados_org.el --eval '(org-lista-cronómetros-de-agenda)' 
;;
;;
;; Sobre exportación de agenda: Le podría añadir colores… pero eso no mejoraría su utilidad ni mi eficiencia.

;; Velocidad de agenda:
;; - suele tardar entre 17 y 20s (aún tras la 1ª) ← no sé en qué ordenador
;; - no, 47s tarda ahora
;; - en m11.2021, tras ciertos cambios de org-element (incluyendo org-persist), tarda 71 segundos

;; Intento instrumentar: ∴ funciona así y le añade sólo unos ~5 segundos:
;; emacs -Q --batch --load .org-muestra-agenda.el --eval '(progn (empezar-perfilado) (org-batch-agenda "a") (acabar-perfilado))'; cat /home/dc/n/perfilado.txt
;;
(defun empezar-perfilado ()
  (setq elp-use-standard-output t)
  (message "Instrumentand")
  ;;(require 'org)
  (elp-instrument-package "org-")
  (elp-instrument-package "org")
  (elp-instrument-package "vc-")
  (elp-instrument-package "beep")
  (elp-instrument-package "flymake-")
  (elp-instrument-package "emacs-")
  (elp-instrument-package "cl-")
  (elp-instrument-package "doctor")
  ;;(elp-instrument-function #'doctor-mode)
  (elp-instrument-package "man")
  (message "Instrumentados")
  )
(defun acabar-perfilado ()
  "Es necesario esta función para que la llames tú tras hacer tus cosas. Ej.    emacs -Q --batch --load .org-muestra-agenda.el --eval '(progn (empezar-perfilado) (emacs-version) (acabar-perfilado))'; cat /home/dc/n/perfilado.txt         "
  (elp-results)
  (with-current-buffer "*ELP Profiling Results*"
    (write-file "/home/dc/n/perfilado.txt")
    )
  (message "/home/dc/n/perfilado.txt")

  )

(defun carga-org-mode-como-el-que-uso-a-diario ()
  "Añade y carga el org-mode del mismo que el real, y pon los mismo ficheros que uso en el día a día. No hay ninguna optimización de exportación aquí. Pongo todo esto en esta función apartada porque ésta será la parte prescindible cuando use emacsclient, porque todo esto ya estará cargado en el emacs gordo"
  ;; Lo de la codificación se soluciona poniendo:
  ;;   (eval-after-load "org-agenda"
  ;;     '(defun org-encode-for-stdout (s) s))
  ;; pero ya lo metió Carsten en org. Sólo HAY QUE CARGAR EL ORG BUENO:
  (add-to-list 'load-path "/w/org-mode/lisp")
  ;; ya no hace falta: (require 'org-install)
  (require 'org)
  (require 'org-agenda) ; hay que hacerlo manualmente parece que a partir de m6.2011
  (require 'org-clock) ; hay que hacerlo manualmente parece que a partir de m8.2011, para conseguir org-duration-string-to-minutes


  ;; este modo me hace falta para considerar el invo.beancount como parte de la agenda (cosa que aún no sé si es útil o funciona)
  ;; lo desactivo porque no uso citas dentro del .beancount
  (ignore '(
            (let ((f "/w/beancount/src/elisp/beancount.el"))
              (when (file-exists-p f) 
                (load-file f)
                (require 'beancount)
                ))
            ))


  ;; Usa los mismos ficheros de agenda que ~/.emacs
  (load-file "~/.org-ficheros-agenda.el") ; probé a compilar, no lo acelera
  )




;; Cargo org-mode. Esto no hará falta cuando use emacsclient (pues org ya estará cargado)
(carga-org-mode-como-el-que-uso-a-diario)

;; se evita el: „File opencraft.org is large (9.5 MiB), really open? ([Y]es, [N]o, [L]iterally, [?]):“
(setq large-file-warning-threshold nil)

;; para el error "locked by" (ver emacs.org). Ej
;; ...home/dc/org/semana.org locked by dc@ali (pid 3733): (s, q, p, ?)? 
;; La solución es redefinir la función que pregunta:
(defun ask-user-about-lock (file opponent)
  nil)
;; 6.m1.2010: ¡¡¡Funciona!!!

;; Acelero enormemente la carga evitando que se active vc-mode al leer cada fichero de agenda. Ver en emacs.org. 7.m6.2010
(defun vc-find-file-hook () nil)
;; En m11.2021: „This function is obsolete since 25.1;“
;; Y encontré esto en vc-hooks.el:
;; (add-hook 'find-file-hook #'vc-refresh-state)
;; Lo contrarresto. Funciona
(remove-hook 'find-file-hook #'vc-refresh-state)
;; (setq find-file-hook nil) ;Esto es más fuerte que el remove-hook. Y eficaz
;; Por lo visto otra forma (una que hace org) es ésta. Pero equivale a la anterior; no lo hace más rápido
;; (setq vc-handled-backends nil)

;; todo esto es configuración de org; no tarda mucho. Alguna es para hacer el nuevo org igual al que uso en el día a día, otras son para acelerar la exportación . Es importante configurar todo ahora, antes de abrir cualquier fichero

(setq org-agenda-start-on-weekday nil)
(setq org-agenda-use-time-grid nil) ; ha de contar bien, pues nº líneas = nº tareas

(setq org-agenda-use-tag-inheritance nil) ; dicen que esto lo acelera mucho. Bueno, de 40s a 39s lo he visto bajar…
(setq org-use-tag-inheritance nil) ; y por si acaso lo aplico aquí también (total, no lo necesito). Creo que no afecta en nada. Parece

;; Modificación mía de mi org-mode
;;Con mi parche:
;;(setq org-agenda-ignore-properties t)
;;(setq org-agenda-ignore-properties nil)
;; con el de Carsten ← oficial
;; Qué curioso, no me está acelerando nada pues YA ESTABA ACELERADO sin esto. Pero la 1ª vez que lo probé noté diferencia de 10 segundos (repetible). De todas formas, lo dejo
(setq org-agenda-ignore-drawer-properties '(effort appt category))
;;(setq org-agenda-ignore-drawer-properties nil)
;;(setq org-agenda-ignore-drawer-properties 'peta) ; peta pues (memq 'uno 'no-es-lista) ← peta, por tanto lee la propiedad

;; Recomiendan ponerlo a nulo para acelerar
(setq org-agenda-dim-blocked-tasks nil)

;; mismo que en .emacs. Con estas 3 líneas paso de 40 a 32 segundos
(defun org-install-agenda-files-menu () nil)
(setq org-inhibit-startup-visibility-stuff t)
(defun org-refresh-effort-properties () nil)
;; ¿Esto ayuda? Veo que no así que lo dejo comentado
;; (setq org-startup-folded nil)

;; otra cosa que dicen (worg) que puede ayudar: org-agenda-inhibit-startup, ver abajo


;; (setq cache-long-scans nil) ; probando. No acelera nada, tarda 2:56 con esto a t o a nil
;; Desactivo esto de la caché, y me va de 2 a 3 veces más rápido
(setq org-element-use-cache nil) ; no acelera; bueno, me fue 5 segundos más rápido, pero no sé si es por esto
(setq org-element-cache-persistent nil)  ;; Cuando lo probé sin desactivar org-element-use-cache:. aún me ralentiza todo y mete cosas en ~/.cache/org-persist/ al final
;; Me parece que además desactivar la caché es lo correcto, pues aquí voy a procesar orgs sin tener en cuenta muchas cosas (herencia de propiedades, etiquetas, etc.) y si cacheo eso, luego puede afectarme mal cuando use el emacs normal. Quizás a eso se refieren los errores como „Warning (org-element-cache): org-element--cache: Warning(opencraft.org): (org-cycle) Cached element is incorrect in opencraft.org. (Cache tic up to date: "yes") Resetting.“


(setq org-agenda-inhibit-startup t) ; dicen que va más rápido. Pero creo que ya estaba activado

;; varias cosas de éstas las copio de .emacs. Quizás es mejor ponerlo en fichero aparte.

(setq org-agenda-format-date "
→ %A %x (semana %W, %B)
===========================================")
(setq org-todo-keywords
      '( (sequence "FARU(f)" "BONUS(b)" "ATENDAS(a)" "|" "IS(i)" "MALFAR(m)")
         (sequence "TODO(t)" "|" "DONE(d)")) )
(setq org-ellipsis (quote org-column))
(add-to-list 'org-global-properties '("Effort_ALL" "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 12:00 18:00 24:00 30:00"))
(setq org-columns-default-format "%40ITEM(Task) %9Effort(Previsión){:} %5CLOCKSUM %6TODO")

;; Creo que no hace falta porque ya ejecuto el (org-batch-agenda "a") en el --load en agact()
;;(org-agenda-list)
;; Tarda un 33% menos si lo quito. → lo quito


(setq org-agenda-sorting-strategy
      '((agenda habit-up time-up todo-state-up priority-down category-keep)
        (todo priority-down category-keep)
        (tags priority-down category-keep)
        (search category-keep))
      )

;; ¡¡¡¡¡¡¡¡¡¡¡¡aaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!!!! ¡Esto me ha bajado el tiempo de creación de la agenda, de 3 minutos a 15 segundos! Gracias al instrumentado descubrí esta función lentísima.
(defun org-update-radio-target-regexp () nil)



;; Ahora que org está configurado sí que se puede hacer una precarga de los .org



;; Ponerlos en caché para que encfs no se pare con cada uno de ellos
;; De momento, en un arranque en caliente (o sea, no el 1º), esto me hace tardar 0'1 segundos más
;; En frío no lo he probado
;; ∴ Pero no import, no es efectivo
;; (shell-command "cat ~/wiki/*.org >/dev/null")


;; Precarga. Intentar hacer algo para acelerar la carga y actualización de la agenda
;; Esto parece que acelera 0,5 segundos (medio segundo) la ejecución de „agact“ ← ¿dónde? En 2d2, la retrasa 1 segundo (quizás es por encfs)
;; El find-file tarda 2'3 pero vale la pena porque hace que el sucesivo org-batch-agenda tarde menos
;;(message "precargando *.org")
;;(find-file "~/wiki/*.org" t)
;;(find-file "~/org/*.org" t)
;;(find-file "~/repoweb/ofinial/hacer/*.org" t)
;;(message "precargados *.org")
;; ∴ Mejor es no hacer todo esto, pues ralentiza
;;(message "no precargo pues ralentizó")

7. org-exportar-mejores-ids.el (cambiar formato de IDs en enlaces internos)

Para evitar que los IDs de secciones (ej. de los ficheros que publico) cambien cada vez que exporto.

;; Unos ajustes para exportar enlaces internos como #nombre-de-la-cabecera-destino, en vez de cosas como #org42c6660 o números al azar. Esto es muy importante porque así al reexportar se mantendrán los mismos IDs en vez de regenerarse.
;;
;; Este código es chapucero, y le quedan errores. Pero funciona y lo uso en las páginas de https://www.danielclemente.com/hacer/
;;
;; Esto incluye:
;; - mis arreglos (del 7.m5.2022):
;;   - adaptado a GNU Emacs
;;   - le desactivo parte de prefijar con padre cuando hay ambigüedad
;;   - le desactivo el quitar palabras y el quitar/destrozar letras no ASCII
;;   - hago que se active en bloques EXAMPLE también
;;   - añado comentarios del código que entiendo (o no) mientras lo pruebo
;; - Está basado en https://tecosaur.github.io/emacs-config/config.html#nicer-generated-heading
;; - … que extendió de https://github.com/alphapapa/unpackaged.el#export-to-html-with-useful-anchors
;; - … que extendió de org-mode
;;
;; Esto está bajo licencia GPLv3, igual que los anteriores.
;;
;; Quedan fallos:
;; - cuando ha tenido que añadir „,example--1“ „,example--2“ etc. para desambiguar (ej. „puedo-instrumentar-para,example--1“) me parece que no lo recuerda, y al reexportar le puede llamar 2 al que antes llamaba 1, etc.
;; - hay aún otros IDs que están escapando de este sistema: las etiquetas radio, y algo llamado „figure“. (ej. <div id="org998a81c" class="figure">). Eso causa que los IDs sigan cambiando en cada exportación
;; - el código no es bonito
;; - hay que contribuir esto a Emacs


;; dclemente: me parecen bien los números
(defvar org-reference-contraction-max-words 3
  "Maximum number of words in a reference reference.")
(defvar org-reference-contraction-max-length 35
  "Maximum length of resulting reference reference, including joining characters.")
(defvar org-reference-contraction-stripped-words
  '(
    ;; dclemente: ni siquiera en inglés quiero exterminar estas palabras. ¡Son bonitas! Tampoco en español le tengo manía a ninguna de las cortas
    ;;    "the" "on" "in" "off" "a" "for" "by" "of" "and" "is" "to"
    )
  "Superfluous words to be removed from a reference.")
(defvar org-reference-contraction-joining-char "-"
  "Character used to join words in the reference reference.")

;; ver pruebas de cada función, tras la función
;; Los textos y documentación no los he escrito yo sino que estaban en la original
(defun org-reference-contraction-truncate-words (words)
  "Using `org-reference-contraction-max-length' as the total character 'budget' for the WORDS
  and truncate individual words to conform to this budget.
  
  To arrive at a budget that accounts for words undershooting their requisite average length,
  the number of characters in the budget freed by short words is distributed among the words
  exceeding the average length.  This adjusts the per-word budget to be the maximum feasable for
  this particular situation, rather than the universal maximum average.
  
  This budget-adjusted per-word maximum length is given by the mathematical expression below:
  
  max length = \\floor{ \\frac{total length - chars for seperators - \\sum_{word \\leq average length} length(word) }{num(words) > average length} }"
  ;; trucate each word to a max word length determined by
  ;;
  (let* ((total-length-budget (- org-reference-contraction-max-length  ; how many non-separator chars we can use
                                 (1- (length words))))
         (word-length-budget (/ total-length-budget                      ; max length of each word to keep within budget
                                org-reference-contraction-max-words))
         (num-overlong (-count (lambda (word)                            ; how many words exceed that budget
                                 (> (length word) word-length-budget))
                               words))
         (total-short-length (-sum (mapcar (lambda (word)                ; total length of words under that budget
                                             (if (<= (length word) word-length-budget)
                                                 (length word) 0))
                                           words)))
         (max-length (/ (- total-length-budget total-short-length)       ; max(max-length) that we can have to fit within the budget
                        num-overlong)))
    (mapcar (lambda (word)
              (if (<= (length word) max-length)
                  word
                (substring word 0 max-length)))
            words)))

;; pruebo la función anterior
;;  (org-reference-contraction-truncate-words '("hola" "esto" "es" "una" "prueba"))
;;  (org-reference-contraction-truncate-words '("hola" "esto" "pruebo"))
;;  (org-reference-contraction-truncate-words '("hola" "esto" "pruebo" "es" "una" "frase" "muy" "larga"))
;; ah, lo anterior no va porque les falta palabra extralarga
;;  (org-reference-contraction-truncate-words '("hola" "esto" "es" "una" "pruebayhayunapalabraextralarga" "que" "no" "cabe"))
;;  (org-reference-contraction-truncate-words '("hola" "estoespalabralarga" "Hay" "una" "pruebayhayunapalabraextralarga" "que" "no" "cabe"))
;;  (org-reference-contraction-truncate-words '("variaaaas" "estoespalabralarga" "palaaabras" "pruebayhayunapalabraextralarga"))
;; Veo que les hace tener longitud parecida

;; ver pruebas abajo
(defun org-reference-contraction (reference-string)
  "Give a contracted form of REFERENCE-STRING that is only contains alphanumeric characters.
  Strips 'joining' words present in `org-reference-contraction-stripped-words',
  and then limits the result to the first `org-reference-contraction-max-words' words.
  If the total length is > `org-reference-contraction-max-length' then individual words are
  truncated to fit within the limit using `org-reference-contraction-truncate-words'."
  (let ((reference-words
         (-filter (lambda (word)
                    (not (member word org-reference-contraction-stripped-words)))
                  (split-string
                   (->> reference-string
                        downcase
                        (replace-regexp-in-string "\\[\\[[^]]+\\]\\[\\([^]]+\\)\\]\\]" "\\1") ; get description from org-link
                        (replace-regexp-in-string "[-/ ]+" " ") ; replace seperator-type chars with space
                        ;; dclemente: no me parece bien la versión que encontré:
                        ;; puny-encode-string
                        ;; (replace-regexp-in-string "^xn--\\(.*?\\) ?-?\\([a-z0-9]+\\)$" "\\2 \\1") ; rearrange punycode
                        ;; (replace-regexp-in-string "[^A-Za-z0-9 ]" "") ; strip chars which need %-encoding in a uri
                        ;;
                        ;; … pues encontrar punycode en un ID es feo, y quitar LETRAS también (independientemente del alfabeto usado). Me va bien si salen palabras como „índice“ etc. en IDs
                        ;; Por tanto prefiero quitar las no-letras/números, y sólo eso
                        (replace-regexp-in-string "[^[:alnum:] ]" "")
                        

                        ) " +"))))
    (when (> (length reference-words)
             org-reference-contraction-max-words)
      (setq reference-words
            (cl-subseq reference-words 0 org-reference-contraction-max-words)))
    
    (when (> (apply #'+ (1- (length reference-words))
                    (mapcar #'length reference-words))
             org-reference-contraction-max-length)
      (setq reference-words (org-reference-contraction-truncate-words reference-words)))
    
    (string-join reference-words org-reference-contraction-joining-char)))
;; La pruebo:
;; (org-reference-contraction "Hola, esto es una prueba")
;; (org-reference-contraction "Hola, esto es una prueba de frase muy larga")
;; (org-reference-contraction "¡Hola!, esto es una prueba")
;; (org-reference-contraction "¡Hola!")
;; (org-reference-contraction "xfa-hola")
;; (org-reference-contraction "¡Hhñaßlŀl他ĉ𒆷y👍🏼…👨‍👩‍👧2!")
;; (org-reference-contraction "Hola, palabramuymuylargaperomuchomuchomuchísimo")
;; (org-reference-contraction "Palabramuymuylargaperomuchomuchomuchísimo")
;; (org-reference-contraction "Palabramuymuylargaperomuchomuchomuchito")
;; (org-reference-contraction "¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡")
;; (org-reference-contraction "++++++")
;; (org-reference-contraction "…")
;; (org-reference-contraction "")
;; (org-reference-contraction ": hola")
;; (org-reference-contraction "- hola")
;; (org-reference-contraction "+hola+")
;; (org-reference-contraction "∴ +hola+")
;; (org-reference-contraction "|| ∴ ∴ - - - [#] [[]]      +hola+")

;; ----------------------
;; Esto vino de otro paquete

(define-minor-mode unpackaged/org-export-html-with-useful-ids-mode
  "Attempt to export Org as HTML with useful link IDs.
  Instead of random IDs like \"#orga1b2c3\", use heading titles,
  made unique when necessary."
  :global t
  (if unpackaged/org-export-html-with-useful-ids-mode
      (advice-add #'org-export-get-reference :override #'unpackaged/org-export-get-reference)
    (advice-remove #'org-export-get-reference #'unpackaged/org-export-get-reference)))
(unpackaged/org-export-html-with-useful-ids-mode 1) ; ensure enabled, and advice run


;; dclemente: veo que aquí se implementa una caché (¿o extiende la de org?). ¿Qué formato tiene? Me es difícil probar todo esto
(defun unpackaged/org-export-get-reference (datum info)
  "Like `org-export-get-reference', except uses heading titles instead of random numbers."
  (let ((cache (plist-get info :internal-references)))
    (or (car (rassq datum cache))
        (let* (
               ;; dclemente: ¿qué es esto?
               ;; „crossrefs“ contien algo raro, tipo
               ;; (((other "No," "no" "tengo" "ese" "problema") . "no-no-tengo") ((headline "No," "no" "tengo" "ese"
               ;; "problema") . "no-no-tengo") ((other "esto" "sí" "que" "va") . "esto-sí-que") ((headline "esto" "sí"
               ;; "que" "va") . "esto-sí-que") ((other "el" "mensaje" "de" "error" "es" "malo") . "el-mensaje-de")
               ;; ((headline "el" "mensaje" "de" "error" "es" "malo") . "el-mensaje-de") ((other "estar," "está") .
               ;; "estar-está") ((headline "estar," "está") . "estar-está") ((other "pruebo" "con" "2.3") .
               ;; "pruebo-con-23") ((headline "pruebo" "con" "2.3") . "pruebo-con-23") ((other "copio" "los"
               ;; […]
               ;; No sé por qué salen dos veces, como headline y como other
               (crossrefs (plist-get info :crossrefs))

               ;; dclemente: ¿qué es esto?
               ;; Ver docum.
               ;; „A search cell follows the pattern (TYPE . SEARCH) where […]“
               ;; Queda en nil muchas veces cuando no encuenta nada
               (cells (org-export-search-cells datum))

               ;; Preserve any pre-existing association between
               ;; a search cell and a reference, i.e., when some
               ;; previously published document referenced a location
               ;; within current file (see
               ;; `org-publish-resolve-external-link').
               ;;
               ;; However, there is no guarantee that search cells are
               ;; unique, e.g., there might be duplicate custom ID or
               ;; two headings with the same title in the file.
               ;;
               ;; As a consequence, before re-using any reference to
               ;; an element or object, we check that it doesn't refer
               ;; to a previous element or object.
               (new (or
                     ;; dclemente: veo que empieza gran „or“ con 4 formas de obtener esto. No estaba muy claramente documentado.
                     ;; Para ver qué pasa:
                     ;; (if (eq (car datum) 'example-block) (debug))
                     ;; Las 4 formas:
                     ;;
                     ;; FORMA 1
                     ;; ¿qué es esto de „crossrefs“? Ver arriba cuando se prepara
                     ;; dclemente: voy a marcarla: ← por hacer
                     (cl-some
                      (lambda (cell)
                        (let ((stored (cdr (assoc cell crossrefs))))
                          (when stored
                            (let ((old (org-export-format-reference stored)))
                              (and (not (assoc old cache)) stored)))))
                      cells)

                     ;; FORMA 2
                     ;; dclemente: estos dos „when“ (forma 2 y 3), ¿por qué no son „if“? ¿Y por qué no son ramas de un mismo condicional como „pcase“? („(pcase (org-element-type datum)“). De hecho, ¿por qué hay código repetido en f2 y f3?
                     ;; dclemente: ¿por qué se ha dejado la llamada a org-export-format-reference? El original la tenía. Aunque sea idempotente creo que debería hacerlo
                     (when (org-element-property :raw-value datum)
                       ;; Heading with a title
                       (unpackaged/org-export-new-named-reference datum cache))
                     ;; FORMA 3
                     ;; ver arriba en f2 sobre el „when“
                     ;; dclemente: también falta org-export-format-reference; ver comentario en f2
                     (when (member (car datum)
                                   '(
                                     ;; dclemente: aquí ponía 'example pero creo que ha de ser 'example-block (comprobado en org-element-all-elements). Cambiado
                                     src-block table example-block fixed-width property-drawer
                                     ))
                       ;; dclemente: probando este caso
                       ;; (debug)
                       ;; Nameable elements
                       (unpackaged/org-export-new-named-reference datum cache))
                     ;; FORMA 4
                     ;; dclemente: ¿de qué va esto? ¿Por qué añadieron este comentario?
                     ;; NOTE: This probably breaks some Org Export
                     ;; feature, but if it does what I need, fine.
                     ;; dclemente: voy a marcarla:    ← en realidad quiero „si no nil, prefíjala; si no, no“. Pero en este caso sé que nunca devuelve nilo
                     (concat
                      ""
                      ;; "conforma4--"
                      (org-export-format-reference
                       (org-export-new-reference cache))
                      )
                     ;; AQUÍ ACABAN las 4 formas
                     ))
               ;; dclemente: ¿esto es sólo para cambiarle el nombre a la variable? ¿Por qué luego abajo aún usa „new“ y „reference-string“?
               ;; Ah, por lo visto esta línea es el remanente de modificar ésta de org:  (reference-string (org-export-format-reference new))
               ;; Pero ¿por qué lo quitaron?
               (reference-string new))
          ;; Cache contains both data already associated to
          ;; a reference and in-use internal references, so as to make
          ;; unique references.
          (dolist (cell cells) (push (cons cell new) cache))
          ;; Retain a direct association between reference string and
          ;; DATUM since (1) not every object or element can be given
          ;; a search cell (2) it permits quick lookup.
          (push (cons reference-string datum) cache)
          (plist-put info :internal-references cache)
          reference-string))))

;; dclemente: ésta es la función más compleja y no la puedo probar bien: Emacs se cuelga excesivamente mientras trazo y depuro, y pronto acaba consumiendo muchos Gb. Es todo debido a manejar estructuras muy grandes de datos (debería truncarlas cuando intenta mostrármelas)
(defun unpackaged/org-export-new-named-reference (datum cache)
  "Return new reference for DATUM that is unique in CACHE."
  ;; dclemente: ¿por qué tan complejo? Modestia aparte, pero lo he reimplentado en 2 líneas y sin necesidad de macros/dash.el/rx/cl-incf. Mi implementación es cutre pero va:  (let* ( (ca "hola--123") (trozos (split-string ca "--")) (nueca (concat (car trozos) "--" (number-to-string (1+ (string-to-number (or (nth 1 trozos) "0"))))))) nueca)
  ;; Quizás debería reemplazar ésta por mi implementación
  (cl-macrolet ((inc-suffixf (place)
                  `(progn
                     (string-match (rx bos
                                       (minimal-match (group (1+ anything)))
                                       (optional "--" (group (1+ digit)))
                                       eos)
                                   ,place)
                     ;; HACK: `s1' instead of a gensym.
                     (-let* (((s1 suffix) (list (match-string 1 ,place)
                                                (match-string 2 ,place)))
                             (suffix (if suffix
                                         (string-to-number suffix)
                                       0)))
                       (setf ,place (format "%s--%s" s1 (cl-incf suffix)))))))
    (let* ((headline-p (eq (car datum) 'headline))
           ;; dclemente: no entiendo esta parte. Entiendo: „Da el título si es cabecera. Para otros: si tiene un nombre, dalo. Si no, toma ¿el padre del padre…?“
           (title (if headline-p
                      (org-element-property :raw-value datum)
                    (or (org-element-property :name datum)
                        (concat (org-element-property :raw-value
                                                      (org-element-property :parent
                                                                            (org-element-property :parent datum)))))))
           ;; get ascii-only form of title without needing percent-encoding
           (ref (concat (org-reference-contraction (substring-no-properties title))
                        ;; dclemente: ¿qué es esto? Por lo visto da IDs a cosas como los #+BEGIN_EXAMPLE, para que sean „id-de-esta-sección,example--1“, „id-de-esta-sección,example--2“ etc.
                        ;; Pero en mis pruebas, no aparecen estos códigos en el HTML final → ah, tuve que insistir mucho y borrar cachés, y entonces fue
                        ;; Por cierto, cada vez que pruebo esto he de vaciar caché de /org-publish/, ver ahí
                        ;; (debug)
                        ;; (unless headline-p (debug))  ;; no me paro en „headline“
                        ;; (if (eq (car datum) 'example-block) (debug))
                        (unless (or headline-p (org-element-property :name datum))
                          (concat ","
                                  (pcase (car datum)
                                    ('src-block "code")
                                    ;; dclemente: aquí ponía 'example, pero creo que se llama 'example-block
                                    ;; ('example "example")
                                    ('example-block "example")
                                    ('fixed-width "mono")
                                    ('property-drawer "properties")
                                    ;; Me pregunto también si le falta algo para procesar tablas (#+TBLNAME: …)
                                    ;; Se lo añado, no sé si está bien
                                    ('table "table")
                                    ;; dclemente: creo que falta otro aquí: los „figure“. No sé código
                                    ;;
                                    ;; dclemente: ¿qué es esto? „_“ se activa como último recurso
                                    ;; Lo puedo retocar un poco para buscar qué hace
                                    ;; (_ (concat "«" (symbol-name (car datum)) "»"))
                                    ;; No lo veo activarse. Lo dejaré como estaba:
                                    (_ (symbol-name (car datum)))
                                    )
                                  "--1"))))
           ;; dclemente: Aquí le desactivaré eso tan inteligente de „prefija con el ID del padre“, porque no está funcionando bien y no estoy seguro de que esté bien implementado (se me ocurren casos extremos que quizás lo rompen, y no tengo tiempo de probarlos). Al desactivarlo me quedo con el sistema de añadir -1, -2, etc.
           ;;(parent (when headline-p (org-element-property :parent datum)))
           (parent nil)
           )
      ;; me miro un poco cómo va ahora, en concreto „ref“. Es correcto
      ;; (if (eq (car datum) 'example-block) (debug))
      (while (--any (equal ref (car it))
                    cache)
        ;; Title not unique: make it so.
        (if parent
            ;; Append ancestor title.
            ;; dclemente: esta parte está desactivada, ver arriba el „(parent nil)“
            (setf title (concat (org-element-property :raw-value parent)
                                "--" title)
                  ;; get ascii-only form of title without needing percent-encoding
                  ref (org-reference-contraction (substring-no-properties title))
                  parent (when headline-p (org-element-property :parent parent)))
          ;; No more ancestors: add and increment a number.
          (inc-suffixf ref)))
      ;; dclemente: veo que lo devuelve pero no ha hecho nada más, como grabarlo en algún lado. Eso lo hace el llamante
      ref)))

(add-hook 'org-load-hook #'unpackaged/org-export-html-with-useful-ids-mode)

;; le tengo que arreglar esto para que vaya en GNU Emacs
;; (defadvice 
;;    org-export-format-reference
;;    (around org-export-format-reference-a (reference) activate)
;;   "Format REFERENCE into a string.
;; 
;; REFERENCE is a either a number or a string representing a reference,
;; as returned by `org-export-new-reference'."
;;   (if
;;      (stringp reference) 
;;      reference
;;    (format "org%07x" reference)
;;    ))

;; quizás mejor:
(defun org-export-format-reference--paracadenaonúmero (reference)
  ;; dclemente: aún no sé cuándo se usa cada variante. No encuentro usada la 1ª → creo que es porque la forma 2 y 3 de encontrar los IDs (las formas que fueron añadidas inoficialmente) se saltan el llamar a esta función porque saben que no iba a hacer nada. Mmmm… Es mala práctica; creo que habría que llamarla siempre
  (if
      (stringp reference) 
      ;; Era:
      reference
    ;; ← por cierto, Emacs me lo indenta mal
    ;; pero pruebo:
    ;; (concat "org142857" reference)
    (format "org%07x" reference)
    ;; (format "orgĥ-%07x" reference)
    )
  )
(advice-add #'org-export-format-reference :override #'org-export-format-reference--paracadenaonúmero)
;; Y la pruebo:
;; (org-export-format-reference--paracadenaonúmero 20222)
;; (org-export-format-reference--paracadenaonúmero "hola")

;; ---------
;; Qué chapucero todo este código… Ver arriba las limitaciones

8. .emacs-simple (un .emacs alternativo para simplificar Emacs)

Una configuración simplificada de Emacs para hacer más sencilla la interfaz (le quita lo complejo). La empecé cuando mi madre se interesó por org-mode (para guardar mucha información en estructura de árbol).

Sin probar desde hace tiempo.

;; -*- mode: emacs-lisp; mode:outline-minor; outline-regexp:";;;;* [^    \n]" -*-

;; Configuración de GNU Emacs para que sea sencillo para alguien que no entiende de informática.
;; Atención: no se intenta mantener parecido con otros programas, sino tener un sistema consistente, simple y eficaz. Por eso no tiene sentido copiar teclas como C-z C-v C-y, o botones como copiar/pegar, …
;;
;; Le hace:
;; - pone colores que no duelen a la vista
;; - quita inglesachos
;; - pone barra de iconos con muy pocos
;; - cambia forma de salir
;; - edita siempre el mismo búfer
;; 
;; Versión 0.1.  1.m11.2010. Daniel Clemente. n142857@gmail.com
;;
;; BONUS:
;; - ordenar
;; - traducir

;; carga
(require 'org)
;; tema y colores
(let ((d "/usr/share/emacs23/site-lisp/emacs-goodies-el/"))
  (when (file-exists-p d) 
    (add-to-list 'load-path d)
    (require 'color-theme)
    (let ((d2 (concat d "color-theme-library.elc")))
      (when (file-exists-p d2) (load-file d2)))
    ;;  (require 'color-theme-library)

    ))


(require 'color-theme)
(color-theme-hober)

(setq org-ellipsis (quote org-column))
(set-face-background 'org-column "grey20") ; era grey30; demasiado brillante y poco contrastante con el 1r plano
(setq org-startup-truncated nil)

;; al salir

;; para el cuadro al salir:
;; interesante: save-some-buffers-action-alist

;; las preguntas se responden con y/n                 
(fset 'yes-or-no-p 'y-or-n-p)
;; Pregunta antes de salir, porque a veces aprieto C-x C-c por error
(add-to-list 'kill-emacs-query-functions
             (lambda () 
               (y-or-n-p "Ĉu mi fermu Emakson? (j/n): "))) 
;; mejor no
(setq kill-emacs-query-functions nil)
;; Aparentemente esto haría lo mismo: 
;; (setq confirm-kill-emacs yes-or-no-p)          ; Confirm quit 

;; El problema ya está en save-some-buffers, que pregunta mucho 
;; Pero puedo mejorar save-buffers-kill-emacs:

;; (defun save-buffers-kill-emacs-142857 (&optional arg)
(defun save-buffers-kill-emacs (&optional arg)
  "Offer to save each buffer, then kill this Emacs process.
With prefix ARG, silently save all file-visiting buffers, then kill."
  (interactive "P")
  ;; (save-some-buffers arg t)
  (and (or (not (memq t (mapcar (function
                                 (lambda (buf) (and (buffer-file-name buf)
                                                    (buffer-modified-p buf))))
                                (buffer-list))))
           (yes-or-no-p "Hay cambios sin grabar. ¿Aún así quieres salir? yes=Salir, no=quedarse"))
       (or (not (fboundp 'process-list))
           ;; process-list is not defined on MSDOS.
           (let ((processes (process-list))
                 active)
             (while processes
               (and (memq (process-status (car processes)) '(run stop open listen))
                    (process-query-on-exit-flag (car processes))
                    (setq active t))
               (setq processes (cdr processes)))
             (or (not active)
                 (list-processes t)
                 ;; (yes-or-no-p "Active processes exist; kill them and exit anyway? ")
                 t

                 )))
       ;; Query the user for other things, perhaps.
       (run-hook-with-args-until-failure 'kill-emacs-query-functions)
       (or (null confirm-kill-emacs)
           (funcall confirm-kill-emacs "Really exit Emacs? "))
       (kill-emacs)))



;; teclillas

(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "<XF86ModeLock>") 'ignore)
(global-set-key [f12] 'cambia-a-búfer-para-notas)
(global-set-key [(control f12)] 'cambia-a-búfer-de-mensajes)

(defun cambia-a-búfer-para-notas ()
  "Va al búfer *scratch*"
  (interactive)
  (switch-to-buffer "*scratch*")
  )
(defun cambia-a-búfer-de-mensajes ()
  "Va al búfer *Messages*"
  (interactive)
  (switch-to-buffer "*Messages*")
  )



;; modos extra
(show-paren-mode 1)

;; barra de  iconos
;; tool-bar-map
;; hacer como tool-bar-setup
(setq tool-bar-map (make-sparse-keymap)) ; borrar
;; Ej. (tool-bar-add-item "pink-gnu" 'pink-bliss-save-or-open 'pink-defun)
(tool-bar-add-item-from-menu 'menu-find-file-existing "open")
;; (tool-bar-add-item-from-menu 'dired "diropen")
(tool-bar-add-item-from-menu 'save-buffer "save" nil
                             :visible '(or buffer-file-name
                                           (not (eq 'special
                                                    (get major-mode
                                                         'mode-class)))))
(tool-bar-add-item-from-menu 'undo "undo" nil
                             :visible '(not (eq 'special (get major-mode
                                                              'mode-class))))
;; (tool-bar-add-item-from-menu 'save-buffers-kill-emacs "exit")
(tool-bar-add-item-from-menu 'save-buffers-kill-terminal "exit")



;; barra de menús
(menu-bar-mode -1)

;; variables varias, por 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.
 '(inhibit-startup-screen t)
 '(initial-scratch-message nil))
(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.
 )

;; abrir ficheros iniciales
(find-file "~/notas.org")

9. otros que no pongo

Me salto ficheros que uso pero que incluyen datos privados o que no tienen nada interesante. Éstos son unas 2100 líneas, 86 Kb en total. Son éstos:

lerno.el
funciones Lisp de pruebas, mientras aprendía
trabajo.el
funciones guarrillas para automatizar tareas repetitivas en cada puesto de trabajo en que he estado. Ej. abrir ficheros que uso frecuentemente, desplegar un código a un servidor, y poco más
montrilo.el
para cambiar a modo para presentar o enseñar ficheros y cerrar todo lo privado
privado-nocable.el
configuraciones con datos sensibles o secretos. Ej. notas privadas aún no listas para publicar, o direcciones de e-mail
privado-claves.el
contraseñas para servicios (correo, IRC, …) a los que accedo desde Emacs
gnus.el
configuración vieja de este lector de correo, de cuando lo usaba (ahora uso wanderlust)
.org-ficheros-agenda.el
para poner y quitar ficheros dentro de mi agenda org dependiendo del ordenador en el que estoy

Además uso paquetes externos; los mencionados en el punto-emacs. Y compilo regularmente el GNU Emacs.

Ver también: (algo desfasado) varios problemas de Emacs a solucionar.

Y si te interesa lo del org-mode, algo más sobre cómo gestiono notas y tareas.


2020, Daniel Clemente Laboreo (web, correo). Actualizado el 20.m03.2023