lisp/frameset.el: Workaround bug#16793.
[bpt/emacs.git] / lisp / delsel.el
CommitLineData
28d3ed91 1;;; delsel.el --- delete selection if you insert
76550a57 2
ba318903 3;; Copyright (C) 1992, 1997-1998, 2001-2014 Free Software Foundation,
ab422c4d 4;; Inc.
76550a57
ER
5
6;; Author: Matthieu Devin <devin@lucid.com>
34dc21db 7;; Maintainer: emacs-devel@gnu.org
76550a57 8;; Created: 14 Jul 92
f947a7fa 9;; Keywords: convenience emulations
b0dbaa21 10
b578f267 11;; This file is part of GNU Emacs.
b0dbaa21 12
eb3fa2cf 13;; GNU Emacs is free software: you can redistribute it and/or modify
b578f267 14;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
b0dbaa21 17
b578f267
EN
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
b0dbaa21 22
b578f267 23;; You should have received a copy of the GNU General Public License
eb3fa2cf 24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
b0dbaa21 25
76550a57 26;;; Commentary:
b0dbaa21 27
b578f267
EN
28;; This file makes the active region be pending delete, meaning that
29;; text inserted while the region is active will replace the region contents.
30;; This is a popular behavior of personal computers text editors.
b0dbaa21 31
69b3c6c7
DL
32;; Interface:
33
34;; Commands which will delete the selection need a 'delete-selection
35;; property on their symbols; commands which insert text but don't
c815b73f 36;; have this property won't delete the selection. It can be one of
69b3c6c7
DL
37;; the values:
38;; 'yank
39;; For commands which do a yank; ensures the region about to be
40;; deleted isn't yanked.
41;; 'supersede
42;; Delete the active region and ignore the current command,
43;; i.e. the command will just delete the region.
44;; 'kill
45;; `kill-region' is used on the selection, rather than
46;; `delete-region'. (Text selected with the mouse will typically
47;; be yankable anyhow.)
c77d37e2 48;; t
69b3c6c7
DL
49;; The normal case: delete the active region prior to executing
50;; the command which will insert replacement text.
c77d37e2 51;; <function>
da5ecfa9 52;; For commands which need to dynamically determine this behavior.
c77d37e2 53;; The function should return one of the above values or nil.
76550a57 54
69b3c6c7 55;;; Code:
7853929f
SM
56
57;;;###autoload
58(defalias 'pending-delete-mode 'delete-selection-mode)
59
60;;;###autoload
ad03cafc 61(define-minor-mode delete-selection-mode
7853929f 62 "Toggle Delete Selection mode.
06e21633
CY
63With a prefix argument ARG, enable Delete Selection mode if ARG
64is positive, and disable it otherwise. If called from Lisp,
65enable the mode if ARG is omitted or nil.
7853929f 66
a69ecd19
GM
67When Delete Selection mode is enabled, typed text replaces the selection
68if the selection is active. Otherwise, typed text is just inserted at
69point regardless of any selection."
82fdafde 70 :global t :group 'editing-basics
7853929f
SM
71 (if (not delete-selection-mode)
72 (remove-hook 'pre-command-hook 'delete-selection-pre-hook)
4b72c12b 73 (add-hook 'pre-command-hook 'delete-selection-pre-hook)))
7853929f 74
b0dbaa21 75(defun delete-active-region (&optional killp)
b1d39ccc
SL
76 "Delete the active region.
77If KILLP in not-nil, the active region is killed instead of deleted."
af9157b9 78 (if killp
bb8097b9
JL
79 ;; Don't allow `kill-region' to change the value of `this-command'.
80 (let (this-command)
81 (kill-region (point) (mark) t))
00a2b823 82 (funcall region-extract-function 'delete-only))
af9157b9 83 t)
b0dbaa21 84
b1d39ccc 85(defun delete-selection-helper (type)
c77d37e2
SM
86 "Delete selection according to TYPE:
87 `yank'
b1d39ccc
SL
88 For commands which do a yank; ensures the region about to be
89 deleted isn't yanked.
c77d37e2 90 `supersede'
b1d39ccc
SL
91 Delete the active region and ignore the current command,
92 i.e. the command will just delete the region.
c77d37e2 93 `kill'
b1d39ccc
SL
94 `kill-region' is used on the selection, rather than
95 `delete-region'. (Text selected with the mouse will typically
96 be yankable anyhow.)
c77d37e2 97 t
b1d39ccc
SL
98 The normal case: delete the active region prior to executing
99 the command which will insert replacement text.
c77d37e2 100 FUNCTION
da5ecfa9 101 For commands which need to dynamically determine this behavior.
c77d37e2 102 FUNCTION should take no argument and return one of the above values or nil."
b1d39ccc
SL
103 (condition-case data
104 (cond ((eq type 'kill)
bb8097b9
JL
105 (delete-active-region t)
106 (if (and overwrite-mode
107 (eq this-command 'self-insert-command))
108 (let ((overwrite-mode nil))
109 (self-insert-command
110 (prefix-numeric-value current-prefix-arg))
111 (setq this-command 'ignore))))
b1d39ccc
SL
112 ((eq type 'yank)
113 ;; Before a yank command, make sure we don't yank the
114 ;; head of the kill-ring that really comes from the
115 ;; currently active region we are going to delete.
116 ;; That would make yank a no-op.
117 (when (and (string= (buffer-substring-no-properties
118 (point) (mark))
119 (car kill-ring))
120 (fboundp 'mouse-region-match)
121 (mouse-region-match))
122 (current-kill 1))
4b72c12b
SM
123 (let ((pos (copy-marker (region-beginning))))
124 (delete-active-region)
125 ;; If the region was, say, rectangular, make sure we yank
126 ;; from the top, to "replace".
127 (goto-char pos)))
b1d39ccc
SL
128 ((eq type 'supersede)
129 (let ((empty-region (= (point) (mark))))
130 (delete-active-region)
131 (unless empty-region
132 (setq this-command 'ignore))))
c77d37e2 133 ((functionp type) (delete-selection-helper (funcall type)))
b1d39ccc
SL
134 (type
135 (delete-active-region)
136 (if (and overwrite-mode
137 (eq this-command 'self-insert-command))
138 (let ((overwrite-mode nil))
139 (self-insert-command
140 (prefix-numeric-value current-prefix-arg))
141 (setq this-command 'ignore)))))
142 ;; If ask-user-about-supersession-threat signals an error,
143 ;; stop safe_run_hooks from clearing out pre-command-hook.
144 (file-supersession (message "%s" (cadr data)) (ding))
145 (text-read-only
146 ;; This signal may come either from `delete-active-region' or
147 ;; `self-insert-command' (when `overwrite-mode' is non-nil).
148 ;; To avoid clearing out `pre-command-hook' we handle this case
149 ;; by issuing a simple message. Note, however, that we do not
150 ;; handle all related problems: When read-only text ends before
151 ;; the end of the region, the latter is not deleted but any
152 ;; subsequent insertion will succeed. We could avoid this case
153 ;; by doing a (setq this-command 'ignore) here. This would,
154 ;; however, still not handle the case where read-only text ends
155 ;; precisely where the region starts: In that case the deletion
156 ;; would succeed but the subsequent insertion would fail with a
157 ;; text-read-only error. To handle that case we would have to
158 ;; investigate text properties at both ends of the region and
159 ;; skip the deletion when inserting text is forbidden there.
160 (message "Text is read-only") (ding))))
161
28d3ed91 162(defun delete-selection-pre-hook ()
c77d37e2
SM
163 "Function run before commands that delete selections are executed.
164Commands which will delete the selection need a `delete-selection'
165property on their symbol; commands which insert text but don't
b1d39ccc 166have this property won't delete the selection.
c77d37e2
SM
167See `delete-selection-helper'."
168 (when (and delete-selection-mode (use-region-p)
7853929f 169 (not buffer-read-only))
c77d37e2
SM
170 (delete-selection-helper (and (symbolp this-command)
171 (get this-command 'delete-selection)))))
b1d39ccc 172
c77d37e2
SM
173(put 'self-insert-command 'delete-selection
174 (lambda ()
175 (not (run-hook-with-args-until-success
176 'self-insert-uses-region-functions))))
b1d39ccc 177
bb8097b9
JL
178(put 'insert-char 'delete-selection t)
179(put 'quoted-insert 'delete-selection t)
180
6b214411 181(put 'yank 'delete-selection 'yank)
b708f0ad 182(put 'clipboard-yank 'delete-selection 'yank)
d4df3279 183(put 'insert-register 'delete-selection t)
b0dbaa21 184
bb8097b9 185(put 'reindent-then-newline-and-indent 'delete-selection t)
69b3c6c7 186(put 'newline-and-indent 'delete-selection t)
28d3ed91 187(put 'newline 'delete-selection t)
69b3c6c7
DL
188(put 'open-line 'delete-selection 'kill)
189
c80e3b4a 190;; This is very useful for canceling a selection in the minibuffer without
b0dbaa21 191;; aborting the minibuffer.
b0dbaa21
RS
192(defun minibuffer-keyboard-quit ()
193 "Abort recursive edit.
69b3c6c7
DL
194In Delete Selection mode, if the mark is active, just deactivate it;
195then it takes a second \\[keyboard-quit] to abort the minibuffer."
b0dbaa21 196 (interactive)
4b72c12b 197 (if (and delete-selection-mode (region-active-p))
d4df3279 198 (setq deactivate-mark t)
b0dbaa21
RS
199 (abort-recursive-edit)))
200
23652376
DL
201(define-key minibuffer-local-map "\C-g" 'minibuffer-keyboard-quit)
202(define-key minibuffer-local-ns-map "\C-g" 'minibuffer-keyboard-quit)
203(define-key minibuffer-local-completion-map "\C-g" 'minibuffer-keyboard-quit)
204(define-key minibuffer-local-must-match-map "\C-g" 'minibuffer-keyboard-quit)
205(define-key minibuffer-local-isearch-map "\C-g" 'minibuffer-keyboard-quit)
206
c815b73f
JB
207(defun delsel-unload-function ()
208 "Unload the Delete Selection library."
23652376
DL
209 (define-key minibuffer-local-map "\C-g" 'abort-recursive-edit)
210 (define-key minibuffer-local-ns-map "\C-g" 'abort-recursive-edit)
211 (define-key minibuffer-local-completion-map "\C-g" 'abort-recursive-edit)
212 (define-key minibuffer-local-must-match-map "\C-g" 'abort-recursive-edit)
c815b73f 213 (define-key minibuffer-local-isearch-map "\C-g" 'abort-recursive-edit)
4b72c12b
SM
214 (dolist (sym '(self-insert-command insert-char quoted-insert yank
215 clipboard-yank insert-register newline-and-indent
216 reindent-then-newline-and-indent newline open-line))
8c8e1952 217 (put sym 'delete-selection nil))
c815b73f
JB
218 ;; continue standard unloading
219 nil)
87f14b12 220
d4df3279 221(provide 'delsel)
b0dbaa21 222
d4df3279 223;;; delsel.el ends here