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