(newline)
(indent-according-to-mode))
+;; 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)))
+
(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.
that uses or sets the mark."
(interactive)
(push-mark (point))
- (push-mark (point-max))
+ (push-mark (point-max) nil t)
(goto-char (point-min)))
(defun count-lines-region (start end)
- "Print number of lines and charcters in the region."
+ "Print number of lines and characters in the region."
(interactive "r")
(message "Region has %d lines, %d characters"
(count-lines start end) (- end start)))
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)
+ (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 "")
+ (setcar minibuffer-history-search-history
+ (nth 1 minibuffer-history-search-history))
+ regexp)
(prefix-numeric-value current-prefix-arg))))
(let ((history (symbol-value minibuffer-history-variable))
prevpos
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)
+ (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)
(prefix-numeric-value current-prefix-arg))))
(previous-matching-history-element regexp (- n)))
(forward-line (1- arg)))))
;Put this on C-x u, so we can force that rather than C-_ into startup msg
-(defalias 'advertised-undo 'undo)
+(define-function 'advertised-undo 'undo)
(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")
- (let ((modified (buffer-modified-p)))
+ (let ((modified (buffer-modified-p))
+ (recent-save (recent-auto-save-p)))
(or (eq (selected-window) (minibuffer-window))
(message "Undo!"))
(or (eq last-command 'undo)
(setq this-command 'undo)
(undo-more (or arg 1))
(and modified (not (buffer-modified-p))
- (delete-auto-save-file-if-necessary))))
+ (delete-auto-save-file-if-necessary recent-save))))
+
+(defvar pending-undo-list nil
+ "Within a run of consecutive undo commands, list remaining to be undone.")
(defun undo-start ()
"Set `pending-undo-list' to the front of the undo list.
;; aliases for shell commands then they can still have them.
(call-process shell-file-name nil t nil
"-c" command)
- (exchange-point-and-mark))
+ ;; 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.
(let ((data (match-data)))
(unwind-protect
(skip-chars-forward " \t"))
(defvar kill-whole-line nil
- "*If non-nil, kill-line kills the whole line (including the newline)
- if point is positioned at the beginning of a line.")
+ "*If non-nil, `kill-line' with no arg at beg of line kills the whole line.")
(defun kill-line (&optional arg)
- "Kill the rest of the current line; if the line is blank, or if point is at
-the beginning of the line and kill-whole-line is non-nil, kill thru newline.
+ "Kill the rest of the current line; if no nonblanks there, kill thru newline.
With prefix argument, kill that many lines from point.
Negative arguments kill lines backward.
When calling from a program, nil means \"no arg\",
-a number counts as a prefix arg."
+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."
(interactive "P")
(kill-region (point)
;; Don't shift point before doing the delete; that way,
"Function to call to make a killed region available to other programs.
Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs. On startup,
-this variable is set to a function which emacs will call whenever text
-is put in the kill ring to make the new kill available to other
+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
programs.
-The function takes one argument, TEXT, which is a string containing
-the text which should be made available.")
+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.")
(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
-pasting text between the windows of different programs. On startup,
-this variable is set to a function which emacs will call to obtain
+pasting text between the windows of different programs.
+This variable holds a function that Emacs calls to obtain
text that other programs have provided for pasting.
The function should be called with no arguments. If the function
(setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
(setq kill-ring-yank-pointer kill-ring)
(if interprogram-cut-function
- (funcall interprogram-cut-function string)))
+ (funcall interprogram-cut-function string t)))
(defun kill-append (string before-p)
"Append STRING to the end of the latest kill in the kill ring.
(eq last-command 'kill-region)
(eq beg end)))
;; Don't let the undo list be truncated before we can even access it.
- (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100)))
+ (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100))
+ (old-list buffer-undo-list)
+ tail)
(delete-region beg end)
+ ;; 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)))
;; Take the same string recorded for undo
;; and put it in the kill-ring.
- (kill-new (car (car buffer-undo-list)))
+ (kill-new (car (car tail)))
(setq this-command 'kill-region)))
(t
(defun kill-ring-save (beg end)
"Save the region as if killed, but don't kill it.
-This command is similar to copy-region-as-kill, except that it gives
+This command is similar to `copy-region-as-kill', except that it gives
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."
(interactive "r")
(copy-region-as-kill beg end)
(if (interactive-p)
- (save-excursion
- (let ((other-end (if (= (point) beg) end beg)))
- (if (pos-visible-in-window-p other-end (selected-window))
- (progn
- (goto-char other-end)
- (sit-for 1))
- (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)))))))))
+ (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.
+ (and quit-flag mark-active
+ (progn
+ (message "foo") ;XXX what is this here for? --roland
+ (deactivate-mark))))
+ (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))))))))
(defun append-next-kill ()
"Cause following command, if it kills, to append to previous kill."
(if (not (eq last-command 'yank))
(error "Previous command was not a yank"))
(setq this-command 'yank)
- (let ((before (< (point) (mark))))
- (delete-region (point) (mark))
- (set-mark (point))
+ (let ((before (< (point) (mark t))))
+ (delete-region (point) (mark t))
+ (set-marker (mark-marker) (point) (current-buffer))
(insert (current-kill arg))
- (if before (exchange-point-and-mark)))
+ (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))))))
nil)
(defun yank (&optional arg)
((eq arg '-) -1)
(t (1- arg)))))
(if (consp arg)
- (exchange-point-and-mark))
+ ;; 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)))))
nil)
(defun rotate-yank-pointer (arg)
BUFFER (or buffer name), START and END.
START and END specify the portion of the current buffer to be copied."
(interactive
- (list (read-buffer "Append to buffer: " (other-buffer nil t) t)))
+ (list (read-buffer "Append to buffer: " (other-buffer nil t))
+ (region-beginning) (region-end)))
(let ((oldbuf (current-buffer)))
(save-excursion
(set-buffer (get-buffer-create buffer))
(save-excursion
(insert-buffer-substring oldbuf start end)))))
\f
+(defvar mark-even-if-inactive nil
+ "*Non-nil means you can use the mark even when inactive.
+This option makes a difference in Transient Mark mode.
+When the option is non-nil, deactivation of the mark
+turns off region highlighting, but commands that use the mark
+behave as if the mark were still active.")
+
+(put 'mark-inactive 'error-conditions '(mark-inactive error))
+(put 'mark-inactive 'error-message "The mark is not active now")
+
(defun mark (&optional force)
- "Return this buffer's mark value as integer, or nil if no active mark now.
+ "Return this buffer's mark value as integer; error if mark inactive.
If optional argument FORCE is non-nil, access the mark value
-even if the mark is not currently active.
+even if the mark is not currently active, and return nil
+if there is no mark at all.
If you are using this in an editing command, you are most likely making
a mistake; see the documentation of `set-mark'."
- (if (or force mark-active)
+ (if (or force mark-active mark-even-if-inactive)
(marker-position (mark-marker))
- (error "The mark is not currently active")))
+ (signal 'mark-inactive nil)))
+
+;; 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.
+Also runs the hook `deactivate-mark-hook'."
+ (setq mark-active nil)
+ (run-hooks 'deactivate-mark-hook))
(defun set-mark (pos)
"Set this buffer's mark to POS. Don't use this function!
purposes. See the documentation of `set-mark' for more information."
(interactive "P")
(if (null arg)
- (push-mark)
+ (progn
+ (push-mark nil nil t))
(if (null (mark t))
(error "No mark set in this buffer")
- (goto-char (mark))
+ (goto-char (mark t))
(pop-mark))))
-(defun push-mark (&optional location nomsg)
+(defun push-mark (&optional location nomsg activate)
"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.
+Display `Mark set' unless the optional second arg NOMSG is non-nil.
+In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil.
Novice Emacs Lisp programmers often try to use the mark for the wrong
-purposes. See the documentation of `set-mark' for more information."
+purposes. See the documentation of `set-mark' for more information.
+
+In Transient Mark mode, this does not activate the mark."
(if (null (mark t))
nil
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
(progn
(move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
(setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
- (set-mark (or location (point)))
+ (set-marker (mark-marker) (or location (point)) (current-buffer))
(or nomsg executing-macro (> (minibuffer-depth) 0)
(message "Mark set"))
+ (if (or activate (not transient-mark-mode))
+ (set-mark (mark t)))
nil)
(defun pop-mark ()
(if mark-ring
(progn
(setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
- (set-mark (+ 0 (car mark-ring)))
+ (set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))
+ (deactivate-mark)
(move-marker (car mark-ring) nil)
- (if (null (mark)) (ding))
+ (if (null (mark t)) (ding))
(setq mark-ring (cdr mark-ring)))))
-(defalias 'exchange-dot-and-mark 'exchange-point-and-mark)
+(define-function 'exchange-dot-and-mark 'exchange-point-and-mark)
(defun exchange-point-and-mark ()
"Put the mark where point is now, and point where the mark is now.
This command works even when the mark is not active,
(set-mark (point))
(goto-char omark)
nil))
+
+(defun transient-mark-mode (arg)
+ "Toggle Transient Mark mode.
+With arg, turn Transient Mark mode on if arg is positive, off otherwise.
+
+In Transient Mark mode, changing the buffer \"deactivates\" the mark.
+While the mark is active, the region is highlighted."
+ (interactive "P")
+ (setq transient-mark-mode
+ (if (null arg)
+ (not transient-mark-mode)
+ (> (prefix-numeric-value arg) 0))))
\f
(defvar next-line-add-newlines t
- "*If non-nil, next-line will insert a newline into the buffer
- when invoked with no newline character between the point and the end
- of the buffer.")
+ "*If non-nil, `next-line' inserts newline to avoid `end of buffer' error.")
(defun next-line (arg)
"Move cursor vertically down ARG lines.
(defun hscroll-point-visible ()
"Scrolls the window horizontally to make point visible."
- (let* ((min (window-hscroll))
- (max (- (+ min (window-width)) 2))
- (here (current-column))
- (delta (if (zerop hscroll-step) (/ (window-width) 2) hscroll-step))
- )
- (if (< here min)
- (scroll-right (max 0 (+ (- min here) delta)))
- (if (>= here max)
- (scroll-left (- (- here min) delta))
- ))))
+ (let* ((here (current-column))
+ (left (window-hscroll))
+ (right (- (+ left (window-width)) 3)))
+ (cond
+ ;; Should we recenter?
+ ((or (< here (- left hscroll-step))
+ (> here (+ right hscroll-step)))
+ (set-window-hscroll
+ (selected-window)
+ ;; Recenter, but don't show too much white space off the end of
+ ;; the line.
+ (max 0
+ (min (- (save-excursion (end-of-line) (current-column))
+ (window-width)
+ -5)
+ (- here (/ (window-width) 2))))))
+ ;; Should we scroll left?
+ ((> here right)
+ (scroll-left hscroll-step))
+ ;; Or right?
+ ((< here left)
+ (scroll-right hscroll-step)))))
-;;; 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))
-
-(defun down-arrow (arg)
- "Move down one line on the screen (with prefix ARG, that many lines).
-If doing so would add lines to the end of the buffer, raise an error."
- (interactive "P")
- (let ((next-line-add-newlines nil))
- (next-line 1)))
-
-(defalias 'up-arrow 'previous-line)
+;; 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))
\f
(defun transpose-chars (arg)
"Interchange characters around point, moving forward one character.
(push-mark
(save-excursion
(forward-word arg)
- (point))))
+ (point))
+ nil t))
(defun kill-word (arg)
"Kill characters forward until encountering the end of a word.
(defvar blink-matching-paren t
"*Non-nil means show matching open-paren when close-paren is inserted.")
-(defconst blink-matching-paren-distance 4000
- "*If non-nil, is maximum distance to search for matching open-paren
-when close-paren is inserted.")
+(defconst blink-matching-paren-distance 12000
+ "*If non-nil, is maximum distance to search for matching open-paren.")
(defun blink-matching-open ()
"Move cursor momentarily to the beginning of the sexp before point."
;Turned off because it makes dbx bomb out.
(setq blink-paren-function 'blink-matching-open)
-; this is just something for the luser to see in a keymap -- this is not
-; how quitting works normally!
+;; 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.
(defun keyboard-quit ()
"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."
(interactive)
+ (deactivate-mark)
(signal 'quit nil))
(define-key global-map "\C-g" 'keyboard-quit)
(eval-minibuffer (format "Set %s to value: " var)))))))
(set var val))
+\f
+;;;; 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.
+
+(mapcar
+ (lambda (keypad-normal)
+ (let ((keypad (nth 0 keypad-normal))
+ (normal (nth 1 keypad-normal)))
+ (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 ?=)))
+
;;; simple.el ends here