(pc-selection-mode): Call normal-erase-is-backspace-mode instead of
[bpt/emacs.git] / lisp / emulation / pc-select.el
CommitLineData
b50c87ee
KH
1;;; pc-select.el --- emulate mark, cut, copy and paste from Motif
2;;; (or MAC GUI or MS-windoze (bah)) look-and-feel
3;;; including key bindings.
215e89e5 4
e7cec005 5;; Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
215e89e5
RS
6
7;; Author: Michael Staats <michael@thp.Uni-Duisburg.DE>
de986953 8;; Keywords: convenience emulation
215e89e5
RS
9;; Created: 26 Sep 1995
10
11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation; either version 2, or (at your option)
16;; any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
b578f267
EN
24;; along with GNU Emacs; see the file COPYING. If not, write to the
25;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26;; Boston, MA 02111-1307, USA.
215e89e5
RS
27
28;;; Commentary:
b578f267 29
215e89e5
RS
30;; This package emulates the mark, copy, cut and paste look-and-feel of motif
31;; programs (which is the same as the MAC gui and (sorry for that) MS-Windows).
32;; It modifies the keybindings of the cursor keys and the next, prior,
33;; home and end keys. They will modify mark-active.
34;; You can still get the old behaviour of cursor moving with the
35;; control sequences C-f, C-b, etc.
36;; This package uses transient-mark-mode and
37;; delete-selection-mode.
38;;
13f5a20e 39;; In addition to that all key-bindings from the pc-mode are
215e89e5
RS
40;; done here too (as suggested by RMS).
41;;
42;; As I found out after I finished the first version, s-region.el tries
43;; to do the same.... But my code is a little more complete and using
44;; delete-selection-mode is very important for the look-and-feel.
45;; Pete Forman <pete.forman@airgun.wg.waii.com> provided some motif
46;; compliant keybindings which I added. I had to modify them a little
47;; to add the -mark and -nomark functionality of cursor moving.
48;;
49;; Credits:
50;; Many thanks to all who made comments.
51;; Thanks to RMS and Ralf Muschall <prm@rz.uni-jena.de> for criticism.
52;; Kevin Cutts <cutts@ukraine.corp.mot.com> added the beginning-of-buffer
53;; and end-of-buffer functions which I modified a little.
54;; David Biesack <sasdjb@unx.sas.com> suggested some more cleanup.
55;; Thanks to Pete Forman <pete.forman@airgun.wg.waii.com>
56;; for additional motif keybindings.
14dacacd
RS
57;; Thanks to jvromans@squirrel.nl (Johan Vromans) for a bug report
58;; concerning setting of this-command.
83d1d58c 59;; Dan Nicolaescu <done@ece.arizona.ro> suggested suppressing the
20c5a87d 60;; scroll-up/scroll-down error.
b50c87ee 61;; Eli Barzilay (eli@cs.bgu.ac.il) suggested the sexps functions and
13f5a20e 62;; keybindings.
215e89e5
RS
63;;
64;; Ok, some details about the idea of pc-selection-mode:
65;;
66;; o The standard keys for moving around (right, left, up, down, home, end,
67;; prior, next, called "move-keys" from now on) will always de-activate
68;; the mark.
69;; o If you press "Shift" together with the "move-keys", the region
70;; you pass along is activated
71;; o You have the copy, cut and paste functions (as in many other programs)
72;; which will operate on the active region
73;; It was not possible to bind them to C-v, C-x and C-c for obvious
74;; emacs reasons.
75;; They will be bound according to the "old" behaviour to S-delete (cut),
76;; S-insert (paste) and C-insert (copy). These keys do the same in many
77;; other programs.
20c5a87d 78;;
215e89e5 79
20c5a87d 80;;;; Customization:
83d1d58c
RS
81(defgroup pc-select nil
82 "Emulate pc bindings."
83 :prefix "pc-select"
f5f727f8
DN
84 :group 'editing-basics
85 :group 'convenience)
20c5a87d 86
83d1d58c 87(defcustom pc-select-override-scroll-error t
20c5a87d
RS
88 "*Non-nil means don't generate error on scrolling past edge of buffer.
89This variable applies in PC Selection mode only.
90The scroll commands normally generate an error if you try to scroll
91past the top or bottom of the buffer. This is annoying when selecting
92text with these commands. If you set this variable to non-nil, these
83d1d58c
RS
93errors are suppressed."
94 :type 'boolean
95 :group 'pc-select)
215e89e5 96
83d1d58c 97(defcustom pc-select-selection-keys-only nil
b50c87ee
KH
98 "*Non-nil means only bind the basic selection keys when started.
99Other keys that emulate pc-behavior will be untouched.
83d1d58c
RS
100This gives mostly Emacs-like behaviour with only the selection keys enabled."
101 :type 'boolean
102 :group 'pc-select)
b50c87ee 103
83d1d58c
RS
104(defcustom pc-select-meta-moves-sexps nil
105 "*Non-nil means move sexp-wise with Meta key, otherwise move word-wise."
106 :type 'boolean
107 :group 'pc-select)
b50c87ee 108
215e89e5
RS
109;;;;
110;; misc
111;;;;
112
113(provide 'pc-select)
114
115(defun copy-region-as-kill-nomark (beg end)
116 "Save the region as if killed; but don't kill it; deactivate mark.
117If `interprogram-cut-function' is non-nil, also save the text for a window
20c5a87d
RS
118system cut and paste.
119
215e89e5
RS
120Deactivating mark is to avoid confusion with delete-selection-mode
121and transient-mark-mode."
122 (interactive "r")
123 (copy-region-as-kill beg end)
124 (setq mark-active nil)
125 (message "Region saved"))
126
b50c87ee
KH
127(defun exchange-point-and-mark-nomark ()
128 (interactive)
129 (exchange-point-and-mark)
130 (setq mark-active nil))
131
215e89e5
RS
132;;;;
133;; non-interactive
134;;;;
135(defun ensure-mark()
136 ;; make sure mark is active
137 ;; test if it is active, if it isn't, set it and activate it
2a811501 138 (or mark-active (set-mark-command nil)))
215e89e5
RS
139
140;;;;;;;;;;;;;;;;;;;;;;;;;;;
141;;;;; forward and mark
142;;;;;;;;;;;;;;;;;;;;;;;;;;;
143
144(defun forward-char-mark (&optional arg)
145 "Ensure mark is active; move point right ARG characters (left if ARG negative).
146On reaching end of buffer, stop and signal error."
147 (interactive "p")
148 (ensure-mark)
149 (forward-char arg))
150
151(defun forward-word-mark (&optional arg)
152 "Ensure mark is active; move point right ARG words (backward if ARG is negative).
153Normally returns t.
154If an edge of the buffer is reached, point is left there
155and nil is returned."
156 (interactive "p")
157 (ensure-mark)
158 (forward-word arg))
159
20c5a87d
RS
160(defun forward-line-mark (&optional arg)
161 "Ensure mark is active; move cursor vertically down ARG lines."
162 (interactive "p")
163 (ensure-mark)
164 (forward-line arg)
165 (setq this-command 'forward-line)
166)
167
b50c87ee
KH
168(defun forward-sexp-mark (&optional arg)
169 "Ensure mark is active; move forward across one balanced expression (sexp).
170With argument, do it that many times. Negative arg -N means
171move backward across N balanced expressions."
172 (interactive "p")
173 (ensure-mark)
174 (forward-sexp arg))
175
215e89e5
RS
176(defun forward-paragraph-mark (&optional arg)
177 "Ensure mark is active; move forward to end of paragraph.
20c5a87d
RS
178With arg N, do it N times; negative arg -N means move backward N paragraphs.
179
215e89e5 180A line which `paragraph-start' matches either separates paragraphs
14dacacd 181\(if `paragraph-separate' matches it also) or is the first line of a paragraph.
215e89e5
RS
182A paragraph end is the beginning of a line which is not part of the paragraph
183to which the end of the previous line belongs, or the end of the buffer."
184 (interactive "p")
185 (ensure-mark)
186 (forward-paragraph arg))
20c5a87d 187
215e89e5
RS
188(defun next-line-mark (&optional arg)
189 "Ensure mark is active; move cursor vertically down ARG lines.
190If there is no character in the target line exactly under the current column,
191the cursor is positioned after the character in that line which spans this
192column, or at the end of the line if it is not long enough.
193If there is no line in the buffer after this one, behavior depends on the
194value of `next-line-add-newlines'. If non-nil, it inserts a newline character
195to create a line, and moves the cursor to that line. Otherwise it moves the
196cursor to the end of the buffer \(if already at the end of the buffer, an error
20c5a87d
RS
197is signaled).
198
215e89e5
RS
199The command C-x C-n can be used to create
200a semipermanent goal column to which this command always moves.
201Then it does not try to move vertically. This goal column is stored
202in `goal-column', which is nil when there is none."
203 (interactive "p")
204 (ensure-mark)
14dacacd
RS
205 (next-line arg)
206 (setq this-command 'next-line))
215e89e5
RS
207
208(defun end-of-line-mark (&optional arg)
209 "Ensure mark is active; move point to end of current line.
210With argument ARG not nil or 1, move forward ARG - 1 lines first.
211If scan reaches end of buffer, stop there without error."
212 (interactive "p")
213 (ensure-mark)
14dacacd
RS
214 (end-of-line arg)
215 (setq this-command 'end-of-line))
215e89e5 216
20c5a87d
RS
217(defun backward-line-mark (&optional arg)
218 "Ensure mark is active; move cursor vertically up ARG lines."
219 (interactive "p")
220 (ensure-mark)
221 (if (null arg)
222 (setq arg 1))
223 (forward-line (- arg))
224 (setq this-command 'forward-line)
225)
226
215e89e5
RS
227(defun scroll-down-mark (&optional arg)
228 "Ensure mark is active; scroll down ARG lines; or near full screen if no ARG.
229A near full screen is `next-screen-context-lines' less than a full screen.
230Negative ARG means scroll upward.
231When calling from a program, supply a number as argument or nil."
13f5a20e 232 (interactive "P")
215e89e5 233 (ensure-mark)
2a811501
RS
234 (cond (pc-select-override-scroll-error
235 (condition-case nil (scroll-down arg)
236 (beginning-of-buffer (goto-char (point-min)))))
237 (t (scroll-down arg))))
215e89e5
RS
238
239(defun end-of-buffer-mark (&optional arg)
240 "Ensure mark is active; move point to the end of the buffer.
20c5a87d
RS
241With arg N, put point N/10 of the way from the end.
242
215e89e5 243If the buffer is narrowed, this command uses the beginning and size
20c5a87d
RS
244of the accessible part of the buffer.
245
215e89e5
RS
246Don't use this command in Lisp programs!
247\(goto-char \(point-max)) is faster and avoids clobbering the mark."
248 (interactive "P")
249 (ensure-mark)
250 (let ((size (- (point-max) (point-min))))
251 (goto-char (if arg
252 (- (point-max)
253 (if (> size 10000)
254 ;; Avoid overflow for large buffer sizes!
255 (* (prefix-numeric-value arg)
256 (/ size 10))
257 (/ (* size (prefix-numeric-value arg)) 10)))
258 (point-max))))
259 ;; If we went to a place in the middle of the buffer,
260 ;; adjust it to the beginning of a line.
261 (if arg (forward-line 1)
262 ;; If the end of the buffer is not already on the screen,
263 ;; then scroll specially to put it near, but not at, the bottom.
264 (if (let ((old-point (point)))
265 (save-excursion
266 (goto-char (window-start))
267 (vertical-motion (window-height))
268 (< (point) old-point)))
269 (progn
270 (overlay-recenter (point))
271 (recenter -3)))))
272
273;;;;;;;;;
274;;;;; no mark
275;;;;;;;;;
276
277(defun forward-char-nomark (&optional arg)
278 "Deactivate mark; move point right ARG characters \(left if ARG negative).
279On reaching end of buffer, stop and signal error."
280 (interactive "p")
281 (setq mark-active nil)
282 (forward-char arg))
283
284(defun forward-word-nomark (&optional arg)
285 "Deactivate mark; move point right ARG words \(backward if ARG is negative).
286Normally returns t.
287If an edge of the buffer is reached, point is left there
288and nil is returned."
289 (interactive "p")
290 (setq mark-active nil)
291 (forward-word arg))
292
20c5a87d
RS
293(defun forward-line-nomark (&optional arg)
294 "Deactivate mark; move cursor vertically down ARG lines."
295 (interactive "p")
296 (setq mark-active nil)
297 (forward-line arg)
298 (setq this-command 'forward-line)
299)
300
b50c87ee
KH
301(defun forward-sexp-nomark (&optional arg)
302 "Deactivate mark; move forward across one balanced expression (sexp).
303With argument, do it that many times. Negative arg -N means
304move backward across N balanced expressions."
305 (interactive "p")
306 (setq mark-active nil)
307 (forward-sexp arg))
308
215e89e5
RS
309(defun forward-paragraph-nomark (&optional arg)
310 "Deactivate mark; move forward to end of paragraph.
20c5a87d
RS
311With arg N, do it N times; negative arg -N means move backward N paragraphs.
312
215e89e5 313A line which `paragraph-start' matches either separates paragraphs
14dacacd 314\(if `paragraph-separate' matches it also) or is the first line of a paragraph.
215e89e5
RS
315A paragraph end is the beginning of a line which is not part of the paragraph
316to which the end of the previous line belongs, or the end of the buffer."
317 (interactive "p")
318 (setq mark-active nil)
319 (forward-paragraph arg))
320
321(defun next-line-nomark (&optional arg)
322 "Deactivate mark; move cursor vertically down ARG lines.
323If there is no character in the target line exactly under the current column,
324the cursor is positioned after the character in that line which spans this
325column, or at the end of the line if it is not long enough.
326If there is no line in the buffer after this one, behavior depends on the
327value of `next-line-add-newlines'. If non-nil, it inserts a newline character
328to create a line, and moves the cursor to that line. Otherwise it moves the
329cursor to the end of the buffer (if already at the end of the buffer, an error
20c5a87d
RS
330is signaled).
331
215e89e5
RS
332The command C-x C-n can be used to create
333a semipermanent goal column to which this command always moves.
334Then it does not try to move vertically. This goal column is stored
335in `goal-column', which is nil when there is none."
336 (interactive "p")
337 (setq mark-active nil)
14dacacd
RS
338 (next-line arg)
339 (setq this-command 'next-line))
215e89e5
RS
340
341(defun end-of-line-nomark (&optional arg)
342 "Deactivate mark; move point to end of current line.
343With argument ARG not nil or 1, move forward ARG - 1 lines first.
344If scan reaches end of buffer, stop there without error."
345 (interactive "p")
346 (setq mark-active nil)
14dacacd
RS
347 (end-of-line arg)
348 (setq this-command 'end-of-line))
215e89e5 349
20c5a87d
RS
350(defun backward-line-nomark (&optional arg)
351 "Deactivate mark; move cursor vertically up ARG lines."
352 (interactive "p")
353 (setq mark-active nil)
354 (if (null arg)
355 (setq arg 1))
356 (forward-line (- arg))
357 (setq this-command 'forward-line)
358)
359
215e89e5
RS
360(defun scroll-down-nomark (&optional arg)
361 "Deactivate mark; scroll down ARG lines; or near full screen if no ARG.
362A near full screen is `next-screen-context-lines' less than a full screen.
363Negative ARG means scroll upward.
364When calling from a program, supply a number as argument or nil."
365 (interactive "P")
366 (setq mark-active nil)
2a811501
RS
367 (cond (pc-select-override-scroll-error
368 (condition-case nil (scroll-down arg)
369 (beginning-of-buffer (goto-char (point-min)))))
370 (t (scroll-down arg))))
215e89e5
RS
371
372(defun end-of-buffer-nomark (&optional arg)
373 "Deactivate mark; move point to the end of the buffer.
20c5a87d
RS
374With arg N, put point N/10 of the way from the end.
375
215e89e5 376If the buffer is narrowed, this command uses the beginning and size
20c5a87d
RS
377of the accessible part of the buffer.
378
215e89e5 379Don't use this command in Lisp programs!
14dacacd 380\(goto-char (point-max)) is faster and avoids clobbering the mark."
215e89e5
RS
381 (interactive "P")
382 (setq mark-active nil)
383 (let ((size (- (point-max) (point-min))))
384 (goto-char (if arg
385 (- (point-max)
386 (if (> size 10000)
387 ;; Avoid overflow for large buffer sizes!
388 (* (prefix-numeric-value arg)
389 (/ size 10))
390 (/ (* size (prefix-numeric-value arg)) 10)))
391 (point-max))))
392 ;; If we went to a place in the middle of the buffer,
393 ;; adjust it to the beginning of a line.
394 (if arg (forward-line 1)
395 ;; If the end of the buffer is not already on the screen,
396 ;; then scroll specially to put it near, but not at, the bottom.
397 (if (let ((old-point (point)))
398 (save-excursion
399 (goto-char (window-start))
400 (vertical-motion (window-height))
401 (< (point) old-point)))
402 (progn
403 (overlay-recenter (point))
404 (recenter -3)))))
405
406
407;;;;;;;;;;;;;;;;;;;;
408;;;;;; backwards and mark
409;;;;;;;;;;;;;;;;;;;;
410
411(defun backward-char-mark (&optional arg)
412"Ensure mark is active; move point left ARG characters (right if ARG negative).
413On attempt to pass beginning or end of buffer, stop and signal error."
414 (interactive "p")
415 (ensure-mark)
416 (backward-char arg))
417
418(defun backward-word-mark (&optional arg)
419 "Ensure mark is active; move backward until encountering the end of a word.
420With argument, do this that many times."
421 (interactive "p")
422 (ensure-mark)
423 (backward-word arg))
424
b50c87ee
KH
425(defun backward-sexp-mark (&optional arg)
426 "Ensure mark is active; move backward across one balanced expression (sexp).
427With argument, do it that many times. Negative arg -N means
428move forward across N balanced expressions."
429 (interactive "p")
430 (ensure-mark)
431 (backward-sexp arg))
432
215e89e5
RS
433(defun backward-paragraph-mark (&optional arg)
434 "Ensure mark is active; move backward to start of paragraph.
20c5a87d
RS
435With arg N, do it N times; negative arg -N means move forward N paragraphs.
436
215e89e5
RS
437A paragraph start is the beginning of a line which is a
438`first-line-of-paragraph' or which is ordinary text and follows a
439paragraph-separating line; except: if the first real line of a
440paragraph is preceded by a blank line, the paragraph starts at that
20c5a87d
RS
441blank line.
442
215e89e5
RS
443See `forward-paragraph' for more information."
444 (interactive "p")
445 (ensure-mark)
446 (backward-paragraph arg))
447
448(defun previous-line-mark (&optional arg)
449 "Ensure mark is active; move cursor vertically up ARG lines.
450If there is no character in the target line exactly over the current column,
451the cursor is positioned after the character in that line which spans this
20c5a87d
RS
452column, or at the end of the line if it is not long enough.
453
215e89e5
RS
454The command C-x C-n can be used to create
455a semipermanent goal column to which this command always moves.
20c5a87d
RS
456Then it does not try to move vertically.
457
215e89e5
RS
458If you are thinking of using this in a Lisp program, consider using
459`forward-line' with a negative argument instead. It is usually easier
460to use and more reliable (no dependence on goal column, etc.)."
461 (interactive "p")
462 (ensure-mark)
14dacacd
RS
463 (previous-line arg)
464 (setq this-command 'previous-line))
215e89e5
RS
465
466(defun beginning-of-line-mark (&optional arg)
467 "Ensure mark is active; move point to beginning of current line.
468With argument ARG not nil or 1, move forward ARG - 1 lines first.
469If scan reaches end of buffer, stop there without error."
470 (interactive "p")
471 (ensure-mark)
472 (beginning-of-line arg))
473
474
475(defun scroll-up-mark (&optional arg)
476"Ensure mark is active; scroll upward ARG lines; or near full screen if no ARG.
477A near full screen is `next-screen-context-lines' less than a full screen.
478Negative ARG means scroll downward.
479When calling from a program, supply a number as argument or nil."
480 (interactive "P")
481 (ensure-mark)
2a811501
RS
482 (cond (pc-select-override-scroll-error
483 (condition-case nil (scroll-up arg)
484 (end-of-buffer (goto-char (point-max)))))
485 (t (scroll-up arg))))
215e89e5
RS
486
487(defun beginning-of-buffer-mark (&optional arg)
488 "Ensure mark is active; move point to the beginning of the buffer.
20c5a87d
RS
489With arg N, put point N/10 of the way from the beginning.
490
215e89e5 491If the buffer is narrowed, this command uses the beginning and size
20c5a87d
RS
492of the accessible part of the buffer.
493
215e89e5
RS
494Don't use this command in Lisp programs!
495\(goto-char (p\oint-min)) is faster and avoids clobbering the mark."
496 (interactive "P")
13f5a20e 497 (ensure-mark)
215e89e5
RS
498 (let ((size (- (point-max) (point-min))))
499 (goto-char (if arg
500 (+ (point-min)
501 (if (> size 10000)
502 ;; Avoid overflow for large buffer sizes!
503 (* (prefix-numeric-value arg)
504 (/ size 10))
505 (/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
506 (point-min))))
507 (if arg (forward-line 1)))
508
509;;;;;;;;
510;;; no mark
511;;;;;;;;
512
513(defun backward-char-nomark (&optional arg)
514 "Deactivate mark; move point left ARG characters (right if ARG negative).
515On attempt to pass beginning or end of buffer, stop and signal error."
516 (interactive "p")
517 (setq mark-active nil)
518 (backward-char arg))
519
520(defun backward-word-nomark (&optional arg)
521 "Deactivate mark; move backward until encountering the end of a word.
522With argument, do this that many times."
523 (interactive "p")
524 (setq mark-active nil)
525 (backward-word arg))
526
b50c87ee
KH
527(defun backward-sexp-nomark (&optional arg)
528 "Deactivate mark; move backward across one balanced expression (sexp).
529With argument, do it that many times. Negative arg -N means
530move forward across N balanced expressions."
531 (interactive "p")
532 (setq mark-active nil)
533 (backward-sexp arg))
534
215e89e5
RS
535(defun backward-paragraph-nomark (&optional arg)
536 "Deactivate mark; move backward to start of paragraph.
20c5a87d
RS
537With arg N, do it N times; negative arg -N means move forward N paragraphs.
538
215e89e5
RS
539A paragraph start is the beginning of a line which is a
540`first-line-of-paragraph' or which is ordinary text and follows a
541paragraph-separating line; except: if the first real line of a
542paragraph is preceded by a blank line, the paragraph starts at that
20c5a87d
RS
543blank line.
544
215e89e5
RS
545See `forward-paragraph' for more information."
546 (interactive "p")
547 (setq mark-active nil)
548 (backward-paragraph arg))
549
550(defun previous-line-nomark (&optional arg)
551 "Deactivate mark; move cursor vertically up ARG lines.
552If there is no character in the target line exactly over the current column,
553the cursor is positioned after the character in that line which spans this
20c5a87d
RS
554column, or at the end of the line if it is not long enough.
555
215e89e5
RS
556The command C-x C-n can be used to create
557a semipermanent goal column to which this command always moves.
558Then it does not try to move vertically."
559 (interactive "p")
560 (setq mark-active nil)
14dacacd
RS
561 (previous-line arg)
562 (setq this-command 'previous-line))
215e89e5
RS
563
564(defun beginning-of-line-nomark (&optional arg)
565 "Deactivate mark; move point to beginning of current line.
566With argument ARG not nil or 1, move forward ARG - 1 lines first.
567If scan reaches end of buffer, stop there without error."
568 (interactive "p")
569 (setq mark-active nil)
570 (beginning-of-line arg))
571
572(defun scroll-up-nomark (&optional arg)
573 "Deactivate mark; scroll upward ARG lines; or near full screen if no ARG.
574A near full screen is `next-screen-context-lines' less than a full screen.
575Negative ARG means scroll downward.
576When calling from a program, supply a number as argument or nil."
577 (interactive "P")
578 (setq mark-active nil)
2a811501
RS
579 (cond (pc-select-override-scroll-error
580 (condition-case nil (scroll-up arg)
581 (end-of-buffer (goto-char (point-max)))))
582 (t (scroll-up arg))))
215e89e5
RS
583
584(defun beginning-of-buffer-nomark (&optional arg)
585 "Deactivate mark; move point to the beginning of the buffer.
20c5a87d
RS
586With arg N, put point N/10 of the way from the beginning.
587
215e89e5 588If the buffer is narrowed, this command uses the beginning and size
20c5a87d
RS
589of the accessible part of the buffer.
590
215e89e5 591Don't use this command in Lisp programs!
14dacacd 592\(goto-char (point-min)) is faster and avoids clobbering the mark."
215e89e5
RS
593 (interactive "P")
594 (setq mark-active nil)
595 (let ((size (- (point-max) (point-min))))
596 (goto-char (if arg
597 (+ (point-min)
598 (if (> size 10000)
599 ;; Avoid overflow for large buffer sizes!
600 (* (prefix-numeric-value arg)
601 (/ size 10))
602 (/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
603 (point-min))))
604 (if arg (forward-line 1)))
605
3eeb7b9f 606;;;###autoload
215e89e5 607(defun pc-selection-mode ()
20c5a87d
RS
608 "Change mark behaviour to emulate Motif, MAC or MS-Windows cut and paste style.
609
610This mode enables Delete Selection mode and Transient Mark mode.
611
612The arrow keys (and others) are bound to new functions
613which modify the status of the mark.
614
615The ordinary arrow keys disable the mark.
616The shift-arrow keys move, leaving the mark behind.
617
618C-LEFT and C-RIGHT move back or forward one word, disabling the mark.
619S-C-LEFT and S-C-RIGHT move back or forward one word, leaving the mark behind.
620
b50c87ee
KH
621M-LEFT and M-RIGHT move back or forward one word or sexp, disabling the mark.
622S-M-LEFT and S-M-RIGHT move back or forward one word or sexp, leaving the mark
623behind. To control wether these keys move word-wise or sexp-wise set the
624variable pc-select-meta-moves-sexps after loading pc-select.el but before
625turning pc-selection-mode on.
626
20c5a87d
RS
627C-DOWN and C-UP move back or forward a paragraph, disabling the mark.
628S-C-DOWN and S-C-UP move back or forward a paragraph, leaving the mark behind.
629
630HOME moves to beginning of line, disabling the mark.
631S-HOME moves to beginning of line, leaving the mark behind.
632With Ctrl or Meta, these keys move to beginning of buffer instead.
633
634END moves to end of line, disabling the mark.
635S-END moves to end of line, leaving the mark behind.
636With Ctrl or Meta, these keys move to end of buffer instead.
637
638PRIOR or PAGE-UP scrolls and disables the mark.
639S-PRIOR or S-PAGE-UP scrolls and leaves the mark behind.
640
641S-DELETE kills the region (`kill-region').
642S-INSERT yanks text from the kill ring (`yank').
643C-INSERT copies the region into the kill ring (`copy-region-as-kill').
644
b50c87ee
KH
645In addition, certain other PC bindings are imitated (to avoid this, set
646the variable pc-select-selection-keys-only to t after loading pc-select.el
647but before calling pc-selection-mode):
20c5a87d
RS
648
649 F6 other-window
650 DELETE delete-char
651 C-DELETE kill-line
652 M-DELETE kill-word
653 C-M-DELETE kill-sexp
654 C-BACKSPACE backward-kill-word
655 M-BACKSPACE undo"
656
215e89e5
RS
657 (interactive)
658 ;;
659 ;; keybindings
660 ;;
661
662 ;; This is to avoid confusion with the delete-selection-mode
663 ;; On simple displays you can't see that a region is active and
b50c87ee
KH
664 ;; will be deleted on the next keypress. IMHO especially for
665 ;; copy-region-as-kill this is confusing.
666 ;; The same goes for exchange-point-and-mark
13f5a20e
SS
667 (define-key global-map "\M-w" 'copy-region-as-kill-nomark)
668 (define-key global-map "\C-x\C-x" 'exchange-point-and-mark-nomark)
a7acbbe4 669 ;; The following keybindings are for standard ISO keyboards
215e89e5
RS
670 ;; as they are used with IBM compatible PCs, IBM RS/6000,
671 ;; MACs, many X-Stations and probably more
672 (define-key global-map [S-right] 'forward-char-mark)
673 (define-key global-map [right] 'forward-char-nomark)
674 (define-key global-map [C-S-right] 'forward-word-mark)
675 (define-key global-map [C-right] 'forward-word-nomark)
b50c87ee
KH
676 (define-key global-map [S-left] 'backward-char-mark)
677 (define-key global-map [left] 'backward-char-nomark)
678 (define-key global-map [C-S-left] 'backward-word-mark)
679 (define-key global-map [C-left] 'backward-word-nomark)
680 (cond (pc-select-meta-moves-sexps
681 (define-key global-map [M-S-right] 'forward-sexp-mark)
682 (define-key global-map [M-right] 'forward-sexp-nomark)
683 (define-key global-map [M-S-left] 'backward-sexp-mark)
684 (define-key global-map [M-left] 'backward-sexp-nomark))
685 (t
686 (define-key global-map [M-S-right] 'forward-word-mark)
687 (define-key global-map [M-right] 'forward-word-nomark)
688 (define-key global-map [M-S-left] 'backward-word-mark)
689 (define-key global-map [M-left] 'backward-word-nomark)))
215e89e5
RS
690
691 (define-key global-map [S-down] 'next-line-mark)
692 (define-key global-map [down] 'next-line-nomark)
693
694 (define-key global-map [S-end] 'end-of-line-mark)
695 (define-key global-map [end] 'end-of-line-nomark)
696 (global-set-key [S-C-end] 'end-of-buffer-mark)
697 (global-set-key [C-end] 'end-of-buffer-nomark)
14dacacd
RS
698 (global-set-key [S-M-end] 'end-of-buffer-mark)
699 (global-set-key [M-end] 'end-of-buffer-nomark)
215e89e5
RS
700
701 (define-key global-map [S-next] 'scroll-up-mark)
702 (define-key global-map [next] 'scroll-up-nomark)
703
215e89e5
RS
704 (define-key global-map [S-up] 'previous-line-mark)
705 (define-key global-map [up] 'previous-line-nomark)
706
707 (define-key global-map [S-home] 'beginning-of-line-mark)
708 (define-key global-map [home] 'beginning-of-line-nomark)
709 (global-set-key [S-C-home] 'beginning-of-buffer-mark)
710 (global-set-key [C-home] 'beginning-of-buffer-nomark)
14dacacd
RS
711 (global-set-key [S-M-home] 'beginning-of-buffer-mark)
712 (global-set-key [M-home] 'beginning-of-buffer-nomark)
215e89e5 713
20c5a87d
RS
714 (define-key global-map [M-S-down] 'forward-line-mark)
715 (define-key global-map [M-down] 'forward-line-nomark)
716 (define-key global-map [M-S-up] 'backward-line-mark)
717 (define-key global-map [M-up] 'backward-line-nomark)
718
b50c87ee
KH
719 (define-key global-map [S-prior] 'scroll-down-mark)
720 (define-key global-map [prior] 'scroll-down-nomark)
721
722 ;; Next four lines are from Pete Forman.
723 (global-set-key [C-down] 'forward-paragraph-nomark) ; KNextPara cDn
724 (global-set-key [C-up] 'backward-paragraph-nomark) ; KPrevPara cUp
215e89e5 725 (global-set-key [S-C-down] 'forward-paragraph-mark)
13f5a20e 726 (global-set-key [S-C-up] 'backward-paragraph-mark)
215e89e5 727
b50c87ee 728 (or pc-select-selection-keys-only
13f5a20e 729 (progn
58e4f61d
EZ
730 ;; We are behaving like normal-erase-is-backspace-mode, so
731 ;; say so explicitly.
732 (setq-default normal-erase-is-backspace t)
733 (normal-erase-is-backspace-mode 1)
b50c87ee
KH
734 (define-key global-map [S-insert] 'yank)
735 (define-key global-map [C-insert] 'copy-region-as-kill)
736 (define-key global-map [S-delete] 'kill-region)
737
738 ;; The following bindings are useful on Sun Type 3 keyboards
739 ;; They implement the Get-Delete-Put (copy-cut-paste)
740 ;; functions from sunview on the L6, L8 and L10 keys
13f5a20e 741 ;; Sam Steingold <sds@gnu.org> says that f16 is copy and f18 is paste.
b50c87ee
KH
742 (define-key global-map [f16] 'copy-region-as-kill)
743 (define-key global-map [f18] 'yank)
744 (define-key global-map [f20] 'kill-region)
745
746 ;; The following bindings are from Pete Forman.
747 (global-set-key [f6] 'other-window) ; KNextPane F6
b50c87ee 748 (global-set-key [C-delete] 'kill-line) ; KEraseEndLine cDel
e7cec005 749 (global-set-key "\M-\d" 'undo) ; KUndo aBS
b50c87ee 750
58e4f61d 751 ;; The following binding is taken from pc-mode.el
b50c87ee 752 ;; as suggested by RMS.
58e4f61d 753 ;; I only used the one that is not covered above.
b50c87ee 754 (global-set-key [C-M-delete] 'kill-sexp)
b50c87ee
KH
755 ;; Next line proposed by Eli Barzilay
756 (global-set-key [C-escape] 'electric-buffer-list)))
13f5a20e 757 ;;
215e89e5
RS
758 ;; setup
759 ;;
b50c87ee
KH
760 ;; Next line proposed by Eli Barzilay
761 (setq highlight-nonselected-windows nil)
215e89e5
RS
762 (setq transient-mark-mode t)
763 (setq mark-even-if-inactive t)
20c5a87d 764 (delete-selection-mode 1)
2a811501 765)
83d1d58c
RS
766
767;;;###autoload
768(defcustom pc-selection-mode nil
769 "Toggle PC Selection mode.
770Change mark behaviour to emulate Motif, MAC or MS-Windows cut and paste style,
771and cursor movement commands.
772This mode enables Delete Selection mode and Transient Mark mode.
773You must modify via \\[customize] for this variable to have an effect."
774 :set (lambda (symbol value)
775 (if value (pc-selection-mode)))
776 :type 'boolean
777 :group 'pc-select
778 :require 'pc-select)
779
215e89e5 780;;; pc-select.el ends here