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