2903
|
1 ;;; delsel.el --- delete selection if you insert
|
2233
|
2
|
64762
|
3 ;; Copyright (C) 1992, 1997, 1998, 2001, 2002, 2003, 2004,
|
79721
|
4 ;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
2233
|
5
|
|
6 ;; Author: Matthieu Devin <devin@lucid.com>
|
17976
|
7 ;; Maintainer: FSF
|
2233
|
8 ;; Created: 14 Jul 92
|
29156
|
9 ;; Keywords: convenience emulations
|
2073
|
10
|
14169
|
11 ;; This file is part of GNU Emacs.
|
2073
|
12
|
14169
|
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
14 ;; it under the terms of the GNU General Public License as published by
|
78236
|
15 ;; the Free Software Foundation; either version 3, or (at your option)
|
14169
|
16 ;; any later version.
|
2073
|
17
|
14169
|
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.
|
2073
|
22
|
14169
|
23 ;; You should have received a copy of the GNU General Public License
|
|
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
64091
|
25 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
26 ;; Boston, MA 02110-1301, USA.
|
2073
|
27
|
2233
|
28 ;;; Commentary:
|
2073
|
29
|
14169
|
30 ;; This file makes the active region be pending delete, meaning that
|
|
31 ;; text inserted while the region is active will replace the region contents.
|
|
32 ;; This is a popular behavior of personal computers text editors.
|
2073
|
33
|
21720
|
34 ;; Interface:
|
2233
|
35
|
21720
|
36 ;; Commands which will delete the selection need a 'delete-selection
|
|
37 ;; property on their symbols; commands which insert text but don't
|
85811
|
38 ;; have this property won't delete the selection. It can be one of
|
21720
|
39 ;; the values:
|
|
40 ;; 'yank
|
|
41 ;; For commands which do a yank; ensures the region about to be
|
|
42 ;; deleted isn't yanked.
|
|
43 ;; 'supersede
|
|
44 ;; Delete the active region and ignore the current command,
|
|
45 ;; i.e. the command will just delete the region.
|
|
46 ;; 'kill
|
|
47 ;; `kill-region' is used on the selection, rather than
|
|
48 ;; `delete-region'. (Text selected with the mouse will typically
|
|
49 ;; be yankable anyhow.)
|
|
50 ;; non-nil
|
|
51 ;; The normal case: delete the active region prior to executing
|
|
52 ;; the command which will insert replacement text.
|
|
53
|
|
54 ;;; Code:
|
18785
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
55
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
56 ;;;###autoload
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
57 (defalias 'pending-delete-mode 'delete-selection-mode)
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
58
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
59 ;;;###autoload
|
32043
|
60 (define-minor-mode delete-selection-mode
|
18785
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
61 "Toggle Delete Selection mode.
|
79678
|
62 With prefix ARG, turn Delete Selection mode on if ARG is
|
|
63 positive, off if ARG is not positive.
|
18785
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
64
|
21720
|
65 When Delete Selection mode is enabled, Transient Mark mode is also
|
|
66 enabled and typed text replaces the selection if the selection is
|
|
67 active. Otherwise, typed text is just inserted at point regardless of
|
|
68 any selection."
|
33185
7630435cbccd
(delete-selection-mode): Drop unneeded positional args.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
69 :global t :group 'editing-basics
|
18785
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
70 (if (not delete-selection-mode)
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
71 (remove-hook 'pre-command-hook 'delete-selection-pre-hook)
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
72 (add-hook 'pre-command-hook 'delete-selection-pre-hook)
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
73 (transient-mark-mode t)))
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
74
|
2073
|
75 (defun delete-active-region (&optional killp)
|
2074
|
76 (if killp
|
|
77 (kill-region (point) (mark))
|
|
78 (delete-region (point) (mark)))
|
|
79 t)
|
2073
|
80
|
2903
|
81 (defun delete-selection-pre-hook ()
|
18785
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
82 (when (and delete-selection-mode transient-mark-mode mark-active
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
83 (not buffer-read-only))
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
84 (let ((type (and (symbolp this-command)
|
1a455d8dfa7c
Customise. Don't modify pre-command-hook on file load; do in command.
Simon Marshall <simon@gnu.org>
diff
changeset
|
85 (get this-command 'delete-selection))))
|
41254
|
86 (condition-case data
|
|
87 (cond ((eq type 'kill)
|
|
88 (delete-active-region t))
|
|
89 ((eq type 'yank)
|
81894
|
90 ;; Before a yank command, make sure we don't yank the
|
|
91 ;; head of the kill-ring that really comes from the
|
82507
9c9e50cbdf1e
(delete-selection-pre-hook): Use `mouse-region-match' instead of checking last-command.
Juri Linkov <juri@jurta.org>
diff
changeset
|
92 ;; currently active region we are going to delete.
|
41254
|
93 ;; That would make yank a no-op.
|
81894
|
94 (when (and (string= (buffer-substring-no-properties (point) (mark))
|
|
95 (car kill-ring))
|
85073
|
96 (fboundp 'mouse-region-match)
|
82507
9c9e50cbdf1e
(delete-selection-pre-hook): Use `mouse-region-match' instead of checking last-command.
Juri Linkov <juri@jurta.org>
diff
changeset
|
97 (mouse-region-match))
|
41254
|
98 (current-kill 1))
|
|
99 (delete-active-region))
|
|
100 ((eq type 'supersede)
|
|
101 (let ((empty-region (= (point) (mark))))
|
|
102 (delete-active-region)
|
|
103 (unless empty-region
|
|
104 (setq this-command 'ignore))))
|
|
105 (type
|
64947
|
106 (delete-active-region)
|
|
107 (if (and overwrite-mode (eq this-command 'self-insert-command))
|
|
108 (let ((overwrite-mode nil))
|
|
109 (self-insert-command (prefix-numeric-value current-prefix-arg))
|
|
110 (setq this-command 'ignore)))))
|
41254
|
111 (file-supersession
|
|
112 ;; If ask-user-about-supersession-threat signals an error,
|
|
113 ;; stop safe_run_hooks from clearing out pre-command-hook.
|
|
114 (and (eq inhibit-quit 'pre-command-hook)
|
|
115 (setq inhibit-quit 'delete-selection-dummy))
|
87933
|
116 (signal 'file-supersession (cdr data)))
|
|
117 (text-read-only
|
|
118 ;; This signal may come either from `delete-active-region' or
|
|
119 ;; `self-insert-command' (when `overwrite-mode' is non-nil).
|
|
120 ;; To avoid clearing out `pre-command-hook' we handle this case
|
|
121 ;; by issuing a simple message. Note, however, that we do not
|
|
122 ;; handle all related problems: When read-only text ends before
|
|
123 ;; the end of the region, the latter is not deleted but any
|
|
124 ;; subsequent insertion will succeed. We could avoid this case
|
|
125 ;; by doing a (setq this-command 'ignore) here. This would,
|
|
126 ;; however, still not handle the case where read-only text ends
|
|
127 ;; precisely where the region starts: In that case the deletion
|
|
128 ;; would succeed but the subsequent insertion would fail with a
|
|
129 ;; text-read-only error. To handle that case we would have to
|
|
130 ;; investigate text properties at both ends of the region and
|
|
131 ;; skip the deletion when inserting text is forbidden there.
|
|
132 (message "Text is read-only") (ding))))))
|
2073
|
133
|
2903
|
134 (put 'self-insert-command 'delete-selection t)
|
9533
|
135 (put 'self-insert-iso 'delete-selection t)
|
2073
|
136
|
12790
|
137 (put 'yank 'delete-selection 'yank)
|
13077
|
138 (put 'clipboard-yank 'delete-selection 'yank)
|
2925
|
139 (put 'insert-register 'delete-selection t)
|
2073
|
140
|
2903
|
141 (put 'delete-backward-char 'delete-selection 'supersede)
|
|
142 (put 'backward-delete-char-untabify 'delete-selection 'supersede)
|
|
143 (put 'delete-char 'delete-selection 'supersede)
|
2073
|
144
|
21720
|
145 (put 'newline-and-indent 'delete-selection t)
|
2903
|
146 (put 'newline 'delete-selection t)
|
21720
|
147 (put 'open-line 'delete-selection 'kill)
|
|
148
|
30817
|
149 ;; This is very useful for cancelling a selection in the minibuffer without
|
2073
|
150 ;; aborting the minibuffer.
|
|
151 (defun minibuffer-keyboard-quit ()
|
|
152 "Abort recursive edit.
|
21720
|
153 In Delete Selection mode, if the mark is active, just deactivate it;
|
|
154 then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
2073
|
155 (interactive)
|
2925
|
156 (if (and delete-selection-mode transient-mark-mode mark-active)
|
|
157 (setq deactivate-mark t)
|
2073
|
158 (abort-recursive-edit)))
|
|
159
|
30817
|
160 (define-key minibuffer-local-map "\C-g" 'minibuffer-keyboard-quit)
|
|
161 (define-key minibuffer-local-ns-map "\C-g" 'minibuffer-keyboard-quit)
|
|
162 (define-key minibuffer-local-completion-map "\C-g" 'minibuffer-keyboard-quit)
|
|
163 (define-key minibuffer-local-must-match-map "\C-g" 'minibuffer-keyboard-quit)
|
|
164 (define-key minibuffer-local-isearch-map "\C-g" 'minibuffer-keyboard-quit)
|
|
165
|
85811
|
166 (defun delsel-unload-function ()
|
|
167 "Unload the Delete Selection library."
|
30817
|
168 (define-key minibuffer-local-map "\C-g" 'abort-recursive-edit)
|
|
169 (define-key minibuffer-local-ns-map "\C-g" 'abort-recursive-edit)
|
|
170 (define-key minibuffer-local-completion-map "\C-g" 'abort-recursive-edit)
|
|
171 (define-key minibuffer-local-must-match-map "\C-g" 'abort-recursive-edit)
|
85811
|
172 (define-key minibuffer-local-isearch-map "\C-g" 'abort-recursive-edit)
|
|
173 (dolist (sym '(self-insert-command self-insert-iso yank clipboard-yank
|
|
174 insert-register delete-backward-char backward-delete-char-untabify
|
|
175 delete-char newline-and-indent newline open-line))
|
87936
b3879b6d2e40
(delsel-unload-function): Don't use `remprop'; it is not autoloaded,
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
176 (put sym 'delete-selection nil))
|
85811
|
177 ;; continue standard unloading
|
|
178 nil)
|
57540
|
179
|
2925
|
180 (provide 'delsel)
|
2073
|
181
|
52401
|
182 ;;; arch-tag: 1e388890-1b50-4ed0-9347-763b1343b6ed
|
2925
|
183 ;;; delsel.el ends here
|