;;; simple.el --- basic editing commands for Emacs
-;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;;; Code:
(defun open-line (arg)
- "Insert a newline and leave point before it. If there is a fill
-prefix, inserts the fill prefix after the newline that it inserts.
-With arg, inserts that many newlines."
+ "Insert a newline and leave point before it.
+If there is a fill prefix, insert the fill prefix on the new line
+if the line would have been empty.
+With arg N, insert N newlines."
(interactive "*p")
- (let ((flag (and (bolp) (not (bobp)))))
- (if flag (forward-char -1))
+ (let* ((do-fill-prefix (and fill-prefix (bolp)))
+ (flag (and (null do-fill-prefix) (bolp) (not (bobp)))))
+ ;; If this is a simple case, and we are at the beginning of a line,
+ ;; actually insert the newline *before* the preceding newline
+ ;; instead of after. That makes better display behavior.
+ (if flag
+ (progn
+ ;; If undo is enabled, don't let this hack be visible:
+ ;; record the real value of point as the place to move back to
+ ;; if we undo this insert.
+ (if (and buffer-undo-list (not (eq buffer-undo-list t)))
+ (setq buffer-undo-list (cons (point) buffer-undo-list)))
+ (forward-char -1)))
(while (> arg 0)
(save-excursion
- (insert ?\n)
- (if fill-prefix (insert fill-prefix)))
+ (insert ?\n))
+ (if do-fill-prefix (insert fill-prefix))
(setq arg (1- arg)))
(if flag (forward-char 1))))
(defun quoted-insert (arg)
"Read next input character and insert it.
-Useful for inserting control characters.
-You may also type up to 3 octal digits, to insert a character with that code"
+This is useful for inserting control characters.
+You may also type up to 3 octal digits, to insert a character with that code.
+`quoted-insert' inserts the character even in overstrike mode; if you
+use overstrike as your normal editing mode, you can use this function
+to insert characters when necessary."
(interactive "*p")
(let ((char (read-quoted-char)))
(while (> arg 0)
;; If the second line started with the fill prefix,
;; delete the prefix.
(if (and fill-prefix
+ (<= (+ (point) (length fill-prefix)) (point-max))
(string= fill-prefix
(buffer-substring (point)
(+ (point) (length fill-prefix)))))
(defun newline-and-indent ()
"Insert a newline, then indent according to major mode.
-Indentation is done using the current indent-line-function.
+Indentation is done using the value of `indent-line-function'.
In programming language modes, this is the same as TAB.
-In some text modes, where TAB inserts a tab, this indents to the
-specified left-margin column."
+In some text modes, where TAB inserts a tab, this command indents to the
+column specified by the variable `left-margin'."
(interactive "*")
(delete-region (point) (progn (skip-chars-backward " \t") (point)))
(newline)
(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,
-which means that the current value of indent-line-function is called.
+which means calling the current value of `indent-line-function'.
In programming language modes, this is the same as TAB.
In some text modes, where TAB inserts a tab, this indents to the
-specified left-margin column."
+column specified by the variable `left-margin'."
(interactive "*")
(save-excursion
(delete-region (point) (progn (skip-chars-backward " \t") (point)))
(defun beginning-of-buffer (&optional arg)
"Move point to the beginning of the buffer; leave mark at previous position.
With arg N, put point N/10 of the way from the true beginning.
-Don't use this in Lisp programs!
+
+Don't use this command in Lisp programs!
\(goto-char (point-min)) is faster and avoids clobbering the mark."
(interactive "P")
(push-mark)
(defun end-of-buffer (&optional arg)
"Move point to the end of the buffer; leave mark at previous position.
With arg N, put point N/10 of the way from the true end.
-Don't use this in Lisp programs!
+
+Don't use this command in Lisp programs!
\(goto-char (point-max)) is faster and avoids clobbering the mark."
(interactive "P")
(push-mark)
(defun count-lines (start end)
"Return number of lines between START and END.
This is usually the number of newlines between them,
-but will be one more if START is not equal to END
+but can be one more if START is not equal to END
and the greater of them is not at the start of a line."
(save-excursion
(save-restriction
(interactive)
(kill-all-local-variables))
+(defvar read-expression-map (copy-keymap minibuffer-local-map)
+ "Minibuffer keymap used for reading Lisp expressions.")
+(define-key read-expression-map "\M-\t" 'lisp-complete-symbol)
+
(put 'eval-expression 'disabled t)
;; We define this, rather than making eval interactive,
;; for the sake of completion of names like eval-region, eval-current-buffer.
(defun eval-expression (expression)
"Evaluate EXPRESSION and print value in minibuffer.
-Value is also consed on to front of variable values 's value."
- (interactive "xEval: ")
+Value is also consed on to front of the variable `values'."
+ (interactive (list (read-from-minibuffer "Eval: "
+ nil read-expression-map t)))
(setq values (cons (eval expression) values))
(prin1 (car values) t))
"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."
- (let ((command (read-minibuffer prompt
- (prin1-to-string command))))
+ (let ((command (read-from-minibuffer prompt
+ (prin1-to-string command)
+ read-expression-map t)))
;; Add edited command to command history, unless redundant.
(or (equal command (car command-history))
(setq command-history (cons command command-history)))
(minibuffer-history-sexp-flag t)
newcmd)
(if elt
- (let ((minibuffer-history-variable ' command-history))
+ (progn
(setq newcmd (read-from-minibuffer "Redo: "
(prin1-to-string elt)
- minibuffer-local-map
+ read-expression-map
t
(cons 'command-history
arg)))
+ ;; If command was added to command-history as a string,
+ ;; get rid of that. We want only evallable expressions there.
+ (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))
(eval newcmd))
(ding))))
\f
-(defvar minibuffer-history nil)
-(defvar minibuffer-history-sexp-flag nil)
+(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
+ "Nonzero when doing history operations on `command-history'.
+More generally, indicates that the history list being acted on
+contains expressions rather than strings.")
(setq minibuffer-history-variable 'minibuffer-history)
(setq minibuffer-history-position nil)
+(defvar minibuffer-history-search-history nil)
(mapcar
- (function (lambda (key-and-command)
- (mapcar
- (function (lambda (keymap)
- (define-key (symbol-value keymap)
- (car key-and-command)
- (cdr key-and-command))))
- '(minibuffer-local-map
- minibuffer-local-ns-map
- minibuffer-local-completion-map
- minibuffer-local-must-match-map))))
- '(("\en" . next-history-element) ([next] . next-history-element)
- ("\ep" . previous-history-element) ([prior] . previous-history-element)
+ (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)
+ (if (cdr keymap-and-completionp)
+ (cdr command)
+ (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))))
+ ;; In completion maps, use the completion-oriented history commands.
+ '(("\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))
("\er" . previous-matching-history-element)
("\es" . next-matching-history-element)))
-(put 'previous-matching-history-element 'enable-recursive-minibuffers t)
(defun previous-matching-history-element (regexp n)
- (interactive "sPrevious element matching (regexp): \np")
+ "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
+ (let ((enable-recursive-minibuffers t)
+ (minibuffer-history-sexp-flag nil))
+ (list (read-from-minibuffer "Previous element matching (regexp): "
+ nil
+ minibuffer-local-map
+ nil
+ 'minibuffer-history-search-history)
+ (prefix-numeric-value current-prefix-arg))))
(let ((history (symbol-value minibuffer-history-variable))
prevpos
(pos minibuffer-history-position))
(if minibuffer-history-sexp-flag
(prin1-to-string (nth (1- pos) history))
(nth (1- pos) history)))
- (setq n (+ n (if (< n 0) -1 1)))))
+ (setq n (+ n (if (< n 0) 1 -1)))))
(setq minibuffer-history-position pos)
(erase-buffer)
(let ((elt (nth (1- pos) history)))
(insert (if minibuffer-history-sexp-flag
(prin1-to-string elt)
elt)))
- (goto-char (point-min))))
+ (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))))
-(put 'next-matching-history-element 'enable-recursive-minibuffers t)
(defun next-matching-history-element (regexp n)
- (interactive "sNext element matching (regexp): \np")
+ "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
+ (let ((enable-recursive-minibuffers t)
+ (minibuffer-history-sexp-flag nil))
+ (list (read-from-minibuffer "Next element matching (regexp): "
+ nil
+ minibuffer-local-map
+ nil
+ 'minibuffer-history-search-history)
+ (prefix-numeric-value current-prefix-arg))))
(previous-matching-history-element regexp (- n)))
(defun next-history-element (n)
(goto-char (point-min)))))
(defun previous-history-element (n)
- "Inserts the previous element of `command-history' into the minibuffer."
+ "Inserts the previous element of the minibuffer history into the minibuffer."
(interactive "p")
(next-history-element (- n)))
+
+(defun next-complete-history-element (n)
+ "\
+Get previous element of history which is a completion of minibuffer contents."
+ (interactive "p")
+ (next-matching-history-element
+ (concat "^" (regexp-quote (buffer-substring (point-min) (point)))) n))
+
+(defun previous-complete-history-element (n)
+ "Get next element of history which is a completion of minibuffer contents."
+ (interactive "p")
+ (next-complete-history-element (- n)))
\f
(defun goto-line (arg)
"Goto line ARG, counting from line 1 at beginning of buffer."
(delete-auto-save-file-if-necessary))))
(defun undo-start ()
- "Move pending-undo-list to front of undo records.
-The next call to undo-more will undo the most recently made change."
+ "Set `pending-undo-list' to the front of the undo list.
+The next call to `undo-more' will undo the most recently made change."
(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.
-Call undo-start to get ready to undo recent changes,
-then call undo-more one or more times to undo them."
+Call `undo-start' to get ready to undo recent changes,
+then call `undo-more' one or more times to undo them."
(or pending-undo-list
(error "No further undo information"))
(setq pending-undo-list (primitive-undo count pending-undo-list)))
even though that buffer is not automatically displayed. If there is no output
or output is inserted in the current buffer then `*Shell Command Output*' is
deleted."
- (interactive (list (min (point) (mark)) (max (point) (mark))
+ (interactive (list (region-beginning) (region-end)
(read-string "Shell command on region: "
last-shell-command-on-region)
current-prefix-arg
(setq sign (- sign) factor nil)
;; (describe-arg value sign)
(setq key (read-key-sequence nil t)))
- (while (and (= (length key) 1)
+ (while (and (stringp key)
+ (= (length key) 1)
(not (string< key "0"))
(not (string< "9" key)))
(setq value (+ (* (if (numberp value) value 0) 10)
(progn
(describe-arg value sign)
(setq key (read-key-sequence nil t))))
- (if (= (length key) 1)
- ;; Make sure self-insert-command finds the proper character;
- ;; unread the character and let the command loop process it.
- (setq unread-command-char (string-to-char key))
- ;; We can't push back a longer string, so we'll emulate the
- ;; command loop ourselves.
- (command-execute (key-binding key)))))
+ (setq unread-command-events (append key '()))))
(defun describe-arg (value sign)
(cond ((numberp value)
a number counts as a prefix arg."
(interactive "P")
(kill-region (point)
- (progn
+ ;; Don't shift point before doing the delete; that way,
+ ;; undo will record the right position of point.
+ (save-excursion
(if arg
(forward-line (prefix-numeric-value arg))
(if (eobp)
(defun kill-append (string before-p)
"Append STRING to the end of the latest kill in the kill ring.
If BEFORE-P is non-nil, prepend STRING to the kill.
-If 'interprogram-cut-function' is set, pass the resulting kill to
+If `interprogram-cut-function' is set, pass the resulting kill to
it."
(setcar kill-ring
(if before-p
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."
- (interactive "r")
+ (interactive "*r")
(cond
- (buffer-read-only
- (copy-region-as-kill beg end))
+ ;; If the buffer was read-only, we used to just do a
+ ;; copy-region-as-kill. This was never what I wanted - usually I
+ ;; was making a mistake and trying to edit a file checked into RCS -
+ ;; so I've taken the code out.
((not (or (eq buffer-undo-list t)
(eq last-command 'kill-region)
(eq beg end)))
(substring killed-text 0 message-len)))))))))
(defun append-next-kill ()
- "Cause following command, if kill, to append to previous kill."
+ "Cause following command, if it kills, to append to previous kill."
(interactive)
(if (interactive-p)
(progn
(setq last-command 'kill-region)))
(defun yank-pop (arg)
- "Replace just-yanked stretch of killed-text with a different stretch.
-This command is allowed only immediately after a yank or a yank-pop.
+ "Replace just-yanked stretch of killed text with a different stretch.
+This command is allowed only immediately after a `yank' or a `yank-pop'.
At such a time, the region contains a stretch of reinserted
-previously-killed text. yank-pop deletes that text and inserts in its
+previously-killed text. `yank-pop' deletes that text and inserts in its
place a different stretch of killed text.
With no argument, the previous kill is inserted.
-With argument n, the n'th previous kill is inserted.
-If n is negative, this is a more recent kill.
+With argument N, insert the Nth previous kill.
+If N is negative, this is a more recent kill.
The sequence of kills wraps around, so that after the oldest one
comes the newest one."
(defun yank (&optional arg)
"Reinsert the last stretch of killed text.
More precisely, reinsert the stretch of killed text most recently
-killed OR yanked.
-With just C-U as argument, same but put point in front (and mark at end).
-With argument n, reinsert the nth most recently killed stretch of killed
+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
text.
See also the command \\[yank-pop]."
(interactive "*P")
"Insert after point the contents of BUFFER.
Puts mark after the inserted text.
BUFFER may be a buffer or a buffer name."
- (interactive (list (read-buffer "Insert buffer: " (other-buffer) t)))
+ (interactive (list (progn (barf-if-buffer-read-only)
+ (read-buffer "Insert buffer: " (other-buffer) t))))
(or (bufferp buffer)
(setq buffer (get-buffer buffer)))
(let (start end newmark)
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.
-Novice emacs-lisp programmers often try to use the mark for the wrong
+Novice Emacs Lisp programmers often try to use the mark for the wrong
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,
(defun set-mark-command (arg)
"Set mark at where point is, or jump to mark.
-With no prefix argument, set mark, and push previous mark on mark ring.
-With argument, jump to mark, and pop into mark off the mark ring.
+With no prefix argument, set mark, and push old mark position on mark ring.
+With argument, jump to mark, and pop a new position for mark off the ring.
-Novice emacs-lisp programmers often try to use the mark for the wrong
+Novice Emacs Lisp programmers often try to use the mark for the wrong
purposes. See the documentation of `set-mark' for more information."
(interactive "P")
(if (null arg)
"Set mark at LOCATION (point, by default) and push old mark on mark ring.
Displays \"Mark set\" unless the optional second arg NOMSG is non-nil.
-Novice emacs-lisp programmers often try to use the mark for the wrong
+Novice Emacs Lisp programmers often try to use the mark for the wrong
purposes. See the documentation of `set-mark' for more information."
(if (null (mark))
nil
Then it does not try to move vertically.
If you are thinking of using this in a Lisp program, consider using
-`forward-line' with negative argument instead.. It is usually easier
+`forward-line' with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.)."
(interactive "p")
(line-move (- arg))
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.")
-(make-variable-buffer-local
- (defvar goal-column nil
- "*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil."))
+(defvar goal-column nil
+ "*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil.")
+(make-variable-buffer-local 'goal-column)
(defvar temporary-goal-column 0
"Current goal column for vertical motion.
(move-to-column (or goal-column temporary-goal-column))
nil)
+;;; 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)
(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
-so that \\[next-line] and \\[previous-line] resume vertical motion."
+so that \\[next-line] and \\[previous-line] resume vertical motion.
+The goal column is stored in the variable `goal-column'."
(interactive "P")
(if arg
(progn
\f
(defconst comment-column 32
"*Column to indent right-margin comments to.
-Setting this variable automatically makes it local to the current buffer.")
+Setting this variable automatically makes it local to the current buffer.
+Each mode establishes a different default value for this variable; you
+can the value for a particular mode using that mode's hook.")
(make-variable-buffer-local 'comment-column)
(defconst comment-start nil
(skip-chars-backward " \t")
(backward-char (length ce))
(if (looking-at (regexp-quote ce))
- (delete-char (length ce))))))
+ (delete-char (length ce)))))
+ (forward-line 1))
(if (looking-at "[ \t]*$") ()
(insert cs)
(if (string= "" ce) ()
(defun backward-word (arg)
"Move backward until encountering the end of a word.
With argument, do this that many times.
-In programs, it is faster to call forward-word with negative arg."
+In programs, it is faster to call `forward-word' with negative arg."
(interactive "p")
(forward-word (- arg)))
"Kill characters forward until encountering the end of a word.
With argument, do this that many times."
(interactive "p")
- (kill-region (point) (progn (forward-word arg) (point))))
+ (kill-region (point) (save-excursion (forward-word arg) (point))))
(defun backward-kill-word (arg)
"Kill characters backward until encountering the end of a word.
(auto-fill-mode 1))
(defun set-fill-column (arg)
- "Set fill-column to current column, or to argument if given.
-fill-column's value is separate for each buffer."
+ "Set `fill-column' to current column, or to argument if given.
+The variable `fill-column' has a separate value for each buffer."
(interactive "P")
(setq fill-column (if (integerp arg) arg (current-column)))
(message "fill-column set to %d" fill-column))
\f
(defun set-selective-display (arg)
- "Set selective-display to ARG; clear it if no arg.
-When selective-display is a number > 0,
-lines whose indentation is >= selective-display are not displayed.
-selective-display's value is separate for each buffer."
+ "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."
(interactive "P")
(if (eq selective-display t)
(error "selective-display already in use for marked lines"))