(menu-bar-options-menu): Add Menu entry for longlines mode.
[bpt/emacs.git] / lisp / novice.el
... / ...
CommitLineData
1;;; novice.el --- handling of disabled commands ("novice mode") for Emacs
2
3;; Copyright (C) 1985, 1986, 1987, 1994, 2001, 2002, 2003, 2004,
4;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6;; Maintainer: FSF
7;; Keywords: internal, help
8
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
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) 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
22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23
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
30;;; Code:
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
37;;;###autoload
38(defvar disabled-command-function 'disabled-command-function
39 "Function to call to handle disabled commands.
40If nil, the feature is disabled, i.e., all commands work normally.")
41
42;;;###autoload
43(define-obsolete-variable-alias 'disabled-command-hook 'disabled-command-function "22.1")
44
45;; It is ok here to assume that this-command is a symbol
46;; because we won't get called otherwise.
47;;;###autoload
48(defun disabled-command-function (&rest ignore)
49 (let (char)
50 (save-window-excursion
51 (with-output-to-temp-buffer "*Disabled Command*"
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)))
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)))))
64 ;; Print any special message saying why the command is disabled.
65 (if (stringp (get this-command 'disabled))
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.
70 (with-current-buffer "*Disabled Command*"
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")
83 (princ "You can now type
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.
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.")
88 (save-excursion
89 (set-buffer standard-output)
90 (help-mode)))
91 (fit-window-to-buffer (get-buffer-window "*Disabled Command*"))
92 (message "Type y, n, ! or SPC (the space bar): ")
93 (let ((cursor-in-echo-area t))
94 (while (progn (setq char (read-event))
95 (or (not (numberp char))
96 (not (memq (downcase char)
97 '(?! ?y ?n ?\s ?\C-g)))))
98 (ding)
99 (message "Please type y, n, ! or SPC (the space bar): "))))
100 (setq char (downcase char))
101 (if (= char ?\C-g)
102 (setq quit-flag t))
103 (if (= char ?!)
104 (setq disabled-command-function nil))
105 (if (= char ?y)
106 (if (and user-init-file
107 (not (string= "" user-init-file))
108 (y-or-n-p "Enable command for future editing sessions also? "))
109 (enable-command this-command)
110 (put this-command 'disabled nil)))
111 (if (/= char ?n)
112 (call-interactively this-command))))
113
114;;;###autoload
115(defun enable-command (command)
116 "Allow COMMAND to be executed without special confirmation from now on.
117COMMAND must be a symbol.
118This command alters the user's .emacs file so that this will apply
119to future sessions."
120 (interactive "CEnable command: ")
121 (put command 'disabled nil)
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)
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))))
151
152;;;###autoload
153(defun disable-command (command)
154 "Require special confirmation to execute COMMAND from now on.
155COMMAND must be a symbol.
156This command alters the user's .emacs file so that this will apply
157to future sessions."
158 (interactive "CDisable command: ")
159 (if (not (commandp command))
160 (error "Invalid command name `%s'" command))
161 (put command 'disabled t)
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))
185 (progn (forward-line 1) (point)))
186 (goto-char (point-max))
187 (insert ?\n))
188 (insert "(put '" (symbol-name command) " 'disabled t)\n")
189 (save-buffer))))
190
191(provide 'novice)
192
193;; arch-tag: f83c0f96-497e-4db6-a430-8703716c6dd9
194;;; novice.el ends here