475
|
1 ;; Basic editing commands for Emacs
|
|
2 ;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
|
|
3
|
|
4 ;; This file is part of GNU Emacs.
|
|
5
|
|
6 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
7 ;; it under the terms of the GNU General Public License as published by
|
|
8 ;; the Free Software Foundation; either version 1, or (at your option)
|
|
9 ;; any later version.
|
|
10
|
|
11 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 ;; GNU General Public License for more details.
|
|
15
|
|
16 ;; You should have received a copy of the GNU General Public License
|
|
17 ;; along with GNU Emacs; see the file COPYING. If not, write to
|
|
18 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
19
|
|
20
|
|
21 (defun open-line (arg)
|
|
22 "Insert a newline and leave point before it. If there is a fill
|
|
23 prefix, inserts the fill prefix after the newline that it inserts.
|
|
24 With arg, inserts that many newlines."
|
|
25 (interactive "*p")
|
|
26 (let ((flag (and (bolp) (not (bobp)))))
|
|
27 (if flag (forward-char -1))
|
|
28 (while (> arg 0)
|
|
29 (save-excursion
|
|
30 (insert ?\n)
|
|
31 (if fill-prefix (insert fill-prefix)))
|
|
32 (setq arg (1- arg)))
|
|
33 (if flag (forward-char 1))))
|
|
34
|
|
35 (defun split-line ()
|
|
36 "Split current line, moving portion beyond point vertically down."
|
|
37 (interactive "*")
|
|
38 (skip-chars-forward " \t")
|
|
39 (let ((col (current-column))
|
|
40 (pos (point)))
|
|
41 (insert ?\n)
|
|
42 (indent-to col 0)
|
|
43 (goto-char pos)))
|
|
44
|
|
45 (defun quoted-insert (arg)
|
|
46 "Read next input character and insert it.
|
|
47 Useful for inserting control characters.
|
|
48 You may also type up to 3 octal digits, to insert a character with that code"
|
|
49 (interactive "*p")
|
|
50 (let ((char (read-quoted-char)))
|
|
51 (while (> arg 0)
|
|
52 (insert char)
|
|
53 (setq arg (1- arg)))))
|
|
54
|
|
55 (defun delete-indentation (&optional arg)
|
|
56 "Join this line to previous and fix up whitespace at join.
|
|
57 With argument, join this line to following line."
|
|
58 (interactive "*P")
|
|
59 (beginning-of-line)
|
|
60 (if arg (forward-line 1))
|
|
61 (if (eq (preceding-char) ?\n)
|
|
62 (progn
|
|
63 (delete-region (point) (1- (point)))
|
|
64 (fixup-whitespace))))
|
|
65
|
|
66 (defun fixup-whitespace ()
|
|
67 "Fixup white space between objects around point.
|
|
68 Leave one space or none, according to the context."
|
|
69 (interactive "*")
|
|
70 (save-excursion
|
|
71 (delete-horizontal-space)
|
|
72 (if (or (looking-at "^\\|\\s)")
|
|
73 (save-excursion (forward-char -1)
|
|
74 (looking-at "$\\|\\s(\\|\\s'")))
|
|
75 nil
|
|
76 (insert ?\ ))))
|
|
77
|
|
78 (defun delete-horizontal-space ()
|
|
79 "Delete all spaces and tabs around point."
|
|
80 (interactive "*")
|
|
81 (skip-chars-backward " \t")
|
|
82 (delete-region (point) (progn (skip-chars-forward " \t") (point))))
|
|
83
|
|
84 (defun just-one-space ()
|
|
85 "Delete all spaces and tabs around point, leaving one space."
|
|
86 (interactive "*")
|
|
87 (skip-chars-backward " \t")
|
|
88 (if (= (following-char) ? )
|
|
89 (forward-char 1)
|
|
90 (insert ? ))
|
|
91 (delete-region (point) (progn (skip-chars-forward " \t") (point))))
|
|
92
|
|
93 (defun delete-blank-lines ()
|
|
94 "On blank line, delete all surrounding blank lines, leaving just one.
|
|
95 On isolated blank line, delete that one.
|
|
96 On nonblank line, delete all blank lines that follow it."
|
|
97 (interactive "*")
|
|
98 (let (thisblank singleblank)
|
|
99 (save-excursion
|
|
100 (beginning-of-line)
|
|
101 (setq thisblank (looking-at "[ \t]*$"))
|
|
102 (setq singleblank
|
|
103 (and thisblank
|
|
104 (not (looking-at "[ \t]*\n[ \t]*$"))
|
|
105 (or (bobp)
|
|
106 (progn (forward-line -1)
|
|
107 (not (looking-at "[ \t]*$")))))))
|
|
108 (if thisblank
|
|
109 (progn
|
|
110 (beginning-of-line)
|
|
111 (if singleblank (forward-line 1))
|
|
112 (delete-region (point)
|
|
113 (if (re-search-backward "[^ \t\n]" nil t)
|
|
114 (progn (forward-line 1) (point))
|
|
115 (point-min)))))
|
|
116 (if (not (and thisblank singleblank))
|
|
117 (save-excursion
|
|
118 (end-of-line)
|
|
119 (forward-line 1)
|
|
120 (delete-region (point)
|
|
121 (if (re-search-forward "[^ \t\n]" nil t)
|
|
122 (progn (beginning-of-line) (point))
|
|
123 (point-max)))))))
|
|
124
|
|
125 (defun back-to-indentation ()
|
|
126 "Move point to the first non-whitespace character on this line."
|
|
127 (interactive)
|
|
128 (beginning-of-line 1)
|
|
129 (skip-chars-forward " \t"))
|
|
130
|
|
131 (defun newline-and-indent ()
|
|
132 "Insert a newline, then indent according to major mode.
|
|
133 Indentation is done using the current indent-line-function.
|
|
134 In programming language modes, this is the same as TAB.
|
|
135 In some text modes, where TAB inserts a tab, this indents to the
|
|
136 specified left-margin column."
|
|
137 (interactive "*")
|
|
138 (delete-region (point) (progn (skip-chars-backward " \t") (point)))
|
|
139 (insert ?\n)
|
|
140 (indent-according-to-mode))
|
|
141
|
|
142 (defun reindent-then-newline-and-indent ()
|
|
143 "Reindent current line, insert newline, then indent the new line.
|
|
144 Indentation of both lines is done according to the current major mode,
|
|
145 which means that the current value of indent-line-function is called.
|
|
146 In programming language modes, this is the same as TAB.
|
|
147 In some text modes, where TAB inserts a tab, this indents to the
|
|
148 specified left-margin column."
|
|
149 (interactive "*")
|
|
150 (save-excursion
|
|
151 (delete-region (point) (progn (skip-chars-backward " \t") (point)))
|
|
152 (indent-according-to-mode))
|
|
153 (insert ?\n)
|
|
154 (indent-according-to-mode))
|
|
155
|
|
156 ;; Internal subroutine of delete-char
|
|
157 (defun kill-forward-chars (arg)
|
|
158 (if (listp arg) (setq arg (car arg)))
|
|
159 (if (eq arg '-) (setq arg -1))
|
|
160 (kill-region (point) (+ (point) arg)))
|
|
161
|
|
162 ;; Internal subroutine of backward-delete-char
|
|
163 (defun kill-backward-chars (arg)
|
|
164 (if (listp arg) (setq arg (car arg)))
|
|
165 (if (eq arg '-) (setq arg -1))
|
|
166 (kill-region (point) (- (point) arg)))
|
|
167
|
|
168 (defun backward-delete-char-untabify (arg &optional killp)
|
|
169 "Delete characters backward, changing tabs into spaces.
|
|
170 Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
|
|
171 Interactively, ARG is the prefix arg (default 1)
|
|
172 and KILLP is t if prefix arg is was specified."
|
|
173 (interactive "*p\nP")
|
|
174 (let ((count arg))
|
|
175 (save-excursion
|
|
176 (while (and (> count 0) (not (bobp)))
|
|
177 (if (= (preceding-char) ?\t)
|
|
178 (let ((col (current-column)))
|
|
179 (forward-char -1)
|
|
180 (setq col (- col (current-column)))
|
|
181 (insert-char ?\ col)
|
|
182 (delete-char 1)))
|
|
183 (forward-char -1)
|
|
184 (setq count (1- count)))))
|
|
185 (delete-backward-char arg killp)
|
|
186 ;; In overwrite mode, back over columns while clearing them out,
|
|
187 ;; unless at end of line.
|
|
188 (and overwrite-mode (not (eolp))
|
|
189 (save-excursion (insert-char ?\ arg))))
|
|
190
|
|
191 (defun zap-to-char (arg char)
|
|
192 "Kill up to and including ARG'th occurrence of CHAR.
|
|
193 Goes backward if ARG is negative; error if CHAR not found."
|
|
194 (interactive "p\ncZap to char: ")
|
|
195 (kill-region (point) (progn
|
|
196 (search-forward (char-to-string char) nil nil arg)
|
|
197 ; (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
|
|
198 (point))))
|
|
199
|
|
200 (defun beginning-of-buffer (&optional arg)
|
|
201 "Move point to the beginning of the buffer; leave mark at previous position.
|
|
202 With arg N, put point N/10 of the way from the true beginning.
|
|
203 Don't use this in Lisp programs!
|
|
204 \(goto-char (point-min)) is faster and avoids clobbering the mark."
|
|
205 (interactive "P")
|
|
206 (push-mark)
|
|
207 (goto-char (if arg
|
|
208 (if (> (buffer-size) 10000)
|
|
209 ;; Avoid overflow for large buffer sizes!
|
|
210 (* (prefix-numeric-value arg)
|
|
211 (/ (buffer-size) 10))
|
|
212 (/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10))
|
|
213 (point-min)))
|
|
214 (if arg (forward-line 1)))
|
|
215
|
|
216 (defun end-of-buffer (&optional arg)
|
|
217 "Move point to the end of the buffer; leave mark at previous position.
|
|
218 With arg N, put point N/10 of the way from the true end.
|
|
219 Don't use this in Lisp programs!
|
|
220 \(goto-char (point-max)) is faster and avoids clobbering the mark."
|
|
221 (interactive "P")
|
|
222 (push-mark)
|
|
223 (goto-char (if arg
|
|
224 (- (1+ (buffer-size))
|
|
225 (if (> (buffer-size) 10000)
|
|
226 ;; Avoid overflow for large buffer sizes!
|
|
227 (* (prefix-numeric-value arg)
|
|
228 (/ (buffer-size) 10))
|
|
229 (/ (* (buffer-size) (prefix-numeric-value arg)) 10)))
|
|
230 (point-max)))
|
|
231 (if arg (forward-line 1)
|
|
232 ;; Scroll to put point near bottom--show nearly maximum amount of text,
|
|
233 ;; but leave room to add something.
|
|
234 (recenter -3)))
|
|
235
|
|
236 (defun mark-whole-buffer ()
|
|
237 "Put point at beginning and mark at end of buffer."
|
|
238 (interactive)
|
|
239 (push-mark (point))
|
|
240 (push-mark (point-max))
|
|
241 (goto-char (point-min)))
|
|
242
|
|
243 (defun count-lines-region (start end)
|
|
244 "Print number of lines and charcters in the region."
|
|
245 (interactive "r")
|
|
246 (message "Region has %d lines, %d characters"
|
|
247 (count-lines start end) (- end start)))
|
|
248
|
|
249 (defun what-line ()
|
|
250 "Print the current line number (in the buffer) of point."
|
|
251 (interactive)
|
|
252 (save-restriction
|
|
253 (widen)
|
|
254 (save-excursion
|
|
255 (beginning-of-line)
|
|
256 (message "Line %d"
|
|
257 (1+ (count-lines 1 (point)))))))
|
|
258
|
|
259 (defun count-lines (start end)
|
|
260 "Return number of lines between START and END.
|
|
261 This is usually the number of newlines between them,
|
|
262 but will be one more if START is not equal to END
|
|
263 and the greater of them is not at the start of a line."
|
|
264 (save-excursion
|
|
265 (save-restriction
|
|
266 (narrow-to-region start end)
|
|
267 (goto-char (point-min))
|
|
268 (if (eq selective-display t)
|
|
269 (let ((done 0))
|
|
270 (while (re-search-forward "[\n\C-m]" nil t 40)
|
|
271 (setq done (+ 40 done)))
|
|
272 (while (re-search-forward "[\n\C-m]" nil t 1)
|
|
273 (setq done (+ 1 done)))
|
|
274 done)
|
|
275 (- (buffer-size) (forward-line (buffer-size)))))))
|
|
276
|
|
277 (defun what-cursor-position ()
|
|
278 "Print info on cursor position (on screen and within buffer)."
|
|
279 (interactive)
|
|
280 (let* ((char (following-char))
|
|
281 (beg (point-min))
|
|
282 (end (point-max))
|
|
283 (pos (point))
|
|
284 (total (buffer-size))
|
|
285 (percent (if (> total 50000)
|
|
286 ;; Avoid overflow from multiplying by 100!
|
|
287 (/ (+ (/ total 200) (1- pos)) (max (/ total 100) 1))
|
|
288 (/ (+ (/ total 2) (* 100 (1- pos))) (max total 1))))
|
|
289 (hscroll (if (= (window-hscroll) 0)
|
|
290 ""
|
|
291 (format " Hscroll=%d" (window-hscroll))))
|
|
292 (col (current-column)))
|
|
293 (if (= pos end)
|
|
294 (if (or (/= beg 1) (/= end (1+ total)))
|
|
295 (message "point=%d of %d(%d%%) <%d - %d> column %d %s"
|
|
296 pos total percent beg end col hscroll)
|
|
297 (message "point=%d of %d(%d%%) column %d %s"
|
|
298 pos total percent col hscroll))
|
|
299 (if (or (/= beg 1) (/= end (1+ total)))
|
|
300 (message "Char: %s (0%o) point=%d of %d(%d%%) <%d - %d> column %d %s"
|
|
301 (single-key-description char) char pos total percent beg end col hscroll)
|
|
302 (message "Char: %s (0%o) point=%d of %d(%d%%) column %d %s"
|
|
303 (single-key-description char) char pos total percent col hscroll)))))
|
|
304
|
|
305 (defun fundamental-mode ()
|
|
306 "Major mode not specialized for anything in particular.
|
|
307 Other major modes are defined by comparison with this one."
|
|
308 (interactive)
|
|
309 (kill-all-local-variables))
|
|
310
|
|
311 (put 'eval-expression 'disabled t)
|
|
312
|
|
313 ;; We define this, rather than making eval interactive,
|
|
314 ;; for the sake of completion of names like eval-region, eval-current-buffer.
|
|
315 (defun eval-expression (expression)
|
|
316 "Evaluate EXPRESSION and print value in minibuffer.
|
|
317 Value is also consed on to front of variable values 's value."
|
|
318 (interactive "xEval: ")
|
|
319 (setq values (cons (eval expression) values))
|
|
320 (prin1 (car values) t))
|
|
321
|
|
322 (defun edit-and-eval-command (prompt command)
|
|
323 "Prompting with PROMPT, let user edit COMMAND and eval result.
|
|
324 COMMAND is a Lisp expression. Let user edit that expression in
|
|
325 the minibuffer, then read and evaluate the result."
|
|
326 (let ((command (read-minibuffer prompt
|
|
327 (prin1-to-string command))))
|
|
328 ;; Add edited command to command history, unless redundant.
|
|
329 (or (equal command (car command-history))
|
|
330 (setq command-history (cons command command-history)))
|
|
331 (eval command)))
|
|
332
|
|
333 ;; (defvar repeat-complex-command nil)
|
|
334
|
|
335 (defvar repeat-complex-command-map (copy-keymap minibuffer-local-map))
|
|
336 (define-key repeat-complex-command-map "\ep" 'previous-complex-command)
|
|
337 (define-key repeat-complex-command-map "\en" 'next-complex-command)
|
|
338 (defun repeat-complex-command (repeat-complex-command-arg)
|
|
339 "Edit and re-evaluate last complex command, or ARGth from last.
|
|
340 A complex command is one which used the minibuffer.
|
|
341 The command is placed in the minibuffer as a Lisp form for editing.
|
|
342 The result is executed, repeating the command as changed.
|
|
343 If the command has been changed or is not the most recent previous command
|
|
344 it is added to the front of the command history.
|
|
345 Whilst editing the command, the following commands are available:
|
|
346 \\{repeat-complex-command-map}"
|
|
347 (interactive "p")
|
|
348 (let ((elt (nth (1- repeat-complex-command-arg) command-history))
|
|
349 (repeat-complex-command-flag t)
|
|
350 newcmd)
|
|
351 (if elt
|
|
352 (progn
|
|
353 (setq newcmd (read-from-minibuffer "Redo: "
|
|
354 (prin1-to-string elt)
|
|
355 repeat-complex-command-map
|
|
356 t))
|
|
357 ;; If command to be redone does not match front of history,
|
|
358 ;; add it to the history.
|
|
359 (or (equal newcmd (car command-history))
|
|
360 (setq command-history (cons newcmd command-history)))
|
|
361 (eval newcmd))
|
|
362 (ding))))
|
|
363
|
|
364 (defun next-complex-command (n)
|
|
365 "Inserts the next element of `command-history' into the minibuffer."
|
|
366 (interactive "p")
|
|
367 (let ((narg (min (max 1 (- repeat-complex-command-arg n))
|
|
368 (length command-history))))
|
|
369 (if (= repeat-complex-command-arg narg)
|
|
370 (error (if (= repeat-complex-command-arg 1)
|
|
371 "No following item in command history"
|
|
372 "No preceding item in command history"))
|
|
373 (erase-buffer)
|
|
374 (setq repeat-complex-command-arg narg)
|
|
375 (insert (prin1-to-string (nth (1- repeat-complex-command-arg)
|
|
376 command-history)))
|
|
377 (goto-char (point-min)))))
|
|
378
|
|
379 (defun previous-complex-command (n)
|
|
380 "Inserts the previous element of `command-history' into the minibuffer."
|
|
381 (interactive "p")
|
|
382 (if repeat-complex-command-flag
|
|
383 (next-complex-command (- n))
|
|
384 (repeat-complex-command 1)))
|
|
385
|
|
386 (defun goto-line (arg)
|
|
387 "Goto line ARG, counting from line 1 at beginning of buffer."
|
|
388 (interactive "NGoto line: ")
|
|
389 (save-restriction
|
|
390 (widen)
|
|
391 (goto-char 1)
|
|
392 (if (eq selective-display t)
|
|
393 (re-search-forward "[\n\C-m]" nil 'end (1- arg))
|
|
394 (forward-line (1- arg)))))
|
|
395
|
|
396 ;Put this on C-x u, so we can force that rather than C-_ into startup msg
|
|
397 (fset 'advertised-undo 'undo)
|
|
398
|
|
399 (defun undo (&optional arg)
|
|
400 "Undo some previous changes.
|
|
401 Repeat this command to undo more changes.
|
|
402 A numeric argument serves as a repeat count."
|
|
403 (interactive "*p")
|
|
404 (let ((modified (buffer-modified-p)))
|
|
405 (message "Undo!")
|
|
406 (or (eq last-command 'undo)
|
|
407 (progn (undo-start)
|
|
408 (undo-more 1)))
|
|
409 (setq this-command 'undo)
|
|
410 (undo-more (or arg 1))
|
|
411 (and modified (not (buffer-modified-p))
|
|
412 (delete-auto-save-file-if-necessary))))
|
|
413
|
|
414 (defun undo-start ()
|
|
415 "Move pending-undo-list to front of undo records.
|
|
416 The next call to undo-more will undo the most recently made change."
|
|
417 (if (eq buffer-undo-list t)
|
|
418 (error "No undo information in this buffer"))
|
|
419 (setq pending-undo-list buffer-undo-list))
|
|
420
|
|
421 (defun undo-more (count)
|
|
422 "Undo back N undo-boundaries beyond what was already undone recently.
|
|
423 Call undo-start to get ready to undo recent changes,
|
|
424 then call undo-more one or more times to undo them."
|
|
425 (or pending-undo-list
|
|
426 (error "No further undo information"))
|
|
427 (setq pending-undo-list (primitive-undo count pending-undo-list)))
|
|
428
|
|
429 (defvar last-shell-command "")
|
|
430 (defvar last-shell-command-on-region "")
|
|
431
|
|
432 (defun shell-command (command &optional flag)
|
|
433 "Execute string COMMAND in inferior shell; display output, if any.
|
|
434 If COMMAND ends in ampersand, execute it asynchronously.
|
|
435
|
|
436 Optional second arg non-nil (prefix arg, if interactive)
|
|
437 means insert output in current buffer after point (leave mark after it).
|
|
438 This cannot be done asynchronously."
|
|
439 (interactive (list (read-string "Shell command: " last-shell-command)
|
|
440 current-prefix-arg))
|
|
441 (if flag
|
|
442 (progn (barf-if-buffer-read-only)
|
|
443 (push-mark)
|
|
444 ;; We do not use -f for csh; we will not support broken use of
|
|
445 ;; .cshrcs. Even the BSD csh manual says to use
|
|
446 ;; "if ($?prompt) exit" before things which are not useful
|
|
447 ;; non-interactively. Besides, if someone wants their other
|
|
448 ;; aliases for shell commands then they can still have them.
|
|
449 (call-process shell-file-name nil t nil
|
|
450 "-c" command)
|
|
451 (exchange-point-and-mark))
|
|
452 ;; Preserve the match data in case called from a program.
|
|
453 (let ((data (match-data)))
|
|
454 (unwind-protect
|
|
455 (if (string-match "[ \t]*&[ \t]*$" command)
|
|
456 ;; Command ending with ampersand means asynchronous.
|
|
457 (let ((buffer (get-buffer-create "*shell-command*"))
|
|
458 (directory default-directory)
|
|
459 proc)
|
|
460 ;; Remove the ampersand.
|
|
461 (setq command (substring command 0 (match-beginning 0)))
|
|
462 ;; If will kill a process, query first.
|
|
463 (setq proc (get-buffer-process buffer))
|
|
464 (if proc
|
|
465 (if (yes-or-no-p "A command is running. Kill it? ")
|
|
466 (kill-process proc)
|
|
467 (error "Shell command in progress")))
|
|
468 (save-excursion
|
|
469 (set-buffer buffer)
|
|
470 (erase-buffer)
|
|
471 (display-buffer buffer)
|
|
472 (setq default-directory directory)
|
|
473 (setq proc (start-process "Shell" buffer
|
|
474 shell-file-name "-c" command))
|
|
475 (setq mode-line-process '(": %s"))
|
|
476 (set-process-sentinel proc 'shell-command-sentinel)
|
|
477 (set-process-filter proc 'shell-command-filter)
|
|
478 ))
|
|
479 (shell-command-on-region (point) (point) command nil))
|
|
480 (store-match-data data)))))
|
|
481
|
|
482 ;; We have a sentinel to prevent insertion of a termination message
|
|
483 ;; in the buffer itself.
|
|
484 (defun shell-command-sentinel (process signal)
|
|
485 (if (memq (process-status process) '(exit signal))
|
|
486 (progn
|
|
487 (message "%s: %s."
|
|
488 (car (cdr (cdr (process-command process))))
|
|
489 (substring signal 0 -1))
|
|
490 (save-excursion
|
|
491 (set-buffer (process-buffer process))
|
|
492 (setq mode-line-process nil))
|
|
493 (delete-process process))))
|
|
494
|
|
495 (defun shell-command-filter (proc string)
|
|
496 ;; Do save-excursion by hand so that we can leave point numerically unchanged
|
|
497 ;; despite an insertion immediately after it.
|
|
498 (let* ((obuf (current-buffer))
|
|
499 (buffer (process-buffer proc))
|
|
500 opoint
|
|
501 (window (get-buffer-window buffer))
|
|
502 (pos (window-start window)))
|
|
503 (unwind-protect
|
|
504 (progn
|
|
505 (set-buffer buffer)
|
|
506 (setq opoint (point))
|
|
507 (goto-char (point-max))
|
|
508 (insert-before-markers string))
|
|
509 ;; insert-before-markers moved this marker: set it back.
|
|
510 (set-window-start window pos)
|
|
511 ;; Finish our save-excursion.
|
|
512 (goto-char opoint)
|
|
513 (set-buffer obuf))))
|
|
514
|
|
515 (defun shell-command-on-region (start end command &optional flag interactive)
|
|
516 "Execute string COMMAND in inferior shell with region as input.
|
|
517 Normally display output (if any) in temp buffer `*Shell Command Output*';
|
|
518 Prefix arg means replace the region with it.
|
|
519 Noninteractive args are START, END, COMMAND, FLAG.
|
|
520 Noninteractively FLAG means insert output in place of text from START to END,
|
|
521 and put point at the end, but don't alter the mark.
|
|
522
|
|
523 If the output is one line, it is displayed in the echo area,
|
|
524 but it is nonetheless available in buffer `*Shell Command Output*'
|
|
525 even though that buffer is not automatically displayed. If there is no output
|
|
526 or output is inserted in the current buffer then `*Shell Command Output*' is
|
|
527 deleted."
|
|
528 (interactive (list (min (point) (mark)) (max (point) (mark))
|
|
529 (read-string "Shell command on region: "
|
|
530 last-shell-command-on-region)
|
|
531 current-prefix-arg
|
|
532 (prefix-numeric-value current-prefix-arg)))
|
|
533 (if flag
|
|
534 ;; Replace specified region with output from command.
|
|
535 (let ((swap (and interactive (< (point) (mark)))))
|
|
536 ;; Don't muck with mark
|
|
537 ;; unless called interactively.
|
|
538 (and interactive (push-mark))
|
|
539 (call-process-region start end shell-file-name t t nil
|
|
540 "-c" command)
|
|
541 (if (get-buffer "*Shell Command Output*")
|
|
542 (kill-buffer "*Shell Command Output*"))
|
|
543 (and interactive swap (exchange-point-and-mark)))
|
|
544 ;; No prefix argument: put the output in a temp buffer,
|
|
545 ;; replacing its entire contents.
|
|
546 (let ((buffer (get-buffer-create "*Shell Command Output*")))
|
|
547 (if (eq buffer (current-buffer))
|
|
548 ;; If the input is the same buffer as the output,
|
|
549 ;; delete everything but the specified region,
|
|
550 ;; then replace that region with the output.
|
|
551 (progn (delete-region end (point-max))
|
|
552 (delete-region (point-min) start)
|
|
553 (call-process-region (point-min) (point-max)
|
|
554 shell-file-name t t nil
|
|
555 "-c" command))
|
|
556 ;; Clear the output buffer, then run the command with output there.
|
|
557 (save-excursion
|
|
558 (set-buffer buffer)
|
|
559 (erase-buffer))
|
|
560 (call-process-region start end shell-file-name
|
|
561 nil buffer nil
|
|
562 "-c" command))
|
|
563 ;; Report the amount of output.
|
|
564 (let ((lines (save-excursion
|
|
565 (set-buffer buffer)
|
|
566 (if (= (buffer-size) 0)
|
|
567 0
|
|
568 (count-lines (point-min) (point-max))))))
|
|
569 (cond ((= lines 0)
|
|
570 (message "(Shell command completed with no output)")
|
|
571 (kill-buffer "*Shell Command Output*"))
|
|
572 ((= lines 1)
|
|
573 (message "%s"
|
|
574 (save-excursion
|
|
575 (set-buffer buffer)
|
|
576 (goto-char (point-min))
|
|
577 (buffer-substring (point)
|
|
578 (progn (end-of-line) (point))))))
|
|
579 (t
|
|
580 (set-window-start (display-buffer buffer) 1)))))))
|
|
581
|
|
582 (defun universal-argument ()
|
|
583 "Begin a numeric argument for the following command.
|
|
584 Digits or minus sign following \\[universal-argument] make up the numeric argument.
|
|
585 \\[universal-argument] following the digits or minus sign ends the argument.
|
|
586 \\[universal-argument] without digits or minus sign provides 4 as argument.
|
|
587 Repeating \\[universal-argument] without digits or minus sign
|
|
588 multiplies the argument by 4 each time."
|
|
589 (interactive nil)
|
|
590 (let ((c-u 4) (argstartchar last-command-char)
|
|
591 char)
|
|
592 ; (describe-arg (list c-u) 1)
|
|
593 (setq char (read-char))
|
|
594 (while (= char argstartchar)
|
|
595 (setq c-u (* 4 c-u))
|
|
596 ; (describe-arg (list c-u) 1)
|
|
597 (setq char (read-char)))
|
|
598 (prefix-arg-internal char c-u nil)))
|
|
599
|
|
600 (defun prefix-arg-internal (char c-u value)
|
|
601 (let ((sign 1))
|
|
602 (if (and (numberp value) (< value 0))
|
|
603 (setq sign -1 value (- value)))
|
|
604 (if (eq value '-)
|
|
605 (setq sign -1 value nil))
|
|
606 ; (describe-arg value sign)
|
|
607 (while (= ?- char)
|
|
608 (setq sign (- sign) c-u nil)
|
|
609 ; (describe-arg value sign)
|
|
610 (setq char (read-char)))
|
|
611 (while (and (>= char ?0) (<= char ?9))
|
|
612 (setq value (+ (* (if (numberp value) value 0) 10) (- char ?0)) c-u nil)
|
|
613 ; (describe-arg value sign)
|
|
614 (setq char (read-char)))
|
|
615 ;; Repeating the arg-start char after digits
|
|
616 ;; terminates the argument but is ignored.
|
|
617 (if (eq (lookup-key global-map (make-string 1 char)) 'universal-argument)
|
|
618 (setq char (read-char)))
|
|
619 (setq prefix-arg
|
|
620 (cond (c-u (list c-u))
|
|
621 ((numberp value) (* value sign))
|
|
622 ((= sign -1) '-)))
|
|
623 (setq unread-command-char char)))
|
|
624
|
|
625 ;(defun describe-arg (value sign)
|
|
626 ; (cond ((numberp value)
|
|
627 ; (message "Arg: %d" (* value sign)))
|
|
628 ; ((consp value)
|
|
629 ; (message "Arg: C-u factor %d" (car value)))
|
|
630 ; ((< sign 0)
|
|
631 ; (message "Arg: -"))))
|
|
632
|
|
633 (defun digit-argument (arg)
|
|
634 "Part of the numeric argument for the next command.
|
|
635 \\[universal-argument] following digits or minus sign ends the argument."
|
|
636 (interactive "P")
|
|
637 (prefix-arg-internal last-command-char nil arg))
|
|
638
|
|
639 (defun negative-argument (arg)
|
|
640 "Begin a negative numeric argument for the next command.
|
|
641 \\[universal-argument] following digits or minus sign ends the argument."
|
|
642 (interactive "P")
|
|
643 (prefix-arg-internal ?- nil arg))
|
|
644
|
|
645 (defun forward-to-indentation (arg)
|
|
646 "Move forward ARG lines and position at first nonblank character."
|
|
647 (interactive "p")
|
|
648 (forward-line arg)
|
|
649 (skip-chars-forward " \t"))
|
|
650
|
|
651 (defun backward-to-indentation (arg)
|
|
652 "Move backward ARG lines and position at first nonblank character."
|
|
653 (interactive "p")
|
|
654 (forward-line (- arg))
|
|
655 (skip-chars-forward " \t"))
|
|
656
|
|
657 (defun kill-line (&optional arg)
|
|
658 "Kill the rest of the current line; if no nonblanks there, kill thru newline.
|
|
659 With prefix argument, kill that many lines from point.
|
|
660 Negative arguments kill lines backward.
|
|
661
|
|
662 When calling from a program, nil means \"no arg\",
|
|
663 a number counts as a prefix arg."
|
|
664 (interactive "P")
|
|
665 (kill-region (point)
|
|
666 (progn
|
|
667 (if arg
|
|
668 (forward-line (prefix-numeric-value arg))
|
|
669 (if (eobp)
|
|
670 (signal 'end-of-buffer nil))
|
|
671 (if (looking-at "[ \t]*$")
|
|
672 (forward-line 1)
|
|
673 (end-of-line)))
|
|
674 (point))))
|
|
675
|
|
676 ;;;; The kill ring
|
|
677
|
|
678 (defvar kill-ring nil
|
|
679 "List of killed text sequences.")
|
|
680
|
|
681 (defconst kill-ring-max 30
|
|
682 "*Maximum length of kill ring before oldest elements are thrown away.")
|
|
683
|
|
684 (defvar kill-ring-yank-pointer nil
|
|
685 "The tail of the kill ring whose car is the last thing yanked.")
|
|
686
|
|
687 (defun kill-append (string before-p)
|
|
688 (setcar kill-ring
|
|
689 (if before-p
|
|
690 (concat string (car kill-ring))
|
|
691 (concat (car kill-ring) string))))
|
|
692
|
|
693 (defun kill-region (beg end)
|
|
694 "Kill between point and mark.
|
|
695 The text is deleted but saved in the kill ring.
|
|
696 The command \\[yank] can retrieve it from there.
|
|
697 \(If you want to kill and then yank immediately, use \\[copy-region-as-kill].)
|
|
698
|
|
699 This is the primitive for programs to kill text (as opposed to deleting it).
|
|
700 Supply two arguments, character numbers indicating the stretch of text
|
|
701 to be killed.
|
|
702 Any command that calls this function is a \"kill command\".
|
|
703 If the previous command was also a kill command,
|
|
704 the text killed this time appends to the text killed last time
|
|
705 to make one entry in the kill ring."
|
|
706 (interactive "r")
|
|
707 (if (and (not (eq buffer-undo-list t))
|
|
708 (not (eq last-command 'kill-region))
|
|
709 (not (eq beg end))
|
|
710 (not buffer-read-only))
|
|
711 ;; Don't let the undo list be truncated before we can even access it.
|
|
712 (let ((undo-high-threshold (+ (- (max beg end) (min beg end)) 100)))
|
|
713 (delete-region beg end)
|
|
714 ;; Take the same string recorded for undo
|
|
715 ;; and put it in the kill-ring.
|
|
716 (setq kill-ring (cons (car (car buffer-undo-list)) kill-ring))
|
|
717 (if (> (length kill-ring) kill-ring-max)
|
|
718 (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
|
|
719 (setq this-command 'kill-region)
|
|
720 (setq kill-ring-yank-pointer kill-ring))
|
|
721 (copy-region-as-kill beg end)
|
|
722 (or buffer-read-only (delete-region beg end))))
|
|
723
|
|
724 (defvar x-select-kill nil)
|
|
725
|
|
726 (defun copy-region-as-kill (beg end)
|
|
727 "Save the region as if killed, but don't kill it.
|
|
728 If `x-select-kill' is non-nil, also save the text for X cut and paste."
|
|
729 (interactive "r")
|
|
730 (if (eq last-command 'kill-region)
|
|
731 (kill-append (buffer-substring beg end) (< end beg))
|
|
732 (setq kill-ring (cons (buffer-substring beg end) kill-ring))
|
|
733 (if (> (length kill-ring) kill-ring-max)
|
|
734 (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
|
|
735 (if (and (eq window-system 'x) x-select-kill)
|
|
736 (x-own-selection (car kill-ring) (selected-screen)))
|
|
737 (setq this-command 'kill-region
|
|
738 kill-ring-yank-pointer kill-ring)
|
|
739 nil)
|
|
740
|
|
741 (defun kill-ring-save (beg end)
|
|
742 "Save the region as if killed, but don't kill it."
|
|
743 (interactive "r")
|
|
744 (copy-region-as-kill beg end)
|
|
745 (message "%d characters copied to kill ring"
|
|
746 (- (max beg end) (min beg end))))
|
|
747
|
|
748 (defun append-next-kill ()
|
|
749 "Cause following command, if kill, to append to previous kill."
|
|
750 (interactive)
|
|
751 (if (interactive-p)
|
|
752 (progn
|
|
753 (setq this-command 'kill-region)
|
|
754 (message "If the next command is a kill, it will append"))
|
|
755 (setq last-command 'kill-region)))
|
|
756
|
|
757 (defun rotate-yank-pointer (arg)
|
|
758 "Rotate the yanking point in the kill ring."
|
|
759 (interactive "p")
|
|
760 (let ((length (length kill-ring)))
|
|
761 (if (zerop length)
|
|
762 (error "Kill ring is empty")
|
|
763 (setq kill-ring-yank-pointer
|
|
764 (nthcdr (% (+ arg (- length (length kill-ring-yank-pointer)))
|
|
765 length)
|
|
766 kill-ring)))))
|
|
767
|
|
768 (defun yank-pop (arg)
|
|
769 "Replace just-yanked stretch of killed-text with a different stretch.
|
|
770 This command is allowed only immediately after a yank or a yank-pop.
|
|
771 At such a time, the region contains a stretch of reinserted
|
|
772 previously-killed text. yank-pop deletes that text and inserts in its
|
|
773 place a different stretch of killed text.
|
|
774
|
|
775 With no argument, the previous kill is inserted.
|
|
776 With argument n, the n'th previous kill is inserted.
|
|
777 If n is negative, this is a more recent kill.
|
|
778
|
|
779 The sequence of kills wraps around, so that after the oldest one
|
|
780 comes the newest one."
|
|
781 (interactive "*p")
|
|
782 (if (not (eq last-command 'yank))
|
|
783 (error "Previous command was not a yank"))
|
|
784 (setq this-command 'yank)
|
|
785 (let ((before (< (point) (mark))))
|
|
786 (delete-region (point) (mark))
|
|
787 (rotate-yank-pointer arg)
|
|
788 (set-mark (point))
|
|
789 (insert (car kill-ring-yank-pointer))
|
|
790 (if before (exchange-point-and-mark))))
|
|
791
|
|
792 (defun yank (&optional arg)
|
|
793 "Reinsert the last stretch of killed text.
|
|
794 More precisely, reinsert the stretch of killed text most recently
|
|
795 killed OR yanked.
|
|
796 With just C-U as argument, same but put point in front (and mark at end).
|
|
797 With argument n, reinsert the nth most recently killed stretch of killed
|
|
798 text.
|
|
799 See also the command \\[yank-pop]."
|
|
800 (interactive "*P")
|
|
801 (rotate-yank-pointer (if (listp arg) 0
|
|
802 (if (eq arg '-) -1
|
|
803 (1- arg))))
|
|
804 (push-mark (point))
|
|
805 (insert (car kill-ring-yank-pointer))
|
|
806 (if (consp arg)
|
|
807 (exchange-point-and-mark)))
|
|
808
|
|
809 (defun insert-buffer (buffer)
|
|
810 "Insert after point the contents of BUFFER.
|
|
811 Puts mark after the inserted text.
|
|
812 BUFFER may be a buffer or a buffer name."
|
|
813 (interactive (list (read-buffer "Insert buffer: " (other-buffer) t)))
|
|
814 (or (bufferp buffer)
|
|
815 (setq buffer (get-buffer buffer)))
|
|
816 (let (start end newmark)
|
|
817 (save-excursion
|
|
818 (save-excursion
|
|
819 (set-buffer buffer)
|
|
820 (setq start (point-min) end (point-max)))
|
|
821 (insert-buffer-substring buffer start end)
|
|
822 (setq newmark (point)))
|
|
823 (push-mark newmark)))
|
|
824
|
|
825 (defun append-to-buffer (buffer start end)
|
|
826 "Append to specified buffer the text of the region.
|
|
827 It is inserted into that buffer before its point.
|
|
828
|
|
829 When calling from a program, give three arguments:
|
|
830 BUFFER (or buffer name), START and END.
|
|
831 START and END specify the portion of the current buffer to be copied."
|
|
832 (interactive "BAppend to buffer: \nr")
|
|
833 (let ((oldbuf (current-buffer)))
|
|
834 (save-excursion
|
|
835 (set-buffer (get-buffer-create buffer))
|
|
836 (insert-buffer-substring oldbuf start end))))
|
|
837
|
|
838 (defun prepend-to-buffer (buffer start end)
|
|
839 "Prepend to specified buffer the text of the region.
|
|
840 It is inserted into that buffer after its point.
|
|
841
|
|
842 When calling from a program, give three arguments:
|
|
843 BUFFER (or buffer name), START and END.
|
|
844 START and END specify the portion of the current buffer to be copied."
|
|
845 (interactive "BPrepend to buffer: \nr")
|
|
846 (let ((oldbuf (current-buffer)))
|
|
847 (save-excursion
|
|
848 (set-buffer (get-buffer-create buffer))
|
|
849 (save-excursion
|
|
850 (insert-buffer-substring oldbuf start end)))))
|
|
851
|
|
852 (defun copy-to-buffer (buffer start end)
|
|
853 "Copy to specified buffer the text of the region.
|
|
854 It is inserted into that buffer, replacing existing text there.
|
|
855
|
|
856 When calling from a program, give three arguments:
|
|
857 BUFFER (or buffer name), START and END.
|
|
858 START and END specify the portion of the current buffer to be copied."
|
|
859 (interactive "BCopy to buffer: \nr")
|
|
860 (let ((oldbuf (current-buffer)))
|
|
861 (save-excursion
|
|
862 (set-buffer (get-buffer-create buffer))
|
|
863 (erase-buffer)
|
|
864 (save-excursion
|
|
865 (insert-buffer-substring oldbuf start end)))))
|
|
866
|
|
867 (defun mark ()
|
|
868 "Return this buffer's mark value as integer, or nil if no mark.
|
|
869 If you are using this in an editing command, you are most likely making
|
|
870 a mistake; see the documentation of `set-mark'."
|
|
871 (marker-position (mark-marker)))
|
|
872
|
|
873 (defun set-mark (pos)
|
|
874 "Set this buffer's mark to POS. Don't use this function!
|
|
875 That is to say, don't use this function unless you want
|
|
876 the user to see that the mark has moved, and you want the previous
|
|
877 mark position to be lost.
|
|
878
|
|
879 Normally, when a new mark is set, the old one should go on the stack.
|
|
880 This is why most applications should use push-mark, not set-mark.
|
|
881
|
|
882 Novice emacs-lisp programmers often try to use the mark for the wrong
|
|
883 purposes. The mark saves a location for the user's convenience.
|
|
884 Most editing commands should not alter the mark.
|
|
885 To remember a location for internal use in the Lisp program,
|
|
886 store it in a Lisp variable. Example:
|
|
887
|
|
888 (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
|
|
889
|
|
890 (set-marker (mark-marker) pos (current-buffer)))
|
|
891
|
|
892 (defvar mark-ring nil
|
|
893 "The list of saved former marks of the current buffer,
|
|
894 most recent first.")
|
|
895 (make-variable-buffer-local 'mark-ring)
|
|
896
|
|
897 (defconst mark-ring-max 16
|
|
898 "*Maximum size of mark ring. Start discarding off end if gets this big.")
|
|
899
|
|
900 (defun set-mark-command (arg)
|
|
901 "Set mark at where point is, or jump to mark.
|
|
902 With no prefix argument, set mark, and push previous mark on mark ring.
|
|
903 With argument, jump to mark, and pop into mark off the mark ring.
|
|
904
|
|
905 Novice emacs-lisp programmers often try to use the mark for the wrong
|
|
906 purposes. See the documentation of `set-mark' for more information."
|
|
907 (interactive "P")
|
|
908 (if (null arg)
|
|
909 (push-mark)
|
|
910 (if (null (mark))
|
|
911 (error "No mark set in this buffer")
|
|
912 (goto-char (mark))
|
|
913 (pop-mark))))
|
|
914
|
|
915 (defun push-mark (&optional location nomsg)
|
|
916 "Set mark at LOCATION (point, by default) and push old mark on mark ring.
|
|
917 Displays \"Mark set\" unless the optional second arg NOMSG is non-nil.
|
|
918
|
|
919 Novice emacs-lisp programmers often try to use the mark for the wrong
|
|
920 purposes. See the documentation of `set-mark' for more information."
|
|
921 (if (null (mark))
|
|
922 nil
|
|
923 (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
|
|
924 (if (> (length mark-ring) mark-ring-max)
|
|
925 (progn
|
|
926 (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
|
|
927 (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
|
|
928 (set-mark (or location (point)))
|
|
929 (or nomsg executing-macro (> (minibuffer-depth) 0)
|
|
930 (message "Mark set"))
|
|
931 nil)
|
|
932
|
|
933 (defun pop-mark ()
|
|
934 "Pop off mark ring into the buffer's actual mark.
|
|
935 Does not set point. Does nothing if mark ring is empty."
|
|
936 (if mark-ring
|
|
937 (progn
|
|
938 (setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
|
|
939 (set-mark (+ 0 (car mark-ring)))
|
|
940 (move-marker (car mark-ring) nil)
|
|
941 (if (null (mark)) (ding))
|
|
942 (setq mark-ring (cdr mark-ring)))))
|
|
943
|
|
944 (fset 'exchange-dot-and-mark 'exchange-point-and-mark)
|
|
945 (defun exchange-point-and-mark ()
|
|
946 "Put the mark where point is now, and point where the mark is now."
|
|
947 (interactive nil)
|
|
948 (let ((omark (mark)))
|
|
949 (if (null omark)
|
|
950 (error "No mark set in this buffer"))
|
|
951 (set-mark (point))
|
|
952 (goto-char omark)
|
|
953 nil))
|
|
954
|
|
955 (defun next-line (arg)
|
|
956 "Move cursor vertically down ARG lines.
|
|
957 If there is no character in the target line exactly under the current column,
|
|
958 the cursor is positioned after the character in that line which spans this
|
|
959 column, or at the end of the line if it is not long enough.
|
|
960 If there is no line in the buffer after this one,
|
|
961 a newline character is inserted to create a line
|
|
962 and the cursor moves to that line.
|
|
963
|
|
964 The command \\[set-goal-column] can be used to create
|
|
965 a semipermanent goal column to which this command always moves.
|
|
966 Then it does not try to move vertically. This goal column is stored
|
|
967 in `goal-column', which is nil when there is none.
|
|
968
|
|
969 If you are thinking of using this in a Lisp program, consider
|
|
970 using `forward-line' instead. It is usually easier to use
|
|
971 and more reliable (no dependence on goal column, etc.)."
|
|
972 (interactive "p")
|
|
973 (if (= arg 1)
|
|
974 (let ((opoint (point)))
|
|
975 (forward-line 1)
|
|
976 (if (or (= opoint (point))
|
|
977 (not (eq (preceding-char) ?\n)))
|
|
978 (insert ?\n)
|
|
979 (goto-char opoint)
|
|
980 (line-move arg)))
|
|
981 (line-move arg))
|
|
982 nil)
|
|
983
|
|
984 (defun previous-line (arg)
|
|
985 "Move cursor vertically up ARG lines.
|
|
986 If there is no character in the target line exactly over the current column,
|
|
987 the cursor is positioned after the character in that line which spans this
|
|
988 column, or at the end of the line if it is not long enough.
|
|
989
|
|
990 The command \\[set-goal-column] can be used to create
|
|
991 a semipermanent goal column to which this command always moves.
|
|
992 Then it does not try to move vertically.
|
|
993
|
|
994 If you are thinking of using this in a Lisp program, consider using
|
|
995 `forward-line' with negative argument instead.. It is usually easier
|
|
996 to use and more reliable (no dependence on goal column, etc.)."
|
|
997 (interactive "p")
|
|
998 (line-move (- arg))
|
|
999 nil)
|
|
1000
|
|
1001 (defconst track-eol nil
|
|
1002 "*Non-nil means vertical motion starting at end of line keeps to ends of lines.
|
|
1003 This means moving to the end of each line moved onto.
|
|
1004 The beginning of a blank line does not count as the end of a line.")
|
|
1005
|
|
1006 (make-variable-buffer-local
|
|
1007 (defvar goal-column nil
|
|
1008 "*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil."))
|
|
1009
|
|
1010 (defvar temporary-goal-column 0
|
|
1011 "Current goal column for vertical motion.
|
|
1012 It is the column where point was
|
|
1013 at the start of current run of vertical motion commands.
|
|
1014 When the `track-eol' feature is doing its job, the value is 9999."
|
|
1015
|
|
1016 (defun line-move (arg)
|
|
1017 (if (not (or (eq last-command 'next-line)
|
|
1018 (eq last-command 'previous-line)))
|
|
1019 (setq temporary-goal-column
|
|
1020 (if (and track-eol (eolp)
|
|
1021 ;; Don't count beg of empty line as end of line
|
|
1022 ;; unless we just did explicit end-of-line.
|
|
1023 (or (not (bolp)) (eq last-command 'end-of-line)))
|
|
1024 9999
|
|
1025 (current-column))))
|
|
1026 (if (not (integerp selective-display))
|
|
1027 (forward-line arg)
|
|
1028 ;; Move by arg lines, but ignore invisible ones.
|
|
1029 (while (> arg 0)
|
|
1030 (vertical-motion 1)
|
|
1031 (forward-char -1)
|
|
1032 (forward-line 1)
|
|
1033 (setq arg (1- arg)))
|
|
1034 (while (< arg 0)
|
|
1035 (vertical-motion -1)
|
|
1036 (beginning-of-line)
|
|
1037 (setq arg (1+ arg))))
|
|
1038 (move-to-column (or goal-column temporary-goal-column))
|
|
1039 nil)
|
|
1040
|
|
1041
|
|
1042 (defun set-goal-column (arg)
|
|
1043 "Set the current horizontal position as a goal for \\[next-line] and \\[previous-line].
|
|
1044 Those commands will move to this position in the line moved to
|
|
1045 rather than trying to keep the same horizontal position.
|
|
1046 With a non-nil argument, clears out the goal column
|
|
1047 so that \\[next-line] and \\[previous-line] resume vertical motion."
|
|
1048 (interactive "P")
|
|
1049 (if arg
|
|
1050 (progn
|
|
1051 (setq goal-column nil)
|
|
1052 (message "No goal column"))
|
|
1053 (setq goal-column (current-column))
|
|
1054 (message (substitute-command-keys
|
|
1055 "Goal column %d (use \\[set-goal-column] with an arg to unset it)")
|
|
1056 goal-column))
|
|
1057 nil)
|
|
1058
|
|
1059 (defun transpose-chars (arg)
|
|
1060 "Interchange characters around point, moving forward one character.
|
|
1061 With prefix arg ARG, effect is to take character before point
|
|
1062 and drag it forward past ARG other characters (backward if ARG negative).
|
|
1063 If no argument and at end of line, the previous two chars are exchanged."
|
|
1064 (interactive "*P")
|
|
1065 (and (null arg) (eolp) (forward-char -1))
|
|
1066 (transpose-subr 'forward-char (prefix-numeric-value arg)))
|
|
1067
|
|
1068 (defun transpose-words (arg)
|
|
1069 "Interchange words around point, leaving point at end of them.
|
|
1070 With prefix arg ARG, effect is to take word before or around point
|
|
1071 and drag it forward past ARG other words (backward if ARG negative).
|
|
1072 If ARG is zero, the words around or after point and around or after mark
|
|
1073 are interchanged."
|
|
1074 (interactive "*p")
|
|
1075 (transpose-subr 'forward-word arg))
|
|
1076
|
|
1077 (defun transpose-sexps (arg)
|
|
1078 "Like \\[transpose-words] but applies to sexps.
|
|
1079 Does not work on a sexp that point is in the middle of
|
|
1080 if it is a list or string."
|
|
1081 (interactive "*p")
|
|
1082 (transpose-subr 'forward-sexp arg))
|
|
1083
|
|
1084 (defun transpose-lines (arg)
|
|
1085 "Exchange current line and previous line, leaving point after both.
|
|
1086 With argument ARG, takes previous line and moves it past ARG lines.
|
|
1087 With argument 0, interchanges line point is in with line mark is in."
|
|
1088 (interactive "*p")
|
|
1089 (transpose-subr (function
|
|
1090 (lambda (arg)
|
|
1091 (if (= arg 1)
|
|
1092 (progn
|
|
1093 ;; Move forward over a line,
|
|
1094 ;; but create a newline if none exists yet.
|
|
1095 (end-of-line)
|
|
1096 (if (eobp)
|
|
1097 (newline)
|
|
1098 (forward-char 1)))
|
|
1099 (forward-line arg))))
|
|
1100 arg))
|
|
1101
|
|
1102 (defun transpose-subr (mover arg)
|
|
1103 (let (start1 end1 start2 end2)
|
|
1104 (if (= arg 0)
|
|
1105 (progn
|
|
1106 (save-excursion
|
|
1107 (funcall mover 1)
|
|
1108 (setq end2 (point))
|
|
1109 (funcall mover -1)
|
|
1110 (setq start2 (point))
|
|
1111 (goto-char (mark))
|
|
1112 (funcall mover 1)
|
|
1113 (setq end1 (point))
|
|
1114 (funcall mover -1)
|
|
1115 (setq start1 (point))
|
|
1116 (transpose-subr-1))
|
|
1117 (exchange-point-and-mark)))
|
|
1118 (while (> arg 0)
|
|
1119 (funcall mover -1)
|
|
1120 (setq start1 (point))
|
|
1121 (funcall mover 1)
|
|
1122 (setq end1 (point))
|
|
1123 (funcall mover 1)
|
|
1124 (setq end2 (point))
|
|
1125 (funcall mover -1)
|
|
1126 (setq start2 (point))
|
|
1127 (transpose-subr-1)
|
|
1128 (goto-char end2)
|
|
1129 (setq arg (1- arg)))
|
|
1130 (while (< arg 0)
|
|
1131 (funcall mover -1)
|
|
1132 (setq start2 (point))
|
|
1133 (funcall mover -1)
|
|
1134 (setq start1 (point))
|
|
1135 (funcall mover 1)
|
|
1136 (setq end1 (point))
|
|
1137 (funcall mover 1)
|
|
1138 (setq end2 (point))
|
|
1139 (transpose-subr-1)
|
|
1140 (setq arg (1+ arg)))))
|
|
1141
|
|
1142 (defun transpose-subr-1 ()
|
|
1143 (if (> (min end1 end2) (max start1 start2))
|
|
1144 (error "Don't have two things to transpose"))
|
|
1145 (let ((word1 (buffer-substring start1 end1))
|
|
1146 (word2 (buffer-substring start2 end2)))
|
|
1147 (delete-region start2 end2)
|
|
1148 (goto-char start2)
|
|
1149 (insert word1)
|
|
1150 (goto-char (if (< start1 start2) start1
|
|
1151 (+ start1 (- (length word1) (length word2)))))
|
|
1152 (delete-char (length word1))
|
|
1153 (insert word2)))
|
|
1154
|
|
1155 (defconst comment-column 32
|
|
1156 "*Column to indent right-margin comments to.
|
|
1157 Setting this variable automatically makes it local to the current buffer.")
|
|
1158 (make-variable-buffer-local 'comment-column)
|
|
1159
|
|
1160 (defconst comment-start nil
|
|
1161 "*String to insert to start a new comment, or nil if no comment syntax defined.")
|
|
1162
|
|
1163 (defconst comment-start-skip nil
|
|
1164 "*Regexp to match the start of a comment plus everything up to its body.
|
|
1165 If there are any \\(...\\) pairs, the comment delimiter text is held to begin
|
|
1166 at the place matched by the close of the first pair.")
|
|
1167
|
|
1168 (defconst comment-end ""
|
|
1169 "*String to insert to end a new comment.
|
|
1170 Should be an empty string if comments are terminated by end-of-line.")
|
|
1171
|
|
1172 (defconst comment-indent-hook
|
|
1173 '(lambda () comment-column)
|
|
1174 "Function to compute desired indentation for a comment.
|
|
1175 This function is called with no args with point at the beginning of
|
|
1176 the comment's starting delimiter.")
|
|
1177
|
|
1178 (defun indent-for-comment ()
|
|
1179 "Indent this line's comment to comment column, or insert an empty comment."
|
|
1180 (interactive "*")
|
|
1181 (beginning-of-line 1)
|
|
1182 (if (null comment-start)
|
|
1183 (error "No comment syntax defined")
|
|
1184 (let* ((eolpos (save-excursion (end-of-line) (point)))
|
|
1185 cpos indent begpos)
|
|
1186 (if (re-search-forward comment-start-skip eolpos 'move)
|
|
1187 (progn (setq cpos (point-marker))
|
|
1188 ;; Find the start of the comment delimiter.
|
|
1189 ;; If there were paren-pairs in comment-start-skip,
|
|
1190 ;; position at the end of the first pair.
|
|
1191 (if (match-end 1)
|
|
1192 (goto-char (match-end 1))
|
|
1193 ;; If comment-start-skip matched a string with internal
|
|
1194 ;; whitespace (not final whitespace) then the delimiter
|
|
1195 ;; start at the end of that whitespace.
|
|
1196 ;; Otherwise, it starts at the beginning of what was matched.
|
|
1197 (skip-chars-backward " \t" (match-beginning 0))
|
|
1198 (skip-chars-backward "^ \t" (match-beginning 0)))))
|
|
1199 (setq begpos (point))
|
|
1200 ;; Compute desired indent.
|
|
1201 (if (= (current-column)
|
|
1202 (setq indent (funcall comment-indent-hook)))
|
|
1203 (goto-char begpos)
|
|
1204 ;; If that's different from current, change it.
|
|
1205 (skip-chars-backward " \t")
|
|
1206 (delete-region (point) begpos)
|
|
1207 (indent-to indent))
|
|
1208 ;; An existing comment?
|
|
1209 (if cpos
|
|
1210 (progn (goto-char cpos)
|
|
1211 (set-marker cpos nil))
|
|
1212 ;; No, insert one.
|
|
1213 (insert comment-start)
|
|
1214 (save-excursion
|
|
1215 (insert comment-end))))))
|
|
1216
|
|
1217 (defun set-comment-column (arg)
|
|
1218 "Set the comment column based on point.
|
|
1219 With no arg, set the comment column to the current column.
|
|
1220 With just minus as arg, kill any comment on this line.
|
|
1221 With any other arg, set comment column to indentation of the previous comment
|
|
1222 and then align or create a comment on this line at that column."
|
|
1223 (interactive "P")
|
|
1224 (if (eq arg '-)
|
|
1225 (kill-comment nil)
|
|
1226 (if arg
|
|
1227 (progn
|
|
1228 (save-excursion
|
|
1229 (beginning-of-line)
|
|
1230 (re-search-backward comment-start-skip)
|
|
1231 (beginning-of-line)
|
|
1232 (re-search-forward comment-start-skip)
|
|
1233 (goto-char (match-beginning 0))
|
|
1234 (setq comment-column (current-column))
|
|
1235 (message "Comment column set to %d" comment-column))
|
|
1236 (indent-for-comment))
|
|
1237 (setq comment-column (current-column))
|
|
1238 (message "Comment column set to %d" comment-column))))
|
|
1239
|
|
1240 (defun kill-comment (arg)
|
|
1241 "Kill the comment on this line, if any.
|
|
1242 With argument, kill comments on that many lines starting with this one."
|
|
1243 ;; this function loses in a lot of situations. it incorrectly recognises
|
|
1244 ;; comment delimiters sometimes (ergo, inside a string), doesn't work
|
|
1245 ;; with multi-line comments, can kill extra whitespace if comment wasn't
|
|
1246 ;; through end-of-line, et cetera.
|
|
1247 (interactive "P")
|
|
1248 (or comment-start-skip (error "No comment syntax defined"))
|
|
1249 (let ((count (prefix-numeric-value arg)) endc)
|
|
1250 (while (> count 0)
|
|
1251 (save-excursion
|
|
1252 (end-of-line)
|
|
1253 (setq endc (point))
|
|
1254 (beginning-of-line)
|
|
1255 (and (string< "" comment-end)
|
|
1256 (setq endc
|
|
1257 (progn
|
|
1258 (re-search-forward (regexp-quote comment-end) endc 'move)
|
|
1259 (skip-chars-forward " \t")
|
|
1260 (point))))
|
|
1261 (beginning-of-line)
|
|
1262 (if (re-search-forward comment-start-skip endc t)
|
|
1263 (progn
|
|
1264 (goto-char (match-beginning 0))
|
|
1265 (skip-chars-backward " \t")
|
|
1266 (kill-region (point) endc)
|
|
1267 ;; to catch comments a line beginnings
|
|
1268 (indent-according-to-mode))))
|
|
1269 (if arg (forward-line 1))
|
|
1270 (setq count (1- count)))))
|
|
1271
|
|
1272 (defun comment-region (beg end &optional arg)
|
|
1273 "Comment the region; third arg numeric means use ARG comment characters.
|
|
1274 If ARG is negative, delete that many comment characters instead.
|
|
1275 Comments are terminated on each line, even for syntax in which newline does
|
|
1276 not end the comment. Blank lines do not get comments."
|
|
1277 ;; if someone wants it to only put a comment-start at the beginning and
|
|
1278 ;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x
|
|
1279 ;; is easy enough. No option is made here for other than commenting
|
|
1280 ;; every line.
|
|
1281 (interactive "r\np")
|
|
1282 (or comment-start (error "No comment syntax is defined"))
|
|
1283 (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
|
|
1284 (save-excursion
|
|
1285 (save-restriction
|
|
1286 (let ((cs comment-start) (ce comment-end))
|
|
1287 (cond ((not arg) (setq arg 1))
|
|
1288 ((> arg 1)
|
|
1289 (while (> (setq arg (1- arg)) 0)
|
|
1290 (setq cs (concat cs comment-start)
|
|
1291 ce (concat ce comment-end)))))
|
|
1292 (narrow-to-region beg end)
|
|
1293 (goto-char beg)
|
|
1294 (while (not (eobp))
|
|
1295 (if (< arg 0)
|
|
1296 (let ((count arg))
|
|
1297 (while (and (> 1 (setq count (1+ count)))
|
|
1298 (looking-at (regexp-quote cs)))
|
|
1299 (delete-char (length cs)))
|
|
1300 (if (string= "" ce) ()
|
|
1301 (setq count arg)
|
|
1302 (while (> 1 (setq count (1+ count)))
|
|
1303 (end-of-line)
|
|
1304 ;; this is questionable if comment-end ends in whitespace
|
|
1305 ;; that is pretty brain-damaged though
|
|
1306 (skip-chars-backward " \t")
|
|
1307 (backward-char (length ce))
|
|
1308 (if (looking-at (regexp-quote ce))
|
|
1309 (delete-char (length ce))))))
|
|
1310 (if (looking-at "[ \t]*$") ()
|
|
1311 (insert cs)
|
|
1312 (if (string= "" ce) ()
|
|
1313 (end-of-line)
|
|
1314 (insert ce)))
|
|
1315 (search-forward "\n" nil 'move)))))))
|
|
1316
|
|
1317 (defun backward-word (arg)
|
|
1318 "Move backward until encountering the end of a word.
|
|
1319 With argument, do this that many times.
|
|
1320 In programs, it is faster to call forward-word with negative arg."
|
|
1321 (interactive "p")
|
|
1322 (forward-word (- arg)))
|
|
1323
|
|
1324 (defun mark-word (arg)
|
|
1325 "Set mark arg words away from point."
|
|
1326 (interactive "p")
|
|
1327 (push-mark
|
|
1328 (save-excursion
|
|
1329 (forward-word arg)
|
|
1330 (point))))
|
|
1331
|
|
1332 (defun kill-word (arg)
|
|
1333 "Kill characters forward until encountering the end of a word.
|
|
1334 With argument, do this that many times."
|
|
1335 (interactive "p")
|
|
1336 (kill-region (point) (progn (forward-word arg) (point))))
|
|
1337
|
|
1338 (defun backward-kill-word (arg)
|
|
1339 "Kill characters backward until encountering the end of a word.
|
|
1340 With argument, do this that many times."
|
|
1341 (interactive "p")
|
|
1342 (kill-word (- arg)))
|
|
1343
|
|
1344 (defconst fill-prefix nil
|
|
1345 "*String for filling to insert at front of new line, or nil for none.
|
|
1346 Setting this variable automatically makes it local to the current buffer.")
|
|
1347 (make-variable-buffer-local 'fill-prefix)
|
|
1348
|
|
1349 (defconst auto-fill-inhibit-regexp nil
|
|
1350 "*Regexp to match lines which should not be auto-filled.")
|
|
1351
|
|
1352 (defun do-auto-fill ()
|
|
1353 (let (give-up)
|
|
1354 (or (and auto-fill-inhibit-regexp
|
|
1355 (save-excursion (beginning-of-line)
|
|
1356 (looking-at auto-fill-inhibit-regexp)))
|
|
1357 (while (and (not give-up) (> (current-column) fill-column))
|
|
1358 (let ((fill-point
|
|
1359 (let ((opoint (point)))
|
|
1360 (save-excursion
|
|
1361 (move-to-column (1+ fill-column))
|
|
1362 (skip-chars-backward "^ \t\n")
|
|
1363 (if (bolp)
|
|
1364 (re-search-forward "[ \t]" opoint t))
|
|
1365 (skip-chars-backward " \t")
|
|
1366 (point)))))
|
|
1367 ;; If there is a space on the line before fill-point,
|
|
1368 ;; and nonspaces precede it, break the line there.
|
|
1369 (if (save-excursion
|
|
1370 (goto-char fill-point)
|
|
1371 (not (bolp)))
|
|
1372 ;; If point is at the fill-point, do not `save-excursion'.
|
|
1373 ;; Otherwise, if a comment prefix or fill-prefix is inserted,
|
|
1374 ;; point will end up before it rather than after it.
|
|
1375 (if (save-excursion
|
|
1376 (skip-chars-backward " \t")
|
|
1377 (= (point) fill-point))
|
|
1378 (indent-new-comment-line)
|
|
1379 (save-excursion
|
|
1380 (goto-char fill-point)
|
|
1381 (indent-new-comment-line)))
|
|
1382 ;; No place to break => stop trying.
|
|
1383 (setq give-up t)))))))
|
|
1384
|
|
1385 (defconst comment-multi-line nil
|
|
1386 "*Non-nil means \\[indent-new-comment-line] should continue same comment
|
|
1387 on new line, with no new terminator or starter.")
|
|
1388
|
|
1389 (defun indent-new-comment-line ()
|
|
1390 "Break line at point and indent, continuing comment if presently within one.
|
|
1391 The body of the continued comment is indented under the previous comment line."
|
|
1392 (interactive "*")
|
|
1393 (let (comcol comstart)
|
|
1394 (skip-chars-backward " \t")
|
|
1395 (delete-region (point)
|
|
1396 (progn (skip-chars-forward " \t")
|
|
1397 (point)))
|
|
1398 (insert ?\n)
|
|
1399 (save-excursion
|
|
1400 (if (and comment-start-skip
|
|
1401 (let ((opoint (point)))
|
|
1402 (forward-line -1)
|
|
1403 (re-search-forward comment-start-skip opoint t)))
|
|
1404 ;; The old line is a comment.
|
|
1405 ;; Set WIN to the pos of the comment-start.
|
|
1406 ;; But if the comment is empty, look at preceding lines
|
|
1407 ;; to find one that has a nonempty comment.
|
|
1408 (let ((win (match-beginning 0)))
|
|
1409 (while (and (eolp) (not (bobp))
|
|
1410 (let (opoint)
|
|
1411 (beginning-of-line)
|
|
1412 (setq opoint (point))
|
|
1413 (forward-line -1)
|
|
1414 (re-search-forward comment-start-skip opoint t)))
|
|
1415 (setq win (match-beginning 0)))
|
|
1416 ;; Indent this line like what we found.
|
|
1417 (goto-char win)
|
|
1418 (setq comcol (current-column))
|
|
1419 (setq comstart (buffer-substring (point) (match-end 0))))))
|
|
1420 (if comcol
|
|
1421 (let ((comment-column comcol)
|
|
1422 (comment-start comstart)
|
|
1423 (comment-end comment-end))
|
|
1424 (and comment-end (not (equal comment-end ""))
|
|
1425 (if (not comment-multi-line)
|
|
1426 (progn
|
|
1427 (forward-char -1)
|
|
1428 (insert comment-end)
|
|
1429 (forward-char 1))
|
|
1430 (setq comment-column (+ comment-column (length comment-start))
|
|
1431 comment-start "")))
|
|
1432 (if (not (eolp))
|
|
1433 (setq comment-end ""))
|
|
1434 (insert ?\n)
|
|
1435 (forward-char -1)
|
|
1436 (indent-for-comment)
|
|
1437 (save-excursion
|
|
1438 ;; Make sure we delete the newline inserted above.
|
|
1439 (end-of-line)
|
|
1440 (delete-char 1)))
|
|
1441 (if fill-prefix
|
|
1442 (insert fill-prefix)
|
|
1443 (indent-according-to-mode)))))
|
|
1444
|
|
1445 (defun auto-fill-mode (&optional arg)
|
|
1446 "Toggle auto-fill mode.
|
|
1447 With arg, turn auto-fill mode on if and only if arg is positive.
|
|
1448 In auto-fill mode, inserting a space at a column beyond fill-column
|
|
1449 automatically breaks the line at a previous space."
|
|
1450 (interactive "P")
|
|
1451 (prog1 (setq auto-fill-function
|
|
1452 (if (if (null arg)
|
|
1453 (not auto-fill-function)
|
|
1454 (> (prefix-numeric-value arg) 0))
|
|
1455 'do-auto-fill
|
|
1456 nil))
|
|
1457 ;; update mode-line
|
|
1458 (set-buffer-modified-p (buffer-modified-p))))
|
|
1459
|
|
1460 (defun turn-on-auto-fill ()
|
|
1461 "Unconditionally turn on Auto Fill mode."
|
|
1462 (auto-fill-mode 1))
|
|
1463
|
|
1464 (defun set-fill-column (arg)
|
|
1465 "Set fill-column to current column, or to argument if given.
|
|
1466 fill-column's value is separate for each buffer."
|
|
1467 (interactive "P")
|
|
1468 (setq fill-column (if (integerp arg) arg (current-column)))
|
|
1469 (message "fill-column set to %d" fill-column))
|
|
1470
|
|
1471 (defun set-selective-display (arg)
|
|
1472 "Set selective-display to ARG; clear it if no arg.
|
|
1473 When selective-display is a number > 0,
|
|
1474 lines whose indentation is >= selective-display are not displayed.
|
|
1475 selective-display's value is separate for each buffer."
|
|
1476 (interactive "P")
|
|
1477 (if (eq selective-display t)
|
|
1478 (error "selective-display already in use for marked lines"))
|
|
1479 (setq selective-display
|
|
1480 (and arg (prefix-numeric-value arg)))
|
|
1481 (set-window-start (selected-window) (window-start (selected-window)))
|
|
1482 (princ "selective-display set to " t)
|
|
1483 (prin1 selective-display t)
|
|
1484 (princ "." t))
|
|
1485
|
|
1486 (defun overwrite-mode (arg)
|
|
1487 "Toggle overwrite mode.
|
|
1488 With arg, turn overwrite mode on iff arg is positive.
|
|
1489 In overwrite mode, printing characters typed in replace existing text
|
|
1490 on a one-for-one basis, rather than pushing it to the right."
|
|
1491 (interactive "P")
|
|
1492 (setq overwrite-mode
|
|
1493 (if (null arg) (not overwrite-mode)
|
|
1494 (> (prefix-numeric-value arg) 0)))
|
|
1495 (set-buffer-modified-p (buffer-modified-p))) ;No-op, but updates mode line.
|
|
1496
|
|
1497 (defvar blink-matching-paren t
|
|
1498 "*Non-nil means show matching open-paren when close-paren is inserted.")
|
|
1499
|
|
1500 (defconst blink-matching-paren-distance 4000
|
|
1501 "*If non-nil, is maximum distance to search for matching open-paren
|
|
1502 when close-paren is inserted.")
|
|
1503
|
|
1504 (defun blink-matching-open ()
|
|
1505 "Move cursor momentarily to the beginning of the sexp before point."
|
|
1506 (interactive)
|
|
1507 (and (> (point) (1+ (point-min)))
|
|
1508 (/= (char-syntax (char-after (- (point) 2))) ?\\ )
|
|
1509 blink-matching-paren
|
|
1510 (let* ((oldpos (point))
|
|
1511 (blinkpos)
|
|
1512 (mismatch))
|
|
1513 (save-excursion
|
|
1514 (save-restriction
|
|
1515 (if blink-matching-paren-distance
|
|
1516 (narrow-to-region (max (point-min)
|
|
1517 (- (point) blink-matching-paren-distance))
|
|
1518 oldpos))
|
|
1519 (condition-case ()
|
|
1520 (setq blinkpos (scan-sexps oldpos -1))
|
|
1521 (error nil)))
|
|
1522 (and blinkpos (/= (char-syntax (char-after blinkpos))
|
|
1523 ?\$)
|
|
1524 (setq mismatch
|
|
1525 (/= (char-after (1- oldpos))
|
|
1526 (logand (lsh (aref (syntax-table)
|
|
1527 (char-after blinkpos))
|
|
1528 -8)
|
|
1529 255))))
|
|
1530 (if mismatch (setq blinkpos nil))
|
|
1531 (if blinkpos
|
|
1532 (progn
|
|
1533 (goto-char blinkpos)
|
|
1534 (if (pos-visible-in-window-p)
|
|
1535 (sit-for 1)
|
|
1536 (goto-char blinkpos)
|
|
1537 (message
|
|
1538 "Matches %s"
|
|
1539 (if (save-excursion
|
|
1540 (skip-chars-backward " \t")
|
|
1541 (not (bolp)))
|
|
1542 (buffer-substring (progn (beginning-of-line) (point))
|
|
1543 (1+ blinkpos))
|
|
1544 (buffer-substring blinkpos
|
|
1545 (progn
|
|
1546 (forward-char 1)
|
|
1547 (skip-chars-forward "\n \t")
|
|
1548 (end-of-line)
|
|
1549 (point)))))))
|
|
1550 (cond (mismatch
|
|
1551 (message "Mismatched parentheses"))
|
|
1552 ((not blink-matching-paren-distance)
|
|
1553 (message "Unmatched parenthesis"))))))))
|
|
1554
|
|
1555 ;Turned off because it makes dbx bomb out.
|
|
1556 (setq blink-paren-function 'blink-matching-open)
|
|
1557
|
|
1558 ; this is just something for the luser to see in a keymap -- this is not
|
|
1559 ; how quitting works normally!
|
|
1560 (defun keyboard-quit ()
|
|
1561 "Signal a quit condition."
|
|
1562 (interactive)
|
|
1563 (signal 'quit nil))
|
|
1564
|
|
1565 (define-key global-map "\C-g" 'keyboard-quit)
|
|
1566
|
|
1567 (defun set-variable (var val)
|
|
1568 "Set VARIABLE to VALUE. VALUE is a Lisp object.
|
|
1569 When using this interactively, supply a Lisp expression for VALUE.
|
|
1570 If you want VALUE to be a string, you must surround it with doublequotes."
|
|
1571 (interactive
|
|
1572 (let* ((var (read-variable "Set variable: "))
|
|
1573 (minibuffer-help-form
|
|
1574 '(funcall myhelp))
|
|
1575 (myhelp
|
|
1576 (function
|
|
1577 (lambda ()
|
|
1578 (with-output-to-temp-buffer "*Help*"
|
|
1579 (prin1 var)
|
|
1580 (princ "\nDocumentation:\n")
|
|
1581 (princ (substring (documentation-property var 'variable-documentation)
|
|
1582 1))
|
|
1583 (if (boundp var)
|
|
1584 (let ((print-length 20))
|
|
1585 (princ "\n\nCurrent value: ")
|
|
1586 (prin1 (symbol-value var))))
|
|
1587 nil)))))
|
|
1588 (list var
|
|
1589 (eval-minibuffer (format "Set %s to value: " var)))))
|
|
1590 (set var val))
|
|
1591
|
|
1592 ;These commands are defined in editfns.c
|
|
1593 ;but they are not assigned to keys there.
|
|
1594 (put 'narrow-to-region 'disabled t)
|
|
1595 (define-key ctl-x-map "n" 'narrow-to-region)
|
|
1596 (define-key ctl-x-map "w" 'widen)
|
|
1597
|
|
1598 (define-key global-map "\C-j" 'newline-and-indent)
|
|
1599 (define-key global-map "\C-m" 'newline)
|
|
1600 (define-key global-map "\C-o" 'open-line)
|
|
1601 (define-key esc-map "\C-o" 'split-line)
|
|
1602 (define-key global-map "\C-q" 'quoted-insert)
|
|
1603 (define-key esc-map "^" 'delete-indentation)
|
|
1604 (define-key esc-map "\\" 'delete-horizontal-space)
|
|
1605 (define-key esc-map "m" 'back-to-indentation)
|
|
1606 (define-key ctl-x-map "\C-o" 'delete-blank-lines)
|
|
1607 (define-key esc-map " " 'just-one-space)
|
|
1608 (define-key esc-map "z" 'zap-to-char)
|
|
1609 (define-key esc-map "=" 'count-lines-region)
|
|
1610 (define-key ctl-x-map "=" 'what-cursor-position)
|
|
1611 (define-key esc-map "\e" 'eval-expression)
|
|
1612 (define-key ctl-x-map "\e" 'repeat-complex-command)
|
|
1613 (define-key ctl-x-map "u" 'advertised-undo)
|
|
1614 (define-key global-map "\C-_" 'undo)
|
|
1615 (define-key esc-map "!" 'shell-command)
|
|
1616 (define-key esc-map "|" 'shell-command-on-region)
|
|
1617
|
|
1618 (define-key global-map "\C-u" 'universal-argument)
|
|
1619 (let ((i ?0))
|
|
1620 (while (<= i ?9)
|
|
1621 (define-key esc-map (char-to-string i) 'digit-argument)
|
|
1622 (setq i (1+ i))))
|
|
1623 (define-key esc-map "-" 'negative-argument)
|
|
1624
|
|
1625 (define-key global-map "\C-k" 'kill-line)
|
|
1626 (define-key global-map "\C-w" 'kill-region)
|
|
1627 (define-key esc-map "w" 'kill-ring-save)
|
|
1628 (define-key esc-map "\C-w" 'append-next-kill)
|
|
1629 (define-key global-map "\C-y" 'yank)
|
|
1630 (define-key esc-map "y" 'yank-pop)
|
|
1631
|
|
1632 (define-key ctl-x-map "a" 'append-to-buffer)
|
|
1633
|
|
1634 (define-key global-map "\C-@" 'set-mark-command)
|
|
1635 (define-key ctl-x-map "\C-x" 'exchange-point-and-mark)
|
|
1636
|
|
1637 (define-key global-map "\C-n" 'next-line)
|
|
1638 (define-key global-map "\C-p" 'previous-line)
|
|
1639 (define-key ctl-x-map "\C-n" 'set-goal-column)
|
|
1640
|
|
1641 (define-key global-map "\C-t" 'transpose-chars)
|
|
1642 (define-key esc-map "t" 'transpose-words)
|
|
1643 (define-key esc-map "\C-t" 'transpose-sexps)
|
|
1644 (define-key ctl-x-map "\C-t" 'transpose-lines)
|
|
1645
|
|
1646 (define-key esc-map ";" 'indent-for-comment)
|
|
1647 (define-key esc-map "j" 'indent-new-comment-line)
|
|
1648 (define-key esc-map "\C-j" 'indent-new-comment-line)
|
|
1649 (define-key ctl-x-map ";" 'set-comment-column)
|
|
1650 (define-key ctl-x-map "f" 'set-fill-column)
|
|
1651 (define-key ctl-x-map "$" 'set-selective-display)
|
|
1652
|
|
1653 (define-key esc-map "@" 'mark-word)
|
|
1654 (define-key esc-map "f" 'forward-word)
|
|
1655 (define-key esc-map "b" 'backward-word)
|
|
1656 (define-key esc-map "d" 'kill-word)
|
|
1657 (define-key esc-map "\177" 'backward-kill-word)
|
|
1658
|
|
1659 (define-key esc-map "<" 'beginning-of-buffer)
|
|
1660 (define-key esc-map ">" 'end-of-buffer)
|
|
1661 (define-key ctl-x-map "h" 'mark-whole-buffer)
|
|
1662 (define-key esc-map "\\" 'delete-horizontal-space)
|
|
1663
|
|
1664 (fset 'mode-specific-command-prefix (make-sparse-keymap))
|
|
1665 (defconst mode-specific-map (symbol-function 'mode-specific-command-prefix)
|
|
1666 "Keymap for characters following C-c.")
|
|
1667 (define-key global-map "\C-c" 'mode-specific-command-prefix)
|