Mercurial > emacs
comparison lisp/emulation/cua-base.el @ 44938:358d42530d42
Added cua-mode based files [split from original cua.el]:
cua-base.el, cua-rect.el, cua-gmrk.el, and keypad.el
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 28 Apr 2002 21:48:39 +0000 |
parents | |
children | 5b88ee8bf05e |
comparison
equal
deleted
inserted
replaced
44937:75c89848438b | 44938:358d42530d42 |
---|---|
1 ;;; cua-base.el --- emulate CUA key bindings | |
2 | |
3 ;; Copyright (C) 1997-2002 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Kim F. Storm <storm@cua.dk> | |
6 ;; Keywords: keyboard emulation convenience cua | |
7 | |
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 | |
12 ;; the Free Software Foundation; either version 2, or (at your option) | |
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 | |
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. | |
24 | |
25 | |
26 ;;; Commentary: | |
27 | |
28 ;; This is the CUA package which provides a complete emulation of the | |
29 ;; standard CUA key bindings (Motif/Windows/Mac GUI) for selecting and | |
30 ;; manipulating the region where S-<movement> is used to highlight & | |
31 ;; extend the region. | |
32 | |
33 ;; This package allow the C-z, C-x, C-c, and C-v keys to be | |
34 ;; bound appropriately according to the Motif/Windows GUI, i.e. | |
35 ;; C-z -> undo | |
36 ;; C-x -> cut | |
37 ;; C-c -> copy | |
38 ;; C-v -> paste | |
39 ;; | |
40 ;; The tricky part is the handling of the C-x and C-c keys which | |
41 ;; are normally used as prefix keys for most of emacs' built-in | |
42 ;; commands. With CUA they still do!!! | |
43 ;; | |
44 ;; Only when the region is currently active (and highlighted since | |
45 ;; transient-mark-mode is used), the C-x and C-c keys will work as CUA | |
46 ;; keys | |
47 ;; C-x -> cut | |
48 ;; C-c -> copy | |
49 ;; When the region is not active, C-x and C-c works as prefix keys! | |
50 ;; | |
51 ;; This probably sounds strange and difficult to get used to - but | |
52 ;; based on my own experience and the feedback from many users of | |
53 ;; this package, it actually works very well and users adapt to it | |
54 ;; instantly - or at least very quickly. So give it a try! | |
55 ;; ... and in the few cases where you make a mistake and accidentally | |
56 ;; delete the region - you just undo the mistake (with C-z). | |
57 ;; | |
58 ;; If you really need to perform a command which starts with one of | |
59 ;; the prefix keys even when the region is active, you have three options: | |
60 ;; - press the prefix key twice very quickly (within 0.2 seconds), | |
61 ;; - press the prefix key and the following key within 0.2 seconds), or | |
62 ;; - use the SHIFT key with the prefix key, i.e. C-X or C-C | |
63 ;; | |
64 ;; This behaviour can be customized via the | |
65 ;; cua-prefix-override-inhibit-delay variable. | |
66 | |
67 ;; In addition to using the shifted movement keys, you can also use | |
68 ;; [C-space] to start the region and use unshifted movement keys to extend | |
69 ;; it. To cancel the region, use [C-space] or [C-g]. | |
70 | |
71 ;; If you prefer to use the standard emacs cut, copy, paste, and undo | |
72 ;; bindings, customize cua-enable-cua-keys to nil. | |
73 | |
74 ;; CUA mode indications | |
75 ;; -------------------- | |
76 ;; You can choose to let CUA use different cursor colors to indicate | |
77 ;; overwrite mode and read-only buffers. For example, the following | |
78 ;; setting will use a RED cursor in normal (insertion) mode in | |
79 ;; read-write buffers, a YELLOW cursor in overwrite mode in read-write | |
80 ;; buffers, and a GREEN cursor read-only buffers: | |
81 ;; | |
82 ;; (setq cua-normal-cursor-color "red") | |
83 ;; (setq cua-overwrite-cursor-color "yellow") | |
84 ;; (setq cua-read-only-cursor-color "green") | |
85 ;; | |
86 | |
87 ;; CUA register support | |
88 ;; -------------------- | |
89 ;; Emacs' standard register support is also based on a separate set of | |
90 ;; "register commands". | |
91 ;; | |
92 ;; CUA's register support is activated by providing a numeric | |
93 ;; prefix argument to the C-x, C-c, and C-v commands. For example, | |
94 ;; to copy the selected region to register 2, enter [M-2 C-c]. | |
95 ;; Or if you have activated the keypad prefix mode, enter [kp-2 C-c]. | |
96 ;; | |
97 ;; And CUA will copy and paste normal region as well as rectangles | |
98 ;; into the registers, i.e. you use exactly the same command for both. | |
99 ;; | |
100 ;; In addition, the last highlighted text that is deleted (not | |
101 ;; copied), e.g. by [delete] or by typing text over a highlighted | |
102 ;; region, is automatically saved in register 0, so you can insert it | |
103 ;; using [M-0 C-v]. | |
104 | |
105 ;; CUA rectangle support | |
106 ;; --------------------- | |
107 ;; Emacs' normal rectangle support is based on interpreting the region | |
108 ;; between the mark and point as a "virtual rectangle", and using a | |
109 ;; completely separate set of "rectangle commands" [C-x r ...] on the | |
110 ;; region to copy, kill, fill a.s.o. the virtual rectangle. | |
111 ;; | |
112 ;; cua-mode's superior rectangle support is based on using a true visual | |
113 ;; representation of the selected rectangle. To start a rectangle, use | |
114 ;; [S-return] and extend it using the normal movement keys (up, down, | |
115 ;; left, right, home, end, C-home, C-end). Once the rectangle has the | |
116 ;; desired size, you can cut or copy it using C-x and C-c (or C-w and M-w), | |
117 ;; and you can subsequently insert it - as a rectangle - using C-v (or | |
118 ;; C-y). So the only new command you need to know to work with | |
119 ;; cua-mode rectangles is S-return! | |
120 ;; | |
121 ;; Normally, when you paste a rectangle using C-v (C-y), each line of | |
122 ;; the rectangle is inserted into the existing lines in the buffer. | |
123 ;; If overwrite-mode is active when you paste a rectangle, it is | |
124 ;; inserted as normal (multi-line) text. | |
125 ;; | |
126 ;; Furthermore, cua-mode's rectangles are not limited to the actual | |
127 ;; contents of the buffer, so if the cursor is currently at the end of a | |
128 ;; short line, you can still extend the rectangle to include more columns | |
129 ;; of longer lines in the same rectangle. Sounds strange? Try it! | |
130 ;; | |
131 ;; You can enable padding for just this rectangle by pressing [M-p]; | |
132 ;; this works like entering `picture-mode' where the tabs and spaces | |
133 ;; are automatically converted/inserted to make the rectangle truly | |
134 ;; rectangular. Or you can do it for all rectangles by setting the | |
135 ;; `cua-auto-expand-rectangles' variable. | |
136 | |
137 ;; And there's more: If you want to extend or reduce the size of the | |
138 ;; rectangle in one of the other corners of the rectangle, just use | |
139 ;; [return] to move the cursor to the "next" corner. Or you can use | |
140 ;; the [M-up], [M-down], [M-left], and [M-right] keys to move the | |
141 ;; entire rectangle overlay (but not the contents) in the given | |
142 ;; direction. | |
143 ;; | |
144 ;; [S-return] cancels the rectangle | |
145 ;; [C-space] activates the region bounded by the rectangle | |
146 | |
147 ;; If you type a normal (self-inserting) character when the rectangle is | |
148 ;; active, the character is inserted on the "current side" of every line | |
149 ;; of the rectangle. The "current side" is the side on which the cursor | |
150 ;; is currently located. If the rectangle is only 1 column wide, | |
151 ;; insertion will be performed to the left when the cursor is at the | |
152 ;; bottom of the rectangle. So, for example, to comment out an entire | |
153 ;; paragraph like this one, just place the cursor on the first character | |
154 ;; of the first line, and enter the following: | |
155 ;; S-return M-} ; ; <space> S-return | |
156 | |
157 ;; cua-mode's rectangle support also includes all the normal rectangle | |
158 ;; functions with easy access: | |
159 ;; | |
160 ;; [M-a] aligns all words at the left edge of the rectangle | |
161 ;; [M-b] fills the rectangle with blanks (tabs and spaces) | |
162 ;; [M-c] closes the rectangle by removing all blanks at the left edge | |
163 ;; of the rectangle | |
164 ;; [M-f] fills the rectangle with a single character (prompt) | |
165 ;; [M-i] increases the first number found on each line of the rectangle | |
166 ;; by the amount given by the numeric prefix argument (default 1) | |
167 ;; It recognizes 0x... as hexadecimal numbers | |
168 ;; [M-k] kills the rectangle as normal multi-line text (for paste) | |
169 ;; [M-l] downcases the rectangle | |
170 ;; [M-m] copies the rectangle as normal multi-line text (for paste) | |
171 ;; [M-n] fills each line of the rectangle with increasing numbers using | |
172 ;; a supplied format string (prompt) | |
173 ;; [M-o] opens the rectangle by moving the highlighted text to the | |
174 ;; right of the rectangle and filling the rectangle with blanks. | |
175 ;; [M-p] toggles rectangle padding, i.e. insert tabs and spaces to | |
176 ;; make rectangles truly rectangular | |
177 ;; [M-q] performs text filling on the rectangle | |
178 ;; [M-r] replaces REGEXP (prompt) by STRING (prompt) in rectangle | |
179 ;; [M-R] reverse the lines in the rectangle | |
180 ;; [M-s] fills each line of the rectangle with the same STRING (prompt) | |
181 ;; [M-t] performs text fill of the rectangle with TEXT (prompt) | |
182 ;; [M-u] upcases the rectangle | |
183 ;; [M-|] runs shell command on rectangle | |
184 ;; [M-'] restricts rectangle to lines with CHAR (prompt) at left column | |
185 ;; [M-/] restricts rectangle to lines matching REGEXP (prompt) | |
186 ;; [C-?] Shows a brief list of the above commands. | |
187 | |
188 ;; [M-C-up] and [M-C-down] scrolls the lines INSIDE the rectangle up | |
189 ;; and down; lines scrolled outside the top or bottom of the rectangle | |
190 ;; are lost, but can be recovered using [C-z]. | |
191 | |
192 ;; CUA Global Mark | |
193 ;; --------------- | |
194 ;; The final feature provided by CUA is the "global mark", which | |
195 ;; makes it very easy to copy bits and pieces from the same and other | |
196 ;; files into the current text. To enable and cancel the global mark, | |
197 ;; use [S-C-space]. The cursor will blink when the global mark | |
198 ;; is active. The following commands behave differently when the global | |
199 ;; mark is set: | |
200 ;; <ch> All characters (including newlines) you type are inserted | |
201 ;; at the global mark! | |
202 ;; [C-x] If you cut a region or rectangle, it is automatically inserted | |
203 ;; at the global mark, and the global mark is advanced. | |
204 ;; [C-c] If you copy a region or rectangle, it is immediately inserted | |
205 ;; at the global mark, and the global mark is advanced. | |
206 ;; [C-v] Copies a single character to the global mark. | |
207 ;; [C-d] Moves (i.e. deletes and inserts) a single character to the | |
208 ;; global mark. | |
209 ;; [backspace] deletes the character before the global mark, while | |
210 ;; [delete] deltes the character after the global mark. | |
211 | |
212 ;; [S-C-space] Jumps to and cancels the global mark. | |
213 ;; [C-u S-C-space] Cancels the global mark (stays in current buffer). | |
214 | |
215 ;; [TAB] Indents the current line or rectangle to the column of the | |
216 ;; global mark. | |
217 | |
218 ;;; Code: | |
219 | |
220 ;;; Customization | |
221 | |
222 (defgroup cua nil | |
223 "Emulate CUA key bindings including C-x and C-c." | |
224 :prefix "cua" | |
225 :group 'editing-basics | |
226 :group 'convenience | |
227 :group 'emulations | |
228 :link '(emacs-commentary-link :tag "Commentary" "cua-base.el") | |
229 :link '(emacs-library-link :tag "Lisp File" "cua-base.el")) | |
230 | |
231 ;;;###autoload | |
232 (defcustom cua-mode nil | |
233 "Non-nil means that CUA emulation mode is enabled. | |
234 In CUA mode, shifted movement keys highlight and extend the region. | |
235 When a region is highlighted, the binding of the C-x and C-c keys are | |
236 temporarily changed to work as Motif, MAC or MS-Windows cut and paste. | |
237 Also, insertion commands first delete the region and then insert. | |
238 This mode enables Transient Mark mode and it provides a superset of the | |
239 PC Selection Mode and Delete Selection Modes. | |
240 | |
241 Setting this variable directly does not take effect; | |
242 use either \\[customize] or the function `cua-mode'." | |
243 :set (lambda (symbol value) | |
244 (cua-mode (or value 0))) | |
245 :initialize 'custom-initialize-default | |
246 :set-after '(cua-enable-modeline-indications cua-use-hyper-key) | |
247 :require 'cua | |
248 :link '(emacs-commentary-link "cua-base.el") | |
249 :version "21.4" | |
250 :type 'boolean | |
251 :group 'cua) | |
252 | |
253 | |
254 (defcustom cua-enable-cua-keys t | |
255 "*Enable using C-z, C-x, C-c, and C-v for undo, cut, copy, and paste. | |
256 If the value is t, these mappings are always enabled. If the value is | |
257 'shift, these keys are only enabled if the last region was marked with | |
258 a shifted movement key. If the value is nil, these keys are never | |
259 enabled." | |
260 :type '(choice (const :tag "Disabled" nil) | |
261 (const :tag "Shift region only" shift) | |
262 (other :tag "Enabled")) | |
263 :group 'cua) | |
264 | |
265 (defcustom cua-highlight-region-shift-only nil | |
266 "*If non-nil, only highlight region if marked with S-<move>. | |
267 When this is non-nil, CUA toggles `transient-mark-mode' on when the region | |
268 is marked using shifted movement keys, and off when the mark is cleared. | |
269 But when the mark was set using \\[cua-set-mark], transient-mark-mode | |
270 is not turned on." | |
271 :type 'boolean | |
272 :group 'cua) | |
273 | |
274 (defcustom cua-prefix-override-inhibit-delay | |
275 (if (featurep 'lisp-float-type) (/ (float 1) (float 5)) nil) | |
276 "*If non-nil, time in seconds to delay before overriding prefix key. | |
277 If there is additional input within this time, the prefix key is | |
278 used as a normal prefix key. So typing a key sequence quickly will | |
279 inhibit overriding the prefix key. | |
280 As a special case, if the prefix keys repeated within this time, the | |
281 first prefix key is discarded, so typing a prefix key twice in quick | |
282 succession will also inhibit overriding the prefix key. | |
283 If the value is nil, use a shifted prefix key to inhibit the override." | |
284 :type '(choice (number :tag "Inhibit delay") | |
285 (const :tag "No delay" nil)) | |
286 :group 'cua) | |
287 | |
288 (defcustom cua-keep-region-after-copy nil | |
289 "If non-nil, don't deselect the region after copying." | |
290 :type 'boolean | |
291 :group 'cua) | |
292 | |
293 (defcustom cua-enable-register-prefix 'not-ctrl-u | |
294 "*If non-nil, registers are supported via numeric prefix arg. | |
295 If the value is t, any numeric prefix arg in the range 0 to 9 will be | |
296 interpreted as a register number. | |
297 If the value is not-ctrl-u, using C-u to enter a numeric prefix is not | |
298 interpreted as a register number. | |
299 If the value is ctrl-u-only, only numeric prefix entered with C-u is | |
300 interpreted as a register number." | |
301 :type '(choice (const :tag "Disabled" nil) | |
302 (const :tag "Enabled, but C-u arg is not a register" not-ctrl-u) | |
303 (const :tag "Enabled, but only for C-u arg" ctrl-u-only) | |
304 (other :tag "Enabled")) | |
305 :group 'cua) | |
306 | |
307 (defcustom cua-delete-copy-to-register-0 t | |
308 "*If non-nil, save last deleted region or rectangle to register 0." | |
309 :type 'boolean | |
310 :group 'cua) | |
311 | |
312 (defcustom cua-use-hyper-key nil | |
313 "*If non-nil, bind rectangle commands to H-? instead of M-?. | |
314 If set to 'also, toggle region command is also on S-return. | |
315 Must be set prior to enabling CUA." | |
316 :type '(choice (const :tag "Meta key and S-return" nil) | |
317 (const :tag "Hyper key only" only) | |
318 (const :tag "Hyper key and S-return" also)) | |
319 :group 'cua) | |
320 | |
321 (defcustom cua-enable-region-auto-help nil | |
322 "*If non-nil, automatically show help for active region." | |
323 :type 'boolean | |
324 :group 'cua) | |
325 | |
326 (defcustom cua-enable-modeline-indications nil | |
327 "*If non-nil, use minor-mode hook to show status in mode line." | |
328 :type 'boolean | |
329 :group 'cua) | |
330 | |
331 (defcustom cua-check-pending-input t | |
332 "*If non-nil, don't override prefix key if input pending. | |
333 It is rumoured that input-pending-p is unreliable under some window | |
334 managers, so try setting this to nil, if prefix override doesn't work." | |
335 :type 'boolean | |
336 :group 'cua) | |
337 | |
338 | |
339 ;;; Rectangle Customization | |
340 | |
341 (defcustom cua-auto-expand-rectangles nil | |
342 "*If non-nil, rectangles are padded with spaces to make straight edges. | |
343 This implies modifying buffer contents by expanding tabs and inserting spaces. | |
344 Consequently, this is inhibited in read-only buffers. | |
345 Can be toggled by [M-p] while the rectangle is active," | |
346 :type 'boolean | |
347 :group 'cua) | |
348 | |
349 (defcustom cua-enable-rectangle-auto-help t | |
350 "*If non-nil, automatically show help for region, rectangle and global mark." | |
351 :type 'boolean | |
352 :group 'cua) | |
353 | |
354 (defface cua-rectangle-face 'nil | |
355 "*Font used by CUA for highlighting the rectangle." | |
356 :group 'cua) | |
357 | |
358 (defface cua-rectangle-noselect-face 'nil | |
359 "*Font used by CUA for highlighting the non-selected rectangle lines." | |
360 :group 'cua) | |
361 | |
362 (defcustom cua-undo-max 64 | |
363 "*Max no of undoable CUA rectangle changes (including undo)." | |
364 :type 'integer | |
365 :group 'cua) | |
366 | |
367 | |
368 ;;; Global Mark Customization | |
369 | |
370 (defcustom cua-global-mark-keep-visible t | |
371 "*If non-nil, always keep global mark visible in other window." | |
372 :type 'boolean | |
373 :group 'cua) | |
374 | |
375 (defface cua-global-mark-face '((((class color)) | |
376 (:foreground "black") | |
377 (:background "yellow")) | |
378 (t (:bold t))) | |
379 "*Font used by CUA for highlighting the global mark." | |
380 :group 'cua) | |
381 | |
382 (defcustom cua-global-mark-blink-cursor-interval 0.20 | |
383 "*Blink cursor at this interval when global mark is active." | |
384 :type '(choice (number :tag "Blink interval") | |
385 (const :tag "No blink" nil)) | |
386 :group 'cua) | |
387 | |
388 | |
389 ;;; Cursor Indication Customization | |
390 | |
391 (defcustom cua-enable-cursor-indications t | |
392 "*If non-nil, use different cursor colors for indications." | |
393 :type 'boolean | |
394 :group 'cua) | |
395 | |
396 (defcustom cua-normal-cursor-color nil | |
397 "Normal (non-overwrite) cursor color. | |
398 Also used to indicate that rectangle padding is not in effect. | |
399 Automatically loaded from frame parameters, if nil." | |
400 :initialize (lambda (symbol value) | |
401 (set symbol (or value | |
402 (and (boundp 'initial-cursor-color) initial-cursor-color) | |
403 (and (boundp 'initial-frame-alist) | |
404 (assoc 'cursor-color initial-frame-alist) | |
405 (cdr (assoc 'cursor-color initial-frame-alist))) | |
406 (and (boundp 'default-frame-alist) | |
407 (assoc 'cursor-color default-frame-alist) | |
408 (cdr (assoc 'cursor-color default-frame-alist))) | |
409 (frame-parameter nil 'cursor-color)))) | |
410 :type 'color | |
411 :group 'cua) | |
412 | |
413 (defcustom cua-read-only-cursor-color "darkgreen" | |
414 "*Cursor color used in read-only buffers, if non-nil." | |
415 :type 'color | |
416 :group 'cua) | |
417 | |
418 (defcustom cua-overwrite-cursor-color "yellow" | |
419 "*Cursor color used when overwrite mode is set, if non-nil. | |
420 Also used to indicate that rectangle padding is in effect." | |
421 :type 'color | |
422 :group 'cua) | |
423 | |
424 (defcustom cua-global-mark-cursor-color "cyan" | |
425 "*Indication for active global mark. | |
426 Will change cursor color to specified color if string." | |
427 :type 'color | |
428 :group 'cua) | |
429 | |
430 | |
431 ;;; Rectangle support is in cua-rect.el | |
432 | |
433 (autoload 'cua-set-rectangle-mark "cua-rect" nil t nil) | |
434 | |
435 ;; Stub definitions until it is loaded | |
436 | |
437 (when (not (featurep 'cua-rect)) | |
438 (defvar cua--rectangle) | |
439 (setq cua--rectangle nil) | |
440 (defvar cua--last-killed-rectangle) | |
441 (setq cua--last-killed-rectangle nil)) | |
442 | |
443 | |
444 | |
445 ;;; Global Mark support is in cua-gmrk.el | |
446 | |
447 (autoload 'cua-toggle-global-mark "cua-gmrk.el" nil t nil) | |
448 | |
449 ;; Stub definitions until cua-gmrk.el is loaded | |
450 | |
451 (when (not (featurep 'cua-gmrk)) | |
452 (defvar cua--global-mark-active) | |
453 (setq cua--global-mark-active nil)) | |
454 | |
455 | |
456 (provide 'cua-base) | |
457 | |
458 (eval-when-compile | |
459 (require 'cua-rect) | |
460 (require 'cua-gmrk) | |
461 ) | |
462 | |
463 ;;; Aux. variables | |
464 | |
465 ;; Current region was started using cua-set-mark. | |
466 (defvar cua--explicit-region-start nil) | |
467 | |
468 ;; Latest region was started using shifted movement command. | |
469 (defvar cua--last-region-shifted nil) | |
470 | |
471 ;; buffer + point prior to current command when rectangle is active | |
472 ;; checked in post-command hook to see if point was moved | |
473 (defvar cua--buffer-and-point-before-command nil) | |
474 | |
475 ;; status string for mode line indications | |
476 (defvar cua--status-string nil) | |
477 | |
478 (defvar cua--debug nil) | |
479 | |
480 | |
481 ;;; Prefix key override mechanism | |
482 | |
483 ;; The prefix override (when mark-active) operates in three substates: | |
484 ;; [1] Before using a prefix key | |
485 ;; [2] Immediately after using a prefix key | |
486 ;; [3] A fraction of a second later | |
487 | |
488 ;; In state [1], the cua--prefix-override-keymap is active. | |
489 ;; This keymap binds the C-x and C-c prefix keys to the | |
490 ;; cua--prefix-override-handler function. | |
491 | |
492 ;; When a prefix key is typed in state [1], cua--prefix-override-handler | |
493 ;; will push back the keys already read to the event queue. If input is | |
494 ;; pending, it changes directly to state [3]. Otherwise, a short timer [T] | |
495 ;; is started, and it changes to state [2]. | |
496 | |
497 ;; In state [2], the cua--prefix-override-keymap is inactive. Instead the | |
498 ;; cua--prefix-repeat-keymap is active. This keymap binds C-c C-c and C-x | |
499 ;; C-x to the cua--prefix-repeat-handler function. | |
500 | |
501 ;; If the prefix key is repeated in state [2], cua--prefix-repeat-handler | |
502 ;; will cancel [T], back the keys already read (except for the second prefix | |
503 ;; keys) to the event queue, and changes to state [3]. | |
504 | |
505 ;; The basic cua--cua-keys-keymap binds [C-x timeout] to kill-region and | |
506 ;; [C-c timeout] to copy-region-as-kill, so if [T] times out in state [2], | |
507 ;; the cua--prefix-override-timeout function will push a `timeout' event on | |
508 ;; the event queue, and changes to state [3]. | |
509 | |
510 ;; In state [3] both cua--prefix-override-keymap and cua--prefix-repeat-keymap | |
511 ;; are inactive, so the timeout in cua-global-keymap binding is used, or the | |
512 ;; normal prefix key binding from the global or local map will be used. | |
513 | |
514 ;; The pre-command hook (executed as a consequence of the timeout or normal | |
515 ;; prefix key binding) will cancel [T] and change from state [3] back to | |
516 ;; state [1]. So cua--prefix-override-handler and cua--prefix-repeat-handler | |
517 ;; are always called with state reset to [1]! | |
518 | |
519 ;; State [1] is recognized by cua--prefix-override-timer is nil, | |
520 ;; state [2] is recognized by cua--prefix-override-timer is a timer, and | |
521 ;; state [3] is recognized by cua--prefix-override-timer is t. | |
522 | |
523 (defvar cua--prefix-override-timer nil) | |
524 (defvar cua--prefix-override-length nil) | |
525 | |
526 (defun cua--prefix-override-replay (arg repeat) | |
527 (let* ((keys (this-command-keys)) | |
528 (i (length keys)) | |
529 (key (aref keys (1- i)))) | |
530 (setq cua--prefix-override-length (- i repeat)) | |
531 (setq cua--prefix-override-timer | |
532 (or | |
533 ;; In state [2], change to state [3] | |
534 (> repeat 0) | |
535 ;; In state [1], change directly to state [3] | |
536 (and cua-check-pending-input (input-pending-p)) | |
537 ;; In state [1], [T] disabled, so change to state [3] | |
538 (not (numberp cua-prefix-override-inhibit-delay)) | |
539 (<= cua-prefix-override-inhibit-delay 0) | |
540 ;; In state [1], start [T] and change to state [2] | |
541 (run-with-timer cua-prefix-override-inhibit-delay nil | |
542 'cua--prefix-override-timeout))) | |
543 ;; Don't record this command | |
544 (setq this-command last-command) | |
545 ;; Restore the prefix arg | |
546 (setq prefix-arg arg) | |
547 (reset-this-command-lengths) | |
548 ;; Push the key back on the event queue | |
549 (setq unread-command-events (cons key unread-command-events)))) | |
550 | |
551 (defun cua--prefix-override-handler (arg) | |
552 "Start timer waiting for prefix key to be followed by another key. | |
553 Repeating prefix key when region is active works as a single prefix key." | |
554 (interactive "P") | |
555 (cua--prefix-override-replay arg 0)) | |
556 | |
557 (defun cua--prefix-repeat-handler (arg) | |
558 "Repeating prefix key when region is active works as a single prefix key." | |
559 (interactive "P") | |
560 (cua--prefix-override-replay arg 1)) | |
561 | |
562 (defun cua--prefix-copy-handler (arg) | |
563 "Copy region/rectangle, then replay last key." | |
564 (interactive "P") | |
565 (if cua--rectangle | |
566 (cua-copy-rectangle arg) | |
567 (cua-copy-region arg)) | |
568 (let ((keys (this-single-command-keys))) | |
569 (setq unread-command-events | |
570 (cons (aref keys (1- (length keys))) unread-command-events)))) | |
571 | |
572 (defun cua--prefix-cut-handler (arg) | |
573 "Cut region/rectangle, then replay last key." | |
574 (interactive "P") | |
575 (if cua--rectangle | |
576 (cua-cut-rectangle arg) | |
577 (cua-cut-region arg)) | |
578 (let ((keys (this-single-command-keys))) | |
579 (setq unread-command-events | |
580 (cons (aref keys (1- (length keys))) unread-command-events)))) | |
581 | |
582 (defun cua--prefix-override-timeout () | |
583 (setq cua--prefix-override-timer t) | |
584 (when (= (length (this-command-keys)) cua--prefix-override-length) | |
585 (setq unread-command-events (cons 'timeout unread-command-events)) | |
586 (if prefix-arg | |
587 (reset-this-command-lengths) | |
588 (setq overriding-terminal-local-map nil)) | |
589 (cua--fix-keymaps nil))) | |
590 | |
591 | |
592 ;;; Aux. functions | |
593 | |
594 (defun cua--fallback () | |
595 ;; Execute original command | |
596 (setq this-command this-original-command) | |
597 (call-interactively this-command)) | |
598 | |
599 (defun cua--keep-active () | |
600 (setq mark-active t | |
601 deactivate-mark nil)) | |
602 | |
603 (defun cua--deactivate (&optional now) | |
604 (setq cua--explicit-region-start nil) | |
605 (if (not now) | |
606 (setq deactivate-mark t) | |
607 (setq mark-active nil) | |
608 (run-hooks 'deactivate-mark-hook))) | |
609 | |
610 | |
611 ;; The current register prefix | |
612 (defvar cua--register nil) | |
613 | |
614 (defun cua--prefix-arg (arg) | |
615 (setq cua--register | |
616 (and cua-enable-register-prefix | |
617 (integerp (this-command-keys)) | |
618 (cond ((eq cua-enable-register-prefix 'not-ctrl-u) | |
619 (not (= (aref (this-command-keys) 0) ?\C-u))) | |
620 ((eq cua-enable-register-prefix 'ctrl-u-only) | |
621 (= (aref (this-command-keys) 0) ?\C-u)) | |
622 (t t)) | |
623 (integerp arg) (>= arg 0) (< arg 10) | |
624 (+ arg ?0))) | |
625 (if cua--register nil arg)) | |
626 | |
627 | |
628 ;;; Enhanced undo - restore rectangle selections | |
629 | |
630 (defun cua-undo (&optional arg) | |
631 "Undo some previous changes. | |
632 Knows about CUA rectangle highlighting in addition to standard undo." | |
633 (interactive "*P") | |
634 (if (fboundp 'cua--rectangle-undo) | |
635 (cua--rectangle-undo arg) | |
636 (undo arg))) | |
637 | |
638 ;;; Region specific commands | |
639 | |
640 (defun cua-delete-region () | |
641 "Delete the active region. | |
642 Save a copy in register 0 if `cua-delete-copy-to-register-0' is non-nil." | |
643 (interactive) | |
644 (let ((start (mark)) (end (point))) | |
645 (or (<= start end) | |
646 (setq start (prog1 end (setq end start)))) | |
647 (if cua-delete-copy-to-register-0 | |
648 (copy-to-register ?0 start end nil)) | |
649 (delete-region start end) | |
650 (cua--deactivate))) | |
651 | |
652 (defun cua-replace-region () | |
653 "Replace the active region with the character you type." | |
654 (interactive) | |
655 (cua-delete-region) | |
656 (if (not (eq this-original-command this-command)) | |
657 (cua--fallback))) | |
658 | |
659 (defun cua-copy-region (arg) | |
660 "Copy the region to the kill ring. | |
661 With numeric prefix arg, copy to register 0-9 instead." | |
662 (interactive "P") | |
663 (setq arg (cua--prefix-arg arg)) | |
664 (setq cua--last-killed-rectangle nil) | |
665 (let ((start (mark)) (end (point))) | |
666 (or (<= start end) | |
667 (setq start (prog1 end (setq end start)))) | |
668 (if cua--register | |
669 (copy-to-register cua--register start end nil) | |
670 (copy-region-as-kill start end)) | |
671 (if cua-keep-region-after-copy | |
672 (cua--keep-active) | |
673 (cua--deactivate)))) | |
674 | |
675 (defun cua-cut-region (arg) | |
676 "Cut the region and copy to the kill ring. | |
677 With numeric prefix arg, copy to register 0-9 instead." | |
678 (interactive "P") | |
679 (setq cua--last-killed-rectangle nil) | |
680 (if buffer-read-only | |
681 (cua-copy-region arg) | |
682 (setq arg (cua--prefix-arg arg)) | |
683 (let ((start (mark)) (end (point))) | |
684 (or (<= start end) | |
685 (setq start (prog1 end (setq end start)))) | |
686 (if cua--register | |
687 (copy-to-register cua--register start end t) | |
688 (kill-region start end))) | |
689 (cua--deactivate))) | |
690 | |
691 ;;; Generic commands for regions, rectangles, and global marks | |
692 | |
693 (defun cua-cancel () | |
694 "Cancel the active region, rectangle, or global mark." | |
695 (interactive) | |
696 (setq mark-active nil) | |
697 (setq cua--explicit-region-start nil) | |
698 (if (fboundp 'cua--cancel-rectangle) | |
699 (cua--cancel-rectangle))) | |
700 | |
701 (defun cua-paste (arg) | |
702 "Paste last cut or copied region or rectangle. | |
703 An active region is deleted before executing the command. | |
704 With numeric prefix arg, paste from register 0-9 instead. | |
705 If global mark is active, copy from register or one character." | |
706 (interactive "P") | |
707 (setq arg (cua--prefix-arg arg)) | |
708 (let ((regtxt (and cua--register (get-register cua--register))) | |
709 (count (prefix-numeric-value arg))) | |
710 (cond | |
711 ((and cua--register (not regtxt)) | |
712 (message "Nothing in register %c" cua--register)) | |
713 (cua--global-mark-active | |
714 (if regtxt | |
715 (cua--insert-at-global-mark regtxt) | |
716 (when (not (eobp)) | |
717 (cua--insert-at-global-mark (buffer-substring (point) (+ (point) count))) | |
718 (forward-char count)))) | |
719 (buffer-read-only | |
720 (message "Cannot paste into a read-only buffer")) | |
721 (t | |
722 ;; Must save register here, since delete may override reg 0. | |
723 (if mark-active | |
724 ;; Before a yank command, make sure we don't yank | |
725 ;; the same region that we are going to delete. | |
726 ;; That would make yank a no-op. | |
727 (if cua--rectangle | |
728 (cua--delete-rectangle) | |
729 (if (string= (buffer-substring (point) (mark)) | |
730 (car kill-ring)) | |
731 (current-kill 1)) | |
732 (cua-delete-region))) | |
733 (cond | |
734 (regtxt | |
735 (cond | |
736 ((consp regtxt) (cua--insert-rectangle regtxt)) | |
737 ((stringp regtxt) (insert-for-yank regtxt)) | |
738 (t (message "Unknown data in register %c" cua--register)))) | |
739 ((and cua--last-killed-rectangle | |
740 (eq (and kill-ring (car kill-ring)) (car cua--last-killed-rectangle))) | |
741 (let ((pt (point))) | |
742 (when (not (eq buffer-undo-list t)) | |
743 (setq this-command 'cua--paste-rectangle) | |
744 (undo-boundary) | |
745 (setq buffer-undo-list (cons pt buffer-undo-list))) | |
746 (cua--insert-rectangle (cdr cua--last-killed-rectangle)) | |
747 (if arg (goto-char pt)))) | |
748 (t (yank arg))))))) | |
749 | |
750 (defun cua-paste-pop (arg) | |
751 "Replace a just-pasted text or rectangle with a different text. | |
752 See `yank-pop' for details." | |
753 (interactive "P") | |
754 (if (eq last-command 'cua--paste-rectangle) | |
755 (progn | |
756 (undo) | |
757 (yank arg)) | |
758 (yank-pop (prefix-numeric-value arg)))) | |
759 | |
760 (defun cua-exchange-point-and-mark (arg) | |
761 "Exchanges point and mark, but don't activate the mark. | |
762 Activates the mark if a prefix argument is given." | |
763 (interactive "P") | |
764 (if arg | |
765 (setq mark-active t) | |
766 (let (mark-active) | |
767 (exchange-point-and-mark) | |
768 (if cua--rectangle | |
769 (cua--rectangle-corner 0))))) | |
770 | |
771 (defun cua-help-for-region (&optional help) | |
772 "Show region specific help in echo area." | |
773 (interactive) | |
774 (message | |
775 (concat (if help "C-?:help " "") | |
776 "C-z:undo C-x:cut C-c:copy C-v:paste S-ret:rect"))) | |
777 | |
778 | |
779 ;;; Shift activated / extended region | |
780 | |
781 (defun cua-set-mark (&optional arg) | |
782 "Set mark at where point is, clear mark, or jump to mark. | |
783 With no prefix argument, set mark, push old mark position on local mark | |
784 ring, and push mark on global mark ring, or if mark is already set, clear mark. | |
785 With argument, jump to mark, and pop a new position for mark off the ring; | |
786 then it jumps to the next mark off the ring if repeated with no argument, or | |
787 sets the mark at the new position if repeated with argument." | |
788 (interactive "P") | |
789 (if (and (eq this-command last-command) | |
790 last-prefix-arg) | |
791 (setq arg (if arg nil last-prefix-arg) | |
792 current-prefix-arg arg)) | |
793 (cond | |
794 (arg | |
795 (if (null (mark t)) | |
796 (error "No mark set in this buffer") | |
797 (goto-char (mark t)) | |
798 (pop-mark))) | |
799 (mark-active | |
800 (cua--deactivate) | |
801 (message "Mark Cleared")) | |
802 (t | |
803 (push-mark nil nil t) | |
804 (setq cua--explicit-region-start t) | |
805 (setq cua--last-region-shifted nil) | |
806 (if cua-enable-region-auto-help | |
807 (cua-help-for-region t))))) | |
808 | |
809 (defvar cua--standard-movement-commands | |
810 '(forward-char backward-char | |
811 next-line previous-line | |
812 forward-word backward-word | |
813 end-of-line beginning-of-line | |
814 end-of-buffer beginning-of-buffer | |
815 scroll-up scroll-down forward-paragraph backward-paragraph) | |
816 "List of standard movement commands. | |
817 Extra commands should be added to `cua-user-movement-commands'") | |
818 | |
819 (defvar cua-movement-commands nil | |
820 "User may add additional movement commands to this list.") | |
821 | |
822 | |
823 ;;; Cursor indications | |
824 | |
825 (defun cua--update-indications () | |
826 (let ((cursor | |
827 (cond | |
828 ((and cua--global-mark-active | |
829 (stringp cua-global-mark-cursor-color)) | |
830 cua-global-mark-cursor-color) | |
831 ((and buffer-read-only | |
832 (stringp cua-read-only-cursor-color)) | |
833 cua-read-only-cursor-color) | |
834 ((and (stringp cua-overwrite-cursor-color) | |
835 (or overwrite-mode | |
836 (and cua--rectangle (cua--rectangle-padding)))) | |
837 cua-overwrite-cursor-color) | |
838 (t cua-normal-cursor-color)))) | |
839 (if (and cursor | |
840 (not (equal cursor (frame-parameter nil 'cursor-color)))) | |
841 (set-cursor-color cursor)) | |
842 cursor)) | |
843 | |
844 | |
845 ;;; Pre-command hook | |
846 | |
847 (defun cua--pre-command-handler () | |
848 (condition-case nil | |
849 (let ((movement (or (memq this-command cua--standard-movement-commands) | |
850 (memq this-command cua-movement-commands)))) | |
851 | |
852 ;; Cancel prefix key timeout if user enters another key. | |
853 (when cua--prefix-override-timer | |
854 (if (timerp cua--prefix-override-timer) | |
855 (cancel-timer cua--prefix-override-timer)) | |
856 (setq cua--prefix-override-timer nil)) | |
857 | |
858 ;; Handle shifted cursor keys and other movement commands. | |
859 ;; If region is not active, region is activated if key is shifted. | |
860 ;; If region is active, region is cancelled if key is unshifted (and region not started with C-SPC). | |
861 ;; If rectangle is active, expand rectangle in specified direction and ignore the movement. | |
862 (if movement | |
863 (cond | |
864 ((memq 'shift (event-modifiers (aref (this-single-command-raw-keys) 0))) | |
865 (unless mark-active | |
866 (push-mark nil t t)) | |
867 (setq cua--last-region-shifted t) | |
868 (setq cua--explicit-region-start nil)) | |
869 ((or cua--explicit-region-start cua--rectangle) | |
870 (unless mark-active | |
871 (push-mark nil nil t))) | |
872 (t | |
873 ;; If we set mark-active to nil here, the region highlight will not be | |
874 ;; removed by the direct_output_ commands. | |
875 (setq deactivate-mark t))) | |
876 | |
877 ;; Handle delete-selection property on other commands | |
878 (let* ((ds (or (get this-command 'delete-selection) | |
879 (get this-command 'pending-delete))) | |
880 (nc (cond | |
881 ((eq ds 'yank) | |
882 'cua-paste) | |
883 ((eq ds 'kill) | |
884 (if cua--rectangle | |
885 'cua-copy-rectangle | |
886 'cua-copy-region)) | |
887 ((eq ds 'supersede) | |
888 (if cua--rectangle | |
889 'cua-delete-rectangle ;; replace? | |
890 'cua-replace-region)) | |
891 (ds | |
892 (if cua--rectangle | |
893 'cua-delete-rectangle | |
894 'cua-delete-region)) | |
895 (t nil)))) | |
896 (if nc | |
897 (setq this-original-command this-command | |
898 this-command nc)))) | |
899 | |
900 ;; Detect extension of rectangles by mouse or other movement | |
901 (setq cua--buffer-and-point-before-command | |
902 (if cua--rectangle (cons (current-buffer) (point)))) | |
903 ) | |
904 (error nil))) | |
905 | |
906 ;;; Post-command hook | |
907 | |
908 (defun cua--post-command-handler () | |
909 (condition-case nil | |
910 (progn | |
911 (when cua--global-mark-active | |
912 (cua--global-mark-post-command)) | |
913 (when (fboundp 'cua--rectangle-post-command) | |
914 (cua--rectangle-post-command)) | |
915 (setq cua--buffer-and-point-before-command nil) | |
916 (if (or (not mark-active) deactivate-mark) | |
917 (setq cua--explicit-region-start nil)) | |
918 | |
919 ;; Debugging | |
920 (if cua--debug | |
921 (cond | |
922 (cua--rectangle (cua--rectangle-assert)) | |
923 (mark-active (message "Mark=%d Point=%d Expl=%s" | |
924 (mark t) (point) cua--explicit-region-start)))) | |
925 | |
926 ;; Disable transient-mark-mode if rectangle active in current buffer. | |
927 (if (not (window-minibuffer-p (selected-window))) | |
928 (setq transient-mark-mode (and (not cua--rectangle) | |
929 (if cua-highlight-region-shift-only | |
930 (not cua--explicit-region-start) | |
931 t)))) | |
932 (if cua-enable-cursor-indications | |
933 (cua--update-indications)) | |
934 | |
935 (cua--fix-keymaps nil) | |
936 ) | |
937 | |
938 (error nil))) | |
939 | |
940 | |
941 ;;; Keymaps | |
942 | |
943 (defun cua--M/H-key (map key fct) | |
944 ;; bind H-KEY or M-KEY to FCT in MAP | |
945 (if (eq key 'space) (setq key ? )) | |
946 (unless (listp key) (setq key (list key))) | |
947 (define-key map (vector (cons (if cua-use-hyper-key 'hyper 'meta) key)) fct)) | |
948 | |
949 (defvar cua-global-keymap (make-sparse-keymap)) | |
950 (defvar cua--cua-keys-keymap (make-sparse-keymap)) | |
951 (defvar cua--prefix-override-keymap (make-sparse-keymap)) | |
952 (defvar cua--prefix-repeat-keymap (make-sparse-keymap)) | |
953 (defvar cua--global-mark-keymap (make-sparse-keymap)) ; Initalized when cua-gmrk.el is loaded | |
954 (defvar cua--rectangle-keymap (make-sparse-keymap)) ; Initalized when cua-rect.el is loaded | |
955 (defvar cua--region-keymap (make-sparse-keymap)) | |
956 | |
957 (defvar cua--ena-cua-keys-keymap nil) | |
958 (defvar cua--ena-prefix-override-keymap nil) | |
959 (defvar cua--ena-prefix-repeat-keymap nil) | |
960 (defvar cua--ena-region-keymap nil) | |
961 (defvar cua--ena-global-mark-keymap nil) | |
962 | |
963 (defvar cua--mmap-prefix-override-keymap (cons 'cua--ena-prefix-override-keymap cua--prefix-override-keymap)) | |
964 (defvar cua--mmap-prefix-repeat-keymap (cons 'cua--ena-prefix-repeat-keymap cua--prefix-repeat-keymap)) | |
965 (defvar cua--mmap-cua-keys-keymap (cons 'cua--ena-cua-keys-keymap cua--cua-keys-keymap)) | |
966 (defvar cua--mmap-global-mark-keymap (cons 'cua--ena-global-mark-keymap cua--global-mark-keymap)) | |
967 (defvar cua--mmap-rectangle-keymap (cons 'cua--rectangle cua--rectangle-keymap)) | |
968 (defvar cua--mmap-region-keymap (cons 'cua--ena-region-keymap cua--region-keymap)) | |
969 (defvar cua--mmap-global-keymap (cons 'cua-mode cua-global-keymap)) | |
970 | |
971 (defvar cua--mmap-list | |
972 (list cua--mmap-prefix-override-keymap | |
973 cua--mmap-prefix-repeat-keymap | |
974 cua--mmap-cua-keys-keymap | |
975 cua--mmap-global-mark-keymap | |
976 cua--mmap-rectangle-keymap | |
977 cua--mmap-region-keymap | |
978 cua--mmap-global-keymap)) | |
979 | |
980 (defun cua--fix-keymaps (disable) | |
981 ;; Ensure that cua's keymaps are in minor-mode-map-alist and | |
982 ;; in the correct order. | |
983 (let (fix | |
984 (mmap minor-mode-map-alist) | |
985 (ml cua--mmap-list)) | |
986 (while (and (not fix) mmap ml) | |
987 (if (not (eq (car mmap) (car ml))) | |
988 (setq fix t) | |
989 (setq mmap (cdr mmap) | |
990 ml (cdr ml)))) | |
991 (if ml | |
992 (setq fix t)) | |
993 (when (or fix disable) | |
994 (setq ml cua--mmap-list) | |
995 (while ml | |
996 (setq minor-mode-map-alist (delq (car ml) minor-mode-map-alist)) | |
997 (setq ml (cdr ml)))) | |
998 (when (and fix (not disable)) | |
999 (setq minor-mode-map-alist | |
1000 (append (copy-sequence cua--mmap-list) minor-mode-map-alist)))) | |
1001 (setq cua--ena-region-keymap | |
1002 (and mark-active (not deactivate-mark))) | |
1003 (setq cua--ena-prefix-override-keymap | |
1004 (and cua--ena-region-keymap | |
1005 cua-enable-cua-keys | |
1006 (or (eq cua-enable-cua-keys t) | |
1007 (not cua--explicit-region-start)) | |
1008 (not executing-kbd-macro) | |
1009 (not cua--prefix-override-timer))) | |
1010 (setq cua--ena-prefix-repeat-keymap | |
1011 (and cua--ena-region-keymap | |
1012 (timerp cua--prefix-override-timer))) | |
1013 (setq cua--ena-cua-keys-keymap | |
1014 (and cua-enable-cua-keys | |
1015 (or (eq cua-enable-cua-keys t) | |
1016 cua--last-region-shifted))) | |
1017 (setq cua--ena-global-mark-keymap | |
1018 (and cua--global-mark-active | |
1019 (not (window-minibuffer-p))))) | |
1020 | |
1021 (defvar cua--keymaps-initalized nil) | |
1022 | |
1023 (defun cua--init-keymaps () | |
1024 (unless (eq cua-use-hyper-key 'only) | |
1025 (define-key cua-global-keymap [(shift return)] 'cua-set-rectangle-mark)) | |
1026 (when cua-use-hyper-key | |
1027 (cua--M/H-key cua-global-keymap 'space 'cua-set-rectangle-mark) | |
1028 (define-key cua-global-keymap [(hyper mouse-1)] 'cua-mouse-set-rectangle-mark)) | |
1029 | |
1030 (define-key cua-global-keymap [(shift control ? )] 'cua-toggle-global-mark) | |
1031 | |
1032 ;; replace region with rectangle or element on kill ring | |
1033 (define-key cua-global-keymap [remap yank] 'cua-paste) | |
1034 (define-key cua-global-keymap [remap clipboard-yank] 'cua-paste) | |
1035 ;; replace current yank with previous kill ring element | |
1036 (define-key cua-global-keymap [remap yank-pop] 'cua-paste-pop) | |
1037 ;; set mark | |
1038 (define-key cua-global-keymap [remap set-mark-command] 'cua-set-mark) | |
1039 ;; undo | |
1040 (define-key cua-global-keymap [remap undo] 'cua-undo) | |
1041 (define-key cua-global-keymap [remap advertised-undo] 'cua-undo) | |
1042 | |
1043 (define-key cua--cua-keys-keymap [(control x) timeout] 'kill-region) | |
1044 (define-key cua--cua-keys-keymap [(shift control x)] 'Control-X-prefix) | |
1045 (define-key cua--cua-keys-keymap [(control c) timeout] 'copy-region-as-kill) | |
1046 (define-key cua--cua-keys-keymap [(shift control c)] 'mode-specific-command-prefix) | |
1047 (define-key cua--cua-keys-keymap [(control z)] 'undo) | |
1048 (define-key cua--cua-keys-keymap [(control v)] 'yank) | |
1049 (define-key cua--cua-keys-keymap [remap exchange-point-and-mark] 'cua-exchange-point-and-mark) | |
1050 | |
1051 (define-key cua--prefix-override-keymap [(control x)] 'cua--prefix-override-handler) | |
1052 (define-key cua--prefix-override-keymap [(control c)] 'cua--prefix-override-handler) | |
1053 | |
1054 (define-key cua--prefix-repeat-keymap [(control x) (control x)] 'cua--prefix-repeat-handler) | |
1055 (define-key cua--prefix-repeat-keymap [(control x) up] 'cua--prefix-cut-handler) | |
1056 (define-key cua--prefix-repeat-keymap [(control x) down] 'cua--prefix-cut-handler) | |
1057 (define-key cua--prefix-repeat-keymap [(control x) left] 'cua--prefix-cut-handler) | |
1058 (define-key cua--prefix-repeat-keymap [(control x) right] 'cua--prefix-cut-handler) | |
1059 (define-key cua--prefix-repeat-keymap [(control c) (control c)] 'cua--prefix-repeat-handler) | |
1060 (define-key cua--prefix-repeat-keymap [(control c) up] 'cua--prefix-copy-handler) | |
1061 (define-key cua--prefix-repeat-keymap [(control c) down] 'cua--prefix-copy-handler) | |
1062 (define-key cua--prefix-repeat-keymap [(control c) left] 'cua--prefix-copy-handler) | |
1063 (define-key cua--prefix-repeat-keymap [(control c) right] 'cua--prefix-copy-handler) | |
1064 | |
1065 ;; replace current region | |
1066 (define-key cua--region-keymap [remap self-insert-command] 'cua-replace-region) | |
1067 (define-key cua--region-keymap [remap self-insert-iso] 'cua-replace-region) | |
1068 (define-key cua--region-keymap [remap insert-register] 'cua-replace-region) | |
1069 (define-key cua--region-keymap [remap newline-and-indent] 'cua-replace-region) | |
1070 (define-key cua--region-keymap [remap newline] 'cua-replace-region) | |
1071 (define-key cua--region-keymap [remap open-line] 'cua-replace-region) | |
1072 ;; delete current region | |
1073 (define-key cua--region-keymap [remap delete-backward-char] 'cua-delete-region) | |
1074 (define-key cua--region-keymap [remap backward-delete-char] 'cua-delete-region) | |
1075 (define-key cua--region-keymap [remap backward-delete-char-untabify] 'cua-delete-region) | |
1076 (define-key cua--region-keymap [remap delete-char] 'cua-delete-region) | |
1077 ;; kill region | |
1078 (define-key cua--region-keymap [remap kill-region] 'cua-cut-region) | |
1079 ;; copy region | |
1080 (define-key cua--region-keymap [remap copy-region-as-kill] 'cua-copy-region) | |
1081 (define-key cua--region-keymap [remap kill-ring-save] 'cua-copy-region) | |
1082 ;; cancel current region/rectangle | |
1083 (define-key cua--region-keymap [remap keyboard-escape-quit] 'cua-cancel) | |
1084 (define-key cua--region-keymap [remap keyboard-quit] 'cua-cancel) | |
1085 ) | |
1086 | |
1087 | |
1088 ;;;###autoload | |
1089 (defun cua-mode (&optional arg) | |
1090 "Toggle CUA key-binding mode. | |
1091 When enabled, using shifted movement keys will activate the region (and | |
1092 highlight the region using `transient-mark-mode'), and typed text replaces | |
1093 the active selection. C-z, C-x, C-c, and C-v will undo, cut, copy, and | |
1094 paste (in addition to the normal emacs bindings)." | |
1095 (interactive "P") | |
1096 (setq cua-mode | |
1097 (cond | |
1098 ((null arg) (not cua-mode)) | |
1099 ((symbolp arg) t) | |
1100 (t (> (prefix-numeric-value arg) 0)))) | |
1101 | |
1102 (setq mark-even-if-inactive t) | |
1103 (setq highlight-nonselected-windows nil) | |
1104 (make-variable-buffer-local 'cua--explicit-region-start) | |
1105 (make-variable-buffer-local 'cua--status-string) | |
1106 | |
1107 (unless cua--keymaps-initalized | |
1108 (cua--init-keymaps) | |
1109 (setq cua--keymaps-initalized t)) | |
1110 | |
1111 (if cua-mode | |
1112 (progn | |
1113 (add-hook 'pre-command-hook 'cua--pre-command-handler) | |
1114 (add-hook 'post-command-hook 'cua--post-command-handler) | |
1115 (if (and cua-enable-modeline-indications (not (assoc 'cua-mode minor-mode-alist))) | |
1116 (setq minor-mode-alist (cons '(cua-mode cua--status-string) minor-mode-alist))) | |
1117 ) | |
1118 (remove-hook 'pre-command-hook 'cua--pre-command-handler) | |
1119 (remove-hook 'post-command-hook 'cua--post-command-handler)) | |
1120 (cua--fix-keymaps (not cua-mode)) | |
1121 (if (fboundp 'cua--rectangle-on-off) | |
1122 (cua--rectangle-on-off cua-mode)) | |
1123 (setq transient-mark-mode (and cua-mode | |
1124 (if cua-highlight-region-shift-only | |
1125 (not cua--explicit-region-start) | |
1126 t)))) | |
1127 | |
1128 (defun cua-debug () | |
1129 "Toggle cua debugging." | |
1130 (interactive) | |
1131 (setq cua--debug (not cua--debug))) | |
1132 | |
1133 ;;; cua-base.el ends here |