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 14.m09.2024; Daniel Clemente. Batallando Emacs desde 2007. Casi sin darme cuenta llevo escritas 17400 líneas, 796 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, y conmutando con outlyne-cycle etc. (ver abajo las teclas que le di)

;;; 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


;; Herramientas rápidas para depurar (y para cuando necesito un .emacs simplificado)
;; Probando mientras depuro https://debbugs.gnu.org/cgi/bugreport.cgi?bug=71176
;; 
;;(setq garbage-collection-messages t)
;;(set-face-foreground 'default "#bbb")
;;(setq max-lisp-eval-depth 100)
;; Pruebas:
;; Para causar desbordamiento de pila Lisp:
;; (defun recurse () (recurse))
;; (recurse)
;; (run-with-timer 0 3 #'recurse)
;; Para causar GC:
;; (setq gc-cons-threshold 1000)
;; (setq gc-cons-threshold 10000)
;; (cl-loop for i from 300000 downto 1 do (+ 2.00 (+ 2.0 (+ 2.0 (+ 2.0 (+ 2.0 2.0))))))
;; (cl-loop for j from 100 downto 1 do (progn (cl-loop for i from 30000 downto 1 do (+ 2.00 (+ 2.0 (+ 2.0 (+ 2.0 (+ 2.0 2.0)))))) (sit-for 1)))
;; (cl-loop for i from 3000000 downto 1 do (garbage-collect))
;; (run-with-idle-timer 1 t #'garbage-collect)
;; (run-with-timer 0 1 #'garbage-collect)
;; (run-with-timer 0.1 0.1 #'garbage-collect)
;; Experimentos extraños
;; (run-with-timer 0.1 0.1 #'debug)
;; (run-with-timer 0.1 0.1 #'redisplay)
;; (run-with-timer 0.1 0.1 '(lambda () (progn (redisplay t) (message "Hecho red. %s" (current-time)))))

;;;; 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

;; Desfasado, lo quito en m6.2024
;;(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

;; Veo demasiado frecuentemente estos mensajes, y preferiría que emacs no hiciere gc en momentos de mucho trabajo

;; gc-cons-percentage: era 0.1 (10%)
;; se mide en „fracción del total reservado“
;; Hacer GC cuando ~~~~ +10% nuevo se reserva

;; gc-cons-threshold: era 800000
;; Subirlo: GC será menos frecuente, pero será más lenta
;; Veo que otros hacen cosas como ponerlo muy alto (* 100 1024 1024) y luego (* 20 1024 1024) justo después. Ej. https://lists.gnu.org/archive/html/emacs-devel/2023-10/msg00392.html
;; O ponerlo alto sólo durante arranque. ~~ ẽ Doom
;; No quiero hacer errores al ponerlo, estilo https://emacs.stackexchange.com/questions/5351/optimizing-font-lock-performance

;; ¿Por qué se pueden poner a mano? Emacs debería ir ajustando estos límites autoanalizándose


;;; 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 iban bien estas teclas:
;; C-TAB (detecta TAB)
;; C-/ (detecta DEL)
;; M-< (no detecta nada)
;; M-: (no detecta nada)
;; S-F12 (no detecta nada)
;; Con el tiempo, emacs mejoró y ya se detectan.


;; Lo siguiente fue detectar combinaciones complejas con Shift, como Meta-Shift-letra, Control-Shift-letra, y Meta-Control-Shift-letra



;; v1 BORRABLE: (defun define-teclas-y-otras-cosas-en-nueva-terminal-modo-texto ()
;; v1 BORRABLE:   ;; un poco copiado de https://blog.hiebl.cc/posts/urxvt-and-emacs-ultimate-guide/#configs
;; v1 BORRABLE:   ;; Requiere xterm-keybinder
;; v1 BORRABLE: 
;; v1 BORRABLE:   (pita-de-verdad-cortito)
;; v1 BORRABLE: 
;; v1 BORRABLE:   ;; enable mouse interaction
;; v1 BORRABLE:   (xterm-mouse-mode)
;; v1 BORRABLE: 
;; v1 BORRABLE:   ;; if the terminal was inited by the terminal-init-rxvt, the
;; v1 BORRABLE:   ;; terminal is a rxvt terminal => trigger keybinding init
;; v1 BORRABLE:   (cl-case (assoc-default 'terminal-initted (terminal-parameters))
;; v1 BORRABLE:     ;; if the init function for rxvt was executed, this likely is a rxvt terminal
;; v1 BORRABLE:     (terminal-init-rxvt
;; v1 BORRABLE:      ;; check if the terminal is urxvt with 256color
;; v1 BORRABLE:      (when (equal
;; v1 BORRABLE:             ;; DCL: parece que ahora ya no lleva la parte „-unicode-“, aunque lo es
;; v1 BORRABLE:             ;; "rxvt-unicode-256color"
;; v1 BORRABLE:             "rxvt-256color"
;; v1 BORRABLE:             (getenv "TERM" (selected-frame)))
;; v1 BORRABLE:        (pita-de-verdad-cortito)
;; v1 BORRABLE:        ;; setup the keybindings for urxvt
;; v1 BORRABLE:        (urxvt-keybinder-setup)
;; v1 BORRABLE: 
;; v1 BORRABLE:        ;; register some missing keybindings
;; v1 BORRABLE:        (define-key input-decode-map "\033[=<" (kbd "C-S-<"))
;; v1 BORRABLE:        (define-key input-decode-map "\033[=>" (kbd "C-S->")))))
;; v1 BORRABLE: 
;; v1 BORRABLE:   ;; DCL: creo que no necesito esto aún:
;; v1 BORRABLE:   ;; DCL: ;; workaround: terminal has already been initialized, but color
;; v1 BORRABLE:   ;; DCL: ;; scheme is wrong for my theme, this fixes the color scheme
;; v1 BORRABLE:   ;; DCL: (terminal-init-xterm)
;; v1 BORRABLE:   ;; DCL: ;; set the font face for the background to white
;; v1 BORRABLE:   ;; DCL: (set-face-background 'default "unspecified-bg" (selected-frame))
;; v1 BORRABLE: 
;; v1 BORRABLE:   )
;; v1 BORRABLE: 
;; v1 BORRABLE: (add-hook 'tty-setup-hook 'define-teclas-y-otras-cosas-en-nueva-terminal-modo-texto)
;; v1 BORRABLE: ;; (remove-hook 'tty-setup-hook 'define-teclas-y-otras-cosas-en-nueva-terminal-modo-texto)
;; v1 BORRABLE: 
;; v1 BORRABLE: 

(defun define-teclas-y-otras-cosas-en-nueva-terminal-modo-texto ()
  "Define teclas que he puesto en .Xresources, y ajusta otras cosas para hacer „emacsclient -nw“ más cómodo. Gracias a esto puedo detectar combinaciones de teclas como C-S-<, C-M-S-p, M-S-o, etc."

  ;; (pita-de-verdad-cortito)

  ;; enable mouse interaction
  (xterm-mouse-mode)

  ;; Requiere xterm-keybinder
  (urxvt-keybinder-setup)

  ;; Otras que faltaban, y que ha añadidod https://blog.hiebl.cc/posts/urxvt-and-emacs-ultimate-guide/#configs
  (define-key input-decode-map "\033[=<" (kbd "C-S-<"))
  (define-key input-decode-map "\033[=>" (kbd "C-S->"))

  ;; ¿hace falta esto? Ver mis notas
  ;; (define-key input-decode-map "\033[===K" (kbd "M-S-k"))

  ;; Aún faltan algunas:
  ;; C-M-S-arriba
  ;; C-M-S-abajo
  ;; (ésas las uso y necesito)
  ;; Las añado a .Xresources, y me invento secuencias de control. Todo esto va
  (define-key input-decode-map "\033[==^ARR" (kbd "C-S-M-<up>"))
  (define-key input-decode-map "\033[==^ABA" (kbd "C-S-M-<down>"))
  ;; otras no las necesito

)

(add-hook 'terminal-init-rxvt-hook 'define-teclas-y-otras-cosas-en-nueva-terminal-modo-texto)

;;;; teclas globales

;; Antiguamente usaba global-set-key. Sólo en m3.2024 descubrí que keymap-global-set es mejor (ẽ valida la forma de escribir la tecla); ∴ usar keymap-global-set a partir de ahora.

;;;;; C-x C-j, para atajos, lo uso para lanzar wl, jabber, …

;; 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)
;; (boundp '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)
;; Aunque a veces por algo la pierdo y he de ejecutarlo a mano


;; 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

;; Me hizo falta otra vez hacer esto, para jabber. Quizás hacerlo TRAS cargar jabber
(define-key ctl-x-map "\C-j" acceso-funciones-varias-map)

;; Más abajo en varios sitios le añado teclas

;;;;; 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
(keymap-global-set "M-k" 'kill-this-buffer--pero-de-verdad)
;; (global-set-key (kbd "<M-k>") 'kill-this-buffer--pero-de-verdad) ; no va

;; 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
;; ¿por qué en „-nw“ no me va? Incluso con xterm-keybinder. Estoy mandando lo que toca: ^[[===K  pero no va. Aún me dice: „M-k runs the command kill-this-buffer--pero-de-verdad“ → ∴ ver abajo el keymap-global-set
;; (global-set-key "\M-K" 'bury-buffer)
;; (global-set-key (kbd "<M-S-k>") 'bury-buffer)
;; (global-set-key (kbd "<M-S-k>") 'pita-de-verdad-cortito)
;; (global-set-key (kbd "<M-S-K>") 'pita-de-verdad-cortito)
;; (global-set-key (kbd "<M-K>") 'pita-de-verdad-cortito)

;; Pruebitas:
;; (keymap-lookup input-decode-map "„…………aquíteníaun^[real……………“[===K")  ;; ← aparentemente mal usado
;; (keymap-lookup global-map (kbd "<M-S-k>"))  ;; ← no sé usar keymap-lookup

;; Aaaaaaaah, la solución es usar keymap-global-set en vez de global-set-key (que está desfasado). Eso me indicó que el formato de escribir teclas estaba mal, Le sobra el „\“. Tras eso, pruebo, y esto va:
;; (keymap-global-set "M-S-k" 'pita-de-verdad-cortito)
(keymap-global-set "M-S-k" 'bury-buffer)
;; Por algún motivo „S-k“ y „K“ son distintos, y alguna vez me hace falta esto (ẽ si quiero apretar „ESC S-k“):
(keymap-global-set "M-K" 'bury-buffer)

;; Aún así me estoy encontrando con que no lo asigna, sino que queda así:     M-k (translated from M-K) runs the command kill-this-buffer--pero-de-verdad (found in global-map),


(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 un carácter de control especial que introduce códigos para Emacs mandados desde urxvt. Ver .Xresources
;; Antes eran (kbd "1") y (kbd "2") pero eso me causa conflictos con C-^
(global-set-key (kbd "[1001~")
                'other-window
                )
(global-set-key (kbd "[1001$") (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...
;; antes era mark-defun
;; (global-set-key "\C-\M-h" 'help-command)
(keymap-global-set "C-M-h" 'help-command)
;; ...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“
;; En consola se recibe como C-f1, así que lo pongo también
(global-set-key [(control f1)] #'(lambda () (interactive) (find-file "~/org/idp.org")))

(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





;;;;; teclas para edición
;; Cuando uso terminal (sin X):
;; Quiero „ “ con AltGr+9 bzw. +0 tal como en X   ← m2.2024: en realidad están en otro sitio ahora; quizás actualizar
;; 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?

(keymap-global-set "C-h" 'backward-delete-char-untabify) ; antes era help-command pero yo no necesito tanta ayuda


;; 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.
;; Atención: he diferenciado entre X y terminal, pero hay una tercera opción, intermedia: una terminal dentro de X (con „emacs -nw“ corriendo dentro). En ese caso me gustaría tratarlo como si fuera X

(defun mi-función-para-cortar (text &optional push)
  ;;    (if (window-system (selected-frame)) 
  ;;    (shell-command "pita la")
  ;;    (shell-command "pita la la"))
  ;; No entiendo lógica aquí. ¿Si no es X, llamo a xsel?
  (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
;; m2.2024: reemplazo por xclip, ver abajo
(ignore '(
          (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)

;; Parece que por defecto era esto. Pero esto no es apropiado para cuando estoy en „emacs -nw“
;;(setq interprogram-cut-function #'gui-select-text)
;;(setq interprogram-paste-function #'gui-selection-value)


;; m2.2024: alternativa a todo eso: pruebo xclip-mode. ¡Parece que funciona!
(xclip-mode 1)


;; 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

;; Por cierto, estoy definiendo ganchos aquí aunque wl-draft etc. no están cargados aún. Por lo visto funciona. El add-hook define esos ganchos
;; 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

            ;; Para moverse por listas etc.
            ;; (define-key org-mode-map (kbd "C-c n") #'org-next-item)
            ;; (define-key org-mode-map (kbd "C-c p") #'org-previous-item)
            (define-key org-mode-map (kbd "M-n") #'org-next-item)
            (define-key org-mode-map (kbd "M-p") #'org-previous-item)
            ))

;;;;; 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)
;; m3.2024: llevo años sin usarlo así que lo quitaré. 
;; (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)
;;

;;;;; svg (para editar a mano ficheros .svg)
;; Me basta con esto
(add-to-list 'auto-mode-alist '("\\.svg$" . xml-mode))

;;; 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


;; Muy cutrecillo, pero: ajusto el tema hober cuando estoy lanzando emacs-O3, que es un emacs especial que he compilado para siempre ser rápido. Lo cambio fondo negro, y lo hago transparente, para así marcar esta ventan como algo especial. Intenté hacer esto de otra forma (con parámetro al lanzar emacs) y no me funcionó. Pero no lo intenté mucho
;; Al rato encontré cómo hacer esto bien. ← pero no iba aún
;;(when
;;  (string-match "/w/emacs-O3/src/emacs"
;;                (shell-command-to-string (format "ps -h %i" (emacs-pid)))
;;                )
;;
;;  (message "Quito fondo negro, y lo hago transparente")
;;  (set-background-color "transparent")
;;  (set-background-color nil)
;;  (modify-frame-parameters (selected-frame) (list (cons 'background-color nil)))
;;  ;; Para mirarlo:
;;  (frame-parameters (selected-frame))
;;  (alist-get 'background-color (frame-parameters (selected-frame)))
;;  (message (alist-get 'background-color (frame-parameters (selected-frame))))
;;
;;  )


;;;; 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
(when
    ;;window-system
    (display-graphic-p)
  (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 global-hl-line-mode
;; 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
;; m3.2024: supongo que los fallos anteriores se han corregido y puedo ajustar los colores, así que si quiero puedo reactivar esto. Voy a probarlo otra vez
(global-hl-line-mode 1)


;; En realidad lo del resaltado de línea siempre 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
;; Pero estoy modificando más cosas ← ¿el qué? ¿Quién más hereda de 'highlight?
;; Podría probar a no cambiar los colores. De momento los dejo:
(set-face-background 'highlight "#008")
(set-face-foreground 'highlight "#ccc")
;; (set-face-foreground 'highlight nil)

;; pruebo a desconectar 'hl-line de 'highlight, y hacer que no defina primer plano. Así resalto el fondo sin perder la colorización del texto
(set-face-attribute 'hl-line nil :inherit nil :foreground 'unspecified :background "#008")

;;;; cursor

;; color del cursor: 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)
;; Irónicamente en m3.2024 mientras uso „emacs -nw“, el cursor parpadea sólo cuando estoy en „emacs -nw“ (pero no en X) y no lo consigo desactivar. → https://emacs.stackexchange.com/questions/18536/cant-remove-cursor-blinking-in-console-mode → esto ha de ir y va:
(setq visible-cursor nil)

;; 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), barra separadora
;; 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))

;; Pero standard-display-table es para „Display table to use for buffers that specify none.“
;; Hay otro: buffer-display-table
;; Además ẽ org usa otra tabla. Por eso la cambio también
;; (set-display-table-slot org-display-table 'vertical-border (make-glyph-code ?┃))
;; Hago que sean idénticos
;; (set-display-table-slot org-display-table 'vertical-border (display-table-slot standard-display-table 'vertical-border))
(eval-after-load "org" '(progn
                          (unless org-display-table
                            (setq org-display-table (make-display-table)))
                          (set-display-table-slot org-display-table 'vertical-border (display-table-slot standard-display-table 'vertical-border))
                          ))



;; Y hay algo llamado „márgen“
;; Esto es local a cada búfer
;; (setq right-margin-width 5)
;; Me añade un trozo que luego puedo clicar, y puedo contraer/expander secciones en outline-mode etc. Funciona pero me parece una interfaz pésima. Imagino que es para pantallas táctiles
;; Y el izquierdo:
;; (setq left-margin-width 5)

;; Esto quería usarlos. Pero yo no
(setq flymake-margin-indicator-position nil)


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

;;;; fuentes
;;;;; sobre los „font backend“ a usar (ver notas mías en org)

;; 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"))
;; m10.2023: vi que fuentes que he creado yo no van bien con este orden („x, xft, ftcr“): muchos caracteres van, pero otros como „a“ no se toman de mi fuente. Sólo pasa al usar la fuente enbuffer-face-mode, pero no pasa al usarla en „emacs -fn XXXXXXXXXX“.
;; Probé a quitar mi ajuste, pero vuelve a pasar lo malo (ver nota m11.2021 arriba)
;; Así que experimento con otros
;; (add-to-list 'default-frame-alist '(font-backend . "xfthb, ftcr"))
;; (add-to-list 'default-frame-alist '(font-backend . "xfthb"))
;; (add-to-list 'default-frame-alist '(font-backend . "x"))
;; (add-to-list 'default-frame-alist '(font-backend . "xfthb"))
;; (add-to-list 'default-frame-alist '(font-backend . "ftcr"))
;; (add-to-list 'default-frame-alist '(font-backend . "ftcr, x"))
;; (add-to-list 'default-frame-alist '(font-backend . "xft, x"))
;; (add-to-list 'default-frame-alist '(font-backend . "x, ftcr, xft"))
;; No encuentro nada bueno



;; Me encuentro con que no me usa las mismas fuentes en „emacs“ y en „emacsclient“. Ver notas en donde apunté lo de la oblicua 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:
;; m3.2024: me parece que ya no es necesario. Lo desactivo:
;; (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)

;;;;; por si las fuentes retardan GC: hay algo de caché de fuentes que se puede cambiar
;; inhibit-compacting-font-caches
;; No lo toco

;;;; 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

;; qué asco, en org-mode han decidido forzar un valor (8) para todos los usuarios, y sale un mensaje diciendo que el resto de valores son erróneos y hay que cambiarlos, y org-mode se niega a funcionar. En realidad es un tema personal, y me ha funcionado perfectamente con 4; poca necesidad había de cambiar esto. Es imponer el gusto de unas personas sobre el de otras
;; https://git.savannah.gnu.org/cgit/emacs/org-mode.git/tree/etc/ORG-NEWS#n36 → „*** ~tab-width~ value is now assumed to be 8“. En entrada de git 315417582


;; 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

;; 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
;;
;; v1:
;; No sé si va bien del todo. Aún he visto un:  tramp-error: 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)")

;; v2: „revbufs“. Ya lo tenía desde hace años pero lo olvidé. Por reusarlo. Desactivo v1

(add-to-list 'load-path "~/.emacs.d/revbufs") (require 'revbufs)
;; Y luego M-x revbufs
(defalias 'revertir-los-búfers-cambiados 'revbufs)
(defalias 'revert-all-changed-buffers 'revbufs)

;; No me gusta el comando „revbufs-mode“ que me ofrece; me confunde: a veces lo encuentro sugerido, cuando lo que busco es „revbufs“. ¿Lo puedo desactivar? ¿O renombrar? Total, lo único que hace es hacer búfer inmutable


;; Tanto con mi revert-all-changed-buffers como con revbufs, tengo este problema con 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")
;;
;; El principal es el „Wrong type argument“
;;
;; Parecido a https://github.com/magit/magit/issues/808


;; Además tengo otros reversores: org-revert-changed-org-buffers, ver ahí

;; 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
;; En 24.m12.2023 por distintos motivos (tecla Enter está empezando a fallar en teclado Kinesis) me volví a quedar sin número siete, y con dificultad para escribir otras letras queridas
;; Son suficientes motivos para discrepar de quienes consideran el siete como un número afortunado
(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)
        )
    (cl-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 4)
;; (setq scroll-conservatively 1000)
;; Parece que a 2 etc. evita saltos grandes, y sólo desliza un poquito

;;;; 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

(when (display-graphic-p)

  ;; 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.

;; ATENDAS m6.2024 quizás esto se parece a algo llamado „dedicated window“, que ya bloquea el cambiar búfers. Por buscar cuando lo necesite


;; 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-xb" "\C-x\C-f"
                                   (kbd "<f35>") (kbd "<S-f35>") (kbd "<M-f35>") (kbd "<C-f35>")
                                   ;; (kbd "3n") (kbd "3S") (kbd "3M") (kbd "3C")
                                   (kbd "[49~") (kbd "[49$") (kbd "[49~") (kbd "[49^") (kbd "[49$")
                                   )
  "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

;; El problema es si hago mod3+k para matar la terminal (la última/única terminal de un emacs abierto sin demonio); contra eso no puede protegerse. Entonces tengo que abrir otro emacs


;;;; 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")
;; Diferenciaré x de nw:
;; (setq frame-title-format "*E*x %b")
(setq frame-title-format "*E* %b (l:%l, %q), %z")

;; 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…

;; Lo del frame-title-format no me va cuando estoy en „emacsclient -nw“ en terminal (uxrvt); muestra sólo „emacsclient“ → ver por /rxvt/
;; REEMPLAZADO-VER-ABAJO: (defun actualiza-título-de-terminal-urxvt-cuando-cambio-de-ventana ()
;; REEMPLAZADO-VER-ABAJO:   "Manda secuencias de control a terminal (urxvt) para actualizar el título de la terminal. Si no lo hago, sólo veré „emacsclient“. Lo he probado con urxvt y con xterm y funciona. Todo esto es para cuando uso „emacsclient -nw“ (pero no terminal real sino en un urxvt dentro de X)."
;; REEMPLAZADO-VER-ABAJO:   ;; Aaaaaaaaaaaaaaah,  depués encontré que poner rxvt-set-window-title a cierto hace lo mismo que esta función. → ver abajo
;; REEMPLAZADO-VER-ABAJO:   (unless window-system
;; REEMPLAZADO-VER-ABAJO:   ;; Para probar sólo:
;; REEMPLAZADO-VER-ABAJO:   ;;(pita-de-verdad-cortito)
;; REEMPLAZADO-VER-ABAJO:   (send-string-to-terminal (format
;; REEMPLAZADO-VER-ABAJO:                             "\e]2;%s\a"
;; REEMPLAZADO-VER-ABAJO:                             ;; "HOLA"
;; REEMPLAZADO-VER-ABAJO:                             ;; (format "Algo al azar: «%s»" (random))
;; REEMPLAZADO-VER-ABAJO:                             ;; (format-mode-line frame-title-format)
;; REEMPLAZADO-VER-ABAJO:                             ;; Ya que estoy le añado un poco de contexto (línea actual); quizás puedo añadir algo más, no sé (¿contenido de línea actual?)
;; REEMPLAZADO-VER-ABAJO:                             ;; Espero que estas llamadas no sean muy lentas. Parece que no lo son
;; REEMPLAZADO-VER-ABAJO:                             (format "*E*nw %s (l:%i)" (buffer-name) (line-number-at-pos (point) t))
;; REEMPLAZADO-VER-ABAJO:                             ))
;; REEMPLAZADO-VER-ABAJO:   )
;; REEMPLAZADO-VER-ABAJO: )
;; REEMPLAZADO-VER-ABAJO: (add-hook 'window-state-change-hook 'actualiza-título-de-terminal-urxvt-cuando-cambio-de-ventana)
;; REEMPLAZADO-VER-ABAJO: ;;(remove-hook 'window-state-change-hook 'actualiza-título-de-terminal-urxvt-cuando-cambio-de-ventana)

;; Pruebo rxvt-set-window-title, hace lo mismo que lo anterior:
;; Pero la función anterior también me va bien, así que quizás la dejo
;; No quiero sobrecargar el post-command-hook (esto lo hace):
(setq rxvt-set-window-title t)
;; ∴ Por reflexionar y probar para ver si es lento. Pero lo puedo dejar con el sistema de Emacs para evitar depender de cosas mías


;;;; 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"
  ;; Irónicamente, no funciona. Esta „verdad“ no es muy buena. Quizás mejor pita-de-verdad-pero-flojito
  (interactive)
  (let ((visible-bell nil)) (beep))
  1
  )

;; (pita-de-verdad-pero-flojito)
(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")
  ;; Para evitar el mensaje „(Shell command succeeded with no output)“ uso esto otro (quizás hay formas mejores
  ;;(call-process-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) (call-process-shell-command "beep -f 9000 -l 10")
  )
(defun pita-de-verdad-cortito ()
  "El normal en tono, pero más corto"
  (interactive) (call-process-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)
       ;; (message "He abierto cajón tras deshacer")
       ))
;; 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"))
;; No la veo usarse

;; Me evito el „Keep current list of tags tables also? (y or n)“, que es una pregunta nada amigable. Yo sólo quiero „que todo funcione“, no esa cosa rara que pregunta
(setq tags-add-tables nil)

;; ¿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)
    )
  )
;;;; mover información por tuberías o procesos
;; Visto en https://lists.gnu.org/archive/html/emacs-devel/2023-10/msg00392.html
;; (setq read-process-output-max (* 1024 1024)) ;; 1mb
;; era: (setq read-process-output-max 4096)
;; ¿A qué afecta? ¿shell? ¿magit? ¿eshell?


;;;; 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 sin código. Y para algún fichero de datos
;;;;; 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)
(message "Voy a hacer el require 'org")
(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
;; m5.2023: Aaaaaaay… Sin caché, el abrir ficheros y moverse y teclear va MUCHO más rápido (qué irónico), pero a cambio la agenda va más lenta, y empezar un cronómetro a veces tarda CINCO MINUTOS o más (esto en cabecera con ~2500 cronómetros). No sé, incluso prefiero esto, mejor que un retardo tras cada tecla que aprieto. Lo malo es que a veces no es 5 m sino *media hora* sólo para añadir el cronómetro inicial. Me empieza a molestar el retardo de varios minutos.
;; Al menos, al desactivar la caché, parece que puedo pedir la agenda y recibo la buena en la primera vez. En vez de tener que pedirla dos o tres veces „por si acaso“ porque a org-element se le escapan cabeceras/tareas las primeras veces.
;;
;; Hay problemas graves en org-mode debido a org-element, la caché, y org-persist. Hay aún bastante trabajo a hacer, y entiendo que es muy difícil. Pero no veo reconocimiento explícito o discusión de todo lo anterior; no veo que estén diciendo „reconocemos que tiene graves problemas“.
;; Estoy muy descontento con el cómo se ha montado. Quiero caché, pero sólo cuando la caché mejora velocidad. Y no cuando me hace perder información silenciosamente.

;; Pruebo esto pues me estoy cansando de la latencia de ~400 ms tras CADA TECLA que aprieto
;; Parece que ayuda
(setq org-element--cache-avoid-synchronous-headline-re-parsing t)

;; probando. Dicen que a 'backtracke lo hace todo más lento. Lo he tenido así un tiempo, y sí que veo errores de vez en cuando, pero no sé interpretarlos
;; (setq org-element--cache-self-verify 'backtrace)
;; Por tanto lo dejo como estaba (valor por defecto, nil)
;; (setq org-element--cache-self-verify nil)
;;
;; Parece que el poner org-element--cache-self-verify a 'backtrace hace que org-element--cache-log-message registre cosas
;;
;; ¿Dónde quedan los registros?
;; Parece que: org-element--cache-diagnostics-ring
;; Por ejemplo veo cosas como:
;; "org-element-cache diagnostics(MF_Empresa.org): Shifting end positions of robust parent (warning 6): \"(headline (:standard-properties [1497828 1497828 1497948 1621533 1621533 0 (:title) nil element t (351 . 1497828) 1498023 1621531 2 #<buffer MF_Empresa.org> nil nil (headline (:standard-properties [361 361 436 1692415 1692415 0 ... nil element t ... 508 1692413 1 #<buffer MF_Empresa.org> nil nil ...] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value ... nil] :title [org-element-deferred org-element-property-2 ... nil] :level 1 :priority 65 :tags nil :todo-keyword nil :todo-type nil :footnote-section-p [org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp [org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil :fragile-cache nil :ID [org-element-deferred org-element--substring ... nil]))] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (3 119) nil] :title [org-element-deferred org-element-property-2 (:raw-value) nil] :level 2 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p [org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp [org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil :fragile-cache nil :ID [org-element-deferred org-element--substring (150 186) nil]))\""


;; 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
;; Más gente quiere desactivar esto
;; - ẽ ver „ However, I do have some Org files which contain sensitive data. I'd like to be able to disable persistence in those files. Now, some of them are ".org.gpg" files, and I've seen the sources of `org-persist' and noticed persistence is inhibited for them. But I also do have some encrypted loop devices which, once opened, have a "plain" .org file there.“, de lista org-mode.  Acaba con petición sensata:   „> Please, please, be reasonable about this. Please, do not store information about known encrypted files in other places. Please, allow users to disable the feature cleanly and safely for arbitrary files if they choose to.“, y  con Ihor diciendo que esto no es crítico ni urgente
;; m5.2024 empiezo a probar a t, para ver si se ha solucionado todo lo malo. Y porque me estoy cansando de esperar minutos mientras depuro cosas en emacs (peta mucho el demonio y lo he de relanzar). Pero ∴ sigue siendo malo. No me hace más rápida la carga, y sin embargo me añade complicación y lentitud al cerrar emacs. Qué pena
;; m6.2024 otra vez pruebo para aprender cómo va. Aunque veo que NUNCA ME ACELERA nada; al contrario, a veces es el doble de lento con esta caché. Escribí informe; por mandarlo más adelante a lista
(setq org-element-cache-persistent t)  ;; probando un tiempo

;; Está bastante mal implementado esto de org-persist, porque se activa oponiéndose a lo que el usuario manda. Crea directorios etc. aunque el usuario haya puesto org-element-cache-persistent a nil para desactivarlo
;; Se quejan mucho, ẽ https://lists.gnu.org/archive/html/emacs-devel/2024-06/msg00203.html. Y mensaje de Eli en lista de org, del 12.m6.2024
;; Este fenómeno (programador más fuerte que el usuario) es malo para el software libre
;; Intento forzarlo, para que no me use ~/.cache/org-persist. Pero eso hace que pete emacs de otras maneras…
;; (setq org-persist-directory "/dev/null")
;; Dicen que mejor uno no existente


;; Mientras intento domarlo, tengo que hacer esto
(setq org-persist--report-time 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.

;;;;;;;; org-superstar, lo pruebo
;; Pruebo org-superstar, hace muchas cosas pero nada de lo que busco (navegar por, y ver mejor, los niveles de listas). No me gustan los cambios que hace.
(require 'org-superstar)

;; Esto funciona en - y * y + pero no en 1. ni 1) y no sé porqué. Lo quiero también en numéricas. Mando https://github.com/integral-dw/org-superstar-mode/issues/53
;; Probando aún
(defface puntolista-de-org-mode
  '((t (:background "#440000")))
  "Prueba para resaltar los „-“ etc. usados en org-mode"
  ;; :group '…
)
;; Que no me cambie nada de las cabeceras
(setq org-superstar-prettify-item-bullets 'only)
;; Que no me cambie nada de las listas
(setq org-superstar-item-bullet-alist
  '(
    ;; (?* . ?•)
    ;; (?+ . ?➤)
    ;; (?- . ?–)
    )
)

;; Le activo esto para fontificar más rápido aunque con más errores
;; Y sí, con font-lock-profiler veo que en vez de estar 53% del tiempo con org-superstar, está el 41%. Aún así es muy lento
(setq org-superstar-lightweight-lists t)

;; Le falta el /53 (ver arriba).
;; Le falta además iluminarme el resto de la línea, no sólo el puntolista.
;; Le falta además: faces distintas para cada nivel de lista.
;; Me molesta que coloree lo de dentro de bloques.
;; Aún así lo probaré un tiempo
(add-hook 'org-mode-hook (lambda () (org-superstar-mode 1)))



;;;;;;; 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, ...)
(defface org-tachado '((t
                        :strike-through t
                        :italic t
                        :foreground "cyan"
                        :background "white"
                        ))
  "Una faz para redefinir cómo se muestra el tachado en org. Me interesa redefinirla porque urxvt no permite tachado, y quiero mostrarlo de otra manera. Funciona"
  ;; :group 'org-faces
  ;; :version "22.1"
  )

;; Antes aquí había HTML aquí, luego ya no → lo quito y muevo a org-html-text-markup-alist abajo
(setq org-emphasis-alist
      '(
        ("*" bold)
        ("/" italic)
        ("_" underline)
        ("~" org-verbatim verbatim)
        ("=" org-code verbatim)
        ;; Ver nota donde defino esta faz
        ;; ("+" (:strike-through t))
        ("+" org-tachado)
        )
      )
;; y nueva variable en org 8, para dar el HTML
(setq org-html-text-markup-alist
      '((bold . "<strong>%s</strong>") ;; era b
        (code . "<code>%s</code>")
        (italic . "<em>%s</em>") ;; era i
        (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…)
;; En m3.2024: sigo con org-update-radio-target-regexp capada, me abre todos mis .org en ~14 segundos. Si quito el desactive, ~19s pero peta „Error during redisplay: (jit-lock-function 1) signaled (invalid-regexp "Regular expression too big")“. Pero hay un cambio reciente para partir expregu de radios en partes. Actualizo org y lo pruebo. Tarda ~22m. Pero abrir todo.org (fichero grande) pasa a tardar minutos (no sé cuántos; lo paro). → ∴ Como llevo tantos años sin usar resaltado de radios, los seguiré desactivando. En el momento en que emacs sea rápido (ẽ <1s para mis >20k radios) quizás los reactivo.
;;(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
  )
;;))

;; Forma más elegante, para incluso evitar llamar a org-update-radio-target-regexp: 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

;; m3.2024 pruebo a quitarlo. Aún así, si redefino la función anterior controlo lo que hace. Como resulta que no quiero radios, dejo el desactive
;;(setq org-inhibit-startup-radio-refresh nil)



;;;;;;; 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 faz (esto lo implementó Carsten en org-mode 5.07 a petición mía).
;; No sé por qué tenía esto: (setq org-ellipsis (quote org-column))
;; (setq org-ellipsis "႐႐႐")
;; (setq org-ellipsis "[၀၀၀]")
;; (setq org-ellipsis "[ႉႉႉ]") ;; bueno, pero es muy alto
;;
;;
;; (setq org-ellipsis "[・・・]") ;; altura un poquita más alta que la normal
;;
;;
;; (setq org-ellipsis "[・・・]") ;; altura perfecta (baja), pero ancho
;; (setq org-ellipsis "[···]") ;; bueno
(setq org-ellipsis "···") ;; más sucinto y claro

;; (setq org-ellipsis "〖〜SIGUE〜〗")  ;; cutre

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

;; Otra forma más rebuscada: ver cdv.

;; Además sale con faz (no recuerdo cuál


;;;;;;; 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)
;; (setq org-use-tag-inheritance t)
;; 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
;; (setq org-agenda-use-tag-inheritance '(todo search agenda))

;;;;;;; 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 'unspecified)
          (set-face-attribute 'org-level-2 nil :background 'unspecified)
          (set-face-attribute 'org-level-3 nil :background 'unspecified)
          (set-face-attribute 'org-level-4 nil :background 'unspecified)
          ))


;; 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
;; Funcionó unos años, luego dejó de funcionar. Tras unos años vi que es que hay que cambiar funciones:
;; org-cycle → ha de ser outline-cycle
;; org-global-cycle → ha de ser outline-cycle-buffer

(add-hook 'outline-minor-mode-hook
          (lambda ()
            (define-key outline-minor-mode-map (kbd "<C-tab>") 'outline-cycle)
            (define-key outline-minor-mode-map (kbd "5") 'outline-cycle) ; versión para emacs -nw
            (define-key outline-minor-mode-map (kbd "<backtab>") 'outline-cycle-buffer) ; 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>") 'outline-cycle-buffer)))
(add-hook 'outline-mode-hook
          (lambda ()
            (define-key outline-mode-map (kbd "<C-tab>") 'outline-cycle)
            (define-key outline-mode-map (kbd "<C-S-iso-lefttab>") 'outline-cycle-buffer)))

;; 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

;; m3.2024: borro todo de nxhtml; por reactivar si hace falta
;; (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
;; Pero no me gusta esa variable; espero que algún día desaparezca y que Emacs sea rápido („optimizado“) en todo, incluyendo la detección de cuándo un búfer es demasiado grande. Entonces se pueden crear otras opciones (con la de grab-invisible, ignore-fragility-checks etc.) pero más centradas en el usuario

;; Parece que tocar esa variable 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)

(setq org-refile-use-cache 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 cambia esto, sólo muestra cabeceras de nivel 1 del fichero actual
;; Mmmm… si usare refile, querría TODOS… pero eso es nivel ~15 o así
(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

;; Aaaaaaaah, m2.2020 parece que Bastien ha añadido el nuevo valor que yo estaba esperando:
;; (setq org-adapt-indentation 'headline-data)
;; Por probar más, pues parece no funcionar bien: indenta el :PROPERTIES: pero no el :CLOCK:, quizás porque los de org-mode ahora lo llaman de otra forma (LOGBOOK o algo así)


;;;;;;; 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
;; Es para visión general
;;;;;;;; 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

;;;;;;; mostrarla sola → ver por idle-org-agenda

;;;;;;; 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)

;; Por cierto, a veces no lo puedo desactivar → hago esto manualmente: (setq org-agenda-show-log nil)

(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: avisa de fechas límites por adelantado
;; 14 días era mucho, porque a las tareas con fecha límite aún les doy un SCHEDULED
(setq org-deadline-warning-days 10)
;; Ah, parece que también se puede poner algo como esto en la ¿fecha DEADLINE?:    <... -3d>   ← por probar

;;;;;;; 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)

          )
         )

        ;; probando
        ("o" "Las tareas normales, pero ordenadas por fecha" agenda ""
         (
          (org-agenda-overriding-header "Tareas ordenadas por fecha")
          (org-agenda-span 1)
          (org-startup-truncated t)
          (org-agenda-sorting-strategy
              '((agenda
                 deadline-up
                 scheduled-up
                 ;; ts-up
                 ;; tsia-up
                 ;; urgency-up
                 ;; deadline-up user-defined-up habit-up time-up priority-down todo-state-up timestamp-up category-keep
                 )
                ;; el resto (todo, tags, search, …) no me hacen falta
                ))
          )
         )

        ("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. 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 sitios tipo 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
;; m6.2024: quito el (require …) y confío en autoload
;; (require 'calfw)
;;~~~(autoload 'cfw:open-calendar-buffer "calfw" nil t)
;;~~~~~(autoload 'cfw:org-agenda-schedule-args "calfw" nil t)
(autoload 'cfw:org-create-source "calfw-org" nil t)


;; Usable con M-x cfw:open-calendar-buffer
;; ¡Qué bueno!
(defalias 'calendario 'cfw:open-calendar-buffer)

;;;;;;;; integración con org
;; m6.2024: quito el (require …) y confío en autoload
;; (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
;; m6.2024: quito el (require …) y confío en autoload
;; (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…


;; org-clock-update-mode-line
;; Se llama a (org-clock-get-clock-string)
;; Faz: org-mode-line-clock


;; 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)

;; Algo parecido para que no se vea tanto
;; Aaaaaah… entiendo que le hayan puesto fondo negro, porque el azul no le queda bien siempre (a veces el fondo es azul, otras gris)
;; + '(org-mode-line-clock ((t (:foreground "#056" :inherit mode-line))))
;; (set-face-attribute 'org-mode-line-clock nil :foreground "#056" :inherit 'mode-line :background nil)
;; (set-face-attribute 'org-mode-line-clock nil :foreground nil :inherit 'mode-line :background nil)
;; Probando
(set-face-attribute 'org-mode-line-clock nil :foreground "#011" :inherit 'mode-line :background 'unspecified)
;; No sé si me gusta; creo que aún no


;; 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 ← método desfasado pues ya no tengo casa desde hace años
(if (equal "ali.danielclemente.com" (system-name))
    (run-with-idle-timer 300 t 'muéstrame-agenda-si-no-molestará-mucho)
  )
;; Me va bien


;; v2, pruebo en 2024
;; Mi intención no es tanto el mostrarla, sino el autoabrir los ficheros poco a poco en caso de que me haya olvidado y aún no estén abiertos
;; (require 'idle-org-agenda)
;; (setq idle-org-agenda-interval 30)
;; (idle-org-agenda-mode)
;; (idle-org-agenda-mode -1)


;; v3, me hago algo parecido o mejor o más afinado a lo que quiero: no para mostrar la agenda (como idle-org-agenda) sino para asegurarse de que todos los ficheros están abiertos (se abren solos, en segundo plano), y que por tanto mostrar la agenda será algo rápido
;; De m6.2024. Aún en pruebas pero va


;; Pruebo a inicializarla yo
;; (setq lista-de-ficheros-que-quedan-por-abrir-poco-a-poco '("~/org/semana.org" "~/wiki/Lisp.org" "~/wiki/Programación.org"))
(defun abre-ficheros-de-org-poco-a-poco-sin-molestar nil
  (interactive)

  ;; (makunbound 'lista-de-ficheros-que-quedan-por-abrir-poco-a-poco)
  ;; Inicializar (la 1ª vez)
  (if (not (boundp 'lista-de-ficheros-que-quedan-por-abrir-poco-a-poco))
      (setq lista-de-ficheros-que-quedan-por-abrir-poco-a-poco org-agenda-files)
    )


  (if lista-de-ficheros-que-quedan-por-abrir-poco-a-poco 
      (message "Voy a empezar a abrir %i ficheros poco a poco" (length lista-de-ficheros-que-quedan-por-abrir-poco-a-poco))
    (message "No hay ningún fichero más por abrir (abrir poco a poco)")
    )
  ;; (car lista-de-ficheros-que-quedan-por-abrir-poco-a-poco)
  ;; (cdr lista-de-ficheros-que-quedan-por-abrir-poco-a-poco)
  (while (and lista-de-ficheros-que-quedan-por-abrir-poco-a-poco (not (input-pending-p)))
    (setq procesando (car lista-de-ficheros-que-quedan-por-abrir-poco-a-poco))
    (message "Ahora podría abrir automáticamente %s. Me lo marco como procesado" procesando)
    (find-file-noselect procesando t) ;; Con el „t“ lo abrirá aunque sea muy grande
    (setq lista-de-ficheros-que-quedan-por-abrir-poco-a-poco (cdr lista-de-ficheros-que-quedan-por-abrir-poco-a-poco))
    )
  (if lista-de-ficheros-que-quedan-por-abrir-poco-a-poco 
      (message "Aún quedan %i por abrir poco a poco" (length lista-de-ficheros-que-quedan-por-abrir-poco-a-poco))
    )
  ;; Y ya de paso podría hacer que me abra la agenda también…

  ;; Aquí también cancelo el reloj una vez he acabado de abrir todo. Pues ya no hará falta abrir otro vez. Este paso no hacía falta pues no es grave si se vuelve a llamar esta función repetidamente; no haría nada
  (if (and
       (not lista-de-ficheros-que-quedan-por-abrir-poco-a-poco)
       (boundp 'reloj-para-abrir-todos-ficheros-una-sola-vez)
       )
      (progn
        (message "Ya cancelo el reloj para no hacer nada más")
        (cancel-timer reloj-para-abrir-todos-ficheros-una-sola-vez)
      )
    )
  ;; (abre-ficheros-de-org-poco-a-poco-sin-molestar)

)

;; Arrancarlo solo al cabo de inactividad
;; (Este reloj luego se cancela solo, al acabar su propósito. Quizás hay mejor forma de hacer esto…)
(setq reloj-para-abrir-todos-ficheros-una-sola-vez
      (run-with-idle-timer 30 t 'abre-ficheros-de-org-poco-a-poco-sin-molestar)
      )


;;;;;;; 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))
                 )
             (cl-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
(when (window-system (selected-frame))
  ;; 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 ")←←←←")
         )
        )
  ;; (cl-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."
            (cl-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)")


;; para revertir todos (no sólo org) → ver por revbufs, arriba

;;;;;; 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
(message "Voy a cargar lenguajes de babel. Bueno, voy a hacer autoload sólo (es v2)") ;; útil tener cosas así para luego ver estos mensajes mezclados con los de GC y ver dónde hay más GC

;; v1. Todo esto es muy lento. ¿Cómo puedo acelerarlo? ∴ Ver v2
;; (message "Ahora org-babel-load-languages es %s" org-babel-load-languages)
;; (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 (← ¿por qué? ¿estoy usando „tangle“ cuando no he?). Además peta por org-babel-haskell-compiler
;;    (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)
;;    ))

;; v2: pruebo con autoload
(setq  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 (← ¿por qué? ¿estoy usando „tangle“ cuando no he?). Además peta por org-babel-haskell-compiler
         (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)
         ;; Pero ¿no debería poner „sh“ también?
         (shell . t) ; no es „sh“ sino „shell“, y sí que va
         (sql . t)
         (sqlite . t)
         ))
(defun haz-autoload-de-lenguajes-de-org-babel nil
  "Como el org-babel-do-load-languages, pero hace autoload en vez de require"
  ;; En concreto hace llamadas como
  ;; (autoload #'org-babel-execute:C "ob-C")
  (dolist (pair org-babel-load-languages)
    (let ((active (cdr pair)) (lang (symbol-name (car pair))))
      (if active
          (autoload (intern (concat "org-babel-execute:" lang))  (concat "ob-" lang))
        (fmakunbound
         (intern (concat "org-babel-execute:" lang)))
        (fmakunbound
         (intern (concat "org-babel-expand-body:" lang)))))))
(haz-autoload-de-lenguajes-de-org-babel)

;;;;;;;; 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")
               )
             ))
          ))
;; m6.2024 pruebo a reactivarlo. Pero aún me causa ~5 segundos de retraso


;;(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
(message "Voy a cargar org-contacts") ;; útil tener cosas así para luego ver estos mensajes mezclados con los de GC y ver dónde hay más GC

(setq org-contacts-files '("~/wiki/Personas.org"))
;; https://repo.or.cz/org-contacts.git
(add-to-list 'load-path "/w/org-contacts")
;; v1, directamente. Esto ralentiza el arranque, varios segundos (cuando uso -O0)
;;(require 'org-contacts)
;; v2, con autoload. La espera ocurre en la 1ª compleción
(autoload #'org-contacts-message-complete-function "org-contacts")


(defun org-contacts-insinúate-a-wl nil
  (message "Voy a hacer org-contacts-insinúate-a-wl")
  (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
              
              ;; Esto está también como función: (org-contacts-setup-completion-at-point)
              (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. Pero ¿requiere tener wl cargado? ¿Cómo es que tengo wl-draft-mode-hook…?

;;;;; 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)
            ))

;;;;; 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

;;;;; 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:
;; Podría intentar usar autoloads, pero ~~~~ ŭ1 de poco me serviría pues al llamar a yas-global-mode ya lo estaré cargando por completo
(message "Voy a hacer el require 'yasnippet")
(require 'yasnippet)
(yas-global-mode 1)
;; m10.2023: por algún motivo no va en org-mode ni python, con emacs recién compilado. Hay que hacer yas-insert-snippet. TAB sigue siendo org-cycle.  → ∴ ah, era porque Emacs rompió la función re-search-forward. Recompilé Emacs y ya va bien todo



;; 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). Parece que en m4.2023 ya no hace falta
;; (add-hook 'wl-draft-mode-hook #'yas-minor-mode-on)
;; (remove-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)
          ))


;;;;; 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)
(autoload 'markdown-mode "markdown-mode" "Markdown mode" t)
(add-to-list 'auto-mode-alist '("\\.md$" . markdown-mode))
;;))

;;;;; 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))

    ))

;;;;; 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)

;;;;; 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)

;;;;; ediff, para diferencias

;; Quiero algo más rápido que ediff-regions-linewise. En vez de marcar qué trozos quiero, coloco los trozos en la 1ª y 2ª línea
(defun ediff-compara-las-dos-primeras-líneas-de-este-búfer-porpalabrasosealoqueediffllamawordwiseenelidiomadeshakespeareyquemencionoaquíparacuandobuscoestafunciónmedianteesapalabra ()
  "Abre sesión ediff. No pregunta búfers ni región. Toma el búfer actual, la 1ª y la 2ª línea, y las compara.
Aún en pruebas.
Basada en ediff-regions-linewise y simplificada"
  (interactive)
  (let (
        ;; (buffer-A
        ;;  (ediff-clone-buffer-for-region-comparison (current-buffer) "-Region.A-"))
        ;; (buffer-B
        ;;  (ediff-clone-buffer-for-region-comparison (current-buffer) "-Region.B-"))

        (buffer-A (ediff-make-cloned-buffer (current-buffer) "-Region.A-"))
        (buffer-B (ediff-make-cloned-buffer (current-buffer) "-Region.B-"))

        reg-A-beg reg-A-end reg-B-beg reg-B-end)

    ;; Probando a hacer lo mismo que ediff-clone-buffer-for-region-comparison hacía
    ;; (ediff-with-current-buffer buffer-A
    ;;   (setq ediff-temp-indirect-buffer t))
    ;; (ediff-with-current-buffer buffer-B
    ;;   (setq ediff-temp-indirect-buffer t))

    ;; (ediff-make-cloned-buffer (current-buffer) "-Region.X-")
    ;; Probablemente hay mejores formas de hacer esto:
    (save-excursion
      (beginning-of-buffer)
      (setq
       reg-A-beg (pos-bol)
       reg-A-end (pos-eol)
       )
      (let((line-move-visual nil)) (next-line))
      (setq
       reg-B-beg (pos-bol)
       reg-B-end (pos-eol)
       )
      (message "A: %i-%i. B: %i-%i" reg-A-beg reg-A-end reg-B-beg reg-B-end)
      (message "Línea 1: «%s»" (buffer-substring reg-A-beg reg-A-end))
      (message "Línea 2: «%s»" (buffer-substring reg-B-beg reg-B-end))
      )

    (ediff-regions-internal
     (get-buffer buffer-A) reg-A-beg reg-A-end
     (get-buffer buffer-B) reg-B-beg reg-B-end
     nil
     'ediff-regions-wordwise 'word-mode nil))
  )

;;;; Comunicaciones (chat, jabber, correo, red)
;;;;; 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.
;; Aún me hace falta hexrgb pues en MELPA no está:
(add-to-list 'load-path "~/.emacs.d/hexrgb")
(require 'hexrgb)

;; m6.2024: paso a autoloads para arrancar más rápido
;;(require 'jabber)
(require 'jabber-autoloads)

;;;;;; arreglo algunas teclas

;; Y le añado varias funciones útiles; adaptado de ~/.emacs.d/emacs-jabber/jabber-keymap.el
(if (boundp 'acceso-funciones-varias-map) ;; con if, para que no pete si ejecuto trocitos sueltos de Emacs que no incluyen este acceso-funciones-varias-map
(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

(eval-after-load "jabber" 
'(progn
;; 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. ∴ De momento la solución es compilar („B“ en dired) mel-q-ccl.el y cargar el .elc

      )
  )
;; 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)

;; (message "Voy a hacer el require 'wl")
;; (require 'wl)
;; 9.m6.2024 por primera vez pruebo esto. Aún no funciona todo el resto de cosas (oauth2 etc.) pero las iré corrigiendo poco a poco
(message "Hago autoload (no hago require) de 'wl")
(autoload 'wl "wl")
(autoload 'wl-user-agent-compose "wl")

;;(require 'sasl-xoauth2)  ;; viene de flim
;; Intento pedir que lo cargue ¿de flim? cuando lo llamen
(autoload 'sasl-xoauth2-steps "sasl-xoauth2")
;; No sé si lo tengo que hacer a mano, o hay forma mejor. A mano me iba, así que lo haré aquí
(eval-after-load "sasl"
'(progn
  (add-to-list 'sasl-mechanism-alist '("XOAUTH2" sasl-xoauth2))
  (add-to-list 'sasl-mechanisms "XOAUTH2")
  )
)


;; Añado algo para depurar https://github.com/wanderlust/flim/issues/17
(advice-add
 'plstore-save
 :around
 (lambda (oldfun &rest r)
   (message "Validando plstore al grabar")
   (let* ((plstore (car r))
      (plist (cdr (plstore-get plstore (caar (plstore--get-alist plstore)))))
      (response (plist-get plist :access-response))
      (refresh (plist-get plist :refresh-token))
      (token (plist-get plist :access-token)))
     (if (and response refresh)
     (progn (when (null token)
          (error "Invalid OAuth2 token!!"))
        (message "DEBUG: OAuth2 access token is %s" token))
       (message "INFO: may not be OAuth2 token"))
     (apply oldfun r)))
 '((name . "validate plstore")))

;; (advice-remove 'plstore-save "validate plstore")
;; No, esto es versión vieja:  (ad-remove-advice #'plstore-save :around "validate plstore")




;; 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

;; ¿Por qué me hace falta esto? Lo veo en elmo-imap4.el
(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
(eval-after-load "wl-template"
  '(progn
     (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

;; Parece que el ~/.elmo/cache

(defun vacía-caché-de-elmo ()
       (interactive)
       ;;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
)
;; ¿Hacer esto al arrancar Emacs? ¿Cada vez? Parece excesivo
;; m6.2024: voy a probar a desactivarlo, sólo para acelerarlo.
;; ATENDAS Si luego me molesta la caché, hacer esto de otra manera (ẽ fuera de emacs, o con run-with-idle-timer)
;; (vacía-caché-de-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.“

;; Y evitar difundir información
;; Me creaba una descripción demasiado detallada, por ejemplo: "Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (Gojō) APEL-LB/10.8 EasyPG/1.0.0 Emacs/30.0.50 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO)"
;; (La difundo aquí arriba una vez, en vez de en cada correo)
(setq wl-generate-mailer-string-function (lambda nil "GNU Emacs"))


;;;;;; 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)
(eval-after-load "mime-view"
  '(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)
;; Ver notas.
;; ¿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. shr también mantiene cosas de HTML como enlaces. shr no tiene los errores/petadas que veo en emacs-w3m (pocos).
;; ∴ de momento prefiero w3m


;; Esto es para evitar código malo en w3m-process-stop, que hace que un correo largo que contiene las palabras „Reading “ pete w3m ("Operation aborted by user")
(setq w3m-clear-display-while-reading nil)

;; 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…


;; Algún día pasaré a use-package… O a incluir más cosas (toda la configuración) bajo este eval-after-load
(eval-after-load "wl" '(progn
                         (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
(if (boundp 'acceso-funciones-varias-map) ;; con if, para que no pete si ejecuto trocitos sueltos de Emacs que no incluyen este acceso-funciones-varias-map
    (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
          ))

;;;;; erc
;; No lo uso, ver abajo lo de rcirc
(setq erc-kill-queries-on-quit t)
(setq erc-modules
      '(autojoin button completion fill irccontrols match menu netsplit noncommands readonly ring services stamp track))

(defun erc ()
  "Avisa de que rcirc es mejor :-)"
  (interactive)
  (beep)
  (message "¡rcirc pli bonas!")
  )

;; ¿Por qué erc se carga solo tras mi .emacs?
;; Creo que era por erc-modules. ∴ Lo he movido a un setq arriba, para ver qué pasa. Eso ya me evita cargarlo

;; (unload-feature 'erc-join)
;; (unload-feature 'erc-track)
;; (unload-feature 'erc-button)
;; (unload-feature 'erc-fill)
;; (unload-feature 'erc-stamp)
;; (unload-feature 'erc-pcomplete)
;; (unload-feature 'erc-goodies)
;; (unload-feature 'erc-match)
;; (unload-feature 'erc-menu)
;; (unload-feature 'erc-netsplit)
;; (unload-feature 'erc-ring)
;; (unload-feature 'erc-services)
;; (unload-feature 'erc)


;;;;; rcirc
;; Chat: rcirc es mejor que ERC 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


;; 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
;; Cargo siempre
;; (require 'rcirc-color)
;; Pruebo alternativa:
;;(eval-after-load 'rcirc '(require 'rcirc-color))

;; El demonio de emacs peta en el eval-after-load
;;
;; 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. Activarlo a mano

;; ∴ He actualizado a 0.4.5. Por probar
;; Sigue petando:
;; Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
;;  rcirc-color-distance("papayawhip" nil)



;;;;; 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, para editar código
;;;;; 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
;; Pero m9.2023 desactivo eso también. Cuando lo renecesite buscaré uno nuevo
;; m3.2024: borro nxhtml de mi cdv. Usar el de ~ELPA la próxima vez.
;; (ignore '(
;; 
;; ;; (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)
;; ;; smarty-mode es de nxhtml (no de JDE)
;; ;;(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
;; 
;; ;; fin de ignore
;; ))


;;;;;; 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…
;; m9.2023: lo desactivaré
(ignore '(
(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
;; m3.2024: comento todo pues no necesito. Lo puebo borrar
;; (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))

;;;;; CEDET: lo necesito para JDEE. CEDET incluye: base (eieio, semantic) y herramientas (Speedbar, EDE, COGRE)

;;;;;; Empieza la función que carga o no cedet
;; Por probar.  13.m6.2024 decido algo drástico: *ignorar todo CEDET*. En realidad sólo estoy ignorando la carga precoz y mi configuración.
;; - Ignoro la carga durante la inicialización de Emacs, pero CEDET/eieio/… se inicializarán más tarde, ẽ al cargar helm. Pero más mínimamente
;; - Ignoro mi configuración, porque tras desactivarla veo que no me he perdido nada
;; El objetivo final es acelerar la carga de mi ~/.emacs incluso en emacs -O0 (muy lento)
(ignore '(
;;;;;; 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

;;;;;; Fin de la función que carga o no cedet
;; Por probar:
)) ;; fin del ignore


;;;;;; 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

;; v1: con require
;; (require 'projectile)
;; (projectile-mode)
;; (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)

;;))

;; v2, pruebo esto, para aprovechar los autoload
(use-package projectile
  :init
  (projectile-mode +1)
  :bind (:map projectile-mode-map
              ;; ("s-p" . projectile-command-map)
              ("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)
;; m5.2023 lo borro. Parece que algunas cosas como avltree.el ya están en emacs
;; (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")
;; ∴ si lo necesito otra vez, instalarlo por apt-get. Borraré éste mío

;; (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
;; En 2023 lo quito:
;; (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
;; En 2023 lo comento pues no lo uso y probablemente está desfasadísimo
;; (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 .

;; 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

;; Nota de 2023: no uso esto desde hace años, así que prefiero quitarlo, y reinstalarlo cuando me haga falta
;; (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
;; 2023: la comento pues es de hace unos 15 años y ya no la uso
;; (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…

;; Pero me molesta que tome tantas líneas de minibúfer y no las aproveche. De momento le desactivo el multilínea, abajo. Ver: eldoc-echo-area-use-multiline-p

;; 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)
;; Ver https://github.com/flymake/emacs-flymake/issues/31
;; (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))
    ))

;; luego lo pruebo desde ELPA pues el de apt-get me fuerza a instalar muchas cosas que no quiero


;;;;; 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.
;; m6.2024: quito el (require …) y confío en autoload
;; (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

;;;;; Modos para Lua. 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)
    ))


;;;;; 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


          ))
;;;; Modos para „multimedia“ (o sea más que texto): imagen, sonido, vídeo, …

;;;;; 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*"))
      )

    ))

;;;;; emms
;; Tengo que aprenderlo más; es muy bueno porque es Emacs ← ¡pero hay otros que también son Emacs y son mejores!
;; 4.m5.2013: ya no lo uso; ver mingus etc. Además 14.m4.2023 lo borré de ~/.emacs.d/emms-git. Si lo requiero, usaré el de elpa.
;; ∴ Lo desactivo
(ignore '(
;;;;;; 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
;; 4.m6.2024 desactivado otra vez porque no uso mpd últimamente
(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)

;; fin de ignore
))

;;;; Control de versiones, cdv
;;;;; 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)
;;        ))

;;;;; magit

;;(require 'magit)
;; Más rápido, con sólo autoloads
;;(autoload #'magit-status "magit")
(require 'magit-autoloads)
;; Aún peta con autoloads, por: ~~~ magit-process-git

;; 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))
;;  ))
;; ))


;;;;; vc-, los métodos oficilaes para control de versiones
;; 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")

;;;; Lanzadores 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
;;;;; 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

;;;;; „ido“
;; Creo que lo usé un tiempo (~2007), no me acuerdo. Luego pasé a icicles/anything/helm

;;;;; 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)"
                                                "curso de piano, libro de Faber (ID 7f0a7d28-a886-4f38-a7b3-668231605378)"
                                                "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
;; m1.2024: me va muy bien y lo uso mucho pero el repositorio oficial parece algo abandonado. ¿Quizás ahora que hay vc-git-grep se puede usar vc-git-grep dentro de helm?
(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

;; Temporalmente hasta que https://github.com/yasuyk/helm-git-grep/issues/52 se corrija
(setq helm-allow-mouse nil)


;; 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)
;; No comentarlo (aunque esté abajo otra vez)
(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
<