aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuanma Barranquero2011-07-05 13:38:44 +0200
committerJuanma Barranquero2011-07-05 13:38:44 +0200
commit53bbe3ad4c130bfc8c2e3d3262f8739ce8f7d553 (patch)
treeae17607ed8829c658340ccf4197de6c3d99e3e3f
parent0d939f4027e1ab1a1c5163c181aea5a1e5f1e2d2 (diff)
downloademacs-53bbe3ad4c130bfc8c2e3d3262f8739ce8f7d553.tar.gz
emacs-53bbe3ad4c130bfc8c2e3d3262f8739ce8f7d553.zip
lisp/emacs-lock.el: New file. Old one moved to lisp/obsolete/.
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/NEWS7
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/emacs-lock.el281
-rw-r--r--lisp/obsolete/old-emacs-lock.el102
5 files changed, 328 insertions, 71 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 0ab5f860d62..4f4e8762328 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
12011-07-05 Juanma Barranquero <lekktu@gmail.com>
2
3 * NEWS: Document new emacs-lock.el and renaming of old one.
4
12011-07-05 Manoj Srivastava <srivasta@ieee.org> 52011-07-05 Manoj Srivastava <srivasta@ieee.org>
2 6
3 * themes/manoj-dark-theme.el (manoj-dark): New file. 7 * themes/manoj-dark-theme.el (manoj-dark): New file.
diff --git a/etc/NEWS b/etc/NEWS
index d123073bd79..5da6e06d0d0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -857,6 +857,13 @@ soap-inspect.el is an interactive inspector for SOAP WSDL structures.
857 857
858** xmodmap-generic-mode for xmodmap files. 858** xmodmap-generic-mode for xmodmap files.
859 859
860** New emacs-lock.el package.
861(The pre-existing one has been renamed to old-emacs-lock.el and moved
862to obsolete/.) Now, Emacs Lock is a proper minor mode
863`emacs-lock-mode'. Protection against exiting Emacs and killing the
864buffer can be set separately. The mechanism for auto turning off
865protection for buffers with inferior processes has been generalized.
866
860 867
861* Incompatible Lisp Changes in Emacs 24.1 868* Incompatible Lisp Changes in Emacs 24.1
862 869
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index a8b65d6915b..701cec11c2e 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
12011-07-05 Juanma Barranquero <lekktu@gmail.com>
2
3 * obsolete/old-emacs-lock.el: Rename from emacs-lock.el.
4 * emacs-lock.el: New file.
5
12011-07-05 Julien Danjou <julien@danjou.info> 62011-07-05 Julien Danjou <julien@danjou.info>
2 7
3 * textmodes/rst.el (rst-define-level-faces): Use `facep' rather 8 * textmodes/rst.el (rst-define-level-faces): Use `facep' rather
diff --git a/lisp/emacs-lock.el b/lisp/emacs-lock.el
index 1553aeae0d5..9e0a93b4731 100644
--- a/lisp/emacs-lock.el
+++ b/lisp/emacs-lock.el
@@ -1,9 +1,10 @@
1;;; emacs-lock.el --- prevents you from exiting Emacs if a buffer is locked 1;;; emacs-lock.el --- protect buffers against killing or exiting -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 1994, 1997, 2001-2011 Free Software Foundation, Inc 3;; Copyright (C) 2011 Free Software Foundation, Inc
4 4
5;; Author: Tom Wurgler <twurgler@goodyear.com> 5;; Author: Juanma Barranquero <lekktu@gmail.com>
6;; Created: 12/8/94 6;; Inspired by emacs-lock.el by Tom Wurgler <twurgler@goodyear.com>
7;; Maintainer: FSF
7;; Keywords: extensions, processes 8;; Keywords: extensions, processes
8 9
9;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -23,79 +24,217 @@
23 24
24;;; Commentary: 25;;; Commentary:
25 26
26;; This code sets a buffer-local variable to t if toggle-emacs-lock is run, 27;; This package defines a minor mode Emacs Lock to mark a buffer as
27;; then if the user attempts to exit Emacs, the locked buffer name will be 28;; protected against accidental killing, or exiting Emacs, or both.
28;; displayed and the exit aborted. This is just a way of protecting 29;; Buffers associated with inferior modes, like shell or telnet, can
29;; yourself from yourself. For example, if you have a shell running a big 30;; be treated specially, by auto-unlocking them if their interior
30;; program and exiting Emacs would abort that program, you may want to lock 31;; processes are dead.
31;; that buffer, then if you forget about it after a while, you won't
32;; accidentally exit Emacs. To unlock the buffer, just goto the buffer and
33;; run toggle-emacs-lock again.
34 32
35;;; Code: 33;;; Code:
36 34
37(defvar emacs-lock-from-exiting nil 35(defgroup emacs-lock nil
38 "Whether Emacs is locked to prevent exiting. See `check-emacs-lock'.") 36 "Emacs-Lock mode."
39(make-variable-buffer-local 'emacs-lock-from-exiting) 37 :version "24.1"
40 38 :group 'convenience)
41(defvar emacs-lock-buffer-locked nil 39
42 "Whether a shell or telnet buffer was locked when its process was killed.") 40(defcustom emacs-lock-default-locking-mode 'all
43(make-variable-buffer-local 'emacs-lock-buffer-locked) 41 "Default locking mode of Emacs-Locked buffers.
44(put 'emacs-lock-buffer-locked 'permanent-local t) 42
43Its value is used as the default for `emacs-lock-mode' (which
44see) the first time that Emacs Lock mode is turned on in a buffer
45without passing an explicit locking mode.
46
47Possible values are:
48 exit -- Emacs cannot exit while the buffer is locked
49 kill -- the buffer cannot be killed, but Emacs can exit as usual
50 all -- the buffer is locked against both actions
51 nil -- the buffer is not locked"
52 :type '(choice
53 (const :tag "Do not allow Emacs to exit" exit)
54 (const :tag "Do not allow killing the buffer" kill)
55 (const :tag "Do not allow killing the buffer or exiting Emacs" all)
56 (const :tag "Do not lock the buffer" nil))
57 :group 'emacs-lock
58 :version "24.1")
59
60;; Note: as auto-unlocking can lead to data loss, it would be better
61;; to default to nil; but the value below is for compatibility with
62;; the old emacs-lock.el.
63(defcustom emacs-lock-unlockable-modes '((shell-mode . all)
64 (telnet-mode . all))
65 "Alist of auto-unlockable modes.
66Each element is a pair (MAJOR-MODE . ACTION), where ACTION is
67one of `kill', `exit' or `all'. Buffers with matching major
68modes are auto-unlocked for the specific action if their
69inferior processes are not alive. If this variable is t, all
70buffers associated to inferior processes are auto-unlockable
71for both actions (NOT RECOMMENDED)."
72 :type '(choice
73 (const :tag "All buffers with inferior processes" t)
74 (repeat :tag "Selected modes"
75 (cons :tag "Set auto-unlock for"
76 (symbol :tag "Major mode")
77 (radio
78 (const :tag "Allow exiting" exit)
79 (const :tag "Allow killing" kill)
80 (const :tag "Allow both" all)))))
81 :group 'emacs-lock
82 :version "24.1")
83
84(defvar emacs-lock-mode nil
85 "If non-nil, the current buffer is locked.
86It can be one of the following values:
87 exit -- Emacs cannot exit while the buffer is locked
88 kill -- the buffer cannot be killed, but Emacs can exit as usual
89 all -- the buffer is locked against both actions
90 nil -- the buffer is not locked")
91(make-variable-buffer-local 'emacs-lock-mode)
92(put 'emacs-lock-mode 'permanent-local t)
93
94(defvar emacs-lock--old-mode nil
95 "Most recent locking mode set on the buffer.
96Internal use only.")
97(make-variable-buffer-local 'emacs-lock--old-mode)
98(put 'emacs-lock--old-mode 'permanent-local t)
99
100(defvar emacs-lock--try-unlocking nil
101 "Non-nil if current buffer should be checked for auto-unlocking.
102Internal use only.")
103(make-variable-buffer-local 'emacs-lock--try-unlocking)
104(put 'emacs-lock--try-unlocking 'permanent-local t)
105
106(defun emacs-lock-live-process-p (buffer-or-name)
107 "Return t if BUFFER-OR-NAME is associated with a live process."
108 (let ((proc (get-buffer-process buffer-or-name)))
109 (and proc (process-live-p proc))))
110
111(defun emacs-lock--can-auto-unlock (action)
112 "Return t if the current buffer can auto-unlock for ACTION.
113ACTION must be one of `kill' or `exit'.
114See `emacs-lock-unlockable-modes'."
115 (and emacs-lock--try-unlocking
116 (not (emacs-lock-live-process-p (current-buffer)))
117 (or (eq emacs-lock-unlockable-modes t)
118 (let ((unlock (cdr (assq major-mode emacs-lock-unlockable-modes))))
119 (or (eq unlock 'all) (eq unlock action))))))
120
121(defun emacs-lock--exit-locked-buffer ()
122 "Return the name of the first exit-locked buffer found."
123 (save-current-buffer
124 (catch :found
125 (dolist (buffer (buffer-list))
126 (set-buffer buffer)
127 (unless (or (emacs-lock--can-auto-unlock 'exit)
128 (memq emacs-lock-mode '(nil kill)))
129 (throw :found (buffer-name))))
130 nil)))
131
132(defun emacs-lock--kill-emacs-hook ()
133 "Signal an error if any buffer is exit-locked.
134Used from `kill-emacs-hook' (which see)."
135 (let ((buffer-name (emacs-lock--exit-locked-buffer)))
136 (when buffer-name
137 (error "Emacs cannot exit because buffer %S is locked" buffer-name))))
138
139(defun emacs-lock--kill-emacs-query-functions ()
140 "Display a message if any buffer is exit-locked.
141Return a value appropriate for `kill-emacs-query-functions' (which see)."
142 (let ((locked (emacs-lock--exit-locked-buffer)))
143 (or (not locked)
144 (progn
145 (message "Emacs cannot exit because buffer %S is locked" locked)
146 nil))))
147
148(defun emacs-lock--kill-buffer-query-functions ()
149 "Display a message if the current buffer is kill-locked.
150Return a value appropriate for `kill-buffer-query-functions' (which see)."
151 (or (emacs-lock--can-auto-unlock 'kill)
152 (memq emacs-lock-mode '(nil exit))
153 (progn
154 (message "Buffer %S is locked and cannot be killed" (buffer-name))
155 nil)))
156
157(defun emacs-lock--set-mode (mode arg)
158 "Setter function for `emacs-lock-mode'."
159 (setq emacs-lock-mode
160 (cond ((memq arg '(all exit kill))
161 ;; explicit locking mode arg, use it
162 arg)
163 ((and (eq arg current-prefix-arg) (consp current-prefix-arg))
164 ;; called with C-u M-x emacs-lock-mode, so ask the user
165 (intern (completing-read "Locking mode: "
166 '("all" "exit" "kill")
167 nil t nil nil
168 (symbol-name
169 emacs-lock-default-locking-mode))))
170 ((eq mode t)
171 ;; turn on, so use previous setting, or customized default
172 (or emacs-lock--old-mode emacs-lock-default-locking-mode))
173 (t
174 ;; anything else (turn off)
175 mode))))
176
177;;;###autoload
178(define-minor-mode emacs-lock-mode
179 "Toggle Emacs Lock mode in the current buffer.
180
181With \\[universal-argument], ask for the locking mode to be used.
182With other prefix ARG, turn mode on if ARG is positive, off otherwise.
183
184Initially, if the user does not pass an explicit locking mode, it defaults
185to `emacs-lock-default-locking-mode' (which see); afterwards, the locking
186mode most recently set on the buffer is used instead.
187
188When called from Elisp code, ARG can be any locking mode:
189
190 exit -- Emacs cannot exit while the buffer is locked
191 kill -- the buffer cannot be killed, but Emacs can exit as usual
192 all -- the buffer is locked against both actions
193
194Other values are interpreted as usual."
195 :init-value nil
196 :lighter (""
197 (emacs-lock--try-unlocking " locked:" " Locked:")
198 (:eval (symbol-name emacs-lock-model)))
199 :group 'emacs-lock
200 :variable (emacs-lock-mode .
201 (lambda (mode)
202 (emacs-lock--set-mode mode arg)))
203 (when emacs-lock-mode
204 (setq emacs-lock--old-mode emacs-lock-mode)
205 (setq emacs-lock--try-unlocking
206 (or (and (eq emacs-lock-unlockable-modes t)
207 (emacs-lock-live-process-p (current-buffer)))
208 (assq major-mode emacs-lock-unlockable-modes)))))
45 209
46(defun check-emacs-lock () 210(unless noninteractive
47 "Check if variable `emacs-lock-from-exiting' is t for any buffer. 211 (add-hook 'kill-buffer-query-functions 'emacs-lock--kill-buffer-query-functions)
48If any locked buffer is found, signal error and display the buffer's name." 212 ;; We set a hook in both kill-emacs-hook and kill-emacs-query-functions because
49 (save-excursion 213 ;; we really want to use k-e-q-f to stop as soon as possible, but don't want to
214 ;; be caught by surprise if someone calls `kill-emacs' instead.
215 (add-hook 'kill-emacs-hook 'emacs-lock--kill-emacs-hook)
216 (add-hook 'kill-emacs-query-functions 'emacs-lock--kill-emacs-query-functions))
217
218(defun emacs-lock-unload-function ()
219 "Unload the Emacs Lock library."
220 (catch :continue
50 (dolist (buffer (buffer-list)) 221 (dolist (buffer (buffer-list))
51 (set-buffer buffer) 222 (set-buffer buffer)
52 (when emacs-lock-from-exiting 223 (when emacs-lock-mode
53 (error "Emacs is locked from exit due to buffer: %s" (buffer-name)))))) 224 (if (y-or-n-p (format "Buffer %S is locked, unlock it? " (buffer-name)))
225 (emacs-lock-mode -1)
226 (message "Unloading of feature `emacs-lock' aborted.")
227 (throw :continue t))))
228 ;; continue standard unloading
229 nil))
54 230
55(defun toggle-emacs-lock () 231;;; Compatibility
56 "Toggle `emacs-lock-from-exiting' for the current buffer.
57See `check-emacs-lock'."
58 (interactive)
59 (setq emacs-lock-from-exiting (not emacs-lock-from-exiting))
60 (if emacs-lock-from-exiting
61 (message "Buffer is now locked")
62 (message "Buffer is now unlocked")))
63
64(defun emacs-lock-check-buffer-lock ()
65 "Check if variable `emacs-lock-from-exiting' is t for a buffer.
66If the buffer is locked, signal error and display its name."
67 (when emacs-lock-from-exiting
68 (error "Buffer `%s' is locked, can't delete it" (buffer-name))))
69
70; These next defuns make it so if you exit a shell that is locked, the lock
71; is shut off for that shell so you can exit Emacs. Same for telnet.
72; Also, if a shell or a telnet buffer was locked and the process killed,
73; turn the lock back on again if the process is restarted.
74
75(defun emacs-lock-shell-sentinel ()
76 (set-process-sentinel
77 (get-buffer-process (buffer-name)) (function emacs-lock-clear-sentinel)))
78
79(defun emacs-lock-clear-sentinel (_proc _str)
80 (if emacs-lock-from-exiting
81 (progn
82 (setq emacs-lock-from-exiting nil)
83 (setq emacs-lock-buffer-locked t)
84 (message "Buffer is now unlocked"))
85 (setq emacs-lock-buffer-locked nil)))
86 232
87(defun emacs-lock-was-buffer-locked () 233(define-obsolete-variable-alias 'emacs-lock-from-exiting 'emacs-lock-mode "24.1")
88 (if emacs-lock-buffer-locked
89 (setq emacs-lock-from-exiting t)))
90 234
91(unless noninteractive 235(defun toggle-emacs-lock ()
92 (add-hook 'kill-emacs-hook 'check-emacs-lock)) 236 "Toggle `emacs-lock-from-exiting' for the current buffer."
93(add-hook 'kill-buffer-hook 'emacs-lock-check-buffer-lock) 237 (interactive)
94(add-hook 'shell-mode-hook 'emacs-lock-was-buffer-locked) 238 (call-interactively 'emacs-lock-mode))
95(add-hook 'shell-mode-hook 'emacs-lock-shell-sentinel) 239(make-obsolete 'toggle-emacs-lock 'emacs-lock-mode "24.1")
96(add-hook 'telnet-mode-hook 'emacs-lock-was-buffer-locked) 240k
97(add-hook 'telnet-mode-hook 'emacs-lock-shell-sentinel)
98
99(provide 'emacs-lock)
100
101;;; emacs-lock.el ends here
diff --git a/lisp/obsolete/old-emacs-lock.el b/lisp/obsolete/old-emacs-lock.el
new file mode 100644
index 00000000000..b45003fcecc
--- /dev/null
+++ b/lisp/obsolete/old-emacs-lock.el
@@ -0,0 +1,102 @@
1;;; emacs-lock.el --- prevents you from exiting Emacs if a buffer is locked
2
3;; Copyright (C) 1994, 1997, 2001-2011 Free Software Foundation, Inc
4
5;; Author: Tom Wurgler <twurgler@goodyear.com>
6;; Created: 12/8/94
7;; Keywords: extensions, processes
8;; Obsolete-since: 24.1
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software: you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24
25;;; Commentary:
26
27;; This code sets a buffer-local variable to t if toggle-emacs-lock is run,
28;; then if the user attempts to exit Emacs, the locked buffer name will be
29;; displayed and the exit aborted. This is just a way of protecting
30;; yourself from yourself. For example, if you have a shell running a big
31;; program and exiting Emacs would abort that program, you may want to lock
32;; that buffer, then if you forget about it after a while, you won't
33;; accidentally exit Emacs. To unlock the buffer, just goto the buffer and
34;; run toggle-emacs-lock again.
35
36;;; Code:
37
38(defvar emacs-lock-from-exiting nil
39 "Whether Emacs is locked to prevent exiting. See `check-emacs-lock'.")
40(make-variable-buffer-local 'emacs-lock-from-exiting)
41
42(defvar emacs-lock-buffer-locked nil
43 "Whether a shell or telnet buffer was locked when its process was killed.")
44(make-variable-buffer-local 'emacs-lock-buffer-locked)
45(put 'emacs-lock-buffer-locked 'permanent-local t)
46
47(defun check-emacs-lock ()
48 "Check if variable `emacs-lock-from-exiting' is t for any buffer.
49If any locked buffer is found, signal error and display the buffer's name."
50 (save-excursion
51 (dolist (buffer (buffer-list))
52 (set-buffer buffer)
53 (when emacs-lock-from-exiting
54 (error "Emacs is locked from exit due to buffer: %s" (buffer-name))))))
55
56(defun toggle-emacs-lock ()
57 "Toggle `emacs-lock-from-exiting' for the current buffer.
58See `check-emacs-lock'."
59 (interactive)
60 (setq emacs-lock-from-exiting (not emacs-lock-from-exiting))
61 (if emacs-lock-from-exiting
62 (message "Buffer is now locked")
63 (message "Buffer is now unlocked")))
64
65(defun emacs-lock-check-buffer-lock ()
66 "Check if variable `emacs-lock-from-exiting' is t for a buffer.
67If the buffer is locked, signal error and display its name."
68 (when emacs-lock-from-exiting
69 (error "Buffer `%s' is locked, can't delete it" (buffer-name))))
70
71; These next defuns make it so if you exit a shell that is locked, the lock
72; is shut off for that shell so you can exit Emacs. Same for telnet.
73; Also, if a shell or a telnet buffer was locked and the process killed,
74; turn the lock back on again if the process is restarted.
75
76(defun emacs-lock-shell-sentinel ()
77 (set-process-sentinel
78 (get-buffer-process (buffer-name)) (function emacs-lock-clear-sentinel)))
79
80(defun emacs-lock-clear-sentinel (_proc _str)
81 (if emacs-lock-from-exiting
82 (progn
83 (setq emacs-lock-from-exiting nil)
84 (setq emacs-lock-buffer-locked t)
85 (message "Buffer is now unlocked"))
86 (setq emacs-lock-buffer-locked nil)))
87
88(defun emacs-lock-was-buffer-locked ()
89 (if emacs-lock-buffer-locked
90 (setq emacs-lock-from-exiting t)))
91
92(unless noninteractive
93 (add-hook 'kill-emacs-hook 'check-emacs-lock))
94(add-hook 'kill-buffer-hook 'emacs-lock-check-buffer-lock)
95(add-hook 'shell-mode-hook 'emacs-lock-was-buffer-locked)
96(add-hook 'shell-mode-hook 'emacs-lock-shell-sentinel)
97(add-hook 'telnet-mode-hook 'emacs-lock-was-buffer-locked)
98(add-hook 'telnet-mode-hook 'emacs-lock-shell-sentinel)
99
100(provide 'emacs-lock)
101
102;;; emacs-lock.el ends here