Revoltijo Elisp (VI): desmontar volúmenes y mandar archivos a un ordenador remoto
Omnia vincit Elisp, así que en esta breve GNUta daré cuenta de un par de apaños en nuestro lenguaje de programación favorito para sendos escenarios que me venían fastidiando un poco en mi trabajo y usos cotidianos. Bueno, tampoco es que el fastidio fuera tan insalvable, pero siempre hay una excusa para escribir unos cuantos paréntesis que nos relajen de la ajetreada vida.
Primer escenario: una función para desmontar volúmenes
O sea, aquellos volúmenes (pen drives, discos externos, etc.) que GNU/Linux monta
automáticamente y de oficio en el directorio /run/media/
. Desmontarlos es tan simple
como tirar un comando en la terminal o abrir un gestor de archivos. Pero si estás en Emacs
es como cuando, cómodos en el sofá, nos resistimos a levantarnos para cerrar la ventana.
Emacs, ya ven, nos vuelve perezosos. Así que se me ocurrió escribir una función
desmontadora de volúmenes montados que me mostrase éstos mediante una lista autocompletiva
Ido
. Y, escogido el candidato, se desmonta.
Primero definimos una función para generar la lista de volúmenes montados:
(defun crea-lista-run-media () (mapcar 'identity (cl-remove-if (lambda (k) (string-match ".+/\\." k)) (directory-files "/run/media/juanmanuel" t))))
Y, por último, nuestra función que lanza Ido
y desmonta el volumen escogido:
(defun ido-desmontar-run-media (dir) (interactive (list (ido-completing-read "Desmontar: " (crea-lista-run-media) nil t))) (let ((default-directory "/sudo::")) (shell-command (concat "sudo umount -R " dir))))
Segundo escenario: mandar un archivo desde Dired a un equipo remoto
Aquí el equipo remoto es mi raspberry. Los archivos los mandaremos de forma asíncrona
mediante el comando rsync
. Y, según sea el tipo de archivo o carpeta, hay cuatro
opciones con cuatro destinos posibles en la raspberry: Películas, Música y Series.
Definimos primero la función que manda el archivo, que toma como argumento la ruta. El
password de la raspberry lo añade con un process-send-string
a la salida del comando
rsync
, que debe estar en el búfer temporal *rsync-raspi*
tras un temporizador (ver
línea 17). Y lo extrae de mi archivo authinfo
(ver línea 8):
(defun archivo-a-raspi (ruta) (interactive) (let* ((archivo (dired-get-file-for-visit)) (auth (nth 0 (auth-source-search :host "192.168.1.36" :requires '(user secret)))) (password (funcall (plist-get auth :secret)))) (start-process-shell-command "rsync" "*rsync-raspi*" (concat "rsync " " -avz " " -e ssh " (shell-quote-argument archivo) " [email protected]:/home/pi" ruta)) (run-with-timer 0.5 nil (lambda () (process-send-string "*rsync-raspi*" password) (process-send-string "*rsync-raspi*" "\r")))))
Aquí, la lista de opciones:
(setq lista-rutas-raspi '((?1 "Películas" (lambda () (archivo-a-raspi "/multimedia/Películas"))) (?2 "Música" (lambda () (archivo-a-raspi "/multimedia/Música"))) (?3 "Series" (lambda () (archivo-a-raspi "/multimedia/series")))))
Y la función que despliega las opciones y ejecuta el candidato escogido:
(defun dired-manda-archivo-a-raspi () "Manda el archivo marcado en Dired a mi raspberry mediante rsync. Hay varias opciones" (interactive) (let ((opcion-rsync (read-char-choice (concat "Enviar a la carpeta >>\n" (mapconcat (lambda (item) (format "%c: %s" (car item) (nth 1 item))) lista-rutas-raspi " -- ")) (mapcar #'car lista-rutas-raspi)))) (funcall (nth 2 (assoc opcion-rsync lista-rutas-raspi)))))
Luego, bastaría con añadir cualquier atajo a nuestro gusto al dired-mode-map
.
∞
Publicado: 15/08/21
Última actualización: 07/08/22
Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.