1;;; cua.el --- emulate CUA key bindings
3;; Copyright (C) 1997-2001 Free Software Foundation, Inc.
5;; Author: Kim F. Storm <storm@cua.dk>
6;; Maintainer: Kim F. Storm <storm@cua.dk>
7;; Location: http://www.cua.dk/
8;; Keywords: keyboard CUA
11;; This file is not [yet] part of GNU Emacs, but is distributed under
14;; GNU Emacs is free software; you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published by
16;; the Free Software Foundation; either version 2, or (at your option)
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs; see the file COPYING. If not, write to the
26;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
27;; Boston, MA 02111-1307, USA.
31;; This file used to be named cua-mode.el; if you or your users
32;; are using a previous release under that name, you can continue
33;; naming the file cua-mode.el; provided you also continue using
34;; (require 'cua-mode) before activation [see below].
39;; To activate CUA-mode, copy the cua.el file into a directory
40;; on the load-path, byte-compile it (using M-x byte-compile-file),
41;; and place the following lines into your .emacs:
46;; If you don't want to modify the bindings of C-z C-x C-c C-v, but still
47;; want the CUA enhanced functionality for the standard emacs bindings of
48;; undo, kill, copy, and yank, use the following lines instead:
53;; If you bind any keys to 'undo or 'advertised-undo in your .emacs file,
54;; CUA-mode should be activated *after* those bindings! Otherwise,
55;; bind the key to CUA-undo
57;; You may also use Customize to turn on CUA-mode and control its
58;; features and fine tune its behaviour. You'll find CUA-mode under
59;; the Editing Basics group.
61;; Optionally, place this line in your .emacs to turn the numeric
62;; keypad keys into numeric command prefix keys (useful with C-x, C-c
63;; and C-v too to save into and load from registers 1-9):
65;; (CUA-keypad-mode 'prefix t)
70;; This is the CUA-mode package which provides a complete emulation of
71;; the standard CUA key bindings (Motif/Windows/Mac GUI) for selecting
72;; and manipulating the region where S-<movement> is used to
73;; highlight & extend the region.
75;; This package allow the C-z, C-x, C-c, and C-v keys to be
76;; bound appropriately according to the Motif/Windows GUI, i.e.
82;; The tricky part is the handling of the C-x and C-c keys which
83;; are normally used as prefix keys for most of emacs' built-in
84;; commands. With CUA-mode they still do!!!
86;; Only when the region is currently active (and highlighted since
87;; transient-mark-mode is used), the C-x and C-c keys will work as CUA
91;; When the region is not active, C-x and C-c works as prefix keys!
93;; This probably sounds strange and difficult to get used to - but
94;; based on my own experience and the feedback from many users of
95;; CUA-mode, it actually works very well and users adapt to it
96;; instantly - or at least very quickly. So give it a try!
97;; ... and in the few cases where you make a mistake and accidentally
98;; delete the region - you just undo the mistake (with C-z).
100;; If you really need to perform a command which starts with one of
101;; the prefix keys even when the region is active, you have three options:
102;; - press the prefix key twice very quickly (within 0.2 seconds),
103;; - press the prefix key and the following key within 0.2 seconds), or
104;; - use the SHIFT key with the prefix key, i.e. C-X or C-C
106;; This behaviour is controlled via the CUA-mode-inhibit-method and
107;; CUA-mode-inhibit-delay variables.
109;; In addition to using the shifted movement keys, you can also use
110;; [C-space] to start the region and use unshifted movement keys to extend
111;; it. To cancel the region, use [C-space] or [C-g].
113;; If you want to take advantage of CUA-mode's superior rectangle
114;; support and uniform bindings, but prefer to use the standard
115;; emacs cut, copy, paste, and undo bindings, set the variable
116;; CUA-mode-emacs-bindings to t before the call to CUA-mode.
121;; With release 2 of the CUA-mode package, the CUA commands have been
122;; extended to handle both rectangles and registers in a homogeneous
123;; manner, as well as adding the concept of a "global mark" as
126;;; CUA rectangle support
128;; Emacs' normal rectangle support is based on interpreting the region
129;; between the mark and point as a "virtual rectangle", and using a
130;; completely separate set of "rectangle commands" [C-x r ...] on the
131;; region to copy, kill, fill a.s.o. the virtual rectangle.
133;; CUA-mode's superior rectangle support is based on using a true visual
134;; representation of the selected rectangle. To start a rectangle, use
135;; [S-return] and extend it using the normal movement keys (up, down,
136;; left, right, home, end, C-home, C-end). Once the rectangle has the
137;; desired size, you can cut or copy it using C-x and C-c, and you can
138;; subsequently insert it - as a rectangle - using C-v. So the only new
139;; command you need to know to work with CUA-mode rectangles is S-return!
141;; Furthermore, CUA-mode's rectangles are not limited to the actual
142;; contents of the buffer, so if the cursor is currently at the end of a
143;; short line, you can still extend the rectangle to include more columns
144;; of longer lines in the same rectangle. Sounds strange? Try it!
146;; You can enable padding for just this rectangle by pressing [M-p];
147;; this works like entering 'picture mode' where the tabs and spaces
148;; are automatically converted/inserted to make the rectangle truly
149;; rectangular. Or you can do it for all rectangles by setting the
150;; CUA-mode-auto-expand-rectangles variable to 'yes.
152;; And there's more: If you want to extend or reduce the size of the
153;; rectangle in one of the other corners of the rectangle, just use
154;; [return] to move the cursor to the "next" corner. Or you can use
155;; the [M-up], [M-down], [M-left], and [M-right] keys to move the
156;; entire rectangle overlay (but not the contents) in the given
159;; [S-return] cancels the rectangle
160;; [C-space] activate region bounded by rectangle
162;; If you type a normal (self-inserting) character when the rectangle is
163;; active, the character is inserted on the "current side" of every line
164;; of the rectangle. The "current side" is the side on which the cursor
165;; is currently located. If the rectangle is only 1 column wide,
166;; insertion will be performed to the left when the cursor is at the
167;; bottom of the rectangle. So, for example, to comment out an entire
168;; paragraph like this one, just place the cursor on the first character
169;; of the first line, and enter the following:
170;; [S-return] [down].... [;; ] [S-return]
172;; CUA-mode's rectangle support also includes all the normal rectangle
173;; functions with easy access:
175;; [M-a] aligns all words at the left edge of the rectangle
176;; [M-b] fills the rectangle with blanks (tabs and spaces)
177;; [M-c] closes the rectangle by removing all blanks at the left edge
179;; [M-f] fills the rectangle with a single character (prompt)
180;; [M-F] performs text filling on the rectangle
181;; [M-i] increases the first number found on each line of the rectangle
182;; by the amount given by the numeric prefix argument (default 1)
183;; It recognizes 0x... as hexadecimal numbers
184;; [M-k] kills the rectangle as a normal multi-line text (for paste)
185;; [M-l] downcases the rectangle
186;; [M-m] kills the rectangle as a normal multi-line text (for paste)
187;; [M-n] fills each line of the rectangle with increasing numbers using
188;; a supplied format string (prompt)
189;; [M-o] opens the rectangle by moving the highlighted text to the
190;; right of the rectangle and filling the rectangle with blanks.
191;; [M-p] toggles rectangle padding, i.e. insert tabs and spaces to
192;; make rectangles truly rectangular
193;; [M-r] replaces REGEXP (prompt) by STRING (prompt) in rectangle
194;; [M-R] reverse the lines in the rectangle
195;; [M-s] fills each line of the rectangle with the same STRING (prompt)
196;; [M-t] performs text fill of the rectangle with TEXT (prompt)
197;; [M-u] upcases the rectangle
198;; [M-|] runs shell command on rectangle
199;; [M-'] restricts rectangle to lines with CHAR (prompt) at left column
200;; [M-/] restricts rectangle to lines matching REGEXP (prompt)
201;; [C-?] Shows a brief list of the above commands.
203;; [M-C-up] and [M-C-down] scrolls the lines INSIDE the rectangle up
204;; and down; lines scrolled outside the top or bottom of the rectangle
205;; are lost, but can be recovered using [C-z].
208;;; CUA register support
210;; Emacs' standard register support is also based on a separate set of
211;; "register commands".
213;; CUA-mode's register support is activated by providing a numeric
214;; prefix argument to the C-x, C-c, and C-v commands. For example,
215;; to copy the selected region to register 2, enter [M-2 C-c].
216;; Or if you have activated the keypad prefix mode, enter [kp-2 C-c].
218;; And CUA-mode will copy and paste normal region as well as rectangles
219;; into the registers, i.e. you use exactly the same command for both.
221;; In addition, the last highlighted text that is deleted (not copied),
222;; e.g. by typing text over a highlighted region, is automatically saved
223;; in register 0, so you can insert it using [kp-0 C-v].
227;; The final feature provided by CUA-mode is the "global mark", which
228;; makes it very easy to copy bits and pieces from the same and other
229;; files into the current text. To enable and cancel the global mark,
230;; use [S-C-space]. The cursor will blink when the global mark
231;; is active. The following commands behave differently when the global
233;; <ch> All characters (including returns) you type are inserted
234;; at the global mark!
235;; [C-x] If you cut a region or rectangle, it is automatically inserted
236;; at the global mark, and the global mark is advanced.
237;; [C-c] If you copy a region or rectangle, it is immediately inserted
238;; at the global mark, and the global mark is advanced.
239;; [C-v] Copies a single character to the global mark.
240;; [C-d] Moves (i.e. deletes and inserts) a single character to the
242;; [backspace] deletes the character before the global mark, while
243;; [delete] deltes the character after the global mark.
245;; [S-C-space] Jumps to and cancels the global mark.
246;; [C-u S-C-space] Cancels the global mark (stays in current buffer).
248;;; CUA mode indications
250;; As mentioned above, the cursor will blink when the global mark is
251;; active. In addition, you can choose to let CUA-mode use different
252;; cursor colors to indicate overwrite mode and read-only buffers.
253;; For example, the following setting will use a RED cursor in normal
254;; (insertion) mode in read-write buffers, a YELLOW cursor in
255;; overwrite mode in read-write buffers, and a GREEN cursor read-only
258;; (setq CUA-mode-normal-cursor-color "red")
259;; (setq CUA-mode-overwrite-cursor-color "yellow")
260;; (setq CUA-mode-read-only-cursor-color "green")
263;;; A few more details:
265;; * When the region is highlighted, TAB and S-TAB will indent the entire
266;; region by the normal tab-width (or the given prefix argument).
268;; * C-x C-x (exchange point and mark) no longer activates the mark (i.e.
269;; highlights the region). I found that to be confusing since the
270;; sequence C-x C-x (exchange once) followed by C-x C-x (change back)
271;; would then cut the region! To activate the region in this way,
274;; * [delete] will delete (not copy) the highlighted region.
276;; * The highlighted region is automatically deleted if other text is
277;; typed or inserted. The previously highlighted text is saved in
278;; register 0 (if CUA-mode-delete-to-register-0 is non-nil).
280;; * You may choose to use M-r as a prefix for the register commands
281;; instead of C-x r by setting CUA-mode-register-commands-prefix.
282;; The original binding of M-r (move-to-window-line) is then moved
285;; * Normally, when you paste a rectangle using C-v, each line of the
286;; rectangle is inserted into the existing lines in the buffer.
287;; However, if overwrite-mode is turned on, the lines of the rectangle
288;; are inserted as a single block of lines at point.
292;; - fix loading of normal cursor color from frame parameters.
293;; - sticky region variable -> unshifted arrow keys deselects region/rectangle.
294;; - more documentation per function / variable
295;; - extended documentation via info would be fine
296;; - rectangle "box" mode
297;; - rectangle "move" mode (eg move all lines up/down)
298;; - insert/delete rectangle shall not modify tabs or eols if padding off.
300;;; Implementation details
302;; CUA-mode uses a versatile pre-command-hook and post-command-hook
303;; to avoid rebinding any of the cursor movement or scrolling keys.
305;; The interpretation of C-x and C-c as either emacs prefix keys
306;; or CUA cut/copy keys is handled via GNU emacs' key-translation-map.
310;; CUA-mode includes code and ideas from several related packages:
311;; pc-selection-mode by Michael Staats <michael@thp.Uni-Duisburg.DE>
312;; s-region by Morten Welinder <terra@diku.dk>
313;; delete-selection-mode by Matthieu Devin <devin@lucid.com>
315;; The rectangle handling and display code borrows from the standard
316;; GNU emacs rect.el package and the the rect-mark.el package by Rick
317;; Sladkey <jrs@world.std.com>.
322;;; Support functions for pre 20.1/20.4 GNU emacsen
324 (if (fboundp 'unless) nil
325 (defmacro unless (cond &rest body)
326 "(unless COND BODY...): if COND yields nil, do BODY, else return nil."
327 `(if ,cond nil ,@body))
328 (put 'unless 'lisp-indent-function 1)
329 (put 'unless 'edebug-form-spec '(&rest form)))
331 (unless (fboundp 'when)
332 (defmacro when (cond &rest body)
333 "(when COND BODY...): if COND yields non-nil, do BODY, else return nil."
334 `(if ,cond (progn ,@body)))
335 (put 'when 'lisp-indent-function 1)
336 (put 'when 'edebug-form-spec '(&rest form)))
338 (unless (fboundp 'with-current-buffer)
339 (defmacro with-current-buffer (buffer &rest body)
340 "Execute the forms in BODY with BUFFER as the current buffer."
341 `(save-excursion (set-buffer ,buffer) ,@body))))
347 (unless (fboundp 'defgroup)
348 (defmacro defgroup (&rest rest) ()))
349 (unless (fboundp 'defcustom)
350 (defmacro defcustom (sym val str &rest rest)
351 `(defvar ,sym ,val ,str)))
352 (unless (fboundp 'defface)
353 (defmacro defface (sym val str &rest rest)
354 `(defvar ,sym (make-face ',sym) ,str))))
356(unless (fboundp 'line-beginning-position)
357 (defun line-beginning-position (&optional N)
359 (beginning-of-line N)
362(unless (fboundp 'line-end-position)
363 (defun line-end-position (&optional N)
371(defgroup CUA-mode nil
372 "Emulate CUA key bindings including C-x and C-c."
374 :group 'editing-basics
377 :link '(emacs-commentary-link :tag "Commentary" "cua.el")
378 :link '(emacs-library-link :tag "Lisp File" "cua.el"))
381(defcustom CUA-mode nil
382 "Non-nil means that CUA emulation mode is enabled.
383In CUA mode, shifted movement keys highlight and extend the region.
384When a region is highlighted, the binding of the C-x and C-c keys are
385temporarily changed to work as Motif, MAC or MS-Windows cut and paste.
386Also, insertion commands first delete the region and then insert.
387This mode enables Transient Mark mode and it provides a superset of the
388PC Selection Mode and Delete Selection Modes.
390Setting this variable directly does not take effect;
391use either \\[customize] or the function `CUA-mode'."
392 :set (lambda (symbol value)
393 (CUA-mode (or value 0)))
394 :initialize 'custom-initialize-default
396 :link '(emacs-commentary-link "cua.el")
401(defcustom CUA-mode-emacs-bindings nil
402 "Non-nil means CUA functionality is enabled without binding CUA keys.
403This causes the normal bindings of kill-region, copy-region-as-kill, yank,
404and undo to behave in the CUA style, but the C-z, C-c, C-x, and
405C-v keys are not rebound.")
407(defcustom CUA-mode-remap-cx-shift-only nil
408 "*If non-nil, only remap C-c and C-x if region was marked with S-<move>.
409I.e. if the mark was set using \\[CUA-set-mark], those keys have their
410normal prefix bindings."
414(defcustom CUA-mode-highlight-shift-only nil
415 "*If non-nil, only highlight region if marked with S-<move>.
416When this is non-nil, CUA toggles `transient-mark-mode' on when the region
417is marked using shifted movement keys, and off when the mark is cleared.
418But when the mark was set using \\[CUA-set-mark], transient-mark-mode
424(defcustom CUA-mode-inhibit-method
425 (if (memq system-type '(windows-nt ms-dos)) 'shift 'twice)
426 "How to inhibit the CUA interpretation of the next prefix key.
428When the region is active, the following methods are available to
429use the normal functionality of the prefix keys:
430delay The interpretation of a prefix keys as a CUA key is delayed
431 for `CUA-mode-inhibit-delay' milliseconds after the prefix
433 If a second key is typed before the delay elapses, the prefix
434 key works as a normal prefix together with the second key.
435twice As delay, but if the second key typed is the same prefix key,
436 the first prefix key is ignored, while the second prefix key
437 will works as a normal prefix key for the following keys.
438shift The Shift key must be used together with the prefix key.
439 (Actually this method always works unless the shifted prefix
440 keys are explicitly bound to a command).
442Notice that the delay and twice options only works well on systems
443with a sit-for function supporting fractions of a second delays."
444 :type '(choice (const delay)
449(defcustom CUA-mode-inhibit-delay 250
450 "Period during which typing another key inhibits CUA prefix keys.
451Measured in milliseconds.
452Used when `CUA-mode-inhibit-method' is delay or twice."
456(defcustom CUA-mode-register-commands-prefix nil
457 "Remap register commands [C-x r ...] onto this prefix.
458E.g. to use M-r as register command prefix, use the value [?\\M-r].
459If set to nil, register commands are not remapped.
460Other C-x ? commands can be remapped using CUA-remap-ctl-x-commands"
461 :set (lambda (symbol value)
463 (CUA-remap-ctl-x-commands "r" value)))
467(defcustom CUA-mode-keep-region-after-copy nil
468 "If non-nil, don't deselect the region after copying."
472(defcustom CUA-mode-auto-expand-rectangles nil
473 "If non-nil, rectangles are padded with spaces to make straight edges.
474This implies modifying buffer contents by expanding tabs and inserting spaces.
475Consequently, this is inhibited in read-only buffers.
476Can be toggled by [M-p] while the rectangle is active,"
480(defcustom CUA-mode-global-mark-visible t
481 "If non-nil, always keep global mark visible in other window."
485(defcustom CUA-mode-feature-global-mark t
486 "If non-nil, target for kill and copy region is global mark when active.
487When nil, or global mark is not active, target is kill-ring."
491(defcustom CUA-mode-feature-registers t
492 "If non-nil, target for kill and copy region is a register if prefix arg.
493When nil, or no prefix arg, target is kill-ring (or global mark)."
497(defcustom CUA-mode-delete-to-register-0 t
498 "*If non-nil, save last deleted region or rectangle to register 0."
502(defcustom CUA-mode-auto-help t
503 "*If non-nil, automatically show help for region, rectangle and global mark."
507(defcustom CUA-mode-use-modeline nil
508 "*If non-nil, use minor-mode hook to show status in mode line."
512(defcustom CUA-mode-use-hyper-key nil
513 "*If non-nil, bind rectangle commands to H-? instead of M-?.
514If set to 'also, toggle region command is also on S-return.
515Must be set prior to enabling CUA-mode."
516 :type '(choice (const nil)
521(defcustom CUA-debug nil
522 "*Enable CUA mode debugging."
526(defface CUA-rectangle-face 'nil
527 "*Font used by CUA for highlighting the rectangle."
530(defface CUA-rectangle-noselect-face 'nil
531 "*Font used by CUA for highlighting the non-selected rectangle lines."
534(defface CUA-global-mark-face '((((class color))
535 (:foreground "black")
536 (:background "yellow"))
538 "*Font used by CUA for highlighting the global mark."
541(defcustom CUA-mode-use-cursor-colors t
542 "*If non-nil, use different cursor colors for indications."
546(defcustom CUA-mode-normal-cursor-color nil
547 "Normal (non-overwrite) cursor color.
548Also used to indicate that rectangle padding is not in effect.
549Automatically loaded from frame parameters, if nil."
550 :initialize (lambda (symbol value)
551 (set symbol (or value
552 (and (boundp 'initial-cursor-color) initial-cursor-color)
553 (and (boundp 'initial-frame-alist)
554 (assoc 'cursor-color initial-frame-alist)
555 (cdr (assoc 'cursor-color initial-frame-alist)))
556 (and (boundp 'default-frame-alist)
557 (assoc 'cursor-color default-frame-alist)
558 (cdr (assoc 'cursor-color default-frame-alist)))
559 (frame-parameter nil 'cursor-color))))
563(defcustom CUA-mode-read-only-cursor-color "darkgreen"
564 "*Cursor color used in read-only buffers, if non-nil."
568(defcustom CUA-mode-overwrite-cursor-color "yellow"
569 "*Cursor color used when overwrite mode is set, if non-nil.
570Also used to indicate that rectangle padding is in effect."
574(defcustom CUA-mode-global-mark-cursor-color "cyan"
575 "*Indication for active global mark.
576Will change cursor color to specified color if string."
580(defcustom CUA-mode-global-mark-cursor-blink t
581 "*If non-nil, use blinking cursor as indication for active global mark."
587;; Basic configuration options
589(defvar CUA-prefix-key-mappings
594 "List of prefix keys which are remapped via key-translation-map.
595Each element in the list is a cons of the prefix key and the
596key it is translated into if the region is active.")
598(defvar CUA-ctl-x-8-prefix-key nil
599 "*Key which CUA uses in key-translation-map instead of C-x 8 prefix.
600Must be set to a single character. If no set, the first unused key
601among the following list is chosen automatically:
602H-8 (hyper 8), s-8 (super 8), C-H-8, C-H-s-8")
606(defvar CUA-explicit-region-start nil
607 "Current region was started using set-mark-command.")
609(defvar CUA-last-action nil
610 "Action taken by last command.")
612(defvar CUA-cur-register nil
613 "Current register selected by prefix arg.")
615(defvar CUA-mode-status nil
616 "Modeline status indication.")
618(defvar CUA-orig-command nil
619 "The original command before remapping.")
623(defun CUA-register ()
624 (and (not CUA-cur-register)
625 CUA-mode-feature-registers
626 (integerp current-prefix-arg)
627 (>= current-prefix-arg 0) (< current-prefix-arg 10)
628 (setq CUA-cur-register (+ current-prefix-arg ?0)
629 current-prefix-arg nil
630 overriding-terminal-local-map nil))
637(defvar CUA-rectangle nil
638 "If non-nil, restrict current region to this rectangle.
639Value is a vector [top bot left right corner ins pad select].
640CORNER specifies currently active corner 0=t/l 1=t/r 2=b/l 3=b/r.
641INS specifies whether to insert on left(nil) or right(t) side.
642If PAD is non-nil, tabs are converted to spaces when necessary.
643If SELECT is a regexp, only lines starting with that regexp are affected.")
645(defvar CUA-last-rectangle nil
646 "Most recent rectangle geometry.
647Note: car is buffer.")
649;; rectangle restored by undo
650(defvar CUA-next-rectangle nil)
652;; buffer + point prior to current command when rectangle is active
653;; checked in post-command hook to see if point was moved
654(defvar CUA-start-point nil)
656(defvar CUA-rect-last-killed nil
657 "Last rectangle copied/killed; nil if last kill was not a rectangle.")
659(defvar CUA-rect-overlays nil
660 "List of overlays used to display current rectangle.")
662(defun CUA-rect-top (&optional val)
663 "Top of CUA rectangle (buffer position on first line)."
665 (aref CUA-rectangle 0)
666 (setq val (line-beginning-position))
667 (if (<= val (aref CUA-rectangle 1))
668 (aset CUA-rectangle 0 val)
669 (aset CUA-rectangle 1 val)
670 (CUA-rect-corner 2))))
672(defun CUA-rect-bot (&optional val)
673 "Bot of CUA rectangle (buffer position on last line)."
675 (aref CUA-rectangle 1)
676 (setq val (line-end-position))
677 (if (>= val (aref CUA-rectangle 0))
678 (aset CUA-rectangle 1 val)
679 (aset CUA-rectangle 0 val)
680 (CUA-rect-corner 2))))
682(defun CUA-rect-left (&optional val)
683 "Left column of CUA rectangle."
685 (if (<= val (aref CUA-rectangle 3))
686 (aset CUA-rectangle 2 val)
687 (aset CUA-rectangle 3 val)
688 (CUA-rect-corner (if (CUA-rect-right-side) -1 1)))
689 (aref CUA-rectangle 2)))
691(defun CUA-rect-right (&optional val)
692 "Right column of CUA rectangle."
694 (if (>= val (aref CUA-rectangle 2))
695 (aset CUA-rectangle 3 val)
696 (aset CUA-rectangle 2 val)
697 (CUA-rect-corner (if (CUA-rect-right-side) -1 1)))
698 (aref CUA-rectangle 3)))
700(defun CUA-rect-corner (&optional advance)
701 "Currently active corner of rectangle."
702 (let ((c (aref CUA-rectangle 4)))
703 (if (not (integerp advance))
705 (aset CUA-rectangle 4
707 (- 3 c) ; opposite corner
708 (mod (+ c 4 advance) 4)))
709 (aset CUA-rectangle 5 0))))
711(defun CUA-rect-right-side (&optional topbot)
712 ;; t if point is on right side of rectangle.
713 (if (and topbot (= (CUA-rect-left) (CUA-rect-right)))
714 (< (CUA-rect-corner) 2)
715 (= (mod (CUA-rect-corner) 2) 1)))
717(defun CUA-rect-column ()
718 (if (CUA-rect-right-side)
722(defun CUA-rect-insert-col (&optional col)
723 "Currently active corner of rectangle."
725 (aset CUA-rectangle 5 col)
726 (if (CUA-rect-right-side t)
727 (if (= (aref CUA-rectangle 5) 0)
728 (1+ (CUA-rect-right))
729 (aref CUA-rectangle 5))
732(defun CUA-rect-padding (&optional set val)
734 (aset CUA-rectangle 6 val))
735 (and (not buffer-read-only)
736 (aref CUA-rectangle 6)))
738(defun CUA-rect-restriction (&optional val bounded negated)
740 (aset CUA-rectangle 7
743 (list val bounded negated)))
744 (aref CUA-rectangle 7)))
746(defun CUA-rect-assert ()
747 (message "%S (%d)" CUA-rectangle (point))
748 (if (< (CUA-rect-right) (CUA-rect-left))
749 (message "rectangle right < left"))
750 (if (< (CUA-rect-bot) (CUA-rect-top))
751 (message "rectangle bot < top")))
753(defun CUA-rect-get-corners (&optional pad)
754 ;; Calculate the rectangular region represented by point and mark,
755 ;; putting start in the upper left corner and end in the
756 ;; bottom right corner.
757 (let ((top (point)) (bot (mark)) r l corner)
760 (setq l (current-column))
762 (setq r (current-column))
764 (setq corner (if (<= l r) 0 1))
765 (setq top (prog1 bot (setq bot top)))
766 (setq corner (if (<= l r) 2 3)))
770 (setq l (prog1 r (setq r l)))
772 (move-to-column l pad)
775 (move-to-column r pad)
777 (vector top bot l r corner 0 pad nil)))
779(defun CUA-rect-set-corners ()
780 ;; Set mark and point in opposite corners of current rectangle.
781 (let (pp pc mp mc (c (CUA-rect-corner)))
783 ((= c 0) ; top/left -> bot/right
784 (setq pp (CUA-rect-top) pc (CUA-rect-left)
785 mp (CUA-rect-bot) mc (CUA-rect-right)))
786 ((= c 1) ; top/right -> bot/left
787 (setq pp (CUA-rect-top) pc (CUA-rect-right)
788 mp (CUA-rect-bot) mc (CUA-rect-left)))
789 ((= c 2) ; bot/left -> top/right
790 (setq pp (CUA-rect-bot) pc (CUA-rect-left)
791 mp (CUA-rect-top) mc (CUA-rect-right)))
792 ((= c 3) ; bot/right -> top/left
793 (setq pp (CUA-rect-bot) pc (CUA-rect-right)
794 mp (CUA-rect-top) mc (CUA-rect-left))))
796 (move-to-column mc (CUA-rect-padding))
799 (move-to-column pc (CUA-rect-padding))))
801(defun CUA-forward-line (n pad)
802 (if (or (not pad) (< n 0))
803 (= (forward-line n) 0)
807(defun CUA-rect-resize (command)
808 ;; Adjust rectangle size based on movement command
809 (let ((cmd (or (get command 'CUA-rect) command))
810 (pad (CUA-rect-padding))
813 ((eq cmd 'forward-char)
815 ((and (CUA-rect-right-side) (or pad (eolp)))
816 (CUA-rect-right (1+ (CUA-rect-right)))
817 (move-to-column (CUA-rect-right) pad))
818 ((CUA-rect-right-side)
820 (CUA-rect-right (current-column)))
822 (CUA-rect-left (1+ (CUA-rect-left)))
823 (move-to-column (CUA-rect-right) pad))
826 (CUA-rect-left (current-column)))))
827 ((eq cmd 'backward-char)
829 ((= (CUA-rect-right) 0)
831 ((and (not (CUA-rect-right-side)) (= (CUA-rect-left) 0))
833 ((and (CUA-rect-right-side) (or pad (eolp) (bolp)))
834 (CUA-rect-right (1- (CUA-rect-right)))
835 (move-to-column (CUA-rect-right) pad))
836 ((CUA-rect-right-side)
838 (CUA-rect-right (current-column)))
839 ((or pad (eolp) (bolp))
840 (CUA-rect-left (1- (CUA-rect-left)))
841 (move-to-column (CUA-rect-right) pad))
844 (CUA-rect-left (current-column)))))
847 ((>= (CUA-rect-corner) 2)
848 (goto-char (CUA-rect-bot))
849 (when (CUA-forward-line 1 pad)
850 (move-to-column (CUA-rect-column) pad)
853 (goto-char (CUA-rect-top))
854 (when (CUA-forward-line 1 pad)
855 (move-to-column (CUA-rect-column) pad)
857 ((eq cmd 'previous-line)
859 ((>= (CUA-rect-corner) 2)
860 (goto-char (CUA-rect-bot))
861 (when (CUA-forward-line -1 pad)
862 (move-to-column (CUA-rect-column) pad)
865 (goto-char (CUA-rect-top))
866 (when (CUA-forward-line -1 pad)
867 (move-to-column (CUA-rect-column) pad)
869 ((memq cmd '(end-of-line end-of-line-or-backward-char))
873 (if (> (current-column) (CUA-rect-right))
874 (CUA-rect-right (current-column)))
875 (if (not (CUA-rect-right-side))
876 (CUA-rect-corner 1)))))
877 ((memq cmd '(beginning-of-line beginning-of-line-or-indent))
881 (CUA-rect-left (current-column))
882 (if (CUA-rect-right-side)
883 (CUA-rect-corner -1)))))
884 ((eq cmd 'end-of-buffer)
885 (goto-char (point-max))
886 (move-to-column (CUA-rect-column) pad)
888 ((eq cmd 'beginning-of-buffer)
889 (goto-char (point-min))
890 (move-to-column (CUA-rect-column) pad)
892 ((memq cmd '(scroll-down scroll-up))
894 (move-to-column (CUA-rect-column) pad)
895 (if (>= (CUA-rect-corner) 2)
901 (CUA-pad-rectangle pad)
902 (CUA-rect-insert-col 0)
903 (CUA-rect-set-corners)
907(defun CUA-rect-move (dir)
908 (let ((pad (CUA-rect-padding))
913 (r (CUA-rect-right)))
917 (when (CUA-forward-line -1 pad)
924 (when (CUA-forward-line 1 pad)
927 (CUA-forward-line 1 pad)
931 (CUA-rect-left (1- l))
932 (CUA-rect-right (1- r))))
934 (CUA-rect-right (1+ r))
935 (CUA-rect-left (1+ l)))
940 (CUA-rect-set-corners)
941 (CUA-keep-active t))))
943(defun CUA-rect-operation (cmd visible undo pad &optional fct post-fct)
944 ;; Call FCT for each line of region with 4 parameters:
945 ;; Region start, end, left-col, right-col
946 ;; Point is at start when FCT is called
947 ;; Rectangle is padded if PAD = t or numeric and (CUA-rect-padding)
948 ;; Mark is kept if keep == t and cleared if keep numeric
949 (let* ((start (CUA-rect-top))
952 (r (1+ (CUA-rect-right)))
954 (tabpad (and (integerp pad) (= pad 2)))
955 (sel (CUA-rect-restriction))
956 (keep-clear (and cmd (get cmd 'CUA-rect))))
958 (CUA-rect-undo-boundary))
960 (setq pad (CUA-rect-padding)))
964 (when (> (CUA-rect-corner) 1)
966 (and (bolp) (not (eolp)) (not (eobp))
967 (setq end (1+ end))))
969 (setq start (max (window-start) start))
970 (setq end (min (window-end) end)))
972 (setq end (line-end-position))
974 (setq start (line-beginning-position))
975 (narrow-to-region start end)
976 (goto-char (point-min))
977 (while (< (point) (point-max))
978 (move-to-column r pad)
979 (and (not pad) (not visible) (> (current-column) r)
981 (if (and tabpad (not pad) (looking-at "\t"))
983 (set-marker m (point))
984 (move-to-column l pad)
986 (let ((v t) (p (point)))
989 (setq v (looking-at (car sel)))
990 (setq v (re-search-forward (car sel) m t))
992 (if (car (cdr (cdr sel)))
995 (funcall fct p m l r v)
997 (funcall fct p m l r)))))
1003 (funcall post-fct l r))))
1005 ((eq keep-clear 'keep)
1006 (CUA-keep-active t))
1007 ((eq keep-clear 'clear)
1008 (CUA-keep-active nil))
1009 ((eq keep-clear 'corners)
1010 (CUA-rect-set-corners)
1011 (CUA-keep-active t)))))
1013(put 'CUA-rect-operation 'lisp-indent-function 4)
1015(defun CUA-pad-rectangle (&optional pad)
1016 (if (or pad (CUA-rect-padding))
1017 (CUA-rect-operation nil nil t t)))
1019(defun CUA-delete-rectangle ()
1020 (CUA-rect-operation nil nil t 2
1022 (delete-region s (if (> e s) e (1+ e))))))
1024(defun CUA-extract-rectangle ()
1026 (CUA-rect-operation nil nil nil 1
1028 (setq rect (cons (buffer-substring-no-properties s e) rect))))
1031(defun CUA-insert-rectangle (rect &optional below)
1032 ;; Insert rectangle as insert-rectangle, but don't set mark and exit with
1033 ;; point at either next to top right or below bottom left corner
1034 ;; Notice: In overwrite mode, the rectangle is inserted as separate text lines.
1035 (if (and below (eq below 'auto))
1036 (setq below (and (bolp)
1037 (or (eolp) (eobp) (= (1+ (point)) (point-max))))))
1039 (insertcolumn (current-column))
1042 (while (or lines below)
1047 (or (bolp) (insert ?\n))
1048 (move-to-column insertcolumn t)))
1051 (insert (car lines))
1052 (setq lines (cdr lines))
1053 (and first (not below)
1056 (and p (not overwrite-mode)
1059(defun CUA-rect-copy-as-kill (&optional ring)
1061 (set-register (CUA-register) (CUA-extract-rectangle))
1062 (setq killed-rectangle (CUA-extract-rectangle))
1063 (setq CUA-rect-last-killed (cons (and kill-ring (car kill-ring)) killed-rectangle))
1065 (kill-new (mapconcat
1066 (function (lambda (row) (concat row "\n")))
1067 killed-rectangle "")))))
1069(defun CUA-rect-activate (&optional force)
1070 ;; Turn on rectangular marking mode by disabling transient mark mode
1071 ;; and manually handling highlighting from a post command hook.
1072 ;; Be careful if we are already marking a rectangle.
1074 (if (and CUA-last-rectangle
1075 (eq (car CUA-last-rectangle) (current-buffer))
1076 (eq (car (cdr CUA-last-rectangle)) (point)))
1077 (cdr (cdr CUA-last-rectangle))
1078 (CUA-rect-get-corners
1079 (and (not buffer-read-only)
1080 (or CUA-mode-auto-expand-rectangles
1082 (eq major-mode 'picture-mode)))))
1083 CUA-mode-status (if (CUA-rect-padding) " Pad" "")
1084 CUA-last-rectangle nil))
1086(defvar CUA-save-point nil)
1088(defun CUA-rect-deactivate ()
1089 ;; This is used to clean up after `CUA-rect-activate'.
1090 (mapcar (function delete-overlay) CUA-rect-overlays)
1091 (setq CUA-last-rectangle (cons (current-buffer) (cons CUA-save-point CUA-rectangle))
1093 CUA-rect-overlays nil
1094 CUA-mode-status nil))
1096(defun CUA-rect-highlight ()
1097 ;; This function is used to highlight the rectangular region.
1098 ;; We do this by putting an overlay on each line within the rectangle.
1099 ;; Each overlay extends across all the columns of the rectangle.
1100 ;; We try to reuse overlays where possible because this is more efficient
1101 ;; and results in less flicker.
1102 ;; If CUA-rect-padding is nil and the buffer contains tabs or short lines,
1103 ;; the higlighted region may not be perfectly rectangular.
1104 (let ((deactivate-mark deactivate-mark)
1105 (old CUA-rect-overlays)
1107 (left (CUA-rect-left))
1108 (right (1+ (CUA-rect-right))))
1109 (when (/= left right)
1110 (sit-for 0) ; make window top/bottom reliable
1111 (CUA-rect-operation nil t nil nil
1112 '(lambda (s e l r v)
1113 (let ((rface (if v 'CUA-rectangle-face 'CUA-rectangle-noselect-face))
1115 ;; Trim old leading overlays.
1117 (setq overlay (car old))
1118 (< (overlay-start overlay) s)
1119 (/= (overlay-end overlay) e))
1120 (delete-overlay overlay)
1121 (setq old (cdr old)))
1122 ;; Reuse an overlay if possible, otherwise create one.
1124 (setq overlay (car old))
1125 (or (= (overlay-start overlay) s)
1126 (= (overlay-end overlay) e)))
1128 (move-overlay overlay s e)
1129 (setq old (cdr old)))
1130 (setq overlay (make-overlay s e)))
1131 (overlay-put overlay 'face rface)
1132 (setq new (cons overlay new))))))
1133 ;; Trim old trailing overlays.
1134 (mapcar (function delete-overlay) old)
1135 (setq CUA-rect-overlays (nreverse new))))
1137(defun CUA-rect-indent-rectangle (&optional ch)
1138 "Indent current rectangle."
1139 (let ((col (CUA-rect-insert-col))
1140 (pad (CUA-rect-padding))
1142 (CUA-rect-operation 'CUA-rect-indent-rectangle nil t pad
1144 (move-to-column col pad)
1146 (< (current-column) col))
1147 (move-to-column col t))
1151 (if (CUA-rect-right-side t)
1152 (CUA-rect-insert-col (current-column))
1153 (setq indent (- (current-column) l))))
1155 (when (and indent (> indent 0))
1156 (aset CUA-rectangle 2 (+ l indent))
1157 (aset CUA-rectangle 3 (+ r indent -1)))))))
1158(put 'CUA-rect-indent-rectangle 'CUA-rect 'corners)
1164(defun CUA-exchange-point-and-mark (arg)
1165 "Exchanges point and mark, but don't activate the mark.
1166Activates the mark if a prefix argument is given."
1169 (setq mark-active t)
1171 (exchange-point-and-mark)
1173 (CUA-rect-corner 0)))))
1177(defvar CUA-global-mark nil
1178 "Global mark position marker.")
1180(defvar CUA-global-mark-overlay nil
1181 "Overlay for global mark position.")
1183(defun CUA-global-mark-active ()
1184 (and (markerp CUA-global-mark) (marker-buffer CUA-global-mark)))
1186(defun CUA-global-mark-deactivate (&optional msg)
1187 (when CUA-global-mark-overlay
1188 (delete-overlay CUA-global-mark-overlay)
1189 (setq CUA-global-mark-overlay nil))
1190 (if (markerp CUA-global-mark)
1191 (move-marker CUA-global-mark nil))
1193 (message "Global Mark Cleared")))
1195(defun CUA-global-mark-activate (&optional msg)
1196 (if (not (markerp CUA-global-mark))
1197 (setq CUA-global-mark (make-marker)))
1201 (move-marker CUA-global-mark (point))
1202 (if (overlayp CUA-global-mark-overlay)
1203 (move-overlay CUA-global-mark-overlay (point) (1+ (point)))
1204 (setq CUA-global-mark-overlay
1205 (make-overlay (point) (1+ (point))))
1206 (overlay-put CUA-global-mark-overlay 'face 'CUA-global-mark-face))
1208 (message "Global Mark Set")))
1210(defun CUA-cmd-toggle-global-mark (stay)
1211 "Set or cancel the global marker.
1212When the global marker is set, CUA cut and copy commands will automatically
1213insert the deleted or copied text before the global marker, even when the
1214global marker is in another buffer.
1215If the global marker isn't set, set the global marker at point in the current
1216buffer. Otherwise jump to the global marker position and cancel it.
1217With prefix argument, don't jump to global mark when cancelling it."
1219 (if (not (CUA-global-mark-active))
1220 (if (not buffer-read-only)
1221 (CUA-global-mark-activate t)
1223 (message "Cannot set global mark in read-only buffer."))
1225 (pop-to-buffer (marker-buffer CUA-global-mark))
1226 (goto-char CUA-global-mark))
1227 (CUA-global-mark-deactivate t)))
1229(defun CUA-global-mark-insert (str &optional msg)
1230 ;; Insert string at global marker and move marker
1232 (set-buffer (marker-buffer CUA-global-mark))
1233 (goto-char (marker-position CUA-global-mark))
1235 (CUA-global-mark-activate))
1237 (message "%s %d to global mark in %s:%d" msg
1239 (buffer-name (marker-buffer CUA-global-mark))
1240 (marker-position CUA-global-mark))))
1242(defun CUA-global-mark-delete-char (arg &optional msg)
1243 ;; Delete chars at global marker
1245 (set-buffer (marker-buffer CUA-global-mark))
1246 (goto-char (marker-position CUA-global-mark))
1249 (message "%s %d chars at global mark in %s:%d" msg arg
1250 (buffer-name (marker-buffer CUA-global-mark))
1251 (marker-position CUA-global-mark))))
1253(defun CUA-global-mark-copy-region (start end)
1254 "Copy region to global mark buffer/position."
1256 (if (CUA-global-mark-active)
1257 (let ((src-buf (current-buffer)))
1259 (if (equal (marker-buffer CUA-global-mark) src-buf)
1260 (let ((text (buffer-substring-no-properties start end)))
1261 (goto-char (marker-position CUA-global-mark))
1263 (set-buffer (marker-buffer CUA-global-mark))
1264 (goto-char (marker-position CUA-global-mark))
1265 (insert-buffer-substring src-buf start end))
1266 (CUA-global-mark-activate)
1267 (message "Copied %d to global mark in %s:%d"
1269 (buffer-name (marker-buffer CUA-global-mark))
1270 (marker-position CUA-global-mark))))
1271 (CUA-global-mark-deactivate)
1272 (message "No Global Mark")))
1274(defun CUA-global-mark-move-region (start end)
1275 "Move region to global buffer/position."
1277 (if (CUA-global-mark-active)
1278 (let ((src-buf (current-buffer)))
1280 (if (equal (marker-buffer CUA-global-mark) src-buf)
1281 (if (and (< start (marker-position CUA-global-mark))
1282 (< (marker-position CUA-global-mark) end))
1283 (message "Can't move region into itself.")
1284 (let ((text (buffer-substring-no-properties start end))
1285 (p1 (copy-marker start))
1286 (p2 (copy-marker end)))
1287 (goto-char (marker-position CUA-global-mark))
1289 (CUA-global-mark-activate)
1290 (delete-region (marker-position p1) (marker-position p2))
1291 (move-marker p1 nil)
1292 (move-marker p2 nil)))
1293 (set-buffer (marker-buffer CUA-global-mark))
1294 (goto-char (marker-position CUA-global-mark))
1295 (insert-buffer-substring src-buf start end)
1296 (message "Moved %d to global mark in %s:%d"
1298 (buffer-name (marker-buffer CUA-global-mark))
1299 (marker-position CUA-global-mark))
1300 (CUA-global-mark-activate)
1301 (set-buffer src-buf)
1302 (delete-region start end))))
1303 (CUA-global-mark-deactivate)
1304 (message "No Global Mark")))
1306(defvar CUA-global-mark-do-rect-as-text nil)
1308(defun CUA-global-mark-copy-rect ()
1309 "Copy rectangle to global mark buffer/position."
1310 (if (CUA-global-mark-active)
1311 (let ((src-buf (current-buffer))
1312 (text (CUA-extract-rectangle)))
1314 (set-buffer (marker-buffer CUA-global-mark))
1315 (goto-char (marker-position CUA-global-mark))
1316 (if CUA-global-mark-do-rect-as-text
1319 (if (setq text (cdr text))
1321 (CUA-insert-rectangle text 'auto))
1322 (CUA-global-mark-activate)
1323 (message "Copied rectangle to global mark in %s:%d"
1324 (buffer-name (marker-buffer CUA-global-mark))
1325 (marker-position CUA-global-mark))))
1326 (CUA-global-mark-deactivate)
1327 (message "No Global Mark")))
1329(defun CUA-global-mark-move-rect ()
1330 "Move rectangle to global buffer/position."
1331 (if (CUA-global-mark-active)
1332 (let ((src-buf (current-buffer)))
1334 (if (equal (marker-buffer CUA-global-mark) src-buf)
1335 (let ((olist (overlays-at (marker-position CUA-global-mark)))
1338 (if (eq (overlay-get (car olist) 'face) 'CUA-rectangle-face)
1339 (setq in-rect t olist nil)
1340 (setq olist (cdr olist))))
1342 (message "Can't move rectangle into itself.")
1343 (let ((text (CUA-extract-rectangle)))
1344 (CUA-delete-rectangle)
1345 (goto-char (marker-position CUA-global-mark))
1346 (if CUA-global-mark-do-rect-as-text
1349 (if (setq text (cdr text))
1351 (CUA-insert-rectangle text 'auto))
1352 (CUA-global-mark-activate))))
1353 (let ((text (CUA-extract-rectangle)))
1354 (CUA-delete-rectangle)
1355 (set-buffer (marker-buffer CUA-global-mark))
1356 (goto-char (marker-position CUA-global-mark))
1357 (CUA-insert-rectangle text 'auto))
1358 (message "Moved rectangle to global mark in %s:%d"
1359 (buffer-name (marker-buffer CUA-global-mark))
1360 (marker-position CUA-global-mark))
1361 (CUA-global-mark-activate))))
1362 (CUA-global-mark-deactivate)
1363 (message "No Global Mark")))
1365;;; Enhanced undo - restore rectangle selections
1367(defvar CUA-undo-list nil
1368 "Per-buffer CUA mode undo list.")
1370(defvar CUA-undo-max 64
1371 "*Max no of undoable CUA rectangle changes (including undo).")
1373(defun CUA-rect-undo-boundary ()
1374 (when (listp buffer-undo-list)
1375 (if (> (length CUA-undo-list) CUA-undo-max)
1376 (setcdr (nthcdr (1- CUA-undo-max) CUA-undo-list) nil))
1379 (cons (cons (cdr buffer-undo-list) (copy-sequence CUA-rectangle)) CUA-undo-list))))
1381(defun CUA-undo (&optional arg)
1382 "Undo some previous changes.
1383Knows about CUA rectangle highlighting in addition to standard undo."
1386 (CUA-rect-undo-boundary))
1388 (let ((l CUA-undo-list))
1390 (if (eq (car (car l)) pending-undo-list)
1391 (setq CUA-next-rectangle
1392 (and (vectorp (cdr (car l))) (cdr (car l)))
1395 (setq CUA-start-point nil))
1397(defvar CUA-tidy-undo-counter 0
1398 "Number of times `CUA-tidy-undo-lists' have run successfully.")
1400(defun CUA-tidy-undo-lists (&optional clean)
1401 (let ((buffers (buffer-list)) (cnt CUA-tidy-undo-counter))
1402 (while (and buffers (or clean (not (input-pending-p))))
1403 (with-current-buffer (car buffers)
1404 (when (local-variable-p 'CUA-undo-list)
1405 (if (or clean (null CUA-undo-list) (eq buffer-undo-list t))
1407 (kill-local-variable 'CUA-undo-list)
1408 (setq CUA-tidy-undo-counter (1+ CUA-tidy-undo-counter)))
1409 (let* ((bul buffer-undo-list)
1410 (cul (cons nil CUA-undo-list))
1411 (cc (car (car (cdr cul)))))
1413 (if (setq bul (memq cc bul))
1415 cc (and (cdr cul) (car (car (cdr cul)))))))
1418 (setq cc (length (cdr cul))))
1419 (if (eq (cdr cul) CUA-undo-list)
1420 (setq CUA-undo-list nil)
1422 (setq CUA-tidy-undo-counter (1+ CUA-tidy-undo-counter))
1424 (message "Clean undo list in %s (%d)"
1425 (buffer-name) cc)))))))
1426 (setq buffers (cdr buffers)))
1427 (/= cnt CUA-tidy-undo-counter)))
1431(defun CUA-indent-active-region (start end backw)
1432 (message "Indenting...")
1433 (let (amount (arg current-prefix-arg))
1436 (setq start (line-beginning-position)))
1437 (if (equal arg '(4))
1438 (indent-region start end nil)
1439 (setq amount (if arg (prefix-numeric-value arg) tab-width))
1440 (indent-rigidly start end (if backw (- amount) amount)))))
1442(defun CUA-set-mark (&optional jump)
1443 "Set mark at where point is, clear mark, or jump to mark.
1444With no prefix argument, set mark, push old mark position on local mark
1445ring, and push mark on global mark ring, or if mark is already set, clear mark.
1446With argument, jump to mark, and pop a new position for mark off the ring."
1450 (set-mark-command t))
1452 (setq mark-active nil
1453 CUA-explicit-region-start nil)
1454 (message "Mark Cleared"))
1456 (set-mark-command nil)
1457 (setq CUA-explicit-region-start t)
1458 (if CUA-mode-auto-help
1459 (CUA-help-for-region t)))))
1461(defun CUA-keep-active (keep)
1464 deactivate-mark nil)
1465 (setq mark-active nil
1466 CUA-explicit-region-start nil)
1467 (run-hooks 'deactivate-mark-hook)))
1470;; region functions / actions
1473(defun CUA-cmd-copy-region ()
1475 (setq CUA-rect-last-killed nil)
1476 (let ((start (mark)) (end (point)))
1478 (setq start (prog1 end (setq end start))))
1480 (copy-to-register (CUA-register) start end nil)
1481 (copy-region-as-kill start end))
1482 (CUA-keep-active CUA-mode-keep-region-after-copy)))
1484(defun CUA-cmd-cut-region ()
1486 (setq CUA-rect-last-killed nil)
1487 (if buffer-read-only
1488 (CUA-cmd-copy-region)
1489 (let ((start (mark)) (end (point)))
1491 (setq start (prog1 end (setq end start))))
1493 (copy-to-register (CUA-register) start end t)
1494 (kill-region start end)))
1495 (CUA-keep-active nil)))
1497(defun CUA-cmd-delete-region ()
1499 (let ((start (mark)) (end (point)))
1501 (setq start (prog1 end (setq end start))))
1502 (if CUA-mode-delete-to-register-0
1503 (copy-to-register ?0 start end nil))
1504 (delete-region start end)
1505 (CUA-keep-active nil)))
1507(defun CUA-cmd-indent-region-left ()
1509 (let ((start (mark)) (end (point)))
1511 (setq start (prog1 end (setq end start))))
1512 (CUA-indent-active-region start end nil)
1513 (CUA-keep-active t)))
1515(defun CUA-cmd-indent-region-right ()
1517 (let ((start (mark)) (end (point)))
1519 (setq start (prog1 end (setq end start))))
1520 (CUA-indent-active-region start end t)
1521 (CUA-keep-active t)))
1524;; rectangle functions / actions
1527(defun CUA-cmd-begin-rectangle (&optional reopen)
1528 "Set mark and start in CUA rectangle mode.
1529With prefix argument, activate previous rectangle if possible."
1531 (when (not CUA-rectangle)
1534 (eq (car CUA-last-rectangle) (current-buffer)))
1535 (goto-char (car (cdr CUA-last-rectangle)))
1536 (if (not mark-active)
1537 (set-mark-command nil)))
1539 (CUA-rect-set-corners)
1541 CUA-explicit-region-start t)
1542 (if CUA-mode-auto-help
1543 (CUA-help-for-rectangle t))))
1545(defun CUA-cmd-end-rectangle ()
1546 "Cancel current rectangle."
1549 (setq mark-active nil
1550 CUA-explicit-region-start nil)
1551 (CUA-rect-deactivate)))
1553(defun CUA-cmd-restrict-regexp-rectangle (arg)
1554 "Restrict rectangle to lines (not) matching REGEXP.
1555With prefix argument, the toggle restriction."
1557 (CUA-absorb-prefix-arg)
1558 (let ((r (CUA-rect-restriction)) regexp)
1559 (if (and r (null (car (cdr r))))
1561 (CUA-rect-restriction (car r) nil (not (car (cdr (cdr r)))))
1562 (CUA-rect-restriction "" nil nil))
1563 (CUA-rect-restriction
1564 (read-from-minibuffer "Restrict rectangle (regexp): "
1565 nil nil nil nil) nil arg))))
1567(defun CUA-cmd-restrict-prefix-rectangle (arg)
1568 "Restrict rectangle to lines (not) starting with CHAR.
1569With prefix argument, the toggle restriction."
1571 (CUA-absorb-prefix-arg)
1572 (let ((r (CUA-rect-restriction)) regexp)
1573 (if (and r (car (cdr r)))
1575 (CUA-rect-restriction (car r) t (not (car (cdr (cdr r)))))
1576 (CUA-rect-restriction "" nil nil))
1577 (CUA-rect-restriction
1579 (read-char "Restrictive rectangle (char): ")) t arg))))
1581(defun CUA-cmd-move-rectangle-up ()
1583 (CUA-rect-move 'up))
1585(defun CUA-cmd-move-rectangle-down ()
1587 (CUA-rect-move 'down))
1589(defun CUA-cmd-move-rectangle-left ()
1591 (CUA-rect-move 'left))
1593(defun CUA-cmd-move-rectangle-right ()
1595 (CUA-rect-move 'right))
1597(defun CUA-cmd-copy-rectangle ()
1599 (CUA-rect-copy-as-kill)
1600 (CUA-keep-active CUA-mode-keep-region-after-copy))
1602(defun CUA-cmd-cut-rectangle ()
1604 (if buffer-read-only
1605 (CUA-cmd-copy-rectangle)
1606 (goto-char (min (mark) (point)))
1607 (CUA-rect-copy-as-kill)
1608 (CUA-delete-rectangle))
1609 (CUA-keep-active nil))
1611(defun CUA-cmd-delete-rectangle ()
1613 (goto-char (min (point) (mark)))
1614 (if CUA-mode-delete-to-register-0
1615 (set-register ?0 (CUA-extract-rectangle)))
1616 (CUA-delete-rectangle)
1617 (CUA-keep-active nil))
1619(defun CUA-cmd-toggle-rectangle ()
1622 (CUA-rect-deactivate)
1623 (CUA-rect-activate))
1624 (if CUA-mode-auto-help
1626 (CUA-help-for-rectangle t)
1627 (CUA-help-for-region t))))
1629(defun CUA-cmd-rotate-rectangle ()
1631 (CUA-rect-corner (if (= (CUA-rect-left) (CUA-rect-right)) 0 1))
1632 (CUA-rect-set-corners))
1634(defun CUA-cmd-toggle-rectangle-padding ()
1636 (if buffer-read-only
1637 (message "Cannot do padding in read-only buffer.")
1638 (CUA-rect-padding t (not (CUA-rect-padding)))
1640 (CUA-rect-set-corners))
1641 (setq CUA-mode-status (and (CUA-rect-padding) " Pad"))
1642 (CUA-keep-active t))
1644(defun CUA-cmd-do-rectangle-padding ()
1646 (if buffer-read-only
1647 (message "Cannot do padding in read-only buffer.")
1648 (CUA-pad-rectangle t)
1649 (CUA-rect-set-corners))
1650 (CUA-keep-active t))
1652(defun CUA-cmd-open-rectangle ()
1653 "Blank out CUA rectangle, shifting text right.
1654The text previously in the region is not overwritten by the blanks,
1655but instead winds up to the right of the rectangle."
1657 (CUA-rect-operation 'CUA-cmd-open-rectangle nil t 1
1659 (skip-chars-forward " \t")
1660 (let ((ws (- (current-column) l))
1662 (skip-chars-backward " \t")
1663 (delete-region (point) p)
1664 (indent-to (+ r ws))))))
1665(put 'CUA-cmd-open-rectangle 'CUA-rect 'corners)
1667(defun CUA-cmd-close-rectangle (arg)
1668 "Delete all whitespace starting at left edge of CUA rectangle.
1669On each line in the rectangle, all continuous whitespace starting
1670at that column is deleted.
1671With prefix arg, also delete whitespace to the left of that column."
1673 (CUA-absorb-prefix-arg)
1674 (CUA-rect-operation 'CUA-cmd-close-rectangle nil t 1
1677 (skip-syntax-backward " " (line-beginning-position))
1679 (skip-syntax-forward " " (line-end-position))
1680 (delete-region s (point)))))
1681(put 'CUA-cmd-close-rectangle 'CUA-rect 'clear)
1683(defun CUA-cmd-blank-rectangle ()
1684 "Blank out CUA rectangle.
1685The text previously in the rectangle is overwritten by the blanks."
1687 (CUA-rect-operation 'CUA-cmd-blank-rectangle nil nil 1
1690 (skip-syntax-forward " " (line-end-position))
1692 (let ((column (current-column)))
1694 (skip-syntax-backward " " (line-beginning-position))
1695 (delete-region (point) e)
1696 (indent-to column)))))
1697(put 'CUA-cmd-blank-rectangle 'CUA-rect 'keep)
1699(defun CUA-cmd-align-rectangle ()
1700 "Align rectangle lines to left column."
1703 (CUA-rect-operation 'CUA-cmd-align-rectangle nil t t
1705 (let ((b (line-beginning-position)))
1706 (skip-syntax-backward "^ " b)
1707 (skip-syntax-backward " " b)
1709 (skip-syntax-forward " " (line-end-position))
1710 (delete-region s (point))
1714 (setq CUA-save-point (point))))))
1715(put 'CUA-cmd-align-rectangle 'CUA-rect 'clear)
1717(defun CUA-cmd-copy-rectangle-as-text (&optional delete)
1718 "Copy rectangle, but store as normal text."
1720 (if (CUA-global-mark-active)
1721 (let ((CUA-global-mark-do-rect-as-text t))
1722 (if (eq delete 'delete)
1723 (CUA-global-mark-move-rect)
1724 (CUA-global-mark-copy-rect)))
1725 (let* ((rect (CUA-extract-rectangle))
1727 (function (lambda (row) (concat row "\n")))
1730 (set-register (CUA-register) text)
1732 (if (eq delete 'delete)
1733 (CUA-delete-rectangle))
1734 (CUA-keep-active nil)))
1736(defun CUA-cmd-cut-rectangle-as-text ()
1737 "Kill rectangle, but store as normal text."
1739 (CUA-cmd-copy-rectangle-as-text (or buffer-read-only 'delete)))
1741(defun CUA-cmd-string-rectangle (string)
1742 "Replace CUA rectangle contents with STRING on each line.
1743The length of STRING need not be the same as the rectangle width."
1744 (interactive "sString rectangle: ")
1745 (CUA-rect-operation 'CUA-cmd-string-rectangle nil t t
1748 (skip-chars-forward " \t")
1749 (let ((ws (- (current-column) l)))
1750 (delete-region s (point))
1752 (indent-to (+ (current-column) ws))))
1753 (unless (CUA-rect-restriction)
1755 (CUA-rect-right (max l (+ l (length string) -1)))))))
1756(put 'CUA-cmd-string-rectangle 'CUA-rect 'keep)
1758(defun CUA-cmd-fill-char-rectangle (ch)
1759 "Replace CUA rectangle contents with CHARACTER."
1760 (interactive "cFill rectangle with character: ")
1761 (CUA-rect-operation 'CUA-cmd-fill-char-rectangle nil t 1
1764 (insert-char ch (- r l)))))
1765(put 'CUA-cmd-fill-char-rectangle 'CUA-rect 'clear)
1767(defun CUA-cmd-replace-in-rectangle (regexp newtext)
1768 "Replace REGEXP with NEWTEXT in each line of CUA rectangle."
1769 (interactive "sReplace regexp: \nsNew text: ")
1770 (if buffer-read-only
1771 (message "Cannot replace in read-only buffer")
1772 (CUA-rect-operation 'CUA-cmd-replace-in-rectangle nil t 1
1774 (if (re-search-forward regexp e t)
1775 (replace-match newtext nil nil))))))
1776(put 'CUA-cmd-replace-in-rectangle 'CUA-rect 'keep)
1778(defun CUA-cmd-incr-rectangle (increment)
1779 "Increment each line of CUA rectangle by prefix amount."
1781 (CUA-absorb-prefix-arg)
1782 (CUA-rect-operation 'CUA-cmd-incr-rectangle nil t 1
1785 ((re-search-forward "0x\\([0-9a-fA-F]+\\)" e t)
1786 (let* ((txt (buffer-substring-no-properties (match-beginning 1) (match-end 1)))
1787 (n (string-to-number txt 16))
1788 (fmt (concat "0x%0" (length txt) "x")))
1789 (replace-match (format fmt (+ n increment)))))
1790 ((re-search-forward "\\( *-?[0-9]+\\)" e t)
1791 (let* ((txt (buffer-substring-no-properties (match-beginning 1) (match-end 1)))
1792 (n (string-to-number txt 10))
1793 (fmt (concat "%" (length txt) "d")))
1794 (replace-match (format fmt (+ n increment)))))
1796 (CUA-keep-active t))
1797(put 'CUA-cmd-incr-rectangle 'CUA-rect 'clear)
1799(defvar CUA-rect-seq-format "%d"
1800 "Last format used by CUA-cmd-sequence-rectangle.")
1802(defun CUA-cmd-sequence-rectangle (first incr fmt)
1803 "Resequence each line of CUA rectangle starting from FIRST.
1804The numbers are formatted according to the FORMAT string."
1806 (list (if current-prefix-arg
1807 (prefix-numeric-value current-prefix-arg)
1809 (read-string "Start value: (0) " nil nil "0")))
1811 (read-string "Increment: (1) " nil nil "1"))
1812 (read-string (concat "Format: (" CUA-rect-seq-format ") "))))
1813 (if (= (length fmt) 0)
1814 (setq fmt CUA-rect-seq-format)
1815 (setq CUA-rect-seq-format fmt))
1816 (CUA-rect-operation 'CUA-cmd-sequence-rectangle nil t 1
1819 (insert (format fmt first))
1820 (setq first (+ first incr)))))
1821(put 'CUA-cmd-sequence-rectangle 'CUA-rect 'clear)
1823(defun CUA-cmd-upcase-rectangle ()
1824 "Convert the rectangle to upper case."
1826 (CUA-rect-operation 'CUA-cmd-upcase-rectangle nil nil nil
1828 (upcase-region s e))))
1829(put 'CUA-cmd-upcase-rectangle 'CUA-rect 'clear)
1831(defun CUA-cmd-downcase-rectangle ()
1832 "Convert the rectangle to lower case."
1834 (CUA-rect-operation 'CUA-cmd-downcase-rectangle nil nil nil
1836 (downcase-region s e))))
1837(put 'CUA-cmd-downcase-rectangle 'CUA-rect 'clear)
1839(defun CUA-rect-aux-replace (width adjust keep replace pad format-fct &optional insert-fct)
1840 ;; Process text inserted by calling INSERT-FCT or current rectangle if nil.
1841 ;; Then call FORMAT-FCT on text (if non-nil); takes two args: start and end.
1842 ;; Fill to WIDTH characters if > 0 or fill to current width if == 0.
1843 ;; Don't fill if WIDTH < 0.
1844 ;; Replace current rectangle by filled text if REPLACE is non-nil
1845 (let ((m (get-buffer-create "*CUA temp*"))
1846 (w (- (CUA-rect-right) (CUA-rect-left) -1))
1847 (r (or insert-fct (CUA-extract-rectangle)))
1855 (funcall insert-fct)
1856 (CUA-insert-rectangle r))
1858 (let ((fill-column w))
1859 (funcall format-fct (point-min) (point-max))))
1861 (goto-char (point-min))
1863 (setq z (cons (buffer-substring (point) (line-end-position)) z)
1864 w (if (> (setq y (length (car z))) w) y w))
1868 (setq z (reverse z))
1869 (CUA-rect-operation nil nil t pad
1873 (skip-chars-forward " \t")
1874 (setq cc (current-column))
1879 (setq y (length (car z)))
1882 ;(insert-char ? (- w y)))
1885 (CUA-rect-right (+ (CUA-rect-left) w -1)))
1887 (CUA-keep-active t)))))
1889(put 'CUA-rect-aux-replace 'lisp-indent-function 4)
1891(defun CUA-cmd-text-fill-rectangle (width text)
1892 "Replace rectagle with filled TEXT read from minibuffer.
1893A numeric prefix argument is used a new width for the filled rectangle."
1895 (prog1 (prefix-numeric-value current-prefix-arg)
1896 (CUA-absorb-prefix-arg))
1897 (read-from-minibuffer "Enter text: "
1899 (CUA-rect-aux-replace width t t t 1
1901 '(lambda () (insert text))))
1903(defun CUA-cmd-self-fill-rectangle (width)
1904 "Fill contents of current rectagle.
1905A numeric prefix argument is used a new width for the filled rectangle."
1907 (CUA-absorb-prefix-arg)
1908 (CUA-rect-aux-replace width t t t 1 'fill-region))
1910(defun CUA-cmd-shell-command-on-rectangle (replace command)
1911 "Run shell command on rectangle like `shell-command-on-region'.
1912With prefix arg, replace rectangle with output from command."
1914 (prog1 current-prefix-arg (CUA-absorb-prefix-arg))
1915 (read-from-minibuffer "Shell command on rectangle: "
1917 'shell-command-history)))
1918 (CUA-rect-aux-replace -1 t t replace 1
1920 (shell-command-on-region s e command
1921 replace replace nil))))
1923(defun CUA-cmd-reverse-rectangle ()
1924 "Reverse the lines of the rectangle."
1926 (CUA-rect-aux-replace 0 t t t t 'reverse-region))
1928(defun CUA-cmd-scroll-rectangle-up ()
1929 "Remove the first line of the rectangle and scroll remaining lines up."
1931 (CUA-rect-aux-replace 0 t t t t
1933 (if (= (forward-line 1) 0)
1934 (delete-region s (point))))))
1936(defun CUA-cmd-scroll-rectangle-down ()
1937 "Insert a blank line at the first line of the rectangle.
1938The remaining lines are scrolled down, losing the last line."
1940 (CUA-rect-aux-replace 0 t t t t
1945(defun CUA-action-insert-char-rectangle ()
1946 (if buffer-read-only
1948 (CUA-rect-indent-rectangle
1949 (aref (this-single-command-keys) 0))
1950 (CUA-keep-active t))
1953(defun CUA-cmd-delete-char-rectangle ()
1954 "Delete char to left or right of rectangle."
1956 (let ((col (CUA-rect-insert-col))
1957 (pad (CUA-rect-padding))
1959 (CUA-rect-operation 'CUA-cmd-delete-char-rectangle nil t pad
1962 (if (CUA-rect-right-side t)
1967 (delete-backward-char 1)
1968 (if (CUA-rect-right-side t)
1969 (CUA-rect-insert-col (current-column))
1970 (setq indent (- l (current-column))))))
1972 (when (and indent (> indent 0))
1973 (aset CUA-rectangle 2 (- l indent))
1974 (aset CUA-rectangle 3 (- r indent 1)))))))
1975(put 'CUA-cmd-delete-char-rectangle 'CUA-rect 'corners)
1977(defun CUA-cmd-mouse-set-rectangle-corner (event)
1978 "Set rectangle corner at mouse click position."
1980 (mouse-set-point event)
1981 (if (CUA-rect-padding)
1982 (move-to-column (car (posn-col-row (event-end event))) t))
1983 (if (CUA-rect-right-side)
1984 (CUA-rect-right (current-column))
1985 (CUA-rect-left (current-column)))
1986 (if (>= (CUA-rect-corner) 2)
1990 (CUA-rect-insert-col 0)
1991 (CUA-rect-set-corners)
1993 (setq CUA-start-point nil))
1998;; global mark actions
2000(defun CUA-cmd-copy-to-global-mark ()
2002 (setq CUA-rect-last-killed nil)
2004 (CUA-global-mark-copy-rect)
2005 (let ((start (mark)) (end (point)))
2007 (setq start (prog1 end (setq end start))))
2008 (CUA-global-mark-copy-region start end))))
2010(defun CUA-cmd-copy1-to-global-mark (n)
2012 (CUA-absorb-prefix-arg)
2013 (setq CUA-rect-last-killed nil)
2017 (CUA-global-mark-copy-region p (point)))))
2019(defun CUA-cmd-cut-to-global-mark ()
2021 (if buffer-read-only
2022 (CUA-cmd-copy-to-global-mark)
2023 (setq CUA-rect-last-killed nil)
2025 (CUA-global-mark-move-rect)
2026 (let ((start (mark)) (end (point)))
2028 (setq start (prog1 end (setq end start))))
2029 (CUA-global-mark-move-region start end)))))
2031(defun CUA-cmd-cut1-to-global-mark (n)
2033 (CUA-absorb-prefix-arg)
2034 (setq CUA-rect-last-killed nil
2035 current-prefix-arg nil
2036 overriding-terminal-local-map nil)
2040 (CUA-global-mark-move-region p (point)))))
2042(defun CUA-cmd-delete-char-at-global-mark (arg)
2044 (CUA-absorb-prefix-arg)
2045 (if (window-minibuffer-p)
2047 (CUA-global-mark-delete-char arg "Deleted")
2050(defun CUA-cmd-delete-backward-char-at-global-mark (arg)
2052 (CUA-absorb-prefix-arg)
2053 (if (window-minibuffer-p)
2055 (CUA-global-mark-delete-char (- arg) "Deleted backward")
2058(defun CUA-action-insert-char-at-global-mark ()
2059 (if (window-minibuffer-p)
2061 (CUA-global-mark-insert (char-to-string (aref (this-single-command-keys) 0)) "Inserted")
2064(defun CUA-action-insert-newline-at-global-mark ()
2065 (if (window-minibuffer-p)
2067 (CUA-global-mark-insert "\n")
2071(defun CUA-cmd-insert-newline-at-global-mark ()
2073 (if (not (CUA-action-insert-newline-at-global-mark))
2074 (call-interactively CUA-orig-command)))
2080(defun CUA-cmd-ignore (arg)
2082 (CUA-absorb-prefix-arg))
2083(defun CUA-lookup-key (map key)
2084 (let ((k (lookup-key map key)))
2090;; command specific CUA actions
2093(defvar CUA-region-commands
2094 '((CUA-action-delete-before ; delete current region before command
2095 self-insert-command self-insert-iso
2096 insert-register newline-and-indent newline open-line)
2097 (CUA-action-delete ; delete current region and ignore command
2098 delete-backward-char backward-delete-char
2099 backward-delete-char-untabify delete-char)
2100 (CUA-action-cut ; kill region and ignore command
2102 (CUA-action-copy ; copy region and ignore command
2103 copy-region-as-kill kill-ring-save)
2104 (CUA-action-paste ; replace region with rectangle or element on kill ring
2105 yank clipboard-yank)
2106 (CUA-action-paste-pop ; replace current yank with previous kill ring element
2108 (CUA-action-cancel ; cancel current region
2109 keyboard-escape-quit keyboard-quit))
2110 "Specifies how various editing functions behave in CUA mode.
2111The value is a list of lists. For each element in the list, the
2112first element is an action function and the rest of the list are names of
2113editing commands which shall perform the specified action if the
2114region is active and CUA mode is enabled.
2115Note: These actions are only used if an action is not specified
2116in the state specific CUA keymap for the current command.
2117The action functions are called without arguments, and if they return
2118a non-nil value, the original command is not executed.")
2120(defun CUA-action-move ()
2121 ;; Action handler for cursor movement keys.
2122 ;; If region is not active, region is activated if key is shifted.
2123 ;; If region is active, region is cancelled if key is unshifted (and region not started with C-SPC).
2124 ;; If rectangle is active, expand rectangle in specified direction and ignore the movement.
2125 (if (or CUA-explicit-region-start
2127 (memq 'shift (event-modifiers (aref (this-single-command-keys) 0))))
2128 (and (not mark-active) (set-mark-command nil))
2129 (setq mark-active nil))
2130 (and mark-active CUA-rectangle
2131 (CUA-rect-resize this-command)))
2134 (defvar CUA-this-action nil))
2136(defun CUA-action-cancel ()
2137 ;; Action handler which cancels the region.
2138 (setq mark-active nil
2139 CUA-explicit-region-start nil)
2141 (CUA-rect-deactivate))
2142 (setq CUA-last-rectangle nil)
2143 (if (CUA-global-mark-active)
2144 (CUA-global-mark-deactivate t)))
2146(defun CUA-action-delete-before ()
2147 ;; Action handler which deletes the region before the command is executed.
2150 (CUA-cmd-delete-rectangle)
2151 (CUA-cmd-delete-region)))
2154(defun CUA-action-delete ()
2155 ;; Action handler which deletes the region and ignores the command.
2156 (if (not mark-active)
2159 (CUA-cmd-delete-rectangle)
2160 (CUA-cmd-delete-region))
2163(defun CUA-action-cut ()
2164 ;; Action handler which cuts the region before executing the command.
2165 ;; If the region is not active, ignore the command.
2166 (if (not mark-active)
2169 (cond ((CUA-global-mark-active) 'CUA-cmd-cut-to-global-mark)
2170 (CUA-rectangle 'CUA-cmd-cut-rectangle)
2171 (t 'CUA-cmd-cut-region)))
2174(defun CUA-action-copy ()
2175 ;; Action handler which copies the region before executing the command.
2176 ;; If the region is not active, ignore the command.
2177 (if (not mark-active)
2180 (cond ((CUA-global-mark-active) 'CUA-cmd-copy-to-global-mark)
2181 (CUA-rectangle 'CUA-cmd-copy-rectangle)
2182 (t 'CUA-cmd-copy-region)))
2185(defun CUA-action-paste ()
2186 ;; Action handler which pastes the last cut or copy.
2187 ;; An active region is deleted before executing the command.
2188 (if buffer-read-only
2189 nil ; fall back to original action
2190 ;; Must save register here, since delete may override reg 0.
2191 (let ((reg (and (CUA-register) (get-register (CUA-register)))))
2193 ;; Before a yank command, make sure we don't yank
2194 ;; the same region that we are going to delete.
2195 ;; That would make yank a no-op.
2197 (CUA-cmd-delete-rectangle)
2198 (if (string= (buffer-substring (point) (mark))
2201 (CUA-cmd-delete-region)))
2205 ((consp reg) (CUA-insert-rectangle reg))
2206 ((stringp reg) (insert reg))
2207 (t (message "Nothing in register %c" (CUA-register))))
2209 ((and CUA-rect-last-killed (eq (and kill-ring (car kill-ring)) (car CUA-rect-last-killed)))
2210 (when (not (eq buffer-undo-list t))
2211 (setq CUA-this-action 'CUA-action-paste-rect) ;; dynamic binding
2213 (setq buffer-undo-list (cons (point) buffer-undo-list)))
2214 (CUA-insert-rectangle (cdr CUA-rect-last-killed))
2216 ((and (CUA-global-mark-active)
2218 (CUA-global-mark-copy-region (point) (1+ (point)))
2223(defun CUA-action-paste-pop ()
2224 (when (eq CUA-last-action 'CUA-action-paste-rect)
2226 (setq this-command 'yank))
2230;; CUA state indications
2232(defvar CUA-ind-do-initialize t)
2234(defun CUA-ind-init-indications (&optional reset)
2235 (unless (face-background 'CUA-rectangle-face)
2236 (copy-face 'region 'CUA-rectangle-face)
2237 (set-face-background 'CUA-rectangle-face "maroon")
2238 (set-face-foreground 'CUA-rectangle-face "white"))
2239 (unless (face-background 'CUA-rectangle-noselect-face)
2240 (copy-face 'region 'CUA-rectangle-noselect-face)
2241 (set-face-background 'CUA-rectangle-noselect-face "dimgray")
2242 (set-face-foreground 'CUA-rectangle-noselect-face "white"))
2243 (unless (face-background 'CUA-global-mark-face)
2244 (copy-face 'region 'CUA-global-mark-face)
2245 (set-face-foreground 'CUA-global-mark-face "black")
2246 (set-face-background 'CUA-global-mark-face "cyan"))
2247 (setq CUA-ind-do-initialize nil))
2249;; change cursor color according to overwrite-mode...
2253(defvar CUA-ind-cursor-blink-timer nil)
2254(defvar CUA-ind-cursor-blink-off nil)
2256(defun CUA-ind-cursor-blink-toggle ()
2257 (setq CUA-ind-cursor-blink-off (not CUA-ind-cursor-blink-off))
2260 (CUA-ind-cursor-blink-off
2261 (frame-parameter nil 'foreground-color))
2263 (if (CUA-rect-padding)
2264 CUA-mode-overwrite-cursor-color
2265 CUA-mode-normal-cursor-color))
2266 (overwrite-mode CUA-mode-overwrite-cursor-color)
2267 (t CUA-mode-normal-cursor-color))))
2269 (set-cursor-color cursor))))
2271(defun CUA-ind-update-indications ()
2272 (if CUA-ind-do-initialize
2273 (CUA-ind-init-indications))
2274 (if CUA-mode-use-cursor-colors
2277 (buffer-read-only CUA-mode-read-only-cursor-color)
2279 (if (CUA-rect-padding)
2280 CUA-mode-overwrite-cursor-color
2281 CUA-mode-normal-cursor-color))
2282 (overwrite-mode CUA-mode-overwrite-cursor-color)
2283 (t CUA-mode-normal-cursor-color))))
2285 ((and (CUA-global-mark-active)
2286 (or CUA-mode-global-mark-cursor-blink
2287 CUA-mode-global-mark-cursor-color))
2288 (if CUA-mode-global-mark-cursor-color
2289 (setq cursor CUA-mode-global-mark-cursor-color))
2290 (if (and CUA-mode-global-mark-cursor-blink
2291 cursor (not CUA-ind-cursor-blink-timer))
2292 (setq CUA-ind-cursor-blink-timer
2293 (run-at-time t 0.25 'CUA-ind-cursor-blink-toggle))))
2294 (CUA-ind-cursor-blink-timer
2295 (cancel-timer CUA-ind-cursor-blink-timer)
2296 (setq CUA-ind-cursor-blink-timer nil)
2297 (setq CUA-ind-cursor-blink-off nil)))
2299 (not (equal cursor (frame-parameter nil 'cursor-color))))
2300 (set-cursor-color cursor)))))
2303;; prefix key handling
2306(defun CUA-absorb-prefix-arg ()
2307 ;; If a CUA command has an optional prefix arg, use this command to clear it.
2308 (setq current-prefix-arg nil
2309 overriding-terminal-local-map nil))
2311(defun CUA-kbd-macro-fixup (e1 &optional e2)
2312 (when defining-kbd-macro
2313 (cancel-kbd-macro-events)
2314 (store-kbd-macro-event e1)
2316 (store-kbd-macro-event e2)))
2319(defun CUA-prefix-handler (prompt)
2320 (let ((prefix last-input-char)
2321 (keys (this-command-keys))
2329 (and CUA-mode-highlight-shift-only CUA-explicit-region-start))
2330 (not executing-kbd-macro)
2331 (not (and CUA-mode-remap-cx-shift-only CUA-explicit-region-start))
2332 (or (= (length keys) 1)
2333 (eq (CUA-lookup-key global-map (substring keys 0 -1)) 'digit-argument))
2334 (not (memq this-command '(describe-key describe-key-briefly)))
2335 (or (not (memq CUA-mode-inhibit-method '(delay twice)))
2336 (= CUA-mode-inhibit-delay 0)
2337 (sit-for 0 CUA-mode-inhibit-delay t)
2338 (symbolp (event-basic-type (setq ev (read-event))))
2339 (eq CUA-mode-inhibit-method 'delay)
2340 ;; We got the next key before the timeout.
2341 ;; Don't perform CUA remapping of prefix.
2342 ;; Also, if prefix == ev, drop ev
2344 (setq ev (CUA-kbd-macro-fixup prefix))))
2345 (setq map (assq prefix CUA-prefix-key-mappings))))
2349 (CUA-kbd-macro-fixup (cdr map) ev)
2351 (setq unread-command-events (cons ev unread-command-events)))
2352 (vector (cdr map)))))
2354(defun CUA-ctl-x-8-prefix-handler ()
2355 "Explicit handing of C-x 8 prefix when CUA mode is used.
2356This is necessary since CUA mode installs its own handler for C-x
2357in key-translation-map."
2359 (unless CUA-ctl-x-8-prefix-key
2360 (setq CUA-ctl-x-8-prefix-key
2361 (cond ((not (lookup-key global-map [?\H-8])) ?\H-8)
2362 ((not (lookup-key global-map [?\s-8])) ?\s-8)
2363 ((not (lookup-key global-map [?\C-\H-8])) ?\C-\H-8)
2365 (unless (and (boundp 'iso-transl-ctl-x-8-map) (lookup-key iso-transl-ctl-x-8-map [?/ ?o]))
2366 (let ((key-translation-map nil)) ;; Avoid barfing about CUA's C-x binding
2367 (require 'iso-transl))
2368 (define-key key-translation-map (vector CUA-ctl-x-8-prefix-key) 'iso-transl-ctl-x-8-map)))
2369 (setq unread-command-events (cons CUA-ctl-x-8-prefix-key unread-command-events)))
2371(defvar CUA-overriding-region-map nil
2372 "Keymap that overrides other keymaps when region is active.")
2374(defvar CUA-overriding-rectangle-map nil
2375 "Keymap that overrides other keymaps when rectangle is active.")
2377(defvar CUA-overriding-global-mark-map nil
2378 "Keymap that overrides other keymaps when global mark is active.")
2380(defvar CUA-overriding-global-mark-commands
2381 '(self-insert-command self-insert-iso indent-for-tab-command)
2382 "List of commands whose global mapping should override mode specific mappings.")
2384(defun CUA-lookup-overriding-maps (keys &optional command)
2386 ((and overriding-terminal-local-map
2387 (CUA-lookup-key overriding-terminal-local-map keys))
2389 ((and (window-minibuffer-p)
2391 (CUA-lookup-key (current-local-map) keys))
2395 (let ((gcmd (CUA-lookup-key global-map keys)))
2398 (if (memq gcmd CUA-overriding-global-mark-commands)
2401 (or (and (CUA-global-mark-active)
2402 (CUA-lookup-key CUA-overriding-global-mark-map keys))
2404 (CUA-lookup-key CUA-overriding-rectangle-map keys))
2406 (CUA-lookup-key CUA-overriding-region-map keys))))))
2408(defun CUA-delete-selection (command)
2409 ;; Convert delete-selection property to corresponding CUA action
2410 (let ((ds (or (get command 'delete-selection) (get command 'pending-delete))))
2413 ((eq ds 'yank) 'CUA-action-paste)
2414 ((eq ds 'kill) 'CUA-action-copy)
2415 ((eq ds 'supersede) 'CUA-action-delete)
2416 (t 'CUA-action-delete-before)))))
2418(defun CUA-pre-hook ()
2419 "Function run prior to command to check for special region handling.
2420If current command is a movement and the key is shifted, set or expand
2423 (let* ((keys (this-single-command-raw-keys))
2424 (new-cmd (and (= (length keys) 1)
2425 (CUA-lookup-overriding-maps keys)))
2426 action CUA-this-action ignore)
2427 (setq CUA-save-point (point))
2429 (setq CUA-orig-command this-command
2430 this-command new-cmd))
2432 (and (symbolp this-command)
2433 (or (CUA-lookup-overriding-maps keys this-command)
2434 (get this-command 'CUA)
2435 (CUA-delete-selection this-command))))
2436 (if (and action (fboundp action))
2437 (setq ignore (funcall (setq CUA-this-action action)))
2439 (message "Unknown function: %S" action)
2440 (setq action nil))))
2441 (setq CUA-last-action CUA-this-action)
2442 (setq CUA-start-point nil)
2444 (setq this-command 'CUA-cmd-ignore
2446 current-prefix-arg nil)
2448 (setq CUA-start-point (cons (current-buffer) (point))))))
2451(defun CUA-post-hook ()
2452 "Function run after command to check for rectangle region handling."
2455 (when (and CUA-mode-global-mark-visible (CUA-global-mark-active))
2457 (if (or (not (eq (current-buffer) (marker-buffer CUA-global-mark)))
2458 (not (pos-visible-in-window-p (marker-position CUA-global-mark))))
2459 (let ((w (selected-window)) (p (point)) h)
2460 ;; The following code is an attempt to keep the global mark visible in
2461 ;; other window -- but it doesn't work.
2462 (switch-to-buffer-other-window (marker-buffer CUA-global-mark) t)
2463 (goto-char (marker-position CUA-global-mark))
2464 (if (not (pos-visible-in-window-p (marker-position CUA-global-mark)))
2465 (recenter (if (> (setq h (- (window-height) 4)) 1) h '(4))))
2468 (if CUA-next-rectangle
2469 (setq CUA-rectangle CUA-next-rectangle
2470 CUA-next-rectangle nil
2472 deactivate-mark nil)
2473 (when (and CUA-rectangle CUA-start-point
2474 (equal (car CUA-start-point) (current-buffer))
2475 (not (= (cdr CUA-start-point) (point))))
2476 (if (CUA-rect-right-side)
2477 (CUA-rect-right (current-column))
2478 (CUA-rect-left (current-column)))
2479 (if (>= (CUA-rect-corner) 2)
2482 (if (CUA-rect-padding)
2483 (setq unread-command-events
2484 (cons (if CUA-mode-use-hyper-key ?\H-P ?\M-P) unread-command-events)))))
2485 (setq CUA-start-point nil)
2487 (if (and mark-active
2488 (not deactivate-mark))
2489 (CUA-rect-highlight)
2490 (CUA-rect-deactivate)))
2491 (if (or (not mark-active) deactivate-mark)
2492 (setq CUA-explicit-region-start nil))
2495 (CUA-rectangle (CUA-rect-assert))
2496 (mark-active (message "Mark=%d Point=%d Expl=%s"
2497 (mark) (point) CUA-explicit-region-start))))
2498 ;; Disable transient-mark-mode if rectangle active in current buffer.
2499 (if (not (window-minibuffer-p (selected-window)))
2500 (setq transient-mark-mode (and (not CUA-rectangle)
2501 (if CUA-mode-highlight-shift-only
2502 (not CUA-explicit-region-start)
2504 CUA-cur-register nil))
2505 (CUA-ind-update-indications))
2509(defvar CUA-movement-keys
2510 '((forward-char right)
2511 (backward-char left)
2514 (forward-word control right)
2515 (backward-word control left)
2517 (beginning-of-line home)
2518 (end-of-buffer control end)
2519 (beginning-of-buffer control home)
2522 (forward-paragraph control down)
2523 (backward-paragraph control up))
2524 "List of cursor movement functions for which to create CUA key mappings.
2525Each element in the list is a list where the first element is the name of
2526the cursor movement function, and the rest of the list are keys to which
2527the function shall be bound. For each key listed, both the key itself and
2528the shifted version S-key are bound to the specified function.")
2530(defun CUA-help-for-region (&optional help)
2533 (concat (if help "C-?:help " "")
2534 "C-z:undo C-x:cut C-c:copy C-v:paste S-ret:rect")))
2536(defun CUA-help-for-rectangle (&optional help)
2539 (concat (if help "C-?:help " "")
2540 "M-p:pad M-o:open M-c:close M-b:blank M-s:string M-f:fill M-i:incr M-n:seq")))
2542(defun CUA-hyper-key (map key fct &optional other)
2543 (if (eq key 'space) (setq key ? ))
2544 (unless (listp key) (setq key (list key)))
2547 (CUA-mode-use-hyper-key (vector (cons 'hyper key)))
2549 (t (vector (cons 'meta key)))))
2550 (define-key map key fct)
2551 (if (and other (eq CUA-mode-use-hyper-key 'also))
2552 (define-key map other fct)))
2554(defun CUA-mode-init-maps (emacs-bindings)
2555 (if (not CUA-overriding-region-map)
2556 (let ((m (make-sparse-keymap)))
2557 (unless emacs-bindings
2558 (define-key m [(control insert)] 'CUA-cmd-copy-region)
2559 (define-key m [(shift delete)] 'CUA-cmd-cut-region))
2560 (CUA-hyper-key m 'space 'CUA-cmd-toggle-rectangle [(shift return)])
2561 (define-key m [(control ?i)] 'CUA-cmd-indent-region-left)
2562 (define-key m [(control shift ?i)] 'CUA-cmd-indent-region-right)
2563 (define-key m [(control ??)] 'CUA-help-for-region)
2564 (setq CUA-overriding-region-map m)))
2565 (if (not CUA-overriding-rectangle-map)
2566 (let ((m (make-keymap)))
2567 (unless emacs-bindings
2568 (define-key m [(control insert)] 'CUA-cmd-copy-rectangle)
2569 (define-key m [(shift delete)] 'CUA-cmd-cut-rectangle))
2570 (define-key m [(control ? )] 'CUA-cmd-toggle-rectangle)
2571 (CUA-hyper-key m 'space 'CUA-cmd-end-rectangle [(shift return)])
2572 (define-key m [return] 'CUA-cmd-rotate-rectangle)
2573 (define-key m "\r" 'CUA-cmd-rotate-rectangle)
2574 (define-key m [mouse-1] 'CUA-cmd-mouse-set-rectangle-corner)
2575 (CUA-hyper-key m 'up 'CUA-cmd-move-rectangle-up)
2576 (CUA-hyper-key m 'down 'CUA-cmd-move-rectangle-down)
2577 (CUA-hyper-key m 'left 'CUA-cmd-move-rectangle-left)
2578 (CUA-hyper-key m 'right 'CUA-cmd-move-rectangle-right)
2579 (CUA-hyper-key m '(control up) 'CUA-cmd-scroll-rectangle-up)
2580 (CUA-hyper-key m '(control down) 'CUA-cmd-scroll-rectangle-down)
2581 (CUA-hyper-key m ?a 'CUA-cmd-align-rectangle)
2582 (CUA-hyper-key m ?b 'CUA-cmd-blank-rectangle)
2583 (CUA-hyper-key m ?c 'CUA-cmd-close-rectangle)
2584 (CUA-hyper-key m ?f 'CUA-cmd-fill-char-rectangle)
2585 (CUA-hyper-key m ?F 'CUA-cmd-self-fill-rectangle)
2586 (CUA-hyper-key m ?i 'CUA-cmd-incr-rectangle)
2587 (CUA-hyper-key m ?k 'CUA-cmd-cut-rectangle-as-text)
2588 (CUA-hyper-key m ?l 'CUA-cmd-downcase-rectangle)
2589 (CUA-hyper-key m ?m 'CUA-cmd-copy-rectangle-as-text)
2590 (CUA-hyper-key m ?n 'CUA-cmd-sequence-rectangle)
2591 (CUA-hyper-key m ?o 'CUA-cmd-open-rectangle)
2592 (CUA-hyper-key m ?p 'CUA-cmd-toggle-rectangle-padding)
2593 (CUA-hyper-key m ?P 'CUA-cmd-do-rectangle-padding)
2594 (CUA-hyper-key m ?r 'CUA-cmd-replace-in-rectangle)
2595 (CUA-hyper-key m ?R 'CUA-cmd-reverse-rectangle)
2596 (CUA-hyper-key m ?s 'CUA-cmd-string-rectangle)
2597 (CUA-hyper-key m ?t 'CUA-cmd-text-fill-rectangle)
2598 (CUA-hyper-key m ?u 'CUA-cmd-upcase-rectangle)
2599 (CUA-hyper-key m ?| 'CUA-cmd-shell-command-on-rectangle)
2600 (CUA-hyper-key m ?' 'CUA-cmd-restrict-prefix-rectangle)
2601 (CUA-hyper-key m ?/ 'CUA-cmd-restrict-regexp-rectangle)
2602 (define-key m [(control ??)] 'CUA-help-for-rectangle)
2603 (define-key m [backspace] 'CUA-cmd-delete-char-rectangle)
2604 (define-key m "\d" 'CUA-cmd-delete-char-rectangle)
2605 (define-key m [self-insert-command] 'CUA-action-insert-char-rectangle)
2606 (define-key m [self-insert-iso] 'CUA-action-insert-char-rectangle)
2607 (define-key m [indent-for-tab-command] 'CUA-action-insert-char-rectangle)
2608 (setq CUA-overriding-rectangle-map m)))
2609 (if (not CUA-overriding-global-mark-map)
2610 (let ((m (make-sparse-keymap)))
2612 (define-key m [(control ?y)] 'CUA-cmd-copy1-to-global-mark)
2613 (define-key m [(control insert)] 'CUA-cmd-copy-to-global-mark)
2614 (define-key m [(shift delete)] 'CUA-cmd-cut-to-global-mark)
2615 (define-key m [(control ?v)] 'CUA-cmd-copy1-to-global-mark))
2616 (define-key m [(control ?d)] 'CUA-cmd-cut1-to-global-mark)
2617 (define-key m [backspace] 'CUA-cmd-delete-backward-char-at-global-mark)
2618 (define-key m "\d" 'CUA-cmd-delete-backward-char-at-global-mark)
2619 (define-key m [delete] 'CUA-cmd-delete-char-at-global-mark)
2620 (define-key m [self-insert-command] 'CUA-action-insert-char-at-global-mark)
2621 (define-key m [self-insert-iso] 'CUA-action-insert-char-at-global-mark)
2622 (define-key m [newline] 'CUA-action-inset-newline-at-global-mark)
2623 (define-key m [newline-and-indent] 'CUA-action-insert-newline-at-global-mark)
2624 (define-key m [return] 'CUA-cmd-insert-newline-at-global-mark)
2625 (define-key m "\r" 'CUA-cmd-insert-newline-at-global-mark)
2626 (setq CUA-overriding-global-mark-map m)))
2627 (unless (get 'forward-char 'CUA)
2628 (let ((list CUA-region-commands) act l)
2635 (put (car l) 'CUA act)
2637 (let ((list CUA-movement-keys) cmd)
2639 (setq cmd (car (car list))
2641 (put cmd 'CUA 'CUA-action-move)))))
2643(defun CUA-define-key (map key cmd)
2644 "Like define-key with specific short-cuts for CUA maps.
2645In MAP, define KEY to run command CMD.
2646Special values for MAP are 'region, 'rect, 'gm, and 'all to bind into
2647the CUA maps for the active region, active rectangle, and active
2648global marker resp., or all of them."
2650 (setq key (vector key)))
2651 (if (memq map '(region all))
2652 (define-key CUA-overriding-region-map key cmd))
2653 (if (memq map '(rect all))
2654 (define-key CUA-overriding-rectangle-map key cmd))
2655 (if (memq map '(gm all))
2656 (define-key CUA-overriding-global-mark-map key cmd)))
2658(defun CUA-define-key-as (map key key2)
2659 "Define a key to run the same CUA command as another key."
2661 (setq key (vector key)))
2663 (setq key2 (vector key2)))
2664 (if (memq map '(region all))
2665 (let ((cmd (CUA-lookup-key CUA-overriding-region-map key2)))
2667 (define-key CUA-overriding-region-map key cmd))))
2668 (if (memq map '(rect all))
2669 (let ((cmd (CUA-lookup-key CUA-overriding-rectangle-map key2)))
2671 (define-key CUA-overriding-rectangle-map key cmd))))
2672 (if (memq map '(gm all))
2673 (let ((cmd (CUA-lookup-key CUA-overriding-global-mark-map key2)))
2675 (define-key CUA-overriding-global-mark-map key cmd)))))
2678(defun CUA-movement-key (key command)
2679 "Like `global-set-key' but also binds shifted KEY to COMMAND.
2680KEY should be a simple symbol or character, like home or ?\\C-e,
2681or a list like (control home)."
2683 (setq key (aref key 0)))
2684 (if (not (listp key))
2685 (setq key (list key)))
2686 (global-set-key (vector key) command)
2687 (global-set-key (vector (cons 'shift key)) command)
2688 (put command 'CUA 'CUA-action-move))
2691(defun CUA-mode-bindings (&optional bind)
2692 "Define even more compatibility bindings.
2693Optional argument BIND identifies what bindings to add."
2696 ;; The following bindings are useful on Sun Type 3 keyboards
2697 ;; They implement the Get-Delete-Put (copy-cut-paste)
2698 ;; functions from sunview on the L6, L8 and L10 keys
2699 (define-key global-map [f16] 'yank)
2700 (define-key global-map [f18] 'copy-region-as-kill)
2701 (define-key global-map [f20] 'kill-region))
2702 ((eq bind 'pc-select)
2703 ;; The following bindings are made by pc-select
2704 ;; I [KFS] personally don't like them, so I made them extra.
2705 (global-set-key [f1] 'help) ; KHelp F1
2706 ;; The following bindings are from Pete Forman.
2707 (global-set-key [f6] 'other-window) ; KNextPane F6
2708 (global-set-key [delete] 'delete-char) ; KDelete Del
2709 (global-set-key [(meta backspace)] 'undo) ; KUndo aBS
2710 ;; The following bindings are taken from pc-mode.el as suggested by RMS.
2711 (define-key function-key-map [(meta delete)] [(meta ?d)])
2712 (global-set-key [(control meta delete)] 'kill-sexp)
2713 (global-set-key [(control backspace)] 'backward-kill-word)
2714 ;; Next line proposed by Eli Barzilay
2715 (global-set-key [(control escape)] 'electric-buffer-list))
2716 ((eq bind 'windows-nt)
2717 ;; From: Kari Heinola <kph@dp.com>
2718 (define-key global-map [(control ?a)] 'mark-whole-buffer)
2719 (define-key global-map [(control ?p)] 'print-buffer)
2720 (define-key global-map [(control ?s)] 'save-buffer)
2721 (define-key global-map [(control ?n)] 'find-file)
2722 (if (fboundp 'dlgopen-open-files)
2723 (define-key global-map [(control ?o)] 'dlgopen-open-files)
2724 (define-key global-map [(control ?o)] 'find-file))
2725 (define-key global-map [(control ?f)] 'isearch-forward)
2726 (define-key isearch-mode-map [(control ?f)] 'isearch-repeat-forward)
2727 (define-key global-map [(control ?h)] 'query-replace)
2728 (define-key global-map [f5] 'insert-time-stamp))
2729 ((eq bind 'emacs) ; CUA functionality for normal emacs bindings
2730 (substitute-key-definition 'undo 'CUA-undo global-map)
2731 (substitute-key-definition 'advertised-undo 'CUA-undo global-map)
2732 (define-key global-map [(control delete)] 'kill-word)
2733 (define-key global-map [(control backspace)] 'backward-kill-word)
2734 (define-key global-map [delete] 'delete-char)
2735 (define-key global-map [(control ? )] 'CUA-set-mark)
2736 (define-key global-map [(shift control ? )] 'CUA-cmd-toggle-global-mark)
2737 (CUA-hyper-key global-map 'space 'CUA-cmd-begin-rectangle [(shift return)]))
2738 ((eq bind 'CUA) ; default CUA mappings
2739 ;; Compatibility mappings
2740 ;; Note: These are required since CUA-prefix-key-mappings maps
2741 ;; C-x into S-delete and C-c into C-insert.
2742 (define-key global-map [(control insert)] 'copy-region-as-kill)
2743 (define-key global-map [(shift delete)] 'kill-region)
2744 (define-key global-map [(shift insert)] 'yank)
2745 (define-key global-map [(meta insert)] 'yank-pop)
2746 (define-key global-map [(control delete)] 'kill-word)
2747 (define-key global-map [(control backspace)] 'backward-kill-word)
2748 (define-key global-map [delete] 'delete-char)
2749 (define-key global-map [(control ? )] 'CUA-set-mark)
2750 (define-key global-map [(shift control ? )] 'CUA-cmd-toggle-global-mark)
2751 (CUA-hyper-key global-map 'space 'CUA-cmd-begin-rectangle [(shift return)]))
2753 (define-key global-map [(control ?z)] 'CUA-undo)
2754 (define-key ctl-x-map [(control ?x)] 'CUA-exchange-point-and-mark)
2755 (define-key global-map [(control ?v)] 'yank)
2756 (or key-translation-map
2757 (setq key-translation-map (make-sparse-keymap)))
2758 (let ((map CUA-prefix-key-mappings))
2760 (define-key key-translation-map
2761 (vector (car (car map))) 'CUA-prefix-handler)
2762 (if (stringp (cdr (car map)))
2763 (setcdr (car map) (read-kbd-macro (cdr (car map)))))
2764 (setq map (cdr map))))
2765 (define-key ctl-x-map [?8] 'CUA-ctl-x-8-prefix-handler))
2767 (let ((list CUA-movement-keys) cmd elt key)
2769 (setq elt (car list)
2773 (define-key global-map (vector key) cmd)
2774 (define-key global-map (vector (cons 'shift key)) cmd))))))
2777(defun CUA-mode (&optional arg extra nobind)
2778 "Toggle CUA keybinding mode.
2779When ON, C-x and C-c will cut and copy the selection if the selection
2780is active (i.e. the region is highlighted), and typed text replaces
2781the active selection. When OFF, typed text is just inserted at point.
2782If non-nil, the optional second argument EXTRA specifies additional
2783key bindings as defined by CUA-mode-bindings.
2784The following key bindings are made unless optional third argument
2788 C-x C-x is CUA-exchange-point-and-mark which doesn't enable the mark
2789 C-space starts/cancels the normal region
2790 S-C-space sets/cancels the global marker
2791 S-return starts a rectangular region, if repeated toggles between
2792 rectangle and normal region."
2796 ((null arg) (not CUA-mode))
2798 (t (> (prefix-numeric-value arg) 0))))
2799 (let ((emacs-bindings (or CUA-mode-emacs-bindings (equal arg 'emacs))))
2800 (CUA-mode-init-maps emacs-bindings)
2802 (CUA-mode-bindings 'emacs)
2803 (CUA-mode-bindings 'CUA)
2804 (CUA-mode-bindings 'zxcv)
2805 (CUA-mode-bindings 'shift))
2807 (CUA-mode-bindings extra)))
2808 (setq mark-even-if-inactive t)
2809 (setq highlight-nonselected-windows nil)
2810 (make-variable-buffer-local 'CUA-explicit-region-start)
2811 (make-variable-buffer-local 'CUA-rectangle)
2812 (make-variable-buffer-local 'CUA-rect-overlays)
2813 (make-variable-buffer-local 'CUA-mode-status)
2814 (make-variable-buffer-local 'CUA-undo-list)
2815 (cancel-function-timers 'CUA-tidy-undo-lists)
2818 (add-hook 'pre-command-hook 'CUA-pre-hook)
2819 (add-hook 'post-command-hook 'CUA-post-hook)
2820 (run-with-idle-timer 10 t 'CUA-tidy-undo-lists)
2821 (if (and CUA-mode-use-modeline (not (assoc 'CUA-mode minor-mode-alist)))
2822 (setq minor-mode-alist (cons '(CUA-mode CUA-mode-status) minor-mode-alist))))
2823 (remove-hook 'pre-command-hook 'CUA-pre-hook)
2824 (remove-hook 'post-command-hook 'CUA-post-hook)
2825 (CUA-tidy-undo-lists t))
2826 (setq transient-mark-mode (and CUA-mode
2827 (if CUA-mode-highlight-shift-only
2828 (not CUA-explicit-region-start)
2832(defun CUA-mode-on ()
2838 (setq CUA-debug (not CUA-debug)))
2840;;; Register commands prefix remapping [C-x r ...]
2842(defun CUA-remap-ctl-x-commands (ctl-x-key prefix &optional no-orig)
2843 "Remap ctl-x commands [C-x r ...] onto [PREFIX ...].
2844Unless the optional third arguments NO-ORIG is non-nil, the original
2845binding of [PREFIX] is remapped to [PREFIX PREFIX]."
2846 (let ((org-prefix-cmd (CUA-lookup-key global-map prefix))
2847 (new-prefix-cmd (CUA-lookup-key ctl-x-map ctl-x-key)))
2849 (global-set-key prefix new-prefix-cmd))
2850 (if (and (not no-orig)
2851 new-prefix-cmd org-prefix-cmd
2852 (not (eq new-prefix-cmd org-prefix-cmd)))
2853 (global-set-key (concat prefix prefix) org-prefix-cmd))))
2857(defun CUA-keypad-bind (kp bind)
2858 "Bind the keys in KP list to BIND list in function-key-map.
2859If BIND is 'unbind, all bindings for the keys are removed."
2860 (if (not (boundp 'function-key-map))
2861 (setq function-key-map (make-sparse-keymap)))
2862 (if (eq bind 'unbind)
2864 (define-key function-key-map (vector (car kp)) nil)
2866 (while (and kp bind)
2867 (define-key function-key-map (vector (car kp)) (vector (car bind)))
2873(defun CUA-keypad-mode (mode &optional numlock decimal)
2874 "Set keypad bindings in function-key-map according to MODE.
2875If optional second argument NUMLOCK is non-nil, the NumLock On bindings
2876are changed. Otherwise, the NumLock Off binding are changed.
2879 -------------------------------------------------------------
2880 'prefix Command prefix argument, i.e. M-0 .. M-9 and M--
2881 'S-cursor Bind shifted keypad keys to the shifted cursor movement keys.
2882 'cursor Bind keypad keys to the cursor movement keys.
2883 'numeric Plain numeric, i.e. 0 .. 9 and . (or DECIMAL arg)
2884 'none Removes all bindings for keypad keys in function-key-map.
2886If mode is 'numeric and the optional third argument DECIMAL is non-nil,
2887the decimal key on the keypad i<s mapped to DECIMAL instead of [.]."
2888 (let ((kp (if numlock
2889 '(kp-decimal kp-0 kp-1 kp-2 kp-3 kp-4 kp-5 kp-6 kp-7 kp-8 kp-9)
2890 '(kp-delete kp-insert kp-end kp-down kp-next kp-left
2891 kp-space kp-right kp-home kp-up kp-prior))))
2898 '(?\M-- ?\M-0 ?\M-1 ?\M-2 ?\M-3 ?\M-4 ?\M-5 ?\M-6 ?\M-7 ?\M-8 ?\M-9))
2900 '(delete insert end down next left space right home up prior))
2901 ((eq mode 'S-cursor)
2902 '(S-delete S-insert S-end S-down S-next S-left S-space S-right S-home S-up S-prior))
2904 (cons (or decimal ?.) '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)))
2906 (signal 'error (list "Unknown keypad mode: " mode)))))))