如何使Emacs锁定缓冲区无法锁定文件时失败? [英] How to make Emacs lock-buffer fail when it cannot lock a file?

查看:294
本文介绍了如何使Emacs锁定缓冲区无法锁定文件时失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一些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提示继续进程。我该怎么做?



编辑:@event_jr提出了一个使用文件锁定 - 对。我认为它大部分时间都有效。然而,我认为其他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


解决方案

似乎没有一种使 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(){
读取-r -d''脚本< EOF
(progn
(setq server-name)
(server-start)
(require'cl)

(defun my-set-buffer-modified-p(flag)
(flet (ask-user-about-lock
(& rest args)
;;(signal'file-locked args)
(应用'错误'%s被%s锁定 ))
(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 ,这很好地解决了。


I want to some Emacs lisp to manipulate same file from different Emacs processes. So I wrote the following script to check how lock-buffer works. However, it stops when trying to lock the file by the second Emacs process (find-and-lock-file $es2 /tmp/dummy). I need to go to another terminal and send emacsclient --socket-name server-2 --eval '(kill-emacs)' to stop the Emacs process. Emacs prompts what to do for the file if I open an UI by emacsclient -t --socket-name server-2, but I want to make it all done in the background and avoid using Emacs prompt to continue the process. How can I do this? Is it possible to make Emacs raise some error when it fails to lock a file?

EDIT: @event_jr proposed an answer using file-locked-p. I think it works most of the time. However, I think other Emacs process can lock the file between the execution of file-locked-p and lock-buffer. So, I will keep this question open. Solved. Thanks, @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

解决方案

There doesn't seem to be a way to make emacsclient --eval return error code. But You can make it print what you need to know:

#!/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

EDIT: I've dug around the source a little bit and found a reference to ask-user-about-lock, which solves it nicely.

这篇关于如何使Emacs锁定缓冲区无法锁定文件时失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆