我想让一些Emacs lisp从不同的Emacs进程处理同一个文件。所以我编写了以下脚本来检查lock-buffer
的工作原理。但是,当尝试通过第二个Emacs进程(find-and-lock-file $es2 /tmp/dummy
)锁定文件时,它会停止。我需要转到另一个终端并发送emacsclient --socket-name server-2 --eval '(kill-emacs)'
来停止Emacs进程。如果我按emacsclient -t --socket-name server-2
打开UI,Emacs会提示如何为文件执行操作,但我想在后台完成所有操作,并避免使用Emacs提示继续此过程。我怎样才能做到这一点?当它无法锁定文件时,是否有可能使Emacs引发一些错误?
编辑:@event_jr使用file-locked-p
提出了答案。我认为它大部分时间都有效。但是,我认为其他Emacs进程可以在执行file-locked-p
和lock-buffer
之间锁定文件。 所以,我会保持这个问题。解决了。谢谢,@ 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
答案 0 :(得分:4)
似乎没有办法让emacsclient --eval
返回错误代码。但是你可以打印出你需要知道的内容:
#!/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
编辑:我在源头挖了一下,发现了一个参考
ask-user-about-lock
,很好地解决了这个问题。
答案 1 :(得分:0)
我找到了使用run-with-timer
的另一个答案,以绕过emacsclient --eval错误,以便我可以检查(signal 'file-locked ...)
是否处于“正常”状态。
#!/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