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