Fix toggling of case-fold-search from re-builder menu (Bug#7650).
[bpt/emacs.git] / lisp / simple.el
CommitLineData
c88ab9ce
ER
1;;; simple.el --- basic editing commands for Emacs
2
c6db81aa 3;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
5df4f04c 4;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
bf825c62 5;; Free Software Foundation, Inc.
2076c87c 6
30764597
PJ
7;; Maintainer: FSF
8;; Keywords: internal
9
2076c87c
JB
10;; This file is part of GNU Emacs.
11
eb3fa2cf 12;; GNU Emacs is free software: you can redistribute it and/or modify
2076c87c 13;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
2076c87c
JB
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
2076c87c 24
d9ecc911
ER
25;;; Commentary:
26
27;; A grab-bag of basic Emacs commands not specifically related to some
28;; major mode or to file-handling.
29
3a801d0c 30;;; Code:
2076c87c 31
30ee26a9
EZ
32;; This is for lexical-let in apply-partially.
33(eval-when-compile (require 'cl))
34
f31b1257
DN
35(declare-function widget-convert "wid-edit" (type &rest args))
36(declare-function shell-mode "shell" ())
d01a33cf 37
ca60ee11
JB
38(defvar compilation-current-error)
39
7fcce20f 40(defcustom idle-update-delay 0.5
1d2b0303 41 "Idle time delay before updating various things on the screen.
7fcce20f
RS
42Various Emacs features that update auxiliary information when point moves
43wait this many seconds after Emacs becomes idle before doing an update."
44 :type 'number
45 :group 'display
46 :version "22.1")
d01a33cf 47
69c1dd37 48(defgroup killing nil
c9f0110e 49 "Killing and yanking commands."
69c1dd37
RS
50 :group 'editing)
51
69c1dd37
RS
52(defgroup paren-matching nil
53 "Highlight (un)matching of parens and expressions."
69c1dd37
RS
54 :group 'matching)
55
7979163c
JL
56(defun get-next-valid-buffer (list &optional buffer visible-ok frame)
57 "Search LIST for a valid buffer to display in FRAME.
a74f9094
KL
58Return nil when all buffers in LIST are undesirable for display,
59otherwise return the first suitable buffer in LIST.
60
61Buffers not visible in windows are preferred to visible buffers,
62unless VISIBLE-OK is non-nil.
63If the optional argument FRAME is nil, it defaults to the selected frame.
7979163c 64If BUFFER is non-nil, ignore occurrences of that buffer in LIST."
a74f9094
KL
65 ;; This logic is more or less copied from other-buffer.
66 (setq frame (or frame (selected-frame)))
67 (let ((pred (frame-parameter frame 'buffer-predicate))
68 found buf)
69 (while (and (not found) list)
70 (setq buf (car list))
71 (if (and (not (eq buffer buf))
72 (buffer-live-p buf)
73 (or (null pred) (funcall pred buf))
74 (not (eq (aref (buffer-name buf) 0) ?\s))
75 (or visible-ok (null (get-buffer-window buf 'visible))))
76 (setq found buf)
77 (setq list (cdr list))))
78 (car list)))
79
7979163c 80(defun last-buffer (&optional buffer visible-ok frame)
4dc1abeb
MR
81 "Return the last buffer in FRAME's buffer list.
82If BUFFER is the last buffer, return the preceding buffer instead.
a74f9094
KL
83Buffers not visible in windows are preferred to visible buffers,
84unless optional argument VISIBLE-OK is non-nil.
4dc1abeb
MR
85Optional third argument FRAME nil or omitted means use the
86selected frame's buffer list.
87If no such buffer exists, return the buffer `*scratch*', creating
88it if necessary."
a74f9094 89 (setq frame (or frame (selected-frame)))
a18b8cb5
KL
90 (or (get-next-valid-buffer (nreverse (buffer-list frame))
91 buffer visible-ok frame)
4dc1abeb
MR
92 (get-buffer "*scratch*")
93 (let ((scratch (get-buffer-create "*scratch*")))
94 (set-buffer-major-mode scratch)
95 scratch)))
96
f54b0d85
RS
97(defun next-buffer ()
98 "Switch to the next buffer in cyclic order."
99 (interactive)
a18b8cb5 100 (let ((buffer (current-buffer)))
a74f9094 101 (switch-to-buffer (other-buffer buffer t))
a18b8cb5 102 (bury-buffer buffer)))
a74f9094
KL
103
104(defun previous-buffer ()
f54b0d85
RS
105 "Switch to the previous buffer in cyclic order."
106 (interactive)
a18b8cb5 107 (switch-to-buffer (last-buffer (current-buffer) t)))
a74f9094 108
ee9c5954 109\f
50f007fb 110;;; next-error support framework
bbf41690
RS
111
112(defgroup next-error nil
f33321ad 113 "`next-error' support framework."
bbf41690 114 :group 'compilation
bf247b6e 115 :version "22.1")
bbf41690
RS
116
117(defface next-error
118 '((t (:inherit region)))
119 "Face used to highlight next error locus."
120 :group 'next-error
bf247b6e 121 :version "22.1")
bbf41690 122
7408ee97 123(defcustom next-error-highlight 0.5
1d2b0303 124 "Highlighting of locations in selected source buffers.
676b1a74
CY
125If a number, highlight the locus in `next-error' face for the given time
126in seconds, or until the next command is executed.
127If t, highlight the locus until the next command is executed, or until
128some other locus replaces it.
bbf41690
RS
129If nil, don't highlight the locus in the source buffer.
130If `fringe-arrow', indicate the locus by the fringe arrow."
6d3c944b 131 :type '(choice (number :tag "Highlight for specified time")
c81b29e6 132 (const :tag "Semipermanent highlighting" t)
bbf41690 133 (const :tag "No highlighting" nil)
6d3c944b 134 (const :tag "Fringe arrow" fringe-arrow))
bbf41690 135 :group 'next-error
bf247b6e 136 :version "22.1")
bbf41690 137
7408ee97 138(defcustom next-error-highlight-no-select 0.5
1d2b0303 139 "Highlighting of locations in `next-error-no-select'.
f33321ad 140If number, highlight the locus in `next-error' face for given time in seconds.
6d3c944b 141If t, highlight the locus indefinitely until some other locus replaces it.
bbf41690
RS
142If nil, don't highlight the locus in the source buffer.
143If `fringe-arrow', indicate the locus by the fringe arrow."
6d3c944b 144 :type '(choice (number :tag "Highlight for specified time")
c81b29e6 145 (const :tag "Semipermanent highlighting" t)
bbf41690 146 (const :tag "No highlighting" nil)
6d3c944b 147 (const :tag "Fringe arrow" fringe-arrow))
bbf41690 148 :group 'next-error
bf247b6e 149 :version "22.1")
bbf41690 150
446b609e 151(defcustom next-error-recenter nil
1d2b0303 152 "Display the line in the visited source file recentered as specified.
28adf31c
TTN
153If non-nil, the value is passed directly to `recenter'."
154 :type '(choice (integer :tag "Line to recenter to")
155 (const :tag "Center of window" (4))
446b609e
TTN
156 (const :tag "No recentering" nil))
157 :group 'next-error
158 :version "23.1")
159
d634a3a2 160(defcustom next-error-hook nil
1d2b0303 161 "List of hook functions run by `next-error' after visiting source file."
d634a3a2
JL
162 :type 'hook
163 :group 'next-error)
164
814c3037
JL
165(defvar next-error-highlight-timer nil)
166
9c9b00d6 167(defvar next-error-overlay-arrow-position nil)
6bdad9ae 168(put 'next-error-overlay-arrow-position 'overlay-arrow-string (purecopy "=>"))
9c9b00d6
JL
169(add-to-list 'overlay-arrow-variable-list 'next-error-overlay-arrow-position)
170
50f007fb 171(defvar next-error-last-buffer nil
f33321ad 172 "The most recent `next-error' buffer.
50f007fb
KS
173A buffer becomes most recent when its compilation, grep, or
174similar mode is started, or when it is used with \\[next-error]
175or \\[compile-goto-error].")
176
177(defvar next-error-function nil
e462ab77
SM
178 "Function to use to find the next error in the current buffer.
179The function is called with 2 parameters:
180ARG is an integer specifying by how many errors to move.
181RESET is a boolean which, if non-nil, says to go back to the beginning
182of the errors before moving.
183Major modes providing compile-like functionality should set this variable
184to indicate to `next-error' that this is a candidate buffer and how
185to navigate in it.")
50f007fb
KS
186(make-variable-buffer-local 'next-error-function)
187
8cdba32b
RS
188(defvar next-error-move-function nil
189 "Function to use to move to an error locus.
190It takes two arguments, a buffer position in the error buffer
191and a buffer position in the error locus buffer.
192The buffer for the error locus should already be current.
193nil means use goto-char using the second argument position.")
194(make-variable-buffer-local 'next-error-move-function)
195
f1e2a033 196(defsubst next-error-buffer-p (buffer
e967cd11 197 &optional avoid-current
f1e2a033 198 extra-test-inclusive
5f9e0ca5 199 extra-test-exclusive)
f33321ad 200 "Test if BUFFER is a `next-error' capable buffer.
e967cd11
RS
201
202If AVOID-CURRENT is non-nil, treat the current buffer
203as an absolute last resort only.
204
205The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
206that normally would not qualify. If it returns t, the buffer
207in question is treated as usable.
208
7979163c 209The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
01ba9662 210that would normally be considered usable. If it returns nil,
e967cd11
RS
211that buffer is rejected."
212 (and (buffer-name buffer) ;First make sure it's live.
213 (not (and avoid-current (eq buffer (current-buffer))))
214 (with-current-buffer buffer
215 (if next-error-function ; This is the normal test.
216 ;; Optionally reject some buffers.
217 (if extra-test-exclusive
218 (funcall extra-test-exclusive)
219 t)
220 ;; Optionally accept some other buffers.
221 (and extra-test-inclusive
222 (funcall extra-test-inclusive))))))
223
224(defun next-error-find-buffer (&optional avoid-current
f1e2a033 225 extra-test-inclusive
5f9e0ca5 226 extra-test-exclusive)
f33321ad 227 "Return a `next-error' capable buffer.
7979163c 228
e967cd11
RS
229If AVOID-CURRENT is non-nil, treat the current buffer
230as an absolute last resort only.
231
01ba9662 232The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
e967cd11
RS
233that normally would not qualify. If it returns t, the buffer
234in question is treated as usable.
235
7979163c 236The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
e967cd11
RS
237that would normally be considered usable. If it returns nil,
238that buffer is rejected."
03e75c7e
JL
239 (or
240 ;; 1. If one window on the selected frame displays such buffer, return it.
241 (let ((window-buffers
242 (delete-dups
243 (delq nil (mapcar (lambda (w)
244 (if (next-error-buffer-p
e967cd11
RS
245 (window-buffer w)
246 avoid-current
f1e2a033 247 extra-test-inclusive extra-test-exclusive)
03e75c7e
JL
248 (window-buffer w)))
249 (window-list))))))
03e75c7e
JL
250 (if (eq (length window-buffers) 1)
251 (car window-buffers)))
e967cd11 252 ;; 2. If next-error-last-buffer is an acceptable buffer, use that.
03e75c7e 253 (if (and next-error-last-buffer
e967cd11 254 (next-error-buffer-p next-error-last-buffer avoid-current
f1e2a033 255 extra-test-inclusive extra-test-exclusive))
e967cd11
RS
256 next-error-last-buffer)
257 ;; 3. If the current buffer is acceptable, choose it.
258 (if (next-error-buffer-p (current-buffer) avoid-current
259 extra-test-inclusive extra-test-exclusive)
03e75c7e 260 (current-buffer))
e967cd11 261 ;; 4. Look for any acceptable buffer.
03e75c7e
JL
262 (let ((buffers (buffer-list)))
263 (while (and buffers
e967cd11
RS
264 (not (next-error-buffer-p
265 (car buffers) avoid-current
266 extra-test-inclusive extra-test-exclusive)))
03e75c7e 267 (setq buffers (cdr buffers)))
e967cd11
RS
268 (car buffers))
269 ;; 5. Use the current buffer as a last resort if it qualifies,
270 ;; even despite AVOID-CURRENT.
271 (and avoid-current
272 (next-error-buffer-p (current-buffer) nil
273 extra-test-inclusive extra-test-exclusive)
274 (progn
ee4dc5d9 275 (message "This is the only buffer with error message locations")
e967cd11
RS
276 (current-buffer)))
277 ;; 6. Give up.
ee4dc5d9 278 (error "No buffers contain error message locations")))
50f007fb 279
310abb0b 280(defun next-error (&optional arg reset)
f33321ad 281 "Visit next `next-error' message and corresponding source code.
50f007fb
KS
282
283If all the error messages parsed so far have been processed already,
284the message buffer is checked for new ones.
285
e462ab77 286A prefix ARG specifies how many error messages to move;
50f007fb
KS
287negative means move back to previous error messages.
288Just \\[universal-argument] as a prefix means reparse the error message buffer
289and start at the first error.
290
e249a6d8 291The RESET argument specifies that we should restart from the beginning.
50f007fb
KS
292
293\\[next-error] normally uses the most recently started
294compilation, grep, or occur buffer. It can also operate on any
295buffer with output from the \\[compile], \\[grep] commands, or,
296more generally, on any buffer in Compilation mode or with
297Compilation Minor mode enabled, or any buffer in which
03e75c7e
JL
298`next-error-function' is bound to an appropriate function.
299To specify use of a particular buffer for error messages, type
300\\[next-error] in that buffer when it is the only one displayed
301in the current frame.
50f007fb 302
d634a3a2
JL
303Once \\[next-error] has chosen the buffer for error messages, it
304runs `next-error-hook' with `run-hooks', and stays with that buffer
305until you use it in some other buffer which uses Compilation mode
306or Compilation Minor mode.
50f007fb
KS
307
308See variables `compilation-parse-errors-function' and
309\`compilation-error-regexp-alist' for customization ideas."
310 (interactive "P")
e462ab77 311 (if (consp arg) (setq reset t arg nil))
50f007fb
KS
312 (when (setq next-error-last-buffer (next-error-find-buffer))
313 ;; we know here that next-error-function is a valid symbol we can funcall
314 (with-current-buffer next-error-last-buffer
d634a3a2 315 (funcall next-error-function (prefix-numeric-value arg) reset)
446b609e
TTN
316 (when next-error-recenter
317 (recenter next-error-recenter))
d634a3a2 318 (run-hooks 'next-error-hook))))
50f007fb 319
56ab610b
RS
320(defun next-error-internal ()
321 "Visit the source code corresponding to the `next-error' message at point."
322 (setq next-error-last-buffer (current-buffer))
323 ;; we know here that next-error-function is a valid symbol we can funcall
324 (with-current-buffer next-error-last-buffer
325 (funcall next-error-function 0 nil)
446b609e
TTN
326 (when next-error-recenter
327 (recenter next-error-recenter))
56ab610b
RS
328 (run-hooks 'next-error-hook)))
329
50f007fb
KS
330(defalias 'goto-next-locus 'next-error)
331(defalias 'next-match 'next-error)
332
310abb0b 333(defun previous-error (&optional n)
f33321ad 334 "Visit previous `next-error' message and corresponding source code.
50f007fb
KS
335
336Prefix arg N says how many error messages to move backwards (or
337forwards, if negative).
338
339This operates on the output from the \\[compile] and \\[grep] commands."
340 (interactive "p")
310abb0b 341 (next-error (- (or n 1))))
50f007fb 342
310abb0b 343(defun first-error (&optional n)
50f007fb
KS
344 "Restart at the first error.
345Visit corresponding source code.
346With prefix arg N, visit the source code of the Nth error.
347This operates on the output from the \\[compile] command, for instance."
348 (interactive "p")
349 (next-error n t))
350
310abb0b 351(defun next-error-no-select (&optional n)
f33321ad 352 "Move point to the next error in the `next-error' buffer and highlight match.
50f007fb
KS
353Prefix arg N says how many error messages to move forwards (or
354backwards, if negative).
355Finds and highlights the source line like \\[next-error], but does not
356select the source buffer."
357 (interactive "p")
ee9c5954
JL
358 (let ((next-error-highlight next-error-highlight-no-select))
359 (next-error n))
50f007fb
KS
360 (pop-to-buffer next-error-last-buffer))
361
310abb0b 362(defun previous-error-no-select (&optional n)
f33321ad 363 "Move point to the previous error in the `next-error' buffer and highlight match.
50f007fb
KS
364Prefix arg N says how many error messages to move backwards (or
365forwards, if negative).
366Finds and highlights the source line like \\[previous-error], but does not
367select the source buffer."
368 (interactive "p")
310abb0b 369 (next-error-no-select (- (or n 1))))
50f007fb 370
85be9ec4 371;; Internal variable for `next-error-follow-mode-post-command-hook'.
282d6eae
EZ
372(defvar next-error-follow-last-line nil)
373
2a223f35 374(define-minor-mode next-error-follow-minor-mode
282d6eae 375 "Minor mode for compilation, occur and diff modes.
2a223f35
EZ
376When turned on, cursor motion in the compilation, grep, occur or diff
377buffer causes automatic display of the corresponding source code
378location."
ed8e0f0a 379 :group 'next-error :init-value nil :lighter " Fol"
8a98a6c2 380 (if (not next-error-follow-minor-mode)
282d6eae
EZ
381 (remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t)
382 (add-hook 'post-command-hook 'next-error-follow-mode-post-command-hook nil t)
e56dd5c6 383 (make-local-variable 'next-error-follow-last-line)))
282d6eae 384
85be9ec4
SM
385;; Used as a `post-command-hook' by `next-error-follow-mode'
386;; for the *Compilation* *grep* and *Occur* buffers.
282d6eae
EZ
387(defun next-error-follow-mode-post-command-hook ()
388 (unless (equal next-error-follow-last-line (line-number-at-pos))
389 (setq next-error-follow-last-line (line-number-at-pos))
390 (condition-case nil
391 (let ((compilation-context-lines nil))
392 (setq compilation-current-error (point))
393 (next-error-no-select 0))
394 (error t))))
395
ee9c5954 396\f
50f007fb
KS
397;;;
398
93be67de
KH
399(defun fundamental-mode ()
400 "Major mode not specialized for anything in particular.
401Other major modes are defined by comparison with this one."
402 (interactive)
e174f8db 403 (kill-all-local-variables)
52167727
LK
404 (unless delay-mode-hooks
405 (run-hooks 'after-change-major-mode-hook)))
eaae8106 406
d445b3f8
SM
407;; Special major modes to view specially formatted data rather than files.
408
409(defvar special-mode-map
410 (let ((map (make-sparse-keymap)))
411 (suppress-keymap map)
412 (define-key map "q" 'quit-window)
413 (define-key map " " 'scroll-up)
414 (define-key map "\C-?" 'scroll-down)
415 (define-key map "?" 'describe-mode)
416 (define-key map ">" 'end-of-buffer)
417 (define-key map "<" 'beginning-of-buffer)
418 (define-key map "g" 'revert-buffer)
419 map))
1d2b0303 420
d445b3f8
SM
421(put 'special-mode 'mode-class 'special)
422(define-derived-mode special-mode nil "Special"
423 "Parent major mode from which special major modes should inherit."
424 (setq buffer-read-only t))
425
93be67de
KH
426;; Making and deleting lines.
427
28fab7b5
GM
428(defvar hard-newline (propertize "\n" 'hard t 'rear-nonsticky '(hard))
429 "Propertized string representing a hard newline character.")
4ea0018b 430
30bb9754 431(defun newline (&optional arg)
d133d835 432 "Insert a newline, and move to left margin of the new line if it's blank.
058d4999
DL
433If `use-hard-newlines' is non-nil, the newline is marked with the
434text-property `hard'.
76c64e24 435With ARG, insert that many newlines.
058d4999 436Call `auto-fill-function' if the current column number is greater
6688f85f 437than the value of `fill-column' and ARG is nil."
30bb9754 438 (interactive "*P")
4c4cbf11 439 (barf-if-buffer-read-only)
30bb9754
BG
440 ;; Inserting a newline at the end of a line produces better redisplay in
441 ;; try_window_id than inserting at the beginning of a line, and the textual
442 ;; result is the same. So, if we're at beginning of line, pretend to be at
443 ;; the end of the previous line.
1e722f9f 444 (let ((flag (and (not (bobp))
30bb9754 445 (bolp)
1cd24721
RS
446 ;; Make sure no functions want to be told about
447 ;; the range of the changes.
1cd24721
RS
448 (not after-change-functions)
449 (not before-change-functions)
fd977703
RS
450 ;; Make sure there are no markers here.
451 (not (buffer-has-markers-at (1- (point))))
2f047f6c 452 (not (buffer-has-markers-at (point)))
1cd24721
RS
453 ;; Make sure no text properties want to know
454 ;; where the change was.
455 (not (get-char-property (1- (point)) 'modification-hooks))
456 (not (get-char-property (1- (point)) 'insert-behind-hooks))
457 (or (eobp)
458 (not (get-char-property (point) 'insert-in-front-hooks)))
31a5333f
MB
459 ;; Make sure the newline before point isn't intangible.
460 (not (get-char-property (1- (point)) 'intangible))
461 ;; Make sure the newline before point isn't read-only.
462 (not (get-char-property (1- (point)) 'read-only))
463 ;; Make sure the newline before point isn't invisible.
464 (not (get-char-property (1- (point)) 'invisible))
465 ;; Make sure the newline before point has the same
466 ;; properties as the char before it (if any).
1e722f9f 467 (< (or (previous-property-change (point)) -2)
d133d835
RS
468 (- (point) 2))))
469 (was-page-start (and (bolp)
470 (looking-at page-delimiter)))
471 (beforepos (point)))
30bb9754
BG
472 (if flag (backward-char 1))
473 ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
8989a920
GM
474 ;; Set last-command-event to tell self-insert what to insert.
475 (let ((last-command-event ?\n)
30bb9754 476 ;; Don't auto-fill if we have a numeric argument.
3954fff9
RS
477 ;; Also not if flag is true (it would fill wrong line);
478 ;; there is no need to since we're at BOL.
479 (auto-fill-function (if (or arg flag) nil auto-fill-function)))
4cc9d0dc
RS
480 (unwind-protect
481 (self-insert-command (prefix-numeric-value arg))
482 ;; If we get an error in self-insert-command, put point at right place.
483 (if flag (forward-char 1))))
2f047f6c
KH
484 ;; Even if we did *not* get an error, keep that forward-char;
485 ;; all further processing should apply to the newline that the user
486 ;; thinks he inserted.
487
30bb9754
BG
488 ;; Mark the newline(s) `hard'.
489 (if use-hard-newlines
2f047f6c 490 (set-hard-newline-properties
3137dda8 491 (- (point) (prefix-numeric-value arg)) (point)))
d133d835
RS
492 ;; If the newline leaves the previous line blank,
493 ;; and we have a left margin, delete that from the blank line.
494 (or flag
495 (save-excursion
496 (goto-char beforepos)
497 (beginning-of-line)
498 (and (looking-at "[ \t]$")
499 (> (current-left-margin) 0)
500 (delete-region (point) (progn (end-of-line) (point))))))
d133d835
RS
501 ;; Indent the line after the newline, except in one case:
502 ;; when we added the newline at the beginning of a line
503 ;; which starts a page.
504 (or was-page-start
505 (move-to-left-margin nil t)))
30bb9754
BG
506 nil)
507
55741b46
RS
508(defun set-hard-newline-properties (from to)
509 (let ((sticky (get-text-property from 'rear-nonsticky)))
510 (put-text-property from to 'hard 't)
511 ;; If rear-nonsticky is not "t", add 'hard to rear-nonsticky list
512 (if (and (listp sticky) (not (memq 'hard sticky)))
513 (put-text-property from (point) 'rear-nonsticky
514 (cons 'hard sticky)))))
eaae8106 515
e249a6d8 516(defun open-line (n)
ff1fbe3e 517 "Insert a newline and leave point before it.
f33321ad
JB
518If there is a fill prefix and/or a `left-margin', insert them
519on the new line if the line would have been blank.
616ed245 520With arg N, insert N newlines."
2076c87c 521 (interactive "*p")
616ed245 522 (let* ((do-fill-prefix (and fill-prefix (bolp)))
3db1e3b5 523 (do-left-margin (and (bolp) (> (current-left-margin) 0)))
207d7545
GM
524 (loc (point))
525 ;; Don't expand an abbrev before point.
526 (abbrev-mode nil))
e249a6d8 527 (newline n)
d133d835 528 (goto-char loc)
e249a6d8 529 (while (> n 0)
d133d835
RS
530 (cond ((bolp)
531 (if do-left-margin (indent-to (current-left-margin)))
532 (if do-fill-prefix (insert-and-inherit fill-prefix))))
533 (forward-line 1)
e249a6d8 534 (setq n (1- n)))
d133d835
RS
535 (goto-char loc)
536 (end-of-line)))
2076c87c 537
da7d231b
KS
538(defun split-line (&optional arg)
539 "Split current line, moving portion beyond point vertically down.
540If the current line starts with `fill-prefix', insert it on the new
f33321ad 541line as well. With prefix ARG, don't insert `fill-prefix' on new line.
da7d231b 542
e249a6d8 543When called from Lisp code, ARG may be a prefix string to copy."
da7d231b 544 (interactive "*P")
2076c87c 545 (skip-chars-forward " \t")
d77bbdc9
RS
546 (let* ((col (current-column))
547 (pos (point))
548 ;; What prefix should we check for (nil means don't).
549 (prefix (cond ((stringp arg) arg)
550 (arg nil)
551 (t fill-prefix)))
552 ;; Does this line start with it?
553 (have-prfx (and prefix
554 (save-excursion
555 (beginning-of-line)
556 (looking-at (regexp-quote prefix))))))
28191e20 557 (newline 1)
d77bbdc9 558 (if have-prfx (insert-and-inherit prefix))
2076c87c
JB
559 (indent-to col 0)
560 (goto-char pos)))
561
2076c87c
JB
562(defun delete-indentation (&optional arg)
563 "Join this line to previous and fix up whitespace at join.
ccc58657 564If there is a fill prefix, delete it from the beginning of this line.
2076c87c
JB
565With argument, join this line to following line."
566 (interactive "*P")
567 (beginning-of-line)
568 (if arg (forward-line 1))
569 (if (eq (preceding-char) ?\n)
570 (progn
571 (delete-region (point) (1- (point)))
ccc58657
RS
572 ;; If the second line started with the fill prefix,
573 ;; delete the prefix.
574 (if (and fill-prefix
01b8e020 575 (<= (+ (point) (length fill-prefix)) (point-max))
ccc58657
RS
576 (string= fill-prefix
577 (buffer-substring (point)
578 (+ (point) (length fill-prefix)))))
579 (delete-region (point) (+ (point) (length fill-prefix))))
2076c87c
JB
580 (fixup-whitespace))))
581
fc025090 582(defalias 'join-line #'delete-indentation) ; easier to find
eaae8106 583
2076c87c
JB
584(defun delete-blank-lines ()
585 "On blank line, delete all surrounding blank lines, leaving just one.
586On isolated blank line, delete that one.
6d30d416 587On nonblank line, delete any immediately following blank lines."
2076c87c
JB
588 (interactive "*")
589 (let (thisblank singleblank)
590 (save-excursion
591 (beginning-of-line)
592 (setq thisblank (looking-at "[ \t]*$"))
70e14c01 593 ;; Set singleblank if there is just one blank line here.
2076c87c
JB
594 (setq singleblank
595 (and thisblank
596 (not (looking-at "[ \t]*\n[ \t]*$"))
597 (or (bobp)
598 (progn (forward-line -1)
599 (not (looking-at "[ \t]*$")))))))
70e14c01 600 ;; Delete preceding blank lines, and this one too if it's the only one.
2076c87c
JB
601 (if thisblank
602 (progn
603 (beginning-of-line)
604 (if singleblank (forward-line 1))
605 (delete-region (point)
606 (if (re-search-backward "[^ \t\n]" nil t)
607 (progn (forward-line 1) (point))
608 (point-min)))))
70e14c01
JB
609 ;; Delete following blank lines, unless the current line is blank
610 ;; and there are no following blank lines.
2076c87c
JB
611 (if (not (and thisblank singleblank))
612 (save-excursion
613 (end-of-line)
614 (forward-line 1)
615 (delete-region (point)
616 (if (re-search-forward "[^ \t\n]" nil t)
617 (progn (beginning-of-line) (point))
70e14c01
JB
618 (point-max)))))
619 ;; Handle the special case where point is followed by newline and eob.
620 ;; Delete the line, leaving point at eob.
621 (if (looking-at "^[ \t]*\n\\'")
622 (delete-region (point) (point-max)))))
2076c87c 623
eaae8106
SS
624(defun delete-trailing-whitespace ()
625 "Delete all the trailing whitespace across the current buffer.
626All whitespace after the last non-whitespace character in a line is deleted.
103db06c
RS
627This respects narrowing, created by \\[narrow-to-region] and friends.
628A formfeed is not considered whitespace by this function."
eaae8106
SS
629 (interactive "*")
630 (save-match-data
631 (save-excursion
632 (goto-char (point-min))
5c9b3fac
MB
633 (while (re-search-forward "\\s-$" nil t)
634 (skip-syntax-backward "-" (save-excursion (forward-line 0) (point)))
3a768251 635 ;; Don't delete formfeeds, even if they are considered whitespace.
661aa5c7
GM
636 (save-match-data
637 (if (looking-at ".*\f")
638 (goto-char (match-end 0))))
7981d89f 639 (delete-region (point) (match-end 0))))))
eaae8106 640
2076c87c
JB
641(defun newline-and-indent ()
642 "Insert a newline, then indent according to major mode.
ff1fbe3e 643Indentation is done using the value of `indent-line-function'.
2076c87c 644In programming language modes, this is the same as TAB.
ff1fbe3e 645In some text modes, where TAB inserts a tab, this command indents to the
eed5698b 646column specified by the function `current-left-margin'."
2076c87c 647 (interactive "*")
5ff4ba3d 648 (delete-horizontal-space t)
46947372 649 (newline)
2076c87c
JB
650 (indent-according-to-mode))
651
652(defun reindent-then-newline-and-indent ()
653 "Reindent current line, insert newline, then indent the new line.
654Indentation of both lines is done according to the current major mode,
ff1fbe3e 655which means calling the current value of `indent-line-function'.
2076c87c
JB
656In programming language modes, this is the same as TAB.
657In some text modes, where TAB inserts a tab, this indents to the
eed5698b 658column specified by the function `current-left-margin'."
2076c87c 659 (interactive "*")
e1e04350
SM
660 (let ((pos (point)))
661 ;; Be careful to insert the newline before indenting the line.
662 ;; Otherwise, the indentation might be wrong.
663 (newline)
664 (save-excursion
665 (goto-char pos)
eb3d6c67
SM
666 ;; We are at EOL before the call to indent-according-to-mode, and
667 ;; after it we usually are as well, but not always. We tried to
668 ;; address it with `save-excursion' but that uses a normal marker
669 ;; whereas we need `move after insertion', so we do the save/restore
670 ;; by hand.
671 (setq pos (copy-marker pos t))
672 (indent-according-to-mode)
673 (goto-char pos)
674 ;; Remove the trailing white-space after indentation because
675 ;; indentation may introduce the whitespace.
6b61353c 676 (delete-horizontal-space t))
e1e04350 677 (indent-according-to-mode)))
eaae8106 678
93be67de
KH
679(defun quoted-insert (arg)
680 "Read next input character and insert it.
681This is useful for inserting control characters.
5626c14e 682With argument, insert ARG copies of the character.
2076c87c 683
93be67de
KH
684If the first character you type after this command is an octal digit,
685you should type a sequence of octal digits which specify a character code.
686Any nondigit terminates the sequence. If the terminator is a RET,
687it is discarded; any other terminator is used itself as input.
688The variable `read-quoted-char-radix' specifies the radix for this feature;
689set it to 10 or 16 to use decimal or hex instead of octal.
dff7d67f 690
93be67de
KH
691In overwrite mode, this function inserts the character anyway, and
692does not handle octal digits specially. This means that if you use
693overwrite as your normal editing mode, you can use this function to
694insert characters when necessary.
dff7d67f 695
93be67de
KH
696In binary overwrite mode, this function does overwrite, and octal
697digits are interpreted as a character code. This is intended to be
698useful for editing binary files."
699 (interactive "*p")
a6c39c14
EZ
700 (let* ((char
701 ;; Avoid "obsolete" warnings for translation-table-for-input.
702 (with-no-warnings
703 (let (translation-table-for-input input-method-function)
704 (if (or (not overwrite-mode)
705 (eq overwrite-mode 'overwrite-mode-binary))
706 (read-quoted-char)
707 (read-char))))))
0e3269e5
JL
708 ;; This used to assume character codes 0240 - 0377 stand for
709 ;; characters in some single-byte character set, and converted them
710 ;; to Emacs characters. But in 23.1 this feature is deprecated
711 ;; in favor of inserting the corresponding Unicode characters.
712 ;; (if (and enable-multibyte-characters
713 ;; (>= char ?\240)
714 ;; (<= char ?\377))
715 ;; (setq char (unibyte-char-to-multibyte char)))
93be67de
KH
716 (if (> arg 0)
717 (if (eq overwrite-mode 'overwrite-mode-binary)
718 (delete-char arg)))
719 (while (> arg 0)
720 (insert-and-inherit char)
721 (setq arg (1- arg)))))
eaae8106 722
6b61353c 723(defun forward-to-indentation (&optional arg)
93be67de 724 "Move forward ARG lines and position at first nonblank character."
109cfe4e 725 (interactive "^p")
6b61353c 726 (forward-line (or arg 1))
93be67de 727 (skip-chars-forward " \t"))
cc2b2b6c 728
6b61353c 729(defun backward-to-indentation (&optional arg)
93be67de 730 "Move backward ARG lines and position at first nonblank character."
109cfe4e 731 (interactive "^p")
6b61353c 732 (forward-line (- (or arg 1)))
93be67de 733 (skip-chars-forward " \t"))
2076c87c 734
93be67de
KH
735(defun back-to-indentation ()
736 "Move point to the first non-whitespace character on this line."
109cfe4e 737 (interactive "^")
93be67de 738 (beginning-of-line 1)
1e96c007 739 (skip-syntax-forward " " (line-end-position))
b9863466
RS
740 ;; Move back over chars that have whitespace syntax but have the p flag.
741 (backward-prefix-chars))
93be67de
KH
742
743(defun fixup-whitespace ()
744 "Fixup white space between objects around point.
745Leave one space or none, according to the context."
746 (interactive "*")
747 (save-excursion
748 (delete-horizontal-space)
749 (if (or (looking-at "^\\|\\s)")
750 (save-excursion (forward-char -1)
751 (looking-at "$\\|\\s(\\|\\s'")))
752 nil
f33321ad 753 (insert ?\s))))
93be67de 754
5ff4ba3d
MB
755(defun delete-horizontal-space (&optional backward-only)
756 "Delete all spaces and tabs around point.
1cfcd2db 757If BACKWARD-ONLY is non-nil, only delete them before point."
a168699d 758 (interactive "*P")
9ab59a1a
MB
759 (let ((orig-pos (point)))
760 (delete-region
761 (if backward-only
762 orig-pos
763 (progn
764 (skip-chars-forward " \t")
765 (constrain-to-field nil orig-pos t)))
5ff4ba3d 766 (progn
9ab59a1a
MB
767 (skip-chars-backward " \t")
768 (constrain-to-field nil orig-pos)))))
93be67de 769
68c16b59 770(defun just-one-space (&optional n)
56abefac
RS
771 "Delete all spaces and tabs around point, leaving one space (or N spaces)."
772 (interactive "*p")
9ab59a1a
MB
773 (let ((orig-pos (point)))
774 (skip-chars-backward " \t")
775 (constrain-to-field nil orig-pos)
68c16b59 776 (dotimes (i (or n 1))
f33321ad 777 (if (= (following-char) ?\s)
56abefac 778 (forward-char 1)
f33321ad 779 (insert ?\s)))
9ab59a1a
MB
780 (delete-region
781 (point)
782 (progn
783 (skip-chars-forward " \t")
784 (constrain-to-field nil orig-pos t)))))
2d88b556 785\f
2076c87c 786(defun beginning-of-buffer (&optional arg)
8d9f4291 787 "Move point to the beginning of the buffer.
a416e7ef 788With numeric arg N, put point N/10 of the way from the beginning.
8d9f4291
CY
789If the buffer is narrowed, this command uses the beginning of the
790accessible part of the buffer.
c66587fe 791
8d9f4291
CY
792If Transient Mark mode is disabled, leave mark at previous
793position, unless a \\[universal-argument] prefix is supplied.
ff1fbe3e
RS
794
795Don't use this command in Lisp programs!
8d9f4291 796\(goto-char (point-min)) is faster."
109cfe4e 797 (interactive "^P")
24199fe7 798 (or (consp arg)
d34c311a 799 (region-active-p)
705a5933 800 (push-mark))
c66587fe 801 (let ((size (- (point-max) (point-min))))
a416e7ef 802 (goto-char (if (and arg (not (consp arg)))
c66587fe
RS
803 (+ (point-min)
804 (if (> size 10000)
805 ;; Avoid overflow for large buffer sizes!
806 (* (prefix-numeric-value arg)
807 (/ size 10))
808 (/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
809 (point-min))))
d7e7ecd7 810 (if (and arg (not (consp arg))) (forward-line 1)))
2076c87c
JB
811
812(defun end-of-buffer (&optional arg)
8d9f4291 813 "Move point to the end of the buffer.
a416e7ef 814With numeric arg N, put point N/10 of the way from the end.
8d9f4291
CY
815If the buffer is narrowed, this command uses the end of the
816accessible part of the buffer.
c66587fe 817
8d9f4291
CY
818If Transient Mark mode is disabled, leave mark at previous
819position, unless a \\[universal-argument] prefix is supplied.
ff1fbe3e
RS
820
821Don't use this command in Lisp programs!
8d9f4291 822\(goto-char (point-max)) is faster."
109cfe4e 823 (interactive "^P")
d34c311a 824 (or (consp arg) (region-active-p) (push-mark))
c66587fe 825 (let ((size (- (point-max) (point-min))))
a416e7ef 826 (goto-char (if (and arg (not (consp arg)))
c66587fe
RS
827 (- (point-max)
828 (if (> size 10000)
829 ;; Avoid overflow for large buffer sizes!
830 (* (prefix-numeric-value arg)
831 (/ size 10))
832 (/ (* size (prefix-numeric-value arg)) 10)))
833 (point-max))))
3a801d0c
ER
834 ;; If we went to a place in the middle of the buffer,
835 ;; adjust it to the beginning of a line.
d7e7ecd7 836 (cond ((and arg (not (consp arg))) (forward-line 1))
919f2812 837 ((> (point) (window-end nil t))
314808dc
GM
838 ;; If the end of the buffer is not already on the screen,
839 ;; then scroll specially to put it near, but not at, the bottom.
840 (overlay-recenter (point))
841 (recenter -3))))
2076c87c
JB
842
843(defun mark-whole-buffer ()
70e14c01
JB
844 "Put point at beginning and mark at end of buffer.
845You probably should not use this function in Lisp programs;
846it is usually a mistake for a Lisp function to use any subroutine
847that uses or sets the mark."
2076c87c
JB
848 (interactive)
849 (push-mark (point))
fd0f4056 850 (push-mark (point-max) nil t)
2076c87c 851 (goto-char (point-min)))
2d88b556 852\f
eaae8106 853
93be67de
KH
854;; Counting lines, one way or another.
855
9af967bd
LK
856(defun goto-line (line &optional buffer)
857 "Goto LINE, counting from line 1 at beginning of buffer.
858Normally, move point in the current buffer, and leave mark at the
859previous position. With just \\[universal-argument] as argument,
a5785534 860move point in the most recently selected other buffer, and switch to it.
9af967bd 861
a5785534
SM
862If there's a number in the buffer at point, it is the default for LINE.
863
864This function is usually the wrong thing to use in a Lisp program.
865What you probably want instead is something like:
866 (goto-char (point-min)) (forward-line (1- N))
867If at all possible, an even better solution is to use char counts
868rather than line counts."
00a369ac
RS
869 (interactive
870 (if (and current-prefix-arg (not (consp current-prefix-arg)))
871 (list (prefix-numeric-value current-prefix-arg))
872 ;; Look for a default, a number in the buffer at point.
873 (let* ((default
874 (save-excursion
875 (skip-chars-backward "0-9")
876 (if (looking-at "[0-9]")
877 (buffer-substring-no-properties
878 (point)
879 (progn (skip-chars-forward "0-9")
880 (point))))))
881 ;; Decide if we're switching buffers.
882 (buffer
883 (if (consp current-prefix-arg)
884 (other-buffer (current-buffer) t)))
885 (buffer-prompt
886 (if buffer
887 (concat " in " (buffer-name buffer))
888 "")))
889 ;; Read the argument, offering that number (if any) as default.
890 (list (read-from-minibuffer (format (if default "Goto line%s (%s): "
891 "Goto line%s: ")
892 buffer-prompt
893 default)
894 nil nil t
895 'minibuffer-history
896 default)
897 buffer))))
898 ;; Switch to the desired buffer, one way or another.
899 (if buffer
900 (let ((window (get-buffer-window buffer)))
901 (if window (select-window window)
902 (switch-to-buffer-other-window buffer))))
f564644b 903 ;; Leave mark at previous position
d34c311a 904 (or (region-active-p) (push-mark))
00a369ac 905 ;; Move to the specified line number in that buffer.
93be67de
KH
906 (save-restriction
907 (widen)
a5785534 908 (goto-char (point-min))
93be67de 909 (if (eq selective-display t)
9af967bd
LK
910 (re-search-forward "[\n\C-m]" nil 'end (1- line))
911 (forward-line (1- line)))))
2076c87c
JB
912
913(defun count-lines-region (start end)
eb8c3be9 914 "Print number of lines and characters in the region."
2076c87c
JB
915 (interactive "r")
916 (message "Region has %d lines, %d characters"
917 (count-lines start end) (- end start)))
918
919(defun what-line ()
2578be76 920 "Print the current buffer line number and narrowed line number of point."
2076c87c 921 (interactive)
c6db81aa 922 (let ((start (point-min))
6b61353c
KH
923 (n (line-number-at-pos)))
924 (if (= start 1)
925 (message "Line %d" n)
926 (save-excursion
927 (save-restriction
928 (widen)
929 (message "line %d (narrowed line %d)"
930 (+ n (line-number-at-pos start) -1) n))))))
2578be76 931
2076c87c
JB
932(defun count-lines (start end)
933 "Return number of lines between START and END.
934This is usually the number of newlines between them,
ff1fbe3e 935but can be one more if START is not equal to END
2076c87c 936and the greater of them is not at the start of a line."
e406700d
RS
937 (save-excursion
938 (save-restriction
939 (narrow-to-region start end)
940 (goto-char (point-min))
941 (if (eq selective-display t)
942 (save-match-data
dde92ca6
RS
943 (let ((done 0))
944 (while (re-search-forward "[\n\C-m]" nil t 40)
945 (setq done (+ 40 done)))
946 (while (re-search-forward "[\n\C-m]" nil t 1)
947 (setq done (+ 1 done)))
043efc41
RS
948 (goto-char (point-max))
949 (if (and (/= start end)
950 (not (bolp)))
951 (1+ done)
e406700d
RS
952 done)))
953 (- (buffer-size) (forward-line (buffer-size)))))))
eaae8106 954
6b61353c
KH
955(defun line-number-at-pos (&optional pos)
956 "Return (narrowed) buffer line number at position POS.
79ffb765
RS
957If POS is nil, use current buffer location.
958Counting starts at (point-min), so the value refers
959to the contents of the accessible portion of the buffer."
6b61353c
KH
960 (let ((opoint (or pos (point))) start)
961 (save-excursion
962 (goto-char (point-min))
963 (setq start (point))
964 (goto-char opoint)
965 (forward-line 0)
966 (1+ (count-lines start (point))))))
967
d5d99b80
KH
968(defun what-cursor-position (&optional detail)
969 "Print info on cursor position (on screen and within buffer).
e38dff0c 970Also describe the character after point, and give its character code
c6fcc518
KH
971in octal, decimal and hex.
972
973For a non-ASCII multibyte character, also give its encoding in the
974buffer's selected coding system if the coding system encodes the
975character safely. If the character is encoded into one byte, that
976code is shown in hex. If the character is encoded into more than one
977byte, just \"...\" is shown.
e5a902cf 978
24dad5d5 979In addition, with prefix argument, show details about that character
0b69eec5 980in *Help* buffer. See also the command `describe-char'."
d5d99b80 981 (interactive "P")
2076c87c
JB
982 (let* ((char (following-char))
983 (beg (point-min))
984 (end (point-max))
985 (pos (point))
986 (total (buffer-size))
987 (percent (if (> total 50000)
988 ;; Avoid overflow from multiplying by 100!
989 (/ (+ (/ total 200) (1- pos)) (max (/ total 100) 1))
990 (/ (+ (/ total 2) (* 100 (1- pos))) (max total 1))))
991 (hscroll (if (= (window-hscroll) 0)
992 ""
993 (format " Hscroll=%d" (window-hscroll))))
994 (col (current-column)))
995 (if (= pos end)
996 (if (or (/= beg 1) (/= end (1+ total)))
a17a79c0 997 (message "point=%d of %d (%d%%) <%d-%d> column=%d%s"
2076c87c 998 pos total percent beg end col hscroll)
a17a79c0 999 (message "point=%d of %d (EOB) column=%d%s"
63219d53 1000 pos total col hscroll))
c6fcc518 1001 (let ((coding buffer-file-coding-system)
a41b50ca 1002 encoded encoding-msg display-prop under-display)
c6fcc518
KH
1003 (if (or (not coding)
1004 (eq (coding-system-type coding) t))
b56a5ae0 1005 (setq coding (default-value 'buffer-file-coding-system)))
8f924df7 1006 (if (eq (char-charset char) 'eight-bit)
28fd4883 1007 (setq encoding-msg
41882805 1008 (format "(%d, #o%o, #x%x, raw-byte)" char char char))
a41b50ca
KH
1009 ;; Check if the character is displayed with some `display'
1010 ;; text property. In that case, set under-display to the
1011 ;; buffer substring covered by that property.
1012 (setq display-prop (get-text-property pos 'display))
1013 (if display-prop
1014 (let ((to (or (next-single-property-change pos 'display)
1015 (point-max))))
1016 (if (< to (+ pos 4))
1017 (setq under-display "")
1018 (setq under-display "..."
1019 to (+ pos 4)))
1020 (setq under-display
1021 (concat (buffer-substring-no-properties pos to)
1022 under-display)))
1023 (setq encoded (and (>= char 128) (encode-coding-char char coding))))
28fd4883 1024 (setq encoding-msg
a41b50ca
KH
1025 (if display-prop
1026 (if (not (stringp display-prop))
a17a79c0 1027 (format "(%d, #o%o, #x%x, part of display \"%s\")"
a41b50ca 1028 char char char under-display)
a17a79c0 1029 (format "(%d, #o%o, #x%x, part of display \"%s\"->\"%s\")"
a41b50ca
KH
1030 char char char under-display display-prop))
1031 (if encoded
a17a79c0 1032 (format "(%d, #o%o, #x%x, file %s)"
a41b50ca
KH
1033 char char char
1034 (if (> (length encoded) 1)
1035 "..."
1036 (encoded-string-description encoded coding)))
a17a79c0 1037 (format "(%d, #o%o, #x%x)" char char char)))))
e5e89e48 1038 (if detail
24dad5d5 1039 ;; We show the detailed information about CHAR.
0b69eec5 1040 (describe-char (point)))
24dad5d5 1041 (if (or (/= beg 1) (/= end (1+ total)))
a17a79c0 1042 (message "Char: %s %s point=%d of %d (%d%%) <%d-%d> column=%d%s"
e5a902cf
KH
1043 (if (< char 256)
1044 (single-key-description char)
f0d16a7f 1045 (buffer-substring-no-properties (point) (1+ (point))))
24dad5d5 1046 encoding-msg pos total percent beg end col hscroll)
a17a79c0 1047 (message "Char: %s %s point=%d of %d (%d%%) column=%d%s"
a41b50ca
KH
1048 (if enable-multibyte-characters
1049 (if (< char 128)
1050 (single-key-description char)
1051 (buffer-substring-no-properties (point) (1+ (point))))
1052 (single-key-description char))
24dad5d5 1053 encoding-msg pos total percent col hscroll))))))
2d88b556 1054\f
71a05b36
RS
1055;; Initialize read-expression-map. It is defined at C level.
1056(let ((m (make-sparse-keymap)))
1057 (define-key m "\M-\t" 'lisp-complete-symbol)
1058 (set-keymap-parent m minibuffer-local-map)
1059 (setq read-expression-map m))
854c16c5 1060
8570b0ca
RM
1061(defvar read-expression-history nil)
1062
ad6aa5ed
CY
1063(defvar minibuffer-completing-symbol nil
1064 "Non-nil means completing a Lisp symbol in the minibuffer.")
1065
d658acb6
CY
1066(defvar minibuffer-default nil
1067 "The current default value or list of default values in the minibuffer.
1068The functions `read-from-minibuffer' and `completing-read' bind
1069this variable locally.")
1070
b49df39d 1071(defcustom eval-expression-print-level 4
2f7e1f5a 1072 "Value for `print-level' while printing value in `eval-expression'.
d26b26dc 1073A value of nil means no limit."
b49df39d 1074 :group 'lisp
058d4999 1075 :type '(choice (const :tag "No Limit" nil) integer)
b49df39d
RS
1076 :version "21.1")
1077
1078(defcustom eval-expression-print-length 12
2f7e1f5a 1079 "Value for `print-length' while printing value in `eval-expression'.
d26b26dc 1080A value of nil means no limit."
b49df39d 1081 :group 'lisp
058d4999 1082 :type '(choice (const :tag "No Limit" nil) integer)
b49df39d
RS
1083 :version "21.1")
1084
1085(defcustom eval-expression-debug-on-error t
2f7e1f5a 1086 "If non-nil set `debug-on-error' to t in `eval-expression'.
ed8bcabe 1087If nil, don't change the value of `debug-on-error'."
b49df39d
RS
1088 :group 'lisp
1089 :type 'boolean
1090 :version "21.1")
1091
fa219ebd
JL
1092(defun eval-expression-print-format (value)
1093 "Format VALUE as a result of evaluated expression.
1094Return a formatted string which is displayed in the echo area
1095in addition to the value printed by prin1 in functions which
1096display the result of expression evaluation."
1097 (if (and (integerp value)
c9f0110e 1098 (or (not (memq this-command '(eval-last-sexp eval-print-last-sexp)))
fa219ebd 1099 (eq this-command last-command)
56abefac 1100 (if (boundp 'edebug-active) edebug-active)))
fa219ebd 1101 (let ((char-string
9bb25ed3 1102 (if (or (if (boundp 'edebug-active) edebug-active)
3137dda8 1103 (memq this-command '(eval-last-sexp eval-print-last-sexp)))
fa219ebd
JL
1104 (prin1-char value))))
1105 (if char-string
1b5fd09e
SM
1106 (format " (#o%o, #x%x, %s)" value value char-string)
1107 (format " (#o%o, #x%x)" value value)))))
fa219ebd 1108
8570b0ca 1109;; We define this, rather than making `eval' interactive,
ac052b48 1110;; for the sake of completion of names like eval-region, eval-buffer.
ecb7ad00
RS
1111(defun eval-expression (eval-expression-arg
1112 &optional eval-expression-insert-value)
a6a1ee53
EZ
1113 "Evaluate EVAL-EXPRESSION-ARG and print value in the echo area.
1114Value is also consed on to front of the variable `values'.
a7a8618b
EZ
1115Optional argument EVAL-EXPRESSION-INSERT-VALUE non-nil (interactively,
1116with prefix argument) means insert the result into the current buffer
1117instead of printing it in the echo area. Truncates long output
1118according to the value of the variables `eval-expression-print-length'
1119and `eval-expression-print-level'.
b4f73994
RS
1120
1121If `eval-expression-debug-on-error' is non-nil, which is the default,
1122this command arranges for all errors to enter the debugger."
adca5fa6 1123 (interactive
ad6aa5ed
CY
1124 (list (let ((minibuffer-completing-symbol t))
1125 (read-from-minibuffer "Eval: "
1126 nil read-expression-map t
1127 'read-expression-history))
ecb7ad00 1128 current-prefix-arg))
eaae8106 1129
ed8bcabe
GM
1130 (if (null eval-expression-debug-on-error)
1131 (setq values (cons (eval eval-expression-arg) values))
1132 (let ((old-value (make-symbol "t")) new-value)
1133 ;; Bind debug-on-error to something unique so that we can
1134 ;; detect when evaled code changes it.
1135 (let ((debug-on-error old-value))
1136 (setq values (cons (eval eval-expression-arg) values))
1137 (setq new-value debug-on-error))
1138 ;; If evaled code has changed the value of debug-on-error,
1139 ;; propagate that change to the global binding.
1140 (unless (eq old-value new-value)
1141 (setq debug-on-error new-value))))
eaae8106 1142
b49df39d
RS
1143 (let ((print-length eval-expression-print-length)
1144 (print-level eval-expression-print-level))
6b61353c
KH
1145 (if eval-expression-insert-value
1146 (with-no-warnings
1147 (let ((standard-output (current-buffer)))
22e088c6 1148 (prin1 (car values))))
fa219ebd
JL
1149 (prog1
1150 (prin1 (car values) t)
1151 (let ((str (eval-expression-print-format (car values))))
1152 (if str (princ str t)))))))
2076c87c
JB
1153
1154(defun edit-and-eval-command (prompt command)
1155 "Prompting with PROMPT, let user edit COMMAND and eval result.
1156COMMAND is a Lisp expression. Let user edit that expression in
1157the minibuffer, then read and evaluate the result."
9f4b6084 1158 (let ((command
6b61353c
KH
1159 (let ((print-level nil)
1160 (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
1161 (unwind-protect
1162 (read-from-minibuffer prompt
1163 (prin1-to-string command)
1164 read-expression-map t
1165 'command-history)
1166 ;; If command was added to command-history as a string,
1167 ;; get rid of that. We want only evaluable expressions there.
1168 (if (stringp (car command-history))
1169 (setq command-history (cdr command-history)))))))
5d6c83ae
KH
1170
1171 ;; If command to be redone does not match front of history,
1172 ;; add it to the history.
1173 (or (equal command (car command-history))
1174 (setq command-history (cons command command-history)))
2076c87c
JB
1175 (eval command)))
1176
ebb61177 1177(defun repeat-complex-command (arg)
2076c87c
JB
1178 "Edit and re-evaluate last complex command, or ARGth from last.
1179A complex command is one which used the minibuffer.
1180The command is placed in the minibuffer as a Lisp form for editing.
1181The result is executed, repeating the command as changed.
5626c14e
JB
1182If the command has been changed or is not the most recent previous
1183command it is added to the front of the command history.
1184You can use the minibuffer history commands \
1185\\<minibuffer-local-map>\\[next-history-element] and \\[previous-history-element]
eb6e9899 1186to get different commands to edit and resubmit."
2076c87c 1187 (interactive "p")
ba343182 1188 (let ((elt (nth (1- arg) command-history))
2076c87c
JB
1189 newcmd)
1190 (if elt
854c16c5 1191 (progn
eab22e27 1192 (setq newcmd
74ae5fab
RS
1193 (let ((print-level nil)
1194 (minibuffer-history-position arg)
99ea24de 1195 (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
9f4b6084
MR
1196 (unwind-protect
1197 (read-from-minibuffer
1198 "Redo: " (prin1-to-string elt) read-expression-map t
1199 (cons 'command-history arg))
1200
1201 ;; If command was added to command-history as a
1202 ;; string, get rid of that. We want only
1203 ;; evaluable expressions there.
1204 (if (stringp (car command-history))
1205 (setq command-history (cdr command-history))))))
db16f109
RS
1206
1207 ;; If command to be redone does not match front of history,
1208 ;; add it to the history.
1209 (or (equal newcmd (car command-history))
1210 (setq command-history (cons newcmd command-history)))
2076c87c 1211 (eval newcmd))
536b728a
RS
1212 (if command-history
1213 (error "Argument %d is beyond length of command history" arg)
1214 (error "There are no previous complex commands to repeat")))))
2d88b556 1215\f
854c16c5
RS
1216(defvar minibuffer-history nil
1217 "Default minibuffer history list.
1218This is used for all minibuffer input
e5f0c02f
EZ
1219except when an alternate history list is specified.
1220
1221Maximum length of the history list is determined by the value
1222of `history-length', which see.")
854c16c5 1223(defvar minibuffer-history-sexp-flag nil
6b61353c
KH
1224 "Control whether history list elements are expressions or strings.
1225If the value of this variable equals current minibuffer depth,
1226they are expressions; otherwise they are strings.
7979163c 1227\(That convention is designed to do the right thing for
6b61353c 1228recursive uses of the minibuffer.)")
e91f80c4 1229(setq minibuffer-history-variable 'minibuffer-history)
535c8bdb 1230(setq minibuffer-history-position nil) ;; Defvar is in C code.
854c16c5 1231(defvar minibuffer-history-search-history nil)
e91f80c4 1232
93cee14b
RS
1233(defvar minibuffer-text-before-history nil
1234 "Text that was in this minibuffer before any history commands.
1235This is nil if there have not yet been any history commands
1236in this use of the minibuffer.")
1237
1238(add-hook 'minibuffer-setup-hook 'minibuffer-history-initialize)
1239
1240(defun minibuffer-history-initialize ()
1241 (setq minibuffer-text-before-history nil))
1242
6e7d0ff7
MB
1243(defun minibuffer-avoid-prompt (new old)
1244 "A point-motion hook for the minibuffer, that moves point out of the prompt."
1245 (constrain-to-field nil (point-max)))
1246
6e30a99a 1247(defcustom minibuffer-history-case-insensitive-variables nil
1d2b0303 1248 "Minibuffer history variables for which matching should ignore case.
6e30a99a
RS
1249If a history variable is a member of this list, then the
1250\\[previous-matching-history-element] and \\[next-matching-history-element]\
1251 commands ignore case when searching it, regardless of `case-fold-search'."
1252 :type '(repeat variable)
1253 :group 'minibuffer)
1254
e91f80c4 1255(defun previous-matching-history-element (regexp n)
854c16c5
RS
1256 "Find the previous history element that matches REGEXP.
1257\(Previous history elements refer to earlier actions.)
1258With prefix argument N, search for Nth previous match.
5c2010f0 1259If N is negative, find the next or Nth next match.
9889af08
EZ
1260Normally, history elements are matched case-insensitively if
1261`case-fold-search' is non-nil, but an uppercase letter in REGEXP
1262makes the search case-sensitive.
6e30a99a 1263See also `minibuffer-history-case-insensitive-variables'."
854c16c5 1264 (interactive
c1172a19 1265 (let* ((enable-recursive-minibuffers t)
c1172a19
RS
1266 (regexp (read-from-minibuffer "Previous element matching (regexp): "
1267 nil
1268 minibuffer-local-map
1269 nil
5794c45d
RS
1270 'minibuffer-history-search-history
1271 (car minibuffer-history-search-history))))
c1172a19
RS
1272 ;; Use the last regexp specified, by default, if input is empty.
1273 (list (if (string= regexp "")
a8e96cea
KH
1274 (if minibuffer-history-search-history
1275 (car minibuffer-history-search-history)
1276 (error "No previous history search regexp"))
c1172a19 1277 regexp)
854c16c5 1278 (prefix-numeric-value current-prefix-arg))))
e276a14a
MB
1279 (unless (zerop n)
1280 (if (and (zerop minibuffer-history-position)
1281 (null minibuffer-text-before-history))
efaac2e6 1282 (setq minibuffer-text-before-history
6d74d713 1283 (minibuffer-contents-no-properties)))
e276a14a
MB
1284 (let ((history (symbol-value minibuffer-history-variable))
1285 (case-fold-search
1286 (if (isearch-no-upper-case-p regexp t) ; assume isearch.el is dumped
1287 ;; On some systems, ignore case for file names.
1288 (if (memq minibuffer-history-variable
1289 minibuffer-history-case-insensitive-variables)
1290 t
1291 ;; Respect the user's setting for case-fold-search:
1292 case-fold-search)
1293 nil))
1294 prevpos
1295 match-string
1296 match-offset
1297 (pos minibuffer-history-position))
1298 (while (/= n 0)
1299 (setq prevpos pos)
1300 (setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
1301 (when (= pos prevpos)
e91f80c4 1302 (error (if (= pos 1)
ccc58657
RS
1303 "No later matching history item"
1304 "No earlier matching history item")))
e276a14a
MB
1305 (setq match-string
1306 (if (eq minibuffer-history-sexp-flag (minibuffer-depth))
7908d27c 1307 (let ((print-level nil))
e276a14a
MB
1308 (prin1-to-string (nth (1- pos) history)))
1309 (nth (1- pos) history)))
1310 (setq match-offset
1311 (if (< n 0)
1312 (and (string-match regexp match-string)
1313 (match-end 0))
1314 (and (string-match (concat ".*\\(" regexp "\\)") match-string)
1315 (match-beginning 1))))
1316 (when match-offset
1317 (setq n (+ n (if (< n 0) 1 -1)))))
1318 (setq minibuffer-history-position pos)
1319 (goto-char (point-max))
efaac2e6 1320 (delete-minibuffer-contents)
e276a14a 1321 (insert match-string)
6d74d713 1322 (goto-char (+ (minibuffer-prompt-end) match-offset))))
e1e04350
SM
1323 (if (memq (car (car command-history)) '(previous-matching-history-element
1324 next-matching-history-element))
854c16c5 1325 (setq command-history (cdr command-history))))
e91f80c4 1326
e91f80c4 1327(defun next-matching-history-element (regexp n)
854c16c5
RS
1328 "Find the next history element that matches REGEXP.
1329\(The next history element refers to a more recent action.)
1330With prefix argument N, search for Nth next match.
5c2010f0 1331If N is negative, find the previous or Nth previous match.
9889af08
EZ
1332Normally, history elements are matched case-insensitively if
1333`case-fold-search' is non-nil, but an uppercase letter in REGEXP
1334makes the search case-sensitive."
854c16c5 1335 (interactive
c1172a19 1336 (let* ((enable-recursive-minibuffers t)
c1172a19
RS
1337 (regexp (read-from-minibuffer "Next element matching (regexp): "
1338 nil
1339 minibuffer-local-map
1340 nil
e967cd11
RS
1341 'minibuffer-history-search-history
1342 (car minibuffer-history-search-history))))
c1172a19
RS
1343 ;; Use the last regexp specified, by default, if input is empty.
1344 (list (if (string= regexp "")
e967cd11
RS
1345 (if minibuffer-history-search-history
1346 (car minibuffer-history-search-history)
1347 (error "No previous history search regexp"))
c1172a19 1348 regexp)
854c16c5 1349 (prefix-numeric-value current-prefix-arg))))
e91f80c4 1350 (previous-matching-history-element regexp (- n)))
2076c87c 1351
8dc3ba7d
MB
1352(defvar minibuffer-temporary-goal-position nil)
1353
7f914bbe 1354(defvar minibuffer-default-add-function 'minibuffer-default-add-completions
0eb5f40f
JL
1355 "Function run by `goto-history-element' before consuming default values.
1356This is useful to dynamically add more elements to the list of default values
7f914bbe
JL
1357when `goto-history-element' reaches the end of this list.
1358Before calling this function `goto-history-element' sets the variable
1359`minibuffer-default-add-done' to t, so it will call this function only
1360once. In special cases, when this function needs to be called more
1361than once, it can set `minibuffer-default-add-done' to nil explicitly,
1362overriding the setting of this variable to t in `goto-history-element'.")
1363
1364(defvar minibuffer-default-add-done nil
1365 "When nil, add more elements to the end of the list of default values.
1366The value nil causes `goto-history-element' to add more elements to
1367the list of defaults when it reaches the end of this list. It does
1368this by calling a function defined by `minibuffer-default-add-function'.")
1369
1370(make-variable-buffer-local 'minibuffer-default-add-done)
1371
1372(defun minibuffer-default-add-completions ()
1373 "Return a list of all completions without the default value.
1374This function is used to add all elements of the completion table to
1375the end of the list of defaults just after the default value."
7f914bbe
JL
1376 (let ((def minibuffer-default)
1377 (all (all-completions ""
1378 minibuffer-completion-table
e96d62cd 1379 minibuffer-completion-predicate)))
7f914bbe
JL
1380 (if (listp def)
1381 (append def all)
1382 (cons def (delete def all)))))
1383
297b8ccd
JL
1384(defun goto-history-element (nabs)
1385 "Puts element of the minibuffer history in the minibuffer.
1386The argument NABS specifies the absolute history position."
1387 (interactive "p")
7f914bbe
JL
1388 (when (and (not minibuffer-default-add-done)
1389 (functionp minibuffer-default-add-function)
1390 (< nabs (- (if (listp minibuffer-default)
1391 (length minibuffer-default)
1392 1))))
1393 (setq minibuffer-default-add-done t
1394 minibuffer-default (funcall minibuffer-default-add-function)))
b38fc7f1
JL
1395 (let ((minimum (if minibuffer-default
1396 (- (if (listp minibuffer-default)
1397 (length minibuffer-default)
1398 1))
1399 0))
297b8ccd
JL
1400 elt minibuffer-returned-to-present)
1401 (if (and (zerop minibuffer-history-position)
1402 (null minibuffer-text-before-history))
1403 (setq minibuffer-text-before-history
1404 (minibuffer-contents-no-properties)))
1405 (if (< nabs minimum)
1406 (if minibuffer-default
7f914bbe 1407 (error "End of defaults; no next item")
297b8ccd
JL
1408 (error "End of history; no default available")))
1409 (if (> nabs (length (symbol-value minibuffer-history-variable)))
1410 (error "Beginning of history; no preceding item"))
1411 (unless (memq last-command '(next-history-element
1412 previous-history-element))
1413 (let ((prompt-end (minibuffer-prompt-end)))
1414 (set (make-local-variable 'minibuffer-temporary-goal-position)
1415 (cond ((<= (point) prompt-end) prompt-end)
1416 ((eobp) nil)
1417 (t (point))))))
1418 (goto-char (point-max))
1419 (delete-minibuffer-contents)
1420 (setq minibuffer-history-position nabs)
b38fc7f1
JL
1421 (cond ((< nabs 0)
1422 (setq elt (if (listp minibuffer-default)
1423 (nth (1- (abs nabs)) minibuffer-default)
1424 minibuffer-default)))
297b8ccd
JL
1425 ((= nabs 0)
1426 (setq elt (or minibuffer-text-before-history ""))
1427 (setq minibuffer-returned-to-present t)
1428 (setq minibuffer-text-before-history nil))
1429 (t (setq elt (nth (1- minibuffer-history-position)
1430 (symbol-value minibuffer-history-variable)))))
1431 (insert
1432 (if (and (eq minibuffer-history-sexp-flag (minibuffer-depth))
1433 (not minibuffer-returned-to-present))
1434 (let ((print-level nil))
1435 (prin1-to-string elt))
1436 elt))
1437 (goto-char (or minibuffer-temporary-goal-position (point-max)))))
1438
ebb61177 1439(defun next-history-element (n)
1459a43b
RS
1440 "Puts next element of the minibuffer history in the minibuffer.
1441With argument N, it uses the Nth following element."
2076c87c 1442 (interactive "p")
0818b15e 1443 (or (zerop n)
297b8ccd 1444 (goto-history-element (- minibuffer-history-position n))))
2076c87c 1445
ebb61177 1446(defun previous-history-element (n)
1459a43b
RS
1447 "Puts previous element of the minibuffer history in the minibuffer.
1448With argument N, it uses the Nth previous element."
2076c87c 1449 (interactive "p")
297b8ccd
JL
1450 (or (zerop n)
1451 (goto-history-element (+ minibuffer-history-position n))))
d0678801
RM
1452
1453(defun next-complete-history-element (n)
a4d1159b
GM
1454 "Get next history element which completes the minibuffer before the point.
1455The contents of the minibuffer after the point are deleted, and replaced
1456by the new completion."
d0678801 1457 (interactive "p")
b5e6f936
RM
1458 (let ((point-at-start (point)))
1459 (next-matching-history-element
a4d1159b 1460 (concat
efaac2e6 1461 "^" (regexp-quote (buffer-substring (minibuffer-prompt-end) (point))))
a4d1159b 1462 n)
b5e6f936
RM
1463 ;; next-matching-history-element always puts us at (point-min).
1464 ;; Move to the position we were at before changing the buffer contents.
1465 ;; This is still sensical, because the text before point has not changed.
1466 (goto-char point-at-start)))
d0678801
RM
1467
1468(defun previous-complete-history-element (n)
1f6fcec3 1469 "\
a4d1159b
GM
1470Get previous history element which completes the minibuffer before the point.
1471The contents of the minibuffer after the point are deleted, and replaced
1472by the new completion."
d0678801
RM
1473 (interactive "p")
1474 (next-complete-history-element (- n)))
a4d1159b 1475
efaac2e6 1476;; For compatibility with the old subr of the same name.
a4d1159b
GM
1477(defun minibuffer-prompt-width ()
1478 "Return the display width of the minibuffer prompt.
f33321ad 1479Return 0 if current buffer is not a minibuffer."
a4d1159b
GM
1480 ;; Return the width of everything before the field at the end of
1481 ;; the buffer; this should be 0 for normal buffers.
efaac2e6 1482 (1- (minibuffer-prompt-end)))
2d88b556 1483\f
297b8ccd
JL
1484;; isearch minibuffer history
1485(add-hook 'minibuffer-setup-hook 'minibuffer-history-isearch-setup)
1486
1487(defvar minibuffer-history-isearch-message-overlay)
1488(make-variable-buffer-local 'minibuffer-history-isearch-message-overlay)
1489
1490(defun minibuffer-history-isearch-setup ()
1491 "Set up a minibuffer for using isearch to search the minibuffer history.
1492Intended to be added to `minibuffer-setup-hook'."
1493 (set (make-local-variable 'isearch-search-fun-function)
1494 'minibuffer-history-isearch-search)
1495 (set (make-local-variable 'isearch-message-function)
1496 'minibuffer-history-isearch-message)
1497 (set (make-local-variable 'isearch-wrap-function)
1498 'minibuffer-history-isearch-wrap)
1499 (set (make-local-variable 'isearch-push-state-function)
1500 'minibuffer-history-isearch-push-state)
1501 (add-hook 'isearch-mode-end-hook 'minibuffer-history-isearch-end nil t))
1502
1503(defun minibuffer-history-isearch-end ()
1504 "Clean up the minibuffer after terminating isearch in the minibuffer."
1505 (if minibuffer-history-isearch-message-overlay
1506 (delete-overlay minibuffer-history-isearch-message-overlay)))
1507
1508(defun minibuffer-history-isearch-search ()
1509 "Return the proper search function, for isearch in minibuffer history."
1510 (cond
1511 (isearch-word
1512 (if isearch-forward 'word-search-forward 'word-search-backward))
1513 (t
1514 (lambda (string bound noerror)
1515 (let ((search-fun
1516 ;; Use standard functions to search within minibuffer text
1517 (cond
1518 (isearch-regexp
1519 (if isearch-forward 're-search-forward 're-search-backward))
1520 (t
1521 (if isearch-forward 'search-forward 'search-backward))))
1522 found)
1523 ;; Avoid lazy-highlighting matches in the minibuffer prompt when
1524 ;; searching forward. Lazy-highlight calls this lambda with the
1525 ;; bound arg, so skip the minibuffer prompt.
1526 (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
1527 (goto-char (minibuffer-prompt-end)))
1528 (or
1529 ;; 1. First try searching in the initial minibuffer text
1530 (funcall search-fun string
1531 (if isearch-forward bound (minibuffer-prompt-end))
1532 noerror)
1533 ;; 2. If the above search fails, start putting next/prev history
1534 ;; elements in the minibuffer successively, and search the string
1535 ;; in them. Do this only when bound is nil (i.e. not while
1536 ;; lazy-highlighting search strings in the current minibuffer text).
1537 (unless bound
1538 (condition-case nil
1539 (progn
1540 (while (not found)
1541 (cond (isearch-forward
1542 (next-history-element 1)
1543 (goto-char (minibuffer-prompt-end)))
1544 (t
1545 (previous-history-element 1)
1546 (goto-char (point-max))))
1547 (setq isearch-barrier (point) isearch-opoint (point))
1548 ;; After putting the next/prev history element, search
1549 ;; the string in them again, until next-history-element
1550 ;; or previous-history-element raises an error at the
1551 ;; beginning/end of history.
1552 (setq found (funcall search-fun string
1553 (unless isearch-forward
1554 ;; For backward search, don't search
1555 ;; in the minibuffer prompt
1556 (minibuffer-prompt-end))
1557 noerror)))
1558 ;; Return point of the new search result
1559 (point))
1560 ;; Return nil when next(prev)-history-element fails
1561 (error nil)))))))))
1562
1563(defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
1564 "Display the minibuffer history search prompt.
1565If there are no search errors, this function displays an overlay with
1566the isearch prompt which replaces the original minibuffer prompt.
1567Otherwise, it displays the standard isearch message returned from
1568`isearch-message'."
1569 (if (not (and (minibufferp) isearch-success (not isearch-error)))
1570 ;; Use standard function `isearch-message' when not in the minibuffer,
1571 ;; or search fails, or has an error (like incomplete regexp).
1572 ;; This function overwrites minibuffer text with isearch message,
1573 ;; so it's possible to see what is wrong in the search string.
1574 (isearch-message c-q-hack ellipsis)
1575 ;; Otherwise, put the overlay with the standard isearch prompt over
1576 ;; the initial minibuffer prompt.
1577 (if (overlayp minibuffer-history-isearch-message-overlay)
1578 (move-overlay minibuffer-history-isearch-message-overlay
1579 (point-min) (minibuffer-prompt-end))
1580 (setq minibuffer-history-isearch-message-overlay
1581 (make-overlay (point-min) (minibuffer-prompt-end)))
1582 (overlay-put minibuffer-history-isearch-message-overlay 'evaporate t))
1583 (overlay-put minibuffer-history-isearch-message-overlay
1584 'display (isearch-message-prefix c-q-hack ellipsis))
1585 ;; And clear any previous isearch message.
1586 (message "")))
1587
1588(defun minibuffer-history-isearch-wrap ()
1d2b0303 1589 "Wrap the minibuffer history search when search fails.
297b8ccd
JL
1590Move point to the first history element for a forward search,
1591or to the last history element for a backward search."
1592 (unless isearch-word
1593 ;; When `minibuffer-history-isearch-search' fails on reaching the
1594 ;; beginning/end of the history, wrap the search to the first/last
1595 ;; minibuffer history element.
1596 (if isearch-forward
1597 (goto-history-element (length (symbol-value minibuffer-history-variable)))
1598 (goto-history-element 0))
1599 (setq isearch-success t))
1600 (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
1601
1602(defun minibuffer-history-isearch-push-state ()
1603 "Save a function restoring the state of minibuffer history search.
1604Save `minibuffer-history-position' to the additional state parameter
1605in the search status stack."
1606 `(lambda (cmd)
1607 (minibuffer-history-isearch-pop-state cmd ,minibuffer-history-position)))
1608
1609(defun minibuffer-history-isearch-pop-state (cmd hist-pos)
1610 "Restore the minibuffer history search state.
5626c14e 1611Go to the history element by the absolute history position HIST-POS."
297b8ccd
JL
1612 (goto-history-element hist-pos))
1613
1614\f
2076c87c 1615;Put this on C-x u, so we can force that rather than C-_ into startup msg
8cb95edf 1616(define-obsolete-function-alias 'advertised-undo 'undo "23.2")
2076c87c 1617
1e96c007 1618(defconst undo-equiv-table (make-hash-table :test 'eq :weakness t)
713c9020
RS
1619 "Table mapping redo records to the corresponding undo one.
1620A redo record for undo-in-region maps to t.
1621A redo record for ordinary undo maps to the following (earlier) undo.")
1e96c007
SM
1622
1623(defvar undo-in-region nil
1624 "Non-nil if `pending-undo-list' is not just a tail of `buffer-undo-list'.")
1625
1626(defvar undo-no-redo nil
1627 "If t, `undo' doesn't go through redo entries.")
1628
a7fe694c
RS
1629(defvar pending-undo-list nil
1630 "Within a run of consecutive undo commands, list remaining to be undone.
8ac28be5 1631If t, we undid all the way to the end of it.")
a7fe694c 1632
2076c87c
JB
1633(defun undo (&optional arg)
1634 "Undo some previous changes.
1635Repeat this command to undo more changes.
5626c14e 1636A numeric ARG serves as a repeat count.
65627aad 1637
3c1b77ca 1638In Transient Mark mode when the mark is active, only undo changes within
1e96c007 1639the current region. Similarly, when not in Transient Mark mode, just \\[universal-argument]
3c1b77ca 1640as an argument limits undo to changes within the current region."
65627aad 1641 (interactive "*P")
2e033693
RS
1642 ;; Make last-command indicate for the next command that this was an undo.
1643 ;; That way, another undo will undo more.
1644 ;; If we get to the end of the undo history and get an error,
1645 ;; another undo command will find the undo history empty
1646 ;; and will get another error. To begin undoing the undos,
1647 ;; you must type some other command.
b553cffa 1648 (let ((modified (buffer-modified-p))
cb3b2ec0
RS
1649 (recent-save (recent-auto-save-p))
1650 message)
6b61353c
KH
1651 ;; If we get an error in undo-start,
1652 ;; the next command should not be a "consecutive undo".
1653 ;; So set `this-command' to something other than `undo'.
1654 (setq this-command 'undo-start)
1655
e967cd11 1656 (unless (and (eq last-command 'undo)
a7fe694c
RS
1657 (or (eq pending-undo-list t)
1658 ;; If something (a timer or filter?) changed the buffer
1659 ;; since the previous command, don't continue the undo seq.
1660 (let ((list buffer-undo-list))
1661 (while (eq (car list) nil)
1662 (setq list (cdr list)))
1663 ;; If the last undo record made was made by undo
1664 ;; it shows nothing else happened in between.
1665 (gethash list undo-equiv-table))))
1e96c007 1666 (setq undo-in-region
d34c311a 1667 (or (region-active-p) (and arg (not (numberp arg)))))
1e96c007 1668 (if undo-in-region
3c1b77ca
MB
1669 (undo-start (region-beginning) (region-end))
1670 (undo-start))
1671 ;; get rid of initial undo boundary
1672 (undo-more 1))
9a1120ea 1673 ;; If we got this far, the next command should be a consecutive undo.
6b61353c 1674 (setq this-command 'undo)
1e96c007
SM
1675 ;; Check to see whether we're hitting a redo record, and if
1676 ;; so, ask the user whether she wants to skip the redo/undo pair.
1677 (let ((equiv (gethash pending-undo-list undo-equiv-table)))
1678 (or (eq (selected-window) (minibuffer-window))
cb3b2ec0
RS
1679 (setq message (if undo-in-region
1680 (if equiv "Redo in region!" "Undo in region!")
1681 (if equiv "Redo!" "Undo!"))))
0047373b 1682 (when (and (consp equiv) undo-no-redo)
1e96c007
SM
1683 ;; The equiv entry might point to another redo record if we have done
1684 ;; undo-redo-undo-redo-... so skip to the very last equiv.
1685 (while (let ((next (gethash equiv undo-equiv-table)))
1686 (if next (setq equiv next))))
1687 (setq pending-undo-list equiv)))
3c1b77ca 1688 (undo-more
d34c311a 1689 (if (numberp arg)
3c1b77ca
MB
1690 (prefix-numeric-value arg)
1691 1))
1e96c007 1692 ;; Record the fact that the just-generated undo records come from an
713c9020
RS
1693 ;; undo operation--that is, they are redo records.
1694 ;; In the ordinary case (not within a region), map the redo
1695 ;; record to the following undos.
1e96c007 1696 ;; I don't know how to do that in the undo-in-region case.
86f0d932
SM
1697 (let ((list buffer-undo-list))
1698 ;; Strip any leading undo boundaries there might be, like we do
1699 ;; above when checking.
1700 (while (eq (car list) nil)
1701 (setq list (cdr list)))
1702 (puthash list (if undo-in-region t pending-undo-list)
1703 undo-equiv-table))
2512c9f0
RS
1704 ;; Don't specify a position in the undo record for the undo command.
1705 ;; Instead, undoing this should move point to where the change is.
1706 (let ((tail buffer-undo-list)
003550c5
GM
1707 (prev nil))
1708 (while (car tail)
1709 (when (integerp (car tail))
1710 (let ((pos (car tail)))
1e96c007
SM
1711 (if prev
1712 (setcdr prev (cdr tail))
1713 (setq buffer-undo-list (cdr tail)))
003550c5
GM
1714 (setq tail (cdr tail))
1715 (while (car tail)
1716 (if (eq pos (car tail))
1717 (if prev
1718 (setcdr prev (cdr tail))
1719 (setq buffer-undo-list (cdr tail)))
1720 (setq prev tail))
1721 (setq tail (cdr tail)))
1722 (setq tail nil)))
1723 (setq prev tail tail (cdr tail))))
e967cd11
RS
1724 ;; Record what the current undo list says,
1725 ;; so the next command can tell if the buffer was modified in between.
2076c87c 1726 (and modified (not (buffer-modified-p))
cb3b2ec0
RS
1727 (delete-auto-save-file-if-necessary recent-save))
1728 ;; Display a message announcing success.
1729 (if message
f6e7ec02 1730 (message "%s" message))))
2076c87c 1731
e967cd11
RS
1732(defun buffer-disable-undo (&optional buffer)
1733 "Make BUFFER stop keeping undo information.
1734No argument or nil as argument means do this for the current buffer."
1735 (interactive)
0d808a63 1736 (with-current-buffer (if buffer (get-buffer buffer) (current-buffer))
d020fce0 1737 (setq buffer-undo-list t)))
e967cd11 1738
1e96c007
SM
1739(defun undo-only (&optional arg)
1740 "Undo some previous changes.
1741Repeat this command to undo more changes.
5626c14e 1742A numeric ARG serves as a repeat count.
1e96c007
SM
1743Contrary to `undo', this will not redo a previous undo."
1744 (interactive "*p")
1745 (let ((undo-no-redo t)) (undo arg)))
1e96c007 1746
52d1110d
RS
1747(defvar undo-in-progress nil
1748 "Non-nil while performing an undo.
1749Some change-hooks test this variable to do something different.")
1750
8ac28be5 1751(defun undo-more (n)
2076c87c 1752 "Undo back N undo-boundaries beyond what was already undone recently.
ff1fbe3e
RS
1753Call `undo-start' to get ready to undo recent changes,
1754then call `undo-more' one or more times to undo them."
a7fe694c 1755 (or (listp pending-undo-list)
8ac28be5 1756 (error (concat "No further undo information"
00fa4024 1757 (and undo-in-region " for region"))))
52d1110d 1758 (let ((undo-in-progress t))
b553f685
AM
1759 ;; Note: The following, while pulling elements off
1760 ;; `pending-undo-list' will call primitive change functions which
1761 ;; will push more elements onto `buffer-undo-list'.
8ac28be5 1762 (setq pending-undo-list (primitive-undo n pending-undo-list))
a7fe694c
RS
1763 (if (null pending-undo-list)
1764 (setq pending-undo-list t))))
2076c87c 1765
65627aad
RS
1766;; Deep copy of a list
1767(defun undo-copy-list (list)
1768 "Make a copy of undo list LIST."
1769 (mapcar 'undo-copy-list-1 list))
1770
1771(defun undo-copy-list-1 (elt)
1772 (if (consp elt)
1773 (cons (car elt) (undo-copy-list-1 (cdr elt)))
1774 elt))
1775
1776(defun undo-start (&optional beg end)
1777 "Set `pending-undo-list' to the front of the undo list.
1778The next call to `undo-more' will undo the most recently made change.
1779If BEG and END are specified, then only undo elements
1780that apply to text between BEG and END are used; other undo elements
1781are ignored. If BEG and END are nil, all undo elements are used."
1782 (if (eq buffer-undo-list t)
1783 (error "No undo information in this buffer"))
1e722f9f 1784 (setq pending-undo-list
65627aad
RS
1785 (if (and beg end (not (= beg end)))
1786 (undo-make-selective-list (min beg end) (max beg end))
1787 buffer-undo-list)))
1788
1789(defvar undo-adjusted-markers)
1790
1791(defun undo-make-selective-list (start end)
1792 "Return a list of undo elements for the region START to END.
1793The elements come from `buffer-undo-list', but we keep only
1794the elements inside this region, and discard those outside this region.
1795If we find an element that crosses an edge of this region,
1796we stop and ignore all further elements."
1797 (let ((undo-list-copy (undo-copy-list buffer-undo-list))
1798 (undo-list (list nil))
1799 undo-adjusted-markers
1800 some-rejected
1801 undo-elt undo-elt temp-undo-list delta)
1802 (while undo-list-copy
1803 (setq undo-elt (car undo-list-copy))
1804 (let ((keep-this
1805 (cond ((and (consp undo-elt) (eq (car undo-elt) t))
1806 ;; This is a "was unmodified" element.
1807 ;; Keep it if we have kept everything thus far.
1808 (not some-rejected))
1809 (t
1810 (undo-elt-in-region undo-elt start end)))))
1811 (if keep-this
1812 (progn
1813 (setq end (+ end (cdr (undo-delta undo-elt))))
1814 ;; Don't put two nils together in the list
1815 (if (not (and (eq (car undo-list) nil)
1816 (eq undo-elt nil)))
1817 (setq undo-list (cons undo-elt undo-list))))
1818 (if (undo-elt-crosses-region undo-elt start end)
1819 (setq undo-list-copy nil)
1820 (setq some-rejected t)
1821 (setq temp-undo-list (cdr undo-list-copy))
1822 (setq delta (undo-delta undo-elt))
1823
1824 (when (/= (cdr delta) 0)
1825 (let ((position (car delta))
1826 (offset (cdr delta)))
1827
e1e04350
SM
1828 ;; Loop down the earlier events adjusting their buffer
1829 ;; positions to reflect the fact that a change to the buffer
1830 ;; isn't being undone. We only need to process those element
1831 ;; types which undo-elt-in-region will return as being in
1832 ;; the region since only those types can ever get into the
1833 ;; output
65627aad
RS
1834
1835 (while temp-undo-list
1836 (setq undo-elt (car temp-undo-list))
1837 (cond ((integerp undo-elt)
1838 (if (>= undo-elt position)
1839 (setcar temp-undo-list (- undo-elt offset))))
1840 ((atom undo-elt) nil)
1841 ((stringp (car undo-elt))
1842 ;; (TEXT . POSITION)
1843 (let ((text-pos (abs (cdr undo-elt)))
1844 (point-at-end (< (cdr undo-elt) 0 )))
1845 (if (>= text-pos position)
1e722f9f 1846 (setcdr undo-elt (* (if point-at-end -1 1)
65627aad
RS
1847 (- text-pos offset))))))
1848 ((integerp (car undo-elt))
1849 ;; (BEGIN . END)
1850 (when (>= (car undo-elt) position)
1851 (setcar undo-elt (- (car undo-elt) offset))
1852 (setcdr undo-elt (- (cdr undo-elt) offset))))
1853 ((null (car undo-elt))
1854 ;; (nil PROPERTY VALUE BEG . END)
1855 (let ((tail (nthcdr 3 undo-elt)))
1856 (when (>= (car tail) position)
1857 (setcar tail (- (car tail) offset))
1858 (setcdr tail (- (cdr tail) offset))))))
1859 (setq temp-undo-list (cdr temp-undo-list))))))))
1860 (setq undo-list-copy (cdr undo-list-copy)))
1861 (nreverse undo-list)))
1862
1863(defun undo-elt-in-region (undo-elt start end)
1864 "Determine whether UNDO-ELT falls inside the region START ... END.
1865If it crosses the edge, we return nil."
1866 (cond ((integerp undo-elt)
1867 (and (>= undo-elt start)
12a93712 1868 (<= undo-elt end)))
65627aad
RS
1869 ((eq undo-elt nil)
1870 t)
1871 ((atom undo-elt)
1872 nil)
1873 ((stringp (car undo-elt))
1874 ;; (TEXT . POSITION)
1875 (and (>= (abs (cdr undo-elt)) start)
1876 (< (abs (cdr undo-elt)) end)))
1877 ((and (consp undo-elt) (markerp (car undo-elt)))
1878 ;; This is a marker-adjustment element (MARKER . ADJUSTMENT).
1879 ;; See if MARKER is inside the region.
1880 (let ((alist-elt (assq (car undo-elt) undo-adjusted-markers)))
1881 (unless alist-elt
1882 (setq alist-elt (cons (car undo-elt)
1883 (marker-position (car undo-elt))))
1884 (setq undo-adjusted-markers
1885 (cons alist-elt undo-adjusted-markers)))
1886 (and (cdr alist-elt)
1887 (>= (cdr alist-elt) start)
12a93712 1888 (<= (cdr alist-elt) end))))
65627aad
RS
1889 ((null (car undo-elt))
1890 ;; (nil PROPERTY VALUE BEG . END)
1891 (let ((tail (nthcdr 3 undo-elt)))
1892 (and (>= (car tail) start)
12a93712 1893 (<= (cdr tail) end))))
65627aad
RS
1894 ((integerp (car undo-elt))
1895 ;; (BEGIN . END)
1896 (and (>= (car undo-elt) start)
12a93712 1897 (<= (cdr undo-elt) end)))))
65627aad
RS
1898
1899(defun undo-elt-crosses-region (undo-elt start end)
1900 "Test whether UNDO-ELT crosses one edge of that region START ... END.
1901This assumes we have already decided that UNDO-ELT
1902is not *inside* the region START...END."
1903 (cond ((atom undo-elt) nil)
1904 ((null (car undo-elt))
1905 ;; (nil PROPERTY VALUE BEG . END)
1906 (let ((tail (nthcdr 3 undo-elt)))
1f8a132d
RS
1907 (and (< (car tail) end)
1908 (> (cdr tail) start))))
65627aad
RS
1909 ((integerp (car undo-elt))
1910 ;; (BEGIN . END)
1f8a132d
RS
1911 (and (< (car undo-elt) end)
1912 (> (cdr undo-elt) start)))))
65627aad
RS
1913
1914;; Return the first affected buffer position and the delta for an undo element
1915;; delta is defined as the change in subsequent buffer positions if we *did*
1916;; the undo.
1917(defun undo-delta (undo-elt)
1918 (if (consp undo-elt)
1919 (cond ((stringp (car undo-elt))
1920 ;; (TEXT . POSITION)
1921 (cons (abs (cdr undo-elt)) (length (car undo-elt))))
1922 ((integerp (car undo-elt))
1923 ;; (BEGIN . END)
1924 (cons (car undo-elt) (- (car undo-elt) (cdr undo-elt))))
1925 (t
1926 '(0 . 0)))
1927 '(0 . 0)))
b6e8e8e5 1928
1223933d 1929(defcustom undo-ask-before-discard nil
28cb725d
LT
1930 "If non-nil ask about discarding undo info for the current command.
1931Normally, Emacs discards the undo info for the current command if
1932it exceeds `undo-outer-limit'. But if you set this option
1933non-nil, it asks in the echo area whether to discard the info.
a3545af4 1934If you answer no, there is a slight risk that Emacs might crash, so
28cb725d
LT
1935only do it if you really want to undo the command.
1936
1937This option is mainly intended for debugging. You have to be
1938careful if you use it for other purposes. Garbage collection is
1939inhibited while the question is asked, meaning that Emacs might
1940leak memory. So you should make sure that you do not wait
1941excessively long before answering the question."
1942 :type 'boolean
1943 :group 'undo
bf247b6e 1944 :version "22.1")
28cb725d 1945
a1a801de
RS
1946(defvar undo-extra-outer-limit nil
1947 "If non-nil, an extra level of size that's ok in an undo item.
1948We don't ask the user about truncating the undo list until the
28cb725d
LT
1949current item gets bigger than this amount.
1950
1951This variable only matters if `undo-ask-before-discard' is non-nil.")
a1a801de
RS
1952(make-variable-buffer-local 'undo-extra-outer-limit)
1953
28cb725d
LT
1954;; When the first undo batch in an undo list is longer than
1955;; undo-outer-limit, this function gets called to warn the user that
1956;; the undo info for the current command was discarded. Garbage
1957;; collection is inhibited around the call, so it had better not do a
1958;; lot of consing.
b6e8e8e5
RS
1959(setq undo-outer-limit-function 'undo-outer-limit-truncate)
1960(defun undo-outer-limit-truncate (size)
28cb725d
LT
1961 (if undo-ask-before-discard
1962 (when (or (null undo-extra-outer-limit)
1963 (> size undo-extra-outer-limit))
1964 ;; Don't ask the question again unless it gets even bigger.
1965 ;; This applies, in particular, if the user quits from the question.
1966 ;; Such a quit quits out of GC, but something else will call GC
1967 ;; again momentarily. It will call this function again,
1968 ;; but we don't want to ask the question again.
1969 (setq undo-extra-outer-limit (+ size 50000))
1970 (if (let (use-dialog-box track-mouse executing-kbd-macro )
d5aa078b 1971 (yes-or-no-p (format "Buffer `%s' undo info is %d bytes long; discard it? "
28cb725d
LT
1972 (buffer-name) size)))
1973 (progn (setq buffer-undo-list nil)
1974 (setq undo-extra-outer-limit nil)
1975 t)
1976 nil))
1977 (display-warning '(undo discard-info)
1978 (concat
d5aa078b 1979 (format "Buffer `%s' undo info was %d bytes long.\n"
28cb725d
LT
1980 (buffer-name) size)
1981 "The undo info was discarded because it exceeded \
1982`undo-outer-limit'.
1983
1984This is normal if you executed a command that made a huge change
1985to the buffer. In that case, to prevent similar problems in the
1986future, set `undo-outer-limit' to a value that is large enough to
1987cover the maximum size of normal changes you expect a single
1988command to make, but not so large that it might exceed the
1989maximum memory allotted to Emacs.
1990
1991If you did not execute any such command, the situation is
1992probably due to a bug and you should report it.
1993
1994You can disable the popping up of this buffer by adding the entry
14f01bef
CY
1995\(undo discard-info) to the user option `warning-suppress-types',
1996which is defined in the `warnings' library.\n")
28cb725d
LT
1997 :warning)
1998 (setq buffer-undo-list nil)
1999 t))
e1e04350 2000\f
009ef402 2001(defvar shell-command-history nil
e5f0c02f
EZ
2002 "History list for some commands that read shell commands.
2003
2004Maximum length of the history list is determined by the value
2005of `history-length', which see.")
009ef402 2006
6d341a2a 2007(defvar shell-command-switch (purecopy "-c")
59fc41e5
RS
2008 "Switch used to have the shell execute its command line argument.")
2009
cc039f78
KH
2010(defvar shell-command-default-error-buffer nil
2011 "*Buffer name for `shell-command' and `shell-command-on-region' error output.
637fff82 2012This buffer is used when `shell-command' or `shell-command-on-region'
cc039f78
KH
2013is run interactively. A value of nil means that output to stderr and
2014stdout will be intermixed in the output stream.")
2015
a98a2fe8 2016(declare-function mailcap-file-default-commands "mailcap" (files))
e0987650 2017(declare-function dired-get-filename "dired" (&optional localp no-error-if-not-filep))
a98a2fe8
JL
2018
2019(defun minibuffer-default-add-shell-commands ()
263bc3fa 2020 "Return a list of all commands associated with the current file.
086a7dd4 2021This function is used to add all related commands retrieved by `mailcap'
a98a2fe8
JL
2022to the end of the list of defaults just after the default value."
2023 (interactive)
2024 (let* ((filename (if (listp minibuffer-default)
2025 (car minibuffer-default)
2026 minibuffer-default))
2027 (commands (and filename (require 'mailcap nil t)
2028 (mailcap-file-default-commands (list filename)))))
2029 (setq commands (mapcar (lambda (command)
2030 (concat command " " filename))
2031 commands))
2032 (if (listp minibuffer-default)
2033 (append minibuffer-default commands)
2034 (cons minibuffer-default commands))))
2035
2e7bd464
GM
2036(defvar shell-delimiter-argument-list)
2037(defvar shell-file-name-chars)
2038(defvar shell-file-name-quote-list)
2039
e5c4079c
SM
2040(defun minibuffer-complete-shell-command ()
2041 "Dynamically complete shell command at point."
2042 (interactive)
2043 (require 'shell)
79ccd1b8
AS
2044 (let ((comint-delimiter-argument-list shell-delimiter-argument-list)
2045 (comint-file-name-chars shell-file-name-chars)
2046 (comint-file-name-quote-list shell-file-name-quote-list))
2047 (run-hook-with-args-until-success 'shell-dynamic-complete-functions)))
e5c4079c
SM
2048
2049(defvar minibuffer-local-shell-command-map
2050 (let ((map (make-sparse-keymap)))
2051 (set-keymap-parent map minibuffer-local-map)
2052 (define-key map "\t" 'minibuffer-complete-shell-command)
2053 map)
1d2b0303 2054 "Keymap used for completing shell commands in minibuffer.")
e5c4079c
SM
2055
2056(defun read-shell-command (prompt &optional initial-contents hist &rest args)
2057 "Read a shell command from the minibuffer.
2058The arguments are the same as the ones of `read-from-minibuffer',
2059except READ and KEYMAP are missing and HIST defaults
2060to `shell-command-history'."
d6601455
JL
2061 (minibuffer-with-setup-hook
2062 (lambda ()
2063 (set (make-local-variable 'minibuffer-default-add-function)
2064 'minibuffer-default-add-shell-commands))
2065 (apply 'read-from-minibuffer prompt initial-contents
2066 minibuffer-local-shell-command-map
2067 nil
2068 (or hist 'shell-command-history)
2069 args)))
e5c4079c 2070
c945a962
JL
2071(defun async-shell-command (command &optional output-buffer error-buffer)
2072 "Execute string COMMAND asynchronously in background.
2073
2074Like `shell-command' but if COMMAND doesn't end in ampersand, adds `&'
2075surrounded by whitespace and executes the command asynchronously.
2076The output appears in the buffer `*Async Shell Command*'."
2077 (interactive
2078 (list
2079 (read-shell-command "Async shell command: " nil nil
2080 (and buffer-file-name
2081 (file-relative-name buffer-file-name)))
2082 current-prefix-arg
2083 shell-command-default-error-buffer))
2084 (unless (string-match "&[ \t]*\\'" command)
2085 (setq command (concat command " &")))
2086 (shell-command command output-buffer error-buffer))
2087
cc039f78 2088(defun shell-command (command &optional output-buffer error-buffer)
2076c87c 2089 "Execute string COMMAND in inferior shell; display output, if any.
0b3f96d4 2090With prefix argument, insert the COMMAND's output at point.
d382f610 2091
2076c87c 2092If COMMAND ends in ampersand, execute it asynchronously.
d382f610 2093The output appears in the buffer `*Async Shell Command*'.
bcad4985 2094That buffer is in shell mode.
d382f610 2095
939ac10c
GM
2096Otherwise, COMMAND is executed synchronously. The output appears in
2097the buffer `*Shell Command Output*'. If the output is short enough to
2098display in the echo area (which is determined by the variables
2099`resize-mini-windows' and `max-mini-window-height'), it is shown
2100there, but it is nonetheless available in buffer `*Shell Command
e1e04350 2101Output*' even though that buffer is not automatically displayed.
d0d74413 2102
07f458c1 2103To specify a coding system for converting non-ASCII characters
5626c14e 2104in the shell command output, use \\[universal-coding-system-argument] \
07f458c1
RS
2105before this command.
2106
2107Noninteractive callers can specify coding systems by binding
2108`coding-system-for-read' and `coding-system-for-write'.
2109
d0d74413
RS
2110The optional second argument OUTPUT-BUFFER, if non-nil,
2111says to put the output in some other buffer.
2112If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
2113If OUTPUT-BUFFER is not a buffer and not nil,
2114insert output in current buffer. (This cannot be done asynchronously.)
e7791447
CY
2115In either case, the buffer is first erased, and the output is
2116inserted after point (leaving mark after it).
cc039f78 2117
2e033693
RS
2118If the command terminates without error, but generates output,
2119and you did not specify \"insert it in the current buffer\",
2120the output can be displayed in the echo area or in its buffer.
2121If the output is short enough to display in the echo area
2122\(determined by the variable `max-mini-window-height' if
5626c14e
JB
2123`resize-mini-windows' is non-nil), it is shown there.
2124Otherwise,the buffer containing the output is displayed.
2e033693
RS
2125
2126If there is output and an error, and you did not specify \"insert it
2127in the current buffer\", a message about the error goes at the end
2128of the output.
2129
2130If there is no output, or if output is inserted in the current buffer,
2131then `*Shell Command Output*' is deleted.
2132
cc039f78
KH
2133If the optional third argument ERROR-BUFFER is non-nil, it is a buffer
2134or buffer name to which to direct the command's standard error output.
2135If it is nil, error output is mingled with regular output.
2136In an interactive call, the variable `shell-command-default-error-buffer'
2137specifies the value of ERROR-BUFFER."
2138
a98a2fe8
JL
2139 (interactive
2140 (list
d6601455 2141 (read-shell-command "Shell command: " nil nil
e0987650
JL
2142 (let ((filename
2143 (cond
2144 (buffer-file-name)
2145 ((eq major-mode 'dired-mode)
2146 (dired-get-filename nil t)))))
2147 (and filename (file-relative-name filename))))
a98a2fe8
JL
2148 current-prefix-arg
2149 shell-command-default-error-buffer))
c7edd03c
KH
2150 ;; Look for a handler in case default-directory is a remote file name.
2151 (let ((handler
2152 (find-file-name-handler (directory-file-name default-directory)
2153 'shell-command)))
2154 (if handler
cc039f78 2155 (funcall handler 'shell-command command output-buffer error-buffer)
c7edd03c
KH
2156 (if (and output-buffer
2157 (not (or (bufferp output-buffer) (stringp output-buffer))))
2e033693 2158 ;; Output goes in current buffer.
cc039f78 2159 (let ((error-file
1e722f9f 2160 (if error-buffer
b005abd5 2161 (make-temp-file
171a45d9
EZ
2162 (expand-file-name "scor"
2163 (or small-temporary-file-directory
2164 temporary-file-directory)))
cc039f78
KH
2165 nil)))
2166 (barf-if-buffer-read-only)
63437623 2167 (push-mark nil t)
cc039f78
KH
2168 ;; We do not use -f for csh; we will not support broken use of
2169 ;; .cshrcs. Even the BSD csh manual says to use
2170 ;; "if ($?prompt) exit" before things which are not useful
2171 ;; non-interactively. Besides, if someone wants their other
2172 ;; aliases for shell commands then they can still have them.
1e722f9f 2173 (call-process shell-file-name nil
cc039f78
KH
2174 (if error-file
2175 (list t error-file)
2176 t)
2177 nil shell-command-switch command)
2178 (when (and error-file (file-exists-p error-file))
2179 (if (< 0 (nth 7 (file-attributes error-file)))
2180 (with-current-buffer (get-buffer-create error-buffer)
2181 (let ((pos-from-end (- (point-max) (point))))
2182 (or (bobp)
2183 (insert "\f\n"))
2184 ;; Do no formatting while reading error file,
2185 ;; because that can run a shell command, and we
2186 ;; don't want that to cause an infinite recursion.
2187 (format-insert-file error-file nil)
2188 ;; Put point after the inserted errors.
2189 (goto-char (- (point-max) pos-from-end)))
2190 (display-buffer (current-buffer))))
2191 (delete-file error-file))
2192 ;; This is like exchange-point-and-mark, but doesn't
2193 ;; activate the mark. It is cleaner to avoid activation,
2194 ;; even though the command loop would deactivate the mark
2195 ;; because we inserted text.
2196 (goto-char (prog1 (mark t)
2197 (set-marker (mark-marker) (point)
2198 (current-buffer)))))
2e033693 2199 ;; Output goes in a separate buffer.
c7edd03c
KH
2200 ;; Preserve the match data in case called from a program.
2201 (save-match-data
aab5d2c5 2202 (if (string-match "[ \t]*&[ \t]*\\'" command)
c7edd03c
KH
2203 ;; Command ending with ampersand means asynchronous.
2204 (let ((buffer (get-buffer-create
2205 (or output-buffer "*Async Shell Command*")))
2206 (directory default-directory)
2207 proc)
2208 ;; Remove the ampersand.
2209 (setq command (substring command 0 (match-beginning 0)))
2210 ;; If will kill a process, query first.
2211 (setq proc (get-buffer-process buffer))
2212 (if proc
2213 (if (yes-or-no-p "A command is running. Kill it? ")
2214 (kill-process proc)
2215 (error "Shell command in progress")))
1e96c007 2216 (with-current-buffer buffer
c7edd03c
KH
2217 (setq buffer-read-only nil)
2218 (erase-buffer)
2219 (display-buffer buffer)
2220 (setq default-directory directory)
1e722f9f 2221 (setq proc (start-process "Shell" buffer shell-file-name
c7edd03c
KH
2222 shell-command-switch command))
2223 (setq mode-line-process '(":%s"))
c2020c27 2224 (require 'shell) (shell-mode)
c7edd03c 2225 (set-process-sentinel proc 'shell-command-sentinel)
50c737e4
JL
2226 ;; Use the comint filter for proper handling of carriage motion
2227 ;; (see `comint-inhibit-carriage-motion'),.
2228 (set-process-filter proc 'comint-output-filter)
c7edd03c 2229 ))
50c737e4 2230 ;; Otherwise, command is executed synchronously.
cc039f78
KH
2231 (shell-command-on-region (point) (point) command
2232 output-buffer nil error-buffer)))))))
eaae8106 2233
f69aad2b
MB
2234(defun display-message-or-buffer (message
2235 &optional buffer-name not-this-window frame)
2236 "Display MESSAGE in the echo area if possible, otherwise in a pop-up buffer.
2237MESSAGE may be either a string or a buffer.
2238
2239A buffer is displayed using `display-buffer' if MESSAGE is too long for
939ac10c
GM
2240the maximum height of the echo area, as defined by `max-mini-window-height'
2241if `resize-mini-windows' is non-nil.
f69aad2b 2242
2a3f00bf
MB
2243Returns either the string shown in the echo area, or when a pop-up
2244buffer is used, the window used to display it.
2245
f69aad2b
MB
2246If MESSAGE is a string, then the optional argument BUFFER-NAME is the
2247name of the buffer used to display it in the case where a pop-up buffer
2248is used, defaulting to `*Message*'. In the case where MESSAGE is a
2249string and it is displayed in the echo area, it is not specified whether
2250the contents are inserted into the buffer anyway.
2251
2252Optional arguments NOT-THIS-WINDOW and FRAME are as for `display-buffer',
2253and only used if a buffer is displayed."
39a8d88a 2254 (cond ((and (stringp message) (not (string-match "\n" message)))
f69aad2b
MB
2255 ;; Trivial case where we can use the echo area
2256 (message "%s" message))
2257 ((and (stringp message)
39a8d88a 2258 (= (string-match "\n" message) (1- (length message))))
f69aad2b
MB
2259 ;; Trivial case where we can just remove single trailing newline
2260 (message "%s" (substring message 0 (1- (length message)))))
2261 (t
2262 ;; General case
2263 (with-current-buffer
2264 (if (bufferp message)
2265 message
2266 (get-buffer-create (or buffer-name "*Message*")))
2267
2268 (unless (bufferp message)
2269 (erase-buffer)
2270 (insert message))
2271
2272 (let ((lines
2273 (if (= (buffer-size) 0)
2274 0
62ffcd76 2275 (count-screen-lines nil nil nil (minibuffer-window)))))
4f017185
RS
2276 (cond ((= lines 0))
2277 ((and (or (<= lines 1)
aab5d2c5
RS
2278 (<= lines
2279 (if resize-mini-windows
2280 (cond ((floatp max-mini-window-height)
2281 (* (frame-height)
2282 max-mini-window-height))
2283 ((integerp max-mini-window-height)
2284 max-mini-window-height)
2285 (t
2286 1))
2287 1)))
2288 ;; Don't use the echo area if the output buffer is
2289 ;; already dispayed in the selected frame.
61b80ebf 2290 (not (get-buffer-window (current-buffer))))
f69aad2b
MB
2291 ;; Echo area
2292 (goto-char (point-max))
2293 (when (bolp)
2294 (backward-char 1))
2295 (message "%s" (buffer-substring (point-min) (point))))
2296 (t
2297 ;; Buffer
2298 (goto-char (point-min))
31252c00
MB
2299 (display-buffer (current-buffer)
2300 not-this-window frame))))))))
f69aad2b
MB
2301
2302
2076c87c
JB
2303;; We have a sentinel to prevent insertion of a termination message
2304;; in the buffer itself.
2305(defun shell-command-sentinel (process signal)
bcad4985 2306 (if (memq (process-status process) '(exit signal))
1e722f9f 2307 (message "%s: %s."
bcad4985
KH
2308 (car (cdr (cdr (process-command process))))
2309 (substring signal 0 -1))))
2076c87c 2310
d0d74413 2311(defun shell-command-on-region (start end command
cce1c318 2312 &optional output-buffer replace
63619f42 2313 error-buffer display-error-buffer)
2076c87c
JB
2314 "Execute string COMMAND in inferior shell with region as input.
2315Normally display output (if any) in temp buffer `*Shell Command Output*';
a0184aeb
DL
2316Prefix arg means replace the region with it. Return the exit code of
2317COMMAND.
56c0450e 2318
07f458c1
RS
2319To specify a coding system for converting non-ASCII characters
2320in the input and output to the shell command, use \\[universal-coding-system-argument]
2321before this command. By default, the input (from the current buffer)
2322is encoded in the same coding system that will be used to save the file,
2323`buffer-file-coding-system'. If the output is going to replace the region,
2324then it is decoded from that same coding system.
2325
63619f42
RS
2326The noninteractive arguments are START, END, COMMAND,
2327OUTPUT-BUFFER, REPLACE, ERROR-BUFFER, and DISPLAY-ERROR-BUFFER.
2328Noninteractive callers can specify coding systems by binding
2329`coding-system-for-read' and `coding-system-for-write'.
2076c87c 2330
2e033693
RS
2331If the command generates output, the output may be displayed
2332in the echo area or in a buffer.
2333If the output is short enough to display in the echo area
2334\(determined by the variable `max-mini-window-height' if
2335`resize-mini-windows' is non-nil), it is shown there. Otherwise
2336it is displayed in the buffer `*Shell Command Output*'. The output
2337is available in that buffer in both cases.
2338
2339If there is output and an error, a message about the error
2340appears at the end of the output.
2341
2342If there is no output, or if output is inserted in the current buffer,
2343then `*Shell Command Output*' is deleted.
d0d74413 2344
56c0450e
RS
2345If the optional fourth argument OUTPUT-BUFFER is non-nil,
2346that says to put the output in some other buffer.
d0d74413
RS
2347If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
2348If OUTPUT-BUFFER is not a buffer and not nil,
2349insert output in the current buffer.
cce1c318
RS
2350In either case, the output is inserted after point (leaving mark after it).
2351
8923a211
RS
2352If REPLACE, the optional fifth argument, is non-nil, that means insert
2353the output in place of text from START to END, putting point and mark
2354around it.
2355
b735c991 2356If optional sixth argument ERROR-BUFFER is non-nil, it is a buffer
cce1c318 2357or buffer name to which to direct the command's standard error output.
7fd47839 2358If it is nil, error output is mingled with regular output.
63619f42
RS
2359If DISPLAY-ERROR-BUFFER is non-nil, display the error buffer if there
2360were any errors. (This is always t, interactively.)
cc039f78
KH
2361In an interactive call, the variable `shell-command-default-error-buffer'
2362specifies the value of ERROR-BUFFER."
195ce311
RS
2363 (interactive (let (string)
2364 (unless (mark)
2365 (error "The mark is not set now, so there is no region"))
2366 ;; Do this before calling region-beginning
2367 ;; and region-end, in case subprocess output
2368 ;; relocates them while we are in the minibuffer.
e5c4079c 2369 (setq string (read-shell-command "Shell command on region: "))
2b03c506
RS
2370 ;; call-interactively recognizes region-beginning and
2371 ;; region-end specially, leaving them in the history.
2372 (list (region-beginning) (region-end)
cae49185
RS
2373 string
2374 current-prefix-arg
7fd47839 2375 current-prefix-arg
63619f42
RS
2376 shell-command-default-error-buffer
2377 t)))
cce1c318 2378 (let ((error-file
171a45d9 2379 (if error-buffer
b005abd5 2380 (make-temp-file
171a45d9
EZ
2381 (expand-file-name "scor"
2382 (or small-temporary-file-directory
2383 temporary-file-directory)))
a0184aeb
DL
2384 nil))
2385 exit-status)
7fd47839
RS
2386 (if (or replace
2387 (and output-buffer
748d6ca4 2388 (not (or (bufferp output-buffer) (stringp output-buffer)))))
7fd47839
RS
2389 ;; Replace specified region with output from command.
2390 (let ((swap (and replace (< start end))))
2391 ;; Don't muck with mark unless REPLACE says we should.
2392 (goto-char start)
30883773 2393 (and replace (push-mark (point) 'nomsg))
a0184aeb
DL
2394 (setq exit-status
2395 (call-process-region start end shell-file-name t
2396 (if error-file
2397 (list t error-file)
2398 t)
2399 nil shell-command-switch command))
e1e04350
SM
2400 ;; It is rude to delete a buffer which the command is not using.
2401 ;; (let ((shell-buffer (get-buffer "*Shell Command Output*")))
2402 ;; (and shell-buffer (not (eq shell-buffer (current-buffer)))
2403 ;; (kill-buffer shell-buffer)))
7fd47839
RS
2404 ;; Don't muck with mark unless REPLACE says we should.
2405 (and replace swap (exchange-point-and-mark)))
2406 ;; No prefix argument: put the output in a temp buffer,
2407 ;; replacing its entire contents.
2408 (let ((buffer (get-buffer-create
d4bbcbb4 2409 (or output-buffer "*Shell Command Output*"))))
7fd47839
RS
2410 (unwind-protect
2411 (if (eq buffer (current-buffer))
2412 ;; If the input is the same buffer as the output,
2413 ;; delete everything but the specified region,
2414 ;; then replace that region with the output.
2415 (progn (setq buffer-read-only nil)
2416 (delete-region (max start end) (point-max))
2417 (delete-region (point-min) (min start end))
2418 (setq exit-status
2419 (call-process-region (point-min) (point-max)
1e722f9f 2420 shell-file-name t
7fd47839
RS
2421 (if error-file
2422 (list t error-file)
2423 t)
a0184aeb
DL
2424 nil shell-command-switch
2425 command)))
2426 ;; Clear the output buffer, then run the command with
2427 ;; output there.
c2e303c8 2428 (let ((directory default-directory))
7fdbcd83 2429 (with-current-buffer buffer
c2e303c8
GM
2430 (setq buffer-read-only nil)
2431 (if (not output-buffer)
2432 (setq default-directory directory))
2433 (erase-buffer)))
7fd47839
RS
2434 (setq exit-status
2435 (call-process-region start end shell-file-name nil
2436 (if error-file
2437 (list buffer error-file)
2438 buffer)
a0184aeb 2439 nil shell-command-switch command)))
2e033693 2440 ;; Report the output.
9a98fa64 2441 (with-current-buffer buffer
f1180544 2442 (setq mode-line-process
d4bbcbb4
AS
2443 (cond ((null exit-status)
2444 " - Error")
2445 ((stringp exit-status)
2446 (format " - Signal [%s]" exit-status))
2447 ((not (equal 0 exit-status))
2448 (format " - Exit [%d]" exit-status)))))
f69aad2b
MB
2449 (if (with-current-buffer buffer (> (point-max) (point-min)))
2450 ;; There's some output, display it
9a98fa64 2451 (display-message-or-buffer buffer)
f69aad2b 2452 ;; No output; error?
94ddbe6d
RS
2453 (let ((output
2454 (if (and error-file
2455 (< 0 (nth 7 (file-attributes error-file))))
2456 "some error output"
2457 "no output")))
d4bbcbb4
AS
2458 (cond ((null exit-status)
2459 (message "(Shell command failed with error)"))
2460 ((equal 0 exit-status)
2461 (message "(Shell command succeeded with %s)"
2462 output))
2463 ((stringp exit-status)
2464 (message "(Shell command killed by signal %s)"
2465 exit-status))
2466 (t
2467 (message "(Shell command failed with code %d and %s)"
2468 exit-status output))))
e1e04350
SM
2469 ;; Don't kill: there might be useful info in the undo-log.
2470 ;; (kill-buffer buffer)
2471 ))))
f69aad2b 2472
cc039f78
KH
2473 (when (and error-file (file-exists-p error-file))
2474 (if (< 0 (nth 7 (file-attributes error-file)))
2475 (with-current-buffer (get-buffer-create error-buffer)
2476 (let ((pos-from-end (- (point-max) (point))))
2477 (or (bobp)
2478 (insert "\f\n"))
2479 ;; Do no formatting while reading error file,
2480 ;; because that can run a shell command, and we
2481 ;; don't want that to cause an infinite recursion.
2482 (format-insert-file error-file nil)
2483 ;; Put point after the inserted errors.
2484 (goto-char (- (point-max) pos-from-end)))
63619f42
RS
2485 (and display-error-buffer
2486 (display-buffer (current-buffer)))))
cc039f78 2487 (delete-file error-file))
a0184aeb 2488 exit-status))
1e722f9f 2489
d589bd99
RS
2490(defun shell-command-to-string (command)
2491 "Execute shell command COMMAND and return its output as a string."
2492 (with-output-to-string
17cc9013
RS
2493 (with-current-buffer
2494 standard-output
2495 (call-process shell-file-name nil t nil shell-command-switch command))))
0457dd55
KG
2496
2497(defun process-file (program &optional infile buffer display &rest args)
2498 "Process files synchronously in a separate process.
2499Similar to `call-process', but may invoke a file handler based on
2500`default-directory'. The current working directory of the
2501subprocess is `default-directory'.
2502
2503File names in INFILE and BUFFER are handled normally, but file
2504names in ARGS should be relative to `default-directory', as they
2505are passed to the process verbatim. \(This is a difference to
2506`call-process' which does not support file handlers for INFILE
2507and BUFFER.\)
2508
2509Some file handlers might not support all variants, for example
2510they might behave as if DISPLAY was nil, regardless of the actual
2511value passed."
2512 (let ((fh (find-file-name-handler default-directory 'process-file))
2513 lc stderr-file)
2514 (unwind-protect
2515 (if fh (apply fh 'process-file program infile buffer display args)
8de40f9f 2516 (when infile (setq lc (file-local-copy infile)))
0457dd55 2517 (setq stderr-file (when (and (consp buffer) (stringp (cadr buffer)))
85af630d
KG
2518 (make-temp-file "emacs")))
2519 (prog1
2520 (apply 'call-process program
2521 (or lc infile)
2522 (if stderr-file (list (car buffer) stderr-file) buffer)
2523 display args)
2524 (when stderr-file (copy-file stderr-file (cadr buffer)))))
0457dd55
KG
2525 (when stderr-file (delete-file stderr-file))
2526 (when lc (delete-file lc)))))
2527
2c4f2562
MA
2528(defvar process-file-side-effects t
2529 "Whether a call of `process-file' changes remote files.
2530
2531Per default, this variable is always set to `t', meaning that a
2532call of `process-file' could potentially change any file on a
2533remote host. When set to `nil', a file handler could optimize
2534its behaviour with respect to remote file attributes caching.
2535
2536This variable should never be changed by `setq'. Instead of, it
2537shall be set only by let-binding.")
2538
7cb76caa
MA
2539(defun start-file-process (name buffer program &rest program-args)
2540 "Start a program in a subprocess. Return the process object for it.
5a5abb2c 2541
7cb76caa 2542Similar to `start-process', but may invoke a file handler based on
5a5abb2c
MA
2543`default-directory'. See Info node `(elisp)Magic File Names'.
2544
2545This handler ought to run PROGRAM, perhaps on the local host,
2546perhaps on a remote host that corresponds to `default-directory'.
2547In the latter case, the local part of `default-directory' becomes
2548the working directory of the process.
7cb76caa
MA
2549
2550PROGRAM and PROGRAM-ARGS might be file names. They are not
91f11424
MA
2551objects of file handler invocation. File handlers might not
2552support pty association, if PROGRAM is nil."
7cb76caa
MA
2553 (let ((fh (find-file-name-handler default-directory 'start-file-process)))
2554 (if fh (apply fh 'start-file-process name buffer program program-args)
2555 (apply 'start-process name buffer program program-args))))
2556
2d88b556 2557\f
1b43f83f 2558(defvar universal-argument-map
69d4c3c4
KH
2559 (let ((map (make-sparse-keymap)))
2560 (define-key map [t] 'universal-argument-other-key)
b9ff190d 2561 (define-key map (vector meta-prefix-char t) 'universal-argument-other-key)
69d4c3c4
KH
2562 (define-key map [switch-frame] nil)
2563 (define-key map [?\C-u] 'universal-argument-more)
2564 (define-key map [?-] 'universal-argument-minus)
2565 (define-key map [?0] 'digit-argument)
2566 (define-key map [?1] 'digit-argument)
2567 (define-key map [?2] 'digit-argument)
2568 (define-key map [?3] 'digit-argument)
2569 (define-key map [?4] 'digit-argument)
2570 (define-key map [?5] 'digit-argument)
2571 (define-key map [?6] 'digit-argument)
2572 (define-key map [?7] 'digit-argument)
2573 (define-key map [?8] 'digit-argument)
2574 (define-key map [?9] 'digit-argument)
bd7acc8d
GM
2575 (define-key map [kp-0] 'digit-argument)
2576 (define-key map [kp-1] 'digit-argument)
2577 (define-key map [kp-2] 'digit-argument)
2578 (define-key map [kp-3] 'digit-argument)
2579 (define-key map [kp-4] 'digit-argument)
2580 (define-key map [kp-5] 'digit-argument)
2581 (define-key map [kp-6] 'digit-argument)
2582 (define-key map [kp-7] 'digit-argument)
2583 (define-key map [kp-8] 'digit-argument)
2584 (define-key map [kp-9] 'digit-argument)
2585 (define-key map [kp-subtract] 'universal-argument-minus)
69d4c3c4
KH
2586 map)
2587 "Keymap used while processing \\[universal-argument].")
2588
0de84e16
RS
2589(defvar universal-argument-num-events nil
2590 "Number of argument-specifying events read by `universal-argument'.
2591`universal-argument-other-key' uses this to discard those events
2592from (this-command-keys), and reread only the final command.")
2593
6b61353c
KH
2594(defvar overriding-map-is-bound nil
2595 "Non-nil when `overriding-terminal-local-map' is `universal-argument-map'.")
2596
2597(defvar saved-overriding-map nil
2598 "The saved value of `overriding-terminal-local-map'.
2599That variable gets restored to this value on exiting \"universal
2600argument mode\".")
2601
2602(defun ensure-overriding-map-is-bound ()
2603 "Check `overriding-terminal-local-map' is `universal-argument-map'."
2604 (unless overriding-map-is-bound
2605 (setq saved-overriding-map overriding-terminal-local-map)
2606 (setq overriding-terminal-local-map universal-argument-map)
2607 (setq overriding-map-is-bound t)))
2608
2609(defun restore-overriding-map ()
2610 "Restore `overriding-terminal-local-map' to its saved value."
2611 (setq overriding-terminal-local-map saved-overriding-map)
2612 (setq overriding-map-is-bound nil))
2613
e8d1a377
KH
2614(defun universal-argument ()
2615 "Begin a numeric argument for the following command.
2616Digits or minus sign following \\[universal-argument] make up the numeric argument.
2617\\[universal-argument] following the digits or minus sign ends the argument.
2618\\[universal-argument] without digits or minus sign provides 4 as argument.
2619Repeating \\[universal-argument] without digits or minus sign
0565d307
RS
2620 multiplies the argument by 4 each time.
2621For some commands, just \\[universal-argument] by itself serves as a flag
a697fc62
RS
2622which is different in effect from any particular numeric argument.
2623These commands include \\[set-mark-command] and \\[start-kbd-macro]."
69d4c3c4
KH
2624 (interactive)
2625 (setq prefix-arg (list 4))
0de84e16 2626 (setq universal-argument-num-events (length (this-command-keys)))
6b61353c 2627 (ensure-overriding-map-is-bound))
e8d1a377 2628
69d4c3c4
KH
2629;; A subsequent C-u means to multiply the factor by 4 if we've typed
2630;; nothing but C-u's; otherwise it means to terminate the prefix arg.
2631(defun universal-argument-more (arg)
e8d1a377 2632 (interactive "P")
69d4c3c4
KH
2633 (if (consp arg)
2634 (setq prefix-arg (list (* 4 (car arg))))
1cd24721
RS
2635 (if (eq arg '-)
2636 (setq prefix-arg (list -4))
2637 (setq prefix-arg arg)
6b61353c 2638 (restore-overriding-map)))
0de84e16 2639 (setq universal-argument-num-events (length (this-command-keys))))
e8d1a377
KH
2640
2641(defun negative-argument (arg)
2642 "Begin a negative numeric argument for the next command.
2643\\[universal-argument] following digits or minus sign ends the argument."
2644 (interactive "P")
69d4c3c4
KH
2645 (cond ((integerp arg)
2646 (setq prefix-arg (- arg)))
2647 ((eq arg '-)
2648 (setq prefix-arg nil))
2649 (t
b9ff190d 2650 (setq prefix-arg '-)))
0de84e16 2651 (setq universal-argument-num-events (length (this-command-keys)))
6b61353c 2652 (ensure-overriding-map-is-bound))
69d4c3c4
KH
2653
2654(defun digit-argument (arg)
2655 "Part of the numeric argument for the next command.
2656\\[universal-argument] following digits or minus sign ends the argument."
2657 (interactive "P")
8989a920
GM
2658 (let* ((char (if (integerp last-command-event)
2659 last-command-event
2660 (get last-command-event 'ascii-character)))
bd7acc8d 2661 (digit (- (logand char ?\177) ?0)))
69d4c3c4
KH
2662 (cond ((integerp arg)
2663 (setq prefix-arg (+ (* arg 10)
2664 (if (< arg 0) (- digit) digit))))
2665 ((eq arg '-)
2666 ;; Treat -0 as just -, so that -01 will work.
2667 (setq prefix-arg (if (zerop digit) '- (- digit))))
2668 (t
b9ff190d 2669 (setq prefix-arg digit))))
0de84e16 2670 (setq universal-argument-num-events (length (this-command-keys)))
6b61353c 2671 (ensure-overriding-map-is-bound))
69d4c3c4
KH
2672
2673;; For backward compatibility, minus with no modifiers is an ordinary
2674;; command if digits have already been entered.
2675(defun universal-argument-minus (arg)
2676 (interactive "P")
2677 (if (integerp arg)
2678 (universal-argument-other-key arg)
2679 (negative-argument arg)))
2680
2681;; Anything else terminates the argument and is left in the queue to be
2682;; executed as a command.
2683(defun universal-argument-other-key (arg)
2684 (interactive "P")
2685 (setq prefix-arg arg)
0de84e16
RS
2686 (let* ((key (this-command-keys))
2687 (keylist (listify-key-sequence key)))
2688 (setq unread-command-events
06697cdb
RS
2689 (append (nthcdr universal-argument-num-events keylist)
2690 unread-command-events)))
f0ef2555 2691 (reset-this-command-lengths)
6b61353c 2692 (restore-overriding-map))
2d88b556 2693\f
7fcce20f
RS
2694(defvar buffer-substring-filters nil
2695 "List of filter functions for `filter-buffer-substring'.
2696Each function must accept a single argument, a string, and return
2697a string. The buffer substring is passed to the first function
2698in the list, and the return value of each function is passed to
2699the next. The return value of the last function is used as the
2700return value of `filter-buffer-substring'.
2701
2702If this variable is nil, no filtering is performed.")
2703
398c9ffb 2704(defun filter-buffer-substring (beg end &optional delete noprops)
7fcce20f
RS
2705 "Return the buffer substring between BEG and END, after filtering.
2706The buffer substring is passed through each of the filter
2707functions in `buffer-substring-filters', and the value from the
2708last filter function is returned. If `buffer-substring-filters'
2709is nil, the buffer substring is returned unaltered.
2710
2711If DELETE is non-nil, the text between BEG and END is deleted
2712from the buffer.
2713
398c9ffb
KS
2714If NOPROPS is non-nil, final string returned does not include
2715text properties, while the string passed to the filters still
2716includes text properties from the buffer text.
2717
2cd16d74 2718Point is temporarily set to BEG before calling
7fcce20f
RS
2719`buffer-substring-filters', in case the functions need to know
2720where the text came from.
2721
398c9ffb
KS
2722This function should be used instead of `buffer-substring',
2723`buffer-substring-no-properties', or `delete-and-extract-region'
2724when you want to allow filtering to take place. For example,
2725major or minor modes can use `buffer-substring-filters' to
2726extract characters that are special to a buffer, and should not
2727be copied into other buffers."
2728 (cond
2729 ((or delete buffer-substring-filters)
2730 (save-excursion
2731 (goto-char beg)
2732 (let ((string (if delete (delete-and-extract-region beg end)
2733 (buffer-substring beg end))))
2734 (dolist (filter buffer-substring-filters)
2735 (setq string (funcall filter string)))
2736 (if noprops
2737 (set-text-properties 0 (length string) nil string))
2738 string)))
2739 (noprops
2740 (buffer-substring-no-properties beg end))
2741 (t
2742 (buffer-substring beg end))))
2743
7fcce20f 2744
93be67de 2745;;;; Window system cut and paste hooks.
70e14c01
JB
2746
2747(defvar interprogram-cut-function nil
2748 "Function to call to make a killed region available to other programs.
2749
2750Most window systems provide some sort of facility for cutting and
9f112a3d
RS
2751pasting text between the windows of different programs.
2752This variable holds a function that Emacs calls whenever text
2753is put in the kill ring, to make the new kill available to other
70e14c01
JB
2754programs.
2755
9f112a3d
RS
2756The function takes one or two arguments.
2757The first argument, TEXT, is a string containing
2758the text which should be made available.
6b61353c
KH
2759The second, optional, argument PUSH, has the same meaning as the
2760similar argument to `x-set-cut-buffer', which see.")
70e14c01
JB
2761
2762(defvar interprogram-paste-function nil
2763 "Function to call to get text cut from other programs.
2764
2765Most window systems provide some sort of facility for cutting and
9f112a3d
RS
2766pasting text between the windows of different programs.
2767This variable holds a function that Emacs calls to obtain
70e14c01
JB
2768text that other programs have provided for pasting.
2769
2770The function should be called with no arguments. If the function
2771returns nil, then no other program has provided such text, and the top
2772of the Emacs kill ring should be used. If the function returns a
6b61353c
KH
2773string, then the caller of the function \(usually `current-kill')
2774should put this string in the kill ring as the latest kill.
daa37602 2775
d4cb4833 2776This function may also return a list of strings if the window
1d2b0303 2777system supports multiple selections. The first string will be
d4cb4833
GM
2778used as the pasted text, but the other will be placed in the
2779kill ring for easy access via `yank-pop'.
2780
daa37602
JB
2781Note that the function should return a string only if a program other
2782than Emacs has provided a string for pasting; if Emacs provided the
2783most recent string, the function should return nil. If it is
2784difficult to tell whether Emacs or some other program provided the
2785current string, it is probably good enough to return nil if the string
2786is equal (according to `string=') to the last text Emacs provided.")
2d88b556 2787\f
70e14c01 2788
eaae8106 2789
70e14c01 2790;;;; The kill ring data structure.
2076c87c
JB
2791
2792(defvar kill-ring nil
70e14c01
JB
2793 "List of killed text sequences.
2794Since the kill ring is supposed to interact nicely with cut-and-paste
2795facilities offered by window systems, use of this variable should
2796interact nicely with `interprogram-cut-function' and
2797`interprogram-paste-function'. The functions `kill-new',
2798`kill-append', and `current-kill' are supposed to implement this
2799interaction; you may want to use them instead of manipulating the kill
2800ring directly.")
2076c87c 2801
bffa4d92 2802(defcustom kill-ring-max 60
1d2b0303 2803 "Maximum length of kill ring before oldest elements are thrown away."
69c1dd37
RS
2804 :type 'integer
2805 :group 'killing)
2076c87c
JB
2806
2807(defvar kill-ring-yank-pointer nil
2808 "The tail of the kill ring whose car is the last thing yanked.")
2809
4ed8c7aa 2810(defcustom save-interprogram-paste-before-kill nil
e8ab3908 2811 "Save clipboard strings into kill ring before replacing them.
4ed8c7aa
SS
2812When one selects something in another program to paste it into Emacs,
2813but kills something in Emacs before actually pasting it,
2814this selection is gone unless this variable is non-nil,
2815in which case the other program's selection is saved in the `kill-ring'
2816before the Emacs kill and one can still paste it using \\[yank] \\[yank-pop]."
2817 :type 'boolean
2818 :group 'killing
2819 :version "23.2")
2820
ba83a64e
SS
2821(defcustom kill-do-not-save-duplicates nil
2822 "Do not add a new string to `kill-ring' when it is the same as the last one."
2823 :type 'boolean
2824 :group 'killing
2825 :version "23.2")
2826
be5936a7 2827(defun kill-new (string &optional replace yank-handler)
70e14c01 2828 "Make STRING the latest kill in the kill ring.
3e505153 2829Set `kill-ring-yank-pointer' to point to it.
f914dc91
KH
2830If `interprogram-cut-function' is non-nil, apply it to STRING.
2831Optional second argument REPLACE non-nil means that STRING will replace
be5936a7
KS
2832the front of the kill ring, rather than being added to the list.
2833
4ed8c7aa
SS
2834When `save-interprogram-paste-before-kill' and `interprogram-paste-function'
2835are non-nil, saves the interprogram paste string(s) into `kill-ring' before
2836STRING.
2837
2a262563
KS
2838When the yank handler has a non-nil PARAM element, the original STRING
2839argument is not used by `insert-for-yank'. However, since Lisp code
f33321ad 2840may access and use elements from the kill ring directly, the STRING
2a262563
KS
2841argument should still be a \"useful\" string for such uses."
2842 (if (> (length string) 0)
f1180544 2843 (if yank-handler
6b61353c
KH
2844 (put-text-property 0 (length string)
2845 'yank-handler yank-handler string))
2a262563 2846 (if yank-handler
f1180544 2847 (signal 'args-out-of-range
2a262563 2848 (list string "yank-handler specified for empty string"))))
ba83a64e
SS
2849 (when (and kill-do-not-save-duplicates
2850 (equal string (car kill-ring)))
2851 (setq replace t))
2a262563
KS
2852 (if (fboundp 'menu-bar-update-yank-menu)
2853 (menu-bar-update-yank-menu string (and replace (car kill-ring))))
4ed8c7aa
SS
2854 (when save-interprogram-paste-before-kill
2855 (let ((interprogram-paste (and interprogram-paste-function
2856 (funcall interprogram-paste-function))))
2857 (when interprogram-paste
2858 (if (listp interprogram-paste)
2859 (dolist (s (nreverse interprogram-paste))
2860 (push s kill-ring))
2861 (push interprogram-paste kill-ring)))))
ab7e20d5 2862 (if (and replace kill-ring)
f914dc91 2863 (setcar kill-ring string)
1b5fd09e 2864 (push string kill-ring)
f914dc91
KH
2865 (if (> (length kill-ring) kill-ring-max)
2866 (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
70e14c01
JB
2867 (setq kill-ring-yank-pointer kill-ring)
2868 (if interprogram-cut-function
657a33ab 2869 (funcall interprogram-cut-function string (not replace))))
9fca7811
SM
2870(set-advertised-calling-convention
2871 'kill-new '(string &optional replace) "23.3")
70e14c01 2872
be5936a7 2873(defun kill-append (string before-p &optional yank-handler)
70e14c01
JB
2874 "Append STRING to the end of the latest kill in the kill ring.
2875If BEFORE-P is non-nil, prepend STRING to the kill.
be5936a7
KS
2876If `interprogram-cut-function' is set, pass the resulting kill to it."
2877 (let* ((cur (car kill-ring)))
2878 (kill-new (if before-p (concat string cur) (concat cur string))
2879 (or (= (length cur) 0)
2880 (equal yank-handler (get-text-property 0 'yank-handler cur)))
2881 yank-handler)))
9fca7811 2882(set-advertised-calling-convention 'kill-append '(string before-p) "23.3")
70e14c01 2883
4496b02b
RS
2884(defcustom yank-pop-change-selection nil
2885 "If non-nil, rotating the kill ring changes the window system selection."
2886 :type 'boolean
2887 :group 'killing
2888 :version "23.1")
2889
70e14c01
JB
2890(defun current-kill (n &optional do-not-move)
2891 "Rotate the yanking point by N places, and then return that kill.
1d2b0303
JB
2892If N is zero, `interprogram-paste-function' is set, and calling
2893it returns a string or list of strings, then that string (or
2894list) is added to the front of the kill ring and the string (or
2895first string in the list) is returned as the latest kill.
4496b02b
RS
2896
2897If N is not zero, and if `yank-pop-change-selection' is
2898non-nil, use `interprogram-cut-function' to transfer the
2899kill at the new yank point into the window system selection.
2900
2901If optional arg DO-NOT-MOVE is non-nil, then don't actually
2902move the yanking point; just return the Nth kill forward."
2903
70e14c01
JB
2904 (let ((interprogram-paste (and (= n 0)
2905 interprogram-paste-function
2906 (funcall interprogram-paste-function))))
2907 (if interprogram-paste
2908 (progn
2909 ;; Disable the interprogram cut function when we add the new
2910 ;; text to the kill ring, so Emacs doesn't try to own the
2911 ;; selection, with identical text.
2912 (let ((interprogram-cut-function nil))
d4cb4833
GM
2913 (if (listp interprogram-paste)
2914 (mapc 'kill-new (nreverse interprogram-paste))
2915 (kill-new interprogram-paste)))
2916 (car kill-ring))
70e14c01 2917 (or kill-ring (error "Kill ring is empty"))
47096a67
PE
2918 (let ((ARGth-kill-element
2919 (nthcdr (mod (- n (length kill-ring-yank-pointer))
2920 (length kill-ring))
2921 kill-ring)))
4496b02b
RS
2922 (unless do-not-move
2923 (setq kill-ring-yank-pointer ARGth-kill-element)
2924 (when (and yank-pop-change-selection
2925 (> n 0)
2926 interprogram-cut-function)
2927 (funcall interprogram-cut-function (car ARGth-kill-element))))
70e14c01 2928 (car ARGth-kill-element)))))
c88ab9ce 2929
c88ab9ce 2930
eaae8106 2931
70e14c01 2932;;;; Commands for manipulating the kill ring.
c88ab9ce 2933
69c1dd37 2934(defcustom kill-read-only-ok nil
1d2b0303 2935 "Non-nil means don't signal an error for killing read-only text."
69c1dd37
RS
2936 :type 'boolean
2937 :group 'killing)
e6291fe1 2938
3a5da8a8
RS
2939(put 'text-read-only 'error-conditions
2940 '(text-read-only buffer-read-only error))
6d341a2a 2941(put 'text-read-only 'error-message (purecopy "Text is read-only"))
3a5da8a8 2942
be5936a7 2943(defun kill-region (beg end &optional yank-handler)
66e9b2b2
RS
2944 "Kill (\"cut\") text between point and mark.
2945This deletes the text from the buffer and saves it in the kill ring.
2076c87c 2946The command \\[yank] can retrieve it from there.
ba2b460a 2947\(If you want to save the region without killing it, use \\[kill-ring-save].)
81558867
EZ
2948
2949If you want to append the killed region to the last killed text,
2950use \\[append-next-kill] before \\[kill-region].
2951
2aa7a8bf
JB
2952If the buffer is read-only, Emacs will beep and refrain from deleting
2953the text, but put the text in the kill ring anyway. This means that
2954you can use the killing commands to copy text from a read-only buffer.
2076c87c 2955
a4aae1a5
CY
2956Lisp programs should use this function for killing text.
2957 (To delete text, use `delete-region'.)
c15dc81f 2958Supply two arguments, character positions indicating the stretch of text
2076c87c
JB
2959 to be killed.
2960Any command that calls this function is a \"kill command\".
2961If the previous command was also a kill command,
2962the text killed this time appends to the text killed last time
9fca7811 2963to make one entry in the kill ring."
214a3db0
RS
2964 ;; Pass point first, then mark, because the order matters
2965 ;; when calling kill-append.
2966 (interactive (list (point) (mark)))
f39d6be0
RS
2967 (unless (and beg end)
2968 (error "The mark is not set now, so there is no region"))
ccd19b9f 2969 (condition-case nil
7fcce20f 2970 (let ((string (filter-buffer-substring beg end t)))
a1eb02bd
SM
2971 (when string ;STRING is nil if BEG = END
2972 ;; Add that string to the kill ring, one way or another.
2973 (if (eq last-command 'kill-region)
be5936a7
KS
2974 (kill-append string (< end beg) yank-handler)
2975 (kill-new string nil yank-handler)))
8a7cda9b 2976 (when (or string (eq last-command 'kill-region))
6b61353c
KH
2977 (setq this-command 'kill-region))
2978 nil)
ccd19b9f
KH
2979 ((buffer-read-only text-read-only)
2980 ;; The code above failed because the buffer, or some of the characters
2981 ;; in the region, are read-only.
2982 ;; We should beep, in case the user just isn't aware of this.
2983 ;; However, there's no harm in putting
2984 ;; the region's text in the kill ring, anyway.
2985 (copy-region-as-kill beg end)
cb3e1b4c
RS
2986 ;; Set this-command now, so it will be set even if we get an error.
2987 (setq this-command 'kill-region)
2988 ;; This should barf, if appropriate, and give us the correct error.
ccd19b9f 2989 (if kill-read-only-ok
6b61353c 2990 (progn (message "Read only text copied to kill ring") nil)
ccd19b9f
KH
2991 ;; Signal an error if the buffer is read-only.
2992 (barf-if-buffer-read-only)
2993 ;; If the buffer isn't read-only, the text is.
2994 (signal 'text-read-only (list (current-buffer)))))))
9fca7811 2995(set-advertised-calling-convention 'kill-region '(beg end) "23.3")
2076c87c 2996
a382890a
KH
2997;; copy-region-as-kill no longer sets this-command, because it's confusing
2998;; to get two copies of the text when the user accidentally types M-w and
2999;; then corrects it with the intended C-w.
2076c87c
JB
3000(defun copy-region-as-kill (beg end)
3001 "Save the region as if killed, but don't kill it.
0e264847 3002In Transient Mark mode, deactivate the mark.
46947372 3003If `interprogram-cut-function' is non-nil, also save the text for a window
b66eb11b
RS
3004system cut and paste.
3005
3006This command's old key binding has been given to `kill-ring-save'."
2076c87c
JB
3007 (interactive "r")
3008 (if (eq last-command 'kill-region)
7fcce20f
RS
3009 (kill-append (filter-buffer-substring beg end) (< end beg))
3010 (kill-new (filter-buffer-substring beg end)))
d34c311a 3011 (setq deactivate-mark t)
2076c87c
JB
3012 nil)
3013
3014(defun kill-ring-save (beg end)
0964e562 3015 "Save the region as if killed, but don't kill it.
0e264847 3016In Transient Mark mode, deactivate the mark.
0964e562 3017If `interprogram-cut-function' is non-nil, also save the text for a window
0e264847
RS
3018system cut and paste.
3019
81558867
EZ
3020If you want to append the killed line to the last killed text,
3021use \\[append-next-kill] before \\[kill-ring-save].
3022
0e264847
RS
3023This command is similar to `copy-region-as-kill', except that it gives
3024visual feedback indicating the extent of the region being copied."
2076c87c
JB
3025 (interactive "r")
3026 (copy-region-as-kill beg end)
32226619 3027 ;; This use of called-interactively-p is correct
bbf41690 3028 ;; because the code it controls just gives the user visual feedback.
32226619 3029 (if (called-interactively-p 'interactive)
66050f10
RS
3030 (let ((other-end (if (= (point) beg) end beg))
3031 (opoint (point))
3032 ;; Inhibit quitting so we can make a quit here
3033 ;; look like a C-g typed as a command.
3034 (inhibit-quit t))
3035 (if (pos-visible-in-window-p other-end (selected-window))
d34c311a
SM
3036 ;; Swap point-and-mark quickly so as to show the region that
3037 ;; was selected. Don't do it if the region is highlighted.
3038 (unless (and (region-active-p)
977e2654 3039 (face-background 'region))
66050f10
RS
3040 ;; Swap point and mark.
3041 (set-marker (mark-marker) (point) (current-buffer))
3042 (goto-char other-end)
e4ef3e92 3043 (sit-for blink-matching-delay)
66050f10
RS
3044 ;; Swap back.
3045 (set-marker (mark-marker) other-end (current-buffer))
3046 (goto-char opoint)
3047 ;; If user quit, deactivate the mark
3048 ;; as C-g would as a command.
e4e593ae 3049 (and quit-flag mark-active
fcadf1c7 3050 (deactivate-mark)))
66050f10
RS
3051 (let* ((killed-text (current-kill 0))
3052 (message-len (min (length killed-text) 40)))
3053 (if (= (point) beg)
3054 ;; Don't say "killed"; that is misleading.
3055 (message "Saved text until \"%s\""
3056 (substring killed-text (- message-len)))
3057 (message "Saved text from \"%s\""
3058 (substring killed-text 0 message-len))))))))
2076c87c 3059
c75d4986
KH
3060(defun append-next-kill (&optional interactive)
3061 "Cause following command, if it kills, to append to previous kill.
3062The argument is used for internal purposes; do not supply one."
3063 (interactive "p")
3064 ;; We don't use (interactive-p), since that breaks kbd macros.
3065 (if interactive
2076c87c
JB
3066 (progn
3067 (setq this-command 'kill-region)
3068 (message "If the next command is a kill, it will append"))
3069 (setq last-command 'kill-region)))
cfb4f123 3070\f
93be67de 3071;; Yanking.
2076c87c 3072
cfb4f123
RS
3073;; This is actually used in subr.el but defcustom does not work there.
3074(defcustom yank-excluded-properties
be5936a7 3075 '(read-only invisible intangible field mouse-face help-echo local-map keymap
7408ee97 3076 yank-handler follow-link fontified)
3137dda8 3077 "Text properties to discard when yanking.
c6ff5a4c
LT
3078The value should be a list of text properties to discard or t,
3079which means to discard all text properties."
cfb4f123 3080 :type '(choice (const :tag "All" t) (repeat symbol))
c9f0110e 3081 :group 'killing
bf247b6e 3082 :version "22.1")
cfb4f123 3083
120de5bd 3084(defvar yank-window-start nil)
be5936a7 3085(defvar yank-undo-function nil
44f5a7b2
KS
3086 "If non-nil, function used by `yank-pop' to delete last stretch of yanked text.
3087Function is called with two parameters, START and END corresponding to
3088the value of the mark and point; it is guaranteed that START <= END.
3089Normally set from the UNDO element of a yank-handler; see `insert-for-yank'.")
120de5bd 3090
6b61353c 3091(defun yank-pop (&optional arg)
ff1fbe3e
RS
3092 "Replace just-yanked stretch of killed text with a different stretch.
3093This command is allowed only immediately after a `yank' or a `yank-pop'.
2076c87c 3094At such a time, the region contains a stretch of reinserted
ff1fbe3e 3095previously-killed text. `yank-pop' deletes that text and inserts in its
2076c87c
JB
3096place a different stretch of killed text.
3097
3098With no argument, the previous kill is inserted.
ff1fbe3e
RS
3099With argument N, insert the Nth previous kill.
3100If N is negative, this is a more recent kill.
2076c87c
JB
3101
3102The sequence of kills wraps around, so that after the oldest one
a0e8eaa3
EZ
3103comes the newest one.
3104
3105When this command inserts killed text into the buffer, it honors
3106`yank-excluded-properties' and `yank-handler' as described in the
3107doc string for `insert-for-yank-1', which see."
2076c87c
JB
3108 (interactive "*p")
3109 (if (not (eq last-command 'yank))
3110 (error "Previous command was not a yank"))
3111 (setq this-command 'yank)
6b61353c 3112 (unless arg (setq arg 1))
3a5da8a8
RS
3113 (let ((inhibit-read-only t)
3114 (before (< (point) (mark t))))
8254897f
KS
3115 (if before
3116 (funcall (or yank-undo-function 'delete-region) (point) (mark t))
3117 (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
be5936a7 3118 (setq yank-undo-function nil)
fd0f4056 3119 (set-marker (mark-marker) (point) (current-buffer))
cfb4f123 3120 (insert-for-yank (current-kill arg))
120de5bd
RS
3121 ;; Set the window start back where it was in the yank command,
3122 ;; if possible.
3123 (set-window-start (selected-window) yank-window-start t)
fd0f4056
RS
3124 (if before
3125 ;; This is like exchange-point-and-mark, but doesn't activate the mark.
3126 ;; It is cleaner to avoid activation, even though the command
3127 ;; loop would deactivate the mark because we inserted text.
3128 (goto-char (prog1 (mark t)
3129 (set-marker (mark-marker) (point) (current-buffer))))))
0964e562 3130 nil)
2076c87c
JB
3131
3132(defun yank (&optional arg)
f894e671 3133 "Reinsert (\"paste\") the last stretch of killed text.
2076c87c 3134More precisely, reinsert the stretch of killed text most recently
ff1fbe3e 3135killed OR yanked. Put point at end, and set mark at beginning.
d99f8496 3136With just \\[universal-argument] as argument, same but put point at beginning (and mark at end).
ff1fbe3e 3137With argument N, reinsert the Nth most recently killed stretch of killed
2076c87c 3138text.
a0e8eaa3
EZ
3139
3140When this command inserts killed text into the buffer, it honors
3141`yank-excluded-properties' and `yank-handler' as described in the
3142doc string for `insert-for-yank-1', which see.
3143
a9b9303c 3144See also the command `yank-pop' (\\[yank-pop])."
2076c87c 3145 (interactive "*P")
120de5bd 3146 (setq yank-window-start (window-start))
456c617c
RS
3147 ;; If we don't get all the way thru, make last-command indicate that
3148 ;; for the following command.
3149 (setq this-command t)
2076c87c 3150 (push-mark (point))
cfb4f123
RS
3151 (insert-for-yank (current-kill (cond
3152 ((listp arg) 0)
6b61353c 3153 ((eq arg '-) -2)
cfb4f123 3154 (t (1- arg)))))
2076c87c 3155 (if (consp arg)
fd0f4056
RS
3156 ;; This is like exchange-point-and-mark, but doesn't activate the mark.
3157 ;; It is cleaner to avoid activation, even though the command
3158 ;; loop would deactivate the mark because we inserted text.
3159 (goto-char (prog1 (mark t)
3160 (set-marker (mark-marker) (point) (current-buffer)))))
456c617c 3161 ;; If we do get all the way thru, make this-command indicate that.
be5936a7
KS
3162 (if (eq this-command t)
3163 (setq this-command 'yank))
0964e562 3164 nil)
70e14c01
JB
3165
3166(defun rotate-yank-pointer (arg)
3167 "Rotate the yanking point in the kill ring.
5626c14e 3168With ARG, rotate that many kills forward (or backward, if negative)."
70e14c01
JB
3169 (interactive "p")
3170 (current-kill arg))
2d88b556 3171\f
93be67de
KH
3172;; Some kill commands.
3173
3174;; Internal subroutine of delete-char
3175(defun kill-forward-chars (arg)
3176 (if (listp arg) (setq arg (car arg)))
3177 (if (eq arg '-) (setq arg -1))
673e5169 3178 (kill-region (point) (+ (point) arg)))
93be67de
KH
3179
3180;; Internal subroutine of backward-delete-char
3181(defun kill-backward-chars (arg)
3182 (if (listp arg) (setq arg (car arg)))
3183 (if (eq arg '-) (setq arg -1))
673e5169 3184 (kill-region (point) (- (point) arg)))
93be67de
KH
3185
3186(defcustom backward-delete-char-untabify-method 'untabify
1d2b0303 3187 "The method for untabifying when deleting backward.
1e722f9f
SS
3188Can be `untabify' -- turn a tab to many spaces, then delete one space;
3189 `hungry' -- delete all whitespace, both tabs and spaces;
3190 `all' -- delete all whitespace, including tabs, spaces and newlines;
93be67de 3191 nil -- just delete one character."
1e722f9f 3192 :type '(choice (const untabify) (const hungry) (const all) (const nil))
03167a34 3193 :version "20.3"
93be67de
KH
3194 :group 'killing)
3195
3196(defun backward-delete-char-untabify (arg &optional killp)
3197 "Delete characters backward, changing tabs into spaces.
3198The exact behavior depends on `backward-delete-char-untabify-method'.
3199Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
3200Interactively, ARG is the prefix arg (default 1)
3201and KILLP is t if a prefix arg was specified."
3202 (interactive "*p\nP")
3203 (when (eq backward-delete-char-untabify-method 'untabify)
3204 (let ((count arg))
3205 (save-excursion
3206 (while (and (> count 0) (not (bobp)))
3207 (if (= (preceding-char) ?\t)
3208 (let ((col (current-column)))
3209 (forward-char -1)
3210 (setq col (- col (current-column)))
f33321ad 3211 (insert-char ?\s col)
93be67de
KH
3212 (delete-char 1)))
3213 (forward-char -1)
3214 (setq count (1- count))))))
3215 (delete-backward-char
1e722f9f
SS
3216 (let ((skip (cond ((eq backward-delete-char-untabify-method 'hungry) " \t")
3217 ((eq backward-delete-char-untabify-method 'all)
3218 " \t\n\r"))))
3219 (if skip
3220 (let ((wh (- (point) (save-excursion (skip-chars-backward skip)
93be67de
KH
3221 (point)))))
3222 (+ arg (if (zerop wh) 0 (1- wh))))
1e722f9f 3223 arg))
93be67de
KH
3224 killp))
3225
3226(defun zap-to-char (arg char)
5626c14e 3227 "Kill up to and including ARGth occurrence of CHAR.
93be67de
KH
3228Case is ignored if `case-fold-search' is non-nil in the current buffer.
3229Goes backward if ARG is negative; error if CHAR not found."
e761e42c 3230 (interactive "p\ncZap to char: ")
a6c39c14
EZ
3231 ;; Avoid "obsolete" warnings for translation-table-for-input.
3232 (with-no-warnings
3233 (if (char-table-p translation-table-for-input)
3234 (setq char (or (aref translation-table-for-input char) char))))
93be67de
KH
3235 (kill-region (point) (progn
3236 (search-forward (char-to-string char) nil nil arg)
3237; (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
3238 (point))))
eaae8106 3239
93be67de
KH
3240;; kill-line and its subroutines.
3241
3242(defcustom kill-whole-line nil
1d2b0303 3243 "If non-nil, `kill-line' with no arg at beg of line kills the whole line."
93be67de
KH
3244 :type 'boolean
3245 :group 'killing)
3246
3247(defun kill-line (&optional arg)
3248 "Kill the rest of the current line; if no nonblanks there, kill thru newline.
5626c14e 3249With prefix argument ARG, kill that many lines from point.
93be67de 3250Negative arguments kill lines backward.
8be7408c 3251With zero argument, kills the text before point on the current line.
93be67de
KH
3252
3253When calling from a program, nil means \"no arg\",
3254a number counts as a prefix arg.
3255
3256To kill a whole line, when point is not at the beginning, type \
602157ab 3257\\[move-beginning-of-line] \\[kill-line] \\[kill-line].
93be67de
KH
3258
3259If `kill-whole-line' is non-nil, then this command kills the whole line
3260including its terminating newline, when used at the beginning of a line
3261with no argument. As a consequence, you can always kill a whole line
602157ab 3262by typing \\[move-beginning-of-line] \\[kill-line].
d3f22784 3263
81558867
EZ
3264If you want to append the killed line to the last killed text,
3265use \\[append-next-kill] before \\[kill-line].
3266
d3f22784
EZ
3267If the buffer is read-only, Emacs will beep and refrain from deleting
3268the line, but put the line in the kill ring anyway. This means that
1a534b89
RS
3269you can use this command to copy text from a read-only buffer.
3270\(If the variable `kill-read-only-ok' is non-nil, then this won't
3271even beep.)"
e761e42c 3272 (interactive "P")
93be67de
KH
3273 (kill-region (point)
3274 ;; It is better to move point to the other end of the kill
3275 ;; before killing. That way, in a read-only buffer, point
3276 ;; moves across the text that is copied to the kill ring.
3277 ;; The choice has no effect on undo now that undo records
3278 ;; the value of point from before the command was run.
3279 (progn
3280 (if arg
3281 (forward-visible-line (prefix-numeric-value arg))
3282 (if (eobp)
3283 (signal 'end-of-buffer nil))
5560dc5d
RS
3284 (let ((end
3285 (save-excursion
3286 (end-of-visible-line) (point))))
3287 (if (or (save-excursion
6b61353c
KH
3288 ;; If trailing whitespace is visible,
3289 ;; don't treat it as nothing.
3290 (unless show-trailing-whitespace
3291 (skip-chars-forward " \t" end))
5560dc5d
RS
3292 (= (point) end))
3293 (and kill-whole-line (bolp)))
3294 (forward-visible-line 1)
3295 (goto-char end))))
93be67de
KH
3296 (point))))
3297
348de80b
KG
3298(defun kill-whole-line (&optional arg)
3299 "Kill current line.
5626c14e
JB
3300With prefix ARG, kill that many lines starting from the current line.
3301If ARG is negative, kill backward. Also kill the preceding newline.
01ba9662 3302\(This is meant to make \\[repeat] work well with negative arguments.\)
5626c14e 3303If ARG is zero, kill current line but exclude the trailing newline."
f8b0f284 3304 (interactive "p")
186133b4 3305 (or arg (setq arg 1))
6c770e38
LT
3306 (if (and (> arg 0) (eobp) (save-excursion (forward-visible-line 0) (eobp)))
3307 (signal 'end-of-buffer nil))
3308 (if (and (< arg 0) (bobp) (save-excursion (end-of-visible-line) (bobp)))
3309 (signal 'beginning-of-buffer nil))
3310 (unless (eq last-command 'kill-region)
3311 (kill-new "")
3312 (setq last-command 'kill-region))
348de80b 3313 (cond ((zerop arg)
6c770e38
LT
3314 ;; We need to kill in two steps, because the previous command
3315 ;; could have been a kill command, in which case the text
3316 ;; before point needs to be prepended to the current kill
3317 ;; ring entry and the text after point appended. Also, we
3318 ;; need to use save-excursion to avoid copying the same text
3319 ;; twice to the kill ring in read-only buffers.
3320 (save-excursion
3321 (kill-region (point) (progn (forward-visible-line 0) (point))))
348de80b
KG
3322 (kill-region (point) (progn (end-of-visible-line) (point))))
3323 ((< arg 0)
6c770e38
LT
3324 (save-excursion
3325 (kill-region (point) (progn (end-of-visible-line) (point))))
3326 (kill-region (point)
3327 (progn (forward-visible-line (1+ arg))
3328 (unless (bobp) (backward-char))
3329 (point))))
348de80b 3330 (t
6c770e38
LT
3331 (save-excursion
3332 (kill-region (point) (progn (forward-visible-line 0) (point))))
3333 (kill-region (point)
3334 (progn (forward-visible-line arg) (point))))))
12a93712 3335
93be67de
KH
3336(defun forward-visible-line (arg)
3337 "Move forward by ARG lines, ignoring currently invisible newlines only.
3338If ARG is negative, move backward -ARG lines.
3339If ARG is zero, move to the beginning of the current line."
3340 (condition-case nil
3341 (if (> arg 0)
12a93712
RS
3342 (progn
3343 (while (> arg 0)
93be67de 3344 (or (zerop (forward-line 1))
12a93712
RS
3345 (signal 'end-of-buffer nil))
3346 ;; If the newline we just skipped is invisible,
3347 ;; don't count it.
3348 (let ((prop
3349 (get-char-property (1- (point)) 'invisible)))
3350 (if (if (eq buffer-invisibility-spec t)
3351 prop
3352 (or (memq prop buffer-invisibility-spec)
3353 (assq prop buffer-invisibility-spec)))
3354 (setq arg (1+ arg))))
3355 (setq arg (1- arg)))
3356 ;; If invisible text follows, and it is a number of complete lines,
3357 ;; skip it.
3358 (let ((opoint (point)))
3359 (while (and (not (eobp))
3360 (let ((prop
3361 (get-char-property (point) 'invisible)))
3362 (if (eq buffer-invisibility-spec t)
3363 prop
3364 (or (memq prop buffer-invisibility-spec)
3365 (assq prop buffer-invisibility-spec)))))
3366 (goto-char
3367 (if (get-text-property (point) 'invisible)
3368 (or (next-single-property-change (point) 'invisible)
3369 (point-max))
3370 (next-overlay-change (point)))))
3371 (unless (bolp)
3372 (goto-char opoint))))
93be67de 3373 (let ((first t))
f5fd8833
JB
3374 (while (or first (<= arg 0))
3375 (if first
93be67de
KH
3376 (beginning-of-line)
3377 (or (zerop (forward-line -1))
3378 (signal 'beginning-of-buffer nil)))
12a93712
RS
3379 ;; If the newline we just moved to is invisible,
3380 ;; don't count it.
3381 (unless (bobp)
3382 (let ((prop
3383 (get-char-property (1- (point)) 'invisible)))
f5fd8833
JB
3384 (unless (if (eq buffer-invisibility-spec t)
3385 prop
3386 (or (memq prop buffer-invisibility-spec)
3387 (assq prop buffer-invisibility-spec)))
3388 (setq arg (1+ arg)))))
3389 (setq first nil))
12a93712
RS
3390 ;; If invisible text follows, and it is a number of complete lines,
3391 ;; skip it.
3392 (let ((opoint (point)))
93be67de
KH
3393 (while (and (not (bobp))
3394 (let ((prop
3395 (get-char-property (1- (point)) 'invisible)))
3396 (if (eq buffer-invisibility-spec t)
3397 prop
3398 (or (memq prop buffer-invisibility-spec)
3399 (assq prop buffer-invisibility-spec)))))
3400 (goto-char
3401 (if (get-text-property (1- (point)) 'invisible)
3402 (or (previous-single-property-change (point) 'invisible)
3403 (point-min))
12a93712
RS
3404 (previous-overlay-change (point)))))
3405 (unless (bolp)
3406 (goto-char opoint)))))
93be67de
KH
3407 ((beginning-of-buffer end-of-buffer)
3408 nil)))
70e14c01 3409
93be67de
KH
3410(defun end-of-visible-line ()
3411 "Move to end of current visible line."
3412 (end-of-line)
3413 ;; If the following character is currently invisible,
3414 ;; skip all characters with that same `invisible' property value,
3415 ;; then find the next newline.
3416 (while (and (not (eobp))
5560dc5d
RS
3417 (save-excursion
3418 (skip-chars-forward "^\n")
3419 (let ((prop
3420 (get-char-property (point) 'invisible)))
3421 (if (eq buffer-invisibility-spec t)
3422 prop
3423 (or (memq prop buffer-invisibility-spec)
3424 (assq prop buffer-invisibility-spec))))))
3425 (skip-chars-forward "^\n")
93be67de
KH
3426 (if (get-text-property (point) 'invisible)
3427 (goto-char (next-single-property-change (point) 'invisible))
3428 (goto-char (next-overlay-change (point))))
3429 (end-of-line)))
2d88b556 3430\f
2076c87c
JB
3431(defun insert-buffer (buffer)
3432 "Insert after point the contents of BUFFER.
3433Puts mark after the inserted text.
6cb6e7a2
GM
3434BUFFER may be a buffer or a buffer name.
3435
3436This function is meant for the user to run interactively.
1e96c007 3437Don't call it from programs: use `insert-buffer-substring' instead!"
c3d4f949 3438 (interactive
a3e7c391
FP
3439 (list
3440 (progn
3441 (barf-if-buffer-read-only)
3442 (read-buffer "Insert buffer: "
3443 (if (eq (selected-window) (next-window (selected-window)))
3444 (other-buffer (current-buffer))
3445 (window-buffer (next-window (selected-window))))
3446 t))))
1e96c007
SM
3447 (push-mark
3448 (save-excursion
3449 (insert-buffer-substring (get-buffer buffer))
3450 (point)))
1537a263 3451 nil)
2076c87c
JB
3452
3453(defun append-to-buffer (buffer start end)
3454 "Append to specified buffer the text of the region.
3455It is inserted into that buffer before its point.
3456
3457When calling from a program, give three arguments:
3458BUFFER (or buffer name), START and END.
3459START and END specify the portion of the current buffer to be copied."
70e14c01 3460 (interactive
5d771766 3461 (list (read-buffer "Append to buffer: " (other-buffer (current-buffer) t))
23efee2c 3462 (region-beginning) (region-end)))
2076c87c 3463 (let ((oldbuf (current-buffer)))
7fdbcd83
SM
3464 (let* ((append-to (get-buffer-create buffer))
3465 (windows (get-buffer-window-list append-to t t))
3466 point)
9d30a9f4
CY
3467 (save-excursion
3468 (with-current-buffer append-to
d0fba174
CY
3469 (setq point (point))
3470 (barf-if-buffer-read-only)
3471 (insert-buffer-substring oldbuf start end)
3472 (dolist (window windows)
3473 (when (= (window-point window) point)
3474 (set-window-point window (point)))))))))
2076c87c
JB
3475
3476(defun prepend-to-buffer (buffer start end)
3477 "Prepend to specified buffer the text of the region.
3478It is inserted into that buffer after its point.
3479
3480When calling from a program, give three arguments:
3481BUFFER (or buffer name), START and END.
3482START and END specify the portion of the current buffer to be copied."
3483 (interactive "BPrepend to buffer: \nr")
3484 (let ((oldbuf (current-buffer)))
7fdbcd83 3485 (with-current-buffer (get-buffer-create buffer)
74399eac 3486 (barf-if-buffer-read-only)
2076c87c
JB
3487 (save-excursion
3488 (insert-buffer-substring oldbuf start end)))))
3489
3490(defun copy-to-buffer (buffer start end)
3491 "Copy to specified buffer the text of the region.
3492It is inserted into that buffer, replacing existing text there.
3493
3494When calling from a program, give three arguments:
3495BUFFER (or buffer name), START and END.
3496START and END specify the portion of the current buffer to be copied."
3497 (interactive "BCopy to buffer: \nr")
3498 (let ((oldbuf (current-buffer)))
1b5fd09e 3499 (with-current-buffer (get-buffer-create buffer)
74399eac 3500 (barf-if-buffer-read-only)
2076c87c
JB
3501 (erase-buffer)
3502 (save-excursion
3503 (insert-buffer-substring oldbuf start end)))))
2d88b556 3504\f
62d1c1fc 3505(put 'mark-inactive 'error-conditions '(mark-inactive error))
8f43cbf3 3506(put 'mark-inactive 'error-message (purecopy "The mark is not active now"))
62d1c1fc 3507
0251bafb
RS
3508(defvar activate-mark-hook nil
3509 "Hook run when the mark becomes active.
3510It is also run at the end of a command, if the mark is active and
6cbb0bb0 3511it is possible that the region may have changed.")
0251bafb
RS
3512
3513(defvar deactivate-mark-hook nil
3514 "Hook run when the mark becomes inactive.")
3515
af39530e 3516(defun mark (&optional force)
f00239cf
RS
3517 "Return this buffer's mark value as integer, or nil if never set.
3518
3519In Transient Mark mode, this function signals an error if
3520the mark is not active. However, if `mark-even-if-inactive' is non-nil,
3521or the argument FORCE is non-nil, it disregards whether the mark
3522is active, and returns an integer or nil in the usual way.
af39530e 3523
2076c87c
JB
3524If you are using this in an editing command, you are most likely making
3525a mistake; see the documentation of `set-mark'."
0e3a7b14 3526 (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)
af39530e 3527 (marker-position (mark-marker))
62d1c1fc 3528 (signal 'mark-inactive nil)))
2076c87c 3529
f9be2e35 3530(defcustom select-active-regions nil
2d34d523 3531 "If non-nil, an active region automatically sets the primary selection."
f9be2e35
CY
3532 :type 'boolean
3533 :group 'killing
3534 :version "23.1")
3535
f6714ede
GM
3536(declare-function x-selection-owner-p "xselect.c" (&optional selection))
3537
19d35374
RM
3538;; Many places set mark-active directly, and several of them failed to also
3539;; run deactivate-mark-hook. This shorthand should simplify.
f9be2e35 3540(defsubst deactivate-mark (&optional force)
19d35374 3541 "Deactivate the mark by setting `mark-active' to nil.
f9be2e35
CY
3542Unless FORCE is non-nil, this function does nothing if Transient
3543Mark mode is disabled.
3544This function also runs `deactivate-mark-hook'."
3545 (when (or transient-mark-mode force)
3546 ;; Copy the latest region into the primary selection, if desired.
3547 (and select-active-regions
3548 mark-active
102e1a41 3549 (display-selections-p)
3f5c9cad 3550 (x-selection-owner-p 'PRIMARY)
f9be2e35
CY
3551 (x-set-selection 'PRIMARY (buffer-substring-no-properties
3552 (region-beginning) (region-end))))
3553 (if (and (null force)
3554 (or (eq transient-mark-mode 'lambda)
3555 (and (eq (car-safe transient-mark-mode) 'only)
3556 (null (cdr transient-mark-mode)))))
3557 ;; When deactivating a temporary region, don't change
3558 ;; `mark-active' or run `deactivate-mark-hook'.
109cfe4e
CY
3559 (setq transient-mark-mode nil)
3560 (if (eq (car-safe transient-mark-mode) 'only)
3561 (setq transient-mark-mode (cdr transient-mark-mode)))
3562 (setq mark-active nil)
3563 (run-hooks 'deactivate-mark-hook))))
19d35374 3564
2977fc37
SM
3565(defun activate-mark ()
3566 "Activate the mark."
3567 (when (mark t)
3568 (setq mark-active t)
3569 (unless transient-mark-mode
f9be2e35 3570 (setq transient-mark-mode 'lambda))
102e1a41
EZ
3571 (when (and select-active-regions
3572 (display-selections-p))
f9be2e35 3573 (x-set-selection 'PRIMARY (current-buffer)))))
98b2fff4 3574
2076c87c
JB
3575(defun set-mark (pos)
3576 "Set this buffer's mark to POS. Don't use this function!
3577That is to say, don't use this function unless you want
3578the user to see that the mark has moved, and you want the previous
3579mark position to be lost.
3580
3581Normally, when a new mark is set, the old one should go on the stack.
f59006cb 3582This is why most applications should use `push-mark', not `set-mark'.
2076c87c 3583
ff1fbe3e 3584Novice Emacs Lisp programmers often try to use the mark for the wrong
2076c87c
JB
3585purposes. The mark saves a location for the user's convenience.
3586Most editing commands should not alter the mark.
3587To remember a location for internal use in the Lisp program,
3588store it in a Lisp variable. Example:
3589
3590 (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
3591
fcadf1c7
RS
3592 (if pos
3593 (progn
3594 (setq mark-active t)
3595 (run-hooks 'activate-mark-hook)
102e1a41
EZ
3596 (when (and select-active-regions
3597 (display-selections-p))
0013b70f 3598 (x-set-selection 'PRIMARY (current-buffer)))
fcadf1c7 3599 (set-marker (mark-marker) pos (current-buffer)))
24c22852 3600 ;; Normally we never clear mark-active except in Transient Mark mode.
f9be2e35
CY
3601 ;; But when we actually clear out the mark value too, we must
3602 ;; clear mark-active in any mode.
3603 (deactivate-mark t)
24c22852 3604 (set-marker (mark-marker) nil)))
2076c87c 3605
d03b9b31 3606(defcustom use-empty-active-region nil
6a9127b6
CY
3607 "Whether \"region-aware\" commands should act on empty regions.
3608If nil, region-aware commands treat empty regions as inactive.
3609If non-nil, region-aware commands treat the region as active as
3610long as the mark is active, even if the region is empty.
3611
58b356e9
CY
3612Region-aware commands are those that act on the region if it is
3613active and Transient Mark mode is enabled, and on the text near
3614point otherwise."
d03b9b31
RS
3615 :type 'boolean
3616 :version "23.1"
3617 :group 'editing-basics)
3618
cb3a9d33 3619(defun use-region-p ()
6a9127b6
CY
3620 "Return t if the region is active and it is appropriate to act on it.
3621This is used by commands that act specially on the region under
16f2e9fc 3622Transient Mark mode.
6a9127b6 3623
c876b263 3624The return value is t if Transient Mark mode is enabled and the
e5b826ae
CY
3625mark is active; furthermore, if `use-empty-active-region' is nil,
3626the region must not be empty. Otherwise, the return value is nil.
16f2e9fc
CY
3627
3628For some commands, it may be appropriate to ignore the value of
3629`use-empty-active-region'; in that case, use `region-active-p'."
d34c311a 3630 (and (region-active-p)
d03b9b31
RS
3631 (or use-empty-active-region (> (region-end) (region-beginning)))))
3632
02d52519 3633(defun region-active-p ()
afa39f21 3634 "Return t if Transient Mark mode is enabled and the mark is active.
6a9127b6 3635
16f2e9fc
CY
3636Some commands act specially on the region when Transient Mark
3637mode is enabled. Usually, such commands should use
3638`use-region-p' instead of this function, because `use-region-p'
3639also checks the value of `use-empty-active-region'."
02d52519
RS
3640 (and transient-mark-mode mark-active))
3641
2076c87c 3642(defvar mark-ring nil
e55e2267 3643 "The list of former marks of the current buffer, most recent first.")
2076c87c 3644(make-variable-buffer-local 'mark-ring)
e55e2267 3645(put 'mark-ring 'permanent-local t)
2076c87c 3646
69c1dd37 3647(defcustom mark-ring-max 16
1d2b0303 3648 "Maximum size of mark ring. Start discarding off end if gets this big."
69c1dd37
RS
3649 :type 'integer
3650 :group 'editing-basics)
2076c87c 3651
dc029f0b
RM
3652(defvar global-mark-ring nil
3653 "The list of saved global marks, most recent first.")
3654
69c1dd37 3655(defcustom global-mark-ring-max 16
1d2b0303 3656 "Maximum size of global mark ring. \
69c1dd37
RS
3657Start discarding off end if gets this big."
3658 :type 'integer
3659 :group 'editing-basics)
dc029f0b 3660
868c2f49 3661(defun pop-to-mark-command ()
5626c14e
JB
3662 "Jump to mark, and pop a new position for mark off the ring.
3663\(Does not affect global mark ring\)."
868c2f49
KS
3664 (interactive)
3665 (if (null (mark t))
3666 (error "No mark set in this buffer")
fb2c06a3
RS
3667 (if (= (point) (mark t))
3668 (message "Mark popped"))
868c2f49
KS
3669 (goto-char (mark t))
3670 (pop-mark)))
3671
d00ffe21 3672(defun push-mark-command (arg &optional nomsg)
868c2f49 3673 "Set mark at where point is.
5626c14e 3674If no prefix ARG and mark is already set there, just activate it.
d00ffe21 3675Display `Mark set' unless the optional second arg NOMSG is non-nil."
868c2f49
KS
3676 (interactive "P")
3677 (let ((mark (marker-position (mark-marker))))
3678 (if (or arg (null mark) (/= mark (point)))
d00ffe21 3679 (push-mark nil nomsg t)
868c2f49 3680 (setq mark-active t)
0251bafb 3681 (run-hooks 'activate-mark-hook)
5cbce271
CY
3682 (and select-active-regions (display-selections-p)
3683 (x-set-selection 'PRIMARY (current-buffer)))
d00ffe21
KS
3684 (unless nomsg
3685 (message "Mark activated")))))
868c2f49 3686
6a936796 3687(defcustom set-mark-command-repeat-pop nil
1d2b0303 3688 "Non-nil means repeating \\[set-mark-command] after popping mark pops it again.
ebd2fc0d
RS
3689That means that C-u \\[set-mark-command] \\[set-mark-command]
3690will pop the mark twice, and
3691C-u \\[set-mark-command] \\[set-mark-command] \\[set-mark-command]
3692will pop the mark three times.
3693
7b17b503 3694A value of nil means \\[set-mark-command]'s behavior does not change
ebd2fc0d 3695after C-u \\[set-mark-command]."
6a936796 3696 :type 'boolean
034ce0ec 3697 :group 'editing-basics)
6a936796 3698
125f7951
SM
3699(defcustom set-mark-default-inactive nil
3700 "If non-nil, setting the mark does not activate it.
3701This causes \\[set-mark-command] and \\[exchange-point-and-mark] to
0fc10137
JL
3702behave the same whether or not `transient-mark-mode' is enabled."
3703 :type 'boolean
3704 :group 'editing-basics
3705 :version "23.1")
125f7951 3706
2076c87c 3707(defun set-mark-command (arg)
fb2c06a3
RS
3708 "Set the mark where point is, or jump to the mark.
3709Setting the mark also alters the region, which is the text
3710between point and mark; this is the closest equivalent in
3711Emacs to what some editors call the \"selection\".
146adea3 3712
fb2c06a3
RS
3713With no prefix argument, set the mark at point, and push the
3714old mark position on local mark ring. Also push the old mark on
3715global mark ring, if the previous mark was set in another buffer.
146adea3 3716
17923ef2
CY
3717When Transient Mark Mode is off, immediately repeating this
3718command activates `transient-mark-mode' temporarily.
66ef2df9 3719
146adea3 3720With prefix argument \(e.g., \\[universal-argument] \\[set-mark-command]\), \
fb2c06a3 3721jump to the mark, and set the mark from
146adea3
EZ
3722position popped off the local mark ring \(this does not affect the global
3723mark ring\). Use \\[pop-global-mark] to jump to a mark popped off the global
66ef2df9 3724mark ring \(see `pop-global-mark'\).
18c5df40 3725
2ef0a47e 3726If `set-mark-command-repeat-pop' is non-nil, repeating
146adea3 3727the \\[set-mark-command] command with no prefix argument pops the next position
2ef0a47e 3728off the local (or global) mark ring and jumps there.
66ef2df9 3729
fb2c06a3
RS
3730With \\[universal-argument] \\[universal-argument] as prefix
3731argument, unconditionally set mark where point is, even if
3732`set-mark-command-repeat-pop' is non-nil.
7cb42362 3733
ff1fbe3e 3734Novice Emacs Lisp programmers often try to use the mark for the wrong
2076c87c
JB
3735purposes. See the documentation of `set-mark' for more information."
3736 (interactive "P")
109cfe4e
CY
3737 (cond ((eq transient-mark-mode 'lambda)
3738 (setq transient-mark-mode nil))
3739 ((eq (car-safe transient-mark-mode) 'only)
3740 (deactivate-mark)))
868c2f49 3741 (cond
18c5df40
KS
3742 ((and (consp arg) (> (prefix-numeric-value arg) 4))
3743 (push-mark-command nil))
868c2f49 3744 ((not (eq this-command 'set-mark-command))
1841f9e3
KS
3745 (if arg
3746 (pop-to-mark-command)
3747 (push-mark-command t)))
6a936796
RS
3748 ((and set-mark-command-repeat-pop
3749 (eq last-command 'pop-to-mark-command))
66ef2df9
KS
3750 (setq this-command 'pop-to-mark-command)
3751 (pop-to-mark-command))
6a936796
RS
3752 ((and set-mark-command-repeat-pop
3753 (eq last-command 'pop-global-mark)
3754 (not arg))
66ef2df9
KS
3755 (setq this-command 'pop-global-mark)
3756 (pop-global-mark))
868c2f49 3757 (arg
1841f9e3 3758 (setq this-command 'pop-to-mark-command)
868c2f49 3759 (pop-to-mark-command))
2977fc37
SM
3760 ((eq last-command 'set-mark-command)
3761 (if (region-active-p)
3762 (progn
3763 (deactivate-mark)
3764 (message "Mark deactivated"))
3765 (activate-mark)
3766 (message "Mark activated")))
868c2f49 3767 (t
125f7951
SM
3768 (push-mark-command nil)
3769 (if set-mark-default-inactive (deactivate-mark)))))
2076c87c 3770
fd0f4056 3771(defun push-mark (&optional location nomsg activate)
2076c87c 3772 "Set mark at LOCATION (point, by default) and push old mark on mark ring.
f1382a3d
RM
3773If the last global mark pushed was not in the current buffer,
3774also push LOCATION on the global mark ring.
fd0f4056 3775Display `Mark set' unless the optional second arg NOMSG is non-nil.
2076c87c 3776
ff1fbe3e 3777Novice Emacs Lisp programmers often try to use the mark for the wrong
9a1277dd
RS
3778purposes. See the documentation of `set-mark' for more information.
3779
de9606f0 3780In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil."
1a0d0b6a 3781 (unless (null (mark t))
2076c87c 3782 (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
1a0d0b6a
JPW
3783 (when (> (length mark-ring) mark-ring-max)
3784 (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
3785 (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil)))
9a1277dd 3786 (set-marker (mark-marker) (or location (point)) (current-buffer))
dc029f0b 3787 ;; Now push the mark on the global mark ring.
f1382a3d 3788 (if (and global-mark-ring
e08d3f7c 3789 (eq (marker-buffer (car global-mark-ring)) (current-buffer)))
f1382a3d
RM
3790 ;; The last global mark pushed was in this same buffer.
3791 ;; Don't push another one.
3792 nil
3793 (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
1a0d0b6a
JPW
3794 (when (> (length global-mark-ring) global-mark-ring-max)
3795 (move-marker (car (nthcdr global-mark-ring-max global-mark-ring)) nil)
3796 (setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil)))
efcf38c7 3797 (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
2076c87c 3798 (message "Mark set"))
8cdc660f
RS
3799 (if (or activate (not transient-mark-mode))
3800 (set-mark (mark t)))
2076c87c
JB
3801 nil)
3802
3803(defun pop-mark ()
3804 "Pop off mark ring into the buffer's actual mark.
3805Does not set point. Does nothing if mark ring is empty."
1a0d0b6a
JPW
3806 (when mark-ring
3807 (setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
3808 (set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))
1a0d0b6a
JPW
3809 (move-marker (car mark-ring) nil)
3810 (if (null (mark t)) (ding))
0137bae6
JL
3811 (setq mark-ring (cdr mark-ring)))
3812 (deactivate-mark))
2076c87c 3813
c613687b
SM
3814(define-obsolete-function-alias
3815 'exchange-dot-and-mark 'exchange-point-and-mark "23.3")
868c2f49 3816(defun exchange-point-and-mark (&optional arg)
af39530e
RS
3817 "Put the mark where point is now, and point where the mark is now.
3818This command works even when the mark is not active,
868c2f49 3819and it reactivates the mark.
109cfe4e 3820
5626c14e 3821If Transient Mark mode is on, a prefix ARG deactivates the mark
109cfe4e 3822if it is active, and otherwise avoids reactivating it. If
5626c14e 3823Transient Mark mode is off, a prefix ARG enables Transient Mark
109cfe4e 3824mode temporarily."
868c2f49 3825 (interactive "P")
109cfe4e
CY
3826 (let ((omark (mark t))
3827 (temp-highlight (eq (car-safe transient-mark-mode) 'only)))
2977fc37
SM
3828 (if (null omark)
3829 (error "No mark set in this buffer"))
109cfe4e 3830 (deactivate-mark)
2977fc37
SM
3831 (set-mark (point))
3832 (goto-char omark)
125f7951 3833 (if set-mark-default-inactive (deactivate-mark))
109cfe4e
CY
3834 (cond (temp-highlight
3835 (setq transient-mark-mode (cons 'only transient-mark-mode)))
3836 ((or (and arg (region-active-p)) ; (xor arg (not (region-active-p)))
3837 (not (or arg (region-active-p))))
3838 (deactivate-mark))
3839 (t (activate-mark)))
2977fc37 3840 nil))
e23c2c21 3841
11ff3b67 3842(defcustom shift-select-mode t
84db11d6
SM
3843 "When non-nil, shifted motion keys activate the mark momentarily.
3844
3845While the mark is activated in this way, any shift-translated point
3846motion key extends the region, and if Transient Mark mode was off, it
3847is temporarily turned on. Furthermore, the mark will be deactivated
3848by any subsequent point motion key that was not shift-translated, or
3849by any action that normally deactivates the mark in Transient Mark mode.
3850
3851See `this-command-keys-shift-translated' for the meaning of
11ff3b67
AS
3852shift-translation."
3853 :type 'boolean
3854 :group 'editing-basics)
84db11d6
SM
3855
3856(defun handle-shift-selection ()
337c561c
CY
3857 "Activate/deactivate mark depending on invocation thru shift translation.
3858This function is called by `call-interactively' when a command
3859with a `^' character in its `interactive' spec is invoked, before
3860running the command itself.
3861
3862If `shift-select-mode' is enabled and the command was invoked
3863through shift translation, set the mark and activate the region
3864temporarily, unless it was already set in this way. See
3865`this-command-keys-shift-translated' for the meaning of shift
3866translation.
3867
3868Otherwise, if the region has been activated temporarily,
3869deactivate it, and restore the variable `transient-mark-mode' to
3870its earlier value."
84db11d6
SM
3871 (cond ((and shift-select-mode this-command-keys-shift-translated)
3872 (unless (and mark-active
3873 (eq (car-safe transient-mark-mode) 'only))
3874 (setq transient-mark-mode
3875 (cons 'only
3876 (unless (eq transient-mark-mode 'lambda)
3877 transient-mark-mode)))
3878 (push-mark nil nil t)))
3879 ((eq (car-safe transient-mark-mode) 'only)
3880 (setq transient-mark-mode (cdr transient-mark-mode))
3881 (deactivate-mark))))
109cfe4e 3882
6710df48 3883(define-minor-mode transient-mark-mode
e23c2c21 3884 "Toggle Transient Mark mode.
1d2b0303 3885With ARG, turn Transient Mark mode on if ARG is positive, off otherwise.
e23c2c21 3886
5dd1220d
RS
3887In Transient Mark mode, when the mark is active, the region is highlighted.
3888Changing the buffer \"deactivates\" the mark.
3889So do certain other operations that set the mark
3890but whose main purpose is something else--for example,
cfa70244
EZ
3891incremental search, \\[beginning-of-buffer], and \\[end-of-buffer].
3892
8e843bc4
EZ
3893You can also deactivate the mark by typing \\[keyboard-quit] or
3894\\[keyboard-escape-quit].
1465c66b 3895
cfa70244
EZ
3896Many commands change their behavior when Transient Mark mode is in effect
3897and the mark is active, by acting on the region instead of their usual
4c5f7215 3898default part of the buffer's text. Examples of such commands include
705a5933
JL
3899\\[comment-dwim], \\[flush-lines], \\[keep-lines], \
3900\\[query-replace], \\[query-replace-regexp], \\[ispell], and \\[undo].
3901Invoke \\[apropos-documentation] and type \"transient\" or
3902\"mark.*active\" at the prompt, to see the documentation of
3903commands which are sensitive to the Transient Mark mode."
43d16385 3904 :global t
715043a5 3905 :init-value (not noninteractive)
adba8116 3906 :initialize 'custom-initialize-delay
a2b84f35 3907 :group 'editing-basics)
dc029f0b 3908
109cfe4e
CY
3909;; The variable transient-mark-mode is ugly: it can take on special
3910;; values. Document these here.
3911(defvar transient-mark-mode t
3912 "*Non-nil if Transient Mark mode is enabled.
3913See the command `transient-mark-mode' for a description of this minor mode.
3914
3915Non-nil also enables highlighting of the region whenever the mark is active.
3916The variable `highlight-nonselected-windows' controls whether to highlight
3917all windows or just the selected window.
3918
e408289f
CY
3919Lisp programs may give this variable certain special values:
3920
3921- A value of `lambda' enables Transient Mark mode temporarily.
3922 It is disabled again after any subsequent action that would
3923 normally deactivate the mark (e.g. buffer modification).
3924
3925- A value of (only . OLDVAL) enables Transient Mark mode
3926 temporarily. After any subsequent point motion command that is
3927 not shift-translated, or any other action that would normally
3928 deactivate the mark (e.g. buffer modification), the value of
3929 `transient-mark-mode' is set to OLDVAL.")
109cfe4e 3930
d0c4882d
RS
3931(defvar widen-automatically t
3932 "Non-nil means it is ok for commands to call `widen' when they want to.
3933Some commands will do this in order to go to positions outside
3934the current accessible part of the buffer.
3935
3936If `widen-automatically' is nil, these commands will do something else
3937as a fallback, and won't change the buffer bounds.")
3938
dc029f0b
RM
3939(defun pop-global-mark ()
3940 "Pop off global mark ring and jump to the top location."
3941 (interactive)
52b6d445
RS
3942 ;; Pop entries which refer to non-existent buffers.
3943 (while (and global-mark-ring (not (marker-buffer (car global-mark-ring))))
3944 (setq global-mark-ring (cdr global-mark-ring)))
dc029f0b
RM
3945 (or global-mark-ring
3946 (error "No global mark set"))
3947 (let* ((marker (car global-mark-ring))
3948 (buffer (marker-buffer marker))
3949 (position (marker-position marker)))
34c31301
RS
3950 (setq global-mark-ring (nconc (cdr global-mark-ring)
3951 (list (car global-mark-ring))))
dc029f0b
RM
3952 (set-buffer buffer)
3953 (or (and (>= position (point-min))
3954 (<= position (point-max)))
d0c4882d 3955 (if widen-automatically
60aee8b2
RS
3956 (widen)
3957 (error "Global mark position is outside accessible part of buffer")))
dc029f0b
RM
3958 (goto-char position)
3959 (switch-to-buffer buffer)))
2d88b556 3960\f
95791033 3961(defcustom next-line-add-newlines nil
1d2b0303 3962 "If non-nil, `next-line' inserts newline to avoid `end of buffer' error."
69c1dd37 3963 :type 'boolean
e1d6e383 3964 :version "21.1"
69c1dd37 3965 :group 'editing-basics)
38ebcf29 3966
295f6616 3967(defun next-line (&optional arg try-vscroll)
2076c87c 3968 "Move cursor vertically down ARG lines.
295f6616 3969Interactively, vscroll tall lines if `auto-window-vscroll' is enabled.
2076c87c
JB
3970If there is no character in the target line exactly under the current column,
3971the cursor is positioned after the character in that line which spans this
3972column, or at the end of the line if it is not long enough.
38ebcf29 3973If there is no line in the buffer after this one, behavior depends on the
1a2c3941
RS
3974value of `next-line-add-newlines'. If non-nil, it inserts a newline character
3975to create a line, and moves the cursor to that line. Otherwise it moves the
e47d38f6 3976cursor to the end of the buffer.
2076c87c 3977
53a22af4
CY
3978If the variable `line-move-visual' is non-nil, this command moves
3979by display lines. Otherwise, it moves by buffer lines, without
3980taking variable-width characters or continued lines into account.
3981
2076c87c 3982The command \\[set-goal-column] can be used to create
85969cb1
RS
3983a semipermanent goal column for this command.
3984Then instead of trying to move exactly vertically (or as close as possible),
3985this command moves to the specified goal column (or as close as possible).
3986The goal column is stored in the variable `goal-column', which is nil
3987when there is no goal column.
2076c87c
JB
3988
3989If you are thinking of using this in a Lisp program, consider
3990using `forward-line' instead. It is usually easier to use
3991and more reliable (no dependence on goal column, etc.)."
109cfe4e 3992 (interactive "^p\np")
6b61353c 3993 (or arg (setq arg 1))
028922cf 3994 (if (and next-line-add-newlines (= arg 1))
207d7545
GM
3995 (if (save-excursion (end-of-line) (eobp))
3996 ;; When adding a newline, don't expand an abbrev.
3997 (let ((abbrev-mode nil))
24886813 3998 (end-of-line)
15575807 3999 (insert (if use-hard-newlines hard-newline "\n")))
295f6616 4000 (line-move arg nil nil try-vscroll))
32226619 4001 (if (called-interactively-p 'interactive)
1a2c3941 4002 (condition-case nil
295f6616 4003 (line-move arg nil nil try-vscroll)
1a2c3941 4004 ((beginning-of-buffer end-of-buffer) (ding)))
295f6616 4005 (line-move arg nil nil try-vscroll)))
2076c87c
JB
4006 nil)
4007
295f6616 4008(defun previous-line (&optional arg try-vscroll)
2076c87c 4009 "Move cursor vertically up ARG lines.
295f6616 4010Interactively, vscroll tall lines if `auto-window-vscroll' is enabled.
2076c87c
JB
4011If there is no character in the target line exactly over the current column,
4012the cursor is positioned after the character in that line which spans this
4013column, or at the end of the line if it is not long enough.
4014
53a22af4
CY
4015If the variable `line-move-visual' is non-nil, this command moves
4016by display lines. Otherwise, it moves by buffer lines, without
4017taking variable-width characters or continued lines into account.
4018
2076c87c 4019The command \\[set-goal-column] can be used to create
85969cb1
RS
4020a semipermanent goal column for this command.
4021Then instead of trying to move exactly vertically (or as close as possible),
4022this command moves to the specified goal column (or as close as possible).
4023The goal column is stored in the variable `goal-column', which is nil
4024when there is no goal column.
2076c87c
JB
4025
4026If you are thinking of using this in a Lisp program, consider using
c2e8a012 4027`forward-line' with a negative argument instead. It is usually easier
2076c87c 4028to use and more reliable (no dependence on goal column, etc.)."
109cfe4e 4029 (interactive "^p\np")
6b61353c 4030 (or arg (setq arg 1))
32226619 4031 (if (called-interactively-p 'interactive)
1a2c3941 4032 (condition-case nil
295f6616 4033 (line-move (- arg) nil nil try-vscroll)
1a2c3941 4034 ((beginning-of-buffer end-of-buffer) (ding)))
295f6616 4035 (line-move (- arg) nil nil try-vscroll))
2076c87c 4036 nil)
eaae8106 4037
69c1dd37 4038(defcustom track-eol nil
1d2b0303 4039 "Non-nil means vertical motion starting at end of line keeps to ends of lines.
2076c87c 4040This means moving to the end of each line moved onto.
4efebb82
CY
4041The beginning of a blank line does not count as the end of a line.
4042This has no effect when `line-move-visual' is non-nil."
69c1dd37
RS
4043 :type 'boolean
4044 :group 'editing-basics)
4045
4046(defcustom goal-column nil
1d2b0303 4047 "Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil."
69c1dd37
RS
4048 :type '(choice integer
4049 (const :tag "None" nil))
4050 :group 'editing-basics)
912c6728 4051(make-variable-buffer-local 'goal-column)
2076c87c
JB
4052
4053(defvar temporary-goal-column 0
4054 "Current goal column for vertical motion.
4efebb82 4055It is the column where point was at the start of the current run
774409a1
CY
4056of vertical motion commands.
4057
4058When moving by visual lines via `line-move-visual', it is a cons
4059cell (COL . HSCROLL), where COL is the x-position, in pixels,
4060divided by the default column width, and HSCROLL is the number of
4061columns by which window is scrolled from left margin.
4062
4063When the `track-eol' feature is doing its job, the value is
4efebb82 4064`most-positive-fixnum'.")
2076c87c 4065
bbf41690 4066(defcustom line-move-ignore-invisible t
1d2b0303 4067 "Non-nil means \\[next-line] and \\[previous-line] ignore invisible lines.
69c1dd37
RS
4068Outline mode sets this."
4069 :type 'boolean
4070 :group 'editing-basics)
098fc1fb 4071
a2cf21a2 4072(defcustom line-move-visual t
4efebb82
CY
4073 "When non-nil, `line-move' moves point by visual lines.
4074This movement is based on where the cursor is displayed on the
4075screen, instead of relying on buffer contents alone. It takes
66e0718b
CY
4076into account variable-width characters and line continuation.
4077If nil, `line-move' moves point by logical lines."
a2cf21a2 4078 :type 'boolean
66e0718b
CY
4079 :group 'editing-basics
4080 :version "23.1")
4efebb82 4081
b704b1f0
KS
4082;; Returns non-nil if partial move was done.
4083(defun line-move-partial (arg noerror to-end)
4084 (if (< arg 0)
4085 ;; Move backward (up).
4086 ;; If already vscrolled, reduce vscroll
4087 (let ((vs (window-vscroll nil t)))
4088 (when (> vs (frame-char-height))
4089 (set-window-vscroll nil (- vs (frame-char-height)) t)))
4090
4091 ;; Move forward (down).
e437f99a
KS
4092 (let* ((lh (window-line-height -1))
4093 (vpos (nth 1 lh))
4094 (ypos (nth 2 lh))
4095 (rbot (nth 3 lh))
3137dda8 4096 py vs)
e437f99a
KS
4097 (when (or (null lh)
4098 (>= rbot (frame-char-height))
4099 (<= ypos (- (frame-char-height))))
4100 (unless lh
0e7a5039
KS
4101 (let ((wend (pos-visible-in-window-p t nil t)))
4102 (setq rbot (nth 3 wend)
4103 vpos (nth 5 wend))))
e437f99a
KS
4104 (cond
4105 ;; If last line of window is fully visible, move forward.
4106 ((or (null rbot) (= rbot 0))
4107 nil)
4108 ;; If cursor is not in the bottom scroll margin, move forward.
4109 ((and (> vpos 0)
95f5a37f
KS
4110 (< (setq py
4111 (or (nth 1 (window-line-height))
4112 (let ((ppos (posn-at-point)))
4113 (cdr (or (posn-actual-col-row ppos)
4114 (posn-col-row ppos))))))
e437f99a
KS
4115 (min (- (window-text-height) scroll-margin 1) (1- vpos))))
4116 nil)
4117 ;; When already vscrolled, we vscroll some more if we can,
4118 ;; or clear vscroll and move forward at end of tall image.
4119 ((> (setq vs (window-vscroll nil t)) 0)
1f10e750
CY
4120
4121 ;; If we are vscrolling an image at the top of the screen,
4122 ;; we could actually advance point if this yields space
4123 ;; below....
4124
e437f99a
KS
4125 (when (> rbot 0)
4126 (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t)))
4127 ;; If cursor just entered the bottom scroll margin, move forward,
4128 ;; but also vscroll one line so redisplay wont recenter.
4129 ((and (> vpos 0)
4130 (= py (min (- (window-text-height) scroll-margin 1)
4131 (1- vpos))))
4132 (set-window-vscroll nil (frame-char-height) t)
4133 (line-move-1 arg noerror to-end)
4134 t)
4135 ;; If there are lines above the last line, scroll-up one line.
4136 ((> vpos 0)
4137 (scroll-up 1)
4138 t)
4139 ;; Finally, start vscroll.
4140 (t
4141 (set-window-vscroll nil (frame-char-height) t)))))))
b704b1f0
KS
4142
4143
03ceda9e
RS
4144;; This is like line-move-1 except that it also performs
4145;; vertical scrolling of tall images if appropriate.
4146;; That is not really a clean thing to do, since it mixes
4147;; scrolling with cursor motion. But so far we don't have
4148;; a cleaner solution to the problem of making C-n do something
4149;; useful given a tall image.
ed02c1db 4150(defun line-move (arg &optional noerror to-end try-vscroll)
b704b1f0
KS
4151 (unless (and auto-window-vscroll try-vscroll
4152 ;; Only vscroll for single line moves
4153 (= (abs arg) 1)
4154 ;; But don't vscroll in a keyboard macro.
4155 (not defining-kbd-macro)
4156 (not executing-kbd-macro)
4157 (line-move-partial arg noerror to-end))
4158 (set-window-vscroll nil 0 t)
4efebb82
CY
4159 (if line-move-visual
4160 (line-move-visual arg noerror)
4161 (line-move-1 arg noerror to-end))))
4162
4163;; Display-based alternative to line-move-1.
4164;; Arg says how many lines to move. The value is t if we can move the
4165;; specified number of lines.
4166(defun line-move-visual (arg &optional noerror)
34be836c 4167 (let ((opoint (point))
774409a1 4168 (hscroll (window-hscroll))
34be836c 4169 target-hscroll)
774409a1
CY
4170 ;; Check if the previous command was a line-motion command, or if
4171 ;; we were called from some other command.
34be836c
CY
4172 (if (and (consp temporary-goal-column)
4173 (memq last-command `(next-line previous-line ,this-command)))
4174 ;; If so, there's no need to reset `temporary-goal-column',
4175 ;; but we may need to hscroll.
4176 (if (or (/= (cdr temporary-goal-column) hscroll)
4177 (> (cdr temporary-goal-column) 0))
4178 (setq target-hscroll (cdr temporary-goal-column)))
4179 ;; Otherwise, we should reset `temporary-goal-column'.
4180 (let ((posn (posn-at-point)))
4181 (cond
4182 ;; Handle the `overflow-newline-into-fringe' case:
4183 ((eq (nth 1 posn) 'right-fringe)
4184 (setq temporary-goal-column (cons (- (window-width) 1) hscroll)))
4185 ((car (posn-x-y posn))
4186 (setq temporary-goal-column
4187 (cons (/ (float (car (posn-x-y posn)))
4188 (frame-char-width)) hscroll))))))
4189 (if target-hscroll
4190 (set-window-hscroll (selected-window) target-hscroll))
624a662f 4191 (or (and (= (vertical-motion
774409a1
CY
4192 (cons (or goal-column
4193 (if (consp temporary-goal-column)
5a66ed0f 4194 (car temporary-goal-column)
774409a1
CY
4195 temporary-goal-column))
4196 arg))
624a662f
CY
4197 arg)
4198 (or (>= arg 0)
4199 (/= (point) opoint)
4200 ;; If the goal column lies on a display string,
4201 ;; `vertical-motion' advances the cursor to the end
4202 ;; of the string. For arg < 0, this can cause the
4203 ;; cursor to get stuck. (Bug#3020).
4204 (= (vertical-motion arg) arg)))
4205 (unless noerror
4206 (signal (if (< arg 0) 'beginning-of-buffer 'end-of-buffer)
4207 nil)))))
16c2f92f 4208
8c745744
RS
4209;; This is the guts of next-line and previous-line.
4210;; Arg says how many lines to move.
bbf41690 4211;; The value is t if we can move the specified number of lines.
16c2f92f 4212(defun line-move-1 (arg &optional noerror to-end)
2596511d
RS
4213 ;; Don't run any point-motion hooks, and disregard intangibility,
4214 ;; for intermediate positions.
4215 (let ((inhibit-point-motion-hooks t)
4216 (opoint (point))
fef11f15 4217 (orig-arg arg))
774409a1
CY
4218 (if (consp temporary-goal-column)
4219 (setq temporary-goal-column (+ (car temporary-goal-column)
4220 (cdr temporary-goal-column))))
2596511d
RS
4221 (unwind-protect
4222 (progn
41d22ee0 4223 (if (not (memq last-command '(next-line previous-line)))
2596511d
RS
4224 (setq temporary-goal-column
4225 (if (and track-eol (eolp)
4226 ;; Don't count beg of empty line as end of line
4227 ;; unless we just did explicit end-of-line.
ab9623c2 4228 (or (not (bolp)) (eq last-command 'move-end-of-line)))
3137dda8 4229 most-positive-fixnum
2596511d 4230 (current-column))))
bbf41690 4231
3137dda8
SM
4232 (if (not (or (integerp selective-display)
4233 line-move-ignore-invisible))
2596511d 4234 ;; Use just newline characters.
e9cd25fe 4235 ;; Set ARG to 0 if we move as many lines as requested.
2596511d
RS
4236 (or (if (> arg 0)
4237 (progn (if (> arg 1) (forward-line (1- arg)))
4238 ;; This way of moving forward ARG lines
4239 ;; verifies that we have a newline after the last one.
4240 ;; It doesn't get confused by intangible text.
4241 (end-of-line)
e9cd25fe
RS
4242 (if (zerop (forward-line 1))
4243 (setq arg 0)))
2596511d 4244 (and (zerop (forward-line arg))
e9cd25fe
RS
4245 (bolp)
4246 (setq arg 0)))
bbf41690
RS
4247 (unless noerror
4248 (signal (if (< arg 0)
4249 'beginning-of-buffer
4250 'end-of-buffer)
4251 nil)))
2596511d 4252 ;; Move by arg lines, but ignore invisible ones.
07889873 4253 (let (done)
bbf41690
RS
4254 (while (and (> arg 0) (not done))
4255 ;; If the following character is currently invisible,
4256 ;; skip all characters with that same `invisible' property value.
c65e6942 4257 (while (and (not (eobp)) (invisible-p (point)))
bbf41690 4258 (goto-char (next-char-property-change (point))))
fef11f15
CY
4259 ;; Move a line.
4260 ;; We don't use `end-of-line', since we want to escape
c0943d3d 4261 ;; from field boundaries occurring exactly at point.
07889873
CY
4262 (goto-char (constrain-to-field
4263 (let ((inhibit-field-text-motion t))
4264 (line-end-position))
4265 (point) t t
4266 'inhibit-line-move-field-capture))
e9ab825f 4267 ;; If there's no invisibility here, move over the newline.
3e43ae87
KS
4268 (cond
4269 ((eobp)
4270 (if (not noerror)
4271 (signal 'end-of-buffer nil)
4272 (setq done t)))
4273 ((and (> arg 1) ;; Use vertical-motion for last move
4274 (not (integerp selective-display))
c65e6942 4275 (not (invisible-p (point))))
3e43ae87
KS
4276 ;; We avoid vertical-motion when possible
4277 ;; because that has to fontify.
4278 (forward-line 1))
4279 ;; Otherwise move a more sophisticated way.
4280 ((zerop (vertical-motion 1))
4281 (if (not noerror)
4282 (signal 'end-of-buffer nil)
4283 (setq done t))))
bbf41690
RS
4284 (unless done
4285 (setq arg (1- arg))))
22c8bff1 4286 ;; The logic of this is the same as the loop above,
e9ab825f 4287 ;; it just goes in the other direction.
bbf41690 4288 (while (and (< arg 0) (not done))
ac6701ea
CY
4289 ;; For completely consistency with the forward-motion
4290 ;; case, we should call beginning-of-line here.
4291 ;; However, if point is inside a field and on a
4292 ;; continued line, the call to (vertical-motion -1)
4293 ;; below won't move us back far enough; then we return
4294 ;; to the same column in line-move-finish, and point
4295 ;; gets stuck -- cyd
4296 (forward-line 0)
3e43ae87
KS
4297 (cond
4298 ((bobp)
4299 (if (not noerror)
4300 (signal 'beginning-of-buffer nil)
4301 (setq done t)))
4302 ((and (< arg -1) ;; Use vertical-motion for last move
4303 (not (integerp selective-display))
c65e6942 4304 (not (invisible-p (1- (point)))))
3e43ae87
KS
4305 (forward-line -1))
4306 ((zerop (vertical-motion -1))
4307 (if (not noerror)
4308 (signal 'beginning-of-buffer nil)
4309 (setq done t))))
bbf41690
RS
4310 (unless done
4311 (setq arg (1+ arg))
4312 (while (and ;; Don't move over previous invis lines
4313 ;; if our target is the middle of this line.
4314 (or (zerop (or goal-column temporary-goal-column))
4315 (< arg 0))
c65e6942 4316 (not (bobp)) (invisible-p (1- (point))))
bbf41690
RS
4317 (goto-char (previous-char-property-change (point))))))))
4318 ;; This is the value the function returns.
4319 (= arg 0))
af894fc9 4320
e9cd25fe 4321 (cond ((> arg 0)
2a1e0c92
CY
4322 ;; If we did not move down as far as desired, at least go
4323 ;; to end of line. Be sure to call point-entered and
4324 ;; point-left-hooks.
4325 (let* ((npoint (prog1 (line-end-position)
4326 (goto-char opoint)))
4327 (inhibit-point-motion-hooks nil))
4328 (goto-char npoint)))
e9cd25fe 4329 ((< arg 0)
f9872a6b
JL
4330 ;; If we did not move up as far as desired,
4331 ;; at least go to beginning of line.
2a1e0c92
CY
4332 (let* ((npoint (prog1 (line-beginning-position)
4333 (goto-char opoint)))
4334 (inhibit-point-motion-hooks nil))
4335 (goto-char npoint)))
e9cd25fe 4336 (t
20782abb 4337 (line-move-finish (or goal-column temporary-goal-column)
fef11f15 4338 opoint (> orig-arg 0)))))))
2076c87c 4339
20782abb 4340(defun line-move-finish (column opoint forward)
af894fc9
RS
4341 (let ((repeat t))
4342 (while repeat
4343 ;; Set REPEAT to t to repeat the whole thing.
4344 (setq repeat nil)
4345
1f980920 4346 (let (new
963355a4 4347 (old (point))
af894fc9 4348 (line-beg (save-excursion (beginning-of-line) (point)))
1f980920
RS
4349 (line-end
4350 ;; Compute the end of the line
20782abb 4351 ;; ignoring effectively invisible newlines.
bbf41690 4352 (save-excursion
a5b4a6a0
RS
4353 ;; Like end-of-line but ignores fields.
4354 (skip-chars-forward "^\n")
c65e6942 4355 (while (and (not (eobp)) (invisible-p (point)))
20782abb 4356 (goto-char (next-char-property-change (point)))
a5b4a6a0 4357 (skip-chars-forward "^\n"))
bbf41690 4358 (point))))
1f980920
RS
4359
4360 ;; Move to the desired column.
54b99340 4361 (line-move-to-column (truncate column))
963355a4
CY
4362
4363 ;; Corner case: suppose we start out in a field boundary in
4364 ;; the middle of a continued line. When we get to
4365 ;; line-move-finish, point is at the start of a new *screen*
4366 ;; line but the same text line; then line-move-to-column would
4367 ;; move us backwards. Test using C-n with point on the "x" in
4368 ;; (insert "a" (propertize "x" 'field t) (make-string 89 ?y))
4369 (and forward
4370 (< (point) old)
4371 (goto-char old))
4372
1f980920 4373 (setq new (point))
af894fc9
RS
4374
4375 ;; Process intangibility within a line.
594a1605
CY
4376 ;; With inhibit-point-motion-hooks bound to nil, a call to
4377 ;; goto-char moves point past intangible text.
4378
4379 ;; However, inhibit-point-motion-hooks controls both the
4380 ;; intangibility and the point-entered/point-left hooks. The
4381 ;; following hack avoids calling the point-* hooks
4382 ;; unnecessarily. Note that we move *forward* past intangible
4383 ;; text when the initial and final points are the same.
d584e29d 4384 (goto-char new)
af894fc9
RS
4385 (let ((inhibit-point-motion-hooks nil))
4386 (goto-char new)
4387
4388 ;; If intangibility moves us to a different (later) place
4389 ;; in the same line, use that as the destination.
4390 (if (<= (point) line-end)
1f980920
RS
4391 (setq new (point))
4392 ;; If that position is "too late",
4393 ;; try the previous allowable position.
4394 ;; See if it is ok.
4395 (backward-char)
20782abb
RS
4396 (if (if forward
4397 ;; If going forward, don't accept the previous
4398 ;; allowable position if it is before the target line.
f1e2a033 4399 (< line-beg (point))
20782abb
RS
4400 ;; If going backward, don't accept the previous
4401 ;; allowable position if it is still after the target line.
4402 (<= (point) line-end))
1f980920
RS
4403 (setq new (point))
4404 ;; As a last resort, use the end of the line.
4405 (setq new line-end))))
af894fc9
RS
4406
4407 ;; Now move to the updated destination, processing fields
4408 ;; as well as intangibility.
4409 (goto-char opoint)
4410 (let ((inhibit-point-motion-hooks nil))
4411 (goto-char
e94e78cc
CY
4412 ;; Ignore field boundaries if the initial and final
4413 ;; positions have the same `field' property, even if the
4414 ;; fields are non-contiguous. This seems to be "nicer"
4415 ;; behavior in many situations.
4416 (if (eq (get-char-property new 'field)
4417 (get-char-property opoint 'field))
4418 new
4419 (constrain-to-field new opoint t t
4420 'inhibit-line-move-field-capture))))
af894fc9 4421
1f980920 4422 ;; If all this moved us to a different line,
af894fc9
RS
4423 ;; retry everything within that new line.
4424 (when (or (< (point) line-beg) (> (point) line-end))
4425 ;; Repeat the intangibility and field processing.
4426 (setq repeat t))))))
4427
4428(defun line-move-to-column (col)
4429 "Try to find column COL, considering invisibility.
4430This function works only in certain cases,
4431because what we really need is for `move-to-column'
4432and `current-column' to be able to ignore invisible text."
a615252b
RS
4433 (if (zerop col)
4434 (beginning-of-line)
095f9ae4 4435 (move-to-column col))
af894fc9
RS
4436
4437 (when (and line-move-ignore-invisible
c65e6942 4438 (not (bolp)) (invisible-p (1- (point))))
af894fc9
RS
4439 (let ((normal-location (point))
4440 (normal-column (current-column)))
4441 ;; If the following character is currently invisible,
4442 ;; skip all characters with that same `invisible' property value.
4443 (while (and (not (eobp))
c65e6942 4444 (invisible-p (point)))
af894fc9
RS
4445 (goto-char (next-char-property-change (point))))
4446 ;; Have we advanced to a larger column position?
4447 (if (> (current-column) normal-column)
4448 ;; We have made some progress towards the desired column.
4449 ;; See if we can make any further progress.
4450 (line-move-to-column (+ (current-column) (- col normal-column)))
4451 ;; Otherwise, go to the place we originally found
4452 ;; and move back over invisible text.
4453 ;; that will get us to the same place on the screen
4454 ;; but with a more reasonable buffer position.
4455 (goto-char normal-location)
4456 (let ((line-beg (save-excursion (beginning-of-line) (point))))
c65e6942 4457 (while (and (not (bolp)) (invisible-p (1- (point))))
af894fc9
RS
4458 (goto-char (previous-char-property-change (point) line-beg))))))))
4459
bbf41690 4460(defun move-end-of-line (arg)
f00239cf 4461 "Move point to end of current line as displayed.
bbf41690
RS
4462With argument ARG not nil or 1, move forward ARG - 1 lines first.
4463If point reaches the beginning or end of buffer, it stops there.
fdb77e6f
CY
4464
4465To ignore the effects of the `intangible' text or overlay
4466property, bind `inhibit-point-motion-hooks' to t.
4467If there is an image in the current line, this function
4468disregards newlines that are part of the text on which the image
4469rests."
109cfe4e 4470 (interactive "^p")
bbf41690
RS
4471 (or arg (setq arg 1))
4472 (let (done)
4473 (while (not done)
4474 (let ((newpos
4475 (save-excursion
4efebb82
CY
4476 (let ((goal-column 0)
4477 (line-move-visual nil))
bbf41690
RS
4478 (and (line-move arg t)
4479 (not (bobp))
4480 (progn
c65e6942 4481 (while (and (not (bobp)) (invisible-p (1- (point))))
3137dda8
SM
4482 (goto-char (previous-single-char-property-change
4483 (point) 'invisible)))
bbf41690
RS
4484 (backward-char 1)))
4485 (point)))))
4486 (goto-char newpos)
4487 (if (and (> (point) newpos)
4488 (eq (preceding-char) ?\n))
4489 (backward-char 1)
4490 (if (and (> (point) newpos) (not (eobp))
4491 (not (eq (following-char) ?\n)))
4efebb82
CY
4492 ;; If we skipped something intangible and now we're not
4493 ;; really at eol, keep going.
bbf41690
RS
4494 (setq arg 1)
4495 (setq done t)))))))
4496
0cbb497c 4497(defun move-beginning-of-line (arg)
f00239cf
RS
4498 "Move point to beginning of current line as displayed.
4499\(If there's an image in the line, this disregards newlines
4500which are part of the text that the image rests on.)
4501
0cbb497c
KS
4502With argument ARG not nil or 1, move forward ARG - 1 lines first.
4503If point reaches the beginning or end of buffer, it stops there.
f00239cf 4504To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
109cfe4e 4505 (interactive "^p")
0cbb497c 4506 (or arg (setq arg 1))
398c9ffb 4507
ad47c4a0 4508 (let ((orig (point))
3137dda8 4509 first-vis first-vis-field-value)
1fffd65f
RS
4510
4511 ;; Move by lines, if ARG is not 1 (the default).
4512 (if (/= arg 1)
4efebb82
CY
4513 (let ((line-move-visual nil))
4514 (line-move (1- arg) t)))
1fffd65f
RS
4515
4516 ;; Move to beginning-of-line, ignoring fields and invisibles.
4517 (skip-chars-backward "^\n")
c65e6942 4518 (while (and (not (bobp)) (invisible-p (1- (point))))
621a4cc8 4519 (goto-char (previous-char-property-change (point)))
1fffd65f 4520 (skip-chars-backward "^\n"))
ad47c4a0
RS
4521
4522 ;; Now find first visible char in the line
c65e6942 4523 (while (and (not (eobp)) (invisible-p (point)))
ad47c4a0
RS
4524 (goto-char (next-char-property-change (point))))
4525 (setq first-vis (point))
4526
4527 ;; See if fields would stop us from reaching FIRST-VIS.
4528 (setq first-vis-field-value
4529 (constrain-to-field first-vis orig (/= arg 1) t nil))
4530
4531 (goto-char (if (/= first-vis-field-value first-vis)
4532 ;; If yes, obey them.
4533 first-vis-field-value
4534 ;; Otherwise, move to START with attention to fields.
4535 ;; (It is possible that fields never matter in this case.)
4536 (constrain-to-field (point) orig
4537 (/= arg 1) t nil)))))
0cbb497c
KS
4538
4539
85be9ec4
SM
4540;; Many people have said they rarely use this feature, and often type
4541;; it by accident. Maybe it shouldn't even be on a key.
d5ab2033 4542(put 'set-goal-column 'disabled t)
2076c87c
JB
4543
4544(defun set-goal-column (arg)
4545 "Set the current horizontal position as a goal for \\[next-line] and \\[previous-line].
4546Those commands will move to this position in the line moved to
4547rather than trying to keep the same horizontal position.
5626c14e 4548With a non-nil argument ARG, clears out the goal column
912c6728
RS
4549so that \\[next-line] and \\[previous-line] resume vertical motion.
4550The goal column is stored in the variable `goal-column'."
2076c87c
JB
4551 (interactive "P")
4552 (if arg
4553 (progn
4554 (setq goal-column nil)
4555 (message "No goal column"))
4556 (setq goal-column (current-column))
8a26c165
DG
4557 ;; The older method below can be erroneous if `set-goal-column' is bound
4558 ;; to a sequence containing %
4559 ;;(message (substitute-command-keys
4560 ;;"Goal column %d (use \\[set-goal-column] with an arg to unset it)")
4561 ;;goal-column)
4562 (message "%s"
63219d53 4563 (concat
8a26c165
DG
4564 (format "Goal column %d " goal-column)
4565 (substitute-command-keys
4566 "(use \\[set-goal-column] with an arg to unset it)")))
63219d53 4567
8a26c165 4568 )
2076c87c 4569 nil)
2d88b556 4570\f
a2cf21a2
CY
4571;;; Editing based on visual lines, as opposed to logical lines.
4572
4573(defun end-of-visual-line (&optional n)
4574 "Move point to end of current visual line.
4575With argument N not nil or 1, move forward N - 1 visual lines first.
4576If point reaches the beginning or end of buffer, it stops there.
4577To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
4578 (interactive "^p")
4579 (or n (setq n 1))
4580 (if (/= n 1)
4581 (let ((line-move-visual t))
4582 (line-move (1- n) t)))
ef187c24
CY
4583 ;; Unlike `move-beginning-of-line', `move-end-of-line' doesn't
4584 ;; constrain to field boundaries, so we don't either.
a2cf21a2
CY
4585 (vertical-motion (cons (window-width) 0)))
4586
4587(defun beginning-of-visual-line (&optional n)
4588 "Move point to beginning of current visual line.
4589With argument N not nil or 1, move forward N - 1 visual lines first.
4590If point reaches the beginning or end of buffer, it stops there.
4591To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
4592 (interactive "^p")
4593 (or n (setq n 1))
ef187c24
CY
4594 (let ((opoint (point)))
4595 (if (/= n 1)
4596 (let ((line-move-visual t))
4597 (line-move (1- n) t)))
4598 (vertical-motion 0)
4599 ;; Constrain to field boundaries, like `move-beginning-of-line'.
4600 (goto-char (constrain-to-field (point) opoint (/= n 1)))))
a2cf21a2
CY
4601
4602(defun kill-visual-line (&optional arg)
4603 "Kill the rest of the visual line.
ad4c1f62
CY
4604With prefix argument ARG, kill that many visual lines from point.
4605If ARG is negative, kill visual lines backward.
4606If ARG is zero, kill the text before point on the current visual
4607line.
a2cf21a2
CY
4608
4609If you want to append the killed line to the last killed text,
4610use \\[append-next-kill] before \\[kill-line].
4611
4612If the buffer is read-only, Emacs will beep and refrain from deleting
4613the line, but put the line in the kill ring anyway. This means that
4614you can use this command to copy text from a read-only buffer.
4615\(If the variable `kill-read-only-ok' is non-nil, then this won't
4616even beep.)"
4617 (interactive "P")
ad4c1f62
CY
4618 ;; Like in `kill-line', it's better to move point to the other end
4619 ;; of the kill before killing.
2066b4fe
CY
4620 (let ((opoint (point))
4621 (kill-whole-line (and kill-whole-line (bolp))))
a2cf21a2
CY
4622 (if arg
4623 (vertical-motion (prefix-numeric-value arg))
ad4c1f62
CY
4624 (end-of-visual-line 1)
4625 (if (= (point) opoint)
4626 (vertical-motion 1)
4627 ;; Skip any trailing whitespace at the end of the visual line.
4628 ;; We used to do this only if `show-trailing-whitespace' is
4629 ;; nil, but that's wrong; the correct thing would be to check
4630 ;; whether the trailing whitespace is highlighted. But, it's
4631 ;; OK to just do this unconditionally.
4632 (skip-chars-forward " \t")))
2066b4fe
CY
4633 (kill-region opoint (if (and kill-whole-line (looking-at "\n"))
4634 (1+ (point))
4635 (point)))))
a2cf21a2
CY
4636
4637(defun next-logical-line (&optional arg try-vscroll)
4638 "Move cursor vertically down ARG lines.
1d2b0303 4639This is identical to `next-line', except that it always moves
a2cf21a2
CY
4640by logical lines instead of visual lines, ignoring the value of
4641the variable `line-move-visual'."
4642 (interactive "^p\np")
4643 (let ((line-move-visual nil))
4644 (with-no-warnings
4645 (next-line arg try-vscroll))))
4646
4647(defun previous-logical-line (&optional arg try-vscroll)
4648 "Move cursor vertically up ARG lines.
4649This is identical to `previous-line', except that it always moves
4650by logical lines instead of visual lines, ignoring the value of
4651the variable `line-move-visual'."
4652 (interactive "^p\np")
4653 (let ((line-move-visual nil))
4654 (with-no-warnings
4655 (previous-line arg try-vscroll))))
4656
4dec5cff
CY
4657(defgroup visual-line nil
4658 "Editing based on visual lines."
4659 :group 'convenience
4660 :version "23.1")
4661
a2cf21a2
CY
4662(defvar visual-line-mode-map
4663 (let ((map (make-sparse-keymap)))
4664 (define-key map [remap kill-line] 'kill-visual-line)
4665 (define-key map [remap move-beginning-of-line] 'beginning-of-visual-line)
4666 (define-key map [remap move-end-of-line] 'end-of-visual-line)
b316b2b8
CY
4667 ;; These keybindings interfere with xterm function keys. Are
4668 ;; there any other suitable bindings?
4669 ;; (define-key map "\M-[" 'previous-logical-line)
4670 ;; (define-key map "\M-]" 'next-logical-line)
a2cf21a2
CY
4671 map))
4672
4dec5cff
CY
4673(defcustom visual-line-fringe-indicators '(nil nil)
4674 "How fringe indicators are shown for wrapped lines in `visual-line-mode'.
4675The value should be a list of the form (LEFT RIGHT), where LEFT
4676and RIGHT are symbols representing the bitmaps to display, to
4677indicate wrapped lines, in the left and right fringes respectively.
4678See also `fringe-indicator-alist'.
4679The default is not to display fringe indicators for wrapped lines.
4680This variable does not affect fringe indicators displayed for
4681other purposes."
4682 :type '(list (choice (const :tag "Hide left indicator" nil)
4683 (const :tag "Left curly arrow" left-curly-arrow)
4684 (symbol :tag "Other bitmap"))
4685 (choice (const :tag "Hide right indicator" nil)
4686 (const :tag "Right curly arrow" right-curly-arrow)
4687 (symbol :tag "Other bitmap")))
4688 :set (lambda (symbol value)
4689 (dolist (buf (buffer-list))
4690 (with-current-buffer buf
4691 (when (and (boundp 'visual-line-mode)
4692 (symbol-value 'visual-line-mode))
4693 (setq fringe-indicator-alist
4694 (cons (cons 'continuation value)
4695 (assq-delete-all
4696 'continuation
4697 (copy-tree fringe-indicator-alist)))))))
4698 (set-default symbol value)))
4699
748e001a
CY
4700(defvar visual-line--saved-state nil)
4701
a2cf21a2 4702(define-minor-mode visual-line-mode
b677cb96
CY
4703 "Redefine simple editing commands to act on visual lines, not logical lines.
4704This also turns on `word-wrap' in the buffer."
a2cf21a2 4705 :keymap visual-line-mode-map
4dec5cff 4706 :group 'visual-line
ea92f9f3 4707 :lighter " Wrap"
a2cf21a2
CY
4708 (if visual-line-mode
4709 (progn
748e001a
CY
4710 (set (make-local-variable 'visual-line--saved-state) nil)
4711 ;; Save the local values of some variables, to be restored if
4712 ;; visual-line-mode is turned off.
4713 (dolist (var '(line-move-visual truncate-lines
4714 truncate-partial-width-windows
4715 word-wrap fringe-indicator-alist))
4716 (if (local-variable-p var)
37820ea9 4717 (push (cons var (symbol-value var))
748e001a 4718 visual-line--saved-state)))
a2cf21a2 4719 (set (make-local-variable 'line-move-visual) t)
c58140f4
CY
4720 (set (make-local-variable 'truncate-partial-width-windows) nil)
4721 (setq truncate-lines nil
4722 word-wrap t
4723 fringe-indicator-alist
4dec5cff
CY
4724 (cons (cons 'continuation visual-line-fringe-indicators)
4725 fringe-indicator-alist)))
a2cf21a2 4726 (kill-local-variable 'line-move-visual)
4dec5cff 4727 (kill-local-variable 'word-wrap)
c58140f4
CY
4728 (kill-local-variable 'truncate-lines)
4729 (kill-local-variable 'truncate-partial-width-windows)
748e001a
CY
4730 (kill-local-variable 'fringe-indicator-alist)
4731 (dolist (saved visual-line--saved-state)
4732 (set (make-local-variable (car saved)) (cdr saved)))
4733 (kill-local-variable 'visual-line--saved-state)))
a2cf21a2
CY
4734
4735(defun turn-on-visual-line-mode ()
4736 (visual-line-mode 1))
4737
4738(define-globalized-minor-mode global-visual-line-mode
4739 visual-line-mode turn-on-visual-line-mode
4740 :lighter " vl")
4741\f
7492f5a6 4742(defun scroll-other-window-down (lines)
e47d38f6
RS
4743 "Scroll the \"other window\" down.
4744For more details, see the documentation for `scroll-other-window'."
7492f5a6
RS
4745 (interactive "P")
4746 (scroll-other-window
4747 ;; Just invert the argument's meaning.
4748 ;; We can do that without knowing which window it will be.
4749 (if (eq lines '-) nil
4750 (if (null lines) '-
4751 (- (prefix-numeric-value lines))))))
3aef9604
RS
4752
4753(defun beginning-of-buffer-other-window (arg)
4754 "Move point to the beginning of the buffer in the other window.
4755Leave mark at previous position.
4756With arg N, put point N/10 of the way from the true beginning."
4757 (interactive "P")
4758 (let ((orig-window (selected-window))
4759 (window (other-window-for-scrolling)))
4760 ;; We use unwind-protect rather than save-window-excursion
4761 ;; because the latter would preserve the things we want to change.
4762 (unwind-protect
4763 (progn
4764 (select-window window)
4765 ;; Set point and mark in that window's buffer.
bbf41690
RS
4766 (with-no-warnings
4767 (beginning-of-buffer arg))
3aef9604
RS
4768 ;; Set point accordingly.
4769 (recenter '(t)))
4770 (select-window orig-window))))
4771
4772(defun end-of-buffer-other-window (arg)
4773 "Move point to the end of the buffer in the other window.
4774Leave mark at previous position.
4775With arg N, put point N/10 of the way from the true end."
4776 (interactive "P")
4777 ;; See beginning-of-buffer-other-window for comments.
4778 (let ((orig-window (selected-window))
4779 (window (other-window-for-scrolling)))
4780 (unwind-protect
4781 (progn
4782 (select-window window)
bbf41690
RS
4783 (with-no-warnings
4784 (end-of-buffer arg))
3aef9604
RS
4785 (recenter '(t)))
4786 (select-window orig-window))))
2d88b556 4787\f
2076c87c
JB
4788(defun transpose-chars (arg)
4789 "Interchange characters around point, moving forward one character.
4790With prefix arg ARG, effect is to take character before point
4791and drag it forward past ARG other characters (backward if ARG negative).
4792If no argument and at end of line, the previous two chars are exchanged."
4793 (interactive "*P")
4794 (and (null arg) (eolp) (forward-char -1))
4795 (transpose-subr 'forward-char (prefix-numeric-value arg)))
4796
4797(defun transpose-words (arg)
4798 "Interchange words around point, leaving point at end of them.
4799With prefix arg ARG, effect is to take word before or around point
4800and drag it forward past ARG other words (backward if ARG negative).
4801If ARG is zero, the words around or after point and around or after mark
4802are interchanged."
41d22ee0 4803 ;; FIXME: `foo a!nd bar' should transpose into `bar and foo'.
2076c87c
JB
4804 (interactive "*p")
4805 (transpose-subr 'forward-word arg))
4806
4807(defun transpose-sexps (arg)
4808 "Like \\[transpose-words] but applies to sexps.
4809Does not work on a sexp that point is in the middle of
4810if it is a list or string."
4811 (interactive "*p")
41d22ee0
SM
4812 (transpose-subr
4813 (lambda (arg)
4814 ;; Here we should try to simulate the behavior of
4815 ;; (cons (progn (forward-sexp x) (point))
4816 ;; (progn (forward-sexp (- x)) (point)))
4817 ;; Except that we don't want to rely on the second forward-sexp
4818 ;; putting us back to where we want to be, since forward-sexp-function
4819 ;; might do funny things like infix-precedence.
4820 (if (if (> arg 0)
4821 (looking-at "\\sw\\|\\s_")
4822 (and (not (bobp))
4823 (save-excursion (forward-char -1) (looking-at "\\sw\\|\\s_"))))
4824 ;; Jumping over a symbol. We might be inside it, mind you.
4825 (progn (funcall (if (> arg 0)
4826 'skip-syntax-backward 'skip-syntax-forward)
4827 "w_")
4828 (cons (save-excursion (forward-sexp arg) (point)) (point)))
4829 ;; Otherwise, we're between sexps. Take a step back before jumping
4830 ;; to make sure we'll obey the same precedence no matter which direction
4831 ;; we're going.
4832 (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) " .")
4833 (cons (save-excursion (forward-sexp arg) (point))
4834 (progn (while (or (forward-comment (if (> arg 0) 1 -1))
4835 (not (zerop (funcall (if (> arg 0)
4836 'skip-syntax-forward
4837 'skip-syntax-backward)
4838 ".")))))
4839 (point)))))
4840 arg 'special))
2076c87c
JB
4841
4842(defun transpose-lines (arg)
4843 "Exchange current line and previous line, leaving point after both.
4844With argument ARG, takes previous line and moves it past ARG lines.
4845With argument 0, interchanges line point is in with line mark is in."
4846 (interactive "*p")
4847 (transpose-subr (function
4848 (lambda (arg)
d3f4ef3f 4849 (if (> arg 0)
2076c87c 4850 (progn
d3f4ef3f
AS
4851 ;; Move forward over ARG lines,
4852 ;; but create newlines if necessary.
4853 (setq arg (forward-line arg))
4854 (if (/= (preceding-char) ?\n)
4855 (setq arg (1+ arg)))
4856 (if (> arg 0)
4857 (newline arg)))
2076c87c
JB
4858 (forward-line arg))))
4859 arg))
4860
36020642
GM
4861;; FIXME seems to leave point BEFORE the current object when ARG = 0,
4862;; which seems inconsistent with the ARG /= 0 case.
4863;; FIXME document SPECIAL.
e1e04350 4864(defun transpose-subr (mover arg &optional special)
36020642
GM
4865 "Subroutine to do the work of transposing objects.
4866Works for lines, sentences, paragraphs, etc. MOVER is a function that
4867moves forward by units of the given object (e.g. forward-sentence,
4868forward-paragraph). If ARG is zero, exchanges the current object
4869with the one containing mark. If ARG is an integer, moves the
4870current object past ARG following (if ARG is positive) or
4871preceding (if ARG is negative) objects, leaving point after the
4872current object."
e1e04350
SM
4873 (let ((aux (if special mover
4874 (lambda (x)
4875 (cons (progn (funcall mover x) (point))
4876 (progn (funcall mover (- x)) (point))))))
4877 pos1 pos2)
4878 (cond
4879 ((= arg 0)
4880 (save-excursion
4881 (setq pos1 (funcall aux 1))
41849bf9 4882 (goto-char (or (mark) (error "No mark set in this buffer")))
e1e04350
SM
4883 (setq pos2 (funcall aux 1))
4884 (transpose-subr-1 pos1 pos2))
4885 (exchange-point-and-mark))
4886 ((> arg 0)
4887 (setq pos1 (funcall aux -1))
4888 (setq pos2 (funcall aux arg))
4889 (transpose-subr-1 pos1 pos2)
4890 (goto-char (car pos2)))
4891 (t
4892 (setq pos1 (funcall aux -1))
4893 (goto-char (car pos1))
4894 (setq pos2 (funcall aux arg))
4895 (transpose-subr-1 pos1 pos2)))))
4896
4897(defun transpose-subr-1 (pos1 pos2)
4898 (when (> (car pos1) (cdr pos1)) (setq pos1 (cons (cdr pos1) (car pos1))))
4899 (when (> (car pos2) (cdr pos2)) (setq pos2 (cons (cdr pos2) (car pos2))))
4900 (when (> (car pos1) (car pos2))
4901 (let ((swap pos1))
4902 (setq pos1 pos2 pos2 swap)))
4903 (if (> (cdr pos1) (car pos2)) (error "Don't have two things to transpose"))
dc7d7552
RS
4904 (atomic-change-group
4905 (let (word2)
1e96c007
SM
4906 ;; FIXME: We first delete the two pieces of text, so markers that
4907 ;; used to point to after the text end up pointing to before it :-(
dc7d7552
RS
4908 (setq word2 (delete-and-extract-region (car pos2) (cdr pos2)))
4909 (goto-char (car pos2))
4910 (insert (delete-and-extract-region (car pos1) (cdr pos1)))
4911 (goto-char (car pos1))
4912 (insert word2))))
2d88b556 4913\f
6b61353c 4914(defun backward-word (&optional arg)
b7e91b0c 4915 "Move backward until encountering the beginning of a word.
5626c14e 4916With argument ARG, do this that many times."
109cfe4e 4917 (interactive "^p")
6b61353c 4918 (forward-word (- (or arg 1))))
2076c87c 4919
a1a801de 4920(defun mark-word (&optional arg allow-extend)
705a5933
JL
4921 "Set mark ARG words away from point.
4922The place mark goes is the same place \\[forward-word] would
4923move to with the same argument.
a1a801de 4924Interactively, if this command is repeated
771069f8 4925or (in Transient Mark mode) if the mark is active,
705a5933 4926it marks the next ARG words after the ones already marked."
a1a801de
RS
4927 (interactive "P\np")
4928 (cond ((and allow-extend
4929 (or (and (eq last-command this-command) (mark t))
d34c311a 4930 (region-active-p)))
705a5933
JL
4931 (setq arg (if arg (prefix-numeric-value arg)
4932 (if (< (mark) (point)) -1 1)))
cad113ae
KG
4933 (set-mark
4934 (save-excursion
4935 (goto-char (mark))
4936 (forward-word arg)
4937 (point))))
4938 (t
4939 (push-mark
4940 (save-excursion
705a5933 4941 (forward-word (prefix-numeric-value arg))
cad113ae
KG
4942 (point))
4943 nil t))))
2076c87c
JB
4944
4945(defun kill-word (arg)
4946 "Kill characters forward until encountering the end of a word.
5626c14e 4947With argument ARG, do this that many times."
e761e42c 4948 (interactive "p")
89ee2bf6 4949 (kill-region (point) (progn (forward-word arg) (point))))
2076c87c
JB
4950
4951(defun backward-kill-word (arg)
654ec269 4952 "Kill characters backward until encountering the beginning of a word.
5626c14e 4953With argument ARG, do this that many times."
e761e42c 4954 (interactive "p")
2076c87c 4955 (kill-word (- arg)))
d7c64071 4956
0f7df535
RS
4957(defun current-word (&optional strict really-word)
4958 "Return the symbol or word that point is on (or a nearby one) as a string.
4959The return value includes no text properties.
1e8c5ac4 4960If optional arg STRICT is non-nil, return nil unless point is within
0fa19a57
RS
4961or adjacent to a symbol or word. In all cases the value can be nil
4962if there is no word nearby.
0f7df535
RS
4963The function, belying its name, normally finds a symbol.
4964If optional arg REALLY-WORD is non-nil, it finds just a word."
d7c64071 4965 (save-excursion
0f7df535 4966 (let* ((oldpoint (point)) (start (point)) (end (point))
81d17173 4967 (syntaxes (if really-word "w" "w_"))
0f7df535
RS
4968 (not-syntaxes (concat "^" syntaxes)))
4969 (skip-syntax-backward syntaxes) (setq start (point))
d7c64071 4970 (goto-char oldpoint)
0f7df535
RS
4971 (skip-syntax-forward syntaxes) (setq end (point))
4972 (when (and (eq start oldpoint) (eq end oldpoint)
4973 ;; Point is neither within nor adjacent to a word.
4974 (not strict))
4975 ;; Look for preceding word in same line.
4976 (skip-syntax-backward not-syntaxes
4977 (save-excursion (beginning-of-line)
4978 (point)))
4979 (if (bolp)
4980 ;; No preceding word in same line.
4981 ;; Look for following word in same line.
4982 (progn
4983 (skip-syntax-forward not-syntaxes
4984 (save-excursion (end-of-line)
4985 (point)))
4986 (setq start (point))
4987 (skip-syntax-forward syntaxes)
4988 (setq end (point)))
4989 (setq end (point))
4990 (skip-syntax-backward syntaxes)
4991 (setq start (point))))
4992 ;; If we found something nonempty, return it as a string.
4993 (unless (= start end)
020db25f 4994 (buffer-substring-no-properties start end)))))
2d88b556 4995\f
69c1dd37 4996(defcustom fill-prefix nil
1d2b0303 4997 "String for filling to insert at front of new line, or nil for none."
69c1dd37
RS
4998 :type '(choice (const :tag "None" nil)
4999 string)
5000 :group 'fill)
2076c87c 5001(make-variable-buffer-local 'fill-prefix)
f31b1257 5002(put 'fill-prefix 'safe-local-variable 'string-or-null-p)
2076c87c 5003
69c1dd37 5004(defcustom auto-fill-inhibit-regexp nil
1d2b0303 5005 "Regexp to match lines which should not be auto-filled."
69c1dd37
RS
5006 :type '(choice (const :tag "None" nil)
5007 regexp)
5008 :group 'fill)
2076c87c 5009
dbe524b6 5010;; This function is used as the auto-fill-function of a buffer
e2504204
KH
5011;; when Auto-Fill mode is enabled.
5012;; It returns t if it really did any work.
dbe524b6
RS
5013;; (Actually some major modes use a different auto-fill function,
5014;; but this one is the default one.)
2076c87c 5015(defun do-auto-fill ()
621a3f62 5016 (let (fc justify give-up
a0170800 5017 (fill-prefix fill-prefix))
c18465c4 5018 (if (or (not (setq justify (current-justification)))
8f066a20
RS
5019 (null (setq fc (current-fill-column)))
5020 (and (eq justify 'left)
5021 (<= (current-column) fc))
621a3f62
SM
5022 (and auto-fill-inhibit-regexp
5023 (save-excursion (beginning-of-line)
eed5698b
RS
5024 (looking-at auto-fill-inhibit-regexp))))
5025 nil ;; Auto-filling not required
3db1e3b5
BG
5026 (if (memq justify '(full center right))
5027 (save-excursion (unjustify-current-line)))
a0170800
RS
5028
5029 ;; Choose a fill-prefix automatically.
e1e04350
SM
5030 (when (and adaptive-fill-mode
5031 (or (null fill-prefix) (string= fill-prefix "")))
5032 (let ((prefix
5033 (fill-context-prefix
5034 (save-excursion (backward-paragraph 1) (point))
5035 (save-excursion (forward-paragraph 1) (point)))))
5036 (and prefix (not (equal prefix ""))
5037 ;; Use auto-indentation rather than a guessed empty prefix.
0e53a373 5038 (not (and fill-indent-according-to-mode
d99f8496 5039 (string-match "\\`[ \t]*\\'" prefix)))
e1e04350 5040 (setq fill-prefix prefix))))
f1180544 5041
eed5698b 5042 (while (and (not give-up) (> (current-column) fc))
e47d38f6 5043 ;; Determine where to split the line.
db893d00
RS
5044 (let* (after-prefix
5045 (fill-point
621a3f62
SM
5046 (save-excursion
5047 (beginning-of-line)
5048 (setq after-prefix (point))
5049 (and fill-prefix
5050 (looking-at (regexp-quote fill-prefix))
5051 (setq after-prefix (match-end 0)))
5052 (move-to-column (1+ fc))
5053 (fill-move-to-break-point after-prefix)
5054 (point))))
db893d00
RS
5055
5056 ;; See whether the place we found is any good.
e47d38f6
RS
5057 (if (save-excursion
5058 (goto-char fill-point)
41d22ee0
SM
5059 (or (bolp)
5060 ;; There is no use breaking at end of line.
5061 (save-excursion (skip-chars-forward " ") (eolp))
5062 ;; It is futile to split at the end of the prefix
5063 ;; since we would just insert the prefix again.
5064 (and after-prefix (<= (point) after-prefix))
5065 ;; Don't split right after a comment starter
5066 ;; since we would just make another comment starter.
5067 (and comment-start-skip
5068 (let ((limit (point)))
5069 (beginning-of-line)
5070 (and (re-search-forward comment-start-skip
5071 limit t)
5072 (eq (point) limit))))))
5073 ;; No good place to break => stop trying.
5074 (setq give-up t)
5075 ;; Ok, we have a useful place to break the line. Do it.
5076 (let ((prev-column (current-column)))
5077 ;; If point is at the fill-point, do not `save-excursion'.
5078 ;; Otherwise, if a comment prefix or fill-prefix is inserted,
5079 ;; point will end up before it rather than after it.
5080 (if (save-excursion
5081 (skip-chars-backward " \t")
5082 (= (point) fill-point))
0b727f9d 5083 (default-indent-new-line t)
41d22ee0
SM
5084 (save-excursion
5085 (goto-char fill-point)
0b727f9d 5086 (default-indent-new-line t)))
41d22ee0
SM
5087 ;; Now do justification, if required
5088 (if (not (eq justify 'left))
e47d38f6 5089 (save-excursion
e1e04350
SM
5090 (end-of-line 0)
5091 (justify-current-line justify nil t)))
41d22ee0
SM
5092 ;; If making the new line didn't reduce the hpos of
5093 ;; the end of the line, then give up now;
5094 ;; trying again will not help.
5095 (if (>= (current-column) prev-column)
5096 (setq give-up t))))))
24ebf92e 5097 ;; Justify last line.
e2504204 5098 (justify-current-line justify t t)
1e722f9f 5099 t)))
2076c87c 5100
0b727f9d
RS
5101(defvar comment-line-break-function 'comment-indent-new-line
5102 "*Mode-specific function which line breaks and continues a comment.
5103This function is called during auto-filling when a comment syntax
5104is defined.
5105The function should take a single optional argument, which is a flag
5106indicating whether it should use soft newlines.")
5107
5108(defun default-indent-new-line (&optional soft)
5109 "Break line at point and indent.
5110If a comment syntax is defined, call `comment-indent-new-line'.
5111
5112The inserted newline is marked hard if variable `use-hard-newlines' is true,
5113unless optional argument SOFT is non-nil."
5114 (interactive)
5115 (if comment-start
5116 (funcall comment-line-break-function soft)
5117 ;; Insert the newline before removing empty space so that markers
5118 ;; get preserved better.
5119 (if soft (insert-and-inherit ?\n) (newline 1))
5120 (save-excursion (forward-char -1) (delete-horizontal-space))
5121 (delete-horizontal-space)
5122
5123 (if (and fill-prefix (not adaptive-fill-mode))
5124 ;; Blindly trust a non-adaptive fill-prefix.
5125 (progn
5126 (indent-to-left-margin)
5127 (insert-before-markers-and-inherit fill-prefix))
5128
5129 (cond
5130 ;; If there's an adaptive prefix, use it unless we're inside
5131 ;; a comment and the prefix is not a comment starter.
5132 (fill-prefix
5133 (indent-to-left-margin)
5134 (insert-and-inherit fill-prefix))
5135 ;; If we're not inside a comment, just try to indent.
5136 (t (indent-according-to-mode))))))
5137
24ebf92e
RS
5138(defvar normal-auto-fill-function 'do-auto-fill
5139 "The function to use for `auto-fill-function' if Auto Fill mode is turned on.
5140Some major modes set this.")
5141
c75505b4 5142(put 'auto-fill-function :minor-mode-function 'auto-fill-mode)
74ab01ff
SM
5143;; `functions' and `hooks' are usually unsafe to set, but setting
5144;; auto-fill-function to nil in a file-local setting is safe and
5145;; can be useful to prevent auto-filling.
5146(put 'auto-fill-function 'safe-local-variable 'null)
d99f8496
SM
5147;; FIXME: turn into a proper minor mode.
5148;; Add a global minor mode version of it.
d7465b15 5149(defun auto-fill-mode (&optional arg)
24ebf92e 5150 "Toggle Auto Fill mode.
1d2b0303 5151With ARG, turn Auto Fill mode on if and only if ARG is positive.
24ebf92e
RS
5152In Auto Fill mode, inserting a space at a column beyond `current-fill-column'
5153automatically breaks the line at a previous space.
5154
5155The value of `normal-auto-fill-function' specifies the function to use
5156for `auto-fill-function' when turning Auto Fill mode on."
d7465b15
RS
5157 (interactive "P")
5158 (prog1 (setq auto-fill-function
5159 (if (if (null arg)
5160 (not auto-fill-function)
5161 (> (prefix-numeric-value arg) 0))
24ebf92e 5162 normal-auto-fill-function
d7465b15 5163 nil))
7911ecc8 5164 (force-mode-line-update)))
d7465b15
RS
5165
5166;; This holds a document string used to document auto-fill-mode.
5167(defun auto-fill-function ()
5168 "Automatically break line at a previous space, in insertion of text."
5169 nil)
5170
5171(defun turn-on-auto-fill ()
5172 "Unconditionally turn on Auto Fill mode."
5173 (auto-fill-mode 1))
3a99c819
GM
5174
5175(defun turn-off-auto-fill ()
5176 "Unconditionally turn off Auto Fill mode."
5177 (auto-fill-mode -1))
5178
7cbf1dc1 5179(custom-add-option 'text-mode-hook 'turn-on-auto-fill)
d7465b15
RS
5180
5181(defun set-fill-column (arg)
4cc0ea11 5182 "Set `fill-column' to specified argument.
923efb99 5183Use \\[universal-argument] followed by a number to specify a column.
4cc0ea11 5184Just \\[universal-argument] as argument means to use the current column."
7c373357
SM
5185 (interactive
5186 (list (or current-prefix-arg
5187 ;; We used to use current-column silently, but C-x f is too easily
5188 ;; typed as a typo for C-x C-f, so we turned it into an error and
5189 ;; now an interactive prompt.
5190 (read-number "Set fill-column to: " (current-column)))))
f4520363
RS
5191 (if (consp arg)
5192 (setq arg (current-column)))
5193 (if (not (integerp arg))
5194 ;; Disallow missing argument; it's probably a typo for C-x C-f.
f33321ad 5195 (error "set-fill-column requires an explicit argument")
f4520363
RS
5196 (message "Fill column set to %d (was %d)" arg fill-column)
5197 (setq fill-column arg)))
2d88b556 5198\f
2076c87c 5199(defun set-selective-display (arg)
ff1fbe3e
RS
5200 "Set `selective-display' to ARG; clear it if no arg.
5201When the value of `selective-display' is a number > 0,
5202lines whose indentation is >= that value are not displayed.
5203The variable `selective-display' has a separate value for each buffer."
2076c87c
JB
5204 (interactive "P")
5205 (if (eq selective-display t)
5206 (error "selective-display already in use for marked lines"))
c88ab9ce
ER
5207 (let ((current-vpos
5208 (save-restriction
5209 (narrow-to-region (point-min) (point))
5210 (goto-char (window-start))
5211 (vertical-motion (window-height)))))
5212 (setq selective-display
5213 (and arg (prefix-numeric-value arg)))
5214 (recenter current-vpos))
2076c87c
JB
5215 (set-window-start (selected-window) (window-start (selected-window)))
5216 (princ "selective-display set to " t)
5217 (prin1 selective-display t)
5218 (princ "." t))
5219
40a64816 5220(defvaralias 'indicate-unused-lines 'indicate-empty-lines)
40a64816 5221
b3228584 5222(defun toggle-truncate-lines (&optional arg)
215f50ce 5223 "Toggle whether to fold or truncate long lines for the current buffer.
4837b516 5224With prefix argument ARG, truncate long lines if ARG is positive,
1d2b0303
JB
5225otherwise don't truncate them. Note that in side-by-side windows,
5226this command has no effect if `truncate-partial-width-windows'
627bb5dc 5227is non-nil."
0bb64d76
PA
5228 (interactive "P")
5229 (setq truncate-lines
5230 (if (null arg)
5231 (not truncate-lines)
46cdfe8f
RS
5232 (> (prefix-numeric-value arg) 0)))
5233 (force-mode-line-update)
4f017185
RS
5234 (unless truncate-lines
5235 (let ((buffer (current-buffer)))
5236 (walk-windows (lambda (window)
5237 (if (eq buffer (window-buffer window))
5238 (set-window-hscroll window 0)))
5239 nil t)))
46cdfe8f
RS
5240 (message "Truncate long lines %s"
5241 (if truncate-lines "enabled" "disabled")))
0bb64d76 5242
c899b3db
JL
5243(defun toggle-word-wrap (&optional arg)
5244 "Toggle whether to use word-wrapping for continuation lines.
5245With prefix argument ARG, wrap continuation lines at word boundaries
5246if ARG is positive, otherwise wrap them at the right screen edge.
5247This command toggles the value of `word-wrap'. It has no effect
5248if long lines are truncated."
5249 (interactive "P")
5250 (setq word-wrap
5251 (if (null arg)
5252 (not word-wrap)
5253 (> (prefix-numeric-value arg) 0)))
5254 (force-mode-line-update)
5255 (message "Word wrapping %s"
5256 (if word-wrap "enabled" "disabled")))
5257
ca0a881a 5258(defvar overwrite-mode-textual (purecopy " Ovwrt")
b6a22db0 5259 "The string displayed in the mode line when in overwrite mode.")
ca0a881a 5260(defvar overwrite-mode-binary (purecopy " Bin Ovwrt")
b6a22db0
JB
5261 "The string displayed in the mode line when in binary overwrite mode.")
5262
2076c87c
JB
5263(defun overwrite-mode (arg)
5264 "Toggle overwrite mode.
4837b516
GM
5265With prefix argument ARG, turn overwrite mode on if ARG is positive,
5266otherwise turn it off. In overwrite mode, printing characters typed
5267in replace existing text on a one-for-one basis, rather than pushing
5268it to the right. At the end of a line, such characters extend the line.
5269Before a tab, such characters insert until the tab is filled in.
b6a22db0
JB
5270\\[quoted-insert] still inserts characters in overwrite mode; this
5271is supposed to make it easier to insert characters when necessary."
5272 (interactive "P")
5273 (setq overwrite-mode
5274 (if (if (null arg) (not overwrite-mode)
5275 (> (prefix-numeric-value arg) 0))
5276 'overwrite-mode-textual))
5277 (force-mode-line-update))
5278
5279(defun binary-overwrite-mode (arg)
5280 "Toggle binary overwrite mode.
4837b516
GM
5281With prefix argument ARG, turn binary overwrite mode on if ARG is
5282positive, otherwise turn it off. In binary overwrite mode, printing
5283characters typed in replace existing text. Newlines are not treated
5284specially, so typing at the end of a line joins the line to the next,
5285with the typed character between them. Typing before a tab character
5286simply replaces the tab with the character typed. \\[quoted-insert]
5287replaces the text at the cursor, just as ordinary typing characters do.
b6a22db0
JB
5288
5289Note that binary overwrite mode is not its own minor mode; it is a
f33321ad 5290specialization of overwrite mode, entered by setting the
b6a22db0 5291`overwrite-mode' variable to `overwrite-mode-binary'."
2076c87c
JB
5292 (interactive "P")
5293 (setq overwrite-mode
b6a22db0 5294 (if (if (null arg)
a61099dd 5295 (not (eq overwrite-mode 'overwrite-mode-binary))
b6a22db0
JB
5296 (> (prefix-numeric-value arg) 0))
5297 'overwrite-mode-binary))
5298 (force-mode-line-update))
eaae8106 5299
6710df48 5300(define-minor-mode line-number-mode
a61099dd 5301 "Toggle Line Number mode.
1d2b0303 5302With ARG, turn Line Number mode on if ARG is positive, otherwise
4837b516
GM
5303turn it off. When Line Number mode is enabled, the line number
5304appears in the mode line.
8dc9e2ef 5305
32f2f98e
EZ
5306Line numbers do not appear for very large buffers and buffers
5307with very long lines; see variables `line-number-display-limit'
5308and `line-number-display-limit-width'."
efeb22bf 5309 :init-value t :global t :group 'mode-line)
bcad4985 5310
6710df48 5311(define-minor-mode column-number-mode
bcad4985 5312 "Toggle Column Number mode.
1d2b0303 5313With ARG, turn Column Number mode on if ARG is positive,
4837b516
GM
5314otherwise turn it off. When Column Number mode is enabled, the
5315column number appears in the mode line."
efeb22bf 5316 :global t :group 'mode-line)
6b61353c
KH
5317
5318(define-minor-mode size-indication-mode
5319 "Toggle Size Indication mode.
1d2b0303 5320With ARG, turn Size Indication mode on if ARG is positive,
4837b516
GM
5321otherwise turn it off. When Size Indication mode is enabled, the
5322size of the accessible part of the buffer appears in the mode line."
efeb22bf 5323 :global t :group 'mode-line)
2d88b556 5324\f
4b384a8f 5325(defgroup paren-blinking nil
020db25f 5326 "Blinking matching of parens and expressions."
4b384a8f
SM
5327 :prefix "blink-matching-"
5328 :group 'paren-matching)
5329
69c1dd37 5330(defcustom blink-matching-paren t
1d2b0303 5331 "Non-nil means show matching open-paren when close-paren is inserted."
69c1dd37 5332 :type 'boolean
4b384a8f 5333 :group 'paren-blinking)
2076c87c 5334
69c1dd37 5335(defcustom blink-matching-paren-on-screen t
1d2b0303 5336 "Non-nil means show matching open-paren when it is on screen.
1c2ba4e7 5337If nil, don't show it (but the open-paren can still be shown
92aa8a33
LT
5338when it is off screen).
5339
9cb370a9 5340This variable has no effect if `blink-matching-paren' is nil.
a9f72e5f 5341\(In that case, the open-paren is never shown.)
9cb370a9 5342It is also ignored if `show-paren-mode' is enabled."
69c1dd37 5343 :type 'boolean
4b384a8f 5344 :group 'paren-blinking)
29fc44dd 5345
fd413a37 5346(defcustom blink-matching-paren-distance (* 100 1024)
1d2b0303 5347 "If non-nil, maximum distance to search backwards for matching open-paren.
66d44a36 5348If nil, search stops at the beginning of the accessible portion of the buffer."
fd413a37 5349 :version "23.2" ; 25->100k
66d44a36 5350 :type '(choice (const nil) integer)
4b384a8f 5351 :group 'paren-blinking)
2076c87c 5352
69c1dd37 5353(defcustom blink-matching-delay 1
1d2b0303 5354 "Time in seconds to delay after showing a matching paren."
4b384a8f
SM
5355 :type 'number
5356 :group 'paren-blinking)
72dddf8b 5357
69c1dd37 5358(defcustom blink-matching-paren-dont-ignore-comments nil
1d2b0303 5359 "If nil, `blink-matching-paren' ignores comments.
ab6b3b16
RS
5360More precisely, when looking for the matching parenthesis,
5361it skips the contents of comments that end before point."
69c1dd37 5362 :type 'boolean
4b384a8f 5363 :group 'paren-blinking)
903b7f65 5364
2076c87c
JB
5365(defun blink-matching-open ()
5366 "Move cursor momentarily to the beginning of the sexp before point."
5367 (interactive)
c448d316 5368 (when (and (> (point) (point-min))
1d0e3fc8
RS
5369 blink-matching-paren
5370 ;; Verify an even number of quoting characters precede the close.
5371 (= 1 (logand 1 (- (point)
5372 (save-excursion
5373 (forward-char -1)
5374 (skip-syntax-backward "/\\")
5375 (point))))))
5376 (let* ((oldpos (point))
3137dda8 5377 (message-log-max nil) ; Don't log messages about paren matching.
bf825c62
GM
5378 (atdollar (eq (syntax-class (syntax-after (1- oldpos))) 8))
5379 (isdollar)
3137dda8
SM
5380 (blinkpos
5381 (save-excursion
5382 (save-restriction
5383 (if blink-matching-paren-distance
5384 (narrow-to-region
5385 (max (minibuffer-prompt-end) ;(point-min) unless minibuf.
5386 (- (point) blink-matching-paren-distance))
5387 oldpos))
5388 (let ((parse-sexp-ignore-comments
5389 (and parse-sexp-ignore-comments
5390 (not blink-matching-paren-dont-ignore-comments))))
5391 (condition-case ()
5392 (scan-sexps oldpos -1)
5393 (error nil))))))
5394 (matching-paren
5395 (and blinkpos
5396 ;; Not syntax '$'.
bf825c62
GM
5397 (not (setq isdollar
5398 (eq (syntax-class (syntax-after blinkpos)) 8)))
3137dda8
SM
5399 (let ((syntax (syntax-after blinkpos)))
5400 (and (consp syntax)
5401 (eq (syntax-class syntax) 4)
5402 (cdr syntax))))))
5403 (cond
bf825c62
GM
5404 ;; isdollar is for:
5405 ;; http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00871.html
5406 ((not (or (and isdollar blinkpos)
5407 (and atdollar (not blinkpos)) ; see below
5408 (eq matching-paren (char-before oldpos))
3137dda8
SM
5409 ;; The cdr might hold a new paren-class info rather than
5410 ;; a matching-char info, in which case the two CDRs
5411 ;; should match.
5412 (eq matching-paren (cdr (syntax-after (1- oldpos))))))
28e271f0
JL
5413 (if (minibufferp)
5414 (minibuffer-message " [Mismatched parentheses]")
5415 (message "Mismatched parentheses")))
3137dda8 5416 ((not blinkpos)
bf825c62
GM
5417 (or blink-matching-paren-distance
5418 ;; Don't complain when `$' with no blinkpos, because it
5419 ;; could just be the first one typed in the buffer.
5420 atdollar
28e271f0
JL
5421 (if (minibufferp)
5422 (minibuffer-message " [Unmatched parenthesis]")
5423 (message "Unmatched parenthesis"))))
3137dda8
SM
5424 ((pos-visible-in-window-p blinkpos)
5425 ;; Matching open within window, temporarily move to blinkpos but only
5426 ;; if `blink-matching-paren-on-screen' is non-nil.
5427 (and blink-matching-paren-on-screen
5428 (not show-paren-mode)
5429 (save-excursion
5430 (goto-char blinkpos)
5431 (sit-for blink-matching-delay))))
5432 (t
5433 (save-excursion
5434 (goto-char blinkpos)
5435 (let ((open-paren-line-string
5436 ;; Show what precedes the open in its line, if anything.
5437 (cond
5438 ((save-excursion (skip-chars-backward " \t") (not (bolp)))
5439 (buffer-substring (line-beginning-position)
5440 (1+ blinkpos)))
5441 ;; Show what follows the open in its line, if anything.
5442 ((save-excursion
5443 (forward-char 1)
5444 (skip-chars-forward " \t")
5445 (not (eolp)))
5446 (buffer-substring blinkpos
5447 (line-end-position)))
5448 ;; Otherwise show the previous nonblank line,
5449 ;; if there is one.
5450 ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
5451 (concat
5452 (buffer-substring (progn
5453 (skip-chars-backward "\n \t")
5454 (line-beginning-position))
5455 (progn (end-of-line)
5456 (skip-chars-backward " \t")
5457 (point)))
5458 ;; Replace the newline and other whitespace with `...'.
5459 "..."
5460 (buffer-substring blinkpos (1+ blinkpos))))
5461 ;; There is nothing to show except the char itself.
5462 (t (buffer-substring blinkpos (1+ blinkpos))))))
5463 (message "Matches %s"
5464 (substring-no-properties open-paren-line-string)))))))))
5465
2076c87c 5466(setq blink-paren-function 'blink-matching-open)
2d88b556 5467\f
9a1277dd
RS
5468;; This executes C-g typed while Emacs is waiting for a command.
5469;; Quitting out of a program does not go through here;
5470;; that happens in the QUIT macro at the C code level.
2076c87c 5471(defun keyboard-quit ()
d5dae4e1 5472 "Signal a `quit' condition.
af39530e
RS
5473During execution of Lisp code, this character causes a quit directly.
5474At top-level, as an editor command, this simply beeps."
2076c87c 5475 (interactive)
19d35374 5476 (deactivate-mark)
8a7644e9
KS
5477 (if (fboundp 'kmacro-keyboard-quit)
5478 (kmacro-keyboard-quit))
f5e13057 5479 (setq defining-kbd-macro nil)
2076c87c
JB
5480 (signal 'quit nil))
5481
1c6c6fde
RS
5482(defvar buffer-quit-function nil
5483 "Function to call to \"quit\" the current buffer, or nil if none.
5484\\[keyboard-escape-quit] calls this function when its more local actions
5485\(such as cancelling a prefix argument, minibuffer or region) do not apply.")
5486
c66587fe
RS
5487(defun keyboard-escape-quit ()
5488 "Exit the current \"mode\" (in a generalized sense of the word).
5489This command can exit an interactive command such as `query-replace',
5490can clear out a prefix argument or a region,
5491can get out of the minibuffer or other recursive edit,
1c6c6fde
RS
5492cancel the use of the current buffer (for special-purpose buffers),
5493or go back to just one window (by deleting all but the selected window)."
c66587fe
RS
5494 (interactive)
5495 (cond ((eq last-command 'mode-exited) nil)
5496 ((> (minibuffer-depth) 0)
5497 (abort-recursive-edit))
5498 (current-prefix-arg
5499 nil)
d34c311a 5500 ((region-active-p)
c66587fe 5501 (deactivate-mark))
1b657835
RS
5502 ((> (recursion-depth) 0)
5503 (exit-recursive-edit))
1c6c6fde
RS
5504 (buffer-quit-function
5505 (funcall buffer-quit-function))
c66587fe 5506 ((not (one-window-p t))
1b657835
RS
5507 (delete-other-windows))
5508 ((string-match "^ \\*" (buffer-name (current-buffer)))
5509 (bury-buffer))))
c66587fe 5510
2d88b556
RS
5511(defun play-sound-file (file &optional volume device)
5512 "Play sound stored in FILE.
5513VOLUME and DEVICE correspond to the keywords of the sound
5514specification for `play-sound'."
5515 (interactive "fPlay sound file: ")
5516 (let ((sound (list :file file)))
5517 (if volume
5518 (plist-put sound :volume volume))
5519 (if device
5520 (plist-put sound :device device))
5521 (push 'sound sound)
5522 (play-sound sound)))
5523
56abefac 5524\f
7683b5c2 5525(defcustom read-mail-command 'rmail
1d2b0303 5526 "Your preference for a mail reading package.
9023837e
DL
5527This is used by some keybindings which support reading mail.
5528See also `mail-user-agent' concerning sending mail."
f6714ede
GM
5529 :type '(radio (function-item :tag "Rmail" :format "%t\n" rmail)
5530 (function-item :tag "Gnus" :format "%t\n" gnus)
5531 (function-item :tag "Emacs interface to MH"
5532 :format "%t\n" mh-rmail)
5533 (function :tag "Other"))
7683b5c2
DL
5534 :version "21.1"
5535 :group 'mail)
5536
cbd61418 5537(defcustom mail-user-agent 'message-user-agent
1d2b0303 5538 "Your preference for a mail composition package.
9023837e 5539Various Emacs Lisp packages (e.g. Reporter) require you to compose an
a31ca314
RS
5540outgoing email message. This variable lets you specify which
5541mail-sending package you prefer.
5542
5543Valid values include:
5544
cfc47664
GM
5545 `message-user-agent' -- use the Message package.
5546 See Info node `(message)'.
5547 `sendmail-user-agent' -- use the Mail package.
9023837e
DL
5548 See Info node `(emacs)Sending Mail'.
5549 `mh-e-user-agent' -- use the Emacs interface to the MH mail system.
5550 See Info node `(mh-e)'.
9023837e
DL
5551 `gnus-user-agent' -- like `message-user-agent', but with Gnus
5552 paraphernalia, particularly the Gcc: header for
5553 archiving.
a31ca314
RS
5554
5555Additional valid symbols may be available; check with the author of
15d0c9b1
DL
5556your package for details. The function should return non-nil if it
5557succeeds.
9023837e
DL
5558
5559See also `read-mail-command' concerning reading mail."
cfc47664
GM
5560 :type '(radio (function-item :tag "Message package"
5561 :format "%t\n"
5562 message-user-agent)
5563 (function-item :tag "Mail package"
69c1dd37
RS
5564 :format "%t\n"
5565 sendmail-user-agent)
5566 (function-item :tag "Emacs interface to MH"
5567 :format "%t\n"
5568 mh-e-user-agent)
cfc47664 5569 (function-item :tag "Message with full Gnus features"
9023837e
DL
5570 :format "%t\n"
5571 gnus-user-agent)
69c1dd37 5572 (function :tag "Other"))
cfc47664 5573 :version "23.2" ; sendmail->message
69c1dd37 5574 :group 'mail)
a31ca314 5575
3d68fa99
CY
5576(defcustom compose-mail-user-agent-warnings t
5577 "If non-nil, `compose-mail' warns about changes in `mail-user-agent'.
5578If the value of `mail-user-agent' is the default, and the user
5579appears to have customizations applying to the old default,
5580`compose-mail' issues a warning."
5581 :type 'boolean
5582 :version "23.2"
5583 :group 'mail)
5584
a31ca314 5585(define-mail-user-agent 'sendmail-user-agent
34fbcdf3 5586 'sendmail-user-agent-compose
a31ca314
RS
5587 'mail-send-and-exit)
5588
360b5483
RS
5589(defun rfc822-goto-eoh ()
5590 ;; Go to header delimiter line in a mail message, following RFC822 rules
5591 (goto-char (point-min))
e1e04350
SM
5592 (when (re-search-forward
5593 "^\\([:\n]\\|[^: \t\n]+[ \t\n]\\)" nil 'move)
5594 (goto-char (match-beginning 0))))
360b5483 5595
34fbcdf3
RS
5596(defun sendmail-user-agent-compose (&optional to subject other-headers continue
5597 switch-function yank-action
5598 send-actions)
5599 (if switch-function
5600 (let ((special-display-buffer-names nil)
5601 (special-display-regexps nil)
5602 (same-window-buffer-names nil)
5603 (same-window-regexps nil))
5604 (funcall switch-function "*mail*")))
6b61353c
KH
5605 (let ((cc (cdr (assoc-string "cc" other-headers t)))
5606 (in-reply-to (cdr (assoc-string "in-reply-to" other-headers t)))
5607 (body (cdr (assoc-string "body" other-headers t))))
34fbcdf3
RS
5608 (or (mail continue to subject in-reply-to cc yank-action send-actions)
5609 continue
5610 (error "Message aborted"))
5611 (save-excursion
360b5483 5612 (rfc822-goto-eoh)
34fbcdf3 5613 (while other-headers
0740c738
GM
5614 (unless (member-ignore-case (car (car other-headers))
5615 '("in-reply-to" "cc" "body"))
34fbcdf3 5616 (insert (car (car other-headers)) ": "
15575807
CY
5617 (cdr (car other-headers))
5618 (if use-hard-newlines hard-newline "\n")))
34fbcdf3 5619 (setq other-headers (cdr other-headers)))
0740c738
GM
5620 (when body
5621 (forward-line 1)
5622 (insert body))
34fbcdf3
RS
5623 t)))
5624
d0008a00
RS
5625(defun compose-mail (&optional to subject other-headers continue
5626 switch-function yank-action send-actions)
5627 "Start composing a mail message to send.
5628This uses the user's chosen mail composition package
5629as selected with the variable `mail-user-agent'.
5630The optional arguments TO and SUBJECT specify recipients
5631and the initial Subject field, respectively.
5632
5633OTHER-HEADERS is an alist specifying additional
5634header fields. Elements look like (HEADER . VALUE) where both
5635HEADER and VALUE are strings.
5636
5637CONTINUE, if non-nil, says to continue editing a message already
9dda5b0e 5638being composed. Interactively, CONTINUE is the prefix argument.
d0008a00
RS
5639
5640SWITCH-FUNCTION, if non-nil, is a function to use to
5641switch to and display the buffer used for mail composition.
5642
5643YANK-ACTION, if non-nil, is an action to perform, if and when necessary,
06720de2
RS
5644to insert the raw text of the message being replied to.
5645It has the form (FUNCTION . ARGS). The user agent will apply
5646FUNCTION to ARGS, to insert the raw text of the original message.
5647\(The user agent will also run `mail-citation-hook', *after* the
5648original text has been inserted in this way.)
d0008a00
RS
5649
5650SEND-ACTIONS is a list of actions to call when the message is sent.
5651Each action has the form (FUNCTION . ARGS)."
b5f019be
RS
5652 (interactive
5653 (list nil nil nil current-prefix-arg))
3d68fa99
CY
5654
5655 ;; In Emacs 23.2, the default value of `mail-user-agent' changed
5656 ;; from sendmail-user-agent to message-user-agent. Some users may
5657 ;; encounter incompatibilities. This hack tries to detect problems
5658 ;; and warn about them.
5659 (and compose-mail-user-agent-warnings
5660 (eq mail-user-agent 'message-user-agent)
5661 (let (warn-vars)
5662 (dolist (var '(mail-mode-hook mail-send-hook mail-setup-hook
5663 mail-yank-hooks mail-archive-file-name
5664 mail-default-reply-to mail-mailing-lists
5e1d4968 5665 mail-self-blind))
3d68fa99
CY
5666 (and (boundp var)
5667 (symbol-value var)
5668 (push var warn-vars)))
5669 (when warn-vars
5670 (display-warning 'mail
5671 (format "\
5672The default mail mode is now Message mode.
5673You have the following Mail mode variable%s customized:
5674\n %s\n\nTo use Mail mode, set `mail-user-agent' to sendmail-user-agent.
2c79f053 5675To disable this warning, set `compose-mail-user-agent-warnings' to nil."
3d68fa99
CY
5676 (if (> (length warn-vars) 1) "s" "")
5677 (mapconcat 'symbol-name
5678 warn-vars " "))))))
5679
676b1a74
CY
5680 (let ((function (get mail-user-agent 'composefunc)))
5681 (funcall function to subject other-headers continue
5682 switch-function yank-action send-actions)))
b5f019be
RS
5683
5684(defun compose-mail-other-window (&optional to subject other-headers continue
5685 yank-action send-actions)
5686 "Like \\[compose-mail], but edit the outgoing message in another window."
5687 (interactive
5688 (list nil nil nil current-prefix-arg))
5689 (compose-mail to subject other-headers continue
5690 'switch-to-buffer-other-window yank-action send-actions))
5691
5692
5693(defun compose-mail-other-frame (&optional to subject other-headers continue
5694 yank-action send-actions)
5695 "Like \\[compose-mail], but edit the outgoing message in another frame."
5696 (interactive
5697 (list nil nil nil current-prefix-arg))
5698 (compose-mail to subject other-headers continue
5699 'switch-to-buffer-other-frame yank-action send-actions))
56abefac 5700\f
610c1c68 5701(defvar set-variable-value-history nil
987ec16d
EZ
5702 "History of values entered with `set-variable'.
5703
5704Maximum length of the history list is determined by the value
5705of `history-length', which see.")
610c1c68 5706
d6281b4e 5707(defun set-variable (variable value &optional make-local)
610c1c68 5708 "Set VARIABLE to VALUE. VALUE is a Lisp object.
d6281b4e
RS
5709VARIABLE should be a user option variable name, a Lisp variable
5710meant to be customized by users. You should enter VALUE in Lisp syntax,
5711so if you want VALUE to be a string, you must surround it with doublequotes.
610c1c68
RS
5712VALUE is used literally, not evaluated.
5713
5714If VARIABLE has a `variable-interactive' property, that is used as if
5715it were the arg to `interactive' (which see) to interactively read VALUE.
5716
5717If VARIABLE has been defined with `defcustom', then the type information
16236388
RS
5718in the definition is used to check that VALUE is valid.
5719
5720With a prefix argument, set VARIABLE to VALUE buffer-locally."
e9dfb72e
RS
5721 (interactive
5722 (let* ((default-var (variable-at-point))
7fd0ef0d
JL
5723 (var (if (user-variable-p default-var)
5724 (read-variable (format "Set variable (default %s): " default-var)
5725 default-var)
5726 (read-variable "Set variable: ")))
6b61353c
KH
5727 (minibuffer-help-form '(describe-variable var))
5728 (prop (get var 'variable-interactive))
0684376b
JB
5729 (obsolete (car (get var 'byte-obsolete-variable)))
5730 (prompt (format "Set %s %s to value: " var
6b61353c 5731 (cond ((local-variable-p var)
0684376b 5732 "(buffer-local)")
6b61353c
KH
5733 ((or current-prefix-arg
5734 (local-variable-if-set-p var))
0684376b
JB
5735 "buffer-locally")
5736 (t "globally"))))
5737 (val (progn
5738 (when obsolete
5739 (message (concat "`%S' is obsolete; "
5740 (if (symbolp obsolete) "use `%S' instead" "%s"))
5741 var obsolete)
5742 (sit-for 3))
5743 (if prop
5744 ;; Use VAR's `variable-interactive' property
5745 ;; as an interactive spec for prompting.
5746 (call-interactively `(lambda (arg)
5747 (interactive ,prop)
5748 arg))
5749 (read
5750 (read-string prompt nil
7fd0ef0d
JL
5751 'set-variable-value-history
5752 (format "%S" (symbol-value var))))))))
6b61353c 5753 (list var val current-prefix-arg)))
610c1c68 5754
d6281b4e
RS
5755 (and (custom-variable-p variable)
5756 (not (get variable 'custom-type))
5757 (custom-load-symbol variable))
5758 (let ((type (get variable 'custom-type)))
610c1c68
RS
5759 (when type
5760 ;; Match with custom type.
36755dd9 5761 (require 'cus-edit)
610c1c68 5762 (setq type (widget-convert type))
d6281b4e 5763 (unless (widget-apply type :match value)
1e722f9f 5764 (error "Value `%S' does not match type %S of %S"
d6281b4e 5765 value (car type) variable))))
16236388
RS
5766
5767 (if make-local
d6281b4e 5768 (make-local-variable variable))
f1180544 5769
d6281b4e 5770 (set variable value)
a2aef080
GM
5771
5772 ;; Force a thorough redisplay for the case that the variable
5773 ;; has an effect on the display, like `tab-width' has.
5774 (force-mode-line-update))
56abefac 5775\f
e8a700bf
RS
5776;; Define the major mode for lists of completions.
5777
e2947429
SM
5778(defvar completion-list-mode-map
5779 (let ((map (make-sparse-keymap)))
5780 (define-key map [mouse-2] 'mouse-choose-completion)
5781 (define-key map [follow-link] 'mouse-face)
5782 (define-key map [down-mouse-2] nil)
5783 (define-key map "\C-m" 'choose-completion)
5784 (define-key map "\e\e\e" 'delete-completion-window)
5785 (define-key map [left] 'previous-completion)
5786 (define-key map [right] 'next-completion)
45f8cb0c 5787 (define-key map "q" 'quit-window)
e2947429 5788 map)
98b45886 5789 "Local map for completion list buffers.")
e8a700bf
RS
5790
5791;; Completion mode is suitable only for specially formatted data.
ac29eb79 5792(put 'completion-list-mode 'mode-class 'special)
e8a700bf 5793
98b45886
RS
5794(defvar completion-reference-buffer nil
5795 "Record the buffer that was current when the completion list was requested.
5796This is a local variable in the completion list buffer.
ec39964e 5797Initial value is nil to avoid some compiler warnings.")
3819736b 5798
83434bda
RS
5799(defvar completion-no-auto-exit nil
5800 "Non-nil means `choose-completion-string' should never exit the minibuffer.
f6714ede 5801This also applies to other functions such as `choose-completion'.")
83434bda 5802
d5e63715
SM
5803(defvar completion-base-position nil
5804 "Position of the base of the text corresponding to the shown completions.
5805This variable is used in the *Completions* buffers.
5806Its value is a list of the form (START END) where START is the place
5807where the completion should be inserted and END (if non-nil) is the end
5808of the text to replace. If END is nil, point is used instead.")
5809
98b45886 5810(defvar completion-base-size nil
3c59150d
CY
5811 "Number of chars before point not involved in completion.
5812This is a local variable in the completion list buffer.
5813It refers to the chars in the minibuffer if completing in the
5814minibuffer, or in `completion-reference-buffer' otherwise.
5815Only characters in the field at point are included.
5816
5817If nil, Emacs determines which part of the tail end of the
5818buffer's text is involved in completion by comparing the text
5819directly.")
d5e63715 5820(make-obsolete-variable 'completion-base-size 'completion-base-position "23.2")
f6b293e3 5821
1c6c6fde
RS
5822(defun delete-completion-window ()
5823 "Delete the completion list window.
5824Go to the window from which completion was requested."
5825 (interactive)
5826 (let ((buf completion-reference-buffer))
ddb2b181
RS
5827 (if (one-window-p t)
5828 (if (window-dedicated-p (selected-window))
5829 (delete-frame (selected-frame)))
5830 (delete-window (selected-window))
5831 (if (get-buffer-window buf)
5832 (select-window (get-buffer-window buf))))))
1c6c6fde 5833
dde69dbe
RS
5834(defun previous-completion (n)
5835 "Move to the previous item in the completion list."
5836 (interactive "p")
5837 (next-completion (- n)))
5838
5839(defun next-completion (n)
5840 "Move to the next item in the completion list.
1f238ac2 5841With prefix argument N, move N items (negative N means move backward)."
dde69dbe 5842 (interactive "p")
58dd38f1
SM
5843 (let ((beg (point-min)) (end (point-max)))
5844 (while (and (> n 0) (not (eobp)))
dde69dbe 5845 ;; If in a completion, move to the end of it.
58dd38f1
SM
5846 (when (get-text-property (point) 'mouse-face)
5847 (goto-char (next-single-property-change (point) 'mouse-face nil end)))
dde69dbe 5848 ;; Move to start of next one.
58dd38f1
SM
5849 (unless (get-text-property (point) 'mouse-face)
5850 (goto-char (next-single-property-change (point) 'mouse-face nil end)))
5851 (setq n (1- n)))
5852 (while (and (< n 0) (not (bobp)))
5853 (let ((prop (get-text-property (1- (point)) 'mouse-face)))
5854 ;; If in a completion, move to the start of it.
5855 (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
b61a81c2 5856 (goto-char (previous-single-property-change
58dd38f1
SM
5857 (point) 'mouse-face nil beg)))
5858 ;; Move to end of the previous completion.
5859 (unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
5860 (goto-char (previous-single-property-change
5861 (point) 'mouse-face nil beg)))
5862 ;; Move to the start of that one.
5863 (goto-char (previous-single-property-change
5864 (point) 'mouse-face nil beg))
5865 (setq n (1+ n))))))
dde69dbe 5866
d5e63715
SM
5867(defun choose-completion (&optional event)
5868 "Choose the completion at point."
5869 (interactive (list last-nonmenu-event))
5870 ;; In case this is run via the mouse, give temporary modes such as
5871 ;; isearch a chance to turn off.
5872 (run-hooks 'mouse-leave-buffer-hook)
5873 (let (buffer base-size base-position choice)
5874 (with-current-buffer (window-buffer (posn-window (event-start event)))
5875 (setq buffer completion-reference-buffer)
5876 (setq base-size completion-base-size)
5877 (setq base-position completion-base-position)
5878 (save-excursion
5879 (goto-char (posn-point (event-start event)))
5880 (let (beg end)
5881 (if (and (not (eobp)) (get-text-property (point) 'mouse-face))
5882 (setq end (point) beg (1+ (point))))
5883 (if (and (not (bobp)) (get-text-property (1- (point)) 'mouse-face))
5884 (setq end (1- (point)) beg (point)))
5885 (if (null beg)
5886 (error "No completion here"))
5887 (setq beg (previous-single-property-change beg 'mouse-face))
5888 (setq end (or (next-single-property-change end 'mouse-face)
5889 (point-max)))
5890 (setq choice (buffer-substring-no-properties beg end)))))
5891
ab63960f 5892 (let ((owindow (selected-window)))
d5e63715 5893 (select-window (posn-window (event-start event)))
ab63960f 5894 (if (and (one-window-p t 'selected-frame)
d5e63715 5895 (window-dedicated-p (selected-window)))
ab63960f
RS
5896 ;; This is a special buffer's frame
5897 (iconify-frame (selected-frame))
5898 (or (window-dedicated-p (selected-window))
5899 (bury-buffer)))
8a7daef5
CY
5900 (select-window
5901 (or (and (buffer-live-p buffer)
d5e63715 5902 (get-buffer-window buffer 0))
8a7daef5 5903 owindow)))
f6714ede 5904
d5e63715
SM
5905 (choose-completion-string
5906 choice buffer
5907 (or base-position
5908 (when base-size
5909 ;; Someone's using old completion code that doesn't know
5910 ;; about base-position yet.
5911 (list (+ base-size (with-current-buffer buffer (field-beginning)))))
5912 ;; If all else fails, just guess.
5913 (with-current-buffer buffer
5914 (list (choose-completion-guess-base-position choice)))))))
80298193
RS
5915
5916;; Delete the longest partial match for STRING
5917;; that can be found before POINT.
d5e63715
SM
5918(defun choose-completion-guess-base-position (string)
5919 (save-excursion
5920 (let ((opoint (point))
5921 len)
5922 ;; Try moving back by the length of the string.
5923 (goto-char (max (- (point) (length string))
5924 (minibuffer-prompt-end)))
5925 ;; See how far back we were actually able to move. That is the
5926 ;; upper bound on how much we can match and delete.
5927 (setq len (- opoint (point)))
5928 (if completion-ignore-case
5929 (setq string (downcase string)))
5930 (while (and (> len 0)
5931 (let ((tail (buffer-substring (point) opoint)))
5932 (if completion-ignore-case
5933 (setq tail (downcase tail)))
5934 (not (string= tail (substring string 0 len)))))
5935 (setq len (1- len))
5936 (forward-char 1))
5937 (point))))
5938
80298193 5939(defun choose-completion-delete-max-match (string)
d5e63715
SM
5940 (delete-region (choose-completion-guess-base-position string) (point)))
5941(make-obsolete 'choose-completion-delete-max-match
5942 'choose-completion-guess-base-position "23.2")
80298193 5943
ba36181b 5944(defvar choose-completion-string-functions nil
bbbbb15b
KS
5945 "Functions that may override the normal insertion of a completion choice.
5946These functions are called in order with four arguments:
5947CHOICE - the string to insert in the buffer,
5948BUFFER - the buffer in which the choice should be inserted,
4837b516 5949MINI-P - non-nil if BUFFER is a minibuffer, and
12829a07
RS
5950BASE-SIZE - the number of characters in BUFFER before
5951the string being completed.
5952
bbbbb15b
KS
5953If a function in the list returns non-nil, that function is supposed
5954to have inserted the CHOICE in the BUFFER, and possibly exited
12829a07 5955the minibuffer; no further functions will be called.
ba36181b 5956
12829a07
RS
5957If all functions in the list return nil, that means to use
5958the default method of inserting the completion in BUFFER.")
74d0290b 5959
d5e63715 5960(defun choose-completion-string (choice &optional buffer base-position)
12829a07 5961 "Switch to BUFFER and insert the completion choice CHOICE.
d5e63715 5962BASE-POSITION, says where to insert the completion."
12829a07
RS
5963
5964 ;; If BUFFER is the minibuffer, exit the minibuffer
5965 ;; unless it is reading a file name and CHOICE is a directory,
5966 ;; or completion-no-auto-exit is non-nil.
5967
d5e63715
SM
5968 ;; Some older code may call us passing `base-size' instead of
5969 ;; `base-position'. It's difficult to make any use of `base-size',
5970 ;; so we just ignore it.
5971 (unless (consp base-position)
5972 (message "Obsolete `base-size' passed to choose-completion-string")
5973 (setq base-position nil))
5974
1a0d0b6a
JPW
5975 (let* ((buffer (or buffer completion-reference-buffer))
5976 (mini-p (minibufferp buffer)))
cf52ad58
RS
5977 ;; If BUFFER is a minibuffer, barf unless it's the currently
5978 ;; active minibuffer.
f436a90a 5979 (if (and mini-p
45486731
RS
5980 (or (not (active-minibuffer-window))
5981 (not (equal buffer
5982 (window-buffer (active-minibuffer-window))))))
cf52ad58 5983 (error "Minibuffer is not active for completion")
17aa3385
KS
5984 ;; Set buffer so buffer-local choose-completion-string-functions works.
5985 (set-buffer buffer)
f1180544 5986 (unless (run-hook-with-args-until-success
d99f8496 5987 'choose-completion-string-functions
d5e63715
SM
5988 ;; The fourth arg used to be `mini-p' but was useless
5989 ;; (since minibufferp can be used on the `buffer' arg)
5990 ;; and indeed unused. The last used to be `base-size', so we
5991 ;; keep it to try and avoid breaking old code.
5992 choice buffer base-position nil)
d99f8496 5993 ;; Insert the completion into the buffer where it was requested.
d5e63715
SM
5994 (delete-region (or (car base-position) (point))
5995 (or (cadr base-position) (point)))
bbbbb15b
KS
5996 (insert choice)
5997 (remove-text-properties (- (point) (length choice)) (point)
5998 '(mouse-face nil))
5999 ;; Update point in the window that BUFFER is showing in.
6000 (let ((window (get-buffer-window buffer t)))
6001 (set-window-point window (point)))
6002 ;; If completing for the minibuffer, exit it with this choice.
6003 (and (not completion-no-auto-exit)
6138158d 6004 (minibufferp buffer)
bbbbb15b
KS
6005 minibuffer-completion-table
6006 ;; If this is reading a file name, and the file name chosen
6007 ;; is a directory, don't exit the minibuffer.
85be9ec4
SM
6008 (let* ((result (buffer-substring (field-beginning) (point)))
6009 (bounds
6010 (completion-boundaries result minibuffer-completion-table
6011 minibuffer-completion-predicate
6012 "")))
6013 (if (eq (car bounds) (length result))
6014 ;; The completion chosen leads to a new set of completions
6015 ;; (e.g. it's a directory): don't exit the minibuffer yet.
6016 (let ((mini (active-minibuffer-window)))
6017 (select-window mini)
6018 (when minibuffer-auto-raise
6019 (raise-frame (window-frame mini))))
6020 (exit-minibuffer))))))))
80298193 6021
e2947429 6022(define-derived-mode completion-list-mode nil "Completion List"
e8a700bf 6023 "Major mode for buffers showing lists of possible completions.
80298193
RS
6024Type \\<completion-list-mode-map>\\[choose-completion] in the completion list\
6025 to select the completion near point.
6026Use \\<completion-list-mode-map>\\[mouse-choose-completion] to select one\
3a77346c
GM
6027 with the mouse.
6028
6029\\{completion-list-mode-map}"
e2947429 6030 (set (make-local-variable 'completion-base-size) nil))
e8a700bf 6031
c8d6d636
GM
6032(defun completion-list-mode-finish ()
6033 "Finish setup of the completions buffer.
6034Called from `temp-buffer-show-hook'."
6035 (when (eq major-mode 'completion-list-mode)
6036 (toggle-read-only 1)))
6037
6038(add-hook 'temp-buffer-show-hook 'completion-list-mode-finish)
6039
f5fab556
MY
6040
6041;; Variables and faces used in `completion-setup-function'.
747a0e2f 6042
d0fd0916
JPW
6043(defcustom completion-show-help t
6044 "Non-nil means show help message in *Completions* buffer."
6045 :type 'boolean
6046 :version "22.1"
6047 :group 'completion)
6048
f5fab556
MY
6049;; This function goes in completion-setup-hook, so that it is called
6050;; after the text of the completion list buffer is written.
e8a700bf 6051(defun completion-setup-function ()
1b5fd09e 6052 (let* ((mainbuf (current-buffer))
a9e3ff69
SM
6053 (base-dir
6054 ;; When reading a file name in the minibuffer,
6055 ;; try and find the right default-directory to set in the
6056 ;; completion list buffer.
6057 ;; FIXME: Why do we do that, actually? --Stef
6058 (if minibuffer-completing-file-name
6059 (file-name-as-directory
6060 (expand-file-name
6061 (substring (minibuffer-completion-contents)
6062 0 (or completion-base-size 0)))))))
621a3f62 6063 (with-current-buffer standard-output
d5e63715
SM
6064 (let ((base-size completion-base-size) ;Read before killing localvars.
6065 (base-position completion-base-position))
e2947429 6066 (completion-list-mode)
d5e63715
SM
6067 (set (make-local-variable 'completion-base-size) base-size)
6068 (set (make-local-variable 'completion-base-position) base-position))
1b5fd09e 6069 (set (make-local-variable 'completion-reference-buffer) mainbuf)
a9e3ff69 6070 (if base-dir (setq default-directory base-dir))
d0fd0916
JPW
6071 ;; Maybe insert help string.
6072 (when completion-show-help
6073 (goto-char (point-min))
6074 (if (display-mouse-p)
6075 (insert (substitute-command-keys
6076 "Click \\[mouse-choose-completion] on a completion to select it.\n")))
6077 (insert (substitute-command-keys
6078 "In this buffer, type \\[choose-completion] to \
6079select the completion near point.\n\n"))))))
c88ab9ce 6080
e8a700bf 6081(add-hook 'completion-setup-hook 'completion-setup-function)
dde69dbe 6082
1b5fd09e
SM
6083(define-key minibuffer-local-completion-map [prior] 'switch-to-completions)
6084(define-key minibuffer-local-completion-map "\M-v" 'switch-to-completions)
dde69dbe
RS
6085
6086(defun switch-to-completions ()
6087 "Select the completion list window."
6088 (interactive)
ab14d7d5 6089 (let ((window (or (get-buffer-window "*Completions*" 0)
042b7cc6 6090 ;; Make sure we have a completions window.
ab14d7d5
SM
6091 (progn (minibuffer-completion-help)
6092 (get-buffer-window "*Completions*" 0)))))
fdbd7c4d
KH
6093 (when window
6094 (select-window window)
042b7cc6
JL
6095 ;; In the new buffer, go to the first completion.
6096 ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
6097 (when (bobp)
6098 (next-completion 1)))))
f6039de6
JL
6099\f
6100;;; Support keyboard commands to turn on various modifiers.
82072f33
RS
6101
6102;; These functions -- which are not commands -- each add one modifier
6103;; to the following event.
6104
6105(defun event-apply-alt-modifier (ignore-prompt)
1e96c007 6106 "\\<function-key-map>Add the Alt modifier to the following event.
70cf9f08 6107For example, type \\[event-apply-alt-modifier] & to enter Alt-&."
82072f33
RS
6108 (vector (event-apply-modifier (read-event) 'alt 22 "A-")))
6109(defun event-apply-super-modifier (ignore-prompt)
1e96c007 6110 "\\<function-key-map>Add the Super modifier to the following event.
70cf9f08 6111For example, type \\[event-apply-super-modifier] & to enter Super-&."
82072f33
RS
6112 (vector (event-apply-modifier (read-event) 'super 23 "s-")))
6113(defun event-apply-hyper-modifier (ignore-prompt)
1e96c007 6114 "\\<function-key-map>Add the Hyper modifier to the following event.
70cf9f08 6115For example, type \\[event-apply-hyper-modifier] & to enter Hyper-&."
82072f33
RS
6116 (vector (event-apply-modifier (read-event) 'hyper 24 "H-")))
6117(defun event-apply-shift-modifier (ignore-prompt)
1e96c007 6118 "\\<function-key-map>Add the Shift modifier to the following event.
70cf9f08 6119For example, type \\[event-apply-shift-modifier] & to enter Shift-&."
82072f33
RS
6120 (vector (event-apply-modifier (read-event) 'shift 25 "S-")))
6121(defun event-apply-control-modifier (ignore-prompt)
1e96c007 6122 "\\<function-key-map>Add the Ctrl modifier to the following event.
70cf9f08 6123For example, type \\[event-apply-control-modifier] & to enter Ctrl-&."
82072f33
RS
6124 (vector (event-apply-modifier (read-event) 'control 26 "C-")))
6125(defun event-apply-meta-modifier (ignore-prompt)
1e96c007 6126 "\\<function-key-map>Add the Meta modifier to the following event.
70cf9f08 6127For example, type \\[event-apply-meta-modifier] & to enter Meta-&."
82072f33
RS
6128 (vector (event-apply-modifier (read-event) 'meta 27 "M-")))
6129
6130(defun event-apply-modifier (event symbol lshiftby prefix)
6131 "Apply a modifier flag to event EVENT.
6132SYMBOL is the name of this modifier, as a symbol.
6133LSHIFTBY is the numeric value of this modifier, in keyboard events.
6134PREFIX is the string that represents this modifier in an event type symbol."
6135 (if (numberp event)
6136 (cond ((eq symbol 'control)
90bebcb0
KH
6137 (if (and (<= (downcase event) ?z)
6138 (>= (downcase event) ?a))
82072f33 6139 (- (downcase event) ?a -1)
90bebcb0
KH
6140 (if (and (<= (downcase event) ?Z)
6141 (>= (downcase event) ?A))
82072f33
RS
6142 (- (downcase event) ?A -1)
6143 (logior (lsh 1 lshiftby) event))))
6144 ((eq symbol 'shift)
6145 (if (and (<= (downcase event) ?z)
6146 (>= (downcase event) ?a))
6147 (upcase event)
6148 (logior (lsh 1 lshiftby) event)))
6149 (t
6150 (logior (lsh 1 lshiftby) event)))
6151 (if (memq symbol (event-modifiers event))
6152 event
6153 (let ((event-type (if (symbolp event) event (car event))))
6154 (setq event-type (intern (concat prefix (symbol-name event-type))))
6155 (if (symbolp event)
6156 event-type
6157 (cons event-type (cdr event)))))))
6158
e5fff738
KH
6159(define-key function-key-map [?\C-x ?@ ?h] 'event-apply-hyper-modifier)
6160(define-key function-key-map [?\C-x ?@ ?s] 'event-apply-super-modifier)
6161(define-key function-key-map [?\C-x ?@ ?m] 'event-apply-meta-modifier)
6162(define-key function-key-map [?\C-x ?@ ?a] 'event-apply-alt-modifier)
6163(define-key function-key-map [?\C-x ?@ ?S] 'event-apply-shift-modifier)
6164(define-key function-key-map [?\C-x ?@ ?c] 'event-apply-control-modifier)
f6039de6 6165\f
a3d1480b
JB
6166;;;; Keypad support.
6167
9b77469a
SM
6168;; Make the keypad keys act like ordinary typing keys. If people add
6169;; bindings for the function key symbols, then those bindings will
6170;; override these, so this shouldn't interfere with any existing
6171;; bindings.
a3d1480b 6172
0d173134 6173;; Also tell read-char how to handle these keys.
e1e04350 6174(mapc
a3d1480b
JB
6175 (lambda (keypad-normal)
6176 (let ((keypad (nth 0 keypad-normal))
6177 (normal (nth 1 keypad-normal)))
0d173134 6178 (put keypad 'ascii-character normal)
a3d1480b
JB
6179 (define-key function-key-map (vector keypad) (vector normal))))
6180 '((kp-0 ?0) (kp-1 ?1) (kp-2 ?2) (kp-3 ?3) (kp-4 ?4)
6181 (kp-5 ?5) (kp-6 ?6) (kp-7 ?7) (kp-8 ?8) (kp-9 ?9)
f33321ad 6182 (kp-space ?\s)
a3d1480b
JB
6183 (kp-tab ?\t)
6184 (kp-enter ?\r)
6185 (kp-multiply ?*)
6186 (kp-add ?+)
6187 (kp-separator ?,)
6188 (kp-subtract ?-)
6189 (kp-decimal ?.)
6190 (kp-divide ?/)
31cd2dd4
SM
6191 (kp-equal ?=)
6192 ;; Do the same for various keys that are represented as symbols under
6193 ;; GUIs but naturally correspond to characters.
6194 (backspace 127)
6195 (delete 127)
6196 (tab ?\t)
6197 (linefeed ?\n)
6198 (clear ?\C-l)
6199 (return ?\C-m)
6200 (escape ?\e)
6201 ))
f54b0d85 6202\f
1e722f9f 6203;;;;
b005abd5 6204;;;; forking a twin copy of a buffer.
1e722f9f 6205;;;;
b005abd5
SM
6206
6207(defvar clone-buffer-hook nil
6208 "Normal hook to run in the new buffer at the end of `clone-buffer'.")
6209
64663f06
SM
6210(defvar clone-indirect-buffer-hook nil
6211 "Normal hook to run in the new buffer at the end of `clone-indirect-buffer'.")
6212
b005abd5
SM
6213(defun clone-process (process &optional newname)
6214 "Create a twin copy of PROCESS.
6215If NEWNAME is nil, it defaults to PROCESS' name;
6216NEWNAME is modified by adding or incrementing <N> at the end as necessary.
6217If PROCESS is associated with a buffer, the new process will be associated
6218 with the current buffer instead.
6219Returns nil if PROCESS has already terminated."
6220 (setq newname (or newname (process-name process)))
6221 (if (string-match "<[0-9]+>\\'" newname)
6222 (setq newname (substring newname 0 (match-beginning 0))))
6223 (when (memq (process-status process) '(run stop open))
6224 (let* ((process-connection-type (process-tty-name process))
b005abd5
SM
6225 (new-process
6226 (if (memq (process-status process) '(open))
ed7069af
KS
6227 (let ((args (process-contact process t)))
6228 (setq args (plist-put args :name newname))
6229 (setq args (plist-put args :buffer
403ca8d9
KS
6230 (if (process-buffer process)
6231 (current-buffer))))
ed7069af 6232 (apply 'make-network-process args))
b005abd5
SM
6233 (apply 'start-process newname
6234 (if (process-buffer process) (current-buffer))
6235 (process-command process)))))
ed7069af
KS
6236 (set-process-query-on-exit-flag
6237 new-process (process-query-on-exit-flag process))
b005abd5
SM
6238 (set-process-inherit-coding-system-flag
6239 new-process (process-inherit-coding-system-flag process))
6240 (set-process-filter new-process (process-filter process))
6241 (set-process-sentinel new-process (process-sentinel process))
403ca8d9 6242 (set-process-plist new-process (copy-sequence (process-plist process)))
b005abd5
SM
6243 new-process)))
6244
b75b82ab 6245;; things to maybe add (currently partly covered by `funcall mode'):
b005abd5
SM
6246;; - syntax-table
6247;; - overlays
6248(defun clone-buffer (&optional newname display-flag)
6b61353c
KH
6249 "Create and return a twin copy of the current buffer.
6250Unlike an indirect buffer, the new buffer can be edited
6251independently of the old one (if it is not read-only).
6252NEWNAME is the name of the new buffer. It may be modified by
6253adding or incrementing <N> at the end as necessary to create a
6254unique buffer name. If nil, it defaults to the name of the
6255current buffer, with the proper suffix. If DISPLAY-FLAG is
6256non-nil, the new buffer is shown with `pop-to-buffer'. Trying to
6257clone a file-visiting buffer, or a buffer whose major mode symbol
6258has a non-nil `no-clone' property, results in an error.
6259
6260Interactively, DISPLAY-FLAG is t and NEWNAME is the name of the
6261current buffer with appropriate suffix. However, if a prefix
6262argument is given, then the command prompts for NEWNAME in the
6263minibuffer.
b005abd5 6264
b005abd5
SM
6265This runs the normal hook `clone-buffer-hook' in the new buffer
6266after it has been set up properly in other respects."
61acfe7f
RS
6267 (interactive
6268 (progn
6269 (if buffer-file-name
6270 (error "Cannot clone a file-visiting buffer"))
6271 (if (get major-mode 'no-clone)
6272 (error "Cannot clone a buffer in %s mode" mode-name))
f6039de6
JL
6273 (list (if current-prefix-arg
6274 (read-buffer "Name of new cloned buffer: " (current-buffer)))
61acfe7f 6275 t)))
b005abd5
SM
6276 (if buffer-file-name
6277 (error "Cannot clone a file-visiting buffer"))
6278 (if (get major-mode 'no-clone)
6279 (error "Cannot clone a buffer in %s mode" mode-name))
6280 (setq newname (or newname (buffer-name)))
6281 (if (string-match "<[0-9]+>\\'" newname)
6282 (setq newname (substring newname 0 (match-beginning 0))))
6283 (let ((buf (current-buffer))
6284 (ptmin (point-min))
6285 (ptmax (point-max))
6286 (pt (point))
6287 (mk (if mark-active (mark t)))
6288 (modified (buffer-modified-p))
6289 (mode major-mode)
6290 (lvars (buffer-local-variables))
6291 (process (get-buffer-process (current-buffer)))
6292 (new (generate-new-buffer (or newname (buffer-name)))))
6293 (save-restriction
6294 (widen)
6295 (with-current-buffer new
6296 (insert-buffer-substring buf)))
6297 (with-current-buffer new
6298 (narrow-to-region ptmin ptmax)
6299 (goto-char pt)
6300 (if mk (set-mark mk))
6301 (set-buffer-modified-p modified)
6302
6303 ;; Clone the old buffer's process, if any.
6304 (when process (clone-process process))
6305
6306 ;; Now set up the major mode.
6307 (funcall mode)
6308
6309 ;; Set up other local variables.
9ca2204b
JB
6310 (mapc (lambda (v)
6311 (condition-case () ;in case var is read-only
6312 (if (symbolp v)
6313 (makunbound v)
6314 (set (make-local-variable (car v)) (cdr v)))
6315 (error nil)))
6316 lvars)
b005abd5
SM
6317
6318 ;; Run any hooks (typically set up by the major mode
6319 ;; for cloning to work properly).
6320 (run-hooks 'clone-buffer-hook))
0a487199
SM
6321 (if display-flag
6322 ;; Presumably the current buffer is shown in the selected frame, so
6323 ;; we want to display the clone elsewhere.
6324 (let ((same-window-regexps nil)
6325 (same-window-buffer-names))
6326 (pop-to-buffer new)))
b005abd5
SM
6327 new))
6328
fa65f20b 6329
7e3afb04 6330(defun clone-indirect-buffer (newname display-flag &optional norecord)
fa65f20b
GM
6331 "Create an indirect buffer that is a twin copy of the current buffer.
6332
01ba9662 6333Give the indirect buffer name NEWNAME. Interactively, read NEWNAME
fa65f20b
GM
6334from the minibuffer when invoked with a prefix arg. If NEWNAME is nil
6335or if not called with a prefix arg, NEWNAME defaults to the current
6336buffer's name. The name is modified by adding a `<N>' suffix to it
1d2b0303
JB
6337or by incrementing the N in an existing suffix. Trying to clone a
6338buffer whose major mode symbol has a non-nil `no-clone-indirect'
6339property results in an error.
fa65f20b
GM
6340
6341DISPLAY-FLAG non-nil means show the new buffer with `pop-to-buffer'.
7e3afb04
GM
6342This is always done when called interactively.
6343
f33321ad 6344Optional third arg NORECORD non-nil means do not put this buffer at the
7e3afb04 6345front of the list of recently selected ones."
61acfe7f
RS
6346 (interactive
6347 (progn
6348 (if (get major-mode 'no-clone-indirect)
6349 (error "Cannot indirectly clone a buffer in %s mode" mode-name))
6350 (list (if current-prefix-arg
f6039de6 6351 (read-buffer "Name of indirect buffer: " (current-buffer)))
61acfe7f
RS
6352 t)))
6353 (if (get major-mode 'no-clone-indirect)
6354 (error "Cannot indirectly clone a buffer in %s mode" mode-name))
fa65f20b
GM
6355 (setq newname (or newname (buffer-name)))
6356 (if (string-match "<[0-9]+>\\'" newname)
6357 (setq newname (substring newname 0 (match-beginning 0))))
6358 (let* ((name (generate-new-buffer-name newname))
6359 (buffer (make-indirect-buffer (current-buffer) name t)))
64663f06
SM
6360 (with-current-buffer buffer
6361 (run-hooks 'clone-indirect-buffer-hook))
fa65f20b 6362 (when display-flag
58dd38f1 6363 (pop-to-buffer buffer norecord))
fa65f20b
GM
6364 buffer))
6365
6366
1fffd65f
RS
6367(defun clone-indirect-buffer-other-window (newname display-flag &optional norecord)
6368 "Like `clone-indirect-buffer' but display in another window."
2ef0a47e
RS
6369 (interactive
6370 (progn
6371 (if (get major-mode 'no-clone-indirect)
6372 (error "Cannot indirectly clone a buffer in %s mode" mode-name))
6373 (list (if current-prefix-arg
f6039de6 6374 (read-buffer "Name of indirect buffer: " (current-buffer)))
2ef0a47e 6375 t)))
acd39eb6 6376 (let ((pop-up-windows t))
1fffd65f 6377 (clone-indirect-buffer newname display-flag norecord)))
7e3afb04 6378
f54b0d85 6379\f
1d4b11bf
GM
6380;;; Handling of Backspace and Delete keys.
6381
30a2fded 6382(defcustom normal-erase-is-backspace 'maybe
3784ec80 6383 "Set the default behavior of the Delete and Backspace keys.
30a2fded
KL
6384
6385If set to t, Delete key deletes forward and Backspace key deletes
6386backward.
6387
6388If set to nil, both Delete and Backspace keys delete backward.
6389
6390If set to 'maybe (which is the default), Emacs automatically
3784ec80 6391selects a behavior. On window systems, the behavior depends on
30a2fded
KL
6392the keyboard used. If the keyboard has both a Backspace key and
6393a Delete key, and both are mapped to their usual meanings, the
6394option's default value is set to t, so that Backspace can be used
6395to delete backward, and Delete can be used to delete forward.
6396
6397If not running under a window system, customizing this option
6398accomplishes a similar effect by mapping C-h, which is usually
6399generated by the Backspace key, to DEL, and by mapping DEL to C-d
6400via `keyboard-translate'. The former functionality of C-h is
6401available on the F1 key. You should probably not use this
6402setting if you don't have both Backspace, Delete and F1 keys.
f060b834
GM
6403
6404Setting this variable with setq doesn't take effect. Programmatically,
7f62656b 6405call `normal-erase-is-backspace-mode' (which see) instead."
30a2fded
KL
6406 :type '(choice (const :tag "Off" nil)
6407 (const :tag "Maybe" maybe)
6408 (other :tag "On" t))
1d4b11bf
GM
6409 :group 'editing-basics
6410 :version "21.1"
6411 :set (lambda (symbol value)
6412 ;; The fboundp is because of a problem with :set when
6413 ;; dumping Emacs. It doesn't really matter.
7f62656b
EZ
6414 (if (fboundp 'normal-erase-is-backspace-mode)
6415 (normal-erase-is-backspace-mode (or value 0))
1d4b11bf
GM
6416 (set-default symbol value))))
6417
30a2fded
KL
6418(defun normal-erase-is-backspace-setup-frame (&optional frame)
6419 "Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
6420 (unless frame (setq frame (selected-frame)))
6421 (with-selected-frame frame
ed8dad6b 6422 (unless (terminal-parameter nil 'normal-erase-is-backspace)
08ea6d2f
SM
6423 (normal-erase-is-backspace-mode
6424 (if (if (eq normal-erase-is-backspace 'maybe)
6425 (and (not noninteractive)
6426 (or (memq system-type '(ms-dos windows-nt))
08ea6d2f
SM
6427 (and (memq window-system '(x))
6428 (fboundp 'x-backspace-delete-keys-p)
6429 (x-backspace-delete-keys-p))
6430 ;; If the terminal Emacs is running on has erase char
6431 ;; set to ^H, use the Backspace key for deleting
6432 ;; backward, and the Delete key for deleting forward.
6433 (and (null window-system)
6434 (eq tty-erase-char ?\^H))))
6435 normal-erase-is-backspace)
6436 1 0)))))
1d4b11bf 6437
7f62656b
EZ
6438(defun normal-erase-is-backspace-mode (&optional arg)
6439 "Toggle the Erase and Delete mode of the Backspace and Delete keys.
6440
1d2b0303 6441With numeric ARG, turn the mode on if and only if ARG is positive.
7f62656b 6442
30a2fded
KL
6443On window systems, when this mode is on, Delete is mapped to C-d
6444and Backspace is mapped to DEL; when this mode is off, both
6445Delete and Backspace are mapped to DEL. (The remapping goes via
6446`local-function-key-map', so binding Delete or Backspace in the
6447global or local keymap will override that.)
7f62656b
EZ
6448
6449In addition, on window systems, the bindings of C-Delete, M-Delete,
6450C-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in
6451the global keymap in accordance with the functionality of Delete and
6452Backspace. For example, if Delete is remapped to C-d, which deletes
6453forward, C-Delete is bound to `kill-word', but if Delete is remapped
6454to DEL, which deletes backward, C-Delete is bound to
6455`backward-kill-word'.
6456
6457If not running on a window system, a similar effect is accomplished by
6458remapping C-h (normally produced by the Backspace key) and DEL via
6459`keyboard-translate': if this mode is on, C-h is mapped to DEL and DEL
6460to C-d; if it's off, the keys are not remapped.
6461
6462When not running on a window system, and this mode is turned on, the
6463former functionality of C-h is available on the F1 key. You should
6464probably not turn on this mode on a text-only terminal if you don't
6465have both Backspace, Delete and F1 keys.
6466
6467See also `normal-erase-is-backspace'."
1d4b11bf 6468 (interactive "P")
0103b7c9 6469 (let ((enabled (or (and arg (> (prefix-numeric-value arg) 0))
85be9ec4
SM
6470 (not (or arg
6471 (eq 1 (terminal-parameter
0103b7c9
KL
6472 nil 'normal-erase-is-backspace)))))))
6473 (set-terminal-parameter nil 'normal-erase-is-backspace
6474 (if enabled 1 0))
6475
9e2a2647 6476 (cond ((or (memq window-system '(x w32 ns pc))
0103b7c9
KL
6477 (memq system-type '(ms-dos windows-nt)))
6478 (let* ((bindings
411c0104 6479 `(([M-delete] [M-backspace])
0103b7c9 6480 ([C-M-delete] [C-M-backspace])
28a90c44 6481 ([?\e C-delete] [?\e C-backspace])))
0103b7c9
KL
6482 (old-state (lookup-key local-function-key-map [delete])))
6483
6484 (if enabled
6485 (progn
6486 (define-key local-function-key-map [delete] [?\C-d])
6487 (define-key local-function-key-map [kp-delete] [?\C-d])
28a90c44
SM
6488 (define-key local-function-key-map [backspace] [?\C-?])
6489 (dolist (b bindings)
6490 ;; Not sure if input-decode-map is really right, but
6491 ;; keyboard-translate-table (used below) only works
6492 ;; for integer events, and key-translation-table is
6493 ;; global (like the global-map, used earlier).
6494 (define-key input-decode-map (car b) nil)
6495 (define-key input-decode-map (cadr b) nil)))
0103b7c9
KL
6496 (define-key local-function-key-map [delete] [?\C-?])
6497 (define-key local-function-key-map [kp-delete] [?\C-?])
28a90c44
SM
6498 (define-key local-function-key-map [backspace] [?\C-?])
6499 (dolist (b bindings)
6500 (define-key input-decode-map (car b) (cadr b))
6501 (define-key input-decode-map (cadr b) (car b))))))
0103b7c9
KL
6502 (t
6503 (if enabled
ec9f4754 6504 (progn
0103b7c9
KL
6505 (keyboard-translate ?\C-h ?\C-?)
6506 (keyboard-translate ?\C-? ?\C-d))
6507 (keyboard-translate ?\C-h ?\C-h)
6508 (keyboard-translate ?\C-? ?\C-?))))
6509
6510 (run-hooks 'normal-erase-is-backspace-hook)
32226619 6511 (if (called-interactively-p 'interactive)
0103b7c9 6512 (message "Delete key deletes %s"
b08016f2 6513 (if (eq 1 (terminal-parameter nil 'normal-erase-is-backspace))
0103b7c9 6514 "forward" "backward")))))
ea82f0df 6515\f
aca8bee5 6516(defvar vis-mode-saved-buffer-invisibility-spec nil
0f7df535 6517 "Saved value of `buffer-invisibility-spec' when Visible mode is on.")
7f62656b 6518
0f7df535
RS
6519(define-minor-mode visible-mode
6520 "Toggle Visible mode.
4837b516
GM
6521With argument ARG turn Visible mode on if ARG is positive, otherwise
6522turn it off.
1d4b11bf 6523
0f7df535 6524Enabling Visible mode makes all invisible text temporarily visible.
1d2b0303
JB
6525Disabling Visible mode turns off that effect. Visible mode works by
6526saving the value of `buffer-invisibility-spec' and setting it to nil."
4e57881d 6527 :lighter " Vis"
ab77efd0 6528 :group 'editing-basics
aca8bee5
SM
6529 (when (local-variable-p 'vis-mode-saved-buffer-invisibility-spec)
6530 (setq buffer-invisibility-spec vis-mode-saved-buffer-invisibility-spec)
6531 (kill-local-variable 'vis-mode-saved-buffer-invisibility-spec))
0f7df535 6532 (when visible-mode
aca8bee5
SM
6533 (set (make-local-variable 'vis-mode-saved-buffer-invisibility-spec)
6534 buffer-invisibility-spec)
6535 (setq buffer-invisibility-spec nil)))
4e57881d 6536\f
30ee26a9 6537;; Partial application of functions (similar to "currying").
a185548b 6538;; This function is here rather than in subr.el because it uses CL.
30ee26a9
EZ
6539(defun apply-partially (fun &rest args)
6540 "Return a function that is a partial application of FUN to ARGS.
6541ARGS is a list of the first N arguments to pass to FUN.
6542The result is a new function which does the same as FUN, except that
6543the first N arguments are fixed at the values with which this function
6544was called."
6545 (lexical-let ((fun fun) (args1 args))
6546 (lambda (&rest args2) (apply fun (append args1 args2)))))
a185548b
SM
6547
6548;; This function is here rather than in subr.el because it uses CL.
6549(defmacro with-wrapper-hook (var args &rest body)
6550 "Run BODY wrapped with the VAR hook.
6551VAR is a special hook: its functions are called with a first argument
6552which is the \"original\" code (the BODY), so the hook function can wrap
6553the original function, or call it any number of times (including not calling
6554it at all). This is similar to an `around' advice.
6555VAR is normally a symbol (a variable) in which case it is treated like
6556a hook, with a buffer-local and a global part. But it can also be an
6557arbitrary expression.
6558ARGS is a list of variables which will be passed as additional arguments
fa5f7c5f 6559to each function, after the initial argument, and which the first argument
a185548b
SM
6560expects to receive when called."
6561 (declare (indent 2) (debug t))
6562 ;; We need those two gensyms because CL's lexical scoping is not available
6563 ;; for function arguments :-(
6564 (let ((funs (make-symbol "funs"))
6565 (global (make-symbol "global"))
6566 (argssym (make-symbol "args")))
6567 ;; Since the hook is a wrapper, the loop has to be done via
6568 ;; recursion: a given hook function will call its parameter in order to
6569 ;; continue looping.
6570 `(labels ((runrestofhook (,funs ,global ,argssym)
6571 ;; `funs' holds the functions left on the hook and `global'
6572 ;; holds the functions left on the global part of the hook
6573 ;; (in case the hook is local).
6574 (lexical-let ((funs ,funs)
6575 (global ,global))
6576 (if (consp funs)
6577 (if (eq t (car funs))
8c22699f
SM
6578 (runrestofhook
6579 (append global (cdr funs)) nil ,argssym)
a185548b 6580 (apply (car funs)
8c22699f
SM
6581 (lambda (&rest ,argssym)
6582 (runrestofhook (cdr funs) global ,argssym))
a185548b
SM
6583 ,argssym))
6584 ;; Once there are no more functions on the hook, run
6585 ;; the original body.
6586 (apply (lambda ,args ,@body) ,argssym)))))
6587 (runrestofhook ,var
6588 ;; The global part of the hook, if any.
6589 ,(if (symbolp var)
6590 `(if (local-variable-p ',var)
6591 (default-value ',var)))
6592 (list ,@args)))))
30ee26a9 6593\f
e1e04350 6594;; Minibuffer prompt stuff.
9b350152 6595
49c14a05
GM
6596;(defun minibuffer-prompt-modification (start end)
6597; (error "You cannot modify the prompt"))
6598;
6599;
6600;(defun minibuffer-prompt-insertion (start end)
6601; (let ((inhibit-modification-hooks t))
6602; (delete-region start end)
6603; ;; Discard undo information for the text insertion itself
6604; ;; and for the text deletion.above.
6605; (when (consp buffer-undo-list)
6606; (setq buffer-undo-list (cddr buffer-undo-list)))
6607; (message "You cannot modify the prompt")))
6608;
6609;
f1180544 6610;(setq minibuffer-prompt-properties
49c14a05
GM
6611; (list 'modification-hooks '(minibuffer-prompt-modification)
6612; 'insert-in-front-hooks '(minibuffer-prompt-insertion)))
f1180544 6613;
9b350152 6614
a2603048
GM
6615\f
6616;;;; Problematic external packages.
6617
6618;; rms says this should be done by specifying symbols that define
6619;; versions together with bad values. This is therefore not as
6620;; flexible as it could be. See the thread:
6621;; http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00300.html
6622(defconst bad-packages-alist
6623 ;; Not sure exactly which semantic versions have problems.
6624 ;; Definitely 2.0pre3, probably all 2.0pre's before this.
7796ee61 6625 '((semantic semantic-version "\\`2\\.0pre[1-3]\\'"
a2603048 6626 "The version of `semantic' loaded does not work in Emacs 22.
72d595b5
GM
6627It can cause constant high CPU load.
6628Upgrade to at least Semantic 2.0pre4 (distributed with CEDET 1.0pre4).")
a2603048
GM
6629 ;; CUA-mode does not work with GNU Emacs version 22.1 and newer.
6630 ;; Except for version 1.2, all of the 1.x and 2.x version of cua-mode
6631 ;; provided the `CUA-mode' feature. Since this is no longer true,
6632 ;; we can warn the user if the `CUA-mode' feature is ever provided.
6633 (CUA-mode t nil
6634"CUA-mode is now part of the standard GNU Emacs distribution,
6635so you can now enable CUA via the Options menu or by customizing `cua-mode'.
6636
6637You have loaded an older version of CUA-mode which does not work
6638correctly with this version of Emacs. You should remove the old
6639version and use the one distributed with Emacs."))
6640 "Alist of packages known to cause problems in this version of Emacs.
6641Each element has the form (PACKAGE SYMBOL REGEXP STRING).
6642PACKAGE is either a regular expression to match file names, or a
6643symbol (a feature name); see the documentation of
6644`after-load-alist', to which this variable adds functions.
6645SYMBOL is either the name of a string variable, or `t'. Upon
6646loading PACKAGE, if SYMBOL is t or matches REGEXP, display a
6647warning using STRING as the message.")
6648
6649(defun bad-package-check (package)
6650 "Run a check using the element from `bad-packages-alist' matching PACKAGE."
6651 (condition-case nil
6652 (let* ((list (assoc package bad-packages-alist))
6653 (symbol (nth 1 list)))
6654 (and list
6655 (boundp symbol)
6656 (or (eq symbol t)
6657 (and (stringp (setq symbol (eval symbol)))
9bc505ab
JB
6658 (string-match-p (nth 2 list) symbol)))
6659 (display-warning package (nth 3 list) :warning)))
a2603048
GM
6660 (error nil)))
6661
6662(mapc (lambda (elem)
6663 (eval-after-load (car elem) `(bad-package-check ',(car elem))))
6664 bad-packages-alist)
6665
6666
00398e3b 6667(provide 'simple)
6b61353c 6668
621a3f62 6669;; arch-tag: 24af67c0-2a49-44f6-b3b1-312d8b570dfd
c88ab9ce 6670;;; simple.el ends here