Mercurial > hg > xemacs-beta
comparison lisp/userlock.el @ 227:0e522484dd2a r20-5b12
Import from CVS: tag r20-5b12
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:12:37 +0200 |
parents | |
children | 4f79e16b1112 |
comparison
equal
deleted
inserted
replaced
226:eea38c7ad7b4 | 227:0e522484dd2a |
---|---|
1 ;;; userlock.el --- handle file access contention between multiple users | |
2 | |
3 ;; Copyright (C) 1985, 1986, 1993 Free Software Foundation, inc. | |
4 | |
5 ;; Maintainer: FSF | |
6 ;; Keywords: internal | |
7 | |
8 ;; This file is part of XEmacs. | |
9 | |
10 ;; XEmacs is free software; you can redistribute it and/or modify it | |
11 ;; under the terms of the GNU General Public License as published by | |
12 ;; the Free Software Foundation; either version 2, or (at your option) | |
13 ;; any later version. | |
14 | |
15 ;; XEmacs is distributed in the hope that it will be useful, but | |
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 ;; General Public License for more details. | |
19 | |
20 ;; You should have received a copy of the GNU General Public License | |
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
22 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
23 ;; 02111-1307, USA. | |
24 | |
25 ;;; Synched up with: FSF 19.34. | |
26 | |
27 ;;; Commentary: | |
28 | |
29 ;; This file is autoloaded to handle certain conditions | |
30 ;; detected by the file-locking code within XEmacs. | |
31 ;; The two entry points are `ask-user-about-lock' and | |
32 ;; `ask-user-about-supersession-threat'. | |
33 | |
34 ;;; Code: | |
35 | |
36 (define-error 'file-locked "File is locked" 'file-error) ; XEmacs | |
37 | |
38 (defun ask-user-about-lock-minibuf (fn opponent) | |
39 (save-window-excursion | |
40 (let (answer) | |
41 (while (null answer) | |
42 (message "%s is locking %s: action (s, q, p, ?)? " opponent fn) | |
43 (let ((tem (let ((inhibit-quit t) | |
44 (cursor-in-echo-area t)) | |
45 (prog1 (downcase (read-char)) | |
46 (setq quit-flag nil))))) | |
47 (if (= tem help-char) | |
48 (ask-user-about-lock-help) | |
49 (setq answer (assoc tem '((?s . t) | |
50 (?q . yield) | |
51 (?\C-g . yield) | |
52 (?p . nil) | |
53 (?? . help)))) | |
54 (cond ((null answer) | |
55 (beep) | |
56 (message "Please type q, s, or p; or ? for help") | |
57 (sit-for 3)) | |
58 ((eq (cdr answer) 'help) | |
59 (ask-user-about-lock-help) | |
60 (setq answer nil)) | |
61 ((eq (cdr answer) 'yield) | |
62 (signal 'file-locked (list "File is locked" fn opponent))))))) | |
63 (cdr answer)))) | |
64 | |
65 (defun ask-user-about-lock-help () | |
66 (with-output-to-temp-buffer "*Help*" | |
67 (princ "It has been detected that you want to modify a file that someone else has | |
68 already started modifying in EMACS. | |
69 | |
70 You can <s>teal the file; The other user becomes the | |
71 intruder if (s)he ever unmodifies the file and then changes it again. | |
72 You can <p>roceed; you edit at your own (and the other user's) risk. | |
73 You can <q>uit; don't modify this file.") | |
74 (save-excursion | |
75 (set-buffer standard-output) | |
76 (help-mode)))) | |
77 | |
78 (define-error 'file-supersession "File changed on disk" 'file-error) ; XEmacs | |
79 | |
80 (defun ask-user-about-supersession-threat-minibuf (fn) | |
81 (save-window-excursion | |
82 (let (answer) | |
83 (while (null answer) | |
84 (message "%s changed on disk; really edit the buffer? (y, n, r or C-h) " | |
85 (file-name-nondirectory fn)) | |
86 (let ((tem (downcase (let ((cursor-in-echo-area t)) | |
87 (read-char))))) | |
88 (setq answer | |
89 (if (= tem help-char) | |
90 'help | |
91 (cdr (assoc tem '((?n . yield) | |
92 (?\C-g . yield) | |
93 (?y . proceed) | |
94 (?r . revert) | |
95 (?? . help)))))) | |
96 (cond ((null answer) | |
97 (beep) | |
98 (message "Please type y, n or r; or ? for help") | |
99 (sit-for 3)) | |
100 ((eq answer 'help) | |
101 (ask-user-about-supersession-help) | |
102 (setq answer nil)) | |
103 ((eq answer 'revert) | |
104 (revert-buffer nil (not (buffer-modified-p))) | |
105 ; ask confirmation iff buffer modified | |
106 (signal 'file-supersession | |
107 (list "File reverted" fn))) | |
108 ((eq answer 'yield) | |
109 (signal 'file-supersession | |
110 (list "File changed on disk" fn)))))) | |
111 (message | |
112 "File on disk now will become a backup file if you save these changes.") | |
113 (setq buffer-backed-up nil)))) | |
114 | |
115 (defun ask-user-about-supersession-help () | |
116 (with-output-to-temp-buffer "*Help*" | |
117 (princ "You want to modify a buffer whose disk file has changed | |
118 since you last read it in or saved it with this buffer. | |
119 | |
120 If you say `y' to go ahead and modify this buffer, | |
121 you risk ruining the work of whoever rewrote the file. | |
122 If you say `r' to revert, the contents of the buffer are refreshed | |
123 from the file on disk. | |
124 If you say `n', the change you started to make will be aborted. | |
125 | |
126 Usually, you should type `n' and then `M-x revert-buffer', | |
127 to get the latest version of the file, then make the change again.") | |
128 (save-excursion | |
129 (set-buffer standard-output) | |
130 (help-mode)))) | |
131 | |
132 ;;; dialog-box versions [XEmacs] | |
133 | |
134 (defun ask-user-about-lock-dbox (fn opponent) | |
135 (let ((echo-keystrokes 0) | |
136 (dbox | |
137 (cons | |
138 (format "%s is locking %s\n | |
139 It has been detected that you want to modify a file that | |
140 someone else has already started modifying in XEmacs." | |
141 opponent fn) | |
142 '(["Steal Lock\n\nThe other user will\nbecome the intruder" steal t] | |
143 ["Proceed\n\nEdit file at your own\n\(and the other user's) risk" | |
144 proceed t] | |
145 nil | |
146 ["Abort\n\nDon't modify the buffer\n" yield t])))) | |
147 (popup-dialog-box dbox) | |
148 (catch 'aual-done | |
149 (while t | |
150 (let ((event (next-command-event))) | |
151 (cond ((and (misc-user-event-p event) (eq (event-object event) 'proceed)) | |
152 (throw 'aual-done nil)) | |
153 ((and (misc-user-event-p event) (eq (event-object event) 'steal)) | |
154 (throw 'aual-done t)) | |
155 ((and (misc-user-event-p event) (eq (event-object event) 'yield)) | |
156 (signal 'file-locked (list "File is locked" fn opponent))) | |
157 ((button-release-event-p event) ;; don't beep twice | |
158 nil) | |
159 (t | |
160 (beep) | |
161 (message "please answer the dialog box")))))))) | |
162 | |
163 (defun ask-user-about-supersession-threat-dbox (fn) | |
164 (let ((echo-keystrokes 0) | |
165 (dbox | |
166 (cons | |
167 (format "File %s has changed on disk | |
168 since its buffer was last read in or saved. | |
169 | |
170 Do you really want to edit the buffer? " fn) | |
171 '(["Yes\n\nEdit the buffer anyway,\nignoring the disk file" | |
172 proceed t] | |
173 ["No\n\nDon't modify the buffer\n" yield t] | |
174 nil | |
175 ["No\n\nDon't modify the buffer\nbut revert it" revert t] | |
176 )))) | |
177 (popup-dialog-box dbox) | |
178 (catch 'auast-done | |
179 (while t | |
180 (let ((event (next-command-event))) | |
181 (cond ((and (misc-user-event-p event) (eq (event-object event) 'proceed)) | |
182 (throw 'auast-done nil)) | |
183 ((and (misc-user-event-p event) (eq (event-object event) 'yield)) | |
184 (signal 'file-supersession (list fn))) | |
185 ((and (misc-user-event-p event) (eq (event-object event) 'revert)) | |
186 (or (equal fn (buffer-file-name)) | |
187 (error | |
188 "ask-user-about-supersession-threat called bogusly")) | |
189 (revert-buffer nil t) | |
190 (signal 'file-supersession | |
191 (list fn "(reverted)"))) | |
192 ((button-release-event-p event) ;; don't beep twice | |
193 nil) | |
194 (t | |
195 (beep) | |
196 (message "please answer the dialog box")))))))) | |
197 | |
198 | |
199 ;;; top-level | |
200 | |
201 ;;;###autoload | |
202 (defun ask-user-about-lock (fn opponent) | |
203 "Ask user what to do when he wants to edit FILE but it is locked by USER. | |
204 This function has a choice of three things to do: | |
205 do (signal 'file-locked (list FILE USER)) | |
206 to refrain from editing the file | |
207 return t (grab the lock on the file) | |
208 return nil (edit the file even though it is locked). | |
209 You can rewrite it to use any criterion you like to choose which one to do." | |
210 (discard-input) | |
211 (if (and (fboundp 'popup-dialog-box) | |
212 (or (button-press-event-p last-command-event) | |
213 (button-release-event-p last-command-event) | |
214 (misc-user-event-p last-command-event))) | |
215 (ask-user-about-lock-dbox fn opponent) | |
216 (ask-user-about-lock-minibuf fn opponent))) | |
217 | |
218 ;;;###autoload | |
219 (defun ask-user-about-supersession-threat (fn) | |
220 "Ask a user who is about to modify an obsolete buffer what to do. | |
221 This function has two choices: it can return, in which case the modification | |
222 of the buffer will proceed, or it can (signal 'file-supersession (file)), | |
223 in which case the proposed buffer modification will not be made. | |
224 | |
225 You can rewrite this to use any criterion you like to choose which one to do. | |
226 The buffer in question is current when this function is called." | |
227 (discard-input) | |
228 (if (and (fboundp 'popup-dialog-box) | |
229 (or (button-press-event-p last-command-event) | |
230 (button-release-event-p last-command-event) | |
231 (misc-user-event-p last-command-event))) | |
232 (ask-user-about-supersession-threat-dbox fn) | |
233 (ask-user-about-supersession-threat-minibuf fn))) | |
234 | |
235 ;;; userlock.el ends here |