Bug fix for vc-dispatcher split.
[bpt/emacs.git] / lisp / novice.el
CommitLineData
55535639 1;;; novice.el --- handling of disabled commands ("novice mode") for Emacs
6594deb0 2
c90f2757 3;; Copyright (C) 1985, 1986, 1987, 1994, 2001, 2002, 2003, 2004,
409cc4a3 4;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
9750e079 5
e5167999 6;; Maintainer: FSF
d7b4d18f 7;; Keywords: internal, help
e5167999 8
a2535589
JA
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
b4aa6026 13;; the Free Software Foundation; either version 3, or (at your option)
a2535589
JA
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267 22;; along with GNU Emacs; see the file COPYING. If not, write to the
086add15
LK
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
a2535589 25
edbd2f74
ER
26;;; Commentary:
27
28;; This mode provides a hook which is, by default, attached to various
29;; putatively dangerous commands in a (probably futile) attempt to
30;; prevent lusers from shooting themselves in the feet.
31
aae56ea7 32;;; Code:
a2535589
JA
33
34;; This function is called (by autoloading)
35;; to handle any disabled command.
36;; The command is found in this-command
37;; and the keys are returned by (this-command-keys).
38
7229064d 39;;;###autoload
939a7761 40(defvar disabled-command-function 'disabled-command-function
4442951c
EN
41 "Function to call to handle disabled commands.
42If nil, the feature is disabled, i.e., all commands work normally.")
73fa8346 43
52e3545b 44;;;###autoload
6d9c9ad9 45(define-obsolete-variable-alias 'disabled-command-hook 'disabled-command-function "22.1")
939a7761 46
e3d47a15
RS
47;; It is ok here to assume that this-command is a symbol
48;; because we won't get called otherwise.
1c599895 49;;;###autoload
939a7761 50(defun disabled-command-function (&rest ignore)
a2535589
JA
51 (let (char)
52 (save-window-excursion
72287c23 53 (with-output-to-temp-buffer "*Disabled Command*"
be29d453
KH
54 (let ((keys (this-command-keys)))
55 (if (or (eq (aref keys 0)
56 (if (stringp keys)
57 (aref "\M-x" 0)
58 ?\M-x))
59 (and (>= (length keys) 2)
60 (eq (aref keys 0) meta-prefix-char)
61 (eq (aref keys 1) ?x)))
606e6135
RS
62 (princ (format "You have invoked the disabled command %s.\n"
63 (symbol-name this-command)))
64 (princ (format "You have typed %s, invoking disabled command %s.\n"
65 (key-description keys) (symbol-name this-command)))))
a2535589
JA
66 ;; Print any special message saying why the command is disabled.
67 (if (stringp (get this-command 'disabled))
606e6135
RS
68 (princ (get this-command 'disabled))
69 (princ "It is disabled because new users often find it confusing.\n")
70 (princ "Here's the first part of its description:\n\n")
71 ;; Keep only the first paragraph of the documentation.
72287c23 72 (with-current-buffer "*Disabled Command*"
606e6135
RS
73 (goto-char (point-max))
74 (let ((start (point)))
75 (save-excursion
76 (princ (or (condition-case ()
77 (documentation this-command)
78 (error nil))
79 "<< not documented >>")))
80 (if (search-forward "\n\n" nil t)
81 (delete-region (match-beginning 0) (point-max)))
82 (goto-char (point-max))
83 (indent-rigidly start (point) 3))))
84 (princ "\n\nDo you want to use this command anyway?\n\n")
a2535589 85 (princ "You can now type
eb4cb84f
PJ
86y to try it and enable it (no questions if you use it again).
87n to cancel--don't try the command, and it remains disabled.
606e6135
RS
88SPC to try the command just this once, but leave it disabled.
89! to try it, and enable all disabled commands for this session only.")
ea165072 90 (save-excursion
0468beec
MR
91 (set-buffer standard-output)
92 (help-mode)))
93 (fit-window-to-buffer (get-buffer-window "*Disabled Command*"))
eb4cb84f 94 (message "Type y, n, ! or SPC (the space bar): ")
a2535589 95 (let ((cursor-in-echo-area t))
72287c23
RS
96 (while (progn (setq char (read-event))
97 (or (not (numberp char))
98 (not (memq (downcase char)
2634a72a 99 '(?! ?y ?n ?\s ?\C-g)))))
a2535589 100 (ding)
eb4cb84f 101 (message "Please type y, n, ! or SPC (the space bar): "))))
72287c23
RS
102 (setq char (downcase char))
103 (if (= char ?\C-g)
104 (setq quit-flag t))
4442951c 105 (if (= char ?!)
939a7761 106 (setq disabled-command-function nil))
a2535589 107 (if (= char ?y)
7435bd25
RS
108 (if (and user-init-file
109 (not (string= "" user-init-file))
110 (y-or-n-p "Enable command for future editing sessions also? "))
a2535589
JA
111 (enable-command this-command)
112 (put this-command 'disabled nil)))
113 (if (/= char ?n)
114 (call-interactively this-command))))
115
7229064d 116;;;###autoload
a2535589
JA
117(defun enable-command (command)
118 "Allow COMMAND to be executed without special confirmation from now on.
7a4d608f
LT
119COMMAND must be a symbol.
120This command alters the user's .emacs file so that this will apply
a2535589
JA
121to future sessions."
122 (interactive "CEnable command: ")
123 (put command 'disabled nil)
2308fe27
EZ
124 (let ((init-file user-init-file)
125 (default-init-file
126 (if (eq system-type 'ms-dos) "~/_emacs" "~/.emacs")))
127 (when (null init-file)
128 (if (or (file-exists-p default-init-file)
129 (and (eq system-type 'windows-nt)
130 (file-exists-p "~/_emacs")))
131 ;; Started with -q, i.e. the file containing
132 ;; enabled/disabled commands hasn't been read. Saving
133 ;; settings there would overwrite other settings.
134 (error "Saving settings from \"emacs -q\" would overwrite existing customizations"))
135 (setq init-file default-init-file)
49b1a638
EZ
136 (if (and (not (file-exists-p init-file))
137 (eq system-type 'windows-nt)
138 (file-exists-p "~/_emacs"))
139 (setq init-file "~/_emacs")))
140 (save-excursion
141 (set-buffer (find-file-noselect
142 (substitute-in-file-name init-file)))
143 (goto-char (point-min))
144 (if (search-forward (concat "(put '" (symbol-name command) " ") nil t)
145 (delete-region
146 (progn (beginning-of-line) (point))
147 (progn (forward-line 1) (point))))
148 ;; Explicitly enable, in case this command is disabled by default
149 ;; or in case the code we deleted was actually a comment.
150 (goto-char (point-max))
151 (insert "\n(put '" (symbol-name command) " 'disabled nil)\n")
152 (save-buffer))))
a2535589 153
7229064d 154;;;###autoload
a2535589
JA
155(defun disable-command (command)
156 "Require special confirmation to execute COMMAND from now on.
7a4d608f
LT
157COMMAND must be a symbol.
158This command alters the user's .emacs file so that this will apply
a2535589
JA
159to future sessions."
160 (interactive "CDisable command: ")
5b817cf2
RS
161 (if (not (commandp command))
162 (error "Invalid command name `%s'" command))
a2535589 163 (put command 'disabled t)
2308fe27
EZ
164 (let ((init-file user-init-file)
165 (default-init-file
166 (if (eq system-type 'ms-dos) "~/_emacs" "~/.emacs")))
167 (when (null init-file)
168 (if (or (file-exists-p default-init-file)
169 (and (eq system-type 'windows-nt)
170 (file-exists-p "~/_emacs")))
171 ;; Started with -q, i.e. the file containing
172 ;; enabled/disabled commands hasn't been read. Saving
173 ;; settings there would overwrite other settings.
174 (error "Saving settings from \"emacs -q\" would overwrite existing customizations"))
175 (setq init-file default-init-file)
176 (if (and (not (file-exists-p init-file))
177 (eq system-type 'windows-nt)
178 (file-exists-p "~/_emacs"))
179 (setq init-file "~/_emacs")))
180 (save-excursion
181 (set-buffer (find-file-noselect
182 (substitute-in-file-name init-file)))
183 (goto-char (point-min))
184 (if (search-forward (concat "(put '" (symbol-name command) " ") nil t)
185 (delete-region
186 (progn (beginning-of-line) (point))
b2b46494
LK
187 (progn (forward-line 1) (point)))
188 (goto-char (point-max))
189 (insert ?\n))
190 (insert "(put '" (symbol-name command) " 'disabled t)\n")
2308fe27 191 (save-buffer))))
a2535589 192
896546cd
RS
193(provide 'novice)
194
c046590e 195;; arch-tag: f83c0f96-497e-4db6-a430-8703716c6dd9
6594deb0 196;;; novice.el ends here