(term-regexp-arg): No need to bind
[bpt/emacs.git] / lisp / simple.el
CommitLineData
c88ab9ce
ER
1;;; simple.el --- basic editing commands for Emacs
2
69c1dd37
RS
3;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 1997
4;; Free Software Foundation, Inc.
2076c87c
JB
5
6;; This file is part of GNU Emacs.
7
8;; GNU Emacs is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
3a801d0c 10;; the Free Software Foundation; either version 2, or (at your option)
2076c87c
JB
11;; any later version.
12
13;; GNU Emacs is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
b578f267
EN
19;; along with GNU Emacs; see the file COPYING. If not, write to the
20;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
2076c87c 22
d9ecc911
ER
23;;; Commentary:
24
25;; A grab-bag of basic Emacs commands not specifically related to some
26;; major mode or to file-handling.
27
3a801d0c 28;;; Code:
2076c87c 29
69c1dd37
RS
30(defgroup killing nil
31 "Killing and yanking commands"
32 :group 'editing)
33
34(defgroup fill-comments nil
35 "Indenting and filling of comments."
36 :prefix "comment-"
37 :group 'fill)
38
39(defgroup paren-matching nil
40 "Highlight (un)matching of parens and expressions."
69c1dd37
RS
41 :group 'matching)
42
43
30bb9754 44(defun newline (&optional arg)
d133d835 45 "Insert a newline, and move to left margin of the new line if it's blank.
30bb9754
BG
46The newline is marked with the text-property `hard'.
47With arg, insert that many newlines.
48In Auto Fill mode, if no numeric arg, break the preceding line if it's long."
49 (interactive "*P")
4c4cbf11 50 (barf-if-buffer-read-only)
30bb9754
BG
51 ;; Inserting a newline at the end of a line produces better redisplay in
52 ;; try_window_id than inserting at the beginning of a line, and the textual
53 ;; result is the same. So, if we're at beginning of line, pretend to be at
54 ;; the end of the previous line.
55 (let ((flag (and (not (bobp))
56 (bolp)
1cd24721
RS
57 ;; Make sure no functions want to be told about
58 ;; the range of the changes.
59 (not after-change-function)
60 (not before-change-function)
61 (not after-change-functions)
62 (not before-change-functions)
fd977703
RS
63 ;; Make sure there are no markers here.
64 (not (buffer-has-markers-at (1- (point))))
1cd24721
RS
65 ;; Make sure no text properties want to know
66 ;; where the change was.
67 (not (get-char-property (1- (point)) 'modification-hooks))
68 (not (get-char-property (1- (point)) 'insert-behind-hooks))
69 (or (eobp)
70 (not (get-char-property (point) 'insert-in-front-hooks)))
31a5333f
MB
71 ;; Make sure the newline before point isn't intangible.
72 (not (get-char-property (1- (point)) 'intangible))
73 ;; Make sure the newline before point isn't read-only.
74 (not (get-char-property (1- (point)) 'read-only))
75 ;; Make sure the newline before point isn't invisible.
76 (not (get-char-property (1- (point)) 'invisible))
77 ;; Make sure the newline before point has the same
78 ;; properties as the char before it (if any).
30bb9754 79 (< (or (previous-property-change (point)) -2)
d133d835
RS
80 (- (point) 2))))
81 (was-page-start (and (bolp)
82 (looking-at page-delimiter)))
83 (beforepos (point)))
30bb9754
BG
84 (if flag (backward-char 1))
85 ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
86 ;; Set last-command-char to tell self-insert what to insert.
87 (let ((last-command-char ?\n)
88 ;; Don't auto-fill if we have a numeric argument.
3954fff9
RS
89 ;; Also not if flag is true (it would fill wrong line);
90 ;; there is no need to since we're at BOL.
91 (auto-fill-function (if (or arg flag) nil auto-fill-function)))
4cc9d0dc
RS
92 (unwind-protect
93 (self-insert-command (prefix-numeric-value arg))
94 ;; If we get an error in self-insert-command, put point at right place.
95 (if flag (forward-char 1))))
96 ;; If we did *not* get an error, cancel that forward-char.
97 (if flag (backward-char 1))
30bb9754
BG
98 ;; Mark the newline(s) `hard'.
99 (if use-hard-newlines
55741b46
RS
100 (set-hard-newline-properties
101 (- (point) (if arg (prefix-numeric-value arg) 1)) (point)))
d133d835
RS
102 ;; If the newline leaves the previous line blank,
103 ;; and we have a left margin, delete that from the blank line.
104 (or flag
105 (save-excursion
106 (goto-char beforepos)
107 (beginning-of-line)
108 (and (looking-at "[ \t]$")
109 (> (current-left-margin) 0)
110 (delete-region (point) (progn (end-of-line) (point))))))
111 (if flag (forward-char 1))
112 ;; Indent the line after the newline, except in one case:
113 ;; when we added the newline at the beginning of a line
114 ;; which starts a page.
115 (or was-page-start
116 (move-to-left-margin nil t)))
30bb9754
BG
117 nil)
118
55741b46
RS
119(defun set-hard-newline-properties (from to)
120 (let ((sticky (get-text-property from 'rear-nonsticky)))
121 (put-text-property from to 'hard 't)
122 ;; If rear-nonsticky is not "t", add 'hard to rear-nonsticky list
123 (if (and (listp sticky) (not (memq 'hard sticky)))
124 (put-text-property from (point) 'rear-nonsticky
125 (cons 'hard sticky)))))
126
2076c87c 127(defun open-line (arg)
ff1fbe3e 128 "Insert a newline and leave point before it.
3db1e3b5 129If there is a fill prefix and/or a left-margin, insert them on the new line
d133d835 130if the line would have been blank.
616ed245 131With arg N, insert N newlines."
2076c87c 132 (interactive "*p")
616ed245 133 (let* ((do-fill-prefix (and fill-prefix (bolp)))
3db1e3b5 134 (do-left-margin (and (bolp) (> (current-left-margin) 0)))
28191e20 135 (loc (point)))
d133d835
RS
136 (newline arg)
137 (goto-char loc)
28191e20 138 (while (> arg 0)
d133d835
RS
139 (cond ((bolp)
140 (if do-left-margin (indent-to (current-left-margin)))
141 (if do-fill-prefix (insert-and-inherit fill-prefix))))
142 (forward-line 1)
28191e20 143 (setq arg (1- arg)))
d133d835
RS
144 (goto-char loc)
145 (end-of-line)))
2076c87c
JB
146
147(defun split-line ()
148 "Split current line, moving portion beyond point vertically down."
149 (interactive "*")
150 (skip-chars-forward " \t")
151 (let ((col (current-column))
152 (pos (point)))
28191e20 153 (newline 1)
2076c87c
JB
154 (indent-to col 0)
155 (goto-char pos)))
156
157(defun quoted-insert (arg)
158 "Read next input character and insert it.
ff1fbe3e 159This is useful for inserting control characters.
37fb0200
RS
160
161If the first character you type after this command is an octal digit,
162you should type a sequence of octal digits which specify a character code.
037a2961 163Any nondigit terminates the sequence. If the terminator is a RET,
37fb0200 164it is discarded; any other terminator is used itself as input.
037a2961
RS
165The variable `read-quoted-char-radix' specifies the radix for this feature;
166set it to 10 or 16 to use decimal or hex instead of octal.
b6a22db0
JB
167
168In overwrite mode, this function inserts the character anyway, and
169does not handle octal digits specially. This means that if you use
170overwrite as your normal editing mode, you can use this function to
171insert characters when necessary.
172
173In binary overwrite mode, this function does overwrite, and octal
37fb0200
RS
174digits are interpreted as a character code. This is intended to be
175useful for editing binary files."
2076c87c 176 (interactive "*p")
b6a22db0
JB
177 (let ((char (if (or (not overwrite-mode)
178 (eq overwrite-mode 'overwrite-mode-binary))
179 (read-quoted-char)
180 (read-char))))
4f588196
RS
181 ;; Assume character codes 0200 - 0377 stand for
182 ;; European characters in Latin-1, and convert them
183 ;; to Emacs characters.
184 (and enable-multibyte-characters
185 (>= char ?\200)
53efb707 186 (<= char ?\377)
16d8aee1 187 (setq char (+ nonascii-insert-offset char)))
ec321cad
RS
188 (if (> arg 0)
189 (if (eq overwrite-mode 'overwrite-mode-binary)
190 (delete-char arg)))
191 (while (> arg 0)
192 (insert-and-inherit char)
193 (setq arg (1- arg)))))
2076c87c
JB
194
195(defun delete-indentation (&optional arg)
196 "Join this line to previous and fix up whitespace at join.
ccc58657 197If there is a fill prefix, delete it from the beginning of this line.
2076c87c
JB
198With argument, join this line to following line."
199 (interactive "*P")
200 (beginning-of-line)
201 (if arg (forward-line 1))
202 (if (eq (preceding-char) ?\n)
203 (progn
204 (delete-region (point) (1- (point)))
ccc58657
RS
205 ;; If the second line started with the fill prefix,
206 ;; delete the prefix.
207 (if (and fill-prefix
01b8e020 208 (<= (+ (point) (length fill-prefix)) (point-max))
ccc58657
RS
209 (string= fill-prefix
210 (buffer-substring (point)
211 (+ (point) (length fill-prefix)))))
212 (delete-region (point) (+ (point) (length fill-prefix))))
2076c87c
JB
213 (fixup-whitespace))))
214
215(defun fixup-whitespace ()
216 "Fixup white space between objects around point.
217Leave one space or none, according to the context."
218 (interactive "*")
219 (save-excursion
220 (delete-horizontal-space)
221 (if (or (looking-at "^\\|\\s)")
222 (save-excursion (forward-char -1)
223 (looking-at "$\\|\\s(\\|\\s'")))
224 nil
225 (insert ?\ ))))
226
227(defun delete-horizontal-space ()
228 "Delete all spaces and tabs around point."
229 (interactive "*")
230 (skip-chars-backward " \t")
231 (delete-region (point) (progn (skip-chars-forward " \t") (point))))
232
233(defun just-one-space ()
234 "Delete all spaces and tabs around point, leaving one space."
235 (interactive "*")
236 (skip-chars-backward " \t")
237 (if (= (following-char) ? )
238 (forward-char 1)
239 (insert ? ))
240 (delete-region (point) (progn (skip-chars-forward " \t") (point))))
241
242(defun delete-blank-lines ()
243 "On blank line, delete all surrounding blank lines, leaving just one.
244On isolated blank line, delete that one.
6d30d416 245On nonblank line, delete any immediately following blank lines."
2076c87c
JB
246 (interactive "*")
247 (let (thisblank singleblank)
248 (save-excursion
249 (beginning-of-line)
250 (setq thisblank (looking-at "[ \t]*$"))
70e14c01 251 ;; Set singleblank if there is just one blank line here.
2076c87c
JB
252 (setq singleblank
253 (and thisblank
254 (not (looking-at "[ \t]*\n[ \t]*$"))
255 (or (bobp)
256 (progn (forward-line -1)
257 (not (looking-at "[ \t]*$")))))))
70e14c01 258 ;; Delete preceding blank lines, and this one too if it's the only one.
2076c87c
JB
259 (if thisblank
260 (progn
261 (beginning-of-line)
262 (if singleblank (forward-line 1))
263 (delete-region (point)
264 (if (re-search-backward "[^ \t\n]" nil t)
265 (progn (forward-line 1) (point))
266 (point-min)))))
70e14c01
JB
267 ;; Delete following blank lines, unless the current line is blank
268 ;; and there are no following blank lines.
2076c87c
JB
269 (if (not (and thisblank singleblank))
270 (save-excursion
271 (end-of-line)
272 (forward-line 1)
273 (delete-region (point)
274 (if (re-search-forward "[^ \t\n]" nil t)
275 (progn (beginning-of-line) (point))
70e14c01
JB
276 (point-max)))))
277 ;; Handle the special case where point is followed by newline and eob.
278 ;; Delete the line, leaving point at eob.
279 (if (looking-at "^[ \t]*\n\\'")
280 (delete-region (point) (point-max)))))
2076c87c
JB
281
282(defun back-to-indentation ()
283 "Move point to the first non-whitespace character on this line."
284 (interactive)
285 (beginning-of-line 1)
286 (skip-chars-forward " \t"))
287
288(defun newline-and-indent ()
289 "Insert a newline, then indent according to major mode.
ff1fbe3e 290Indentation is done using the value of `indent-line-function'.
2076c87c 291In programming language modes, this is the same as TAB.
ff1fbe3e 292In some text modes, where TAB inserts a tab, this command indents to the
eed5698b 293column specified by the function `current-left-margin'."
2076c87c
JB
294 (interactive "*")
295 (delete-region (point) (progn (skip-chars-backward " \t") (point)))
46947372 296 (newline)
2076c87c
JB
297 (indent-according-to-mode))
298
299(defun reindent-then-newline-and-indent ()
300 "Reindent current line, insert newline, then indent the new line.
301Indentation of both lines is done according to the current major mode,
ff1fbe3e 302which means calling the current value of `indent-line-function'.
2076c87c
JB
303In programming language modes, this is the same as TAB.
304In some text modes, where TAB inserts a tab, this indents to the
eed5698b 305column specified by the function `current-left-margin'."
2076c87c
JB
306 (interactive "*")
307 (save-excursion
308 (delete-region (point) (progn (skip-chars-backward " \t") (point)))
309 (indent-according-to-mode))
46947372 310 (newline)
2076c87c
JB
311 (indent-according-to-mode))
312
dff7d67f
RS
313;; Internal subroutine of delete-char
314(defun kill-forward-chars (arg)
315 (if (listp arg) (setq arg (car arg)))
316 (if (eq arg '-) (setq arg -1))
d5d99b80 317 (kill-region (point) (forward-point arg)))
dff7d67f
RS
318
319;; Internal subroutine of backward-delete-char
320(defun kill-backward-chars (arg)
321 (if (listp arg) (setq arg (car arg)))
322 (if (eq arg '-) (setq arg -1))
d5d99b80 323 (kill-region (point) (forward-point (- arg))))
dff7d67f 324
2076c87c
JB
325(defun backward-delete-char-untabify (arg &optional killp)
326 "Delete characters backward, changing tabs into spaces.
327Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
328Interactively, ARG is the prefix arg (default 1)
aba05ae4 329and KILLP is t if a prefix arg was specified."
2076c87c
JB
330 (interactive "*p\nP")
331 (let ((count arg))
332 (save-excursion
333 (while (and (> count 0) (not (bobp)))
334 (if (= (preceding-char) ?\t)
335 (let ((col (current-column)))
336 (forward-char -1)
337 (setq col (- col (current-column)))
338 (insert-char ?\ col)
339 (delete-char 1)))
340 (forward-char -1)
341 (setq count (1- count)))))
4718d52e 342 (delete-backward-char arg killp))
2076c87c
JB
343
344(defun zap-to-char (arg char)
345 "Kill up to and including ARG'th occurrence of CHAR.
346Goes backward if ARG is negative; error if CHAR not found."
347 (interactive "p\ncZap to char: ")
348 (kill-region (point) (progn
349 (search-forward (char-to-string char) nil nil arg)
350; (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
351 (point))))
352
353(defun beginning-of-buffer (&optional arg)
354 "Move point to the beginning of the buffer; leave mark at previous position.
c66587fe
RS
355With arg N, put point N/10 of the way from the beginning.
356
357If the buffer is narrowed, this command uses the beginning and size
358of the accessible part of the buffer.
ff1fbe3e
RS
359
360Don't use this command in Lisp programs!
2076c87c
JB
361\(goto-char (point-min)) is faster and avoids clobbering the mark."
362 (interactive "P")
363 (push-mark)
c66587fe
RS
364 (let ((size (- (point-max) (point-min))))
365 (goto-char (if arg
366 (+ (point-min)
367 (if (> size 10000)
368 ;; Avoid overflow for large buffer sizes!
369 (* (prefix-numeric-value arg)
370 (/ size 10))
371 (/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
372 (point-min))))
2076c87c
JB
373 (if arg (forward-line 1)))
374
375(defun end-of-buffer (&optional arg)
376 "Move point to the end of the buffer; leave mark at previous position.
c66587fe
RS
377With arg N, put point N/10 of the way from the end.
378
379If the buffer is narrowed, this command uses the beginning and size
380of the accessible part of the buffer.
ff1fbe3e
RS
381
382Don't use this command in Lisp programs!
2076c87c
JB
383\(goto-char (point-max)) is faster and avoids clobbering the mark."
384 (interactive "P")
385 (push-mark)
c66587fe
RS
386 (let ((size (- (point-max) (point-min))))
387 (goto-char (if arg
388 (- (point-max)
389 (if (> size 10000)
390 ;; Avoid overflow for large buffer sizes!
391 (* (prefix-numeric-value arg)
392 (/ size 10))
393 (/ (* size (prefix-numeric-value arg)) 10)))
394 (point-max))))
3a801d0c
ER
395 ;; If we went to a place in the middle of the buffer,
396 ;; adjust it to the beginning of a line.
2076c87c 397 (if arg (forward-line 1)
3a801d0c
ER
398 ;; If the end of the buffer is not already on the screen,
399 ;; then scroll specially to put it near, but not at, the bottom.
400 (if (let ((old-point (point)))
401 (save-excursion
402 (goto-char (window-start))
403 (vertical-motion (window-height))
404 (< (point) old-point)))
97dfc68c
RS
405 (progn
406 (overlay-recenter (point))
407 (recenter -3)))))
2076c87c
JB
408
409(defun mark-whole-buffer ()
70e14c01
JB
410 "Put point at beginning and mark at end of buffer.
411You probably should not use this function in Lisp programs;
412it is usually a mistake for a Lisp function to use any subroutine
413that uses or sets the mark."
2076c87c
JB
414 (interactive)
415 (push-mark (point))
fd0f4056 416 (push-mark (point-max) nil t)
2076c87c
JB
417 (goto-char (point-min)))
418
419(defun count-lines-region (start end)
eb8c3be9 420 "Print number of lines and characters in the region."
2076c87c
JB
421 (interactive "r")
422 (message "Region has %d lines, %d characters"
423 (count-lines start end) (- end start)))
424
425(defun what-line ()
2578be76 426 "Print the current buffer line number and narrowed line number of point."
2076c87c 427 (interactive)
2578be76 428 (let ((opoint (point)) start)
2076c87c 429 (save-excursion
2578be76
RS
430 (save-restriction
431 (goto-char (point-min))
432 (widen)
433 (beginning-of-line)
434 (setq start (point))
435 (goto-char opoint)
436 (beginning-of-line)
437 (if (/= start 1)
438 (message "line %d (narrowed line %d)"
439 (1+ (count-lines 1 (point)))
440 (1+ (count-lines start (point))))
441 (message "Line %d" (1+ (count-lines 1 (point)))))))))
442
2076c87c
JB
443
444(defun count-lines (start end)
445 "Return number of lines between START and END.
446This is usually the number of newlines between them,
ff1fbe3e 447but can be one more if START is not equal to END
2076c87c 448and the greater of them is not at the start of a line."
e406700d
RS
449 (save-excursion
450 (save-restriction
451 (narrow-to-region start end)
452 (goto-char (point-min))
453 (if (eq selective-display t)
454 (save-match-data
dde92ca6
RS
455 (let ((done 0))
456 (while (re-search-forward "[\n\C-m]" nil t 40)
457 (setq done (+ 40 done)))
458 (while (re-search-forward "[\n\C-m]" nil t 1)
459 (setq done (+ 1 done)))
043efc41
RS
460 (goto-char (point-max))
461 (if (and (/= start end)
462 (not (bolp)))
463 (1+ done)
e406700d
RS
464 done)))
465 (- (buffer-size) (forward-line (buffer-size)))))))
2076c87c 466
d5d99b80
KH
467(defun what-cursor-position (&optional detail)
468 "Print info on cursor position (on screen and within buffer).
469With prefix argument, print detailed info of a character on cursor position."
470 (interactive "P")
2076c87c
JB
471 (let* ((char (following-char))
472 (beg (point-min))
473 (end (point-max))
474 (pos (point))
475 (total (buffer-size))
476 (percent (if (> total 50000)
477 ;; Avoid overflow from multiplying by 100!
478 (/ (+ (/ total 200) (1- pos)) (max (/ total 100) 1))
479 (/ (+ (/ total 2) (* 100 (1- pos))) (max total 1))))
480 (hscroll (if (= (window-hscroll) 0)
481 ""
482 (format " Hscroll=%d" (window-hscroll))))
483 (col (current-column)))
484 (if (= pos end)
485 (if (or (/= beg 1) (/= end (1+ total)))
486 (message "point=%d of %d(%d%%) <%d - %d> column %d %s"
487 pos total percent beg end col hscroll)
488 (message "point=%d of %d(%d%%) column %d %s"
489 pos total percent col hscroll))
d5d99b80
KH
490 (let ((str (if detail (format " %s" (split-char char)) "")))
491 (if (or (/= beg 1) (/= end (1+ total)))
492 (message "Char: %s (0%o, %d, 0x%x) %s point=%d of %d(%d%%) <%d - %d> column %d %s"
493 (if (< char 256)
494 (single-key-description char)
495 (char-to-string char))
496 char char char str pos total percent beg end col hscroll)
497 (message "Char: %s (0%o, %d, 0x%x)%s point=%d of %d(%d%%) column %d %s"
498 (if (< char 256)
499 (single-key-description char)
500 (char-to-string char))
501 char char char str pos total percent col hscroll))))))
2076c87c
JB
502
503(defun fundamental-mode ()
504 "Major mode not specialized for anything in particular.
505Other major modes are defined by comparison with this one."
506 (interactive)
507 (kill-all-local-variables))
508
4578d35d 509(defvar read-expression-map (cons 'keymap minibuffer-local-map)
854c16c5
RS
510 "Minibuffer keymap used for reading Lisp expressions.")
511(define-key read-expression-map "\M-\t" 'lisp-complete-symbol)
512
8570b0ca
RM
513(defvar read-expression-history nil)
514
515;; We define this, rather than making `eval' interactive,
2076c87c 516;; for the sake of completion of names like eval-region, eval-current-buffer.
ecb7ad00
RS
517(defun eval-expression (eval-expression-arg
518 &optional eval-expression-insert-value)
2076c87c 519 "Evaluate EXPRESSION and print value in minibuffer.
eb57c304 520Value is also consed on to front of the variable `values'."
adca5fa6 521 (interactive
b387ef9a
RS
522 (list (read-from-minibuffer "Eval: "
523 nil read-expression-map t
ecb7ad00
RS
524 'read-expression-history)
525 current-prefix-arg))
bc43b8e8 526 (setq values (cons (eval eval-expression-arg) values))
ecb7ad00
RS
527 (prin1 (car values)
528 (if eval-expression-insert-value (current-buffer) t)))
2076c87c
JB
529
530(defun edit-and-eval-command (prompt command)
531 "Prompting with PROMPT, let user edit COMMAND and eval result.
532COMMAND is a Lisp expression. Let user edit that expression in
533the minibuffer, then read and evaluate the result."
b387ef9a
RS
534 (let ((command (read-from-minibuffer prompt
535 (prin1-to-string command)
536 read-expression-map t
537 '(command-history . 1))))
5d6c83ae 538 ;; If command was added to command-history as a string,
1f238ac2 539 ;; get rid of that. We want only evaluable expressions there.
5d6c83ae
KH
540 (if (stringp (car command-history))
541 (setq command-history (cdr command-history)))
542
543 ;; If command to be redone does not match front of history,
544 ;; add it to the history.
545 (or (equal command (car command-history))
546 (setq command-history (cons command command-history)))
2076c87c
JB
547 (eval command)))
548
ebb61177 549(defun repeat-complex-command (arg)
2076c87c
JB
550 "Edit and re-evaluate last complex command, or ARGth from last.
551A complex command is one which used the minibuffer.
552The command is placed in the minibuffer as a Lisp form for editing.
553The result is executed, repeating the command as changed.
554If the command has been changed or is not the most recent previous command
555it is added to the front of the command history.
eb6e9899
RS
556You can use the minibuffer history commands \\<minibuffer-local-map>\\[next-history-element] and \\[previous-history-element]
557to get different commands to edit and resubmit."
2076c87c 558 (interactive "p")
ba343182 559 (let ((elt (nth (1- arg) command-history))
2076c87c
JB
560 newcmd)
561 (if elt
854c16c5 562 (progn
eab22e27 563 (setq newcmd
74ae5fab
RS
564 (let ((print-level nil)
565 (minibuffer-history-position arg)
566 (minibuffer-history-sexp-flag t))
7908d27c
RS
567 (read-from-minibuffer
568 "Redo: " (prin1-to-string elt) read-expression-map t
569 (cons 'command-history arg))))
eab22e27 570
db16f109 571 ;; If command was added to command-history as a string,
1f238ac2 572 ;; get rid of that. We want only evaluable expressions there.
db16f109
RS
573 (if (stringp (car command-history))
574 (setq command-history (cdr command-history)))
575
576 ;; If command to be redone does not match front of history,
577 ;; add it to the history.
578 (or (equal newcmd (car command-history))
579 (setq command-history (cons newcmd command-history)))
2076c87c
JB
580 (eval newcmd))
581 (ding))))
e91f80c4 582\f
854c16c5
RS
583(defvar minibuffer-history nil
584 "Default minibuffer history list.
585This is used for all minibuffer input
586except when an alternate history list is specified.")
587(defvar minibuffer-history-sexp-flag nil
c2d4b6d9 588 "Non-nil when doing history operations on `command-history'.
854c16c5
RS
589More generally, indicates that the history list being acted on
590contains expressions rather than strings.")
e91f80c4
RS
591(setq minibuffer-history-variable 'minibuffer-history)
592(setq minibuffer-history-position nil)
854c16c5 593(defvar minibuffer-history-search-history nil)
e91f80c4 594
29929437 595(mapcar
d0678801
RM
596 (lambda (key-and-command)
597 (mapcar
598 (lambda (keymap-and-completionp)
599 ;; Arg is (KEYMAP-SYMBOL . COMPLETION-MAP-P).
600 ;; If the cdr of KEY-AND-COMMAND (the command) is a cons,
601 ;; its car is used if COMPLETION-MAP-P is nil, its cdr if it is t.
602 (define-key (symbol-value (car keymap-and-completionp))
603 (car key-and-command)
604 (let ((command (cdr key-and-command)))
605 (if (consp command)
b5e6f936
RM
606 ;; (and ... nil) => ... turns back on the completion-oriented
607 ;; history commands which rms turned off since they seem to
608 ;; do things he doesn't like.
609 (if (and (cdr keymap-and-completionp) nil) ;XXX turned off
d81362b0 610 (progn (error "EMACS BUG!") (cdr command))
d0678801
RM
611 (car command))
612 command))))
613 '((minibuffer-local-map . nil)
614 (minibuffer-local-ns-map . nil)
615 (minibuffer-local-completion-map . t)
616 (minibuffer-local-must-match-map . t)
617 (read-expression-map . nil))))
d81362b0
RM
618 '(("\en" . (next-history-element . next-complete-history-element))
619 ([next] . (next-history-element . next-complete-history-element))
620 ("\ep" . (previous-history-element . previous-complete-history-element))
621 ([prior] . (previous-history-element . previous-complete-history-element))
29929437
JB
622 ("\er" . previous-matching-history-element)
623 ("\es" . next-matching-history-element)))
e91f80c4 624
93cee14b
RS
625(defvar minibuffer-text-before-history nil
626 "Text that was in this minibuffer before any history commands.
627This is nil if there have not yet been any history commands
628in this use of the minibuffer.")
629
630(add-hook 'minibuffer-setup-hook 'minibuffer-history-initialize)
631
632(defun minibuffer-history-initialize ()
633 (setq minibuffer-text-before-history nil))
634
e91f80c4 635(defun previous-matching-history-element (regexp n)
854c16c5
RS
636 "Find the previous history element that matches REGEXP.
637\(Previous history elements refer to earlier actions.)
638With prefix argument N, search for Nth previous match.
639If N is negative, find the next or Nth next match."
640 (interactive
c1172a19
RS
641 (let* ((enable-recursive-minibuffers t)
642 (minibuffer-history-sexp-flag nil)
643 (regexp (read-from-minibuffer "Previous element matching (regexp): "
644 nil
645 minibuffer-local-map
646 nil
647 'minibuffer-history-search-history)))
648 ;; Use the last regexp specified, by default, if input is empty.
649 (list (if (string= regexp "")
a8e96cea
KH
650 (if minibuffer-history-search-history
651 (car minibuffer-history-search-history)
652 (error "No previous history search regexp"))
c1172a19 653 regexp)
854c16c5 654 (prefix-numeric-value current-prefix-arg))))
93cee14b
RS
655 (if (and (zerop minibuffer-history-position)
656 (null minibuffer-text-before-history))
657 (setq minibuffer-text-before-history (buffer-string)))
e91f80c4 658 (let ((history (symbol-value minibuffer-history-variable))
ccc58657 659 prevpos
e91f80c4
RS
660 (pos minibuffer-history-position))
661 (while (/= n 0)
662 (setq prevpos pos)
663 (setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
664 (if (= pos prevpos)
665 (error (if (= pos 1)
ccc58657
RS
666 "No later matching history item"
667 "No earlier matching history item")))
e91f80c4
RS
668 (if (string-match regexp
669 (if minibuffer-history-sexp-flag
7908d27c
RS
670 (let ((print-level nil))
671 (prin1-to-string (nth (1- pos) history)))
e91f80c4 672 (nth (1- pos) history)))
854c16c5 673 (setq n (+ n (if (< n 0) 1 -1)))))
e91f80c4
RS
674 (setq minibuffer-history-position pos)
675 (erase-buffer)
676 (let ((elt (nth (1- pos) history)))
677 (insert (if minibuffer-history-sexp-flag
7908d27c
RS
678 (let ((print-level nil))
679 (prin1-to-string elt))
e91f80c4 680 elt)))
854c16c5
RS
681 (goto-char (point-min)))
682 (if (or (eq (car (car command-history)) 'previous-matching-history-element)
683 (eq (car (car command-history)) 'next-matching-history-element))
684 (setq command-history (cdr command-history))))
e91f80c4 685
e91f80c4 686(defun next-matching-history-element (regexp n)
854c16c5
RS
687 "Find the next history element that matches REGEXP.
688\(The next history element refers to a more recent action.)
689With prefix argument N, search for Nth next match.
690If N is negative, find the previous or Nth previous match."
691 (interactive
c1172a19
RS
692 (let* ((enable-recursive-minibuffers t)
693 (minibuffer-history-sexp-flag nil)
694 (regexp (read-from-minibuffer "Next element matching (regexp): "
695 nil
696 minibuffer-local-map
697 nil
698 'minibuffer-history-search-history)))
699 ;; Use the last regexp specified, by default, if input is empty.
700 (list (if (string= regexp "")
701 (setcar minibuffer-history-search-history
702 (nth 1 minibuffer-history-search-history))
703 regexp)
854c16c5 704 (prefix-numeric-value current-prefix-arg))))
e91f80c4 705 (previous-matching-history-element regexp (- n)))
2076c87c 706
ebb61177
RS
707(defun next-history-element (n)
708 "Insert the next element of the minibuffer history into the minibuffer."
2076c87c 709 (interactive "p")
0818b15e 710 (or (zerop n)
93cee14b
RS
711 (let ((narg (- minibuffer-history-position n))
712 (minimum (if minibuffer-default -1 0))
713 elt)
714 (if (and (zerop minibuffer-history-position)
715 (null minibuffer-text-before-history))
716 (setq minibuffer-text-before-history (buffer-string)))
717 (if (< narg minimum)
718 (error "End of history; no next item"))
719 (if (> narg (length (symbol-value minibuffer-history-variable)))
720 (error "Beginning of history; no preceding item"))
721 (erase-buffer)
722 (setq minibuffer-history-position narg)
723 (cond ((= narg -1)
724 (setq elt minibuffer-default))
725 ((= narg 0)
54c548db 726 (setq elt (or minibuffer-text-before-history ""))
93cee14b
RS
727 (setq minibuffer-text-before-history nil))
728 (t (setq elt (nth (1- minibuffer-history-position)
729 (symbol-value minibuffer-history-variable)))))
730 (insert
731 (if minibuffer-history-sexp-flag
732 (let ((print-level nil))
733 (prin1-to-string elt))
734 elt))
735 (goto-char (point-min)))))
2076c87c 736
ebb61177 737(defun previous-history-element (n)
3ee3a076 738 "Inserts the previous element of the minibuffer history into the minibuffer."
2076c87c 739 (interactive "p")
2c5e21c1 740 (next-history-element (- n)))
d0678801
RM
741
742(defun next-complete-history-element (n)
1f6fcec3 743 "Get next element of history which is a completion of minibuffer contents."
d0678801 744 (interactive "p")
b5e6f936
RM
745 (let ((point-at-start (point)))
746 (next-matching-history-element
747 (concat "^" (regexp-quote (buffer-substring (point-min) (point)))) n)
748 ;; next-matching-history-element always puts us at (point-min).
749 ;; Move to the position we were at before changing the buffer contents.
750 ;; This is still sensical, because the text before point has not changed.
751 (goto-char point-at-start)))
d0678801
RM
752
753(defun previous-complete-history-element (n)
1f6fcec3
RS
754 "\
755Get previous element of history which is a completion of minibuffer contents."
d0678801
RM
756 (interactive "p")
757 (next-complete-history-element (- n)))
e91f80c4 758\f
2076c87c
JB
759(defun goto-line (arg)
760 "Goto line ARG, counting from line 1 at beginning of buffer."
761 (interactive "NGoto line: ")
5f1a943c 762 (setq arg (prefix-numeric-value arg))
2076c87c
JB
763 (save-restriction
764 (widen)
765 (goto-char 1)
766 (if (eq selective-display t)
767 (re-search-forward "[\n\C-m]" nil 'end (1- arg))
768 (forward-line (1- arg)))))
769
770;Put this on C-x u, so we can force that rather than C-_ into startup msg
e462e42f 771(defalias 'advertised-undo 'undo)
2076c87c
JB
772
773(defun undo (&optional arg)
774 "Undo some previous changes.
775Repeat this command to undo more changes.
776A numeric argument serves as a repeat count."
777 (interactive "*p")
456c617c
RS
778 ;; If we don't get all the way thru, make last-command indicate that
779 ;; for the following command.
780 (setq this-command t)
b553cffa
RS
781 (let ((modified (buffer-modified-p))
782 (recent-save (recent-auto-save-p)))
71e40adf
JB
783 (or (eq (selected-window) (minibuffer-window))
784 (message "Undo!"))
2076c87c
JB
785 (or (eq last-command 'undo)
786 (progn (undo-start)
787 (undo-more 1)))
2076c87c 788 (undo-more (or arg 1))
2512c9f0
RS
789 ;; Don't specify a position in the undo record for the undo command.
790 ;; Instead, undoing this should move point to where the change is.
791 (let ((tail buffer-undo-list)
792 done)
793 (while (and tail (not done) (not (null (car tail))))
794 (if (integerp (car tail))
795 (progn
796 (setq done t)
797 (setq buffer-undo-list (delq (car tail) buffer-undo-list))))
798 (setq tail (cdr tail))))
2076c87c 799 (and modified (not (buffer-modified-p))
456c617c
RS
800 (delete-auto-save-file-if-necessary recent-save)))
801 ;; If we do get all the way thru, make this-command indicate that.
802 (setq this-command 'undo))
2076c87c 803
278b0a58
RS
804(defvar pending-undo-list nil
805 "Within a run of consecutive undo commands, list remaining to be undone.")
806
2076c87c 807(defun undo-start ()
ff1fbe3e
RS
808 "Set `pending-undo-list' to the front of the undo list.
809The next call to `undo-more' will undo the most recently made change."
2076c87c
JB
810 (if (eq buffer-undo-list t)
811 (error "No undo information in this buffer"))
812 (setq pending-undo-list buffer-undo-list))
813
814(defun undo-more (count)
815 "Undo back N undo-boundaries beyond what was already undone recently.
ff1fbe3e
RS
816Call `undo-start' to get ready to undo recent changes,
817then call `undo-more' one or more times to undo them."
2076c87c
JB
818 (or pending-undo-list
819 (error "No further undo information"))
820 (setq pending-undo-list (primitive-undo count pending-undo-list)))
821
009ef402
RS
822(defvar shell-command-history nil
823 "History list for some commands that read shell commands.")
824
59fc41e5
RS
825(defvar shell-command-switch "-c"
826 "Switch used to have the shell execute its command line argument.")
827
d0d74413 828(defun shell-command (command &optional output-buffer)
2076c87c 829 "Execute string COMMAND in inferior shell; display output, if any.
d382f610 830
2076c87c 831If COMMAND ends in ampersand, execute it asynchronously.
d382f610 832The output appears in the buffer `*Async Shell Command*'.
bcad4985 833That buffer is in shell mode.
d382f610 834
bcad4985
KH
835Otherwise, COMMAND is executed synchronously. The output appears in the
836buffer `*Shell Command Output*'.
d382f610
RS
837If the output is one line, it is displayed in the echo area *as well*,
838but it is nonetheless available in buffer `*Shell Command Output*',
839even though that buffer is not automatically displayed.
840If there is no output, or if output is inserted in the current buffer,
841then `*Shell Command Output*' is deleted.
d0d74413 842
07f458c1
RS
843To specify a coding system for converting non-ASCII characters
844in the shell command output, use \\[universal-coding-system-argument]
845before this command.
846
847Noninteractive callers can specify coding systems by binding
848`coding-system-for-read' and `coding-system-for-write'.
849
d0d74413
RS
850The optional second argument OUTPUT-BUFFER, if non-nil,
851says to put the output in some other buffer.
852If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
853If OUTPUT-BUFFER is not a buffer and not nil,
854insert output in current buffer. (This cannot be done asynchronously.)
855In either case, the output is inserted after point (leaving mark after it)."
aa00b92d
RS
856 (interactive (list (read-from-minibuffer "Shell command: "
857 nil nil nil 'shell-command-history)
858 current-prefix-arg))
c7edd03c
KH
859 ;; Look for a handler in case default-directory is a remote file name.
860 (let ((handler
861 (find-file-name-handler (directory-file-name default-directory)
862 'shell-command)))
863 (if handler
864 (funcall handler 'shell-command command output-buffer)
865 (if (and output-buffer
866 (not (or (bufferp output-buffer) (stringp output-buffer))))
867 (progn (barf-if-buffer-read-only)
868 (push-mark)
869 ;; We do not use -f for csh; we will not support broken use of
870 ;; .cshrcs. Even the BSD csh manual says to use
871 ;; "if ($?prompt) exit" before things which are not useful
872 ;; non-interactively. Besides, if someone wants their other
873 ;; aliases for shell commands then they can still have them.
874 (call-process shell-file-name nil t nil
875 shell-command-switch command)
876 ;; This is like exchange-point-and-mark, but doesn't
877 ;; activate the mark. It is cleaner to avoid activation,
878 ;; even though the command loop would deactivate the mark
879 ;; because we inserted text.
880 (goto-char (prog1 (mark t)
881 (set-marker (mark-marker) (point)
882 (current-buffer)))))
883 ;; Preserve the match data in case called from a program.
884 (save-match-data
885 (if (string-match "[ \t]*&[ \t]*$" command)
886 ;; Command ending with ampersand means asynchronous.
887 (let ((buffer (get-buffer-create
888 (or output-buffer "*Async Shell Command*")))
889 (directory default-directory)
890 proc)
891 ;; Remove the ampersand.
892 (setq command (substring command 0 (match-beginning 0)))
893 ;; If will kill a process, query first.
894 (setq proc (get-buffer-process buffer))
895 (if proc
896 (if (yes-or-no-p "A command is running. Kill it? ")
897 (kill-process proc)
898 (error "Shell command in progress")))
899 (save-excursion
900 (set-buffer buffer)
901 (setq buffer-read-only nil)
902 (erase-buffer)
903 (display-buffer buffer)
904 (setq default-directory directory)
905 (setq proc (start-process "Shell" buffer shell-file-name
906 shell-command-switch command))
907 (setq mode-line-process '(":%s"))
908 (require 'shell) (shell-mode)
909 (set-process-sentinel proc 'shell-command-sentinel)
910 ))
f2b3cdc3 911 (shell-command-on-region (point) (point) command output-buffer)
c7edd03c 912 ))))))
2076c87c
JB
913
914;; We have a sentinel to prevent insertion of a termination message
915;; in the buffer itself.
916(defun shell-command-sentinel (process signal)
bcad4985
KH
917 (if (memq (process-status process) '(exit signal))
918 (message "%s: %s."
919 (car (cdr (cdr (process-command process))))
920 (substring signal 0 -1))))
2076c87c 921
d0d74413 922(defun shell-command-on-region (start end command
cce1c318
RS
923 &optional output-buffer replace
924 error-buffer)
2076c87c
JB
925 "Execute string COMMAND in inferior shell with region as input.
926Normally display output (if any) in temp buffer `*Shell Command Output*';
927Prefix arg means replace the region with it.
56c0450e 928
07f458c1
RS
929To specify a coding system for converting non-ASCII characters
930in the input and output to the shell command, use \\[universal-coding-system-argument]
931before this command. By default, the input (from the current buffer)
932is encoded in the same coding system that will be used to save the file,
933`buffer-file-coding-system'. If the output is going to replace the region,
934then it is decoded from that same coding system.
935
cce1c318
RS
936The noninteractive arguments are START, END, COMMAND, OUTPUT-BUFFER, REPLACE,
937ERROR-BUFFER. If REPLACE is non-nil, that means insert the output
4d9bd664 938in place of text from START to END, putting point and mark around it.
07f458c1
RS
939Noninteractive callers can specify coding systems by binding
940`coding-system-for-read' and `coding-system-for-write'.
2076c87c
JB
941
942If the output is one line, it is displayed in the echo area,
943but it is nonetheless available in buffer `*Shell Command Output*'
56c0450e 944even though that buffer is not automatically displayed.
c42f586d 945If there is no output, or if output is inserted in the current buffer,
56c0450e 946then `*Shell Command Output*' is deleted.
d0d74413 947
56c0450e
RS
948If the optional fourth argument OUTPUT-BUFFER is non-nil,
949that says to put the output in some other buffer.
d0d74413
RS
950If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
951If OUTPUT-BUFFER is not a buffer and not nil,
952insert output in the current buffer.
cce1c318
RS
953In either case, the output is inserted after point (leaving mark after it).
954
955If optional fifth argument ERROR-BUFFER is non-nil, it is a buffer
956or buffer name to which to direct the command's standard error output.
957If it is nil, error output is mingled with regular output."
cae49185
RS
958 (interactive (let ((string
959 ;; Do this before calling region-beginning
960 ;; and region-end, in case subprocess output
961 ;; relocates them while we are in the minibuffer.
962 (read-from-minibuffer "Shell command on region: "
963 nil nil nil
964 'shell-command-history)))
2b03c506
RS
965 ;; call-interactively recognizes region-beginning and
966 ;; region-end specially, leaving them in the history.
967 (list (region-beginning) (region-end)
cae49185
RS
968 string
969 current-prefix-arg
4d9bd664 970 current-prefix-arg)))
cce1c318
RS
971 (let ((error-file
972 (if error-buffer
973 (concat (file-name-directory temp-file-name-pattern)
974 (make-temp-name "scor"))
975 nil)))
4d9bd664
RS
976 (if (or replace
977 (and output-buffer
29fc44dd
KH
978 (not (or (bufferp output-buffer) (stringp output-buffer))))
979 (equal (buffer-name (current-buffer)) "*Shell Command Output*"))
2076c87c 980 ;; Replace specified region with output from command.
6db3a963 981 (let ((swap (and replace (< start end))))
4d9bd664
RS
982 ;; Don't muck with mark unless REPLACE says we should.
983 (goto-char start)
56c0450e 984 (and replace (push-mark))
cce1c318
RS
985 (call-process-region start end shell-file-name t
986 (if error-file
987 (list t error-file)
988 t)
989 nil shell-command-switch command)
b5f7c943
KH
990 (let ((shell-buffer (get-buffer "*Shell Command Output*")))
991 (and shell-buffer (not (eq shell-buffer (current-buffer)))
992 (kill-buffer shell-buffer)))
4d9bd664 993 ;; Don't muck with mark unless REPLACE says we should.
56c0450e 994 (and replace swap (exchange-point-and-mark)))
2076c87c
JB
995 ;; No prefix argument: put the output in a temp buffer,
996 ;; replacing its entire contents.
d0d74413
RS
997 (let ((buffer (get-buffer-create
998 (or output-buffer "*Shell Command Output*")))
34ee0963
RS
999 (success nil))
1000 (unwind-protect
1001 (if (eq buffer (current-buffer))
1002 ;; If the input is the same buffer as the output,
1003 ;; delete everything but the specified region,
1004 ;; then replace that region with the output.
a9594ce3 1005 (progn (setq buffer-read-only nil)
6db3a963 1006 (delete-region (max start end) (point-max))
aa247686 1007 (delete-region (point-min) (min start end))
34ee0963 1008 (call-process-region (point-min) (point-max)
cce1c318
RS
1009 shell-file-name t
1010 (if error-file
1011 (list t error-file)
1012 t)
1013 nil shell-command-switch command)
34ee0963
RS
1014 (setq success t))
1015 ;; Clear the output buffer, then run the command with output there.
1016 (save-excursion
1017 (set-buffer buffer)
a9594ce3 1018 (setq buffer-read-only nil)
34ee0963 1019 (erase-buffer))
cce1c318
RS
1020 (call-process-region start end shell-file-name nil
1021 (if error-file
1022 (list buffer error-file)
1023 buffer)
1024 nil shell-command-switch command)
34ee0963
RS
1025 (setq success t))
1026 ;; Report the amount of output.
1027 (let ((lines (save-excursion
1028 (set-buffer buffer)
1029 (if (= (buffer-size) 0)
1030 0
1031 (count-lines (point-min) (point-max))))))
1032 (cond ((= lines 0)
1033 (if success
1034 (message "(Shell command completed with no output)"))
1035 (kill-buffer buffer))
1036 ((and success (= lines 1))
1037 (message "%s"
1038 (save-excursion
1039 (set-buffer buffer)
1040 (goto-char (point-min))
1041 (buffer-substring (point)
4ec982c5 1042 (progn (end-of-line) (point))))))
34ee0963 1043 (t
1277e7a2
KH
1044 (save-excursion
1045 (set-buffer buffer)
1046 (goto-char (point-min)))
cce1c318
RS
1047 (display-buffer buffer)))))))
1048 (if (and error-file (file-exists-p error-file))
1049 (save-excursion
1050 (set-buffer (get-buffer-create error-buffer))
1051 ;; Do no formatting while reading error file, for fear of looping.
1052 (format-insert-file error-file nil)
1053 (delete-file error-file)))))
d589bd99
RS
1054
1055(defun shell-command-to-string (command)
1056 "Execute shell command COMMAND and return its output as a string."
1057 (with-output-to-string
17cc9013
RS
1058 (with-current-buffer
1059 standard-output
1060 (call-process shell-file-name nil t nil shell-command-switch command))))
2076c87c 1061\f
1b43f83f 1062(defvar universal-argument-map
69d4c3c4
KH
1063 (let ((map (make-sparse-keymap)))
1064 (define-key map [t] 'universal-argument-other-key)
b9ff190d 1065 (define-key map (vector meta-prefix-char t) 'universal-argument-other-key)
69d4c3c4
KH
1066 (define-key map [switch-frame] nil)
1067 (define-key map [?\C-u] 'universal-argument-more)
1068 (define-key map [?-] 'universal-argument-minus)
1069 (define-key map [?0] 'digit-argument)
1070 (define-key map [?1] 'digit-argument)
1071 (define-key map [?2] 'digit-argument)
1072 (define-key map [?3] 'digit-argument)
1073 (define-key map [?4] 'digit-argument)
1074 (define-key map [?5] 'digit-argument)
1075 (define-key map [?6] 'digit-argument)
1076 (define-key map [?7] 'digit-argument)
1077 (define-key map [?8] 'digit-argument)
1078 (define-key map [?9] 'digit-argument)
1079 map)
1080 "Keymap used while processing \\[universal-argument].")
1081
0de84e16
RS
1082(defvar universal-argument-num-events nil
1083 "Number of argument-specifying events read by `universal-argument'.
1084`universal-argument-other-key' uses this to discard those events
1085from (this-command-keys), and reread only the final command.")
1086
e8d1a377
KH
1087(defun universal-argument ()
1088 "Begin a numeric argument for the following command.
1089Digits or minus sign following \\[universal-argument] make up the numeric argument.
1090\\[universal-argument] following the digits or minus sign ends the argument.
1091\\[universal-argument] without digits or minus sign provides 4 as argument.
1092Repeating \\[universal-argument] without digits or minus sign
0565d307
RS
1093 multiplies the argument by 4 each time.
1094For some commands, just \\[universal-argument] by itself serves as a flag
a697fc62
RS
1095which is different in effect from any particular numeric argument.
1096These commands include \\[set-mark-command] and \\[start-kbd-macro]."
69d4c3c4
KH
1097 (interactive)
1098 (setq prefix-arg (list 4))
0de84e16 1099 (setq universal-argument-num-events (length (this-command-keys)))
69d4c3c4 1100 (setq overriding-terminal-local-map universal-argument-map))
e8d1a377 1101
69d4c3c4
KH
1102;; A subsequent C-u means to multiply the factor by 4 if we've typed
1103;; nothing but C-u's; otherwise it means to terminate the prefix arg.
1104(defun universal-argument-more (arg)
e8d1a377 1105 (interactive "P")
69d4c3c4
KH
1106 (if (consp arg)
1107 (setq prefix-arg (list (* 4 (car arg))))
1cd24721
RS
1108 (if (eq arg '-)
1109 (setq prefix-arg (list -4))
1110 (setq prefix-arg arg)
1111 (setq overriding-terminal-local-map nil)))
0de84e16 1112 (setq universal-argument-num-events (length (this-command-keys))))
e8d1a377
KH
1113
1114(defun negative-argument (arg)
1115 "Begin a negative numeric argument for the next command.
1116\\[universal-argument] following digits or minus sign ends the argument."
1117 (interactive "P")
69d4c3c4
KH
1118 (cond ((integerp arg)
1119 (setq prefix-arg (- arg)))
1120 ((eq arg '-)
1121 (setq prefix-arg nil))
1122 (t
b9ff190d 1123 (setq prefix-arg '-)))
0de84e16 1124 (setq universal-argument-num-events (length (this-command-keys)))
b9ff190d 1125 (setq overriding-terminal-local-map universal-argument-map))
69d4c3c4
KH
1126
1127(defun digit-argument (arg)
1128 "Part of the numeric argument for the next command.
1129\\[universal-argument] following digits or minus sign ends the argument."
1130 (interactive "P")
1131 (let ((digit (- (logand last-command-char ?\177) ?0)))
1132 (cond ((integerp arg)
1133 (setq prefix-arg (+ (* arg 10)
1134 (if (< arg 0) (- digit) digit))))
1135 ((eq arg '-)
1136 ;; Treat -0 as just -, so that -01 will work.
1137 (setq prefix-arg (if (zerop digit) '- (- digit))))
1138 (t
b9ff190d 1139 (setq prefix-arg digit))))
0de84e16 1140 (setq universal-argument-num-events (length (this-command-keys)))
b9ff190d 1141 (setq overriding-terminal-local-map universal-argument-map))
69d4c3c4
KH
1142
1143;; For backward compatibility, minus with no modifiers is an ordinary
1144;; command if digits have already been entered.
1145(defun universal-argument-minus (arg)
1146 (interactive "P")
1147 (if (integerp arg)
1148 (universal-argument-other-key arg)
1149 (negative-argument arg)))
1150
1151;; Anything else terminates the argument and is left in the queue to be
1152;; executed as a command.
1153(defun universal-argument-other-key (arg)
1154 (interactive "P")
1155 (setq prefix-arg arg)
0de84e16
RS
1156 (let* ((key (this-command-keys))
1157 (keylist (listify-key-sequence key)))
1158 (setq unread-command-events
06697cdb
RS
1159 (append (nthcdr universal-argument-num-events keylist)
1160 unread-command-events)))
f0ef2555 1161 (reset-this-command-lengths)
69d4c3c4 1162 (setq overriding-terminal-local-map nil))
e8d1a377 1163\f
2076c87c
JB
1164(defun forward-to-indentation (arg)
1165 "Move forward ARG lines and position at first nonblank character."
1166 (interactive "p")
1167 (forward-line arg)
1168 (skip-chars-forward " \t"))
1169
1170(defun backward-to-indentation (arg)
1171 "Move backward ARG lines and position at first nonblank character."
1172 (interactive "p")
1173 (forward-line (- arg))
1174 (skip-chars-forward " \t"))
1175
69c1dd37
RS
1176(defcustom kill-whole-line nil
1177 "*If non-nil, `kill-line' with no arg at beg of line kills the whole line."
1178 :type 'boolean
1179 :group 'killing)
38ebcf29 1180
2076c87c 1181(defun kill-line (&optional arg)
dff7d67f 1182 "Kill the rest of the current line; if no nonblanks there, kill thru newline.
2076c87c
JB
1183With prefix argument, kill that many lines from point.
1184Negative arguments kill lines backward.
1185
1186When calling from a program, nil means \"no arg\",
dff7d67f
RS
1187a number counts as a prefix arg.
1188
85969cb1
RS
1189To kill a whole line, when point is not at the beginning, type \
1190\\[beginning-of-line] \\[kill-line] \\[kill-line].
1191
1192If `kill-whole-line' is non-nil, then this command kills the whole line
1193including its terminating newline, when used at the beginning of a line
1194with no argument. As a consequence, you can always kill a whole line
1195by typing \\[beginning-of-line] \\[kill-line]."
2076c87c
JB
1196 (interactive "P")
1197 (kill-region (point)
e6291fe1
RS
1198 ;; It is better to move point to the other end of the kill
1199 ;; before killing. That way, in a read-only buffer, point
1200 ;; moves across the text that is copied to the kill ring.
1201 ;; The choice has no effect on undo now that undo records
1202 ;; the value of point from before the command was run.
1203 (progn
2076c87c 1204 (if arg
53efb707 1205 (forward-visible-line (prefix-numeric-value arg))
2076c87c
JB
1206 (if (eobp)
1207 (signal 'end-of-buffer nil))
38ebcf29 1208 (if (or (looking-at "[ \t]*$") (and kill-whole-line (bolp)))
53efb707
RS
1209 (forward-visible-line 1)
1210 (end-of-visible-line)))
2076c87c 1211 (point))))
53efb707
RS
1212
1213(defun forward-visible-line (arg)
9e7a6b30
RS
1214 "Move forward by ARG lines, ignoring currently invisible newlines only.
1215If ARG is negative, move backward -ARG lines.
1216If ARG is zero, move to the beginning of the current line."
53efb707 1217 (condition-case nil
29df77ba
RS
1218 (if (> arg 0)
1219 (while (> arg 0)
1220 (or (zerop (forward-line 1))
1221 (signal 'end-of-buffer nil))
9e7a6b30
RS
1222 ;; If the following character is currently invisible,
1223 ;; skip all characters with that same `invisible' property value,
1224 ;; then find the next newline.
1225 (while (and (not (eobp))
1226 (let ((prop
1227 (get-char-property (point) 'invisible)))
1228 (if (eq buffer-invisibility-spec t)
1229 prop
1230 (or (memq prop buffer-invisibility-spec)
1231 (assq prop buffer-invisibility-spec)))))
d91462ce
RS
1232 (goto-char
1233 (if (get-text-property (point) 'invisible)
1234 (or (next-single-property-change (point) 'invisible)
1235 (point-max))
1236 (next-overlay-change (point))))
9e7a6b30
RS
1237 (or (zerop (forward-line 1))
1238 (signal 'end-of-buffer nil)))
1239 (setq arg (1- arg)))
29df77ba
RS
1240 (let ((first t))
1241 (while (or first (< arg 0))
1242 (if (zerop arg)
1243 (beginning-of-line)
1244 (or (zerop (forward-line -1))
1245 (signal 'beginning-of-buffer nil)))
1246 (while (and (not (bobp))
1247 (let ((prop
1248 (get-char-property (1- (point)) 'invisible)))
1249 (if (eq buffer-invisibility-spec t)
1250 prop
1251 (or (memq prop buffer-invisibility-spec)
1252 (assq prop buffer-invisibility-spec)))))
d91462ce
RS
1253 (goto-char
1254 (if (get-text-property (1- (point)) 'invisible)
1255 (or (previous-single-property-change (point) 'invisible)
1256 (point-min))
1257 (previous-overlay-change (point))))
29df77ba
RS
1258 (or (zerop (forward-line -1))
1259 (signal 'beginning-of-buffer nil)))
1260 (setq first nil)
1261 (setq arg (1+ arg)))))
53efb707
RS
1262 ((beginning-of-buffer end-of-buffer)
1263 nil)))
1264
1265(defun end-of-visible-line ()
1266 "Move to end of current visible line."
1267 (end-of-line)
1268 ;; If the following character is currently invisible,
1269 ;; skip all characters with that same `invisible' property value,
1270 ;; then find the next newline.
1271 (while (and (not (eobp))
1272 (let ((prop
1273 (get-char-property (point) 'invisible)))
1274 (if (eq buffer-invisibility-spec t)
1275 prop
1276 (or (memq prop buffer-invisibility-spec)
1277 (assq prop buffer-invisibility-spec)))))
1278 (if (get-text-property (point) 'invisible)
1279 (goto-char (next-single-property-change (point) 'invisible))
1280 (goto-char (next-overlay-change (point))))
1281 (forward-char 1)
1282 (end-of-line)))
2076c87c 1283\f
70e14c01
JB
1284;;;; Window system cut and paste hooks.
1285
1286(defvar interprogram-cut-function nil
1287 "Function to call to make a killed region available to other programs.
1288
1289Most window systems provide some sort of facility for cutting and
9f112a3d
RS
1290pasting text between the windows of different programs.
1291This variable holds a function that Emacs calls whenever text
1292is put in the kill ring, to make the new kill available to other
70e14c01
JB
1293programs.
1294
9f112a3d
RS
1295The function takes one or two arguments.
1296The first argument, TEXT, is a string containing
1297the text which should be made available.
1298The second, PUSH, if non-nil means this is a \"new\" kill;
1299nil means appending to an \"old\" kill.")
70e14c01
JB
1300
1301(defvar interprogram-paste-function nil
1302 "Function to call to get text cut from other programs.
1303
1304Most window systems provide some sort of facility for cutting and
9f112a3d
RS
1305pasting text between the windows of different programs.
1306This variable holds a function that Emacs calls to obtain
70e14c01
JB
1307text that other programs have provided for pasting.
1308
1309The function should be called with no arguments. If the function
1310returns nil, then no other program has provided such text, and the top
1311of the Emacs kill ring should be used. If the function returns a
daa37602
JB
1312string, that string should be put in the kill ring as the latest kill.
1313
1314Note that the function should return a string only if a program other
1315than Emacs has provided a string for pasting; if Emacs provided the
1316most recent string, the function should return nil. If it is
1317difficult to tell whether Emacs or some other program provided the
1318current string, it is probably good enough to return nil if the string
1319is equal (according to `string=') to the last text Emacs provided.")
70e14c01
JB
1320
1321
1322\f
1323;;;; The kill ring data structure.
2076c87c
JB
1324
1325(defvar kill-ring nil
70e14c01
JB
1326 "List of killed text sequences.
1327Since the kill ring is supposed to interact nicely with cut-and-paste
1328facilities offered by window systems, use of this variable should
1329interact nicely with `interprogram-cut-function' and
1330`interprogram-paste-function'. The functions `kill-new',
1331`kill-append', and `current-kill' are supposed to implement this
1332interaction; you may want to use them instead of manipulating the kill
1333ring directly.")
2076c87c 1334
69c1dd37
RS
1335(defcustom kill-ring-max 30
1336 "*Maximum length of kill ring before oldest elements are thrown away."
1337 :type 'integer
1338 :group 'killing)
2076c87c
JB
1339
1340(defvar kill-ring-yank-pointer nil
1341 "The tail of the kill ring whose car is the last thing yanked.")
1342
f914dc91 1343(defun kill-new (string &optional replace)
70e14c01
JB
1344 "Make STRING the latest kill in the kill ring.
1345Set the kill-ring-yank pointer to point to it.
f914dc91
KH
1346If `interprogram-cut-function' is non-nil, apply it to STRING.
1347Optional second argument REPLACE non-nil means that STRING will replace
1348the front of the kill ring, rather than being added to the list."
f1d01ba2
KH
1349 (and (fboundp 'menu-bar-update-yank-menu)
1350 (menu-bar-update-yank-menu string (and replace (car kill-ring))))
f914dc91
KH
1351 (if replace
1352 (setcar kill-ring string)
1353 (setq kill-ring (cons string kill-ring))
1354 (if (> (length kill-ring) kill-ring-max)
1355 (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
70e14c01
JB
1356 (setq kill-ring-yank-pointer kill-ring)
1357 (if interprogram-cut-function
657a33ab 1358 (funcall interprogram-cut-function string (not replace))))
70e14c01 1359
2076c87c 1360(defun kill-append (string before-p)
70e14c01
JB
1361 "Append STRING to the end of the latest kill in the kill ring.
1362If BEFORE-P is non-nil, prepend STRING to the kill.
88c1aa79 1363If `interprogram-cut-function' is set, pass the resulting kill to
70e14c01 1364it."
f914dc91
KH
1365 (kill-new (if before-p
1366 (concat string (car kill-ring))
1367 (concat (car kill-ring) string)) t))
70e14c01
JB
1368
1369(defun current-kill (n &optional do-not-move)
1370 "Rotate the yanking point by N places, and then return that kill.
1371If N is zero, `interprogram-paste-function' is set, and calling it
1372returns a string, then that string is added to the front of the
1373kill ring and returned as the latest kill.
1374If optional arg DO-NOT-MOVE is non-nil, then don't actually move the
1375yanking point; just return the Nth kill forward."
1376 (let ((interprogram-paste (and (= n 0)
1377 interprogram-paste-function
1378 (funcall interprogram-paste-function))))
1379 (if interprogram-paste
1380 (progn
1381 ;; Disable the interprogram cut function when we add the new
1382 ;; text to the kill ring, so Emacs doesn't try to own the
1383 ;; selection, with identical text.
1384 (let ((interprogram-cut-function nil))
1385 (kill-new interprogram-paste))
1386 interprogram-paste)
1387 (or kill-ring (error "Kill ring is empty"))
47096a67
PE
1388 (let ((ARGth-kill-element
1389 (nthcdr (mod (- n (length kill-ring-yank-pointer))
1390 (length kill-ring))
1391 kill-ring)))
70e14c01
JB
1392 (or do-not-move
1393 (setq kill-ring-yank-pointer ARGth-kill-element))
1394 (car ARGth-kill-element)))))
c88ab9ce 1395
c88ab9ce 1396
70e14c01
JB
1397\f
1398;;;; Commands for manipulating the kill ring.
c88ab9ce 1399
69c1dd37
RS
1400(defcustom kill-read-only-ok nil
1401 "*Non-nil means don't signal an error for killing read-only text."
1402 :type 'boolean
1403 :group 'killing)
e6291fe1 1404
3a5da8a8
RS
1405(put 'text-read-only 'error-conditions
1406 '(text-read-only buffer-read-only error))
1407(put 'text-read-only 'error-message "Text is read-only")
1408
2076c87c
JB
1409(defun kill-region (beg end)
1410 "Kill between point and mark.
1411The text is deleted but saved in the kill ring.
1412The command \\[yank] can retrieve it from there.
1413\(If you want to kill and then yank immediately, use \\[copy-region-as-kill].)
2aa7a8bf
JB
1414If the buffer is read-only, Emacs will beep and refrain from deleting
1415the text, but put the text in the kill ring anyway. This means that
1416you can use the killing commands to copy text from a read-only buffer.
2076c87c
JB
1417
1418This is the primitive for programs to kill text (as opposed to deleting it).
1419Supply two arguments, character numbers indicating the stretch of text
1420 to be killed.
1421Any command that calls this function is a \"kill command\".
1422If the previous command was also a kill command,
1423the text killed this time appends to the text killed last time
1424to make one entry in the kill ring."
2aa7a8bf 1425 (interactive "r")
70e14c01 1426 (cond
2aa7a8bf
JB
1427
1428 ;; If the buffer is read-only, we should beep, in case the person
1429 ;; just isn't aware of this. However, there's no harm in putting
1430 ;; the region's text in the kill ring, anyway.
18aa68c3
RS
1431 ((and (not inhibit-read-only)
1432 (or buffer-read-only
1433 (text-property-not-all beg end 'read-only nil)))
2aa7a8bf 1434 (copy-region-as-kill beg end)
1537a263 1435 ;; This should always barf, and give us the correct error.
e6291fe1
RS
1436 (if kill-read-only-ok
1437 (message "Read only text copied to kill ring")
626a097c 1438 (setq this-command 'kill-region)
3a5da8a8
RS
1439 ;; Signal an error if the buffer is read-only.
1440 (barf-if-buffer-read-only)
1441 ;; If the buffer isn't read-only, the text is.
1442 (signal 'text-read-only (list (current-buffer)))))
2aa7a8bf
JB
1443
1444 ;; In certain cases, we can arrange for the undo list and the kill
1445 ;; ring to share the same string object. This code does that.
70e14c01
JB
1446 ((not (or (eq buffer-undo-list t)
1447 (eq last-command 'kill-region)
713dca1c
RS
1448 ;; Use = since positions may be numbers or markers.
1449 (= beg end)))
70e14c01 1450 ;; Don't let the undo list be truncated before we can even access it.
12bcd3b6
RS
1451 (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100))
1452 (old-list buffer-undo-list)
1453 tail)
70e14c01 1454 (delete-region beg end)
12bcd3b6
RS
1455 ;; Search back in buffer-undo-list for this string,
1456 ;; in case a change hook made property changes.
1457 (setq tail buffer-undo-list)
1458 (while (not (stringp (car (car tail))))
1459 (setq tail (cdr tail)))
70e14c01
JB
1460 ;; Take the same string recorded for undo
1461 ;; and put it in the kill-ring.
626a097c 1462 (kill-new (car (car tail)))))
2aa7a8bf 1463
70e14c01 1464 (t
2076c87c 1465 (copy-region-as-kill beg end)
626a097c
KH
1466 (delete-region beg end)))
1467 (setq this-command 'kill-region))
2076c87c 1468
a382890a
KH
1469;; copy-region-as-kill no longer sets this-command, because it's confusing
1470;; to get two copies of the text when the user accidentally types M-w and
1471;; then corrects it with the intended C-w.
2076c87c
JB
1472(defun copy-region-as-kill (beg end)
1473 "Save the region as if killed, but don't kill it.
46947372
JB
1474If `interprogram-cut-function' is non-nil, also save the text for a window
1475system cut and paste."
2076c87c
JB
1476 (interactive "r")
1477 (if (eq last-command 'kill-region)
1478 (kill-append (buffer-substring beg end) (< end beg))
70e14c01 1479 (kill-new (buffer-substring beg end)))
2076c87c
JB
1480 nil)
1481
1482(defun kill-ring-save (beg end)
0964e562 1483 "Save the region as if killed, but don't kill it.
230c6b36 1484This command is similar to `copy-region-as-kill', except that it gives
0964e562
JB
1485visual feedback indicating the extent of the region being copied.
1486If `interprogram-cut-function' is non-nil, also save the text for a window
1487system cut and paste."
2076c87c
JB
1488 (interactive "r")
1489 (copy-region-as-kill beg end)
3a801d0c 1490 (if (interactive-p)
66050f10
RS
1491 (let ((other-end (if (= (point) beg) end beg))
1492 (opoint (point))
1493 ;; Inhibit quitting so we can make a quit here
1494 ;; look like a C-g typed as a command.
1495 (inhibit-quit t))
1496 (if (pos-visible-in-window-p other-end (selected-window))
1497 (progn
1498 ;; Swap point and mark.
1499 (set-marker (mark-marker) (point) (current-buffer))
1500 (goto-char other-end)
1501 (sit-for 1)
1502 ;; Swap back.
1503 (set-marker (mark-marker) other-end (current-buffer))
1504 (goto-char opoint)
1505 ;; If user quit, deactivate the mark
1506 ;; as C-g would as a command.
e4e593ae 1507 (and quit-flag mark-active
fcadf1c7 1508 (deactivate-mark)))
66050f10
RS
1509 (let* ((killed-text (current-kill 0))
1510 (message-len (min (length killed-text) 40)))
1511 (if (= (point) beg)
1512 ;; Don't say "killed"; that is misleading.
1513 (message "Saved text until \"%s\""
1514 (substring killed-text (- message-len)))
1515 (message "Saved text from \"%s\""
1516 (substring killed-text 0 message-len))))))))
2076c87c
JB
1517
1518(defun append-next-kill ()
ff1fbe3e 1519 "Cause following command, if it kills, to append to previous kill."
2076c87c
JB
1520 (interactive)
1521 (if (interactive-p)
1522 (progn
1523 (setq this-command 'kill-region)
1524 (message "If the next command is a kill, it will append"))
1525 (setq last-command 'kill-region)))
1526
2076c87c 1527(defun yank-pop (arg)
ff1fbe3e
RS
1528 "Replace just-yanked stretch of killed text with a different stretch.
1529This command is allowed only immediately after a `yank' or a `yank-pop'.
2076c87c 1530At such a time, the region contains a stretch of reinserted
ff1fbe3e 1531previously-killed text. `yank-pop' deletes that text and inserts in its
2076c87c
JB
1532place a different stretch of killed text.
1533
1534With no argument, the previous kill is inserted.
ff1fbe3e
RS
1535With argument N, insert the Nth previous kill.
1536If N is negative, this is a more recent kill.
2076c87c
JB
1537
1538The sequence of kills wraps around, so that after the oldest one
1539comes the newest one."
1540 (interactive "*p")
1541 (if (not (eq last-command 'yank))
1542 (error "Previous command was not a yank"))
1543 (setq this-command 'yank)
3a5da8a8
RS
1544 (let ((inhibit-read-only t)
1545 (before (< (point) (mark t))))
9a1277dd 1546 (delete-region (point) (mark t))
fd0f4056 1547 (set-marker (mark-marker) (point) (current-buffer))
6cd829a8 1548 (let ((opoint (point)))
7ae13091 1549 (insert (current-kill arg))
6cd829a8
RS
1550 (let ((inhibit-read-only t))
1551 (remove-text-properties opoint (point) '(read-only nil))))
fd0f4056
RS
1552 (if before
1553 ;; This is like exchange-point-and-mark, but doesn't activate the mark.
1554 ;; It is cleaner to avoid activation, even though the command
1555 ;; loop would deactivate the mark because we inserted text.
1556 (goto-char (prog1 (mark t)
1557 (set-marker (mark-marker) (point) (current-buffer))))))
0964e562 1558 nil)
2076c87c
JB
1559
1560(defun yank (&optional arg)
1561 "Reinsert the last stretch of killed text.
1562More precisely, reinsert the stretch of killed text most recently
ff1fbe3e
RS
1563killed OR yanked. Put point at end, and set mark at beginning.
1564With just C-u as argument, same but put point at beginning (and mark at end).
1565With argument N, reinsert the Nth most recently killed stretch of killed
2076c87c
JB
1566text.
1567See also the command \\[yank-pop]."
1568 (interactive "*P")
456c617c
RS
1569 ;; If we don't get all the way thru, make last-command indicate that
1570 ;; for the following command.
1571 (setq this-command t)
2076c87c 1572 (push-mark (point))
6cd829a8 1573 (let ((opoint (point)))
7ae13091
RS
1574 (insert (current-kill (cond
1575 ((listp arg) 0)
1576 ((eq arg '-) -1)
1577 (t (1- arg)))))
6cd829a8
RS
1578 (let ((inhibit-read-only t))
1579 (remove-text-properties opoint (point) '(read-only nil))))
2076c87c 1580 (if (consp arg)
fd0f4056
RS
1581 ;; This is like exchange-point-and-mark, but doesn't activate the mark.
1582 ;; It is cleaner to avoid activation, even though the command
1583 ;; loop would deactivate the mark because we inserted text.
1584 (goto-char (prog1 (mark t)
1585 (set-marker (mark-marker) (point) (current-buffer)))))
456c617c
RS
1586 ;; If we do get all the way thru, make this-command indicate that.
1587 (setq this-command 'yank)
0964e562 1588 nil)
70e14c01
JB
1589
1590(defun rotate-yank-pointer (arg)
1591 "Rotate the yanking point in the kill ring.
1592With argument, rotate that many kills forward (or backward, if negative)."
1593 (interactive "p")
1594 (current-kill arg))
1595
2076c87c
JB
1596\f
1597(defun insert-buffer (buffer)
1598 "Insert after point the contents of BUFFER.
1599Puts mark after the inserted text.
1600BUFFER may be a buffer or a buffer name."
c3d4f949 1601 (interactive
a3e7c391
FP
1602 (list
1603 (progn
1604 (barf-if-buffer-read-only)
1605 (read-buffer "Insert buffer: "
1606 (if (eq (selected-window) (next-window (selected-window)))
1607 (other-buffer (current-buffer))
1608 (window-buffer (next-window (selected-window))))
1609 t))))
2076c87c
JB
1610 (or (bufferp buffer)
1611 (setq buffer (get-buffer buffer)))
1612 (let (start end newmark)
1613 (save-excursion
1614 (save-excursion
1615 (set-buffer buffer)
1616 (setq start (point-min) end (point-max)))
1617 (insert-buffer-substring buffer start end)
1618 (setq newmark (point)))
1537a263
JB
1619 (push-mark newmark))
1620 nil)
2076c87c
JB
1621
1622(defun append-to-buffer (buffer start end)
1623 "Append to specified buffer the text of the region.
1624It is inserted into that buffer before its point.
1625
1626When calling from a program, give three arguments:
1627BUFFER (or buffer name), START and END.
1628START and END specify the portion of the current buffer to be copied."
70e14c01 1629 (interactive
5d771766 1630 (list (read-buffer "Append to buffer: " (other-buffer (current-buffer) t))
23efee2c 1631 (region-beginning) (region-end)))
2076c87c
JB
1632 (let ((oldbuf (current-buffer)))
1633 (save-excursion
1634 (set-buffer (get-buffer-create buffer))
1635 (insert-buffer-substring oldbuf start end))))
1636
1637(defun prepend-to-buffer (buffer start end)
1638 "Prepend to specified buffer the text of the region.
1639It is inserted into that buffer after its point.
1640
1641When calling from a program, give three arguments:
1642BUFFER (or buffer name), START and END.
1643START and END specify the portion of the current buffer to be copied."
1644 (interactive "BPrepend to buffer: \nr")
1645 (let ((oldbuf (current-buffer)))
1646 (save-excursion
1647 (set-buffer (get-buffer-create buffer))
1648 (save-excursion
1649 (insert-buffer-substring oldbuf start end)))))
1650
1651(defun copy-to-buffer (buffer start end)
1652 "Copy to specified buffer the text of the region.
1653It is inserted into that buffer, replacing existing text there.
1654
1655When calling from a program, give three arguments:
1656BUFFER (or buffer name), START and END.
1657START and END specify the portion of the current buffer to be copied."
1658 (interactive "BCopy to buffer: \nr")
1659 (let ((oldbuf (current-buffer)))
1660 (save-excursion
1661 (set-buffer (get-buffer-create buffer))
1662 (erase-buffer)
1663 (save-excursion
1664 (insert-buffer-substring oldbuf start end)))))
1665\f
62d1c1fc
RM
1666(put 'mark-inactive 'error-conditions '(mark-inactive error))
1667(put 'mark-inactive 'error-message "The mark is not active now")
1668
af39530e 1669(defun mark (&optional force)
c7c8b31e 1670 "Return this buffer's mark value as integer; error if mark inactive.
af39530e 1671If optional argument FORCE is non-nil, access the mark value
c7c8b31e
RS
1672even if the mark is not currently active, and return nil
1673if there is no mark at all.
af39530e 1674
2076c87c
JB
1675If you are using this in an editing command, you are most likely making
1676a mistake; see the documentation of `set-mark'."
0e3a7b14 1677 (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)
af39530e 1678 (marker-position (mark-marker))
62d1c1fc 1679 (signal 'mark-inactive nil)))
2076c87c 1680
19d35374
RM
1681;; Many places set mark-active directly, and several of them failed to also
1682;; run deactivate-mark-hook. This shorthand should simplify.
1683(defsubst deactivate-mark ()
1684 "Deactivate the mark by setting `mark-active' to nil.
fcadf1c7 1685\(That makes a difference only in Transient Mark mode.)
19d35374 1686Also runs the hook `deactivate-mark-hook'."
a4b9d3da
RS
1687 (if transient-mark-mode
1688 (progn
1689 (setq mark-active nil)
1690 (run-hooks 'deactivate-mark-hook))))
19d35374 1691
2076c87c
JB
1692(defun set-mark (pos)
1693 "Set this buffer's mark to POS. Don't use this function!
1694That is to say, don't use this function unless you want
1695the user to see that the mark has moved, and you want the previous
1696mark position to be lost.
1697
1698Normally, when a new mark is set, the old one should go on the stack.
1699This is why most applications should use push-mark, not set-mark.
1700
ff1fbe3e 1701Novice Emacs Lisp programmers often try to use the mark for the wrong
2076c87c
JB
1702purposes. The mark saves a location for the user's convenience.
1703Most editing commands should not alter the mark.
1704To remember a location for internal use in the Lisp program,
1705store it in a Lisp variable. Example:
1706
1707 (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
1708
fcadf1c7
RS
1709 (if pos
1710 (progn
1711 (setq mark-active t)
1712 (run-hooks 'activate-mark-hook)
1713 (set-marker (mark-marker) pos (current-buffer)))
24c22852
RS
1714 ;; Normally we never clear mark-active except in Transient Mark mode.
1715 ;; But when we actually clear out the mark value too,
1716 ;; we must clear mark-active in any mode.
1717 (setq mark-active nil)
1718 (run-hooks 'deactivate-mark-hook)
1719 (set-marker (mark-marker) nil)))
2076c87c
JB
1720
1721(defvar mark-ring nil
e55e2267 1722 "The list of former marks of the current buffer, most recent first.")
2076c87c 1723(make-variable-buffer-local 'mark-ring)
e55e2267 1724(put 'mark-ring 'permanent-local t)
2076c87c 1725
69c1dd37
RS
1726(defcustom mark-ring-max 16
1727 "*Maximum size of mark ring. Start discarding off end if gets this big."
1728 :type 'integer
1729 :group 'editing-basics)
2076c87c 1730
dc029f0b
RM
1731(defvar global-mark-ring nil
1732 "The list of saved global marks, most recent first.")
1733
69c1dd37 1734(defcustom global-mark-ring-max 16
dc029f0b 1735 "*Maximum size of global mark ring. \
69c1dd37
RS
1736Start discarding off end if gets this big."
1737 :type 'integer
1738 :group 'editing-basics)
dc029f0b 1739
2076c87c
JB
1740(defun set-mark-command (arg)
1741 "Set mark at where point is, or jump to mark.
dc029f0b
RM
1742With no prefix argument, set mark, push old mark position on local mark
1743ring, and push mark on global mark ring.
1744With argument, jump to mark, and pop a new position for mark off the ring
1745\(does not affect global mark ring\).
2076c87c 1746
ff1fbe3e 1747Novice Emacs Lisp programmers often try to use the mark for the wrong
2076c87c
JB
1748purposes. See the documentation of `set-mark' for more information."
1749 (interactive "P")
1750 (if (null arg)
9a1277dd 1751 (progn
fd0f4056 1752 (push-mark nil nil t))
af39530e 1753 (if (null (mark t))
2076c87c 1754 (error "No mark set in this buffer")
9a1277dd 1755 (goto-char (mark t))
2076c87c
JB
1756 (pop-mark))))
1757
fd0f4056 1758(defun push-mark (&optional location nomsg activate)
2076c87c 1759 "Set mark at LOCATION (point, by default) and push old mark on mark ring.
f1382a3d
RM
1760If the last global mark pushed was not in the current buffer,
1761also push LOCATION on the global mark ring.
fd0f4056 1762Display `Mark set' unless the optional second arg NOMSG is non-nil.
8cdc660f 1763In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil.
2076c87c 1764
ff1fbe3e 1765Novice Emacs Lisp programmers often try to use the mark for the wrong
9a1277dd
RS
1766purposes. See the documentation of `set-mark' for more information.
1767
1768In Transient Mark mode, this does not activate the mark."
af39530e 1769 (if (null (mark t))
2076c87c
JB
1770 nil
1771 (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
1772 (if (> (length mark-ring) mark-ring-max)
1773 (progn
1774 (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
1775 (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
9a1277dd 1776 (set-marker (mark-marker) (or location (point)) (current-buffer))
dc029f0b 1777 ;; Now push the mark on the global mark ring.
f1382a3d 1778 (if (and global-mark-ring
e08d3f7c 1779 (eq (marker-buffer (car global-mark-ring)) (current-buffer)))
f1382a3d
RM
1780 ;; The last global mark pushed was in this same buffer.
1781 ;; Don't push another one.
1782 nil
1783 (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
dc029f0b
RM
1784 (if (> (length global-mark-ring) global-mark-ring-max)
1785 (progn
1786 (move-marker (car (nthcdr global-mark-ring-max global-mark-ring))
1787 nil)
f1382a3d 1788 (setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil))))
efcf38c7 1789 (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
2076c87c 1790 (message "Mark set"))
8cdc660f
RS
1791 (if (or activate (not transient-mark-mode))
1792 (set-mark (mark t)))
2076c87c
JB
1793 nil)
1794
1795(defun pop-mark ()
1796 "Pop off mark ring into the buffer's actual mark.
1797Does not set point. Does nothing if mark ring is empty."
1798 (if mark-ring
1799 (progn
1800 (setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
9a1277dd 1801 (set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))
19d35374 1802 (deactivate-mark)
2076c87c 1803 (move-marker (car mark-ring) nil)
9a1277dd 1804 (if (null (mark t)) (ding))
2076c87c
JB
1805 (setq mark-ring (cdr mark-ring)))))
1806
e462e42f 1807(defalias 'exchange-dot-and-mark 'exchange-point-and-mark)
2076c87c 1808(defun exchange-point-and-mark ()
af39530e
RS
1809 "Put the mark where point is now, and point where the mark is now.
1810This command works even when the mark is not active,
1811and it reactivates the mark."
2076c87c 1812 (interactive nil)
af39530e 1813 (let ((omark (mark t)))
2076c87c
JB
1814 (if (null omark)
1815 (error "No mark set in this buffer"))
1816 (set-mark (point))
1817 (goto-char omark)
1818 nil))
e23c2c21 1819
22c3935a 1820(defun transient-mark-mode (arg)
e23c2c21 1821 "Toggle Transient Mark mode.
b411b5fa 1822With arg, turn Transient Mark mode on if arg is positive, off otherwise.
e23c2c21 1823
5dd1220d
RS
1824In Transient Mark mode, when the mark is active, the region is highlighted.
1825Changing the buffer \"deactivates\" the mark.
1826So do certain other operations that set the mark
1827but whose main purpose is something else--for example,
1828incremental search, \\[beginning-of-buffer], and \\[end-of-buffer]."
22c3935a 1829 (interactive "P")
e23c2c21
RS
1830 (setq transient-mark-mode
1831 (if (null arg)
1832 (not transient-mark-mode)
2c5d387c 1833 (> (prefix-numeric-value arg) 0)))
22c3935a
RS
1834 (if (interactive-p)
1835 (if transient-mark-mode
1836 (message "Transient Mark mode enabled")
1837 (message "Transient Mark mode disabled"))))
dc029f0b
RM
1838
1839(defun pop-global-mark ()
1840 "Pop off global mark ring and jump to the top location."
1841 (interactive)
52b6d445
RS
1842 ;; Pop entries which refer to non-existent buffers.
1843 (while (and global-mark-ring (not (marker-buffer (car global-mark-ring))))
1844 (setq global-mark-ring (cdr global-mark-ring)))
dc029f0b
RM
1845 (or global-mark-ring
1846 (error "No global mark set"))
1847 (let* ((marker (car global-mark-ring))
1848 (buffer (marker-buffer marker))
1849 (position (marker-position marker)))
34c31301
RS
1850 (setq global-mark-ring (nconc (cdr global-mark-ring)
1851 (list (car global-mark-ring))))
dc029f0b
RM
1852 (set-buffer buffer)
1853 (or (and (>= position (point-min))
1854 (<= position (point-max)))
1855 (widen))
1856 (goto-char position)
1857 (switch-to-buffer buffer)))
2076c87c 1858\f
69c1dd37
RS
1859(defcustom next-line-add-newlines t
1860 "*If non-nil, `next-line' inserts newline to avoid `end of buffer' error."
1861 :type 'boolean
1862 :group 'editing-basics)
38ebcf29 1863
2076c87c
JB
1864(defun next-line (arg)
1865 "Move cursor vertically down ARG lines.
1866If there is no character in the target line exactly under the current column,
1867the cursor is positioned after the character in that line which spans this
1868column, or at the end of the line if it is not long enough.
38ebcf29 1869If there is no line in the buffer after this one, behavior depends on the
1a2c3941
RS
1870value of `next-line-add-newlines'. If non-nil, it inserts a newline character
1871to create a line, and moves the cursor to that line. Otherwise it moves the
e47d38f6 1872cursor to the end of the buffer.
2076c87c
JB
1873
1874The command \\[set-goal-column] can be used to create
85969cb1
RS
1875a semipermanent goal column for this command.
1876Then instead of trying to move exactly vertically (or as close as possible),
1877this command moves to the specified goal column (or as close as possible).
1878The goal column is stored in the variable `goal-column', which is nil
1879when there is no goal column.
2076c87c
JB
1880
1881If you are thinking of using this in a Lisp program, consider
1882using `forward-line' instead. It is usually easier to use
1883and more reliable (no dependence on goal column, etc.)."
1884 (interactive "p")
028922cf
RS
1885 (if (and next-line-add-newlines (= arg 1))
1886 (let ((opoint (point)))
3534a809
RS
1887 (end-of-line)
1888 (if (eobp)
28191e20 1889 (newline 1)
028922cf
RS
1890 (goto-char opoint)
1891 (line-move arg)))
1a2c3941
RS
1892 (if (interactive-p)
1893 (condition-case nil
1894 (line-move arg)
1895 ((beginning-of-buffer end-of-buffer) (ding)))
1896 (line-move arg)))
2076c87c
JB
1897 nil)
1898
1899(defun previous-line (arg)
1900 "Move cursor vertically up ARG lines.
1901If there is no character in the target line exactly over the current column,
1902the cursor is positioned after the character in that line which spans this
1903column, or at the end of the line if it is not long enough.
1904
1905The command \\[set-goal-column] can be used to create
85969cb1
RS
1906a semipermanent goal column for this command.
1907Then instead of trying to move exactly vertically (or as close as possible),
1908this command moves to the specified goal column (or as close as possible).
1909The goal column is stored in the variable `goal-column', which is nil
1910when there is no goal column.
2076c87c
JB
1911
1912If you are thinking of using this in a Lisp program, consider using
c2e8a012 1913`forward-line' with a negative argument instead. It is usually easier
2076c87c
JB
1914to use and more reliable (no dependence on goal column, etc.)."
1915 (interactive "p")
1a2c3941
RS
1916 (if (interactive-p)
1917 (condition-case nil
1918 (line-move (- arg))
1919 ((beginning-of-buffer end-of-buffer) (ding)))
1920 (line-move (- arg)))
2076c87c
JB
1921 nil)
1922
69c1dd37 1923(defcustom track-eol nil
2076c87c
JB
1924 "*Non-nil means vertical motion starting at end of line keeps to ends of lines.
1925This means moving to the end of each line moved onto.
69c1dd37
RS
1926The beginning of a blank line does not count as the end of a line."
1927 :type 'boolean
1928 :group 'editing-basics)
1929
1930(defcustom goal-column nil
1931 "*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil."
1932 :type '(choice integer
1933 (const :tag "None" nil))
1934 :group 'editing-basics)
912c6728 1935(make-variable-buffer-local 'goal-column)
2076c87c
JB
1936
1937(defvar temporary-goal-column 0
1938 "Current goal column for vertical motion.
1939It is the column where point was
1940at the start of current run of vertical motion commands.
c637ae6f 1941When the `track-eol' feature is doing its job, the value is 9999.")
2076c87c 1942
69c1dd37 1943(defcustom line-move-ignore-invisible nil
098fc1fb 1944 "*Non-nil means \\[next-line] and \\[previous-line] ignore invisible lines.
69c1dd37
RS
1945Outline mode sets this."
1946 :type 'boolean
1947 :group 'editing-basics)
098fc1fb 1948
8c745744
RS
1949;; This is the guts of next-line and previous-line.
1950;; Arg says how many lines to move.
2076c87c 1951(defun line-move (arg)
2596511d
RS
1952 ;; Don't run any point-motion hooks, and disregard intangibility,
1953 ;; for intermediate positions.
1954 (let ((inhibit-point-motion-hooks t)
1955 (opoint (point))
6c8499b9 1956 new line-end line-beg)
2596511d
RS
1957 (unwind-protect
1958 (progn
1959 (if (not (or (eq last-command 'next-line)
1960 (eq last-command 'previous-line)))
1961 (setq temporary-goal-column
1962 (if (and track-eol (eolp)
1963 ;; Don't count beg of empty line as end of line
1964 ;; unless we just did explicit end-of-line.
1965 (or (not (bolp)) (eq last-command 'end-of-line)))
1966 9999
1967 (current-column))))
1968 (if (and (not (integerp selective-display))
1969 (not line-move-ignore-invisible))
1970 ;; Use just newline characters.
1971 (or (if (> arg 0)
1972 (progn (if (> arg 1) (forward-line (1- arg)))
1973 ;; This way of moving forward ARG lines
1974 ;; verifies that we have a newline after the last one.
1975 ;; It doesn't get confused by intangible text.
1976 (end-of-line)
1977 (zerop (forward-line 1)))
1978 (and (zerop (forward-line arg))
1979 (bolp)))
1980 (signal (if (< arg 0)
1981 'beginning-of-buffer
1982 'end-of-buffer)
1983 nil))
1984 ;; Move by arg lines, but ignore invisible ones.
1985 (while (> arg 0)
1986 (end-of-line)
1987 (and (zerop (vertical-motion 1))
1988 (signal 'end-of-buffer nil))
1989 ;; If the following character is currently invisible,
1990 ;; skip all characters with that same `invisible' property value.
1991 (while (and (not (eobp))
1992 (let ((prop
1993 (get-char-property (point) 'invisible)))
1994 (if (eq buffer-invisibility-spec t)
1995 prop
1996 (or (memq prop buffer-invisibility-spec)
1997 (assq prop buffer-invisibility-spec)))))
1998 (if (get-text-property (point) 'invisible)
1999 (goto-char (next-single-property-change (point) 'invisible))
2000 (goto-char (next-overlay-change (point)))))
2001 (setq arg (1- arg)))
2002 (while (< arg 0)
2003 (beginning-of-line)
2004 (and (zerop (vertical-motion -1))
2005 (signal 'beginning-of-buffer nil))
2006 (while (and (not (bobp))
2007 (let ((prop
2008 (get-char-property (1- (point)) 'invisible)))
2009 (if (eq buffer-invisibility-spec t)
2010 prop
2011 (or (memq prop buffer-invisibility-spec)
2012 (assq prop buffer-invisibility-spec)))))
2013 (if (get-text-property (1- (point)) 'invisible)
2014 (goto-char (previous-single-property-change (point) 'invisible))
2015 (goto-char (previous-overlay-change (point)))))
2016 (setq arg (1+ arg))))
0565d307
RS
2017 (let ((buffer-invisibility-spec nil))
2018 (move-to-column (or goal-column temporary-goal-column))))
50be475d
RS
2019 (setq new (point))
2020 ;; If we are moving into some intangible text,
2021 ;; look for following text on the same line which isn't intangible
2022 ;; and move there.
6c8499b9
RS
2023 (setq line-end (save-excursion (end-of-line) (point)))
2024 (setq line-beg (save-excursion (beginning-of-line) (point)))
50be475d
RS
2025 (let ((after (and (< new (point-max))
2026 (get-char-property new 'intangible)))
2027 (before (and (> new (point-min))
6c8499b9
RS
2028 (get-char-property (1- new) 'intangible))))
2029 (when (and before (eq before after)
2030 (not (bolp)))
50be475d
RS
2031 (goto-char (point-min))
2032 (let ((inhibit-point-motion-hooks nil))
2033 (goto-char new))
2034 (if (<= new line-end)
2035 (setq new (point)))))
6c8499b9
RS
2036 ;; NEW is where we want to move to.
2037 ;; LINE-BEG and LINE-END are the beginning and end of the line.
2038 ;; Move there in just one step, from our starting position,
2039 ;; with intangibility and point-motion hooks enabled this time.
2596511d
RS
2040 (goto-char opoint)
2041 (setq inhibit-point-motion-hooks nil)
6c8499b9
RS
2042 (goto-char new)
2043 ;; If intangibility processing moved us to a different line,
2044 ;; readjust the horizontal position within the line we ended up at.
2045 (when (or (< (point) line-beg) (> (point) line-end))
2046 (setq new (point))
2047 (setq inhibit-point-motion-hooks t)
2048 (setq line-end (save-excursion (end-of-line) (point)))
2049 (beginning-of-line)
2050 (setq line-beg (point))
2051 (let ((buffer-invisibility-spec nil))
2052 (move-to-column (or goal-column temporary-goal-column)))
2053 (if (<= (point) line-end)
2054 (setq new (point)))
2055 (goto-char (point-min))
2056 (setq inhibit-point-motion-hooks nil)
2057 (goto-char new)
2058 )))
2596511d 2059 nil)
2076c87c 2060
d5ab2033
JB
2061;;; Many people have said they rarely use this feature, and often type
2062;;; it by accident. Maybe it shouldn't even be on a key.
2063(put 'set-goal-column 'disabled t)
2076c87c
JB
2064
2065(defun set-goal-column (arg)
2066 "Set the current horizontal position as a goal for \\[next-line] and \\[previous-line].
2067Those commands will move to this position in the line moved to
2068rather than trying to keep the same horizontal position.
2069With a non-nil argument, clears out the goal column
912c6728
RS
2070so that \\[next-line] and \\[previous-line] resume vertical motion.
2071The goal column is stored in the variable `goal-column'."
2076c87c
JB
2072 (interactive "P")
2073 (if arg
2074 (progn
2075 (setq goal-column nil)
2076 (message "No goal column"))
2077 (setq goal-column (current-column))
2078 (message (substitute-command-keys
2079 "Goal column %d (use \\[set-goal-column] with an arg to unset it)")
2080 goal-column))
2081 nil)
2082\f
0d5bbbf7
ER
2083;;; Partial support for horizontal autoscrolling. Someday, this feature
2084;;; will be built into the C level and all the (hscroll-point-visible) calls
2085;;; will go away.
2086
69c1dd37 2087(defcustom hscroll-step 0
0d5bbbf7
ER
2088 "*The number of columns to try scrolling a window by when point moves out.
2089If that fails to bring point back on frame, point is centered instead.
69c1dd37
RS
2090If this is zero, point is always centered after it moves off frame."
2091 :type '(choice (const :tag "Alway Center" 0)
2092 (integer :format "%v" 1))
2093 :group 'editing-basics)
0d5bbbf7
ER
2094
2095(defun hscroll-point-visible ()
26c5bf8e
KH
2096 "Scrolls the selected window horizontally to make point visible."
2097 (save-excursion
2098 (set-buffer (window-buffer))
2099 (if (not (or truncate-lines
2100 (> (window-hscroll) 0)
2101 (and truncate-partial-width-windows
2102 (< (window-width) (frame-width)))))
2103 ;; Point is always visible when lines are wrapped.
2104 ()
2105 ;; If point is on the invisible part of the line before window-start,
2106 ;; then hscrolling can't bring it back, so reset window-start first.
2107 (and (< (point) (window-start))
2108 (let ((ws-bol (save-excursion
2109 (goto-char (window-start))
2110 (beginning-of-line)
2111 (point))))
2112 (and (>= (point) ws-bol)
2113 (set-window-start nil ws-bol))))
2114 (let* ((here (hscroll-window-column))
2115 (left (min (window-hscroll) 1))
2116 (right (1- (window-width))))
2117 ;; Allow for the truncation glyph, if we're not exactly at eol.
2118 (if (not (and (= here right)
2119 (= (following-char) ?\n)))
2120 (setq right (1- right)))
2121 (cond
2122 ;; If too far away, just recenter. But don't show too much
2123 ;; white space off the end of the line.
2124 ((or (< here (- left hscroll-step))
2125 (> here (+ right hscroll-step)))
2126 (let ((eol (save-excursion (end-of-line) (hscroll-window-column))))
2127 (scroll-left (min (- here (/ (window-width) 2))
2128 (- eol (window-width) -5)))))
2129 ;; Within range. Scroll by one step (or maybe not at all).
2130 ((< here left)
2131 (scroll-right hscroll-step))
2132 ((> here right)
2133 (scroll-left hscroll-step)))))))
2134
2135;; This function returns the window's idea of the display column of point,
2136;; assuming that the window is already known to be truncated rather than
2137;; wrapped, and that we've already handled the case where point is on the
2138;; part of the line before window-start. We ignore window-width; if point
2139;; is beyond the right margin, we want to know how far. The return value
2140;; includes the effects of window-hscroll, window-start, and the prompt
2141;; string in the minibuffer. It may be negative due to hscroll.
2142(defun hscroll-window-column ()
2143 (let* ((hscroll (window-hscroll))
2144 (startpos (save-excursion
2145 (beginning-of-line)
2146 (if (= (point) (save-excursion
2147 (goto-char (window-start))
2148 (beginning-of-line)
2149 (point)))
2150 (goto-char (window-start)))
2151 (point)))
2152 (hpos (+ (if (and (eq (selected-window) (minibuffer-window))
2153 (= 1 (window-start))
2154 (= startpos (point-min)))
2155 (minibuffer-prompt-width)
2156 0)
2157 (min 0 (- 1 hscroll))))
2158 val)
2159 (car (cdr (compute-motion startpos (cons hpos 0)
2160 (point) (cons 0 1)
2161 1000000 (cons hscroll 0) nil)))))
2162
0d5bbbf7 2163
dff7d67f
RS
2164;; rms: (1) The definitions of arrow keys should not simply restate
2165;; what keys they are. The arrow keys should run the ordinary commands.
2166;; (2) The arrow keys are just one of many common ways of moving point
2167;; within a line. Real horizontal autoscrolling would be a good feature,
2168;; but supporting it only for arrow keys is too incomplete to be desirable.
2169
2170;;;;; Make arrow keys do the right thing for improved terminal support
2171;;;;; When we implement true horizontal autoscrolling, right-arrow and
2172;;;;; left-arrow can lose the (if truncate-lines ...) clause and become
2173;;;;; aliases. These functions are bound to the corresponding keyboard
2174;;;;; events in loaddefs.el.
2175
2176;;(defun right-arrow (arg)
2177;; "Move right one character on the screen (with prefix ARG, that many chars).
2178;;Scroll right if needed to keep point horizontally onscreen."
2179;; (interactive "P")
2180;; (forward-char arg)
2181;; (hscroll-point-visible))
2182
2183;;(defun left-arrow (arg)
2184;; "Move left one character on the screen (with prefix ARG, that many chars).
2185;;Scroll left if needed to keep point horizontally onscreen."
2186;; (interactive "P")
2187;; (backward-char arg)
2188;; (hscroll-point-visible))
7492f5a6
RS
2189
2190(defun scroll-other-window-down (lines)
e47d38f6
RS
2191 "Scroll the \"other window\" down.
2192For more details, see the documentation for `scroll-other-window'."
7492f5a6
RS
2193 (interactive "P")
2194 (scroll-other-window
2195 ;; Just invert the argument's meaning.
2196 ;; We can do that without knowing which window it will be.
2197 (if (eq lines '-) nil
2198 (if (null lines) '-
2199 (- (prefix-numeric-value lines))))))
e47d38f6 2200(define-key esc-map [?\C-\S-v] 'scroll-other-window-down)
3aef9604
RS
2201
2202(defun beginning-of-buffer-other-window (arg)
2203 "Move point to the beginning of the buffer in the other window.
2204Leave mark at previous position.
2205With arg N, put point N/10 of the way from the true beginning."
2206 (interactive "P")
2207 (let ((orig-window (selected-window))
2208 (window (other-window-for-scrolling)))
2209 ;; We use unwind-protect rather than save-window-excursion
2210 ;; because the latter would preserve the things we want to change.
2211 (unwind-protect
2212 (progn
2213 (select-window window)
2214 ;; Set point and mark in that window's buffer.
2215 (beginning-of-buffer arg)
2216 ;; Set point accordingly.
2217 (recenter '(t)))
2218 (select-window orig-window))))
2219
2220(defun end-of-buffer-other-window (arg)
2221 "Move point to the end of the buffer in the other window.
2222Leave mark at previous position.
2223With arg N, put point N/10 of the way from the true end."
2224 (interactive "P")
2225 ;; See beginning-of-buffer-other-window for comments.
2226 (let ((orig-window (selected-window))
2227 (window (other-window-for-scrolling)))
2228 (unwind-protect
2229 (progn
2230 (select-window window)
4500ff36 2231 (end-of-buffer arg)
3aef9604
RS
2232 (recenter '(t)))
2233 (select-window orig-window))))
38ebcf29 2234\f
2076c87c
JB
2235(defun transpose-chars (arg)
2236 "Interchange characters around point, moving forward one character.
2237With prefix arg ARG, effect is to take character before point
2238and drag it forward past ARG other characters (backward if ARG negative).
2239If no argument and at end of line, the previous two chars are exchanged."
2240 (interactive "*P")
2241 (and (null arg) (eolp) (forward-char -1))
2242 (transpose-subr 'forward-char (prefix-numeric-value arg)))
2243
2244(defun transpose-words (arg)
2245 "Interchange words around point, leaving point at end of them.
2246With prefix arg ARG, effect is to take word before or around point
2247and drag it forward past ARG other words (backward if ARG negative).
2248If ARG is zero, the words around or after point and around or after mark
2249are interchanged."
2250 (interactive "*p")
2251 (transpose-subr 'forward-word arg))
2252
2253(defun transpose-sexps (arg)
2254 "Like \\[transpose-words] but applies to sexps.
2255Does not work on a sexp that point is in the middle of
2256if it is a list or string."
2257 (interactive "*p")
2258 (transpose-subr 'forward-sexp arg))
2259
2260(defun transpose-lines (arg)
2261 "Exchange current line and previous line, leaving point after both.
2262With argument ARG, takes previous line and moves it past ARG lines.
2263With argument 0, interchanges line point is in with line mark is in."
2264 (interactive "*p")
2265 (transpose-subr (function
2266 (lambda (arg)
2267 (if (= arg 1)
2268 (progn
2269 ;; Move forward over a line,
2270 ;; but create a newline if none exists yet.
2271 (end-of-line)
2272 (if (eobp)
2273 (newline)
2274 (forward-char 1)))
2275 (forward-line arg))))
2276 arg))
2277
2278(defun transpose-subr (mover arg)
2279 (let (start1 end1 start2 end2)
2280 (if (= arg 0)
2281 (progn
2282 (save-excursion
2283 (funcall mover 1)
2284 (setq end2 (point))
2285 (funcall mover -1)
2286 (setq start2 (point))
2287 (goto-char (mark))
2288 (funcall mover 1)
2289 (setq end1 (point))
2290 (funcall mover -1)
2291 (setq start1 (point))
2292 (transpose-subr-1))
2293 (exchange-point-and-mark)))
2294 (while (> arg 0)
2295 (funcall mover -1)
2296 (setq start1 (point))
2297 (funcall mover 1)
2298 (setq end1 (point))
2299 (funcall mover 1)
2300 (setq end2 (point))
2301 (funcall mover -1)
2302 (setq start2 (point))
2303 (transpose-subr-1)
2304 (goto-char end2)
2305 (setq arg (1- arg)))
2306 (while (< arg 0)
2307 (funcall mover -1)
2308 (setq start2 (point))
2309 (funcall mover -1)
2310 (setq start1 (point))
2311 (funcall mover 1)
2312 (setq end1 (point))
2313 (funcall mover 1)
2314 (setq end2 (point))
2315 (transpose-subr-1)
2316 (setq arg (1+ arg)))))
2317
2318(defun transpose-subr-1 ()
2319 (if (> (min end1 end2) (max start1 start2))
2320 (error "Don't have two things to transpose"))
d5d99b80
KH
2321 (let* ((word1 (buffer-substring start1 end1))
2322 (len1 (length word1))
2323 (word2 (buffer-substring start2 end2))
2324 (len2 (length word2)))
2076c87c
JB
2325 (delete-region start2 end2)
2326 (goto-char start2)
2327 (insert word1)
2328 (goto-char (if (< start1 start2) start1
d5d99b80
KH
2329 (+ start1 (- len1 len2))))
2330 (delete-region (point) (+ (point) len1))
2076c87c
JB
2331 (insert word2)))
2332\f
69c1dd37 2333(defcustom comment-column 32
2076c87c 2334 "*Column to indent right-margin comments to.
8a8fa723
JB
2335Setting this variable automatically makes it local to the current buffer.
2336Each mode establishes a different default value for this variable; you
69c1dd37
RS
2337can set the value for a particular mode using that mode's hook."
2338 :type 'integer
2339 :group 'fill-comments)
2076c87c
JB
2340(make-variable-buffer-local 'comment-column)
2341
69c1dd37
RS
2342(defcustom comment-start nil
2343 "*String to insert to start a new comment, or nil if no comment syntax."
2344 :type '(choice (const :tag "None" nil)
2345 string)
2346 :group 'fill-comments)
2076c87c 2347
69c1dd37 2348(defcustom comment-start-skip nil
2076c87c
JB
2349 "*Regexp to match the start of a comment plus everything up to its body.
2350If there are any \\(...\\) pairs, the comment delimiter text is held to begin
69c1dd37
RS
2351at the place matched by the close of the first pair."
2352 :type '(choice (const :tag "None" nil)
2353 regexp)
2354 :group 'fill-comments)
2076c87c 2355
69c1dd37 2356(defcustom comment-end ""
2076c87c 2357 "*String to insert to end a new comment.
69c1dd37
RS
2358Should be an empty string if comments are terminated by end-of-line."
2359 :type 'string
2360 :group 'fill-comments)
2076c87c 2361
1b43f83f 2362(defvar comment-indent-hook nil
ec9a76e3
JB
2363 "Obsolete variable for function to compute desired indentation for a comment.
2364This function is called with no args with point at the beginning of
2365the comment's starting delimiter.")
2366
1b43f83f 2367(defvar comment-indent-function
2076c87c
JB
2368 '(lambda () comment-column)
2369 "Function to compute desired indentation for a comment.
2370This function is called with no args with point at the beginning of
2371the comment's starting delimiter.")
2372
69c1dd37 2373(defcustom block-comment-start nil
534a0de5
RS
2374 "*String to insert to start a new comment on a line by itself.
2375If nil, use `comment-start' instead.
2376Note that the regular expression `comment-start-skip' should skip this string
69c1dd37
RS
2377as well as the `comment-start' string."
2378 :type '(choice (const :tag "Use comment-start" nil)
2379 string)
2380 :group 'fill-comments)
534a0de5 2381
69c1dd37 2382(defcustom block-comment-end nil
534a0de5
RS
2383 "*String to insert to end a new comment on a line by itself.
2384Should be an empty string if comments are terminated by end-of-line.
69c1dd37
RS
2385If nil, use `comment-end' instead."
2386 :type '(choice (const :tag "Use comment-end" nil)
2387 string)
2388 :group 'fill-comments)
534a0de5 2389
2076c87c
JB
2390(defun indent-for-comment ()
2391 "Indent this line's comment to comment column, or insert an empty comment."
2392 (interactive "*")
534a0de5
RS
2393 (let* ((empty (save-excursion (beginning-of-line)
2394 (looking-at "[ \t]*$")))
2395 (starter (or (and empty block-comment-start) comment-start))
2396 (ender (or (and empty block-comment-end) comment-end)))
2397 (if (null starter)
2398 (error "No comment syntax defined")
2399 (let* ((eolpos (save-excursion (end-of-line) (point)))
2400 cpos indent begpos)
6389928d 2401 (beginning-of-line)
534a0de5
RS
2402 (if (re-search-forward comment-start-skip eolpos 'move)
2403 (progn (setq cpos (point-marker))
2404 ;; Find the start of the comment delimiter.
2405 ;; If there were paren-pairs in comment-start-skip,
2406 ;; position at the end of the first pair.
2407 (if (match-end 1)
2408 (goto-char (match-end 1))
2409 ;; If comment-start-skip matched a string with
2410 ;; internal whitespace (not final whitespace) then
2411 ;; the delimiter start at the end of that
2412 ;; whitespace. Otherwise, it starts at the
2413 ;; beginning of what was matched.
2414 (skip-syntax-backward " " (match-beginning 0))
2415 (skip-syntax-backward "^ " (match-beginning 0)))))
2416 (setq begpos (point))
2417 ;; Compute desired indent.
2418 (if (= (current-column)
2419 (setq indent (if comment-indent-hook
2420 (funcall comment-indent-hook)
2421 (funcall comment-indent-function))))
2422 (goto-char begpos)
2423 ;; If that's different from current, change it.
2424 (skip-chars-backward " \t")
2425 (delete-region (point) begpos)
2426 (indent-to indent))
2427 ;; An existing comment?
2428 (if cpos
2429 (progn (goto-char cpos)
2430 (set-marker cpos nil))
2431 ;; No, insert one.
2432 (insert starter)
2433 (save-excursion
2434 (insert ender)))))))
2076c87c
JB
2435
2436(defun set-comment-column (arg)
2437 "Set the comment column based on point.
2438With no arg, set the comment column to the current column.
2439With just minus as arg, kill any comment on this line.
2440With any other arg, set comment column to indentation of the previous comment
2441 and then align or create a comment on this line at that column."
2442 (interactive "P")
2443 (if (eq arg '-)
2444 (kill-comment nil)
2445 (if arg
2446 (progn
2447 (save-excursion
2448 (beginning-of-line)
2449 (re-search-backward comment-start-skip)
2450 (beginning-of-line)
2451 (re-search-forward comment-start-skip)
2452 (goto-char (match-beginning 0))
2453 (setq comment-column (current-column))
2454 (message "Comment column set to %d" comment-column))
2455 (indent-for-comment))
2456 (setq comment-column (current-column))
2457 (message "Comment column set to %d" comment-column))))
2458
2459(defun kill-comment (arg)
2460 "Kill the comment on this line, if any.
2461With argument, kill comments on that many lines starting with this one."
2462 ;; this function loses in a lot of situations. it incorrectly recognises
2463 ;; comment delimiters sometimes (ergo, inside a string), doesn't work
2464 ;; with multi-line comments, can kill extra whitespace if comment wasn't
2465 ;; through end-of-line, et cetera.
2466 (interactive "P")
2467 (or comment-start-skip (error "No comment syntax defined"))
2468 (let ((count (prefix-numeric-value arg)) endc)
2469 (while (> count 0)
2470 (save-excursion
2471 (end-of-line)
2472 (setq endc (point))
2473 (beginning-of-line)
2474 (and (string< "" comment-end)
2475 (setq endc
2476 (progn
2477 (re-search-forward (regexp-quote comment-end) endc 'move)
2478 (skip-chars-forward " \t")
2479 (point))))
2480 (beginning-of-line)
2481 (if (re-search-forward comment-start-skip endc t)
2482 (progn
2483 (goto-char (match-beginning 0))
2484 (skip-chars-backward " \t")
2485 (kill-region (point) endc)
2486 ;; to catch comments a line beginnings
2487 (indent-according-to-mode))))
2488 (if arg (forward-line 1))
2489 (setq count (1- count)))))
2490
2491(defun comment-region (beg end &optional arg)
f28039bb
RS
2492 "Comment or uncomment each line in the region.
2493With just C-u prefix arg, uncomment each line in region.
2494Numeric prefix arg ARG means use ARG comment characters.
2076c87c
JB
2495If ARG is negative, delete that many comment characters instead.
2496Comments are terminated on each line, even for syntax in which newline does
2497not end the comment. Blank lines do not get comments."
2498 ;; if someone wants it to only put a comment-start at the beginning and
2499 ;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x
2500 ;; is easy enough. No option is made here for other than commenting
2501 ;; every line.
f28039bb 2502 (interactive "r\nP")
2076c87c
JB
2503 (or comment-start (error "No comment syntax is defined"))
2504 (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
2505 (save-excursion
2506 (save-restriction
f28039bb
RS
2507 (let ((cs comment-start) (ce comment-end)
2508 numarg)
2509 (if (consp arg) (setq numarg t)
2510 (setq numarg (prefix-numeric-value arg))
2511 ;; For positive arg > 1, replicate the comment delims now,
2512 ;; then insert the replicated strings just once.
2513 (while (> numarg 1)
2514 (setq cs (concat cs comment-start)
2515 ce (concat ce comment-end))
2516 (setq numarg (1- numarg))))
2517 ;; Loop over all lines from BEG to END.
2076c87c
JB
2518 (narrow-to-region beg end)
2519 (goto-char beg)
2520 (while (not (eobp))
f28039bb
RS
2521 (if (or (eq numarg t) (< numarg 0))
2522 (progn
2523 ;; Delete comment start from beginning of line.
2524 (if (eq numarg t)
2525 (while (looking-at (regexp-quote cs))
2526 (delete-char (length cs)))
2527 (let ((count numarg))
2528 (while (and (> 1 (setq count (1+ count)))
2529 (looking-at (regexp-quote cs)))
2530 (delete-char (length cs)))))
2531 ;; Delete comment end from end of line.
2532 (if (string= "" ce)
2533 nil
2534 (if (eq numarg t)
2535 (progn
2536 (end-of-line)
2537 ;; This is questionable if comment-end ends in
2538 ;; whitespace. That is pretty brain-damaged,
2539 ;; though.
5c8ddcfb
RS
2540 (while (progn (skip-chars-backward " \t")
2541 (and (>= (- (point) (point-min)) (length ce))
2542 (save-excursion
2543 (backward-char (length ce))
2544 (looking-at (regexp-quote ce)))))
f28039bb 2545 (delete-char (- (length ce)))))
ee095968
RS
2546 (let ((count numarg))
2547 (while (> 1 (setq count (1+ count)))
2548 (end-of-line)
2549 ;; this is questionable if comment-end ends in whitespace
2550 ;; that is pretty brain-damaged though
2551 (skip-chars-backward " \t")
2552 (save-excursion
2553 (backward-char (length ce))
2554 (if (looking-at (regexp-quote ce))
2555 (delete-char (length ce))))))))
6e88ed49 2556 (forward-line 1))
f28039bb 2557 ;; Insert at beginning and at end.
2076c87c
JB
2558 (if (looking-at "[ \t]*$") ()
2559 (insert cs)
2560 (if (string= "" ce) ()
2561 (end-of-line)
2562 (insert ce)))
2563 (search-forward "\n" nil 'move)))))))
2564\f
2565(defun backward-word (arg)
2566 "Move backward until encountering the end of a word.
2567With argument, do this that many times.
ff1fbe3e 2568In programs, it is faster to call `forward-word' with negative arg."
9e50756b 2569 (interactive "p")
2076c87c
JB
2570 (forward-word (- arg)))
2571
2572(defun mark-word (arg)
2573 "Set mark arg words away from point."
2574 (interactive "p")
2575 (push-mark
2576 (save-excursion
2577 (forward-word arg)
fd0f4056
RS
2578 (point))
2579 nil t))
2076c87c
JB
2580
2581(defun kill-word (arg)
2582 "Kill characters forward until encountering the end of a word.
2583With argument, do this that many times."
2584 (interactive "p")
e6291fe1 2585 (kill-region (point) (progn (forward-word arg) (point))))
2076c87c
JB
2586
2587(defun backward-kill-word (arg)
2588 "Kill characters backward until encountering the end of a word.
2589With argument, do this that many times."
2590 (interactive "p")
2591 (kill-word (- arg)))
d7c64071 2592
1e8c5ac4
RS
2593(defun current-word (&optional strict)
2594 "Return the word point is on (or a nearby word) as a string.
2595If optional arg STRICT is non-nil, return nil unless point is within
2596or adjacent to a word."
d7c64071
ER
2597 (save-excursion
2598 (let ((oldpoint (point)) (start (point)) (end (point)))
2599 (skip-syntax-backward "w_") (setq start (point))
2600 (goto-char oldpoint)
2601 (skip-syntax-forward "w_") (setq end (point))
2602 (if (and (eq start oldpoint) (eq end oldpoint))
1e8c5ac4
RS
2603 ;; Point is neither within nor adjacent to a word.
2604 (and (not strict)
2605 (progn
2606 ;; Look for preceding word in same line.
2607 (skip-syntax-backward "^w_"
2608 (save-excursion (beginning-of-line)
2609 (point)))
2610 (if (bolp)
2611 ;; No preceding word in same line.
2612 ;; Look for following word in same line.
2613 (progn
2614 (skip-syntax-forward "^w_"
2615 (save-excursion (end-of-line)
2616 (point)))
2617 (setq start (point))
2618 (skip-syntax-forward "w_")
2619 (setq end (point)))
2620 (setq end (point))
2621 (skip-syntax-backward "w_")
2622 (setq start (point)))
020db25f
RS
2623 (buffer-substring-no-properties start end)))
2624 (buffer-substring-no-properties start end)))))
2076c87c 2625\f
69c1dd37 2626(defcustom fill-prefix nil
2076c87c 2627 "*String for filling to insert at front of new line, or nil for none.
69c1dd37
RS
2628Setting this variable automatically makes it local to the current buffer."
2629 :type '(choice (const :tag "None" nil)
2630 string)
2631 :group 'fill)
2076c87c
JB
2632(make-variable-buffer-local 'fill-prefix)
2633
69c1dd37
RS
2634(defcustom auto-fill-inhibit-regexp nil
2635 "*Regexp to match lines which should not be auto-filled."
2636 :type '(choice (const :tag "None" nil)
2637 regexp)
2638 :group 'fill)
2076c87c 2639
b3ac9fa9
RS
2640(defvar comment-line-break-function 'indent-new-comment-line
2641 "*Mode-specific function which line breaks and continues a comment.
2642
2643This function is only called during auto-filling of a comment section.
2644The function should take a single optional argument, which is a flag
2645indicating whether it should use soft newlines.
2646
2647Setting this variable automatically makes it local to the current buffer.")
2648
e2504204
KH
2649;; This function is the auto-fill-function of a buffer
2650;; when Auto-Fill mode is enabled.
2651;; It returns t if it really did any work.
2076c87c 2652(defun do-auto-fill ()
a0170800
RS
2653 (let (fc justify bol give-up
2654 (fill-prefix fill-prefix))
c18465c4 2655 (if (or (not (setq justify (current-justification)))
8f066a20
RS
2656 (null (setq fc (current-fill-column)))
2657 (and (eq justify 'left)
2658 (<= (current-column) fc))
eed5698b
RS
2659 (save-excursion (beginning-of-line)
2660 (setq bol (point))
2661 (and auto-fill-inhibit-regexp
2662 (looking-at auto-fill-inhibit-regexp))))
2663 nil ;; Auto-filling not required
3db1e3b5
BG
2664 (if (memq justify '(full center right))
2665 (save-excursion (unjustify-current-line)))
a0170800
RS
2666
2667 ;; Choose a fill-prefix automatically.
2668 (if (and adaptive-fill-mode
2669 (or (null fill-prefix) (string= fill-prefix "")))
e4b62d7c
RS
2670 (let ((prefix
2671 (fill-context-prefix
2672 (save-excursion (backward-paragraph 1) (point))
50be475d 2673 (save-excursion (forward-paragraph 1) (point)))))
e4b62d7c
RS
2674 (and prefix (not (equal prefix ""))
2675 (setq fill-prefix prefix))))
a0170800 2676
eed5698b 2677 (while (and (not give-up) (> (current-column) fc))
e47d38f6 2678 ;; Determine where to split the line.
db893d00
RS
2679 (let* (after-prefix
2680 (fill-point
2681 (let ((opoint (point))
2682 bounce
2683 (first t))
2684 (save-excursion
2685 (beginning-of-line)
2686 (setq after-prefix (point))
2687 (and fill-prefix
2688 (looking-at (regexp-quote fill-prefix))
2689 (setq after-prefix (match-end 0)))
2690 (move-to-column (1+ fc))
2691 ;; Move back to the point where we can break the
2692 ;; line at. We break the line between word or
2693 ;; after/before the character which has character
2694 ;; category `|'. We search space, \c| followed by
2695 ;; a character, or \c| follwoing a character. If
2696 ;; not found, place the point at beginning of line.
2697 (while (or first
2698 ;; If this is after period and a single space,
2699 ;; move back once more--we don't want to break
2700 ;; the line there and make it look like a
2701 ;; sentence end.
2702 (and (not (bobp))
2703 (not bounce)
2704 sentence-end-double-space
2705 (save-excursion (forward-char -1)
2706 (and (looking-at "\\. ")
2707 (not (looking-at "\\. "))))))
2708 (setq first nil)
2709 (re-search-backward "[ \t]\\|\\c|.\\|.\\c|\\|^")
2710 ;; If we find nowhere on the line to break it,
2711 ;; break after one word. Set bounce to t
2712 ;; so we will not keep going in this while loop.
2713 (if (<= (point) after-prefix)
2714 (progn
2715 (goto-char after-prefix)
2716 (re-search-forward "[ \t]" opoint t)
2717 (setq bounce t))
2718 (if (looking-at "[ \t]")
2719 ;; Break the line at word boundary.
2720 (skip-chars-backward " \t")
2721 ;; Break the line after/before \c|.
2722 (forward-char 1))))
2723 (if (and enable-kinsoku enable-multibyte-characters)
2724 (kinsoku (save-excursion
2725 (forward-line 0) (point))))
2726 ;; Let fill-point be set to the place where we end up.
2727 (point)))))
2728
2729 ;; See whether the place we found is any good.
e47d38f6
RS
2730 (if (save-excursion
2731 (goto-char fill-point)
07f458c1 2732 (and (not (bolp))
db893d00
RS
2733 ;; There is no use breaking at end of line.
2734 (not (save-excursion (skip-chars-forward " ") (eolp)))
2735 ;; It is futile to split at the end of the prefix
2736 ;; since we would just insert the prefix again.
2737 (not (and after-prefix (<= (point) after-prefix)))
07f458c1
RS
2738 ;; Don't split right after a comment starter
2739 ;; since we would just make another comment starter.
2740 (not (and comment-start-skip
2741 (let ((limit (point)))
2742 (beginning-of-line)
2743 (and (re-search-forward comment-start-skip
2744 limit t)
2745 (eq (point) limit)))))))
db893d00 2746 ;; Ok, we have a useful place to break the line. Do it.
e47d38f6
RS
2747 (let ((prev-column (current-column)))
2748 ;; If point is at the fill-point, do not `save-excursion'.
2749 ;; Otherwise, if a comment prefix or fill-prefix is inserted,
2750 ;; point will end up before it rather than after it.
2751 (if (save-excursion
2752 (skip-chars-backward " \t")
2753 (= (point) fill-point))
b3ac9fa9 2754 (funcall comment-line-break-function t)
e47d38f6
RS
2755 (save-excursion
2756 (goto-char fill-point)
b3ac9fa9 2757 (funcall comment-line-break-function t)))
e47d38f6
RS
2758 ;; Now do justification, if required
2759 (if (not (eq justify 'left))
2760 (save-excursion
2761 (end-of-line 0)
2762 (justify-current-line justify nil t)))
2763 ;; If making the new line didn't reduce the hpos of
2764 ;; the end of the line, then give up now;
2765 ;; trying again will not help.
2766 (if (>= (current-column) prev-column)
2767 (setq give-up t)))
db893d00 2768 ;; No good place to break => stop trying.
e47d38f6 2769 (setq give-up t))))
24ebf92e 2770 ;; Justify last line.
e2504204
KH
2771 (justify-current-line justify t t)
2772 t)))
2076c87c 2773
24ebf92e
RS
2774(defvar normal-auto-fill-function 'do-auto-fill
2775 "The function to use for `auto-fill-function' if Auto Fill mode is turned on.
2776Some major modes set this.")
2777
d7465b15 2778(defun auto-fill-mode (&optional arg)
24ebf92e
RS
2779 "Toggle Auto Fill mode.
2780With arg, turn Auto Fill mode on if and only if arg is positive.
2781In Auto Fill mode, inserting a space at a column beyond `current-fill-column'
2782automatically breaks the line at a previous space.
2783
2784The value of `normal-auto-fill-function' specifies the function to use
2785for `auto-fill-function' when turning Auto Fill mode on."
d7465b15
RS
2786 (interactive "P")
2787 (prog1 (setq auto-fill-function
2788 (if (if (null arg)
2789 (not auto-fill-function)
2790 (> (prefix-numeric-value arg) 0))
24ebf92e 2791 normal-auto-fill-function
d7465b15 2792 nil))
7911ecc8 2793 (force-mode-line-update)))
d7465b15
RS
2794
2795;; This holds a document string used to document auto-fill-mode.
2796(defun auto-fill-function ()
2797 "Automatically break line at a previous space, in insertion of text."
2798 nil)
2799
2800(defun turn-on-auto-fill ()
2801 "Unconditionally turn on Auto Fill mode."
2802 (auto-fill-mode 1))
2803
2804(defun set-fill-column (arg)
4cc0ea11
RS
2805 "Set `fill-column' to specified argument.
2806Just \\[universal-argument] as argument means to use the current column."
d7465b15 2807 (interactive "P")
f4520363
RS
2808 (if (consp arg)
2809 (setq arg (current-column)))
2810 (if (not (integerp arg))
2811 ;; Disallow missing argument; it's probably a typo for C-x C-f.
2812 (error "set-fill-column requires an explicit argument")
2813 (message "Fill column set to %d (was %d)" arg fill-column)
2814 (setq fill-column arg)))
d7465b15 2815\f
69c1dd37 2816(defcustom comment-multi-line nil
2076c87c 2817 "*Non-nil means \\[indent-new-comment-line] should continue same comment
c88ab9ce 2818on new line, with no new terminator or starter.
69c1dd37
RS
2819This is obsolete because you might as well use \\[newline-and-indent]."
2820 :type 'boolean
2821 :group 'fill-comments)
2076c87c 2822
28191e20 2823(defun indent-new-comment-line (&optional soft)
d7465b15
RS
2824 "Break line at point and indent, continuing comment if within one.
2825This indents the body of the continued comment
2826under the previous comment line.
c88ab9ce
ER
2827
2828This command is intended for styles where you write a comment per line,
2829starting a new comment (and terminating it if necessary) on each line.
28191e20
RS
2830If you want to continue one comment across several lines, use \\[newline-and-indent].
2831
3a0c4755
RS
2832If a fill column is specified, it overrides the use of the comment column
2833or comment indentation.
2834
28191e20
RS
2835The inserted newline is marked hard if `use-hard-newlines' is true,
2836unless optional argument SOFT is non-nil."
2837 (interactive)
2076c87c
JB
2838 (let (comcol comstart)
2839 (skip-chars-backward " \t")
2840 (delete-region (point)
2841 (progn (skip-chars-forward " \t")
2842 (point)))
eed5698b 2843 (if soft (insert-and-inherit ?\n) (newline 1))
3a0c4755
RS
2844 (if fill-prefix
2845 (progn
2846 (indent-to-left-margin)
2847 (insert-and-inherit fill-prefix))
2848 (if (not comment-multi-line)
2076c87c 2849 (save-excursion
3a0c4755
RS
2850 (if (and comment-start-skip
2851 (let ((opoint (point)))
2852 (forward-line -1)
2853 (re-search-forward comment-start-skip opoint t)))
2854 ;; The old line is a comment.
2855 ;; Set WIN to the pos of the comment-start.
2856 ;; But if the comment is empty, look at preceding lines
2857 ;; to find one that has a nonempty comment.
2858
2859 ;; If comment-start-skip contains a \(...\) pair,
2860 ;; the real comment delimiter starts at the end of that pair.
2861 (let ((win (or (match-end 1) (match-beginning 0))))
2862 (while (and (eolp) (not (bobp))
2863 (let (opoint)
2864 (beginning-of-line)
2865 (setq opoint (point))
2866 (forward-line -1)
2867 (re-search-forward comment-start-skip opoint t)))
2868 (setq win (or (match-end 1) (match-beginning 0))))
2869 ;; Indent this line like what we found.
2870 (goto-char win)
2871 (setq comcol (current-column))
2872 (setq comstart
2873 (buffer-substring (point) (match-end 0)))))))
2874 (if comcol
2875 (let ((comment-column comcol)
2876 (comment-start comstart)
2877 (comment-end comment-end))
2878 (and comment-end (not (equal comment-end ""))
2879 ; (if (not comment-multi-line)
2880 (progn
2881 (forward-char -1)
2882 (insert comment-end)
2883 (forward-char 1))
2884 ; (setq comment-column (+ comment-column (length comment-start))
2885 ; comment-start "")
2886 ; )
2887 )
2888 (if (not (eolp))
2889 (setq comment-end ""))
2890 (insert-and-inherit ?\n)
2891 (forward-char -1)
2892 (indent-for-comment)
2893 (save-excursion
2894 ;; Make sure we delete the newline inserted above.
2895 (end-of-line)
2896 (delete-char 1)))
2897 (indent-according-to-mode)))))
2076c87c
JB
2898\f
2899(defun set-selective-display (arg)
ff1fbe3e
RS
2900 "Set `selective-display' to ARG; clear it if no arg.
2901When the value of `selective-display' is a number > 0,
2902lines whose indentation is >= that value are not displayed.
2903The variable `selective-display' has a separate value for each buffer."
2076c87c
JB
2904 (interactive "P")
2905 (if (eq selective-display t)
2906 (error "selective-display already in use for marked lines"))
c88ab9ce
ER
2907 (let ((current-vpos
2908 (save-restriction
2909 (narrow-to-region (point-min) (point))
2910 (goto-char (window-start))
2911 (vertical-motion (window-height)))))
2912 (setq selective-display
2913 (and arg (prefix-numeric-value arg)))
2914 (recenter current-vpos))
2076c87c
JB
2915 (set-window-start (selected-window) (window-start (selected-window)))
2916 (princ "selective-display set to " t)
2917 (prin1 selective-display t)
2918 (princ "." t))
2919
4f8f7f9f 2920(defvar overwrite-mode-textual " Ovwrt"
b6a22db0 2921 "The string displayed in the mode line when in overwrite mode.")
4f8f7f9f 2922(defvar overwrite-mode-binary " Bin Ovwrt"
b6a22db0
JB
2923 "The string displayed in the mode line when in binary overwrite mode.")
2924
2076c87c
JB
2925(defun overwrite-mode (arg)
2926 "Toggle overwrite mode.
2927With arg, turn overwrite mode on iff arg is positive.
2928In overwrite mode, printing characters typed in replace existing text
b6a22db0
JB
2929on a one-for-one basis, rather than pushing it to the right. At the
2930end of a line, such characters extend the line. Before a tab,
2931such characters insert until the tab is filled in.
2932\\[quoted-insert] still inserts characters in overwrite mode; this
2933is supposed to make it easier to insert characters when necessary."
2934 (interactive "P")
2935 (setq overwrite-mode
2936 (if (if (null arg) (not overwrite-mode)
2937 (> (prefix-numeric-value arg) 0))
2938 'overwrite-mode-textual))
2939 (force-mode-line-update))
2940
2941(defun binary-overwrite-mode (arg)
2942 "Toggle binary overwrite mode.
2943With arg, turn binary overwrite mode on iff arg is positive.
2944In binary overwrite mode, printing characters typed in replace
2945existing text. Newlines are not treated specially, so typing at the
2946end of a line joins the line to the next, with the typed character
2947between them. Typing before a tab character simply replaces the tab
2948with the character typed.
2949\\[quoted-insert] replaces the text at the cursor, just as ordinary
2950typing characters do.
2951
2952Note that binary overwrite mode is not its own minor mode; it is a
2953specialization of overwrite-mode, entered by setting the
2954`overwrite-mode' variable to `overwrite-mode-binary'."
2076c87c
JB
2955 (interactive "P")
2956 (setq overwrite-mode
b6a22db0 2957 (if (if (null arg)
a61099dd 2958 (not (eq overwrite-mode 'overwrite-mode-binary))
b6a22db0
JB
2959 (> (prefix-numeric-value arg) 0))
2960 'overwrite-mode-binary))
2961 (force-mode-line-update))
2076c87c 2962\f
69c1dd37
RS
2963(defcustom line-number-mode t
2964 "*Non-nil means display line number in mode line."
2965 :type 'boolean
2966 :group 'editing-basics)
a61099dd
RS
2967
2968(defun line-number-mode (arg)
2969 "Toggle Line Number mode.
2970With arg, turn Line Number mode on iff arg is positive.
2971When Line Number mode is enabled, the line number appears
2972in the mode line."
2973 (interactive "P")
2974 (setq line-number-mode
2975 (if (null arg) (not line-number-mode)
2976 (> (prefix-numeric-value arg) 0)))
2977 (force-mode-line-update))
2978
69c1dd37
RS
2979(defcustom column-number-mode nil
2980 "*Non-nil means display column number in mode line."
2981 :type 'boolean
2982 :group 'editing-basics)
bcad4985
KH
2983
2984(defun column-number-mode (arg)
2985 "Toggle Column Number mode.
2986With arg, turn Column Number mode on iff arg is positive.
2987When Column Number mode is enabled, the column number appears
2988in the mode line."
2989 (interactive "P")
2990 (setq column-number-mode
2991 (if (null arg) (not column-number-mode)
2992 (> (prefix-numeric-value arg) 0)))
2993 (force-mode-line-update))
2994
4b384a8f 2995(defgroup paren-blinking nil
020db25f 2996 "Blinking matching of parens and expressions."
4b384a8f
SM
2997 :prefix "blink-matching-"
2998 :group 'paren-matching)
2999
69c1dd37
RS
3000(defcustom blink-matching-paren t
3001 "*Non-nil means show matching open-paren when close-paren is inserted."
3002 :type 'boolean
4b384a8f 3003 :group 'paren-blinking)
2076c87c 3004
69c1dd37 3005(defcustom blink-matching-paren-on-screen t
29fc44dd 3006 "*Non-nil means show matching open-paren when it is on screen.
4b384a8f
SM
3007If nil, means don't show it (but the open-paren can still be shown
3008when it is off screen)."
69c1dd37 3009 :type 'boolean
4b384a8f 3010 :group 'paren-blinking)
29fc44dd 3011
4b384a8f 3012(defcustom blink-matching-paren-distance (* 25 1024)
69c1dd37
RS
3013 "*If non-nil, is maximum distance to search for matching open-paren."
3014 :type 'integer
4b384a8f 3015 :group 'paren-blinking)
2076c87c 3016
69c1dd37 3017(defcustom blink-matching-delay 1
4b384a8f
SM
3018 "*Time in seconds to delay after showing a matching paren."
3019 :type 'number
3020 :group 'paren-blinking)
72dddf8b 3021
69c1dd37 3022(defcustom blink-matching-paren-dont-ignore-comments nil
4b384a8f 3023 "*Non-nil means `blink-matching-paren' will not ignore comments."
69c1dd37 3024 :type 'boolean
4b384a8f 3025 :group 'paren-blinking)
903b7f65 3026
2076c87c
JB
3027(defun blink-matching-open ()
3028 "Move cursor momentarily to the beginning of the sexp before point."
3029 (interactive)
3030 (and (> (point) (1+ (point-min)))
2076c87c 3031 blink-matching-paren
7e1ddd45
RS
3032 ;; Verify an even number of quoting characters precede the close.
3033 (= 1 (logand 1 (- (point)
3034 (save-excursion
3035 (forward-char -1)
3036 (skip-syntax-backward "/\\")
3037 (point)))))
2076c87c
JB
3038 (let* ((oldpos (point))
3039 (blinkpos)
3040 (mismatch))
3041 (save-excursion
3042 (save-restriction
3043 (if blink-matching-paren-distance
3044 (narrow-to-region (max (point-min)
3045 (- (point) blink-matching-paren-distance))
3046 oldpos))
3047 (condition-case ()
903b7f65
RS
3048 (let ((parse-sexp-ignore-comments
3049 (and parse-sexp-ignore-comments
3050 (not blink-matching-paren-dont-ignore-comments))))
3051 (setq blinkpos (scan-sexps oldpos -1)))
2076c87c 3052 (error nil)))
903b7f65
RS
3053 (and blinkpos
3054 (/= (char-syntax (char-after blinkpos))
3055 ?\$)
2076c87c 3056 (setq mismatch
903b7f65
RS
3057 (or (null (matching-paren (char-after blinkpos)))
3058 (/= (char-after (1- oldpos))
3059 (matching-paren (char-after blinkpos))))))
2076c87c
JB
3060 (if mismatch (setq blinkpos nil))
3061 (if blinkpos
3062 (progn
3063 (goto-char blinkpos)
3064 (if (pos-visible-in-window-p)
29fc44dd
KH
3065 (and blink-matching-paren-on-screen
3066 (sit-for blink-matching-delay))
2076c87c
JB
3067 (goto-char blinkpos)
3068 (message
3069 "Matches %s"
e9f1d66d 3070 ;; Show what precedes the open in its line, if anything.
2076c87c
JB
3071 (if (save-excursion
3072 (skip-chars-backward " \t")
3073 (not (bolp)))
3074 (buffer-substring (progn (beginning-of-line) (point))
3075 (1+ blinkpos))
e9f1d66d
RS
3076 ;; Show what follows the open in its line, if anything.
3077 (if (save-excursion
3078 (forward-char 1)
3079 (skip-chars-forward " \t")
3080 (not (eolp)))
3081 (buffer-substring blinkpos
3082 (progn (end-of-line) (point)))
267935b9
RS
3083 ;; Otherwise show the previous nonblank line,
3084 ;; if there is one.
3085 (if (save-excursion
3086 (skip-chars-backward "\n \t")
3087 (not (bobp)))
3088 (concat
3089 (buffer-substring (progn
3090 (skip-chars-backward "\n \t")
3091 (beginning-of-line)
3092 (point))
3093 (progn (end-of-line)
3094 (skip-chars-backward " \t")
3095 (point)))
3096 ;; Replace the newline and other whitespace with `...'.
3097 "..."
3098 (buffer-substring blinkpos (1+ blinkpos)))
3099 ;; There is nothing to show except the char itself.
3100 (buffer-substring blinkpos (1+ blinkpos))))))))
2076c87c
JB
3101 (cond (mismatch
3102 (message "Mismatched parentheses"))
3103 ((not blink-matching-paren-distance)
3104 (message "Unmatched parenthesis"))))))))
3105
3106;Turned off because it makes dbx bomb out.
3107(setq blink-paren-function 'blink-matching-open)
3108
9a1277dd
RS
3109;; This executes C-g typed while Emacs is waiting for a command.
3110;; Quitting out of a program does not go through here;
3111;; that happens in the QUIT macro at the C code level.
2076c87c 3112(defun keyboard-quit ()
af39530e
RS
3113 "Signal a quit condition.
3114During execution of Lisp code, this character causes a quit directly.
3115At top-level, as an editor command, this simply beeps."
2076c87c 3116 (interactive)
19d35374 3117 (deactivate-mark)
2076c87c
JB
3118 (signal 'quit nil))
3119
3120(define-key global-map "\C-g" 'keyboard-quit)
c66587fe 3121
1c6c6fde
RS
3122(defvar buffer-quit-function nil
3123 "Function to call to \"quit\" the current buffer, or nil if none.
3124\\[keyboard-escape-quit] calls this function when its more local actions
3125\(such as cancelling a prefix argument, minibuffer or region) do not apply.")
3126
c66587fe
RS
3127(defun keyboard-escape-quit ()
3128 "Exit the current \"mode\" (in a generalized sense of the word).
3129This command can exit an interactive command such as `query-replace',
3130can clear out a prefix argument or a region,
3131can get out of the minibuffer or other recursive edit,
1c6c6fde
RS
3132cancel the use of the current buffer (for special-purpose buffers),
3133or go back to just one window (by deleting all but the selected window)."
c66587fe
RS
3134 (interactive)
3135 (cond ((eq last-command 'mode-exited) nil)
3136 ((> (minibuffer-depth) 0)
3137 (abort-recursive-edit))
3138 (current-prefix-arg
3139 nil)
3140 ((and transient-mark-mode
3141 mark-active)
3142 (deactivate-mark))
1b657835
RS
3143 ((> (recursion-depth) 0)
3144 (exit-recursive-edit))
1c6c6fde
RS
3145 (buffer-quit-function
3146 (funcall buffer-quit-function))
c66587fe 3147 ((not (one-window-p t))
1b657835
RS
3148 (delete-other-windows))
3149 ((string-match "^ \\*" (buffer-name (current-buffer)))
3150 (bury-buffer))))
c66587fe 3151
1c6c6fde 3152(define-key global-map "\e\e\e" 'keyboard-escape-quit)
2076c87c 3153\f
69c1dd37 3154(defcustom mail-user-agent 'sendmail-user-agent
a31ca314
RS
3155 "*Your preference for a mail composition package.
3156Various Emacs Lisp packages (e.g. reporter) require you to compose an
3157outgoing email message. This variable lets you specify which
3158mail-sending package you prefer.
3159
3160Valid values include:
3161
3183b230
RS
3162 sendmail-user-agent -- use the default Emacs Mail package
3163 mh-e-user-agent -- use the Emacs interface to the MH mail system
3164 message-user-agent -- use the GNUS mail sending package
a31ca314
RS
3165
3166Additional valid symbols may be available; check with the author of
69c1dd37
RS
3167your package for details."
3168 :type '(radio (function-item :tag "Default Emacs mail"
3169 :format "%t\n"
3170 sendmail-user-agent)
3171 (function-item :tag "Emacs interface to MH"
3172 :format "%t\n"
3173 mh-e-user-agent)
3174 (function-item :tag "Gnus mail sending package"
3175 :format "%t\n"
3176 message-user-agent)
3177 (function :tag "Other"))
3178 :group 'mail)
a31ca314
RS
3179
3180(defun define-mail-user-agent (symbol composefunc sendfunc
3181 &optional abortfunc hookvar)
3182 "Define a symbol to identify a mail-sending package for `mail-user-agent'.
3183
3184SYMBOL can be any Lisp symbol. Its function definition and/or
3185value as a variable do not matter for this usage; we use only certain
3186properties on its property list, to encode the rest of the arguments.
3187
3188COMPOSEFUNC is program callable function that composes an outgoing
3189mail message buffer. This function should set up the basics of the
3190buffer without requiring user interaction. It should populate the
3183b230
RS
3191standard mail headers, leaving the `to:' and `subject:' headers blank
3192by default.
a31ca314 3193
d0008a00
RS
3194COMPOSEFUNC should accept several optional arguments--the same
3195arguments that `compose-mail' takes. See that function's documentation.
a31ca314 3196
3183b230
RS
3197SENDFUNC is the command a user would run to send the message.
3198
3199Optional ABORTFUNC is the command a user would run to abort the
a31ca314
RS
3200message. For mail packages that don't have a separate abort function,
3201this can be `kill-buffer' (the equivalent of omitting this argument).
3202
3203Optional HOOKVAR is a hook variable that gets run before the message
3183b230
RS
3204is actually sent. Callers that use the `mail-user-agent' may
3205install a hook function temporarily on this hook variable.
3206If HOOKVAR is nil, `mail-send-hook' is used.
a31ca314
RS
3207
3208The properties used on SYMBOL are `composefunc', `sendfunc',
3209`abortfunc', and `hookvar'."
3210 (put symbol 'composefunc composefunc)
3211 (put symbol 'sendfunc sendfunc)
3212 (put symbol 'abortfunc (or abortfunc 'kill-buffer))
3213 (put symbol 'hookvar (or hookvar 'mail-send-hook)))
3214
d0008a00
RS
3215(defun assoc-ignore-case (key alist)
3216 "Like `assoc', but assumes KEY is a string and ignores case when comparing."
53efb707 3217 (setq key (downcase key))
d0008a00
RS
3218 (let (element)
3219 (while (and alist (not element))
3220 (if (equal key (downcase (car (car alist))))
3221 (setq element (car alist)))
3222 (setq alist (cdr alist)))
3223 element))
3224
a31ca314 3225(define-mail-user-agent 'sendmail-user-agent
34fbcdf3 3226 'sendmail-user-agent-compose
a31ca314
RS
3227 'mail-send-and-exit)
3228
34fbcdf3
RS
3229(defun sendmail-user-agent-compose (&optional to subject other-headers continue
3230 switch-function yank-action
3231 send-actions)
3232 (if switch-function
3233 (let ((special-display-buffer-names nil)
3234 (special-display-regexps nil)
3235 (same-window-buffer-names nil)
3236 (same-window-regexps nil))
3237 (funcall switch-function "*mail*")))
3238 (let ((cc (cdr (assoc-ignore-case "cc" other-headers)))
3239 (in-reply-to (cdr (assoc-ignore-case "in-reply-to" other-headers))))
3240 (or (mail continue to subject in-reply-to cc yank-action send-actions)
3241 continue
3242 (error "Message aborted"))
3243 (save-excursion
3244 (goto-char (point-min))
3245 (search-forward mail-header-separator)
3246 (beginning-of-line)
3247 (while other-headers
3248 (if (not (member (car (car other-headers)) '("in-reply-to" "cc")))
3249 (insert (car (car other-headers)) ": "
3250 (cdr (car other-headers)) "\n"))
3251 (setq other-headers (cdr other-headers)))
3252 t)))
3253
a31ca314
RS
3254(define-mail-user-agent 'mh-e-user-agent
3255 'mh-smail-batch 'mh-send-letter 'mh-fully-kill-draft
3256 'mh-before-send-letter-hook)
d0008a00
RS
3257
3258(defun compose-mail (&optional to subject other-headers continue
3259 switch-function yank-action send-actions)
3260 "Start composing a mail message to send.
3261This uses the user's chosen mail composition package
3262as selected with the variable `mail-user-agent'.
3263The optional arguments TO and SUBJECT specify recipients
3264and the initial Subject field, respectively.
3265
3266OTHER-HEADERS is an alist specifying additional
3267header fields. Elements look like (HEADER . VALUE) where both
3268HEADER and VALUE are strings.
3269
3270CONTINUE, if non-nil, says to continue editing a message already
3271being composed.
3272
3273SWITCH-FUNCTION, if non-nil, is a function to use to
3274switch to and display the buffer used for mail composition.
3275
3276YANK-ACTION, if non-nil, is an action to perform, if and when necessary,
06720de2
RS
3277to insert the raw text of the message being replied to.
3278It has the form (FUNCTION . ARGS). The user agent will apply
3279FUNCTION to ARGS, to insert the raw text of the original message.
3280\(The user agent will also run `mail-citation-hook', *after* the
3281original text has been inserted in this way.)
d0008a00
RS
3282
3283SEND-ACTIONS is a list of actions to call when the message is sent.
3284Each action has the form (FUNCTION . ARGS)."
b5f019be
RS
3285 (interactive
3286 (list nil nil nil current-prefix-arg))
d0008a00
RS
3287 (let ((function (get mail-user-agent 'composefunc)))
3288 (funcall function to subject other-headers continue
3289 switch-function yank-action send-actions)))
b5f019be
RS
3290
3291(defun compose-mail-other-window (&optional to subject other-headers continue
3292 yank-action send-actions)
3293 "Like \\[compose-mail], but edit the outgoing message in another window."
3294 (interactive
3295 (list nil nil nil current-prefix-arg))
3296 (compose-mail to subject other-headers continue
3297 'switch-to-buffer-other-window yank-action send-actions))
3298
3299
3300(defun compose-mail-other-frame (&optional to subject other-headers continue
3301 yank-action send-actions)
3302 "Like \\[compose-mail], but edit the outgoing message in another frame."
3303 (interactive
3304 (list nil nil nil current-prefix-arg))
3305 (compose-mail to subject other-headers continue
3306 'switch-to-buffer-other-frame yank-action send-actions))
a31ca314 3307\f
610c1c68
RS
3308(defvar set-variable-value-history nil
3309 "History of values entered with `set-variable'.")
3310
3311(defun set-variable (var val)
3312 "Set VARIABLE to VALUE. VALUE is a Lisp object.
3313When using this interactively, enter a Lisp object for VALUE.
3314If you want VALUE to be a string, you must surround it with doublequotes.
3315VALUE is used literally, not evaluated.
3316
3317If VARIABLE has a `variable-interactive' property, that is used as if
3318it were the arg to `interactive' (which see) to interactively read VALUE.
3319
3320If VARIABLE has been defined with `defcustom', then the type information
3321in the definition is used to check that VALUE is valid."
3322 (interactive (let* ((var (read-variable "Set variable: "))
3323 (minibuffer-help-form '(describe-variable var))
3324 (prop (get var 'variable-interactive))
3325 (prompt (format "Set %s to value: " var))
3326 (val (if prop
3327 ;; Use VAR's `variable-interactive' property
3328 ;; as an interactive spec for prompting.
3329 (call-interactively `(lambda (arg)
3330 (interactive ,prop)
3331 arg))
3332 (read
3333 (read-string prompt nil
3334 'set-variable-value-history)))))
3335 (list var val)))
3336
f8496faa 3337 (let ((type (get var 'custom-type)))
610c1c68
RS
3338 (when type
3339 ;; Match with custom type.
3340 (require 'wid-edit)
610c1c68
RS
3341 (setq type (widget-convert type))
3342 (unless (widget-apply type :match val)
3343 (error "Value `%S' does not match type %S of %S"
3344 val (car type) var))))
3345 (set var val))
e8a700bf
RS
3346\f
3347;; Define the major mode for lists of completions.
3348
98b45886
RS
3349(defvar completion-list-mode-map nil
3350 "Local map for completion list buffers.")
ac29eb79 3351(or completion-list-mode-map
e8a700bf
RS
3352 (let ((map (make-sparse-keymap)))
3353 (define-key map [mouse-2] 'mouse-choose-completion)
eaf76065 3354 (define-key map [down-mouse-2] nil)
80298193 3355 (define-key map "\C-m" 'choose-completion)
1c6c6fde 3356 (define-key map "\e\e\e" 'delete-completion-window)
dde69dbe
RS
3357 (define-key map [left] 'previous-completion)
3358 (define-key map [right] 'next-completion)
ac29eb79 3359 (setq completion-list-mode-map map)))
e8a700bf
RS
3360
3361;; Completion mode is suitable only for specially formatted data.
ac29eb79 3362(put 'completion-list-mode 'mode-class 'special)
e8a700bf 3363
98b45886
RS
3364(defvar completion-reference-buffer nil
3365 "Record the buffer that was current when the completion list was requested.
3366This is a local variable in the completion list buffer.
ec39964e 3367Initial value is nil to avoid some compiler warnings.")
3819736b 3368
83434bda
RS
3369(defvar completion-no-auto-exit nil
3370 "Non-nil means `choose-completion-string' should never exit the minibuffer.
3371This also applies to other functions such as `choose-completion'
3372and `mouse-choose-completion'.")
3373
98b45886
RS
3374(defvar completion-base-size nil
3375 "Number of chars at beginning of minibuffer not involved in completion.
3376This is a local variable in the completion list buffer
3377but it talks about the buffer in `completion-reference-buffer'.
3378If this is nil, it means to compare text to determine which part
3379of the tail end of the buffer's text is involved in completion.")
f6b293e3 3380
1c6c6fde
RS
3381(defun delete-completion-window ()
3382 "Delete the completion list window.
3383Go to the window from which completion was requested."
3384 (interactive)
3385 (let ((buf completion-reference-buffer))
ddb2b181
RS
3386 (if (one-window-p t)
3387 (if (window-dedicated-p (selected-window))
3388 (delete-frame (selected-frame)))
3389 (delete-window (selected-window))
3390 (if (get-buffer-window buf)
3391 (select-window (get-buffer-window buf))))))
1c6c6fde 3392
dde69dbe
RS
3393(defun previous-completion (n)
3394 "Move to the previous item in the completion list."
3395 (interactive "p")
3396 (next-completion (- n)))
3397
3398(defun next-completion (n)
3399 "Move to the next item in the completion list.
1f238ac2 3400With prefix argument N, move N items (negative N means move backward)."
dde69dbe
RS
3401 (interactive "p")
3402 (while (and (> n 0) (not (eobp)))
b61a81c2
RS
3403 (let ((prop (get-text-property (point) 'mouse-face))
3404 (end (point-max)))
dde69dbe
RS
3405 ;; If in a completion, move to the end of it.
3406 (if prop
b61a81c2 3407 (goto-char (next-single-property-change (point) 'mouse-face nil end)))
dde69dbe 3408 ;; Move to start of next one.
b61a81c2 3409 (goto-char (next-single-property-change (point) 'mouse-face nil end)))
dde69dbe
RS
3410 (setq n (1- n)))
3411 (while (and (< n 0) (not (bobp)))
b61a81c2
RS
3412 (let ((prop (get-text-property (1- (point)) 'mouse-face))
3413 (end (point-min)))
dde69dbe
RS
3414 ;; If in a completion, move to the start of it.
3415 (if prop
b61a81c2
RS
3416 (goto-char (previous-single-property-change
3417 (point) 'mouse-face nil end)))
dde69dbe 3418 ;; Move to end of the previous completion.
b61a81c2 3419 (goto-char (previous-single-property-change (point) 'mouse-face nil end))
dde69dbe 3420 ;; Move to the start of that one.
b61a81c2 3421 (goto-char (previous-single-property-change (point) 'mouse-face nil end)))
dde69dbe
RS
3422 (setq n (1+ n))))
3423
80298193
RS
3424(defun choose-completion ()
3425 "Choose the completion that point is in or next to."
3426 (interactive)
f6b293e3
RS
3427 (let (beg end completion (buffer completion-reference-buffer)
3428 (base-size completion-base-size))
6096f362
RS
3429 (if (and (not (eobp)) (get-text-property (point) 'mouse-face))
3430 (setq end (point) beg (1+ (point))))
3431 (if (and (not (bobp)) (get-text-property (1- (point)) 'mouse-face))
3f299281 3432 (setq end (1- (point)) beg (point)))
6096f362
RS
3433 (if (null beg)
3434 (error "No completion here"))
3435 (setq beg (previous-single-property-change beg 'mouse-face))
88dd3c24 3436 (setq end (or (next-single-property-change end 'mouse-face) (point-max)))
ab63960f
RS
3437 (setq completion (buffer-substring beg end))
3438 (let ((owindow (selected-window)))
3439 (if (and (one-window-p t 'selected-frame)
3440 (window-dedicated-p (selected-window)))
3441 ;; This is a special buffer's frame
3442 (iconify-frame (selected-frame))
3443 (or (window-dedicated-p (selected-window))
3444 (bury-buffer)))
3445 (select-window owindow))
f6b293e3 3446 (choose-completion-string completion buffer base-size)))
80298193
RS
3447
3448;; Delete the longest partial match for STRING
3449;; that can be found before POINT.
3450(defun choose-completion-delete-max-match (string)
3451 (let ((opoint (point))
3452 (len (min (length string)
3453 (- (point) (point-min)))))
3454 (goto-char (- (point) (length string)))
61bbf6fe
RS
3455 (if completion-ignore-case
3456 (setq string (downcase string)))
80298193
RS
3457 (while (and (> len 0)
3458 (let ((tail (buffer-substring (point)
3459 (+ (point) len))))
61bbf6fe
RS
3460 (if completion-ignore-case
3461 (setq tail (downcase tail)))
80298193
RS
3462 (not (string= tail (substring string 0 len)))))
3463 (setq len (1- len))
3464 (forward-char 1))
3465 (delete-char len)))
3466
98b45886
RS
3467;; Switch to BUFFER and insert the completion choice CHOICE.
3468;; BASE-SIZE, if non-nil, says how many characters of BUFFER's text
3469;; to keep. If it is nil, use choose-completion-delete-max-match instead.
74d0290b
RS
3470
3471;; If BUFFER is the minibuffer, exit the minibuffer
83434bda
RS
3472;; unless it is reading a file name and CHOICE is a directory,
3473;; or completion-no-auto-exit is non-nil.
f6b293e3 3474(defun choose-completion-string (choice &optional buffer base-size)
80298193 3475 (let ((buffer (or buffer completion-reference-buffer)))
cf52ad58
RS
3476 ;; If BUFFER is a minibuffer, barf unless it's the currently
3477 ;; active minibuffer.
3478 (if (and (string-match "\\` \\*Minibuf-[0-9]+\\*\\'" (buffer-name buffer))
45486731
RS
3479 (or (not (active-minibuffer-window))
3480 (not (equal buffer
3481 (window-buffer (active-minibuffer-window))))))
cf52ad58
RS
3482 (error "Minibuffer is not active for completion")
3483 ;; Insert the completion into the buffer where completion was requested.
3484 (set-buffer buffer)
f6b293e3
RS
3485 (if base-size
3486 (delete-region (+ base-size (point-min)) (point))
3487 (choose-completion-delete-max-match choice))
cf52ad58 3488 (insert choice)
63240af1
RS
3489 (remove-text-properties (- (point) (length choice)) (point)
3490 '(mouse-face nil))
cf52ad58
RS
3491 ;; Update point in the window that BUFFER is showing in.
3492 (let ((window (get-buffer-window buffer t)))
3493 (set-window-point window (point)))
3494 ;; If completing for the minibuffer, exit it with this choice.
83434bda
RS
3495 (and (not completion-no-auto-exit)
3496 (equal buffer (window-buffer (minibuffer-window)))
8881ad9a 3497 minibuffer-completion-table
74d0290b
RS
3498 ;; If this is reading a file name, and the file name chosen
3499 ;; is a directory, don't exit the minibuffer.
3500 (if (and (eq minibuffer-completion-table 'read-file-name-internal)
3501 (file-directory-p (buffer-string)))
3502 (select-window (active-minibuffer-window))
3503 (exit-minibuffer))))))
80298193 3504
ac29eb79 3505(defun completion-list-mode ()
e8a700bf 3506 "Major mode for buffers showing lists of possible completions.
80298193
RS
3507Type \\<completion-list-mode-map>\\[choose-completion] in the completion list\
3508 to select the completion near point.
3509Use \\<completion-list-mode-map>\\[mouse-choose-completion] to select one\
3510 with the mouse."
e8a700bf
RS
3511 (interactive)
3512 (kill-all-local-variables)
ac29eb79
RS
3513 (use-local-map completion-list-mode-map)
3514 (setq mode-name "Completion List")
3515 (setq major-mode 'completion-list-mode)
f6b293e3
RS
3516 (make-local-variable 'completion-base-size)
3517 (setq completion-base-size nil)
ac29eb79 3518 (run-hooks 'completion-list-mode-hook))
e8a700bf 3519
98b45886
RS
3520(defvar completion-fixup-function nil
3521 "A function to customize how completions are identified in completion lists.
3522`completion-setup-function' calls this function with no arguments
3523each time it has found what it thinks is one completion.
3524Point is at the end of the completion in the completion list buffer.
3525If this function moves point, it can alter the end of that completion.")
3526
3527;; This function goes in completion-setup-hook, so that it is called
3528;; after the text of the completion list buffer is written.
6096f362 3529
e8a700bf
RS
3530(defun completion-setup-function ()
3531 (save-excursion
98b45886 3532 (let ((mainbuf (current-buffer)))
3819736b
RS
3533 (set-buffer standard-output)
3534 (completion-list-mode)
3535 (make-local-variable 'completion-reference-buffer)
3536 (setq completion-reference-buffer mainbuf)
50be475d
RS
3537 (if (eq minibuffer-completion-table 'read-file-name-internal)
3538 ;; For file name completion,
3539 ;; use the number of chars before the start of the
3540 ;; last file name component.
3541 (setq completion-base-size
3542 (save-excursion
3543 (set-buffer mainbuf)
3544 (goto-char (point-max))
3545 (skip-chars-backward (format "^%c" directory-sep-char))
3546 (- (point) (point-min))))
19183a29
RS
3547 ;; Otherwise, in minibuffer, the whole input is being completed.
3548 (save-match-data
3549 (if (string-match "\\` \\*Minibuf-[0-9]+\\*\\'"
3550 (buffer-name mainbuf))
3551 (setq completion-base-size 0))))
3819736b
RS
3552 (goto-char (point-min))
3553 (if window-system
3554 (insert (substitute-command-keys
80298193
RS
3555 "Click \\[mouse-choose-completion] on a completion to select it.\n")))
3556 (insert (substitute-command-keys
3557 "In this buffer, type \\[choose-completion] to \
c26bb96e
KH
3558select the completion near point.\n\n"))
3559 (forward-line 1)
6096f362
RS
3560 (while (re-search-forward "[^ \t\n]+\\( [^ \t\n]+\\)*" nil t)
3561 (let ((beg (match-beginning 0))
3562 (end (point)))
3563 (if completion-fixup-function
3564 (funcall completion-fixup-function))
3565 (put-text-property beg (point) 'mouse-face 'highlight)
3566 (goto-char end))))))
c88ab9ce 3567
e8a700bf 3568(add-hook 'completion-setup-hook 'completion-setup-function)
dde69dbe
RS
3569
3570(define-key minibuffer-local-completion-map [prior]
3571 'switch-to-completions)
3572(define-key minibuffer-local-must-match-map [prior]
3573 'switch-to-completions)
3574(define-key minibuffer-local-completion-map "\M-v"
3575 'switch-to-completions)
3576(define-key minibuffer-local-must-match-map "\M-v"
3577 'switch-to-completions)
3578
3579(defun switch-to-completions ()
3580 "Select the completion list window."
3581 (interactive)
9595fbdb
RS
3582 ;; Make sure we have a completions window.
3583 (or (get-buffer-window "*Completions*")
3584 (minibuffer-completion-help))
dde69dbe
RS
3585 (select-window (get-buffer-window "*Completions*"))
3586 (goto-char (point-min))
3587 (search-forward "\n\n")
3588 (forward-line 1))
a3d1480b 3589\f
82072f33
RS
3590;; Support keyboard commands to turn on various modifiers.
3591
3592;; These functions -- which are not commands -- each add one modifier
3593;; to the following event.
3594
3595(defun event-apply-alt-modifier (ignore-prompt)
3596 (vector (event-apply-modifier (read-event) 'alt 22 "A-")))
3597(defun event-apply-super-modifier (ignore-prompt)
3598 (vector (event-apply-modifier (read-event) 'super 23 "s-")))
3599(defun event-apply-hyper-modifier (ignore-prompt)
3600 (vector (event-apply-modifier (read-event) 'hyper 24 "H-")))
3601(defun event-apply-shift-modifier (ignore-prompt)
3602 (vector (event-apply-modifier (read-event) 'shift 25 "S-")))
3603(defun event-apply-control-modifier (ignore-prompt)
3604 (vector (event-apply-modifier (read-event) 'control 26 "C-")))
3605(defun event-apply-meta-modifier (ignore-prompt)
3606 (vector (event-apply-modifier (read-event) 'meta 27 "M-")))
3607
3608(defun event-apply-modifier (event symbol lshiftby prefix)
3609 "Apply a modifier flag to event EVENT.
3610SYMBOL is the name of this modifier, as a symbol.
3611LSHIFTBY is the numeric value of this modifier, in keyboard events.
3612PREFIX is the string that represents this modifier in an event type symbol."
3613 (if (numberp event)
3614 (cond ((eq symbol 'control)
90bebcb0
KH
3615 (if (and (<= (downcase event) ?z)
3616 (>= (downcase event) ?a))
82072f33 3617 (- (downcase event) ?a -1)
90bebcb0
KH
3618 (if (and (<= (downcase event) ?Z)
3619 (>= (downcase event) ?A))
82072f33
RS
3620 (- (downcase event) ?A -1)
3621 (logior (lsh 1 lshiftby) event))))
3622 ((eq symbol 'shift)
3623 (if (and (<= (downcase event) ?z)
3624 (>= (downcase event) ?a))
3625 (upcase event)
3626 (logior (lsh 1 lshiftby) event)))
3627 (t
3628 (logior (lsh 1 lshiftby) event)))
3629 (if (memq symbol (event-modifiers event))
3630 event
3631 (let ((event-type (if (symbolp event) event (car event))))
3632 (setq event-type (intern (concat prefix (symbol-name event-type))))
3633 (if (symbolp event)
3634 event-type
3635 (cons event-type (cdr event)))))))
3636
e5fff738
KH
3637(define-key function-key-map [?\C-x ?@ ?h] 'event-apply-hyper-modifier)
3638(define-key function-key-map [?\C-x ?@ ?s] 'event-apply-super-modifier)
3639(define-key function-key-map [?\C-x ?@ ?m] 'event-apply-meta-modifier)
3640(define-key function-key-map [?\C-x ?@ ?a] 'event-apply-alt-modifier)
3641(define-key function-key-map [?\C-x ?@ ?S] 'event-apply-shift-modifier)
3642(define-key function-key-map [?\C-x ?@ ?c] 'event-apply-control-modifier)
82072f33 3643\f
a3d1480b
JB
3644;;;; Keypad support.
3645
3646;;; Make the keypad keys act like ordinary typing keys. If people add
3647;;; bindings for the function key symbols, then those bindings will
3648;;; override these, so this shouldn't interfere with any existing
3649;;; bindings.
3650
0d173134 3651;; Also tell read-char how to handle these keys.
a3d1480b
JB
3652(mapcar
3653 (lambda (keypad-normal)
3654 (let ((keypad (nth 0 keypad-normal))
3655 (normal (nth 1 keypad-normal)))
0d173134 3656 (put keypad 'ascii-character normal)
a3d1480b
JB
3657 (define-key function-key-map (vector keypad) (vector normal))))
3658 '((kp-0 ?0) (kp-1 ?1) (kp-2 ?2) (kp-3 ?3) (kp-4 ?4)
3659 (kp-5 ?5) (kp-6 ?6) (kp-7 ?7) (kp-8 ?8) (kp-9 ?9)
3660 (kp-space ?\ )
3661 (kp-tab ?\t)
3662 (kp-enter ?\r)
3663 (kp-multiply ?*)
3664 (kp-add ?+)
3665 (kp-separator ?,)
3666 (kp-subtract ?-)
3667 (kp-decimal ?.)
3668 (kp-divide ?/)
3669 (kp-equal ?=)))
3670
c88ab9ce 3671;;; simple.el ends here