1992-05-30 21:11:25 +00:00
|
|
|
|
;;; simple.el --- basic editing commands for Emacs
|
|
|
|
|
|
1995-04-07 02:21:52 +00:00
|
|
|
|
;; Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
1992-07-22 04:22:42 +00:00
|
|
|
|
;; the Free Software Foundation; either version 2, or (at your option)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
;; any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
1996-01-14 07:34:30 +00:00
|
|
|
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
|
|
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
|
;; Boston, MA 02111-1307, USA.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1993-03-22 16:53:22 +00:00
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; A grab-bag of basic Emacs commands not specifically related to some
|
|
|
|
|
;; major mode or to file-handling.
|
|
|
|
|
|
1992-07-22 04:22:42 +00:00
|
|
|
|
;;; Code:
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1995-03-01 15:09:58 +00:00
|
|
|
|
(defun newline (&optional arg)
|
1995-04-09 06:47:22 +00:00
|
|
|
|
"Insert a newline, and move to left margin of the new line if it's blank.
|
1995-03-01 15:09:58 +00:00
|
|
|
|
The newline is marked with the text-property `hard'.
|
|
|
|
|
With arg, insert that many newlines.
|
|
|
|
|
In Auto Fill mode, if no numeric arg, break the preceding line if it's long."
|
|
|
|
|
(interactive "*P")
|
1995-10-06 22:40:25 +00:00
|
|
|
|
(barf-if-buffer-read-only)
|
1995-03-01 15:09:58 +00:00
|
|
|
|
;; Inserting a newline at the end of a line produces better redisplay in
|
|
|
|
|
;; try_window_id than inserting at the beginning of a line, and the textual
|
|
|
|
|
;; result is the same. So, if we're at beginning of line, pretend to be at
|
|
|
|
|
;; the end of the previous line.
|
|
|
|
|
(let ((flag (and (not (bobp))
|
|
|
|
|
(bolp)
|
1996-07-04 18:55:49 +00:00
|
|
|
|
;; Make sure the newline before point isn't intangible.
|
|
|
|
|
(not (get-char-property (1- (point)) 'intangible))
|
|
|
|
|
;; Make sure the newline before point isn't read-only.
|
|
|
|
|
(not (get-char-property (1- (point)) 'read-only))
|
|
|
|
|
;; Make sure the newline before point isn't invisible.
|
|
|
|
|
(not (get-char-property (1- (point)) 'invisible))
|
|
|
|
|
;; Make sure the newline before point has the same
|
|
|
|
|
;; properties as the char before it (if any).
|
1995-03-01 15:09:58 +00:00
|
|
|
|
(< (or (previous-property-change (point)) -2)
|
1995-04-09 06:47:22 +00:00
|
|
|
|
(- (point) 2))))
|
|
|
|
|
(was-page-start (and (bolp)
|
|
|
|
|
(looking-at page-delimiter)))
|
|
|
|
|
(beforepos (point)))
|
1995-03-01 15:09:58 +00:00
|
|
|
|
(if flag (backward-char 1))
|
|
|
|
|
;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
|
|
|
|
|
;; Set last-command-char to tell self-insert what to insert.
|
|
|
|
|
(let ((last-command-char ?\n)
|
|
|
|
|
;; Don't auto-fill if we have a numeric argument.
|
1995-04-10 21:01:12 +00:00
|
|
|
|
;; Also not if flag is true (it would fill wrong line);
|
|
|
|
|
;; there is no need to since we're at BOL.
|
|
|
|
|
(auto-fill-function (if (or arg flag) nil auto-fill-function)))
|
1995-06-27 18:58:26 +00:00
|
|
|
|
(unwind-protect
|
|
|
|
|
(self-insert-command (prefix-numeric-value arg))
|
|
|
|
|
;; If we get an error in self-insert-command, put point at right place.
|
|
|
|
|
(if flag (forward-char 1))))
|
|
|
|
|
;; If we did *not* get an error, cancel that forward-char.
|
|
|
|
|
(if flag (backward-char 1))
|
1995-03-01 15:09:58 +00:00
|
|
|
|
;; Mark the newline(s) `hard'.
|
|
|
|
|
(if use-hard-newlines
|
|
|
|
|
(let* ((from (- (point) (if arg (prefix-numeric-value arg) 1)))
|
|
|
|
|
(sticky (get-text-property from 'rear-nonsticky)))
|
|
|
|
|
(put-text-property from (point) 'hard 't)
|
|
|
|
|
;; If rear-nonsticky is not "t", add 'hard to rear-nonsticky list
|
|
|
|
|
(if (and (listp sticky) (not (memq 'hard sticky)))
|
|
|
|
|
(put-text-property from (point) 'rear-nonsticky
|
|
|
|
|
(cons 'hard sticky)))))
|
1995-04-09 06:47:22 +00:00
|
|
|
|
;; If the newline leaves the previous line blank,
|
|
|
|
|
;; and we have a left margin, delete that from the blank line.
|
|
|
|
|
(or flag
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char beforepos)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(and (looking-at "[ \t]$")
|
|
|
|
|
(> (current-left-margin) 0)
|
|
|
|
|
(delete-region (point) (progn (end-of-line) (point))))))
|
|
|
|
|
(if flag (forward-char 1))
|
|
|
|
|
;; Indent the line after the newline, except in one case:
|
|
|
|
|
;; when we added the newline at the beginning of a line
|
|
|
|
|
;; which starts a page.
|
|
|
|
|
(or was-page-start
|
|
|
|
|
(move-to-left-margin nil t)))
|
1995-03-01 15:09:58 +00:00
|
|
|
|
nil)
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun open-line (arg)
|
1992-08-21 07:18:16 +00:00
|
|
|
|
"Insert a newline and leave point before it.
|
1995-02-23 18:38:42 +00:00
|
|
|
|
If there is a fill prefix and/or a left-margin, insert them on the new line
|
1995-04-09 06:47:22 +00:00
|
|
|
|
if the line would have been blank.
|
1992-08-31 20:22:03 +00:00
|
|
|
|
With arg N, insert N newlines."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "*p")
|
1992-08-31 20:22:03 +00:00
|
|
|
|
(let* ((do-fill-prefix (and fill-prefix (bolp)))
|
1995-02-23 18:38:42 +00:00
|
|
|
|
(do-left-margin (and (bolp) (> (current-left-margin) 0)))
|
1995-01-13 08:43:40 +00:00
|
|
|
|
(loc (point)))
|
1995-04-09 06:47:22 +00:00
|
|
|
|
(newline arg)
|
|
|
|
|
(goto-char loc)
|
1995-01-13 08:43:40 +00:00
|
|
|
|
(while (> arg 0)
|
1995-04-09 06:47:22 +00:00
|
|
|
|
(cond ((bolp)
|
|
|
|
|
(if do-left-margin (indent-to (current-left-margin)))
|
|
|
|
|
(if do-fill-prefix (insert-and-inherit fill-prefix))))
|
|
|
|
|
(forward-line 1)
|
1995-01-13 08:43:40 +00:00
|
|
|
|
(setq arg (1- arg)))
|
1995-04-09 06:47:22 +00:00
|
|
|
|
(goto-char loc)
|
|
|
|
|
(end-of-line)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun split-line ()
|
|
|
|
|
"Split current line, moving portion beyond point vertically down."
|
|
|
|
|
(interactive "*")
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
(let ((col (current-column))
|
|
|
|
|
(pos (point)))
|
1995-01-13 08:43:40 +00:00
|
|
|
|
(newline 1)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(indent-to col 0)
|
|
|
|
|
(goto-char pos)))
|
|
|
|
|
|
|
|
|
|
(defun quoted-insert (arg)
|
|
|
|
|
"Read next input character and insert it.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
This is useful for inserting control characters.
|
1993-01-26 01:58:16 +00:00
|
|
|
|
You may also type up to 3 octal digits, to insert a character with that code.
|
1993-03-16 18:18:47 +00:00
|
|
|
|
|
|
|
|
|
In overwrite mode, this function inserts the character anyway, and
|
|
|
|
|
does not handle octal digits specially. This means that if you use
|
|
|
|
|
overwrite as your normal editing mode, you can use this function to
|
|
|
|
|
insert characters when necessary.
|
|
|
|
|
|
|
|
|
|
In binary overwrite mode, this function does overwrite, and octal
|
|
|
|
|
digits are interpreted as a character code. This is supposed to make
|
|
|
|
|
this function useful in editing binary files."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "*p")
|
1993-03-16 18:18:47 +00:00
|
|
|
|
(let ((char (if (or (not overwrite-mode)
|
|
|
|
|
(eq overwrite-mode 'overwrite-mode-binary))
|
|
|
|
|
(read-quoted-char)
|
|
|
|
|
(read-char))))
|
1995-02-17 23:59:43 +00:00
|
|
|
|
(if (> arg 0)
|
|
|
|
|
(if (eq overwrite-mode 'overwrite-mode-binary)
|
|
|
|
|
(delete-char arg)))
|
|
|
|
|
(while (> arg 0)
|
|
|
|
|
(insert-and-inherit char)
|
|
|
|
|
(setq arg (1- arg)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun delete-indentation (&optional arg)
|
|
|
|
|
"Join this line to previous and fix up whitespace at join.
|
1992-07-29 02:15:26 +00:00
|
|
|
|
If there is a fill prefix, delete it from the beginning of this line.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
With argument, join this line to following line."
|
|
|
|
|
(interactive "*P")
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(if arg (forward-line 1))
|
|
|
|
|
(if (eq (preceding-char) ?\n)
|
|
|
|
|
(progn
|
|
|
|
|
(delete-region (point) (1- (point)))
|
1992-07-29 02:15:26 +00:00
|
|
|
|
;; If the second line started with the fill prefix,
|
|
|
|
|
;; delete the prefix.
|
|
|
|
|
(if (and fill-prefix
|
1992-09-30 10:31:31 +00:00
|
|
|
|
(<= (+ (point) (length fill-prefix)) (point-max))
|
1992-07-29 02:15:26 +00:00
|
|
|
|
(string= fill-prefix
|
|
|
|
|
(buffer-substring (point)
|
|
|
|
|
(+ (point) (length fill-prefix)))))
|
|
|
|
|
(delete-region (point) (+ (point) (length fill-prefix))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(fixup-whitespace))))
|
|
|
|
|
|
|
|
|
|
(defun fixup-whitespace ()
|
|
|
|
|
"Fixup white space between objects around point.
|
|
|
|
|
Leave one space or none, according to the context."
|
|
|
|
|
(interactive "*")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(delete-horizontal-space)
|
|
|
|
|
(if (or (looking-at "^\\|\\s)")
|
|
|
|
|
(save-excursion (forward-char -1)
|
|
|
|
|
(looking-at "$\\|\\s(\\|\\s'")))
|
|
|
|
|
nil
|
|
|
|
|
(insert ?\ ))))
|
|
|
|
|
|
|
|
|
|
(defun delete-horizontal-space ()
|
|
|
|
|
"Delete all spaces and tabs around point."
|
|
|
|
|
(interactive "*")
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(delete-region (point) (progn (skip-chars-forward " \t") (point))))
|
|
|
|
|
|
|
|
|
|
(defun just-one-space ()
|
|
|
|
|
"Delete all spaces and tabs around point, leaving one space."
|
|
|
|
|
(interactive "*")
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(if (= (following-char) ? )
|
|
|
|
|
(forward-char 1)
|
|
|
|
|
(insert ? ))
|
|
|
|
|
(delete-region (point) (progn (skip-chars-forward " \t") (point))))
|
|
|
|
|
|
|
|
|
|
(defun delete-blank-lines ()
|
|
|
|
|
"On blank line, delete all surrounding blank lines, leaving just one.
|
|
|
|
|
On isolated blank line, delete that one.
|
1994-06-07 07:47:24 +00:00
|
|
|
|
On nonblank line, delete any immediately following blank lines."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "*")
|
|
|
|
|
(let (thisblank singleblank)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(setq thisblank (looking-at "[ \t]*$"))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
;; Set singleblank if there is just one blank line here.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(setq singleblank
|
|
|
|
|
(and thisblank
|
|
|
|
|
(not (looking-at "[ \t]*\n[ \t]*$"))
|
|
|
|
|
(or (bobp)
|
|
|
|
|
(progn (forward-line -1)
|
|
|
|
|
(not (looking-at "[ \t]*$")))))))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
;; Delete preceding blank lines, and this one too if it's the only one.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if thisblank
|
|
|
|
|
(progn
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(if singleblank (forward-line 1))
|
|
|
|
|
(delete-region (point)
|
|
|
|
|
(if (re-search-backward "[^ \t\n]" nil t)
|
|
|
|
|
(progn (forward-line 1) (point))
|
|
|
|
|
(point-min)))))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
;; Delete following blank lines, unless the current line is blank
|
|
|
|
|
;; and there are no following blank lines.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if (not (and thisblank singleblank))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(forward-line 1)
|
|
|
|
|
(delete-region (point)
|
|
|
|
|
(if (re-search-forward "[^ \t\n]" nil t)
|
|
|
|
|
(progn (beginning-of-line) (point))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(point-max)))))
|
|
|
|
|
;; Handle the special case where point is followed by newline and eob.
|
|
|
|
|
;; Delete the line, leaving point at eob.
|
|
|
|
|
(if (looking-at "^[ \t]*\n\\'")
|
|
|
|
|
(delete-region (point) (point-max)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun back-to-indentation ()
|
|
|
|
|
"Move point to the first non-whitespace character on this line."
|
|
|
|
|
(interactive)
|
|
|
|
|
(beginning-of-line 1)
|
|
|
|
|
(skip-chars-forward " \t"))
|
|
|
|
|
|
|
|
|
|
(defun newline-and-indent ()
|
|
|
|
|
"Insert a newline, then indent according to major mode.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
Indentation is done using the value of `indent-line-function'.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
In programming language modes, this is the same as TAB.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
In some text modes, where TAB inserts a tab, this command indents to the
|
1995-01-19 04:21:56 +00:00
|
|
|
|
column specified by the function `current-left-margin'."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "*")
|
|
|
|
|
(delete-region (point) (progn (skip-chars-backward " \t") (point)))
|
1992-04-19 08:53:55 +00:00
|
|
|
|
(newline)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(indent-according-to-mode))
|
|
|
|
|
|
|
|
|
|
(defun reindent-then-newline-and-indent ()
|
|
|
|
|
"Reindent current line, insert newline, then indent the new line.
|
|
|
|
|
Indentation of both lines is done according to the current major mode,
|
1992-08-21 07:18:16 +00:00
|
|
|
|
which means calling the current value of `indent-line-function'.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
In programming language modes, this is the same as TAB.
|
|
|
|
|
In some text modes, where TAB inserts a tab, this indents to the
|
1995-01-19 04:21:56 +00:00
|
|
|
|
column specified by the function `current-left-margin'."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "*")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(delete-region (point) (progn (skip-chars-backward " \t") (point)))
|
|
|
|
|
(indent-according-to-mode))
|
1992-04-19 08:53:55 +00:00
|
|
|
|
(newline)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(indent-according-to-mode))
|
|
|
|
|
|
1993-04-29 13:57:52 +00:00
|
|
|
|
;; Internal subroutine of delete-char
|
|
|
|
|
(defun kill-forward-chars (arg)
|
|
|
|
|
(if (listp arg) (setq arg (car arg)))
|
|
|
|
|
(if (eq arg '-) (setq arg -1))
|
|
|
|
|
(kill-region (point) (+ (point) arg)))
|
|
|
|
|
|
|
|
|
|
;; Internal subroutine of backward-delete-char
|
|
|
|
|
(defun kill-backward-chars (arg)
|
|
|
|
|
(if (listp arg) (setq arg (car arg)))
|
|
|
|
|
(if (eq arg '-) (setq arg -1))
|
|
|
|
|
(kill-region (point) (- (point) arg)))
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun backward-delete-char-untabify (arg &optional killp)
|
|
|
|
|
"Delete characters backward, changing tabs into spaces.
|
|
|
|
|
Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
|
|
|
|
|
Interactively, ARG is the prefix arg (default 1)
|
1994-08-23 22:58:08 +00:00
|
|
|
|
and KILLP is t if a prefix arg was specified."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "*p\nP")
|
|
|
|
|
(let ((count arg))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(while (and (> count 0) (not (bobp)))
|
|
|
|
|
(if (= (preceding-char) ?\t)
|
|
|
|
|
(let ((col (current-column)))
|
|
|
|
|
(forward-char -1)
|
|
|
|
|
(setq col (- col (current-column)))
|
|
|
|
|
(insert-char ?\ col)
|
|
|
|
|
(delete-char 1)))
|
|
|
|
|
(forward-char -1)
|
|
|
|
|
(setq count (1- count)))))
|
1996-02-29 22:00:50 +00:00
|
|
|
|
(delete-backward-char arg killp))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun zap-to-char (arg char)
|
|
|
|
|
"Kill up to and including ARG'th occurrence of CHAR.
|
|
|
|
|
Goes backward if ARG is negative; error if CHAR not found."
|
|
|
|
|
(interactive "p\ncZap to char: ")
|
|
|
|
|
(kill-region (point) (progn
|
|
|
|
|
(search-forward (char-to-string char) nil nil arg)
|
|
|
|
|
; (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
|
|
|
|
|
(point))))
|
|
|
|
|
|
|
|
|
|
(defun beginning-of-buffer (&optional arg)
|
|
|
|
|
"Move point to the beginning of the buffer; leave mark at previous position.
|
1994-11-28 19:44:16 +00:00
|
|
|
|
With arg N, put point N/10 of the way from the beginning.
|
|
|
|
|
|
|
|
|
|
If the buffer is narrowed, this command uses the beginning and size
|
|
|
|
|
of the accessible part of the buffer.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
|
|
|
|
|
Don't use this command in Lisp programs!
|
1991-12-21 09:29:41 +00:00
|
|
|
|
\(goto-char (point-min)) is faster and avoids clobbering the mark."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(push-mark)
|
1994-11-28 19:44:16 +00:00
|
|
|
|
(let ((size (- (point-max) (point-min))))
|
|
|
|
|
(goto-char (if arg
|
|
|
|
|
(+ (point-min)
|
|
|
|
|
(if (> size 10000)
|
|
|
|
|
;; Avoid overflow for large buffer sizes!
|
|
|
|
|
(* (prefix-numeric-value arg)
|
|
|
|
|
(/ size 10))
|
|
|
|
|
(/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
|
|
|
|
|
(point-min))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if arg (forward-line 1)))
|
|
|
|
|
|
|
|
|
|
(defun end-of-buffer (&optional arg)
|
|
|
|
|
"Move point to the end of the buffer; leave mark at previous position.
|
1994-11-28 19:44:16 +00:00
|
|
|
|
With arg N, put point N/10 of the way from the end.
|
|
|
|
|
|
|
|
|
|
If the buffer is narrowed, this command uses the beginning and size
|
|
|
|
|
of the accessible part of the buffer.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
|
|
|
|
|
Don't use this command in Lisp programs!
|
1991-12-21 09:29:41 +00:00
|
|
|
|
\(goto-char (point-max)) is faster and avoids clobbering the mark."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(push-mark)
|
1994-11-28 19:44:16 +00:00
|
|
|
|
(let ((size (- (point-max) (point-min))))
|
|
|
|
|
(goto-char (if arg
|
|
|
|
|
(- (point-max)
|
|
|
|
|
(if (> size 10000)
|
|
|
|
|
;; Avoid overflow for large buffer sizes!
|
|
|
|
|
(* (prefix-numeric-value arg)
|
|
|
|
|
(/ size 10))
|
|
|
|
|
(/ (* size (prefix-numeric-value arg)) 10)))
|
|
|
|
|
(point-max))))
|
1992-07-22 04:22:42 +00:00
|
|
|
|
;; If we went to a place in the middle of the buffer,
|
|
|
|
|
;; adjust it to the beginning of a line.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if arg (forward-line 1)
|
1992-07-22 04:22:42 +00:00
|
|
|
|
;; If the end of the buffer is not already on the screen,
|
|
|
|
|
;; then scroll specially to put it near, but not at, the bottom.
|
|
|
|
|
(if (let ((old-point (point)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (window-start))
|
|
|
|
|
(vertical-motion (window-height))
|
|
|
|
|
(< (point) old-point)))
|
1994-06-13 23:40:33 +00:00
|
|
|
|
(progn
|
|
|
|
|
(overlay-recenter (point))
|
|
|
|
|
(recenter -3)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun mark-whole-buffer ()
|
1992-06-12 22:23:00 +00:00
|
|
|
|
"Put point at beginning and mark at end of buffer.
|
|
|
|
|
You probably should not use this function in Lisp programs;
|
|
|
|
|
it is usually a mistake for a Lisp function to use any subroutine
|
|
|
|
|
that uses or sets the mark."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(push-mark (point))
|
1993-05-16 15:39:39 +00:00
|
|
|
|
(push-mark (point-max) nil t)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(goto-char (point-min)))
|
|
|
|
|
|
|
|
|
|
(defun count-lines-region (start end)
|
1993-06-09 11:59:12 +00:00
|
|
|
|
"Print number of lines and characters in the region."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "r")
|
|
|
|
|
(message "Region has %d lines, %d characters"
|
|
|
|
|
(count-lines start end) (- end start)))
|
|
|
|
|
|
|
|
|
|
(defun what-line ()
|
1995-08-25 14:16:26 +00:00
|
|
|
|
"Print the current buffer line number and narrowed line number of point."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive)
|
1995-08-25 14:16:26 +00:00
|
|
|
|
(let ((opoint (point)) start)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(save-excursion
|
1995-08-25 14:16:26 +00:00
|
|
|
|
(save-restriction
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(widen)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(setq start (point))
|
|
|
|
|
(goto-char opoint)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(if (/= start 1)
|
|
|
|
|
(message "line %d (narrowed line %d)"
|
|
|
|
|
(1+ (count-lines 1 (point)))
|
|
|
|
|
(1+ (count-lines start (point))))
|
|
|
|
|
(message "Line %d" (1+ (count-lines 1 (point)))))))))
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun count-lines (start end)
|
|
|
|
|
"Return number of lines between START and END.
|
|
|
|
|
This is usually the number of newlines between them,
|
1992-08-21 07:18:16 +00:00
|
|
|
|
but can be one more if START is not equal to END
|
1991-12-21 09:29:41 +00:00
|
|
|
|
and the greater of them is not at the start of a line."
|
1994-10-16 08:20:07 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region start end)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(if (eq selective-display t)
|
|
|
|
|
(save-match-data
|
1993-03-29 19:09:05 +00:00
|
|
|
|
(let ((done 0))
|
|
|
|
|
(while (re-search-forward "[\n\C-m]" nil t 40)
|
|
|
|
|
(setq done (+ 40 done)))
|
|
|
|
|
(while (re-search-forward "[\n\C-m]" nil t 1)
|
|
|
|
|
(setq done (+ 1 done)))
|
1993-11-24 04:35:28 +00:00
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(if (and (/= start end)
|
|
|
|
|
(not (bolp)))
|
|
|
|
|
(1+ done)
|
1994-10-16 08:20:07 +00:00
|
|
|
|
done)))
|
|
|
|
|
(- (buffer-size) (forward-line (buffer-size)))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun what-cursor-position ()
|
|
|
|
|
"Print info on cursor position (on screen and within buffer)."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((char (following-char))
|
|
|
|
|
(beg (point-min))
|
|
|
|
|
(end (point-max))
|
|
|
|
|
(pos (point))
|
|
|
|
|
(total (buffer-size))
|
|
|
|
|
(percent (if (> total 50000)
|
|
|
|
|
;; Avoid overflow from multiplying by 100!
|
|
|
|
|
(/ (+ (/ total 200) (1- pos)) (max (/ total 100) 1))
|
|
|
|
|
(/ (+ (/ total 2) (* 100 (1- pos))) (max total 1))))
|
|
|
|
|
(hscroll (if (= (window-hscroll) 0)
|
|
|
|
|
""
|
|
|
|
|
(format " Hscroll=%d" (window-hscroll))))
|
|
|
|
|
(col (current-column)))
|
|
|
|
|
(if (= pos end)
|
|
|
|
|
(if (or (/= beg 1) (/= end (1+ total)))
|
|
|
|
|
(message "point=%d of %d(%d%%) <%d - %d> column %d %s"
|
|
|
|
|
pos total percent beg end col hscroll)
|
|
|
|
|
(message "point=%d of %d(%d%%) column %d %s"
|
|
|
|
|
pos total percent col hscroll))
|
|
|
|
|
(if (or (/= beg 1) (/= end (1+ total)))
|
1995-01-06 20:48:57 +00:00
|
|
|
|
(message "Char: %s (0%o, %d, 0x%x) point=%d of %d(%d%%) <%d - %d> column %d %s"
|
|
|
|
|
(single-key-description char) char char char pos total percent beg end col hscroll)
|
|
|
|
|
(message "Char: %s (0%o, %d, 0x%x) point=%d of %d(%d%%) column %d %s"
|
|
|
|
|
(single-key-description char) char char char pos total percent col hscroll)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun fundamental-mode ()
|
|
|
|
|
"Major mode not specialized for anything in particular.
|
|
|
|
|
Other major modes are defined by comparison with this one."
|
|
|
|
|
(interactive)
|
|
|
|
|
(kill-all-local-variables))
|
|
|
|
|
|
1993-10-26 18:06:48 +00:00
|
|
|
|
(defvar read-expression-map (cons 'keymap minibuffer-local-map)
|
1992-09-14 06:53:22 +00:00
|
|
|
|
"Minibuffer keymap used for reading Lisp expressions.")
|
|
|
|
|
(define-key read-expression-map "\M-\t" 'lisp-complete-symbol)
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(put 'eval-expression 'disabled t)
|
|
|
|
|
|
1993-07-26 18:32:07 +00:00
|
|
|
|
(defvar read-expression-history nil)
|
|
|
|
|
|
|
|
|
|
;; We define this, rather than making `eval' interactive,
|
1991-12-21 09:29:41 +00:00
|
|
|
|
;; for the sake of completion of names like eval-region, eval-current-buffer.
|
|
|
|
|
(defun eval-expression (expression)
|
|
|
|
|
"Evaluate EXPRESSION and print value in minibuffer.
|
1992-08-11 07:25:06 +00:00
|
|
|
|
Value is also consed on to front of the variable `values'."
|
1993-10-25 06:07:23 +00:00
|
|
|
|
(interactive
|
1993-11-19 17:43:24 +00:00
|
|
|
|
(list (read-from-minibuffer "Eval: "
|
|
|
|
|
nil read-expression-map t
|
|
|
|
|
'read-expression-history)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(setq values (cons (eval expression) values))
|
|
|
|
|
(prin1 (car values) t))
|
|
|
|
|
|
|
|
|
|
(defun edit-and-eval-command (prompt command)
|
|
|
|
|
"Prompting with PROMPT, let user edit COMMAND and eval result.
|
|
|
|
|
COMMAND is a Lisp expression. Let user edit that expression in
|
|
|
|
|
the minibuffer, then read and evaluate the result."
|
1993-11-19 17:43:24 +00:00
|
|
|
|
(let ((command (read-from-minibuffer prompt
|
|
|
|
|
(prin1-to-string command)
|
|
|
|
|
read-expression-map t
|
|
|
|
|
'(command-history . 1))))
|
1994-10-20 20:14:45 +00:00
|
|
|
|
;; If command was added to command-history as a string,
|
1996-01-04 23:20:13 +00:00
|
|
|
|
;; get rid of that. We want only evaluable expressions there.
|
1994-10-20 20:14:45 +00:00
|
|
|
|
(if (stringp (car command-history))
|
|
|
|
|
(setq command-history (cdr command-history)))
|
|
|
|
|
|
|
|
|
|
;; If command to be redone does not match front of history,
|
|
|
|
|
;; add it to the history.
|
|
|
|
|
(or (equal command (car command-history))
|
|
|
|
|
(setq command-history (cons command command-history)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(eval command)))
|
|
|
|
|
|
1992-07-24 03:42:21 +00:00
|
|
|
|
(defun repeat-complex-command (arg)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
"Edit and re-evaluate last complex command, or ARGth from last.
|
|
|
|
|
A complex command is one which used the minibuffer.
|
|
|
|
|
The command is placed in the minibuffer as a Lisp form for editing.
|
|
|
|
|
The result is executed, repeating the command as changed.
|
|
|
|
|
If the command has been changed or is not the most recent previous command
|
|
|
|
|
it is added to the front of the command history.
|
1992-07-24 22:37:33 +00:00
|
|
|
|
You can use the minibuffer history commands \\<minibuffer-local-map>\\[next-history-element] and \\[previous-history-element]
|
|
|
|
|
to get different commands to edit and resubmit."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "p")
|
1992-07-24 06:09:27 +00:00
|
|
|
|
(let ((elt (nth (1- arg) command-history))
|
1992-07-24 03:42:21 +00:00
|
|
|
|
(minibuffer-history-position arg)
|
1992-07-24 06:09:27 +00:00
|
|
|
|
(minibuffer-history-sexp-flag t)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
newcmd)
|
|
|
|
|
(if elt
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(progn
|
1993-10-05 01:19:12 +00:00
|
|
|
|
(setq newcmd
|
1994-09-14 09:01:02 +00:00
|
|
|
|
(let ((print-level nil))
|
|
|
|
|
(read-from-minibuffer
|
|
|
|
|
"Redo: " (prin1-to-string elt) read-expression-map t
|
|
|
|
|
(cons 'command-history arg))))
|
1993-10-05 01:19:12 +00:00
|
|
|
|
|
1993-11-23 11:03:16 +00:00
|
|
|
|
;; If command was added to command-history as a string,
|
1996-01-04 23:20:13 +00:00
|
|
|
|
;; get rid of that. We want only evaluable expressions there.
|
1993-11-23 11:03:16 +00:00
|
|
|
|
(if (stringp (car command-history))
|
|
|
|
|
(setq command-history (cdr command-history)))
|
|
|
|
|
|
|
|
|
|
;; If command to be redone does not match front of history,
|
|
|
|
|
;; add it to the history.
|
|
|
|
|
(or (equal newcmd (car command-history))
|
|
|
|
|
(setq command-history (cons newcmd command-history)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(eval newcmd))
|
|
|
|
|
(ding))))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(defvar minibuffer-history nil
|
|
|
|
|
"Default minibuffer history list.
|
|
|
|
|
This is used for all minibuffer input
|
|
|
|
|
except when an alternate history list is specified.")
|
|
|
|
|
(defvar minibuffer-history-sexp-flag nil
|
1994-05-07 01:17:18 +00:00
|
|
|
|
"Non-nil when doing history operations on `command-history'.
|
1992-09-14 06:53:22 +00:00
|
|
|
|
More generally, indicates that the history list being acted on
|
|
|
|
|
contains expressions rather than strings.")
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(setq minibuffer-history-variable 'minibuffer-history)
|
|
|
|
|
(setq minibuffer-history-position nil)
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(defvar minibuffer-history-search-history nil)
|
1992-07-26 19:54:20 +00:00
|
|
|
|
|
1992-08-04 02:36:45 +00:00
|
|
|
|
(mapcar
|
1993-01-25 00:45:01 +00:00
|
|
|
|
(lambda (key-and-command)
|
|
|
|
|
(mapcar
|
|
|
|
|
(lambda (keymap-and-completionp)
|
|
|
|
|
;; Arg is (KEYMAP-SYMBOL . COMPLETION-MAP-P).
|
|
|
|
|
;; If the cdr of KEY-AND-COMMAND (the command) is a cons,
|
|
|
|
|
;; its car is used if COMPLETION-MAP-P is nil, its cdr if it is t.
|
|
|
|
|
(define-key (symbol-value (car keymap-and-completionp))
|
|
|
|
|
(car key-and-command)
|
|
|
|
|
(let ((command (cdr key-and-command)))
|
|
|
|
|
(if (consp command)
|
1993-01-28 20:22:03 +00:00
|
|
|
|
;; (and ... nil) => ... turns back on the completion-oriented
|
|
|
|
|
;; history commands which rms turned off since they seem to
|
|
|
|
|
;; do things he doesn't like.
|
|
|
|
|
(if (and (cdr keymap-and-completionp) nil) ;XXX turned off
|
1993-02-05 17:41:42 +00:00
|
|
|
|
(progn (error "EMACS BUG!") (cdr command))
|
1993-01-25 00:45:01 +00:00
|
|
|
|
(car command))
|
|
|
|
|
command))))
|
|
|
|
|
'((minibuffer-local-map . nil)
|
|
|
|
|
(minibuffer-local-ns-map . nil)
|
|
|
|
|
(minibuffer-local-completion-map . t)
|
|
|
|
|
(minibuffer-local-must-match-map . t)
|
|
|
|
|
(read-expression-map . nil))))
|
1993-02-05 17:41:42 +00:00
|
|
|
|
'(("\en" . (next-history-element . next-complete-history-element))
|
|
|
|
|
([next] . (next-history-element . next-complete-history-element))
|
|
|
|
|
("\ep" . (previous-history-element . previous-complete-history-element))
|
|
|
|
|
([prior] . (previous-history-element . previous-complete-history-element))
|
1992-08-04 02:36:45 +00:00
|
|
|
|
("\er" . previous-matching-history-element)
|
|
|
|
|
("\es" . next-matching-history-element)))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
|
|
|
|
|
(defun previous-matching-history-element (regexp n)
|
1992-09-14 06:53:22 +00:00
|
|
|
|
"Find the previous history element that matches REGEXP.
|
|
|
|
|
\(Previous history elements refer to earlier actions.)
|
|
|
|
|
With prefix argument N, search for Nth previous match.
|
|
|
|
|
If N is negative, find the next or Nth next match."
|
|
|
|
|
(interactive
|
1993-05-06 18:54:32 +00:00
|
|
|
|
(let* ((enable-recursive-minibuffers t)
|
|
|
|
|
(minibuffer-history-sexp-flag nil)
|
|
|
|
|
(regexp (read-from-minibuffer "Previous element matching (regexp): "
|
|
|
|
|
nil
|
|
|
|
|
minibuffer-local-map
|
|
|
|
|
nil
|
|
|
|
|
'minibuffer-history-search-history)))
|
|
|
|
|
;; Use the last regexp specified, by default, if input is empty.
|
|
|
|
|
(list (if (string= regexp "")
|
1995-05-27 00:40:31 +00:00
|
|
|
|
(if minibuffer-history-search-history
|
|
|
|
|
(car minibuffer-history-search-history)
|
|
|
|
|
(error "No previous history search regexp"))
|
1993-05-06 18:54:32 +00:00
|
|
|
|
regexp)
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(prefix-numeric-value current-prefix-arg))))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(let ((history (symbol-value minibuffer-history-variable))
|
1992-07-29 02:15:26 +00:00
|
|
|
|
prevpos
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(pos minibuffer-history-position))
|
|
|
|
|
(while (/= n 0)
|
|
|
|
|
(setq prevpos pos)
|
|
|
|
|
(setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
|
|
|
|
|
(if (= pos prevpos)
|
|
|
|
|
(error (if (= pos 1)
|
1992-07-29 02:15:26 +00:00
|
|
|
|
"No later matching history item"
|
|
|
|
|
"No earlier matching history item")))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(if (string-match regexp
|
|
|
|
|
(if minibuffer-history-sexp-flag
|
1994-09-14 09:01:02 +00:00
|
|
|
|
(let ((print-level nil))
|
|
|
|
|
(prin1-to-string (nth (1- pos) history)))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(nth (1- pos) history)))
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(setq n (+ n (if (< n 0) 1 -1)))))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(setq minibuffer-history-position pos)
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(let ((elt (nth (1- pos) history)))
|
|
|
|
|
(insert (if minibuffer-history-sexp-flag
|
1994-09-14 09:01:02 +00:00
|
|
|
|
(let ((print-level nil))
|
|
|
|
|
(prin1-to-string elt))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
elt)))
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(goto-char (point-min)))
|
|
|
|
|
(if (or (eq (car (car command-history)) 'previous-matching-history-element)
|
|
|
|
|
(eq (car (car command-history)) 'next-matching-history-element))
|
|
|
|
|
(setq command-history (cdr command-history))))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
|
|
|
|
|
(defun next-matching-history-element (regexp n)
|
1992-09-14 06:53:22 +00:00
|
|
|
|
"Find the next history element that matches REGEXP.
|
|
|
|
|
\(The next history element refers to a more recent action.)
|
|
|
|
|
With prefix argument N, search for Nth next match.
|
|
|
|
|
If N is negative, find the previous or Nth previous match."
|
|
|
|
|
(interactive
|
1993-05-06 18:54:32 +00:00
|
|
|
|
(let* ((enable-recursive-minibuffers t)
|
|
|
|
|
(minibuffer-history-sexp-flag nil)
|
|
|
|
|
(regexp (read-from-minibuffer "Next element matching (regexp): "
|
|
|
|
|
nil
|
|
|
|
|
minibuffer-local-map
|
|
|
|
|
nil
|
|
|
|
|
'minibuffer-history-search-history)))
|
|
|
|
|
;; Use the last regexp specified, by default, if input is empty.
|
|
|
|
|
(list (if (string= regexp "")
|
|
|
|
|
(setcar minibuffer-history-search-history
|
|
|
|
|
(nth 1 minibuffer-history-search-history))
|
|
|
|
|
regexp)
|
1992-09-14 06:53:22 +00:00
|
|
|
|
(prefix-numeric-value current-prefix-arg))))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
(previous-matching-history-element regexp (- n)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1992-07-24 03:42:21 +00:00
|
|
|
|
(defun next-history-element (n)
|
|
|
|
|
"Insert the next element of the minibuffer history into the minibuffer."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "p")
|
1995-02-12 08:27:38 +00:00
|
|
|
|
(or (zerop n)
|
|
|
|
|
(let ((narg (min (max 1 (- minibuffer-history-position n))
|
|
|
|
|
(length (symbol-value minibuffer-history-variable)))))
|
|
|
|
|
(if (or (zerop narg)
|
|
|
|
|
(= minibuffer-history-position narg))
|
|
|
|
|
(error (if (if (zerop narg)
|
|
|
|
|
(> n 0)
|
|
|
|
|
(= minibuffer-history-position 1))
|
|
|
|
|
"End of history; no next item"
|
|
|
|
|
"Beginning of history; no preceding item"))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(setq minibuffer-history-position narg)
|
|
|
|
|
(let ((elt (nth (1- minibuffer-history-position)
|
|
|
|
|
(symbol-value minibuffer-history-variable))))
|
|
|
|
|
(insert
|
|
|
|
|
(if minibuffer-history-sexp-flag
|
|
|
|
|
(let ((print-level nil))
|
|
|
|
|
(prin1-to-string elt))
|
|
|
|
|
elt)))
|
|
|
|
|
(goto-char (point-min))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1992-07-24 03:42:21 +00:00
|
|
|
|
(defun previous-history-element (n)
|
1992-09-15 08:15:41 +00:00
|
|
|
|
"Inserts the previous element of the minibuffer history into the minibuffer."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "p")
|
1992-07-24 03:49:00 +00:00
|
|
|
|
(next-history-element (- n)))
|
1993-01-25 00:45:01 +00:00
|
|
|
|
|
|
|
|
|
(defun next-complete-history-element (n)
|
1993-12-24 02:44:13 +00:00
|
|
|
|
"Get next element of history which is a completion of minibuffer contents."
|
1993-01-25 00:45:01 +00:00
|
|
|
|
(interactive "p")
|
1993-01-28 20:22:03 +00:00
|
|
|
|
(let ((point-at-start (point)))
|
|
|
|
|
(next-matching-history-element
|
|
|
|
|
(concat "^" (regexp-quote (buffer-substring (point-min) (point)))) n)
|
|
|
|
|
;; next-matching-history-element always puts us at (point-min).
|
|
|
|
|
;; Move to the position we were at before changing the buffer contents.
|
|
|
|
|
;; This is still sensical, because the text before point has not changed.
|
|
|
|
|
(goto-char point-at-start)))
|
1993-01-25 00:45:01 +00:00
|
|
|
|
|
|
|
|
|
(defun previous-complete-history-element (n)
|
1993-12-24 02:44:13 +00:00
|
|
|
|
"\
|
|
|
|
|
Get previous element of history which is a completion of minibuffer contents."
|
1993-01-25 00:45:01 +00:00
|
|
|
|
(interactive "p")
|
|
|
|
|
(next-complete-history-element (- n)))
|
1992-07-26 19:54:20 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun goto-line (arg)
|
|
|
|
|
"Goto line ARG, counting from line 1 at beginning of buffer."
|
|
|
|
|
(interactive "NGoto line: ")
|
1994-10-04 22:57:42 +00:00
|
|
|
|
(setq arg (prefix-numeric-value arg))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
|
|
|
|
(goto-char 1)
|
|
|
|
|
(if (eq selective-display t)
|
|
|
|
|
(re-search-forward "[\n\C-m]" nil 'end (1- arg))
|
|
|
|
|
(forward-line (1- arg)))))
|
|
|
|
|
|
|
|
|
|
;Put this on C-x u, so we can force that rather than C-_ into startup msg
|
1993-04-29 13:57:52 +00:00
|
|
|
|
(define-function 'advertised-undo 'undo)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun undo (&optional arg)
|
|
|
|
|
"Undo some previous changes.
|
|
|
|
|
Repeat this command to undo more changes.
|
|
|
|
|
A numeric argument serves as a repeat count."
|
|
|
|
|
(interactive "*p")
|
1994-02-13 00:16:23 +00:00
|
|
|
|
;; If we don't get all the way thru, make last-command indicate that
|
|
|
|
|
;; for the following command.
|
|
|
|
|
(setq this-command t)
|
1993-06-01 20:31:47 +00:00
|
|
|
|
(let ((modified (buffer-modified-p))
|
|
|
|
|
(recent-save (recent-auto-save-p)))
|
1992-03-16 15:23:26 +00:00
|
|
|
|
(or (eq (selected-window) (minibuffer-window))
|
|
|
|
|
(message "Undo!"))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(or (eq last-command 'undo)
|
|
|
|
|
(progn (undo-start)
|
|
|
|
|
(undo-more 1)))
|
|
|
|
|
(undo-more (or arg 1))
|
1994-03-16 23:41:32 +00:00
|
|
|
|
;; Don't specify a position in the undo record for the undo command.
|
|
|
|
|
;; Instead, undoing this should move point to where the change is.
|
|
|
|
|
(let ((tail buffer-undo-list)
|
|
|
|
|
done)
|
|
|
|
|
(while (and tail (not done) (not (null (car tail))))
|
|
|
|
|
(if (integerp (car tail))
|
|
|
|
|
(progn
|
|
|
|
|
(setq done t)
|
|
|
|
|
(setq buffer-undo-list (delq (car tail) buffer-undo-list))))
|
|
|
|
|
(setq tail (cdr tail))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(and modified (not (buffer-modified-p))
|
1994-02-13 00:16:23 +00:00
|
|
|
|
(delete-auto-save-file-if-necessary recent-save)))
|
|
|
|
|
;; If we do get all the way thru, make this-command indicate that.
|
|
|
|
|
(setq this-command 'undo))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1993-05-22 04:21:25 +00:00
|
|
|
|
(defvar pending-undo-list nil
|
|
|
|
|
"Within a run of consecutive undo commands, list remaining to be undone.")
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun undo-start ()
|
1992-08-21 07:18:16 +00:00
|
|
|
|
"Set `pending-undo-list' to the front of the undo list.
|
|
|
|
|
The next call to `undo-more' will undo the most recently made change."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if (eq buffer-undo-list t)
|
|
|
|
|
(error "No undo information in this buffer"))
|
|
|
|
|
(setq pending-undo-list buffer-undo-list))
|
|
|
|
|
|
|
|
|
|
(defun undo-more (count)
|
|
|
|
|
"Undo back N undo-boundaries beyond what was already undone recently.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
Call `undo-start' to get ready to undo recent changes,
|
|
|
|
|
then call `undo-more' one or more times to undo them."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(or pending-undo-list
|
|
|
|
|
(error "No further undo information"))
|
|
|
|
|
(setq pending-undo-list (primitive-undo count pending-undo-list)))
|
|
|
|
|
|
1993-07-31 06:10:44 +00:00
|
|
|
|
(defvar shell-command-history nil
|
|
|
|
|
"History list for some commands that read shell commands.")
|
|
|
|
|
|
1994-11-01 05:50:57 +00:00
|
|
|
|
(defvar shell-command-switch "-c"
|
|
|
|
|
"Switch used to have the shell execute its command line argument.")
|
|
|
|
|
|
1994-10-15 10:16:09 +00:00
|
|
|
|
(defun shell-command (command &optional output-buffer)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
"Execute string COMMAND in inferior shell; display output, if any.
|
1995-03-21 05:14:38 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
If COMMAND ends in ampersand, execute it asynchronously.
|
1995-03-21 05:14:38 +00:00
|
|
|
|
The output appears in the buffer `*Async Shell Command*'.
|
1995-07-17 23:03:53 +00:00
|
|
|
|
That buffer is in shell mode.
|
1995-03-21 05:14:38 +00:00
|
|
|
|
|
1995-07-17 23:03:53 +00:00
|
|
|
|
Otherwise, COMMAND is executed synchronously. The output appears in the
|
|
|
|
|
buffer `*Shell Command Output*'.
|
1995-03-21 05:14:38 +00:00
|
|
|
|
If the output is one line, it is displayed in the echo area *as well*,
|
|
|
|
|
but it is nonetheless available in buffer `*Shell Command Output*',
|
|
|
|
|
even though that buffer is not automatically displayed.
|
|
|
|
|
If there is no output, or if output is inserted in the current buffer,
|
|
|
|
|
then `*Shell Command Output*' is deleted.
|
1994-10-15 10:16:09 +00:00
|
|
|
|
|
|
|
|
|
The optional second argument OUTPUT-BUFFER, if non-nil,
|
|
|
|
|
says to put the output in some other buffer.
|
|
|
|
|
If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
|
|
|
|
|
If OUTPUT-BUFFER is not a buffer and not nil,
|
|
|
|
|
insert output in current buffer. (This cannot be done asynchronously.)
|
|
|
|
|
In either case, the output is inserted after point (leaving mark after it)."
|
1993-08-08 07:47:33 +00:00
|
|
|
|
(interactive (list (read-from-minibuffer "Shell command: "
|
|
|
|
|
nil nil nil 'shell-command-history)
|
|
|
|
|
current-prefix-arg))
|
1996-02-21 21:25:30 +00:00
|
|
|
|
;; Look for a handler in case default-directory is a remote file name.
|
|
|
|
|
(let ((handler
|
|
|
|
|
(find-file-name-handler (directory-file-name default-directory)
|
|
|
|
|
'shell-command)))
|
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'shell-command command output-buffer)
|
|
|
|
|
(if (and output-buffer
|
|
|
|
|
(not (or (bufferp output-buffer) (stringp output-buffer))))
|
|
|
|
|
(progn (barf-if-buffer-read-only)
|
|
|
|
|
(push-mark)
|
|
|
|
|
;; We do not use -f for csh; we will not support broken use of
|
|
|
|
|
;; .cshrcs. Even the BSD csh manual says to use
|
|
|
|
|
;; "if ($?prompt) exit" before things which are not useful
|
|
|
|
|
;; non-interactively. Besides, if someone wants their other
|
|
|
|
|
;; aliases for shell commands then they can still have them.
|
|
|
|
|
(call-process shell-file-name nil t nil
|
|
|
|
|
shell-command-switch command)
|
|
|
|
|
;; This is like exchange-point-and-mark, but doesn't
|
|
|
|
|
;; activate the mark. It is cleaner to avoid activation,
|
|
|
|
|
;; even though the command loop would deactivate the mark
|
|
|
|
|
;; because we inserted text.
|
|
|
|
|
(goto-char (prog1 (mark t)
|
|
|
|
|
(set-marker (mark-marker) (point)
|
|
|
|
|
(current-buffer)))))
|
|
|
|
|
;; Preserve the match data in case called from a program.
|
|
|
|
|
(save-match-data
|
|
|
|
|
(if (string-match "[ \t]*&[ \t]*$" command)
|
|
|
|
|
;; Command ending with ampersand means asynchronous.
|
|
|
|
|
(let ((buffer (get-buffer-create
|
|
|
|
|
(or output-buffer "*Async Shell Command*")))
|
|
|
|
|
(directory default-directory)
|
|
|
|
|
proc)
|
|
|
|
|
;; Remove the ampersand.
|
|
|
|
|
(setq command (substring command 0 (match-beginning 0)))
|
|
|
|
|
;; If will kill a process, query first.
|
|
|
|
|
(setq proc (get-buffer-process buffer))
|
|
|
|
|
(if proc
|
|
|
|
|
(if (yes-or-no-p "A command is running. Kill it? ")
|
|
|
|
|
(kill-process proc)
|
|
|
|
|
(error "Shell command in progress")))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(setq buffer-read-only nil)
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(display-buffer buffer)
|
|
|
|
|
(setq default-directory directory)
|
|
|
|
|
(setq proc (start-process "Shell" buffer shell-file-name
|
|
|
|
|
shell-command-switch command))
|
|
|
|
|
(setq mode-line-process '(":%s"))
|
|
|
|
|
(require 'shell) (shell-mode)
|
|
|
|
|
(set-process-sentinel proc 'shell-command-sentinel)
|
|
|
|
|
))
|
1996-08-17 02:10:31 +00:00
|
|
|
|
(shell-command-on-region (point) (point) command output-buffer)
|
1996-02-21 21:25:30 +00:00
|
|
|
|
))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
;; We have a sentinel to prevent insertion of a termination message
|
|
|
|
|
;; in the buffer itself.
|
|
|
|
|
(defun shell-command-sentinel (process signal)
|
1995-07-17 23:03:53 +00:00
|
|
|
|
(if (memq (process-status process) '(exit signal))
|
|
|
|
|
(message "%s: %s."
|
|
|
|
|
(car (cdr (cdr (process-command process))))
|
|
|
|
|
(substring signal 0 -1))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1994-10-15 10:16:09 +00:00
|
|
|
|
(defun shell-command-on-region (start end command
|
1995-02-28 18:04:57 +00:00
|
|
|
|
&optional output-buffer replace)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
"Execute string COMMAND in inferior shell with region as input.
|
|
|
|
|
Normally display output (if any) in temp buffer `*Shell Command Output*';
|
|
|
|
|
Prefix arg means replace the region with it.
|
1995-02-28 18:04:57 +00:00
|
|
|
|
|
|
|
|
|
The noninteractive arguments are START, END, COMMAND, OUTPUT-BUFFER, REPLACE.
|
|
|
|
|
If REPLACE is non-nil, that means insert the output
|
1995-03-03 06:48:20 +00:00
|
|
|
|
in place of text from START to END, putting point and mark around it.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
If the output is one line, it is displayed in the echo area,
|
|
|
|
|
but it is nonetheless available in buffer `*Shell Command Output*'
|
1995-02-28 18:04:57 +00:00
|
|
|
|
even though that buffer is not automatically displayed.
|
1995-03-01 03:42:18 +00:00
|
|
|
|
If there is no output, or if output is inserted in the current buffer,
|
1995-02-28 18:04:57 +00:00
|
|
|
|
then `*Shell Command Output*' is deleted.
|
1994-10-15 10:16:09 +00:00
|
|
|
|
|
1995-02-28 18:04:57 +00:00
|
|
|
|
If the optional fourth argument OUTPUT-BUFFER is non-nil,
|
|
|
|
|
that says to put the output in some other buffer.
|
1994-10-15 10:16:09 +00:00
|
|
|
|
If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
|
|
|
|
|
If OUTPUT-BUFFER is not a buffer and not nil,
|
|
|
|
|
insert output in the current buffer.
|
|
|
|
|
In either case, the output is inserted after point (leaving mark after it)."
|
1995-02-23 05:02:54 +00:00
|
|
|
|
(interactive (let ((string
|
|
|
|
|
;; Do this before calling region-beginning
|
|
|
|
|
;; and region-end, in case subprocess output
|
|
|
|
|
;; relocates them while we are in the minibuffer.
|
|
|
|
|
(read-from-minibuffer "Shell command on region: "
|
|
|
|
|
nil nil nil
|
|
|
|
|
'shell-command-history)))
|
1995-11-10 17:33:26 +00:00
|
|
|
|
;; call-interactively recognizes region-beginning and
|
|
|
|
|
;; region-end specially, leaving them in the history.
|
|
|
|
|
(list (region-beginning) (region-end)
|
1995-02-23 05:02:54 +00:00
|
|
|
|
string
|
|
|
|
|
current-prefix-arg
|
1995-03-03 06:48:20 +00:00
|
|
|
|
current-prefix-arg)))
|
|
|
|
|
(if (or replace
|
|
|
|
|
(and output-buffer
|
1995-12-21 18:08:12 +00:00
|
|
|
|
(not (or (bufferp output-buffer) (stringp output-buffer))))
|
|
|
|
|
(equal (buffer-name (current-buffer)) "*Shell Command Output*"))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
;; Replace specified region with output from command.
|
1995-08-12 09:22:04 +00:00
|
|
|
|
(let ((swap (and replace (< start end))))
|
1995-03-03 06:48:20 +00:00
|
|
|
|
;; Don't muck with mark unless REPLACE says we should.
|
|
|
|
|
(goto-char start)
|
1995-02-28 18:04:57 +00:00
|
|
|
|
(and replace (push-mark))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(call-process-region start end shell-file-name t t nil
|
1994-11-01 05:50:57 +00:00
|
|
|
|
shell-command-switch command)
|
1994-08-24 00:55:52 +00:00
|
|
|
|
(let ((shell-buffer (get-buffer "*Shell Command Output*")))
|
|
|
|
|
(and shell-buffer (not (eq shell-buffer (current-buffer)))
|
|
|
|
|
(kill-buffer shell-buffer)))
|
1995-03-03 06:48:20 +00:00
|
|
|
|
;; Don't muck with mark unless REPLACE says we should.
|
1995-02-28 18:04:57 +00:00
|
|
|
|
(and replace swap (exchange-point-and-mark)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
;; No prefix argument: put the output in a temp buffer,
|
|
|
|
|
;; replacing its entire contents.
|
1994-10-15 10:16:09 +00:00
|
|
|
|
(let ((buffer (get-buffer-create
|
|
|
|
|
(or output-buffer "*Shell Command Output*")))
|
1994-01-19 15:25:32 +00:00
|
|
|
|
(success nil))
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(if (eq buffer (current-buffer))
|
|
|
|
|
;; If the input is the same buffer as the output,
|
|
|
|
|
;; delete everything but the specified region,
|
|
|
|
|
;; then replace that region with the output.
|
1994-09-24 04:52:10 +00:00
|
|
|
|
(progn (setq buffer-read-only nil)
|
1995-08-12 09:22:04 +00:00
|
|
|
|
(delete-region (max start end) (point-max))
|
1996-04-30 03:21:44 +00:00
|
|
|
|
(delete-region (point-min) (min start end))
|
1994-01-19 15:25:32 +00:00
|
|
|
|
(call-process-region (point-min) (point-max)
|
|
|
|
|
shell-file-name t t nil
|
1994-11-01 05:50:57 +00:00
|
|
|
|
shell-command-switch command)
|
1994-01-19 15:25:32 +00:00
|
|
|
|
(setq success t))
|
|
|
|
|
;; Clear the output buffer, then run the command with output there.
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buffer)
|
1994-09-24 04:52:10 +00:00
|
|
|
|
(setq buffer-read-only nil)
|
1994-01-19 15:25:32 +00:00
|
|
|
|
(erase-buffer))
|
|
|
|
|
(call-process-region start end shell-file-name
|
|
|
|
|
nil buffer nil
|
1994-11-01 05:50:57 +00:00
|
|
|
|
shell-command-switch command)
|
1994-01-19 15:25:32 +00:00
|
|
|
|
(setq success t))
|
|
|
|
|
;; Report the amount of output.
|
|
|
|
|
(let ((lines (save-excursion
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(if (= (buffer-size) 0)
|
|
|
|
|
0
|
|
|
|
|
(count-lines (point-min) (point-max))))))
|
|
|
|
|
(cond ((= lines 0)
|
|
|
|
|
(if success
|
|
|
|
|
(message "(Shell command completed with no output)"))
|
|
|
|
|
(kill-buffer buffer))
|
|
|
|
|
((and success (= lines 1))
|
|
|
|
|
(message "%s"
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(buffer-substring (point)
|
1994-05-10 05:13:14 +00:00
|
|
|
|
(progn (end-of-line) (point))))))
|
1994-01-19 15:25:32 +00:00
|
|
|
|
(t
|
1996-05-30 20:44:17 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(goto-char (point-min)))
|
|
|
|
|
(display-buffer buffer))))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(defconst universal-argument-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map [t] 'universal-argument-other-key)
|
1995-06-19 16:15:06 +00:00
|
|
|
|
(define-key map (vector meta-prefix-char t) 'universal-argument-other-key)
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(define-key map [switch-frame] nil)
|
|
|
|
|
(define-key map [?\C-u] 'universal-argument-more)
|
|
|
|
|
(define-key map [?-] 'universal-argument-minus)
|
|
|
|
|
(define-key map [?0] 'digit-argument)
|
|
|
|
|
(define-key map [?1] 'digit-argument)
|
|
|
|
|
(define-key map [?2] 'digit-argument)
|
|
|
|
|
(define-key map [?3] 'digit-argument)
|
|
|
|
|
(define-key map [?4] 'digit-argument)
|
|
|
|
|
(define-key map [?5] 'digit-argument)
|
|
|
|
|
(define-key map [?6] 'digit-argument)
|
|
|
|
|
(define-key map [?7] 'digit-argument)
|
|
|
|
|
(define-key map [?8] 'digit-argument)
|
|
|
|
|
(define-key map [?9] 'digit-argument)
|
|
|
|
|
map)
|
|
|
|
|
"Keymap used while processing \\[universal-argument].")
|
|
|
|
|
|
1995-06-20 14:25:36 +00:00
|
|
|
|
(defvar universal-argument-num-events nil
|
|
|
|
|
"Number of argument-specifying events read by `universal-argument'.
|
|
|
|
|
`universal-argument-other-key' uses this to discard those events
|
|
|
|
|
from (this-command-keys), and reread only the final command.")
|
|
|
|
|
|
1995-06-14 22:30:41 +00:00
|
|
|
|
(defun universal-argument ()
|
|
|
|
|
"Begin a numeric argument for the following command.
|
|
|
|
|
Digits or minus sign following \\[universal-argument] make up the numeric argument.
|
|
|
|
|
\\[universal-argument] following the digits or minus sign ends the argument.
|
|
|
|
|
\\[universal-argument] without digits or minus sign provides 4 as argument.
|
|
|
|
|
Repeating \\[universal-argument] without digits or minus sign
|
|
|
|
|
multiplies the argument by 4 each time."
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(setq prefix-arg (list 4))
|
1995-06-20 14:25:36 +00:00
|
|
|
|
(setq universal-argument-num-events (length (this-command-keys)))
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(setq overriding-terminal-local-map universal-argument-map))
|
1995-06-14 22:30:41 +00:00
|
|
|
|
|
1995-06-16 06:14:44 +00:00
|
|
|
|
;; A subsequent C-u means to multiply the factor by 4 if we've typed
|
|
|
|
|
;; nothing but C-u's; otherwise it means to terminate the prefix arg.
|
|
|
|
|
(defun universal-argument-more (arg)
|
1995-06-14 22:30:41 +00:00
|
|
|
|
(interactive "P")
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(if (consp arg)
|
|
|
|
|
(setq prefix-arg (list (* 4 (car arg))))
|
|
|
|
|
(setq prefix-arg arg)
|
1995-06-20 14:25:36 +00:00
|
|
|
|
(setq overriding-terminal-local-map nil))
|
|
|
|
|
(setq universal-argument-num-events (length (this-command-keys))))
|
1995-06-14 22:30:41 +00:00
|
|
|
|
|
|
|
|
|
(defun negative-argument (arg)
|
|
|
|
|
"Begin a negative numeric argument for the next command.
|
|
|
|
|
\\[universal-argument] following digits or minus sign ends the argument."
|
|
|
|
|
(interactive "P")
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(cond ((integerp arg)
|
|
|
|
|
(setq prefix-arg (- arg)))
|
|
|
|
|
((eq arg '-)
|
|
|
|
|
(setq prefix-arg nil))
|
|
|
|
|
(t
|
1995-06-19 16:15:06 +00:00
|
|
|
|
(setq prefix-arg '-)))
|
1995-06-20 14:25:36 +00:00
|
|
|
|
(setq universal-argument-num-events (length (this-command-keys)))
|
1995-06-19 16:15:06 +00:00
|
|
|
|
(setq overriding-terminal-local-map universal-argument-map))
|
1995-06-16 06:14:44 +00:00
|
|
|
|
|
|
|
|
|
(defun digit-argument (arg)
|
|
|
|
|
"Part of the numeric argument for the next command.
|
|
|
|
|
\\[universal-argument] following digits or minus sign ends the argument."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((digit (- (logand last-command-char ?\177) ?0)))
|
|
|
|
|
(cond ((integerp arg)
|
|
|
|
|
(setq prefix-arg (+ (* arg 10)
|
|
|
|
|
(if (< arg 0) (- digit) digit))))
|
|
|
|
|
((eq arg '-)
|
|
|
|
|
;; Treat -0 as just -, so that -01 will work.
|
|
|
|
|
(setq prefix-arg (if (zerop digit) '- (- digit))))
|
|
|
|
|
(t
|
1995-06-19 16:15:06 +00:00
|
|
|
|
(setq prefix-arg digit))))
|
1995-06-20 14:25:36 +00:00
|
|
|
|
(setq universal-argument-num-events (length (this-command-keys)))
|
1995-06-19 16:15:06 +00:00
|
|
|
|
(setq overriding-terminal-local-map universal-argument-map))
|
1995-06-16 06:14:44 +00:00
|
|
|
|
|
|
|
|
|
;; For backward compatibility, minus with no modifiers is an ordinary
|
|
|
|
|
;; command if digits have already been entered.
|
|
|
|
|
(defun universal-argument-minus (arg)
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (integerp arg)
|
|
|
|
|
(universal-argument-other-key arg)
|
|
|
|
|
(negative-argument arg)))
|
|
|
|
|
|
|
|
|
|
;; Anything else terminates the argument and is left in the queue to be
|
|
|
|
|
;; executed as a command.
|
|
|
|
|
(defun universal-argument-other-key (arg)
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq prefix-arg arg)
|
1995-06-20 14:25:36 +00:00
|
|
|
|
(let* ((key (this-command-keys))
|
|
|
|
|
(keylist (listify-key-sequence key)))
|
|
|
|
|
(setq unread-command-events
|
1995-11-11 23:56:47 +00:00
|
|
|
|
(append (nthcdr universal-argument-num-events keylist)
|
|
|
|
|
unread-command-events)))
|
1995-06-19 20:10:21 +00:00
|
|
|
|
(reset-this-command-lengths)
|
1995-06-16 06:14:44 +00:00
|
|
|
|
(setq overriding-terminal-local-map nil))
|
1995-06-14 22:30:41 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun forward-to-indentation (arg)
|
|
|
|
|
"Move forward ARG lines and position at first nonblank character."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(forward-line arg)
|
|
|
|
|
(skip-chars-forward " \t"))
|
|
|
|
|
|
|
|
|
|
(defun backward-to-indentation (arg)
|
|
|
|
|
"Move backward ARG lines and position at first nonblank character."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(forward-line (- arg))
|
|
|
|
|
(skip-chars-forward " \t"))
|
|
|
|
|
|
1993-04-23 06:50:37 +00:00
|
|
|
|
(defvar kill-whole-line nil
|
1993-04-29 13:57:52 +00:00
|
|
|
|
"*If non-nil, `kill-line' with no arg at beg of line kills the whole line.")
|
1993-04-23 06:50:37 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun kill-line (&optional arg)
|
1993-04-29 13:57:52 +00:00
|
|
|
|
"Kill the rest of the current line; if no nonblanks there, kill thru newline.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
With prefix argument, kill that many lines from point.
|
|
|
|
|
Negative arguments kill lines backward.
|
|
|
|
|
|
|
|
|
|
When calling from a program, nil means \"no arg\",
|
1993-04-29 13:57:52 +00:00
|
|
|
|
a number counts as a prefix arg.
|
|
|
|
|
|
|
|
|
|
If `kill-whole-line' is non-nil, then kill the whole line
|
|
|
|
|
when given no argument at the beginning of a line."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(kill-region (point)
|
1994-04-24 05:44:23 +00:00
|
|
|
|
;; It is better to move point to the other end of the kill
|
|
|
|
|
;; before killing. That way, in a read-only buffer, point
|
|
|
|
|
;; moves across the text that is copied to the kill ring.
|
|
|
|
|
;; The choice has no effect on undo now that undo records
|
|
|
|
|
;; the value of point from before the command was run.
|
|
|
|
|
(progn
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if arg
|
|
|
|
|
(forward-line (prefix-numeric-value arg))
|
|
|
|
|
(if (eobp)
|
|
|
|
|
(signal 'end-of-buffer nil))
|
1993-04-23 06:50:37 +00:00
|
|
|
|
(if (or (looking-at "[ \t]*$") (and kill-whole-line (bolp)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(forward-line 1)
|
|
|
|
|
(end-of-line)))
|
|
|
|
|
(point))))
|
|
|
|
|
|
1992-06-12 22:23:00 +00:00
|
|
|
|
;;;; Window system cut and paste hooks.
|
|
|
|
|
|
|
|
|
|
(defvar interprogram-cut-function nil
|
|
|
|
|
"Function to call to make a killed region available to other programs.
|
|
|
|
|
|
|
|
|
|
Most window systems provide some sort of facility for cutting and
|
1993-05-24 21:19:08 +00:00
|
|
|
|
pasting text between the windows of different programs.
|
|
|
|
|
This variable holds a function that Emacs calls whenever text
|
|
|
|
|
is put in the kill ring, to make the new kill available to other
|
1992-06-12 22:23:00 +00:00
|
|
|
|
programs.
|
|
|
|
|
|
1993-05-24 21:19:08 +00:00
|
|
|
|
The function takes one or two arguments.
|
|
|
|
|
The first argument, TEXT, is a string containing
|
|
|
|
|
the text which should be made available.
|
|
|
|
|
The second, PUSH, if non-nil means this is a \"new\" kill;
|
|
|
|
|
nil means appending to an \"old\" kill.")
|
1992-06-12 22:23:00 +00:00
|
|
|
|
|
|
|
|
|
(defvar interprogram-paste-function nil
|
|
|
|
|
"Function to call to get text cut from other programs.
|
|
|
|
|
|
|
|
|
|
Most window systems provide some sort of facility for cutting and
|
1993-05-24 21:19:08 +00:00
|
|
|
|
pasting text between the windows of different programs.
|
|
|
|
|
This variable holds a function that Emacs calls to obtain
|
1992-06-12 22:23:00 +00:00
|
|
|
|
text that other programs have provided for pasting.
|
|
|
|
|
|
|
|
|
|
The function should be called with no arguments. If the function
|
|
|
|
|
returns nil, then no other program has provided such text, and the top
|
|
|
|
|
of the Emacs kill ring should be used. If the function returns a
|
1992-06-24 05:09:26 +00:00
|
|
|
|
string, that string should be put in the kill ring as the latest kill.
|
|
|
|
|
|
|
|
|
|
Note that the function should return a string only if a program other
|
|
|
|
|
than Emacs has provided a string for pasting; if Emacs provided the
|
|
|
|
|
most recent string, the function should return nil. If it is
|
|
|
|
|
difficult to tell whether Emacs or some other program provided the
|
|
|
|
|
current string, it is probably good enough to return nil if the string
|
|
|
|
|
is equal (according to `string=') to the last text Emacs provided.")
|
1992-06-12 22:23:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;; The kill ring data structure.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defvar kill-ring nil
|
1992-06-12 22:23:00 +00:00
|
|
|
|
"List of killed text sequences.
|
|
|
|
|
Since the kill ring is supposed to interact nicely with cut-and-paste
|
|
|
|
|
facilities offered by window systems, use of this variable should
|
|
|
|
|
interact nicely with `interprogram-cut-function' and
|
|
|
|
|
`interprogram-paste-function'. The functions `kill-new',
|
|
|
|
|
`kill-append', and `current-kill' are supposed to implement this
|
|
|
|
|
interaction; you may want to use them instead of manipulating the kill
|
|
|
|
|
ring directly.")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defconst kill-ring-max 30
|
|
|
|
|
"*Maximum length of kill ring before oldest elements are thrown away.")
|
|
|
|
|
|
|
|
|
|
(defvar kill-ring-yank-pointer nil
|
|
|
|
|
"The tail of the kill ring whose car is the last thing yanked.")
|
|
|
|
|
|
1994-09-15 21:30:21 +00:00
|
|
|
|
(defun kill-new (string &optional replace)
|
1992-06-12 22:23:00 +00:00
|
|
|
|
"Make STRING the latest kill in the kill ring.
|
|
|
|
|
Set the kill-ring-yank pointer to point to it.
|
1994-09-15 21:30:21 +00:00
|
|
|
|
If `interprogram-cut-function' is non-nil, apply it to STRING.
|
|
|
|
|
Optional second argument REPLACE non-nil means that STRING will replace
|
|
|
|
|
the front of the kill ring, rather than being added to the list."
|
1994-09-15 22:19:50 +00:00
|
|
|
|
(and (fboundp 'menu-bar-update-yank-menu)
|
|
|
|
|
(menu-bar-update-yank-menu string (and replace (car kill-ring))))
|
1994-09-15 21:30:21 +00:00
|
|
|
|
(if replace
|
|
|
|
|
(setcar kill-ring string)
|
|
|
|
|
(setq kill-ring (cons string kill-ring))
|
|
|
|
|
(if (> (length kill-ring) kill-ring-max)
|
|
|
|
|
(setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(setq kill-ring-yank-pointer kill-ring)
|
|
|
|
|
(if interprogram-cut-function
|
1995-08-30 19:33:08 +00:00
|
|
|
|
(funcall interprogram-cut-function string (not replace))))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun kill-append (string before-p)
|
1992-06-12 22:23:00 +00:00
|
|
|
|
"Append STRING to the end of the latest kill in the kill ring.
|
|
|
|
|
If BEFORE-P is non-nil, prepend STRING to the kill.
|
1993-01-11 05:10:15 +00:00
|
|
|
|
If `interprogram-cut-function' is set, pass the resulting kill to
|
1992-06-12 22:23:00 +00:00
|
|
|
|
it."
|
1994-09-15 21:30:21 +00:00
|
|
|
|
(kill-new (if before-p
|
|
|
|
|
(concat string (car kill-ring))
|
|
|
|
|
(concat (car kill-ring) string)) t))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
|
|
|
|
|
(defun current-kill (n &optional do-not-move)
|
|
|
|
|
"Rotate the yanking point by N places, and then return that kill.
|
|
|
|
|
If N is zero, `interprogram-paste-function' is set, and calling it
|
|
|
|
|
returns a string, then that string is added to the front of the
|
|
|
|
|
kill ring and returned as the latest kill.
|
|
|
|
|
If optional arg DO-NOT-MOVE is non-nil, then don't actually move the
|
|
|
|
|
yanking point; just return the Nth kill forward."
|
|
|
|
|
(let ((interprogram-paste (and (= n 0)
|
|
|
|
|
interprogram-paste-function
|
|
|
|
|
(funcall interprogram-paste-function))))
|
|
|
|
|
(if interprogram-paste
|
|
|
|
|
(progn
|
|
|
|
|
;; Disable the interprogram cut function when we add the new
|
|
|
|
|
;; text to the kill ring, so Emacs doesn't try to own the
|
|
|
|
|
;; selection, with identical text.
|
|
|
|
|
(let ((interprogram-cut-function nil))
|
|
|
|
|
(kill-new interprogram-paste))
|
|
|
|
|
interprogram-paste)
|
|
|
|
|
(or kill-ring (error "Kill ring is empty"))
|
1993-08-10 04:14:17 +00:00
|
|
|
|
(let ((ARGth-kill-element
|
|
|
|
|
(nthcdr (mod (- n (length kill-ring-yank-pointer))
|
|
|
|
|
(length kill-ring))
|
|
|
|
|
kill-ring)))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(or do-not-move
|
|
|
|
|
(setq kill-ring-yank-pointer ARGth-kill-element))
|
|
|
|
|
(car ARGth-kill-element)))))
|
1992-05-30 21:11:25 +00:00
|
|
|
|
|
|
|
|
|
|
1992-06-12 22:23:00 +00:00
|
|
|
|
|
|
|
|
|
;;;; Commands for manipulating the kill ring.
|
1992-05-30 21:11:25 +00:00
|
|
|
|
|
1994-04-24 05:44:23 +00:00
|
|
|
|
(defvar kill-read-only-ok nil
|
|
|
|
|
"*Non-nil means don't signal an error for killing read-only text.")
|
|
|
|
|
|
1996-02-06 23:56:47 +00:00
|
|
|
|
(put 'text-read-only 'error-conditions
|
|
|
|
|
'(text-read-only buffer-read-only error))
|
|
|
|
|
(put 'text-read-only 'error-message "Text is read-only")
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun kill-region (beg end)
|
|
|
|
|
"Kill between point and mark.
|
|
|
|
|
The text is deleted but saved in the kill ring.
|
|
|
|
|
The command \\[yank] can retrieve it from there.
|
|
|
|
|
\(If you want to kill and then yank immediately, use \\[copy-region-as-kill].)
|
1993-02-01 22:31:17 +00:00
|
|
|
|
If the buffer is read-only, Emacs will beep and refrain from deleting
|
|
|
|
|
the text, but put the text in the kill ring anyway. This means that
|
|
|
|
|
you can use the killing commands to copy text from a read-only buffer.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
This is the primitive for programs to kill text (as opposed to deleting it).
|
|
|
|
|
Supply two arguments, character numbers indicating the stretch of text
|
|
|
|
|
to be killed.
|
|
|
|
|
Any command that calls this function is a \"kill command\".
|
|
|
|
|
If the previous command was also a kill command,
|
|
|
|
|
the text killed this time appends to the text killed last time
|
|
|
|
|
to make one entry in the kill ring."
|
1993-02-01 22:31:17 +00:00
|
|
|
|
(interactive "r")
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(cond
|
1993-02-01 22:31:17 +00:00
|
|
|
|
|
|
|
|
|
;; If the buffer is read-only, we should beep, in case the person
|
|
|
|
|
;; just isn't aware of this. However, there's no harm in putting
|
|
|
|
|
;; the region's text in the kill ring, anyway.
|
1996-08-21 16:20:39 +00:00
|
|
|
|
((and (not inhibit-read-only)
|
|
|
|
|
(or buffer-read-only
|
|
|
|
|
(text-property-not-all beg end 'read-only nil)))
|
1993-02-01 22:31:17 +00:00
|
|
|
|
(copy-region-as-kill beg end)
|
1993-03-02 07:33:17 +00:00
|
|
|
|
;; This should always barf, and give us the correct error.
|
1994-04-24 05:44:23 +00:00
|
|
|
|
(if kill-read-only-ok
|
|
|
|
|
(message "Read only text copied to kill ring")
|
1994-11-18 07:47:19 +00:00
|
|
|
|
(setq this-command 'kill-region)
|
1996-02-06 23:56:47 +00:00
|
|
|
|
;; Signal an error if the buffer is read-only.
|
|
|
|
|
(barf-if-buffer-read-only)
|
|
|
|
|
;; If the buffer isn't read-only, the text is.
|
|
|
|
|
(signal 'text-read-only (list (current-buffer)))))
|
1993-02-01 22:31:17 +00:00
|
|
|
|
|
|
|
|
|
;; In certain cases, we can arrange for the undo list and the kill
|
|
|
|
|
;; ring to share the same string object. This code does that.
|
1992-06-12 22:23:00 +00:00
|
|
|
|
((not (or (eq buffer-undo-list t)
|
|
|
|
|
(eq last-command 'kill-region)
|
1994-11-22 02:52:14 +00:00
|
|
|
|
;; Use = since positions may be numbers or markers.
|
|
|
|
|
(= beg end)))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
;; Don't let the undo list be truncated before we can even access it.
|
1993-07-03 19:12:35 +00:00
|
|
|
|
(let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100))
|
|
|
|
|
(old-list buffer-undo-list)
|
|
|
|
|
tail)
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(delete-region beg end)
|
1993-07-03 19:12:35 +00:00
|
|
|
|
;; Search back in buffer-undo-list for this string,
|
|
|
|
|
;; in case a change hook made property changes.
|
|
|
|
|
(setq tail buffer-undo-list)
|
|
|
|
|
(while (not (stringp (car (car tail))))
|
|
|
|
|
(setq tail (cdr tail)))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
;; Take the same string recorded for undo
|
|
|
|
|
;; and put it in the kill-ring.
|
1994-11-18 07:47:19 +00:00
|
|
|
|
(kill-new (car (car tail)))))
|
1993-02-01 22:31:17 +00:00
|
|
|
|
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(t
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(copy-region-as-kill beg end)
|
1994-11-18 07:47:19 +00:00
|
|
|
|
(delete-region beg end)))
|
|
|
|
|
(setq this-command 'kill-region))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1994-11-09 22:10:55 +00:00
|
|
|
|
;; copy-region-as-kill no longer sets this-command, because it's confusing
|
|
|
|
|
;; to get two copies of the text when the user accidentally types M-w and
|
|
|
|
|
;; then corrects it with the intended C-w.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun copy-region-as-kill (beg end)
|
|
|
|
|
"Save the region as if killed, but don't kill it.
|
1992-04-19 08:53:55 +00:00
|
|
|
|
If `interprogram-cut-function' is non-nil, also save the text for a window
|
|
|
|
|
system cut and paste."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "r")
|
|
|
|
|
(if (eq last-command 'kill-region)
|
|
|
|
|
(kill-append (buffer-substring beg end) (< end beg))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(kill-new (buffer-substring beg end)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(defun kill-ring-save (beg end)
|
1993-03-11 07:07:17 +00:00
|
|
|
|
"Save the region as if killed, but don't kill it.
|
1993-06-04 02:39:51 +00:00
|
|
|
|
This command is similar to `copy-region-as-kill', except that it gives
|
1993-03-11 07:07:17 +00:00
|
|
|
|
visual feedback indicating the extent of the region being copied.
|
|
|
|
|
If `interprogram-cut-function' is non-nil, also save the text for a window
|
|
|
|
|
system cut and paste."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "r")
|
|
|
|
|
(copy-region-as-kill beg end)
|
1992-07-22 04:22:42 +00:00
|
|
|
|
(if (interactive-p)
|
1993-05-17 21:52:21 +00:00
|
|
|
|
(let ((other-end (if (= (point) beg) end beg))
|
|
|
|
|
(opoint (point))
|
|
|
|
|
;; Inhibit quitting so we can make a quit here
|
|
|
|
|
;; look like a C-g typed as a command.
|
|
|
|
|
(inhibit-quit t))
|
|
|
|
|
(if (pos-visible-in-window-p other-end (selected-window))
|
|
|
|
|
(progn
|
|
|
|
|
;; Swap point and mark.
|
|
|
|
|
(set-marker (mark-marker) (point) (current-buffer))
|
|
|
|
|
(goto-char other-end)
|
|
|
|
|
(sit-for 1)
|
|
|
|
|
;; Swap back.
|
|
|
|
|
(set-marker (mark-marker) other-end (current-buffer))
|
|
|
|
|
(goto-char opoint)
|
|
|
|
|
;; If user quit, deactivate the mark
|
|
|
|
|
;; as C-g would as a command.
|
1993-07-08 22:42:14 +00:00
|
|
|
|
(and quit-flag mark-active
|
1993-07-26 07:31:11 +00:00
|
|
|
|
(deactivate-mark)))
|
1993-05-17 21:52:21 +00:00
|
|
|
|
(let* ((killed-text (current-kill 0))
|
|
|
|
|
(message-len (min (length killed-text) 40)))
|
|
|
|
|
(if (= (point) beg)
|
|
|
|
|
;; Don't say "killed"; that is misleading.
|
|
|
|
|
(message "Saved text until \"%s\""
|
|
|
|
|
(substring killed-text (- message-len)))
|
|
|
|
|
(message "Saved text from \"%s\""
|
|
|
|
|
(substring killed-text 0 message-len))))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun append-next-kill ()
|
1992-08-21 07:18:16 +00:00
|
|
|
|
"Cause following command, if it kills, to append to previous kill."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(if (interactive-p)
|
|
|
|
|
(progn
|
|
|
|
|
(setq this-command 'kill-region)
|
|
|
|
|
(message "If the next command is a kill, it will append"))
|
|
|
|
|
(setq last-command 'kill-region)))
|
|
|
|
|
|
|
|
|
|
(defun yank-pop (arg)
|
1992-08-21 07:18:16 +00:00
|
|
|
|
"Replace just-yanked stretch of killed text with a different stretch.
|
|
|
|
|
This command is allowed only immediately after a `yank' or a `yank-pop'.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
At such a time, the region contains a stretch of reinserted
|
1992-08-21 07:18:16 +00:00
|
|
|
|
previously-killed text. `yank-pop' deletes that text and inserts in its
|
1991-12-21 09:29:41 +00:00
|
|
|
|
place a different stretch of killed text.
|
|
|
|
|
|
|
|
|
|
With no argument, the previous kill is inserted.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
With argument N, insert the Nth previous kill.
|
|
|
|
|
If N is negative, this is a more recent kill.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
The sequence of kills wraps around, so that after the oldest one
|
|
|
|
|
comes the newest one."
|
|
|
|
|
(interactive "*p")
|
|
|
|
|
(if (not (eq last-command 'yank))
|
|
|
|
|
(error "Previous command was not a yank"))
|
|
|
|
|
(setq this-command 'yank)
|
1996-02-06 23:56:47 +00:00
|
|
|
|
(let ((inhibit-read-only t)
|
|
|
|
|
(before (< (point) (mark t))))
|
1993-05-15 20:55:02 +00:00
|
|
|
|
(delete-region (point) (mark t))
|
1993-05-16 15:39:39 +00:00
|
|
|
|
(set-marker (mark-marker) (point) (current-buffer))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(insert (current-kill arg))
|
1993-05-16 15:39:39 +00:00
|
|
|
|
(if before
|
|
|
|
|
;; This is like exchange-point-and-mark, but doesn't activate the mark.
|
|
|
|
|
;; It is cleaner to avoid activation, even though the command
|
|
|
|
|
;; loop would deactivate the mark because we inserted text.
|
|
|
|
|
(goto-char (prog1 (mark t)
|
|
|
|
|
(set-marker (mark-marker) (point) (current-buffer))))))
|
1993-03-11 07:07:17 +00:00
|
|
|
|
nil)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun yank (&optional arg)
|
|
|
|
|
"Reinsert the last stretch of killed text.
|
|
|
|
|
More precisely, reinsert the stretch of killed text most recently
|
1992-08-21 07:18:16 +00:00
|
|
|
|
killed OR yanked. Put point at end, and set mark at beginning.
|
|
|
|
|
With just C-u as argument, same but put point at beginning (and mark at end).
|
|
|
|
|
With argument N, reinsert the Nth most recently killed stretch of killed
|
1991-12-21 09:29:41 +00:00
|
|
|
|
text.
|
|
|
|
|
See also the command \\[yank-pop]."
|
|
|
|
|
(interactive "*P")
|
1994-02-13 00:16:23 +00:00
|
|
|
|
;; If we don't get all the way thru, make last-command indicate that
|
|
|
|
|
;; for the following command.
|
|
|
|
|
(setq this-command t)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(push-mark (point))
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(insert (current-kill (cond
|
|
|
|
|
((listp arg) 0)
|
|
|
|
|
((eq arg '-) -1)
|
|
|
|
|
(t (1- arg)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if (consp arg)
|
1993-05-16 15:39:39 +00:00
|
|
|
|
;; This is like exchange-point-and-mark, but doesn't activate the mark.
|
|
|
|
|
;; It is cleaner to avoid activation, even though the command
|
|
|
|
|
;; loop would deactivate the mark because we inserted text.
|
|
|
|
|
(goto-char (prog1 (mark t)
|
|
|
|
|
(set-marker (mark-marker) (point) (current-buffer)))))
|
1994-02-13 00:16:23 +00:00
|
|
|
|
;; If we do get all the way thru, make this-command indicate that.
|
|
|
|
|
(setq this-command 'yank)
|
1993-03-11 07:07:17 +00:00
|
|
|
|
nil)
|
1992-06-12 22:23:00 +00:00
|
|
|
|
|
|
|
|
|
(defun rotate-yank-pointer (arg)
|
|
|
|
|
"Rotate the yanking point in the kill ring.
|
|
|
|
|
With argument, rotate that many kills forward (or backward, if negative)."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(current-kill arg))
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun insert-buffer (buffer)
|
|
|
|
|
"Insert after point the contents of BUFFER.
|
|
|
|
|
Puts mark after the inserted text.
|
|
|
|
|
BUFFER may be a buffer or a buffer name."
|
1996-03-18 19:32:24 +00:00
|
|
|
|
(interactive
|
1996-03-18 18:50:25 +00:00
|
|
|
|
(list
|
|
|
|
|
(progn
|
|
|
|
|
(barf-if-buffer-read-only)
|
|
|
|
|
(read-buffer "Insert buffer: "
|
|
|
|
|
(if (eq (selected-window) (next-window (selected-window)))
|
|
|
|
|
(other-buffer (current-buffer))
|
|
|
|
|
(window-buffer (next-window (selected-window))))
|
|
|
|
|
t))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(or (bufferp buffer)
|
|
|
|
|
(setq buffer (get-buffer buffer)))
|
|
|
|
|
(let (start end newmark)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(setq start (point-min) end (point-max)))
|
|
|
|
|
(insert-buffer-substring buffer start end)
|
|
|
|
|
(setq newmark (point)))
|
1993-03-02 07:33:17 +00:00
|
|
|
|
(push-mark newmark))
|
|
|
|
|
nil)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun append-to-buffer (buffer start end)
|
|
|
|
|
"Append to specified buffer the text of the region.
|
|
|
|
|
It is inserted into that buffer before its point.
|
|
|
|
|
|
|
|
|
|
When calling from a program, give three arguments:
|
|
|
|
|
BUFFER (or buffer name), START and END.
|
|
|
|
|
START and END specify the portion of the current buffer to be copied."
|
1992-06-12 22:23:00 +00:00
|
|
|
|
(interactive
|
1994-11-22 19:19:42 +00:00
|
|
|
|
(list (read-buffer "Append to buffer: " (other-buffer (current-buffer) t))
|
1993-06-10 23:06:50 +00:00
|
|
|
|
(region-beginning) (region-end)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(let ((oldbuf (current-buffer)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create buffer))
|
|
|
|
|
(insert-buffer-substring oldbuf start end))))
|
|
|
|
|
|
|
|
|
|
(defun prepend-to-buffer (buffer start end)
|
|
|
|
|
"Prepend to specified buffer the text of the region.
|
|
|
|
|
It is inserted into that buffer after its point.
|
|
|
|
|
|
|
|
|
|
When calling from a program, give three arguments:
|
|
|
|
|
BUFFER (or buffer name), START and END.
|
|
|
|
|
START and END specify the portion of the current buffer to be copied."
|
|
|
|
|
(interactive "BPrepend to buffer: \nr")
|
|
|
|
|
(let ((oldbuf (current-buffer)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create buffer))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(insert-buffer-substring oldbuf start end)))))
|
|
|
|
|
|
|
|
|
|
(defun copy-to-buffer (buffer start end)
|
|
|
|
|
"Copy to specified buffer the text of the region.
|
|
|
|
|
It is inserted into that buffer, replacing existing text there.
|
|
|
|
|
|
|
|
|
|
When calling from a program, give three arguments:
|
|
|
|
|
BUFFER (or buffer name), START and END.
|
|
|
|
|
START and END specify the portion of the current buffer to be copied."
|
|
|
|
|
(interactive "BCopy to buffer: \nr")
|
|
|
|
|
(let ((oldbuf (current-buffer)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create buffer))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(insert-buffer-substring oldbuf start end)))))
|
|
|
|
|
|
1993-07-08 21:46:22 +00:00
|
|
|
|
(put 'mark-inactive 'error-conditions '(mark-inactive error))
|
|
|
|
|
(put 'mark-inactive 'error-message "The mark is not active now")
|
|
|
|
|
|
1993-03-09 05:40:33 +00:00
|
|
|
|
(defun mark (&optional force)
|
1993-06-05 02:48:22 +00:00
|
|
|
|
"Return this buffer's mark value as integer; error if mark inactive.
|
1993-03-09 05:40:33 +00:00
|
|
|
|
If optional argument FORCE is non-nil, access the mark value
|
1993-06-05 02:48:22 +00:00
|
|
|
|
even if the mark is not currently active, and return nil
|
|
|
|
|
if there is no mark at all.
|
1993-03-09 05:40:33 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
If you are using this in an editing command, you are most likely making
|
|
|
|
|
a mistake; see the documentation of `set-mark'."
|
1995-01-23 22:37:46 +00:00
|
|
|
|
(if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)
|
1993-03-09 05:40:33 +00:00
|
|
|
|
(marker-position (mark-marker))
|
1993-07-08 21:46:22 +00:00
|
|
|
|
(signal 'mark-inactive nil)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1993-07-08 22:37:42 +00:00
|
|
|
|
;; Many places set mark-active directly, and several of them failed to also
|
|
|
|
|
;; run deactivate-mark-hook. This shorthand should simplify.
|
|
|
|
|
(defsubst deactivate-mark ()
|
|
|
|
|
"Deactivate the mark by setting `mark-active' to nil.
|
1993-07-26 07:31:11 +00:00
|
|
|
|
\(That makes a difference only in Transient Mark mode.)
|
1993-07-08 22:37:42 +00:00
|
|
|
|
Also runs the hook `deactivate-mark-hook'."
|
1994-05-28 12:04:04 +00:00
|
|
|
|
(if transient-mark-mode
|
|
|
|
|
(progn
|
|
|
|
|
(setq mark-active nil)
|
|
|
|
|
(run-hooks 'deactivate-mark-hook))))
|
1993-07-08 22:37:42 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun set-mark (pos)
|
|
|
|
|
"Set this buffer's mark to POS. Don't use this function!
|
|
|
|
|
That is to say, don't use this function unless you want
|
|
|
|
|
the user to see that the mark has moved, and you want the previous
|
|
|
|
|
mark position to be lost.
|
|
|
|
|
|
|
|
|
|
Normally, when a new mark is set, the old one should go on the stack.
|
|
|
|
|
This is why most applications should use push-mark, not set-mark.
|
|
|
|
|
|
1992-08-21 07:18:16 +00:00
|
|
|
|
Novice Emacs Lisp programmers often try to use the mark for the wrong
|
1991-12-21 09:29:41 +00:00
|
|
|
|
purposes. The mark saves a location for the user's convenience.
|
|
|
|
|
Most editing commands should not alter the mark.
|
|
|
|
|
To remember a location for internal use in the Lisp program,
|
|
|
|
|
store it in a Lisp variable. Example:
|
|
|
|
|
|
|
|
|
|
(let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
|
|
|
|
|
|
1993-07-26 07:31:11 +00:00
|
|
|
|
(if pos
|
|
|
|
|
(progn
|
|
|
|
|
(setq mark-active t)
|
|
|
|
|
(run-hooks 'activate-mark-hook)
|
|
|
|
|
(set-marker (mark-marker) pos (current-buffer)))
|
1994-08-30 00:36:48 +00:00
|
|
|
|
;; Normally we never clear mark-active except in Transient Mark mode.
|
|
|
|
|
;; But when we actually clear out the mark value too,
|
|
|
|
|
;; we must clear mark-active in any mode.
|
|
|
|
|
(setq mark-active nil)
|
|
|
|
|
(run-hooks 'deactivate-mark-hook)
|
|
|
|
|
(set-marker (mark-marker) nil)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defvar mark-ring nil
|
1994-09-03 23:33:50 +00:00
|
|
|
|
"The list of former marks of the current buffer, most recent first.")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(make-variable-buffer-local 'mark-ring)
|
1994-09-03 23:33:50 +00:00
|
|
|
|
(put 'mark-ring 'permanent-local t)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defconst mark-ring-max 16
|
|
|
|
|
"*Maximum size of mark ring. Start discarding off end if gets this big.")
|
|
|
|
|
|
1994-02-07 02:24:01 +00:00
|
|
|
|
(defvar global-mark-ring nil
|
|
|
|
|
"The list of saved global marks, most recent first.")
|
|
|
|
|
|
|
|
|
|
(defconst global-mark-ring-max 16
|
|
|
|
|
"*Maximum size of global mark ring. \
|
|
|
|
|
Start discarding off end if gets this big.")
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun set-mark-command (arg)
|
|
|
|
|
"Set mark at where point is, or jump to mark.
|
1994-02-07 02:24:01 +00:00
|
|
|
|
With no prefix argument, set mark, push old mark position on local mark
|
|
|
|
|
ring, and push mark on global mark ring.
|
|
|
|
|
With argument, jump to mark, and pop a new position for mark off the ring
|
|
|
|
|
\(does not affect global mark ring\).
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1992-08-21 07:18:16 +00:00
|
|
|
|
Novice Emacs Lisp programmers often try to use the mark for the wrong
|
1991-12-21 09:29:41 +00:00
|
|
|
|
purposes. See the documentation of `set-mark' for more information."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (null arg)
|
1993-05-15 20:55:02 +00:00
|
|
|
|
(progn
|
1993-05-16 15:39:39 +00:00
|
|
|
|
(push-mark nil nil t))
|
1993-03-09 05:40:33 +00:00
|
|
|
|
(if (null (mark t))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(error "No mark set in this buffer")
|
1993-05-15 20:55:02 +00:00
|
|
|
|
(goto-char (mark t))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(pop-mark))))
|
|
|
|
|
|
1993-05-16 15:39:39 +00:00
|
|
|
|
(defun push-mark (&optional location nomsg activate)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
"Set mark at LOCATION (point, by default) and push old mark on mark ring.
|
1994-02-07 04:48:18 +00:00
|
|
|
|
If the last global mark pushed was not in the current buffer,
|
|
|
|
|
also push LOCATION on the global mark ring.
|
1993-05-16 15:39:39 +00:00
|
|
|
|
Display `Mark set' unless the optional second arg NOMSG is non-nil.
|
1993-05-16 23:09:57 +00:00
|
|
|
|
In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1992-08-21 07:18:16 +00:00
|
|
|
|
Novice Emacs Lisp programmers often try to use the mark for the wrong
|
1993-05-15 20:55:02 +00:00
|
|
|
|
purposes. See the documentation of `set-mark' for more information.
|
|
|
|
|
|
|
|
|
|
In Transient Mark mode, this does not activate the mark."
|
1993-03-09 05:40:33 +00:00
|
|
|
|
(if (null (mark t))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
nil
|
|
|
|
|
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
|
|
|
|
|
(if (> (length mark-ring) mark-ring-max)
|
|
|
|
|
(progn
|
|
|
|
|
(move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
|
|
|
|
|
(setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
|
1993-05-15 20:55:02 +00:00
|
|
|
|
(set-marker (mark-marker) (or location (point)) (current-buffer))
|
1994-02-07 02:24:01 +00:00
|
|
|
|
;; Now push the mark on the global mark ring.
|
1994-02-07 04:48:18 +00:00
|
|
|
|
(if (and global-mark-ring
|
1994-02-07 18:40:13 +00:00
|
|
|
|
(eq (marker-buffer (car global-mark-ring)) (current-buffer)))
|
1994-02-07 04:48:18 +00:00
|
|
|
|
;; The last global mark pushed was in this same buffer.
|
|
|
|
|
;; Don't push another one.
|
|
|
|
|
nil
|
|
|
|
|
(setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
|
1994-02-07 02:24:01 +00:00
|
|
|
|
(if (> (length global-mark-ring) global-mark-ring-max)
|
|
|
|
|
(progn
|
|
|
|
|
(move-marker (car (nthcdr global-mark-ring-max global-mark-ring))
|
|
|
|
|
nil)
|
1994-02-07 04:48:18 +00:00
|
|
|
|
(setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil))))
|
1996-05-29 17:17:34 +00:00
|
|
|
|
(or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(message "Mark set"))
|
1993-05-16 23:09:57 +00:00
|
|
|
|
(if (or activate (not transient-mark-mode))
|
|
|
|
|
(set-mark (mark t)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(defun pop-mark ()
|
|
|
|
|
"Pop off mark ring into the buffer's actual mark.
|
|
|
|
|
Does not set point. Does nothing if mark ring is empty."
|
|
|
|
|
(if mark-ring
|
|
|
|
|
(progn
|
|
|
|
|
(setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
|
1993-05-15 20:55:02 +00:00
|
|
|
|
(set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))
|
1993-07-08 22:37:42 +00:00
|
|
|
|
(deactivate-mark)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(move-marker (car mark-ring) nil)
|
1993-05-15 20:55:02 +00:00
|
|
|
|
(if (null (mark t)) (ding))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(setq mark-ring (cdr mark-ring)))))
|
|
|
|
|
|
1993-04-29 13:57:52 +00:00
|
|
|
|
(define-function 'exchange-dot-and-mark 'exchange-point-and-mark)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun exchange-point-and-mark ()
|
1993-03-09 05:40:33 +00:00
|
|
|
|
"Put the mark where point is now, and point where the mark is now.
|
|
|
|
|
This command works even when the mark is not active,
|
|
|
|
|
and it reactivates the mark."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive nil)
|
1993-03-09 05:40:33 +00:00
|
|
|
|
(let ((omark (mark t)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if (null omark)
|
|
|
|
|
(error "No mark set in this buffer"))
|
|
|
|
|
(set-mark (point))
|
|
|
|
|
(goto-char omark)
|
|
|
|
|
nil))
|
1993-05-15 18:47:18 +00:00
|
|
|
|
|
|
|
|
|
(defun transient-mark-mode (arg)
|
|
|
|
|
"Toggle Transient Mark mode.
|
1993-05-21 17:26:48 +00:00
|
|
|
|
With arg, turn Transient Mark mode on if arg is positive, off otherwise.
|
1993-05-15 18:47:18 +00:00
|
|
|
|
|
1993-12-30 10:06:31 +00:00
|
|
|
|
In Transient Mark mode, when the mark is active, the region is highlighted.
|
|
|
|
|
Changing the buffer \"deactivates\" the mark.
|
|
|
|
|
So do certain other operations that set the mark
|
|
|
|
|
but whose main purpose is something else--for example,
|
|
|
|
|
incremental search, \\[beginning-of-buffer], and \\[end-of-buffer]."
|
1993-05-15 18:47:18 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq transient-mark-mode
|
|
|
|
|
(if (null arg)
|
|
|
|
|
(not transient-mark-mode)
|
|
|
|
|
(> (prefix-numeric-value arg) 0))))
|
1994-02-07 02:24:01 +00:00
|
|
|
|
|
|
|
|
|
(defun pop-global-mark ()
|
|
|
|
|
"Pop off global mark ring and jump to the top location."
|
|
|
|
|
(interactive)
|
1994-06-14 00:34:43 +00:00
|
|
|
|
;; Pop entries which refer to non-existent buffers.
|
|
|
|
|
(while (and global-mark-ring (not (marker-buffer (car global-mark-ring))))
|
|
|
|
|
(setq global-mark-ring (cdr global-mark-ring)))
|
1994-02-07 02:24:01 +00:00
|
|
|
|
(or global-mark-ring
|
|
|
|
|
(error "No global mark set"))
|
|
|
|
|
(let* ((marker (car global-mark-ring))
|
|
|
|
|
(buffer (marker-buffer marker))
|
|
|
|
|
(position (marker-position marker)))
|
1995-01-05 23:53:01 +00:00
|
|
|
|
(setq global-mark-ring (nconc (cdr global-mark-ring)
|
|
|
|
|
(list (car global-mark-ring))))
|
1994-02-07 02:24:01 +00:00
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(or (and (>= position (point-min))
|
|
|
|
|
(<= position (point-max)))
|
|
|
|
|
(widen))
|
|
|
|
|
(goto-char position)
|
|
|
|
|
(switch-to-buffer buffer)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1993-04-23 06:50:37 +00:00
|
|
|
|
(defvar next-line-add-newlines t
|
1993-04-29 13:57:52 +00:00
|
|
|
|
"*If non-nil, `next-line' inserts newline to avoid `end of buffer' error.")
|
1993-04-23 06:50:37 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun next-line (arg)
|
|
|
|
|
"Move cursor vertically down ARG lines.
|
|
|
|
|
If there is no character in the target line exactly under the current column,
|
|
|
|
|
the cursor is positioned after the character in that line which spans this
|
|
|
|
|
column, or at the end of the line if it is not long enough.
|
1993-04-23 06:50:37 +00:00
|
|
|
|
If there is no line in the buffer after this one, behavior depends on the
|
1994-12-23 17:25:50 +00:00
|
|
|
|
value of `next-line-add-newlines'. If non-nil, it inserts a newline character
|
|
|
|
|
to create a line, and moves the cursor to that line. Otherwise it moves the
|
1995-07-30 00:46:23 +00:00
|
|
|
|
cursor to the end of the buffer.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
The command \\[set-goal-column] can be used to create
|
|
|
|
|
a semipermanent goal column to which this command always moves.
|
|
|
|
|
Then it does not try to move vertically. This goal column is stored
|
|
|
|
|
in `goal-column', which is nil when there is none.
|
|
|
|
|
|
|
|
|
|
If you are thinking of using this in a Lisp program, consider
|
|
|
|
|
using `forward-line' instead. It is usually easier to use
|
|
|
|
|
and more reliable (no dependence on goal column, etc.)."
|
|
|
|
|
(interactive "p")
|
1994-01-26 17:19:32 +00:00
|
|
|
|
(if (and next-line-add-newlines (= arg 1))
|
|
|
|
|
(let ((opoint (point)))
|
1994-07-24 01:10:14 +00:00
|
|
|
|
(end-of-line)
|
|
|
|
|
(if (eobp)
|
1995-01-13 08:43:40 +00:00
|
|
|
|
(newline 1)
|
1994-01-26 17:19:32 +00:00
|
|
|
|
(goto-char opoint)
|
|
|
|
|
(line-move arg)))
|
1994-12-23 17:25:50 +00:00
|
|
|
|
(if (interactive-p)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(line-move arg)
|
|
|
|
|
((beginning-of-buffer end-of-buffer) (ding)))
|
|
|
|
|
(line-move arg)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(defun previous-line (arg)
|
|
|
|
|
"Move cursor vertically up ARG lines.
|
|
|
|
|
If there is no character in the target line exactly over the current column,
|
|
|
|
|
the cursor is positioned after the character in that line which spans this
|
|
|
|
|
column, or at the end of the line if it is not long enough.
|
|
|
|
|
|
|
|
|
|
The command \\[set-goal-column] can be used to create
|
|
|
|
|
a semipermanent goal column to which this command always moves.
|
|
|
|
|
Then it does not try to move vertically.
|
|
|
|
|
|
|
|
|
|
If you are thinking of using this in a Lisp program, consider using
|
1992-11-07 06:13:23 +00:00
|
|
|
|
`forward-line' with a negative argument instead. It is usually easier
|
1991-12-21 09:29:41 +00:00
|
|
|
|
to use and more reliable (no dependence on goal column, etc.)."
|
|
|
|
|
(interactive "p")
|
1994-12-23 17:25:50 +00:00
|
|
|
|
(if (interactive-p)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(line-move (- arg))
|
|
|
|
|
((beginning-of-buffer end-of-buffer) (ding)))
|
|
|
|
|
(line-move (- arg)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(defconst track-eol nil
|
|
|
|
|
"*Non-nil means vertical motion starting at end of line keeps to ends of lines.
|
|
|
|
|
This means moving to the end of each line moved onto.
|
|
|
|
|
The beginning of a blank line does not count as the end of a line.")
|
|
|
|
|
|
1992-10-23 08:54:08 +00:00
|
|
|
|
(defvar goal-column nil
|
|
|
|
|
"*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil.")
|
|
|
|
|
(make-variable-buffer-local 'goal-column)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defvar temporary-goal-column 0
|
|
|
|
|
"Current goal column for vertical motion.
|
|
|
|
|
It is the column where point was
|
|
|
|
|
at the start of current run of vertical motion commands.
|
1992-01-27 22:52:05 +00:00
|
|
|
|
When the `track-eol' feature is doing its job, the value is 9999.")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1995-03-10 03:27:46 +00:00
|
|
|
|
(defvar line-move-ignore-invisible nil
|
|
|
|
|
"*Non-nil means \\[next-line] and \\[previous-line] ignore invisible lines.
|
|
|
|
|
Outline mode sets this.")
|
|
|
|
|
|
1995-04-09 09:34:05 +00:00
|
|
|
|
;; This is the guts of next-line and previous-line.
|
|
|
|
|
;; Arg says how many lines to move.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun line-move (arg)
|
1995-04-18 07:01:34 +00:00
|
|
|
|
;; Don't run any point-motion hooks, and disregard intangibility,
|
|
|
|
|
;; for intermediate positions.
|
|
|
|
|
(let ((inhibit-point-motion-hooks t)
|
|
|
|
|
(opoint (point))
|
|
|
|
|
new)
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
(if (not (or (eq last-command 'next-line)
|
|
|
|
|
(eq last-command 'previous-line)))
|
|
|
|
|
(setq temporary-goal-column
|
|
|
|
|
(if (and track-eol (eolp)
|
|
|
|
|
;; Don't count beg of empty line as end of line
|
|
|
|
|
;; unless we just did explicit end-of-line.
|
|
|
|
|
(or (not (bolp)) (eq last-command 'end-of-line)))
|
|
|
|
|
9999
|
|
|
|
|
(current-column))))
|
|
|
|
|
(if (and (not (integerp selective-display))
|
|
|
|
|
(not line-move-ignore-invisible))
|
|
|
|
|
;; Use just newline characters.
|
|
|
|
|
(or (if (> arg 0)
|
|
|
|
|
(progn (if (> arg 1) (forward-line (1- arg)))
|
|
|
|
|
;; This way of moving forward ARG lines
|
|
|
|
|
;; verifies that we have a newline after the last one.
|
|
|
|
|
;; It doesn't get confused by intangible text.
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(zerop (forward-line 1)))
|
|
|
|
|
(and (zerop (forward-line arg))
|
|
|
|
|
(bolp)))
|
|
|
|
|
(signal (if (< arg 0)
|
|
|
|
|
'beginning-of-buffer
|
|
|
|
|
'end-of-buffer)
|
|
|
|
|
nil))
|
|
|
|
|
;; Move by arg lines, but ignore invisible ones.
|
|
|
|
|
(while (> arg 0)
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(and (zerop (vertical-motion 1))
|
|
|
|
|
(signal 'end-of-buffer nil))
|
|
|
|
|
;; If the following character is currently invisible,
|
|
|
|
|
;; skip all characters with that same `invisible' property value.
|
|
|
|
|
(while (and (not (eobp))
|
|
|
|
|
(let ((prop
|
|
|
|
|
(get-char-property (point) 'invisible)))
|
|
|
|
|
(if (eq buffer-invisibility-spec t)
|
|
|
|
|
prop
|
|
|
|
|
(or (memq prop buffer-invisibility-spec)
|
|
|
|
|
(assq prop buffer-invisibility-spec)))))
|
|
|
|
|
(if (get-text-property (point) 'invisible)
|
|
|
|
|
(goto-char (next-single-property-change (point) 'invisible))
|
|
|
|
|
(goto-char (next-overlay-change (point)))))
|
|
|
|
|
(setq arg (1- arg)))
|
|
|
|
|
(while (< arg 0)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(and (zerop (vertical-motion -1))
|
|
|
|
|
(signal 'beginning-of-buffer nil))
|
|
|
|
|
(while (and (not (bobp))
|
|
|
|
|
(let ((prop
|
|
|
|
|
(get-char-property (1- (point)) 'invisible)))
|
|
|
|
|
(if (eq buffer-invisibility-spec t)
|
|
|
|
|
prop
|
|
|
|
|
(or (memq prop buffer-invisibility-spec)
|
|
|
|
|
(assq prop buffer-invisibility-spec)))))
|
|
|
|
|
(if (get-text-property (1- (point)) 'invisible)
|
|
|
|
|
(goto-char (previous-single-property-change (point) 'invisible))
|
|
|
|
|
(goto-char (previous-overlay-change (point)))))
|
|
|
|
|
(setq arg (1+ arg))))
|
|
|
|
|
(move-to-column (or goal-column temporary-goal-column)))
|
|
|
|
|
;; Remember where we moved to, go back home,
|
|
|
|
|
;; then do the motion over again
|
|
|
|
|
;; in just one step, with intangibility and point-motion hooks
|
|
|
|
|
;; enabled this time.
|
|
|
|
|
(setq new (point))
|
|
|
|
|
(goto-char opoint)
|
|
|
|
|
(setq inhibit-point-motion-hooks nil)
|
|
|
|
|
(goto-char new)))
|
|
|
|
|
nil)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1993-01-14 14:50:16 +00:00
|
|
|
|
;;; Many people have said they rarely use this feature, and often type
|
|
|
|
|
;;; it by accident. Maybe it shouldn't even be on a key.
|
|
|
|
|
(put 'set-goal-column 'disabled t)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun set-goal-column (arg)
|
|
|
|
|
"Set the current horizontal position as a goal for \\[next-line] and \\[previous-line].
|
|
|
|
|
Those commands will move to this position in the line moved to
|
|
|
|
|
rather than trying to keep the same horizontal position.
|
|
|
|
|
With a non-nil argument, clears out the goal column
|
1992-10-23 08:54:08 +00:00
|
|
|
|
so that \\[next-line] and \\[previous-line] resume vertical motion.
|
|
|
|
|
The goal column is stored in the variable `goal-column'."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(if arg
|
|
|
|
|
(progn
|
|
|
|
|
(setq goal-column nil)
|
|
|
|
|
(message "No goal column"))
|
|
|
|
|
(setq goal-column (current-column))
|
|
|
|
|
(message (substitute-command-keys
|
|
|
|
|
"Goal column %d (use \\[set-goal-column] with an arg to unset it)")
|
|
|
|
|
goal-column))
|
|
|
|
|
nil)
|
|
|
|
|
|
1993-04-27 22:01:32 +00:00
|
|
|
|
;;; Partial support for horizontal autoscrolling. Someday, this feature
|
|
|
|
|
;;; will be built into the C level and all the (hscroll-point-visible) calls
|
|
|
|
|
;;; will go away.
|
|
|
|
|
|
|
|
|
|
(defvar hscroll-step 0
|
|
|
|
|
"*The number of columns to try scrolling a window by when point moves out.
|
|
|
|
|
If that fails to bring point back on frame, point is centered instead.
|
|
|
|
|
If this is zero, point is always centered after it moves off frame.")
|
|
|
|
|
|
|
|
|
|
(defun hscroll-point-visible ()
|
1994-04-08 03:23:08 +00:00
|
|
|
|
"Scrolls the selected window horizontally to make point visible."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (window-buffer))
|
|
|
|
|
(if (not (or truncate-lines
|
|
|
|
|
(> (window-hscroll) 0)
|
|
|
|
|
(and truncate-partial-width-windows
|
|
|
|
|
(< (window-width) (frame-width)))))
|
|
|
|
|
;; Point is always visible when lines are wrapped.
|
|
|
|
|
()
|
|
|
|
|
;; If point is on the invisible part of the line before window-start,
|
|
|
|
|
;; then hscrolling can't bring it back, so reset window-start first.
|
|
|
|
|
(and (< (point) (window-start))
|
|
|
|
|
(let ((ws-bol (save-excursion
|
|
|
|
|
(goto-char (window-start))
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(point))))
|
|
|
|
|
(and (>= (point) ws-bol)
|
|
|
|
|
(set-window-start nil ws-bol))))
|
|
|
|
|
(let* ((here (hscroll-window-column))
|
|
|
|
|
(left (min (window-hscroll) 1))
|
|
|
|
|
(right (1- (window-width))))
|
|
|
|
|
;; Allow for the truncation glyph, if we're not exactly at eol.
|
|
|
|
|
(if (not (and (= here right)
|
|
|
|
|
(= (following-char) ?\n)))
|
|
|
|
|
(setq right (1- right)))
|
|
|
|
|
(cond
|
|
|
|
|
;; If too far away, just recenter. But don't show too much
|
|
|
|
|
;; white space off the end of the line.
|
|
|
|
|
((or (< here (- left hscroll-step))
|
|
|
|
|
(> here (+ right hscroll-step)))
|
|
|
|
|
(let ((eol (save-excursion (end-of-line) (hscroll-window-column))))
|
|
|
|
|
(scroll-left (min (- here (/ (window-width) 2))
|
|
|
|
|
(- eol (window-width) -5)))))
|
|
|
|
|
;; Within range. Scroll by one step (or maybe not at all).
|
|
|
|
|
((< here left)
|
|
|
|
|
(scroll-right hscroll-step))
|
|
|
|
|
((> here right)
|
|
|
|
|
(scroll-left hscroll-step)))))))
|
|
|
|
|
|
|
|
|
|
;; This function returns the window's idea of the display column of point,
|
|
|
|
|
;; assuming that the window is already known to be truncated rather than
|
|
|
|
|
;; wrapped, and that we've already handled the case where point is on the
|
|
|
|
|
;; part of the line before window-start. We ignore window-width; if point
|
|
|
|
|
;; is beyond the right margin, we want to know how far. The return value
|
|
|
|
|
;; includes the effects of window-hscroll, window-start, and the prompt
|
|
|
|
|
;; string in the minibuffer. It may be negative due to hscroll.
|
|
|
|
|
(defun hscroll-window-column ()
|
|
|
|
|
(let* ((hscroll (window-hscroll))
|
|
|
|
|
(startpos (save-excursion
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(if (= (point) (save-excursion
|
|
|
|
|
(goto-char (window-start))
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(point)))
|
|
|
|
|
(goto-char (window-start)))
|
|
|
|
|
(point)))
|
|
|
|
|
(hpos (+ (if (and (eq (selected-window) (minibuffer-window))
|
|
|
|
|
(= 1 (window-start))
|
|
|
|
|
(= startpos (point-min)))
|
|
|
|
|
(minibuffer-prompt-width)
|
|
|
|
|
0)
|
|
|
|
|
(min 0 (- 1 hscroll))))
|
|
|
|
|
val)
|
|
|
|
|
(car (cdr (compute-motion startpos (cons hpos 0)
|
|
|
|
|
(point) (cons 0 1)
|
|
|
|
|
1000000 (cons hscroll 0) nil)))))
|
|
|
|
|
|
1993-04-27 22:01:32 +00:00
|
|
|
|
|
1993-04-29 13:57:52 +00:00
|
|
|
|
;; rms: (1) The definitions of arrow keys should not simply restate
|
|
|
|
|
;; what keys they are. The arrow keys should run the ordinary commands.
|
|
|
|
|
;; (2) The arrow keys are just one of many common ways of moving point
|
|
|
|
|
;; within a line. Real horizontal autoscrolling would be a good feature,
|
|
|
|
|
;; but supporting it only for arrow keys is too incomplete to be desirable.
|
|
|
|
|
|
|
|
|
|
;;;;; Make arrow keys do the right thing for improved terminal support
|
|
|
|
|
;;;;; When we implement true horizontal autoscrolling, right-arrow and
|
|
|
|
|
;;;;; left-arrow can lose the (if truncate-lines ...) clause and become
|
|
|
|
|
;;;;; aliases. These functions are bound to the corresponding keyboard
|
|
|
|
|
;;;;; events in loaddefs.el.
|
|
|
|
|
|
|
|
|
|
;;(defun right-arrow (arg)
|
|
|
|
|
;; "Move right one character on the screen (with prefix ARG, that many chars).
|
|
|
|
|
;;Scroll right if needed to keep point horizontally onscreen."
|
|
|
|
|
;; (interactive "P")
|
|
|
|
|
;; (forward-char arg)
|
|
|
|
|
;; (hscroll-point-visible))
|
|
|
|
|
|
|
|
|
|
;;(defun left-arrow (arg)
|
|
|
|
|
;; "Move left one character on the screen (with prefix ARG, that many chars).
|
|
|
|
|
;;Scroll left if needed to keep point horizontally onscreen."
|
|
|
|
|
;; (interactive "P")
|
|
|
|
|
;; (backward-char arg)
|
|
|
|
|
;; (hscroll-point-visible))
|
1994-06-22 05:16:22 +00:00
|
|
|
|
|
|
|
|
|
(defun scroll-other-window-down (lines)
|
1995-07-30 00:46:23 +00:00
|
|
|
|
"Scroll the \"other window\" down.
|
|
|
|
|
For more details, see the documentation for `scroll-other-window'."
|
1994-06-22 05:16:22 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(scroll-other-window
|
|
|
|
|
;; Just invert the argument's meaning.
|
|
|
|
|
;; We can do that without knowing which window it will be.
|
|
|
|
|
(if (eq lines '-) nil
|
|
|
|
|
(if (null lines) '-
|
|
|
|
|
(- (prefix-numeric-value lines))))))
|
1995-07-30 00:46:23 +00:00
|
|
|
|
(define-key esc-map [?\C-\S-v] 'scroll-other-window-down)
|
1994-06-25 18:58:42 +00:00
|
|
|
|
|
|
|
|
|
(defun beginning-of-buffer-other-window (arg)
|
|
|
|
|
"Move point to the beginning of the buffer in the other window.
|
|
|
|
|
Leave mark at previous position.
|
|
|
|
|
With arg N, put point N/10 of the way from the true beginning."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((orig-window (selected-window))
|
|
|
|
|
(window (other-window-for-scrolling)))
|
|
|
|
|
;; We use unwind-protect rather than save-window-excursion
|
|
|
|
|
;; because the latter would preserve the things we want to change.
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
(select-window window)
|
|
|
|
|
;; Set point and mark in that window's buffer.
|
|
|
|
|
(beginning-of-buffer arg)
|
|
|
|
|
;; Set point accordingly.
|
|
|
|
|
(recenter '(t)))
|
|
|
|
|
(select-window orig-window))))
|
|
|
|
|
|
|
|
|
|
(defun end-of-buffer-other-window (arg)
|
|
|
|
|
"Move point to the end of the buffer in the other window.
|
|
|
|
|
Leave mark at previous position.
|
|
|
|
|
With arg N, put point N/10 of the way from the true end."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
;; See beginning-of-buffer-other-window for comments.
|
|
|
|
|
(let ((orig-window (selected-window))
|
|
|
|
|
(window (other-window-for-scrolling)))
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
(select-window window)
|
1994-08-04 19:59:03 +00:00
|
|
|
|
(end-of-buffer arg)
|
1994-06-25 18:58:42 +00:00
|
|
|
|
(recenter '(t)))
|
|
|
|
|
(select-window orig-window))))
|
1993-04-23 06:50:37 +00:00
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun transpose-chars (arg)
|
|
|
|
|
"Interchange characters around point, moving forward one character.
|
|
|
|
|
With prefix arg ARG, effect is to take character before point
|
|
|
|
|
and drag it forward past ARG other characters (backward if ARG negative).
|
|
|
|
|
If no argument and at end of line, the previous two chars are exchanged."
|
|
|
|
|
(interactive "*P")
|
|
|
|
|
(and (null arg) (eolp) (forward-char -1))
|
|
|
|
|
(transpose-subr 'forward-char (prefix-numeric-value arg)))
|
|
|
|
|
|
|
|
|
|
(defun transpose-words (arg)
|
|
|
|
|
"Interchange words around point, leaving point at end of them.
|
|
|
|
|
With prefix arg ARG, effect is to take word before or around point
|
|
|
|
|
and drag it forward past ARG other words (backward if ARG negative).
|
|
|
|
|
If ARG is zero, the words around or after point and around or after mark
|
|
|
|
|
are interchanged."
|
|
|
|
|
(interactive "*p")
|
|
|
|
|
(transpose-subr 'forward-word arg))
|
|
|
|
|
|
|
|
|
|
(defun transpose-sexps (arg)
|
|
|
|
|
"Like \\[transpose-words] but applies to sexps.
|
|
|
|
|
Does not work on a sexp that point is in the middle of
|
|
|
|
|
if it is a list or string."
|
|
|
|
|
(interactive "*p")
|
|
|
|
|
(transpose-subr 'forward-sexp arg))
|
|
|
|
|
|
|
|
|
|
(defun transpose-lines (arg)
|
|
|
|
|
"Exchange current line and previous line, leaving point after both.
|
|
|
|
|
With argument ARG, takes previous line and moves it past ARG lines.
|
|
|
|
|
With argument 0, interchanges line point is in with line mark is in."
|
|
|
|
|
(interactive "*p")
|
|
|
|
|
(transpose-subr (function
|
|
|
|
|
(lambda (arg)
|
|
|
|
|
(if (= arg 1)
|
|
|
|
|
(progn
|
|
|
|
|
;; Move forward over a line,
|
|
|
|
|
;; but create a newline if none exists yet.
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(if (eobp)
|
|
|
|
|
(newline)
|
|
|
|
|
(forward-char 1)))
|
|
|
|
|
(forward-line arg))))
|
|
|
|
|
arg))
|
|
|
|
|
|
|
|
|
|
(defun transpose-subr (mover arg)
|
|
|
|
|
(let (start1 end1 start2 end2)
|
|
|
|
|
(if (= arg 0)
|
|
|
|
|
(progn
|
|
|
|
|
(save-excursion
|
|
|
|
|
(funcall mover 1)
|
|
|
|
|
(setq end2 (point))
|
|
|
|
|
(funcall mover -1)
|
|
|
|
|
(setq start2 (point))
|
|
|
|
|
(goto-char (mark))
|
|
|
|
|
(funcall mover 1)
|
|
|
|
|
(setq end1 (point))
|
|
|
|
|
(funcall mover -1)
|
|
|
|
|
(setq start1 (point))
|
|
|
|
|
(transpose-subr-1))
|
|
|
|
|
(exchange-point-and-mark)))
|
|
|
|
|
(while (> arg 0)
|
|
|
|
|
(funcall mover -1)
|
|
|
|
|
(setq start1 (point))
|
|
|
|
|
(funcall mover 1)
|
|
|
|
|
(setq end1 (point))
|
|
|
|
|
(funcall mover 1)
|
|
|
|
|
(setq end2 (point))
|
|
|
|
|
(funcall mover -1)
|
|
|
|
|
(setq start2 (point))
|
|
|
|
|
(transpose-subr-1)
|
|
|
|
|
(goto-char end2)
|
|
|
|
|
(setq arg (1- arg)))
|
|
|
|
|
(while (< arg 0)
|
|
|
|
|
(funcall mover -1)
|
|
|
|
|
(setq start2 (point))
|
|
|
|
|
(funcall mover -1)
|
|
|
|
|
(setq start1 (point))
|
|
|
|
|
(funcall mover 1)
|
|
|
|
|
(setq end1 (point))
|
|
|
|
|
(funcall mover 1)
|
|
|
|
|
(setq end2 (point))
|
|
|
|
|
(transpose-subr-1)
|
|
|
|
|
(setq arg (1+ arg)))))
|
|
|
|
|
|
|
|
|
|
(defun transpose-subr-1 ()
|
|
|
|
|
(if (> (min end1 end2) (max start1 start2))
|
|
|
|
|
(error "Don't have two things to transpose"))
|
|
|
|
|
(let ((word1 (buffer-substring start1 end1))
|
|
|
|
|
(word2 (buffer-substring start2 end2)))
|
|
|
|
|
(delete-region start2 end2)
|
|
|
|
|
(goto-char start2)
|
|
|
|
|
(insert word1)
|
|
|
|
|
(goto-char (if (< start1 start2) start1
|
|
|
|
|
(+ start1 (- (length word1) (length word2)))))
|
|
|
|
|
(delete-char (length word1))
|
|
|
|
|
(insert word2)))
|
|
|
|
|
|
|
|
|
|
(defconst comment-column 32
|
|
|
|
|
"*Column to indent right-margin comments to.
|
1992-11-15 23:57:39 +00:00
|
|
|
|
Setting this variable automatically makes it local to the current buffer.
|
|
|
|
|
Each mode establishes a different default value for this variable; you
|
1994-03-07 19:44:50 +00:00
|
|
|
|
can set the value for a particular mode using that mode's hook.")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(make-variable-buffer-local 'comment-column)
|
|
|
|
|
|
|
|
|
|
(defconst comment-start nil
|
1995-03-12 19:23:25 +00:00
|
|
|
|
"*String to insert to start a new comment, or nil if no comment syntax.")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defconst comment-start-skip nil
|
|
|
|
|
"*Regexp to match the start of a comment plus everything up to its body.
|
|
|
|
|
If there are any \\(...\\) pairs, the comment delimiter text is held to begin
|
|
|
|
|
at the place matched by the close of the first pair.")
|
|
|
|
|
|
|
|
|
|
(defconst comment-end ""
|
|
|
|
|
"*String to insert to end a new comment.
|
|
|
|
|
Should be an empty string if comments are terminated by end-of-line.")
|
|
|
|
|
|
1993-03-21 07:04:44 +00:00
|
|
|
|
(defconst comment-indent-hook nil
|
|
|
|
|
"Obsolete variable for function to compute desired indentation for a comment.
|
|
|
|
|
This function is called with no args with point at the beginning of
|
|
|
|
|
the comment's starting delimiter.")
|
|
|
|
|
|
|
|
|
|
(defconst comment-indent-function
|
1991-12-21 09:29:41 +00:00
|
|
|
|
'(lambda () comment-column)
|
|
|
|
|
"Function to compute desired indentation for a comment.
|
|
|
|
|
This function is called with no args with point at the beginning of
|
|
|
|
|
the comment's starting delimiter.")
|
|
|
|
|
|
1995-03-12 19:23:25 +00:00
|
|
|
|
(defconst block-comment-start nil
|
|
|
|
|
"*String to insert to start a new comment on a line by itself.
|
|
|
|
|
If nil, use `comment-start' instead.
|
|
|
|
|
Note that the regular expression `comment-start-skip' should skip this string
|
|
|
|
|
as well as the `comment-start' string.")
|
|
|
|
|
|
|
|
|
|
(defconst block-comment-end nil
|
|
|
|
|
"*String to insert to end a new comment on a line by itself.
|
|
|
|
|
Should be an empty string if comments are terminated by end-of-line.
|
|
|
|
|
If nil, use `comment-end' instead.")
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun indent-for-comment ()
|
|
|
|
|
"Indent this line's comment to comment column, or insert an empty comment."
|
|
|
|
|
(interactive "*")
|
1995-03-12 19:23:25 +00:00
|
|
|
|
(let* ((empty (save-excursion (beginning-of-line)
|
|
|
|
|
(looking-at "[ \t]*$")))
|
|
|
|
|
(starter (or (and empty block-comment-start) comment-start))
|
|
|
|
|
(ender (or (and empty block-comment-end) comment-end)))
|
|
|
|
|
(if (null starter)
|
|
|
|
|
(error "No comment syntax defined")
|
|
|
|
|
(let* ((eolpos (save-excursion (end-of-line) (point)))
|
|
|
|
|
cpos indent begpos)
|
1995-05-29 06:19:46 +00:00
|
|
|
|
(beginning-of-line)
|
1995-03-12 19:23:25 +00:00
|
|
|
|
(if (re-search-forward comment-start-skip eolpos 'move)
|
|
|
|
|
(progn (setq cpos (point-marker))
|
|
|
|
|
;; Find the start of the comment delimiter.
|
|
|
|
|
;; If there were paren-pairs in comment-start-skip,
|
|
|
|
|
;; position at the end of the first pair.
|
|
|
|
|
(if (match-end 1)
|
|
|
|
|
(goto-char (match-end 1))
|
|
|
|
|
;; If comment-start-skip matched a string with
|
|
|
|
|
;; internal whitespace (not final whitespace) then
|
|
|
|
|
;; the delimiter start at the end of that
|
|
|
|
|
;; whitespace. Otherwise, it starts at the
|
|
|
|
|
;; beginning of what was matched.
|
|
|
|
|
(skip-syntax-backward " " (match-beginning 0))
|
|
|
|
|
(skip-syntax-backward "^ " (match-beginning 0)))))
|
|
|
|
|
(setq begpos (point))
|
|
|
|
|
;; Compute desired indent.
|
|
|
|
|
(if (= (current-column)
|
|
|
|
|
(setq indent (if comment-indent-hook
|
|
|
|
|
(funcall comment-indent-hook)
|
|
|
|
|
(funcall comment-indent-function))))
|
|
|
|
|
(goto-char begpos)
|
|
|
|
|
;; If that's different from current, change it.
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(delete-region (point) begpos)
|
|
|
|
|
(indent-to indent))
|
|
|
|
|
;; An existing comment?
|
|
|
|
|
(if cpos
|
|
|
|
|
(progn (goto-char cpos)
|
|
|
|
|
(set-marker cpos nil))
|
|
|
|
|
;; No, insert one.
|
|
|
|
|
(insert starter)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(insert ender)))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun set-comment-column (arg)
|
|
|
|
|
"Set the comment column based on point.
|
|
|
|
|
With no arg, set the comment column to the current column.
|
|
|
|
|
With just minus as arg, kill any comment on this line.
|
|
|
|
|
With any other arg, set comment column to indentation of the previous comment
|
|
|
|
|
and then align or create a comment on this line at that column."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (eq arg '-)
|
|
|
|
|
(kill-comment nil)
|
|
|
|
|
(if arg
|
|
|
|
|
(progn
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(re-search-backward comment-start-skip)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(re-search-forward comment-start-skip)
|
|
|
|
|
(goto-char (match-beginning 0))
|
|
|
|
|
(setq comment-column (current-column))
|
|
|
|
|
(message "Comment column set to %d" comment-column))
|
|
|
|
|
(indent-for-comment))
|
|
|
|
|
(setq comment-column (current-column))
|
|
|
|
|
(message "Comment column set to %d" comment-column))))
|
|
|
|
|
|
|
|
|
|
(defun kill-comment (arg)
|
|
|
|
|
"Kill the comment on this line, if any.
|
|
|
|
|
With argument, kill comments on that many lines starting with this one."
|
|
|
|
|
;; this function loses in a lot of situations. it incorrectly recognises
|
|
|
|
|
;; comment delimiters sometimes (ergo, inside a string), doesn't work
|
|
|
|
|
;; with multi-line comments, can kill extra whitespace if comment wasn't
|
|
|
|
|
;; through end-of-line, et cetera.
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(or comment-start-skip (error "No comment syntax defined"))
|
|
|
|
|
(let ((count (prefix-numeric-value arg)) endc)
|
|
|
|
|
(while (> count 0)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(setq endc (point))
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(and (string< "" comment-end)
|
|
|
|
|
(setq endc
|
|
|
|
|
(progn
|
|
|
|
|
(re-search-forward (regexp-quote comment-end) endc 'move)
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
(point))))
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(if (re-search-forward comment-start-skip endc t)
|
|
|
|
|
(progn
|
|
|
|
|
(goto-char (match-beginning 0))
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(kill-region (point) endc)
|
|
|
|
|
;; to catch comments a line beginnings
|
|
|
|
|
(indent-according-to-mode))))
|
|
|
|
|
(if arg (forward-line 1))
|
|
|
|
|
(setq count (1- count)))))
|
|
|
|
|
|
|
|
|
|
(defun comment-region (beg end &optional arg)
|
1994-02-02 00:05:42 +00:00
|
|
|
|
"Comment or uncomment each line in the region.
|
|
|
|
|
With just C-u prefix arg, uncomment each line in region.
|
|
|
|
|
Numeric prefix arg ARG means use ARG comment characters.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
If ARG is negative, delete that many comment characters instead.
|
|
|
|
|
Comments are terminated on each line, even for syntax in which newline does
|
|
|
|
|
not end the comment. Blank lines do not get comments."
|
|
|
|
|
;; if someone wants it to only put a comment-start at the beginning and
|
|
|
|
|
;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x
|
|
|
|
|
;; is easy enough. No option is made here for other than commenting
|
|
|
|
|
;; every line.
|
1994-02-02 00:05:42 +00:00
|
|
|
|
(interactive "r\nP")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(or comment-start (error "No comment syntax is defined"))
|
|
|
|
|
(if (> beg end) (let (mid) (setq mid beg beg end end mid)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
1994-02-02 00:05:42 +00:00
|
|
|
|
(let ((cs comment-start) (ce comment-end)
|
|
|
|
|
numarg)
|
|
|
|
|
(if (consp arg) (setq numarg t)
|
|
|
|
|
(setq numarg (prefix-numeric-value arg))
|
|
|
|
|
;; For positive arg > 1, replicate the comment delims now,
|
|
|
|
|
;; then insert the replicated strings just once.
|
|
|
|
|
(while (> numarg 1)
|
|
|
|
|
(setq cs (concat cs comment-start)
|
|
|
|
|
ce (concat ce comment-end))
|
|
|
|
|
(setq numarg (1- numarg))))
|
|
|
|
|
;; Loop over all lines from BEG to END.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(narrow-to-region beg end)
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
(while (not (eobp))
|
1994-02-02 00:05:42 +00:00
|
|
|
|
(if (or (eq numarg t) (< numarg 0))
|
|
|
|
|
(progn
|
|
|
|
|
;; Delete comment start from beginning of line.
|
|
|
|
|
(if (eq numarg t)
|
|
|
|
|
(while (looking-at (regexp-quote cs))
|
|
|
|
|
(delete-char (length cs)))
|
|
|
|
|
(let ((count numarg))
|
|
|
|
|
(while (and (> 1 (setq count (1+ count)))
|
|
|
|
|
(looking-at (regexp-quote cs)))
|
|
|
|
|
(delete-char (length cs)))))
|
|
|
|
|
;; Delete comment end from end of line.
|
|
|
|
|
(if (string= "" ce)
|
|
|
|
|
nil
|
|
|
|
|
(if (eq numarg t)
|
|
|
|
|
(progn
|
|
|
|
|
(end-of-line)
|
|
|
|
|
;; This is questionable if comment-end ends in
|
|
|
|
|
;; whitespace. That is pretty brain-damaged,
|
|
|
|
|
;; though.
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(if (and (>= (- (point) (point-min)) (length ce))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(backward-char (length ce))
|
|
|
|
|
(looking-at (regexp-quote ce))))
|
|
|
|
|
(delete-char (- (length ce)))))
|
1994-02-04 01:13:05 +00:00
|
|
|
|
(let ((count numarg))
|
|
|
|
|
(while (> 1 (setq count (1+ count)))
|
|
|
|
|
(end-of-line)
|
|
|
|
|
;; this is questionable if comment-end ends in whitespace
|
|
|
|
|
;; that is pretty brain-damaged though
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(backward-char (length ce))
|
|
|
|
|
(if (looking-at (regexp-quote ce))
|
|
|
|
|
(delete-char (length ce))))))))
|
1992-10-20 21:22:44 +00:00
|
|
|
|
(forward-line 1))
|
1994-02-02 00:05:42 +00:00
|
|
|
|
;; Insert at beginning and at end.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if (looking-at "[ \t]*$") ()
|
|
|
|
|
(insert cs)
|
|
|
|
|
(if (string= "" ce) ()
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(insert ce)))
|
|
|
|
|
(search-forward "\n" nil 'move)))))))
|
|
|
|
|
|
|
|
|
|
(defun backward-word (arg)
|
|
|
|
|
"Move backward until encountering the end of a word.
|
|
|
|
|
With argument, do this that many times.
|
1992-08-21 07:18:16 +00:00
|
|
|
|
In programs, it is faster to call `forward-word' with negative arg."
|
1994-02-03 23:48:59 +00:00
|
|
|
|
(interactive "p")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(forward-word (- arg)))
|
|
|
|
|
|
|
|
|
|
(defun mark-word (arg)
|
|
|
|
|
"Set mark arg words away from point."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(push-mark
|
|
|
|
|
(save-excursion
|
|
|
|
|
(forward-word arg)
|
1993-05-16 15:39:39 +00:00
|
|
|
|
(point))
|
|
|
|
|
nil t))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun kill-word (arg)
|
|
|
|
|
"Kill characters forward until encountering the end of a word.
|
|
|
|
|
With argument, do this that many times."
|
|
|
|
|
(interactive "p")
|
1994-04-24 05:44:23 +00:00
|
|
|
|
(kill-region (point) (progn (forward-word arg) (point))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun backward-kill-word (arg)
|
|
|
|
|
"Kill characters backward until encountering the end of a word.
|
|
|
|
|
With argument, do this that many times."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(kill-word (- arg)))
|
1993-03-29 04:58:31 +00:00
|
|
|
|
|
1994-03-03 18:27:51 +00:00
|
|
|
|
(defun current-word (&optional strict)
|
|
|
|
|
"Return the word point is on (or a nearby word) as a string.
|
|
|
|
|
If optional arg STRICT is non-nil, return nil unless point is within
|
|
|
|
|
or adjacent to a word."
|
1993-03-29 04:58:31 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(let ((oldpoint (point)) (start (point)) (end (point)))
|
|
|
|
|
(skip-syntax-backward "w_") (setq start (point))
|
|
|
|
|
(goto-char oldpoint)
|
|
|
|
|
(skip-syntax-forward "w_") (setq end (point))
|
|
|
|
|
(if (and (eq start oldpoint) (eq end oldpoint))
|
1994-03-03 18:27:51 +00:00
|
|
|
|
;; Point is neither within nor adjacent to a word.
|
|
|
|
|
(and (not strict)
|
|
|
|
|
(progn
|
|
|
|
|
;; Look for preceding word in same line.
|
|
|
|
|
(skip-syntax-backward "^w_"
|
|
|
|
|
(save-excursion (beginning-of-line)
|
|
|
|
|
(point)))
|
|
|
|
|
(if (bolp)
|
|
|
|
|
;; No preceding word in same line.
|
|
|
|
|
;; Look for following word in same line.
|
|
|
|
|
(progn
|
|
|
|
|
(skip-syntax-forward "^w_"
|
|
|
|
|
(save-excursion (end-of-line)
|
|
|
|
|
(point)))
|
|
|
|
|
(setq start (point))
|
|
|
|
|
(skip-syntax-forward "w_")
|
|
|
|
|
(setq end (point)))
|
|
|
|
|
(setq end (point))
|
|
|
|
|
(skip-syntax-backward "w_")
|
|
|
|
|
(setq start (point)))
|
|
|
|
|
(buffer-substring start end)))
|
|
|
|
|
(buffer-substring start end)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defconst fill-prefix nil
|
|
|
|
|
"*String for filling to insert at front of new line, or nil for none.
|
|
|
|
|
Setting this variable automatically makes it local to the current buffer.")
|
|
|
|
|
(make-variable-buffer-local 'fill-prefix)
|
|
|
|
|
|
|
|
|
|
(defconst auto-fill-inhibit-regexp nil
|
|
|
|
|
"*Regexp to match lines which should not be auto-filled.")
|
|
|
|
|
|
1996-05-21 14:31:40 +00:00
|
|
|
|
;; This function is the auto-fill-function of a buffer
|
|
|
|
|
;; when Auto-Fill mode is enabled.
|
|
|
|
|
;; It returns t if it really did any work.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun do-auto-fill ()
|
1995-07-28 02:38:16 +00:00
|
|
|
|
(let (fc justify bol give-up
|
|
|
|
|
(fill-prefix fill-prefix))
|
1995-01-19 04:26:55 +00:00
|
|
|
|
(if (or (not (setq justify (current-justification)))
|
1995-06-29 03:18:29 +00:00
|
|
|
|
(null (setq fc (current-fill-column)))
|
|
|
|
|
(and (eq justify 'left)
|
|
|
|
|
(<= (current-column) fc))
|
1995-01-19 04:21:56 +00:00
|
|
|
|
(save-excursion (beginning-of-line)
|
|
|
|
|
(setq bol (point))
|
|
|
|
|
(and auto-fill-inhibit-regexp
|
|
|
|
|
(looking-at auto-fill-inhibit-regexp))))
|
|
|
|
|
nil ;; Auto-filling not required
|
1995-02-23 18:38:42 +00:00
|
|
|
|
(if (memq justify '(full center right))
|
|
|
|
|
(save-excursion (unjustify-current-line)))
|
1995-07-28 02:38:16 +00:00
|
|
|
|
|
|
|
|
|
;; Choose a fill-prefix automatically.
|
|
|
|
|
(if (and adaptive-fill-mode
|
|
|
|
|
(or (null fill-prefix) (string= fill-prefix "")))
|
1995-11-18 16:46:53 +00:00
|
|
|
|
(let ((prefix
|
|
|
|
|
(fill-context-prefix
|
|
|
|
|
(save-excursion (backward-paragraph 1) (point))
|
|
|
|
|
(save-excursion (forward-paragraph 1) (point))
|
|
|
|
|
;; Don't accept a non-whitespace fill prefix
|
|
|
|
|
;; from the first line of a paragraph.
|
|
|
|
|
"^[ \t]*$")))
|
|
|
|
|
(and prefix (not (equal prefix ""))
|
|
|
|
|
(setq fill-prefix prefix))))
|
1995-07-28 02:38:16 +00:00
|
|
|
|
|
1995-01-19 04:21:56 +00:00
|
|
|
|
(while (and (not give-up) (> (current-column) fc))
|
1995-07-30 00:46:23 +00:00
|
|
|
|
;; Determine where to split the line.
|
|
|
|
|
(let ((fill-point
|
|
|
|
|
(let ((opoint (point))
|
|
|
|
|
bounce
|
1996-08-30 16:59:20 +00:00
|
|
|
|
(first t)
|
|
|
|
|
after-prefix)
|
1995-07-30 00:46:23 +00:00
|
|
|
|
(save-excursion
|
1996-08-30 16:59:20 +00:00
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(setq after-prefix (point))
|
|
|
|
|
(and fill-prefix
|
|
|
|
|
(looking-at (regexp-quote fill-prefix))
|
|
|
|
|
(setq after-prefix (match-end 0)))
|
1995-07-30 00:46:23 +00:00
|
|
|
|
(move-to-column (1+ fc))
|
|
|
|
|
;; Move back to a word boundary.
|
|
|
|
|
(while (or first
|
|
|
|
|
;; If this is after period and a single space,
|
|
|
|
|
;; move back once more--we don't want to break
|
|
|
|
|
;; the line there and make it look like a
|
|
|
|
|
;; sentence end.
|
|
|
|
|
(and (not (bobp))
|
|
|
|
|
(not bounce)
|
|
|
|
|
sentence-end-double-space
|
|
|
|
|
(save-excursion (forward-char -1)
|
|
|
|
|
(and (looking-at "\\. ")
|
|
|
|
|
(not (looking-at "\\. "))))))
|
|
|
|
|
(setq first nil)
|
|
|
|
|
(skip-chars-backward "^ \t\n")
|
|
|
|
|
;; If we find nowhere on the line to break it,
|
|
|
|
|
;; break after one word. Set bounce to t
|
|
|
|
|
;; so we will not keep going in this while loop.
|
1996-08-30 16:59:20 +00:00
|
|
|
|
(if (<= (point) after-prefix)
|
1995-07-30 00:46:23 +00:00
|
|
|
|
(progn
|
|
|
|
|
(re-search-forward "[ \t]" opoint t)
|
|
|
|
|
(setq bounce t)))
|
|
|
|
|
(skip-chars-backward " \t"))
|
|
|
|
|
;; Let fill-point be set to the place where we end up.
|
|
|
|
|
(point)))))
|
|
|
|
|
;; If that place is not the beginning of the line,
|
|
|
|
|
;; break the line there.
|
|
|
|
|
(if (save-excursion
|
|
|
|
|
(goto-char fill-point)
|
|
|
|
|
(not (bolp)))
|
|
|
|
|
(let ((prev-column (current-column)))
|
|
|
|
|
;; If point is at the fill-point, do not `save-excursion'.
|
|
|
|
|
;; Otherwise, if a comment prefix or fill-prefix is inserted,
|
|
|
|
|
;; point will end up before it rather than after it.
|
|
|
|
|
(if (save-excursion
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(= (point) fill-point))
|
|
|
|
|
(indent-new-comment-line t)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char fill-point)
|
|
|
|
|
(indent-new-comment-line t)))
|
|
|
|
|
;; Now do justification, if required
|
|
|
|
|
(if (not (eq justify 'left))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(end-of-line 0)
|
|
|
|
|
(justify-current-line justify nil t)))
|
|
|
|
|
;; If making the new line didn't reduce the hpos of
|
|
|
|
|
;; the end of the line, then give up now;
|
|
|
|
|
;; trying again will not help.
|
|
|
|
|
(if (>= (current-column) prev-column)
|
|
|
|
|
(setq give-up t)))
|
|
|
|
|
;; No place to break => stop trying.
|
|
|
|
|
(setq give-up t))))
|
1996-08-07 19:45:46 +00:00
|
|
|
|
;; Justify last line.
|
1996-05-21 14:31:40 +00:00
|
|
|
|
(justify-current-line justify t t)
|
|
|
|
|
t)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1996-08-07 19:45:46 +00:00
|
|
|
|
(defvar normal-auto-fill-function 'do-auto-fill
|
|
|
|
|
"The function to use for `auto-fill-function' if Auto Fill mode is turned on.
|
|
|
|
|
Some major modes set this.")
|
|
|
|
|
|
1994-04-16 02:06:17 +00:00
|
|
|
|
(defun auto-fill-mode (&optional arg)
|
1996-08-07 19:45:46 +00:00
|
|
|
|
"Toggle Auto Fill mode.
|
|
|
|
|
With arg, turn Auto Fill mode on if and only if arg is positive.
|
|
|
|
|
In Auto Fill mode, inserting a space at a column beyond `current-fill-column'
|
|
|
|
|
automatically breaks the line at a previous space.
|
|
|
|
|
|
|
|
|
|
The value of `normal-auto-fill-function' specifies the function to use
|
|
|
|
|
for `auto-fill-function' when turning Auto Fill mode on."
|
1994-04-16 02:06:17 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(prog1 (setq auto-fill-function
|
|
|
|
|
(if (if (null arg)
|
|
|
|
|
(not auto-fill-function)
|
|
|
|
|
(> (prefix-numeric-value arg) 0))
|
1996-08-07 19:45:46 +00:00
|
|
|
|
normal-auto-fill-function
|
1994-04-16 02:06:17 +00:00
|
|
|
|
nil))
|
1995-04-25 22:26:16 +00:00
|
|
|
|
(force-mode-line-update)))
|
1994-04-16 02:06:17 +00:00
|
|
|
|
|
|
|
|
|
;; This holds a document string used to document auto-fill-mode.
|
|
|
|
|
(defun auto-fill-function ()
|
|
|
|
|
"Automatically break line at a previous space, in insertion of text."
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(defun turn-on-auto-fill ()
|
|
|
|
|
"Unconditionally turn on Auto Fill mode."
|
|
|
|
|
(auto-fill-mode 1))
|
|
|
|
|
|
|
|
|
|
(defun set-fill-column (arg)
|
1996-06-14 02:11:11 +00:00
|
|
|
|
"Set `fill-column' to specified argument.
|
|
|
|
|
Just \\[universal-argument] as argument means to use the current column."
|
1994-04-16 02:06:17 +00:00
|
|
|
|
(interactive "P")
|
1996-06-14 02:11:11 +00:00
|
|
|
|
(cond ((integerp arg)
|
|
|
|
|
(setq fill-column arg))
|
|
|
|
|
((consp arg)
|
|
|
|
|
(setq fill-column (current-column)))
|
|
|
|
|
;; Disallow missing argument; it's probably a typo for C-x C-f.
|
|
|
|
|
(t
|
|
|
|
|
(error "set-fill-column requires an explicit argument")))
|
1994-04-16 02:06:17 +00:00
|
|
|
|
(message "fill-column set to %d" fill-column))
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defconst comment-multi-line nil
|
|
|
|
|
"*Non-nil means \\[indent-new-comment-line] should continue same comment
|
1992-05-30 21:11:25 +00:00
|
|
|
|
on new line, with no new terminator or starter.
|
|
|
|
|
This is obsolete because you might as well use \\[newline-and-indent].")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1995-01-13 08:43:40 +00:00
|
|
|
|
(defun indent-new-comment-line (&optional soft)
|
1994-04-16 02:06:17 +00:00
|
|
|
|
"Break line at point and indent, continuing comment if within one.
|
|
|
|
|
This indents the body of the continued comment
|
|
|
|
|
under the previous comment line.
|
1992-05-30 21:11:25 +00:00
|
|
|
|
|
|
|
|
|
This command is intended for styles where you write a comment per line,
|
|
|
|
|
starting a new comment (and terminating it if necessary) on each line.
|
1995-01-13 08:43:40 +00:00
|
|
|
|
If you want to continue one comment across several lines, use \\[newline-and-indent].
|
|
|
|
|
|
1995-07-21 01:43:21 +00:00
|
|
|
|
If a fill column is specified, it overrides the use of the comment column
|
|
|
|
|
or comment indentation.
|
|
|
|
|
|
1995-01-13 08:43:40 +00:00
|
|
|
|
The inserted newline is marked hard if `use-hard-newlines' is true,
|
|
|
|
|
unless optional argument SOFT is non-nil."
|
|
|
|
|
(interactive)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(let (comcol comstart)
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(delete-region (point)
|
|
|
|
|
(progn (skip-chars-forward " \t")
|
|
|
|
|
(point)))
|
1995-01-19 04:21:56 +00:00
|
|
|
|
(if soft (insert-and-inherit ?\n) (newline 1))
|
1995-07-21 01:43:21 +00:00
|
|
|
|
(if fill-prefix
|
|
|
|
|
(progn
|
|
|
|
|
(indent-to-left-margin)
|
|
|
|
|
(insert-and-inherit fill-prefix))
|
|
|
|
|
(if (not comment-multi-line)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(save-excursion
|
1995-07-21 01:43:21 +00:00
|
|
|
|
(if (and comment-start-skip
|
|
|
|
|
(let ((opoint (point)))
|
|
|
|
|
(forward-line -1)
|
|
|
|
|
(re-search-forward comment-start-skip opoint t)))
|
|
|
|
|
;; The old line is a comment.
|
|
|
|
|
;; Set WIN to the pos of the comment-start.
|
|
|
|
|
;; But if the comment is empty, look at preceding lines
|
|
|
|
|
;; to find one that has a nonempty comment.
|
|
|
|
|
|
|
|
|
|
;; If comment-start-skip contains a \(...\) pair,
|
|
|
|
|
;; the real comment delimiter starts at the end of that pair.
|
|
|
|
|
(let ((win (or (match-end 1) (match-beginning 0))))
|
|
|
|
|
(while (and (eolp) (not (bobp))
|
|
|
|
|
(let (opoint)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(setq opoint (point))
|
|
|
|
|
(forward-line -1)
|
|
|
|
|
(re-search-forward comment-start-skip opoint t)))
|
|
|
|
|
(setq win (or (match-end 1) (match-beginning 0))))
|
|
|
|
|
;; Indent this line like what we found.
|
|
|
|
|
(goto-char win)
|
|
|
|
|
(setq comcol (current-column))
|
|
|
|
|
(setq comstart
|
|
|
|
|
(buffer-substring (point) (match-end 0)))))))
|
|
|
|
|
(if comcol
|
|
|
|
|
(let ((comment-column comcol)
|
|
|
|
|
(comment-start comstart)
|
|
|
|
|
(comment-end comment-end))
|
|
|
|
|
(and comment-end (not (equal comment-end ""))
|
|
|
|
|
; (if (not comment-multi-line)
|
|
|
|
|
(progn
|
|
|
|
|
(forward-char -1)
|
|
|
|
|
(insert comment-end)
|
|
|
|
|
(forward-char 1))
|
|
|
|
|
; (setq comment-column (+ comment-column (length comment-start))
|
|
|
|
|
; comment-start "")
|
|
|
|
|
; )
|
|
|
|
|
)
|
|
|
|
|
(if (not (eolp))
|
|
|
|
|
(setq comment-end ""))
|
|
|
|
|
(insert-and-inherit ?\n)
|
|
|
|
|
(forward-char -1)
|
|
|
|
|
(indent-for-comment)
|
|
|
|
|
(save-excursion
|
|
|
|
|
;; Make sure we delete the newline inserted above.
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(delete-char 1)))
|
|
|
|
|
(indent-according-to-mode)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
|
|
|
|
(defun set-selective-display (arg)
|
1992-08-21 07:18:16 +00:00
|
|
|
|
"Set `selective-display' to ARG; clear it if no arg.
|
|
|
|
|
When the value of `selective-display' is a number > 0,
|
|
|
|
|
lines whose indentation is >= that value are not displayed.
|
|
|
|
|
The variable `selective-display' has a separate value for each buffer."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (eq selective-display t)
|
|
|
|
|
(error "selective-display already in use for marked lines"))
|
1992-05-30 21:11:25 +00:00
|
|
|
|
(let ((current-vpos
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region (point-min) (point))
|
|
|
|
|
(goto-char (window-start))
|
|
|
|
|
(vertical-motion (window-height)))))
|
|
|
|
|
(setq selective-display
|
|
|
|
|
(and arg (prefix-numeric-value arg)))
|
|
|
|
|
(recenter current-vpos))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(set-window-start (selected-window) (window-start (selected-window)))
|
|
|
|
|
(princ "selective-display set to " t)
|
|
|
|
|
(prin1 selective-display t)
|
|
|
|
|
(princ "." t))
|
|
|
|
|
|
1993-03-16 18:18:47 +00:00
|
|
|
|
(defconst overwrite-mode-textual " Ovwrt"
|
|
|
|
|
"The string displayed in the mode line when in overwrite mode.")
|
|
|
|
|
(defconst overwrite-mode-binary " Bin Ovwrt"
|
|
|
|
|
"The string displayed in the mode line when in binary overwrite mode.")
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun overwrite-mode (arg)
|
|
|
|
|
"Toggle overwrite mode.
|
|
|
|
|
With arg, turn overwrite mode on iff arg is positive.
|
|
|
|
|
In overwrite mode, printing characters typed in replace existing text
|
1993-03-16 18:18:47 +00:00
|
|
|
|
on a one-for-one basis, rather than pushing it to the right. At the
|
|
|
|
|
end of a line, such characters extend the line. Before a tab,
|
|
|
|
|
such characters insert until the tab is filled in.
|
|
|
|
|
\\[quoted-insert] still inserts characters in overwrite mode; this
|
|
|
|
|
is supposed to make it easier to insert characters when necessary."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq overwrite-mode
|
|
|
|
|
(if (if (null arg) (not overwrite-mode)
|
|
|
|
|
(> (prefix-numeric-value arg) 0))
|
|
|
|
|
'overwrite-mode-textual))
|
|
|
|
|
(force-mode-line-update))
|
|
|
|
|
|
|
|
|
|
(defun binary-overwrite-mode (arg)
|
|
|
|
|
"Toggle binary overwrite mode.
|
|
|
|
|
With arg, turn binary overwrite mode on iff arg is positive.
|
|
|
|
|
In binary overwrite mode, printing characters typed in replace
|
|
|
|
|
existing text. Newlines are not treated specially, so typing at the
|
|
|
|
|
end of a line joins the line to the next, with the typed character
|
|
|
|
|
between them. Typing before a tab character simply replaces the tab
|
|
|
|
|
with the character typed.
|
|
|
|
|
\\[quoted-insert] replaces the text at the cursor, just as ordinary
|
|
|
|
|
typing characters do.
|
|
|
|
|
|
|
|
|
|
Note that binary overwrite mode is not its own minor mode; it is a
|
|
|
|
|
specialization of overwrite-mode, entered by setting the
|
|
|
|
|
`overwrite-mode' variable to `overwrite-mode-binary'."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq overwrite-mode
|
1993-03-16 18:18:47 +00:00
|
|
|
|
(if (if (null arg)
|
1993-03-21 08:22:37 +00:00
|
|
|
|
(not (eq overwrite-mode 'overwrite-mode-binary))
|
1993-03-16 18:18:47 +00:00
|
|
|
|
(> (prefix-numeric-value arg) 0))
|
|
|
|
|
'overwrite-mode-binary))
|
|
|
|
|
(force-mode-line-update))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1995-08-06 06:27:10 +00:00
|
|
|
|
(defvar line-number-mode t
|
1993-03-21 08:22:37 +00:00
|
|
|
|
"*Non-nil means display line number in mode line.")
|
|
|
|
|
|
|
|
|
|
(defun line-number-mode (arg)
|
|
|
|
|
"Toggle Line Number mode.
|
|
|
|
|
With arg, turn Line Number mode on iff arg is positive.
|
|
|
|
|
When Line Number mode is enabled, the line number appears
|
|
|
|
|
in the mode line."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq line-number-mode
|
|
|
|
|
(if (null arg) (not line-number-mode)
|
|
|
|
|
(> (prefix-numeric-value arg) 0)))
|
|
|
|
|
(force-mode-line-update))
|
|
|
|
|
|
1995-10-29 23:03:05 +00:00
|
|
|
|
(defvar column-number-mode nil
|
1995-07-17 23:03:53 +00:00
|
|
|
|
"*Non-nil means display column number in mode line.")
|
|
|
|
|
|
|
|
|
|
(defun column-number-mode (arg)
|
|
|
|
|
"Toggle Column Number mode.
|
|
|
|
|
With arg, turn Column Number mode on iff arg is positive.
|
|
|
|
|
When Column Number mode is enabled, the column number appears
|
|
|
|
|
in the mode line."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq column-number-mode
|
|
|
|
|
(if (null arg) (not column-number-mode)
|
|
|
|
|
(> (prefix-numeric-value arg) 0)))
|
|
|
|
|
(force-mode-line-update))
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defvar blink-matching-paren t
|
|
|
|
|
"*Non-nil means show matching open-paren when close-paren is inserted.")
|
|
|
|
|
|
1995-12-21 18:08:12 +00:00
|
|
|
|
(defvar blink-matching-paren-on-screen t
|
|
|
|
|
"*Non-nil means show matching open-paren when it is on screen.
|
|
|
|
|
nil means don't show it (but the open-paren can still be shown
|
|
|
|
|
when it is off screen.")
|
|
|
|
|
|
1993-05-05 18:12:04 +00:00
|
|
|
|
(defconst blink-matching-paren-distance 12000
|
|
|
|
|
"*If non-nil, is maximum distance to search for matching open-paren.")
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1994-11-01 04:22:00 +00:00
|
|
|
|
(defconst blink-matching-delay 1
|
|
|
|
|
"*The number of seconds that `blink-matching-open' will delay at a match.")
|
|
|
|
|
|
1995-08-19 16:59:43 +00:00
|
|
|
|
(defconst blink-matching-paren-dont-ignore-comments nil
|
|
|
|
|
"*Non-nil means `blink-matching-paren' should not ignore comments.")
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun blink-matching-open ()
|
|
|
|
|
"Move cursor momentarily to the beginning of the sexp before point."
|
|
|
|
|
(interactive)
|
|
|
|
|
(and (> (point) (1+ (point-min)))
|
|
|
|
|
blink-matching-paren
|
1994-10-30 02:19:14 +00:00
|
|
|
|
;; Verify an even number of quoting characters precede the close.
|
|
|
|
|
(= 1 (logand 1 (- (point)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(forward-char -1)
|
|
|
|
|
(skip-syntax-backward "/\\")
|
|
|
|
|
(point)))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(let* ((oldpos (point))
|
|
|
|
|
(blinkpos)
|
|
|
|
|
(mismatch))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(if blink-matching-paren-distance
|
|
|
|
|
(narrow-to-region (max (point-min)
|
|
|
|
|
(- (point) blink-matching-paren-distance))
|
|
|
|
|
oldpos))
|
|
|
|
|
(condition-case ()
|
1995-08-19 16:59:43 +00:00
|
|
|
|
(let ((parse-sexp-ignore-comments
|
|
|
|
|
(and parse-sexp-ignore-comments
|
|
|
|
|
(not blink-matching-paren-dont-ignore-comments))))
|
|
|
|
|
(setq blinkpos (scan-sexps oldpos -1)))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(error nil)))
|
1995-08-19 16:59:43 +00:00
|
|
|
|
(and blinkpos
|
|
|
|
|
(/= (char-syntax (char-after blinkpos))
|
|
|
|
|
?\$)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(setq mismatch
|
1995-08-19 16:59:43 +00:00
|
|
|
|
(or (null (matching-paren (char-after blinkpos)))
|
|
|
|
|
(/= (char-after (1- oldpos))
|
|
|
|
|
(matching-paren (char-after blinkpos))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if mismatch (setq blinkpos nil))
|
|
|
|
|
(if blinkpos
|
|
|
|
|
(progn
|
|
|
|
|
(goto-char blinkpos)
|
|
|
|
|
(if (pos-visible-in-window-p)
|
1995-12-21 18:08:12 +00:00
|
|
|
|
(and blink-matching-paren-on-screen
|
|
|
|
|
(sit-for blink-matching-delay))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(goto-char blinkpos)
|
|
|
|
|
(message
|
|
|
|
|
"Matches %s"
|
1994-03-26 05:53:18 +00:00
|
|
|
|
;; Show what precedes the open in its line, if anything.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(if (save-excursion
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(not (bolp)))
|
|
|
|
|
(buffer-substring (progn (beginning-of-line) (point))
|
|
|
|
|
(1+ blinkpos))
|
1994-03-26 05:53:18 +00:00
|
|
|
|
;; Show what follows the open in its line, if anything.
|
|
|
|
|
(if (save-excursion
|
|
|
|
|
(forward-char 1)
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
(not (eolp)))
|
|
|
|
|
(buffer-substring blinkpos
|
|
|
|
|
(progn (end-of-line) (point)))
|
1994-10-11 07:29:05 +00:00
|
|
|
|
;; Otherwise show the previous nonblank line,
|
|
|
|
|
;; if there is one.
|
|
|
|
|
(if (save-excursion
|
|
|
|
|
(skip-chars-backward "\n \t")
|
|
|
|
|
(not (bobp)))
|
|
|
|
|
(concat
|
|
|
|
|
(buffer-substring (progn
|
|
|
|
|
(skip-chars-backward "\n \t")
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(point))
|
|
|
|
|
(progn (end-of-line)
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(point)))
|
|
|
|
|
;; Replace the newline and other whitespace with `...'.
|
|
|
|
|
"..."
|
|
|
|
|
(buffer-substring blinkpos (1+ blinkpos)))
|
|
|
|
|
;; There is nothing to show except the char itself.
|
|
|
|
|
(buffer-substring blinkpos (1+ blinkpos))))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(cond (mismatch
|
|
|
|
|
(message "Mismatched parentheses"))
|
|
|
|
|
((not blink-matching-paren-distance)
|
|
|
|
|
(message "Unmatched parenthesis"))))))))
|
|
|
|
|
|
|
|
|
|
;Turned off because it makes dbx bomb out.
|
|
|
|
|
(setq blink-paren-function 'blink-matching-open)
|
|
|
|
|
|
1993-05-15 20:55:02 +00:00
|
|
|
|
;; This executes C-g typed while Emacs is waiting for a command.
|
|
|
|
|
;; Quitting out of a program does not go through here;
|
|
|
|
|
;; that happens in the QUIT macro at the C code level.
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun keyboard-quit ()
|
1993-03-09 05:40:33 +00:00
|
|
|
|
"Signal a quit condition.
|
|
|
|
|
During execution of Lisp code, this character causes a quit directly.
|
|
|
|
|
At top-level, as an editor command, this simply beeps."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive)
|
1993-07-08 22:37:42 +00:00
|
|
|
|
(deactivate-mark)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(signal 'quit nil))
|
|
|
|
|
|
|
|
|
|
(define-key global-map "\C-g" 'keyboard-quit)
|
1994-11-28 19:44:16 +00:00
|
|
|
|
|
1994-12-15 02:02:04 +00:00
|
|
|
|
(defvar buffer-quit-function nil
|
|
|
|
|
"Function to call to \"quit\" the current buffer, or nil if none.
|
|
|
|
|
\\[keyboard-escape-quit] calls this function when its more local actions
|
|
|
|
|
\(such as cancelling a prefix argument, minibuffer or region) do not apply.")
|
|
|
|
|
|
1994-11-28 19:44:16 +00:00
|
|
|
|
(defun keyboard-escape-quit ()
|
|
|
|
|
"Exit the current \"mode\" (in a generalized sense of the word).
|
|
|
|
|
This command can exit an interactive command such as `query-replace',
|
|
|
|
|
can clear out a prefix argument or a region,
|
|
|
|
|
can get out of the minibuffer or other recursive edit,
|
1994-12-15 02:02:04 +00:00
|
|
|
|
cancel the use of the current buffer (for special-purpose buffers),
|
|
|
|
|
or go back to just one window (by deleting all but the selected window)."
|
1994-11-28 19:44:16 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(cond ((eq last-command 'mode-exited) nil)
|
|
|
|
|
((> (minibuffer-depth) 0)
|
|
|
|
|
(abort-recursive-edit))
|
|
|
|
|
(current-prefix-arg
|
|
|
|
|
nil)
|
|
|
|
|
((and transient-mark-mode
|
|
|
|
|
mark-active)
|
|
|
|
|
(deactivate-mark))
|
1994-12-15 02:02:04 +00:00
|
|
|
|
(buffer-quit-function
|
|
|
|
|
(funcall buffer-quit-function))
|
1994-11-28 19:44:16 +00:00
|
|
|
|
((not (one-window-p t))
|
|
|
|
|
(delete-other-windows))))
|
|
|
|
|
|
1994-12-15 02:02:04 +00:00
|
|
|
|
(define-key global-map "\e\e\e" 'keyboard-escape-quit)
|
1991-12-21 09:29:41 +00:00
|
|
|
|
|
1996-08-30 16:59:20 +00:00
|
|
|
|
(defvar mail-user-agent 'sendmail-user-agent
|
|
|
|
|
"*Your preference for a mail composition package.
|
|
|
|
|
Various Emacs Lisp packages (e.g. reporter) require you to compose an
|
|
|
|
|
outgoing email message. This variable lets you specify which
|
|
|
|
|
mail-sending package you prefer.
|
|
|
|
|
|
|
|
|
|
Valid values include:
|
|
|
|
|
|
|
|
|
|
'sendmail-user-agent -- use Emacs built-in Mail package
|
|
|
|
|
'mh-e-user-agent -- use the Emacs interface to the MH mail system
|
|
|
|
|
|
|
|
|
|
Additional valid symbols may be available; check with the author of
|
|
|
|
|
your package for details.")
|
|
|
|
|
|
|
|
|
|
(defun define-mail-user-agent (symbol composefunc sendfunc
|
|
|
|
|
&optional abortfunc hookvar)
|
|
|
|
|
"Define a symbol to identify a mail-sending package for `mail-user-agent'.
|
|
|
|
|
|
|
|
|
|
SYMBOL can be any Lisp symbol. Its function definition and/or
|
|
|
|
|
value as a variable do not matter for this usage; we use only certain
|
|
|
|
|
properties on its property list, to encode the rest of the arguments.
|
|
|
|
|
|
|
|
|
|
COMPOSEFUNC is program callable function that composes an outgoing
|
|
|
|
|
mail message buffer. This function should set up the basics of the
|
|
|
|
|
buffer without requiring user interaction. It should populate the
|
|
|
|
|
standard mail headers, leaving the `to:' and `subject:' headers blank.
|
|
|
|
|
|
|
|
|
|
SENDFUNC is the command a user would type to send the message.
|
|
|
|
|
|
|
|
|
|
Optional ABORTFUNC is the command a user would type to abort the
|
|
|
|
|
message. For mail packages that don't have a separate abort function,
|
|
|
|
|
this can be `kill-buffer' (the equivalent of omitting this argument).
|
|
|
|
|
|
|
|
|
|
Optional HOOKVAR is a hook variable that gets run before the message
|
|
|
|
|
is actually sent. Reporter will install `reporter-bug-hook' onto this
|
|
|
|
|
hook so that empty bug reports can be suppressed by raising an error.
|
|
|
|
|
If not supplied, `mail-send-hook' will be used.
|
|
|
|
|
|
|
|
|
|
The properties used on SYMBOL are `composefunc', `sendfunc',
|
|
|
|
|
`abortfunc', and `hookvar'."
|
|
|
|
|
(put symbol 'composefunc composefunc)
|
|
|
|
|
(put symbol 'sendfunc sendfunc)
|
|
|
|
|
(put symbol 'abortfunc (or abortfunc 'kill-buffer))
|
|
|
|
|
(put symbol 'hookvar (or hookvar 'mail-send-hook)))
|
|
|
|
|
|
|
|
|
|
(define-mail-user-agent 'sendmail-user-agent
|
|
|
|
|
'(lambda (&rest args) (or (apply 'mail args)
|
|
|
|
|
(error "Message aborted")))
|
|
|
|
|
'mail-send-and-exit)
|
|
|
|
|
|
|
|
|
|
(define-mail-user-agent 'mh-e-user-agent
|
|
|
|
|
'mh-smail-batch 'mh-send-letter 'mh-fully-kill-draft
|
|
|
|
|
'mh-before-send-letter-hook)
|
|
|
|
|
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(defun set-variable (var val)
|
|
|
|
|
"Set VARIABLE to VALUE. VALUE is a Lisp object.
|
|
|
|
|
When using this interactively, supply a Lisp expression for VALUE.
|
1992-07-22 04:22:42 +00:00
|
|
|
|
If you want VALUE to be a string, you must surround it with doublequotes.
|
|
|
|
|
|
|
|
|
|
If VARIABLE has a `variable-interactive' property, that is used as if
|
|
|
|
|
it were the arg to `interactive' (which see) to interactively read the value."
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(let* ((var (read-variable "Set variable: "))
|
|
|
|
|
(minibuffer-help-form
|
|
|
|
|
'(funcall myhelp))
|
|
|
|
|
(myhelp
|
|
|
|
|
(function
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-output-to-temp-buffer "*Help*"
|
|
|
|
|
(prin1 var)
|
|
|
|
|
(princ "\nDocumentation:\n")
|
|
|
|
|
(princ (substring (documentation-property var 'variable-documentation)
|
|
|
|
|
1))
|
|
|
|
|
(if (boundp var)
|
|
|
|
|
(let ((print-length 20))
|
|
|
|
|
(princ "\n\nCurrent value: ")
|
|
|
|
|
(prin1 (symbol-value var))))
|
1994-11-09 05:47:20 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer standard-output)
|
|
|
|
|
(help-mode))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
nil)))))
|
|
|
|
|
(list var
|
1992-07-22 04:22:42 +00:00
|
|
|
|
(let ((prop (get var 'variable-interactive)))
|
|
|
|
|
(if prop
|
|
|
|
|
;; Use VAR's `variable-interactive' property
|
|
|
|
|
;; as an interactive spec for prompting.
|
|
|
|
|
(call-interactively (list 'lambda '(arg)
|
|
|
|
|
(list 'interactive prop)
|
|
|
|
|
'arg))
|
|
|
|
|
(eval-minibuffer (format "Set %s to value: " var)))))))
|
1991-12-21 09:29:41 +00:00
|
|
|
|
(set var val))
|
1993-07-13 21:34:05 +00:00
|
|
|
|
|
|
|
|
|
;; Define the major mode for lists of completions.
|
|
|
|
|
|
1995-04-08 22:42:47 +00:00
|
|
|
|
(defvar completion-list-mode-map nil
|
|
|
|
|
"Local map for completion list buffers.")
|
1993-07-22 05:47:10 +00:00
|
|
|
|
(or completion-list-mode-map
|
1993-07-13 21:34:05 +00:00
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map [mouse-2] 'mouse-choose-completion)
|
1994-06-01 18:28:06 +00:00
|
|
|
|
(define-key map [down-mouse-2] nil)
|
1994-03-27 22:21:04 +00:00
|
|
|
|
(define-key map "\C-m" 'choose-completion)
|
1994-12-15 02:02:04 +00:00
|
|
|
|
(define-key map "\e\e\e" 'delete-completion-window)
|
1994-12-29 18:53:25 +00:00
|
|
|
|
(define-key map [left] 'previous-completion)
|
|
|
|
|
(define-key map [right] 'next-completion)
|
1993-07-22 05:47:10 +00:00
|
|
|
|
(setq completion-list-mode-map map)))
|
1993-07-13 21:34:05 +00:00
|
|
|
|
|
|
|
|
|
;; Completion mode is suitable only for specially formatted data.
|
1993-07-22 05:47:10 +00:00
|
|
|
|
(put 'completion-list-mode 'mode-class 'special)
|
1993-07-13 21:34:05 +00:00
|
|
|
|
|
1995-04-08 22:42:47 +00:00
|
|
|
|
(defvar completion-reference-buffer nil
|
|
|
|
|
"Record the buffer that was current when the completion list was requested.
|
|
|
|
|
This is a local variable in the completion list buffer.
|
1995-04-09 03:33:01 +00:00
|
|
|
|
Initial value is nil to avoid some compiler warnings.")
|
1994-03-02 23:09:40 +00:00
|
|
|
|
|
1995-04-08 22:42:47 +00:00
|
|
|
|
(defvar completion-base-size nil
|
|
|
|
|
"Number of chars at beginning of minibuffer not involved in completion.
|
|
|
|
|
This is a local variable in the completion list buffer
|
|
|
|
|
but it talks about the buffer in `completion-reference-buffer'.
|
|
|
|
|
If this is nil, it means to compare text to determine which part
|
|
|
|
|
of the tail end of the buffer's text is involved in completion.")
|
1994-08-07 18:11:58 +00:00
|
|
|
|
|
1994-12-15 02:02:04 +00:00
|
|
|
|
(defun delete-completion-window ()
|
|
|
|
|
"Delete the completion list window.
|
|
|
|
|
Go to the window from which completion was requested."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((buf completion-reference-buffer))
|
|
|
|
|
(delete-window (selected-window))
|
|
|
|
|
(if (get-buffer-window buf)
|
|
|
|
|
(select-window (get-buffer-window buf)))))
|
|
|
|
|
|
1994-12-29 18:53:25 +00:00
|
|
|
|
(defun previous-completion (n)
|
|
|
|
|
"Move to the previous item in the completion list."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(next-completion (- n)))
|
|
|
|
|
|
|
|
|
|
(defun next-completion (n)
|
|
|
|
|
"Move to the next item in the completion list.
|
1996-01-04 23:20:13 +00:00
|
|
|
|
With prefix argument N, move N items (negative N means move backward)."
|
1994-12-29 18:53:25 +00:00
|
|
|
|
(interactive "p")
|
|
|
|
|
(while (and (> n 0) (not (eobp)))
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(let ((prop (get-text-property (point) 'mouse-face))
|
|
|
|
|
(end (point-max)))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
;; If in a completion, move to the end of it.
|
|
|
|
|
(if prop
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(goto-char (next-single-property-change (point) 'mouse-face nil end)))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
;; Move to start of next one.
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(goto-char (next-single-property-change (point) 'mouse-face nil end)))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
(setq n (1- n)))
|
|
|
|
|
(while (and (< n 0) (not (bobp)))
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(let ((prop (get-text-property (1- (point)) 'mouse-face))
|
|
|
|
|
(end (point-min)))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
;; If in a completion, move to the start of it.
|
|
|
|
|
(if prop
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(goto-char (previous-single-property-change
|
|
|
|
|
(point) 'mouse-face nil end)))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
;; Move to end of the previous completion.
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(goto-char (previous-single-property-change (point) 'mouse-face nil end))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
;; Move to the start of that one.
|
1995-10-11 03:11:11 +00:00
|
|
|
|
(goto-char (previous-single-property-change (point) 'mouse-face nil end)))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
(setq n (1+ n))))
|
|
|
|
|
|
1994-03-27 22:21:04 +00:00
|
|
|
|
(defun choose-completion ()
|
|
|
|
|
"Choose the completion that point is in or next to."
|
|
|
|
|
(interactive)
|
1994-08-07 18:11:58 +00:00
|
|
|
|
(let (beg end completion (buffer completion-reference-buffer)
|
|
|
|
|
(base-size completion-base-size))
|
1994-07-11 21:25:19 +00:00
|
|
|
|
(if (and (not (eobp)) (get-text-property (point) 'mouse-face))
|
|
|
|
|
(setq end (point) beg (1+ (point))))
|
|
|
|
|
(if (and (not (bobp)) (get-text-property (1- (point)) 'mouse-face))
|
1995-03-11 19:13:52 +00:00
|
|
|
|
(setq end (1- (point)) beg (point)))
|
1994-07-11 21:25:19 +00:00
|
|
|
|
(if (null beg)
|
|
|
|
|
(error "No completion here"))
|
|
|
|
|
(setq beg (previous-single-property-change beg 'mouse-face))
|
1994-07-29 21:35:56 +00:00
|
|
|
|
(setq end (or (next-single-property-change end 'mouse-face) (point-max)))
|
1994-08-06 21:51:31 +00:00
|
|
|
|
(setq completion (buffer-substring beg end))
|
|
|
|
|
(let ((owindow (selected-window)))
|
|
|
|
|
(if (and (one-window-p t 'selected-frame)
|
|
|
|
|
(window-dedicated-p (selected-window)))
|
|
|
|
|
;; This is a special buffer's frame
|
|
|
|
|
(iconify-frame (selected-frame))
|
|
|
|
|
(or (window-dedicated-p (selected-window))
|
|
|
|
|
(bury-buffer)))
|
|
|
|
|
(select-window owindow))
|
1994-08-07 18:11:58 +00:00
|
|
|
|
(choose-completion-string completion buffer base-size)))
|
1994-03-27 22:21:04 +00:00
|
|
|
|
|
|
|
|
|
;; Delete the longest partial match for STRING
|
|
|
|
|
;; that can be found before POINT.
|
|
|
|
|
(defun choose-completion-delete-max-match (string)
|
|
|
|
|
(let ((opoint (point))
|
|
|
|
|
(len (min (length string)
|
|
|
|
|
(- (point) (point-min)))))
|
|
|
|
|
(goto-char (- (point) (length string)))
|
1994-05-19 23:06:47 +00:00
|
|
|
|
(if completion-ignore-case
|
|
|
|
|
(setq string (downcase string)))
|
1994-03-27 22:21:04 +00:00
|
|
|
|
(while (and (> len 0)
|
|
|
|
|
(let ((tail (buffer-substring (point)
|
|
|
|
|
(+ (point) len))))
|
1994-05-19 23:06:47 +00:00
|
|
|
|
(if completion-ignore-case
|
|
|
|
|
(setq tail (downcase tail)))
|
1994-03-27 22:21:04 +00:00
|
|
|
|
(not (string= tail (substring string 0 len)))))
|
|
|
|
|
(setq len (1- len))
|
|
|
|
|
(forward-char 1))
|
|
|
|
|
(delete-char len)))
|
|
|
|
|
|
1995-04-08 22:42:47 +00:00
|
|
|
|
;; Switch to BUFFER and insert the completion choice CHOICE.
|
|
|
|
|
;; BASE-SIZE, if non-nil, says how many characters of BUFFER's text
|
|
|
|
|
;; to keep. If it is nil, use choose-completion-delete-max-match instead.
|
1996-06-22 04:50:32 +00:00
|
|
|
|
|
|
|
|
|
;; If BUFFER is the minibuffer, exit the minibuffer
|
|
|
|
|
;; unless it is reading a file name and CHOICE is a directory.
|
1994-08-07 18:11:58 +00:00
|
|
|
|
(defun choose-completion-string (choice &optional buffer base-size)
|
1994-03-27 22:21:04 +00:00
|
|
|
|
(let ((buffer (or buffer completion-reference-buffer)))
|
1994-05-05 05:27:59 +00:00
|
|
|
|
;; If BUFFER is a minibuffer, barf unless it's the currently
|
|
|
|
|
;; active minibuffer.
|
|
|
|
|
(if (and (string-match "\\` \\*Minibuf-[0-9]+\\*\\'" (buffer-name buffer))
|
1995-03-31 01:48:40 +00:00
|
|
|
|
(or (not (active-minibuffer-window))
|
|
|
|
|
(not (equal buffer
|
|
|
|
|
(window-buffer (active-minibuffer-window))))))
|
1994-05-05 05:27:59 +00:00
|
|
|
|
(error "Minibuffer is not active for completion")
|
|
|
|
|
;; Insert the completion into the buffer where completion was requested.
|
|
|
|
|
(set-buffer buffer)
|
1994-08-07 18:11:58 +00:00
|
|
|
|
(if base-size
|
|
|
|
|
(delete-region (+ base-size (point-min)) (point))
|
|
|
|
|
(choose-completion-delete-max-match choice))
|
1994-05-05 05:27:59 +00:00
|
|
|
|
(insert choice)
|
1994-05-26 23:15:32 +00:00
|
|
|
|
(remove-text-properties (- (point) (length choice)) (point)
|
|
|
|
|
'(mouse-face nil))
|
1994-05-05 05:27:59 +00:00
|
|
|
|
;; Update point in the window that BUFFER is showing in.
|
|
|
|
|
(let ((window (get-buffer-window buffer t)))
|
|
|
|
|
(set-window-point window (point)))
|
|
|
|
|
;; If completing for the minibuffer, exit it with this choice.
|
|
|
|
|
(and (equal buffer (window-buffer (minibuffer-window)))
|
1994-08-17 22:33:37 +00:00
|
|
|
|
minibuffer-completion-table
|
1996-06-22 04:50:32 +00:00
|
|
|
|
;; If this is reading a file name, and the file name chosen
|
|
|
|
|
;; is a directory, don't exit the minibuffer.
|
|
|
|
|
(if (and (eq minibuffer-completion-table 'read-file-name-internal)
|
|
|
|
|
(file-directory-p (buffer-string)))
|
|
|
|
|
(select-window (active-minibuffer-window))
|
|
|
|
|
(exit-minibuffer))))))
|
1994-03-27 22:21:04 +00:00
|
|
|
|
|
1993-07-22 05:47:10 +00:00
|
|
|
|
(defun completion-list-mode ()
|
1993-07-13 21:34:05 +00:00
|
|
|
|
"Major mode for buffers showing lists of possible completions.
|
1994-03-27 22:21:04 +00:00
|
|
|
|
Type \\<completion-list-mode-map>\\[choose-completion] in the completion list\
|
|
|
|
|
to select the completion near point.
|
|
|
|
|
Use \\<completion-list-mode-map>\\[mouse-choose-completion] to select one\
|
|
|
|
|
with the mouse."
|
1993-07-13 21:34:05 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(kill-all-local-variables)
|
1993-07-22 05:47:10 +00:00
|
|
|
|
(use-local-map completion-list-mode-map)
|
|
|
|
|
(setq mode-name "Completion List")
|
|
|
|
|
(setq major-mode 'completion-list-mode)
|
1994-08-07 18:11:58 +00:00
|
|
|
|
(make-local-variable 'completion-base-size)
|
|
|
|
|
(setq completion-base-size nil)
|
1993-07-22 05:47:10 +00:00
|
|
|
|
(run-hooks 'completion-list-mode-hook))
|
1993-07-13 21:34:05 +00:00
|
|
|
|
|
1995-04-08 22:42:47 +00:00
|
|
|
|
(defvar completion-fixup-function nil
|
|
|
|
|
"A function to customize how completions are identified in completion lists.
|
|
|
|
|
`completion-setup-function' calls this function with no arguments
|
|
|
|
|
each time it has found what it thinks is one completion.
|
|
|
|
|
Point is at the end of the completion in the completion list buffer.
|
|
|
|
|
If this function moves point, it can alter the end of that completion.")
|
|
|
|
|
|
|
|
|
|
;; This function goes in completion-setup-hook, so that it is called
|
|
|
|
|
;; after the text of the completion list buffer is written.
|
1994-07-11 21:25:19 +00:00
|
|
|
|
|
1993-07-13 21:34:05 +00:00
|
|
|
|
(defun completion-setup-function ()
|
|
|
|
|
(save-excursion
|
1995-04-08 22:42:47 +00:00
|
|
|
|
(let ((mainbuf (current-buffer)))
|
1994-03-02 23:09:40 +00:00
|
|
|
|
(set-buffer standard-output)
|
|
|
|
|
(completion-list-mode)
|
|
|
|
|
(make-local-variable 'completion-reference-buffer)
|
|
|
|
|
(setq completion-reference-buffer mainbuf)
|
1995-04-08 22:42:47 +00:00
|
|
|
|
;;; The value 0 is right in most cases, but not for file name completion.
|
|
|
|
|
;;; so this has to be turned off.
|
|
|
|
|
;;; (setq completion-base-size 0)
|
1994-03-02 23:09:40 +00:00
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(if window-system
|
|
|
|
|
(insert (substitute-command-keys
|
1994-03-27 22:21:04 +00:00
|
|
|
|
"Click \\[mouse-choose-completion] on a completion to select it.\n")))
|
|
|
|
|
(insert (substitute-command-keys
|
|
|
|
|
"In this buffer, type \\[choose-completion] to \
|
1994-04-05 02:29:03 +00:00
|
|
|
|
select the completion near point.\n\n"))
|
|
|
|
|
(forward-line 1)
|
1994-07-11 21:25:19 +00:00
|
|
|
|
(while (re-search-forward "[^ \t\n]+\\( [^ \t\n]+\\)*" nil t)
|
|
|
|
|
(let ((beg (match-beginning 0))
|
|
|
|
|
(end (point)))
|
|
|
|
|
(if completion-fixup-function
|
|
|
|
|
(funcall completion-fixup-function))
|
|
|
|
|
(put-text-property beg (point) 'mouse-face 'highlight)
|
|
|
|
|
(goto-char end))))))
|
1992-05-30 21:11:25 +00:00
|
|
|
|
|
1993-07-13 21:34:05 +00:00
|
|
|
|
(add-hook 'completion-setup-hook 'completion-setup-function)
|
1994-12-29 18:53:25 +00:00
|
|
|
|
|
|
|
|
|
(define-key minibuffer-local-completion-map [prior]
|
|
|
|
|
'switch-to-completions)
|
|
|
|
|
(define-key minibuffer-local-must-match-map [prior]
|
|
|
|
|
'switch-to-completions)
|
|
|
|
|
(define-key minibuffer-local-completion-map "\M-v"
|
|
|
|
|
'switch-to-completions)
|
|
|
|
|
(define-key minibuffer-local-must-match-map "\M-v"
|
|
|
|
|
'switch-to-completions)
|
|
|
|
|
|
|
|
|
|
(defun switch-to-completions ()
|
|
|
|
|
"Select the completion list window."
|
|
|
|
|
(interactive)
|
1995-07-07 13:26:23 +00:00
|
|
|
|
;; Make sure we have a completions window.
|
|
|
|
|
(or (get-buffer-window "*Completions*")
|
|
|
|
|
(minibuffer-completion-help))
|
1994-12-29 18:53:25 +00:00
|
|
|
|
(select-window (get-buffer-window "*Completions*"))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(search-forward "\n\n")
|
|
|
|
|
(forward-line 1))
|
1993-07-01 20:34:13 +00:00
|
|
|
|
|
1995-03-28 03:49:39 +00:00
|
|
|
|
;; Support keyboard commands to turn on various modifiers.
|
|
|
|
|
|
|
|
|
|
;; These functions -- which are not commands -- each add one modifier
|
|
|
|
|
;; to the following event.
|
|
|
|
|
|
|
|
|
|
(defun event-apply-alt-modifier (ignore-prompt)
|
|
|
|
|
(vector (event-apply-modifier (read-event) 'alt 22 "A-")))
|
|
|
|
|
(defun event-apply-super-modifier (ignore-prompt)
|
|
|
|
|
(vector (event-apply-modifier (read-event) 'super 23 "s-")))
|
|
|
|
|
(defun event-apply-hyper-modifier (ignore-prompt)
|
|
|
|
|
(vector (event-apply-modifier (read-event) 'hyper 24 "H-")))
|
|
|
|
|
(defun event-apply-shift-modifier (ignore-prompt)
|
|
|
|
|
(vector (event-apply-modifier (read-event) 'shift 25 "S-")))
|
|
|
|
|
(defun event-apply-control-modifier (ignore-prompt)
|
|
|
|
|
(vector (event-apply-modifier (read-event) 'control 26 "C-")))
|
|
|
|
|
(defun event-apply-meta-modifier (ignore-prompt)
|
|
|
|
|
(vector (event-apply-modifier (read-event) 'meta 27 "M-")))
|
|
|
|
|
|
|
|
|
|
(defun event-apply-modifier (event symbol lshiftby prefix)
|
|
|
|
|
"Apply a modifier flag to event EVENT.
|
|
|
|
|
SYMBOL is the name of this modifier, as a symbol.
|
|
|
|
|
LSHIFTBY is the numeric value of this modifier, in keyboard events.
|
|
|
|
|
PREFIX is the string that represents this modifier in an event type symbol."
|
|
|
|
|
(if (numberp event)
|
|
|
|
|
(cond ((eq symbol 'control)
|
1995-04-04 22:48:16 +00:00
|
|
|
|
(if (and (<= (downcase event) ?z)
|
|
|
|
|
(>= (downcase event) ?a))
|
1995-03-28 03:49:39 +00:00
|
|
|
|
(- (downcase event) ?a -1)
|
1995-04-04 22:48:16 +00:00
|
|
|
|
(if (and (<= (downcase event) ?Z)
|
|
|
|
|
(>= (downcase event) ?A))
|
1995-03-28 03:49:39 +00:00
|
|
|
|
(- (downcase event) ?A -1)
|
|
|
|
|
(logior (lsh 1 lshiftby) event))))
|
|
|
|
|
((eq symbol 'shift)
|
|
|
|
|
(if (and (<= (downcase event) ?z)
|
|
|
|
|
(>= (downcase event) ?a))
|
|
|
|
|
(upcase event)
|
|
|
|
|
(logior (lsh 1 lshiftby) event)))
|
|
|
|
|
(t
|
|
|
|
|
(logior (lsh 1 lshiftby) event)))
|
|
|
|
|
(if (memq symbol (event-modifiers event))
|
|
|
|
|
event
|
|
|
|
|
(let ((event-type (if (symbolp event) event (car event))))
|
|
|
|
|
(setq event-type (intern (concat prefix (symbol-name event-type))))
|
|
|
|
|
(if (symbolp event)
|
|
|
|
|
event-type
|
|
|
|
|
(cons event-type (cdr event)))))))
|
|
|
|
|
|
1995-04-05 03:34:40 +00:00
|
|
|
|
(define-key function-key-map [?\C-x ?@ ?h] 'event-apply-hyper-modifier)
|
|
|
|
|
(define-key function-key-map [?\C-x ?@ ?s] 'event-apply-super-modifier)
|
|
|
|
|
(define-key function-key-map [?\C-x ?@ ?m] 'event-apply-meta-modifier)
|
|
|
|
|
(define-key function-key-map [?\C-x ?@ ?a] 'event-apply-alt-modifier)
|
|
|
|
|
(define-key function-key-map [?\C-x ?@ ?S] 'event-apply-shift-modifier)
|
|
|
|
|
(define-key function-key-map [?\C-x ?@ ?c] 'event-apply-control-modifier)
|
1995-03-28 03:49:39 +00:00
|
|
|
|
|
1993-07-01 20:34:13 +00:00
|
|
|
|
;;;; Keypad support.
|
|
|
|
|
|
|
|
|
|
;;; Make the keypad keys act like ordinary typing keys. If people add
|
|
|
|
|
;;; bindings for the function key symbols, then those bindings will
|
|
|
|
|
;;; override these, so this shouldn't interfere with any existing
|
|
|
|
|
;;; bindings.
|
|
|
|
|
|
1993-12-25 00:45:07 +00:00
|
|
|
|
;; Also tell read-char how to handle these keys.
|
1993-07-01 20:34:13 +00:00
|
|
|
|
(mapcar
|
|
|
|
|
(lambda (keypad-normal)
|
|
|
|
|
(let ((keypad (nth 0 keypad-normal))
|
|
|
|
|
(normal (nth 1 keypad-normal)))
|
1993-12-25 00:45:07 +00:00
|
|
|
|
(put keypad 'ascii-character normal)
|
1993-07-01 20:34:13 +00:00
|
|
|
|
(define-key function-key-map (vector keypad) (vector normal))))
|
|
|
|
|
'((kp-0 ?0) (kp-1 ?1) (kp-2 ?2) (kp-3 ?3) (kp-4 ?4)
|
|
|
|
|
(kp-5 ?5) (kp-6 ?6) (kp-7 ?7) (kp-8 ?8) (kp-9 ?9)
|
|
|
|
|
(kp-space ?\ )
|
|
|
|
|
(kp-tab ?\t)
|
|
|
|
|
(kp-enter ?\r)
|
|
|
|
|
(kp-multiply ?*)
|
|
|
|
|
(kp-add ?+)
|
|
|
|
|
(kp-separator ?,)
|
|
|
|
|
(kp-subtract ?-)
|
|
|
|
|
(kp-decimal ?.)
|
|
|
|
|
(kp-divide ?/)
|
|
|
|
|
(kp-equal ?=)))
|
|
|
|
|
|
1992-05-30 21:11:25 +00:00
|
|
|
|
;;; simple.el ends here
|