Comment faire échouer le tampon de verrouillage d'Emacs lorsqu'il ne peut pas verrouiller un fichier ?
-
09-12-2019 - |
Question
Je souhaite qu'un certain Lisp Emacs manipule le même fichier à partir de différents processus Emacs.J'ai donc écrit le script suivant pour vérifier comment lock-buffer
travaux.Cependant, il s'arrête lorsque vous essayez de verrouiller le fichier par le deuxième processus Emacs (find-and-lock-file $es2 /tmp/dummy
).Je dois aller sur un autre terminal et envoyer emacsclient --socket-name server-2 --eval '(kill-emacs)'
pour arrêter le processus Emacs.Emacs me demande quoi faire pour le fichier si j'ouvre une interface utilisateur en emacsclient -t --socket-name server-2
, mais je veux que tout se fasse en arrière-plan et éviter d'utiliser l'invite Emacs pour continuer le processus.Comment puis-je faire ceci?Est-il possible qu'Emacs génère une erreur lorsqu'il ne parvient pas à verrouiller un fichier ?
MODIFIER:@event_jr a proposé une réponse en utilisant file-locked-p
.Je pense que ça marche la plupart du temps.Cependant, je pense que d'autres processus Emacs peuvent verrouiller le fichier entre l'exécution de file-locked-p
et lock-buffer
. Je vais donc garder cette question ouverte. Résolu.Merci, @event_jr !
#!/bin/bash
es1="server-1"
es2="server-2"
start-server () {
emacs -q --daemon --eval "(progn (setq server-name \"$1\") (server-start) (require 'cl))"
}
emacs-eval () {
echo "@$1 >>> $2"
emacsclient --socket-name "$1" --eval "$2"
}
kill-emacs () {
emacs-eval "$1" '(kill-emacs)'
}
find-and-lock-file () {
emacs-eval "$1" "(progn (find-file \"$2\") (set-buffer-modified-p t) (lock-buffer))"
}
start-server $es1
start-server $es2
find-and-lock-file $es1 /tmp/dummy
find-and-lock-file $es2 /tmp/dummy
kill-emacs $es1
kill-emacs $es2
La solution
Il ne semble pas y avoir de moyen de faire emacsclient --eval
renvoyer le code d'erreur.Mais vous pouvez lui faire imprimer ce que vous devez savoir :
#!/usr/bin/env bash
es1="server-1"
es2="server-2"
emacs=/Applications/Emacs.app/Contents/MacOS/Emacs
[ -e $emacs ] || emacs=emacs
start-server () {
read -r -d '' script <<EOF
(progn
(setq server-name "$1")
(server-start)
(require 'cl)
(defun my-set-buffer-modified-p (flag)
(flet ((ask-user-about-lock
(&rest args)
;; (signal 'file-locked args)
(apply 'error "%s was locked by %s" args)))
(set-buffer-modified-p flag))))
EOF
$emacs -q --daemon --eval "$script"
}
emacs-eval () {
echo "@$1 >>> $2"
emacsclient --socket-name "$1" --eval "$2"
}
kill-emacs () {
emacs-eval "$1" '(kill-emacs)'
}
find-and-lock-file () {
read -r -d '' script <<EOF
(with-current-buffer (find-file-noselect "$2")
(my-set-buffer-modified-p t))
EOF
emacs-eval "$1" "$script"
}
start-server $es1
start-server $es2
find-and-lock-file $es1 /tmp/dummy
find-and-lock-file $es2 /tmp/dummy
kill-emacs $es1
kill-emacs $es2
MODIFIER:J'ai fouillé un peu la source et j'ai trouvé une référence àask-user-about-lock
, ce qui le résout bien.
Autres conseils
J'ai trouvé une autre réponse en utilisant run-with-timer
, pour contourner le bogue emacsclient --eval, afin que je puisse vérifier cela (signal 'file-locked ...)
fonctionne en situation "normale".
#!/usr/bin/env bash
es1="server-1"
es2="server-2"
emacs=/Applications/Emacs.app/Contents/MacOS/Emacs
[ -e $emacs ] || emacs=emacs
start-server () {
read -r -d '' script <<EOF
(progn
(setq server-name "$1")
(server-start)
(require 'cl)
(defvar my-file-is-locked "undefined")
(defun my-set-buffer-modified-p (flag)
(flet ((ask-user-about-lock
(&rest args)
(setq my-file-is-locked "no")
(signal 'file-locked args)))
(set-buffer-modified-p flag)
(setq my-file-is-locked "yes"))))
EOF
$emacs -q --daemon --eval "$script"
}
emacs-eval () {
echo "@$1 >>> $2"
emacsclient --socket-name "$1" --eval "$2"
}
kill-emacs () {
emacs-eval "$1" '(kill-emacs)'
}
find-and-lock-file () {
read -r -d '' script <<EOF
(run-with-timer 0 nil (lambda ()
(with-current-buffer (find-file-noselect "$2")
(my-set-buffer-modified-p t))))
EOF
emacs-eval "$1" "$script"
}
file-locked-p () {
emacs-eval "$1" "(message \"my-file-is-locked = %s\" my-file-is-locked)"
}
start-server $es1
start-server $es2
find-and-lock-file $es1 /tmp/dummy
find-and-lock-file $es2 /tmp/dummy
file-locked-p $es1
file-locked-p $es2
kill-emacs $es1
kill-emacs $es2