;;; simple.el --- basic editing commands for Emacs
;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: internal
;; 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
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
buffer list instead of the selected frame's buffer list.
If no other buffer exists, the buffer `*scratch*' is returned."
(setq frame (or frame (selected-frame)))
- (or (get-next-valid-buffer (frame-parameter frame 'buried-buffer-list)
- buffer visible-ok frame)
- (get-next-valid-buffer (nreverse (buffer-list frame))
- buffer visible-ok frame)
+ (or (get-next-valid-buffer (nreverse (buffer-list frame))
+ buffer visible-ok frame)
(progn
(set-buffer-major-mode (get-buffer-create "*scratch*"))
(get-buffer "*scratch*"))))
-
(defun next-buffer ()
"Switch to the next buffer in cyclic order."
(interactive)
- (let ((buffer (current-buffer))
- (bbl (frame-parameter nil 'buried-buffer-list)))
+ (let ((buffer (current-buffer)))
(switch-to-buffer (other-buffer buffer t))
- (bury-buffer buffer)
- (set-frame-parameter nil 'buried-buffer-list
- (cons buffer (delq buffer bbl)))))
+ (bury-buffer buffer)))
(defun previous-buffer ()
"Switch to the previous buffer in cyclic order."
(interactive)
- (let ((buffer (last-buffer (current-buffer) t))
- (bbl (frame-parameter nil 'buried-buffer-list)))
- (switch-to-buffer buffer)
- ;; Clean up buried-buffer-list up to and including the chosen buffer.
- (while (and bbl (not (eq (car bbl) buffer)))
- (setq bbl (cdr bbl)))
- (set-frame-parameter nil 'buried-buffer-list bbl)))
+ (switch-to-buffer (last-buffer (current-buffer) t)))
\f
;;; next-error support framework
;; Mark the newline(s) `hard'.
(if use-hard-newlines
(set-hard-newline-properties
- (- (point) (if arg (prefix-numeric-value arg) 1)) (point)))
+ (- (point) (prefix-numeric-value arg)) (point)))
;; If the newline leaves the previous line blank,
;; and we have a left margin, delete that from the blank line.
(or flag
(newline)
(save-excursion
(goto-char pos)
+ ;; We are at EOL before the call to indent-according-to-mode, and
+ ;; after it we usually are as well, but not always. We tried to
+ ;; address it with `save-excursion' but that uses a normal marker
+ ;; whereas we need `move after insertion', so we do the save/restore
+ ;; by hand.
+ (setq pos (copy-marker pos t))
(indent-according-to-mode)
+ (goto-char pos)
+ ;; Remove the trailing white-space after indentation because
+ ;; indentation may introduce the whitespace.
(delete-horizontal-space t))
(indent-according-to-mode)))
(if (boundp 'edebug-active) edebug-active)))
(let ((char-string
(if (or (if (boundp 'edebug-active) edebug-active)
- (memq this-command '(eval-last-sexp eval-print-last-sexp)))
+ (memq this-command '(eval-last-sexp eval-print-last-sexp)))
(prin1-char value))))
(if char-string
(format " (#o%o, #x%x, %s)" value value char-string)
"Puts element of the minibuffer history in the minibuffer.
The argument NABS specifies the absolute history position."
(interactive "p")
- (let ((minimum (if minibuffer-default -1 0))
+ (let ((minimum (if minibuffer-default
+ (- (if (listp minibuffer-default)
+ (length minibuffer-default)
+ 1))
+ 0))
elt minibuffer-returned-to-present)
(if (and (zerop minibuffer-history-position)
(null minibuffer-text-before-history))
(goto-char (point-max))
(delete-minibuffer-contents)
(setq minibuffer-history-position nabs)
- (cond ((= nabs -1)
- (setq elt minibuffer-default))
+ (cond ((< nabs 0)
+ (setq elt (if (listp minibuffer-default)
+ (nth (1- (abs nabs)) minibuffer-default)
+ minibuffer-default)))
((= nabs 0)
(setq elt (or minibuffer-text-before-history ""))
(setq minibuffer-returned-to-present t)
string, then the caller of the function \(usually `current-kill')
should put this string in the kill ring as the latest kill.
+This function may also return a list of strings if the window
+system supports multiple selections. The first string will be
+used as the pasted text, but the other will be placed in the
+kill ring for easy access via `yank-pop'.
+
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
(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."
+If N is zero, `interprogram-paste-function' is set, and calling it returns a
+string or list of strings, then that string (or list) is added to the front
+of the kill ring and the string (or first string in the list) is 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))))
;; 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)
+ (if (listp interprogram-paste)
+ (mapc 'kill-new (nreverse interprogram-paste))
+ (kill-new interprogram-paste)))
+ (car kill-ring))
(or kill-ring (error "Kill ring is empty"))
(let ((ARGth-kill-element
(nthcdr (mod (- n (length kill-ring-yank-pointer))
"Save the region as if killed, but don't kill it.
In Transient Mark mode, deactivate the mark.
If `interprogram-cut-function' is non-nil, also save the text for a window
-system cut and paste."
+system cut and paste.
+
+This command's old key binding has been given to `kill-ring-save'."
(interactive "r")
(if (eq last-command 'kill-region)
(kill-append (filter-buffer-substring beg end) (< end beg))
(defcustom yank-excluded-properties
'(read-only invisible intangible field mouse-face help-echo local-map keymap
yank-handler follow-link fontified)
- "*Text properties to discard when yanking.
+ "Text properties to discard when yanking.
The value should be a list of text properties to discard or t,
which means to discard all text properties."
:type '(choice (const :tag "All" t) (repeat symbol))
"Current goal column for vertical motion.
It is the column where point was
at the start of current run of vertical motion commands.
-When the `track-eol' feature is doing its job, the value is 9999.")
+When the `track-eol' feature is doing its job, the value is `most-positive-fixnum'.")
(defcustom line-move-ignore-invisible t
"*Non-nil means \\[next-line] and \\[previous-line] ignore invisible lines.
:type 'boolean
:group 'editing-basics)
-(defun line-move-invisible-p (pos)
- "Return non-nil if the character after POS is currently invisible."
- (let ((prop
- (get-char-property pos 'invisible)))
- (if (eq buffer-invisibility-spec t)
- prop
- (or (memq prop buffer-invisibility-spec)
- (assq prop buffer-invisibility-spec)))))
-
;; Returns non-nil if partial move was done.
(defun line-move-partial (arg noerror to-end)
(if (< arg 0)
(vpos (nth 1 lh))
(ypos (nth 2 lh))
(rbot (nth 3 lh))
- ppos py vs)
+ py vs)
(when (or (null lh)
(>= rbot (frame-char-height))
(<= ypos (- (frame-char-height))))
;; 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 'move-end-of-line)))
- 9999
+ most-positive-fixnum
(current-column))))
- (if (and (not (integerp selective-display))
- (not line-move-ignore-invisible))
+ (if (not (or (integerp selective-display)
+ line-move-ignore-invisible))
;; Use just newline characters.
;; Set ARG to 0 if we move as many lines as requested.
(or (if (> arg 0)
(while (and (> arg 0) (not done))
;; If the following character is currently invisible,
;; skip all characters with that same `invisible' property value.
- (while (and (not (eobp)) (line-move-invisible-p (point)))
+ (while (and (not (eobp)) (invisible-p (point)))
(goto-char (next-char-property-change (point))))
;; Move a line.
;; We don't use `end-of-line', since we want to escape
(setq done t)))
((and (> arg 1) ;; Use vertical-motion for last move
(not (integerp selective-display))
- (not (line-move-invisible-p (point))))
+ (not (invisible-p (point))))
;; We avoid vertical-motion when possible
;; because that has to fontify.
(forward-line 1))
(setq done t)))
((and (< arg -1) ;; Use vertical-motion for last move
(not (integerp selective-display))
- (not (line-move-invisible-p (1- (point)))))
+ (not (invisible-p (1- (point)))))
(forward-line -1))
((zerop (vertical-motion -1))
(if (not noerror)
;; if our target is the middle of this line.
(or (zerop (or goal-column temporary-goal-column))
(< arg 0))
- (not (bobp)) (line-move-invisible-p (1- (point))))
+ (not (bobp)) (invisible-p (1- (point))))
(goto-char (previous-char-property-change (point))))))))
;; This is the value the function returns.
(= arg 0))
(save-excursion
;; Like end-of-line but ignores fields.
(skip-chars-forward "^\n")
- (while (and (not (eobp)) (line-move-invisible-p (point)))
+ (while (and (not (eobp)) (invisible-p (point)))
(goto-char (next-char-property-change (point)))
(skip-chars-forward "^\n"))
(point))))
(move-to-column col))
(when (and line-move-ignore-invisible
- (not (bolp)) (line-move-invisible-p (1- (point))))
+ (not (bolp)) (invisible-p (1- (point))))
(let ((normal-location (point))
(normal-column (current-column)))
;; If the following character is currently invisible,
;; skip all characters with that same `invisible' property value.
(while (and (not (eobp))
- (line-move-invisible-p (point)))
+ (invisible-p (point)))
(goto-char (next-char-property-change (point))))
;; Have we advanced to a larger column position?
(if (> (current-column) normal-column)
;; but with a more reasonable buffer position.
(goto-char normal-location)
(let ((line-beg (save-excursion (beginning-of-line) (point))))
- (while (and (not (bolp)) (line-move-invisible-p (1- (point))))
+ (while (and (not (bolp)) (invisible-p (1- (point))))
(goto-char (previous-char-property-change (point) line-beg))))))))
(defun move-end-of-line (arg)
(and (line-move arg t)
(not (bobp))
(progn
- (while (and (not (bobp)) (line-move-invisible-p (1- (point))))
- (goto-char (previous-char-property-change (point))))
+ (while (and (not (bobp)) (invisible-p (1- (point))))
+ (goto-char (previous-single-char-property-change
+ (point) 'invisible)))
(backward-char 1)))
(point)))))
(goto-char newpos)
(or arg (setq arg 1))
(let ((orig (point))
- start first-vis first-vis-field-value)
+ first-vis first-vis-field-value)
;; Move by lines, if ARG is not 1 (the default).
(if (/= arg 1)
;; Move to beginning-of-line, ignoring fields and invisibles.
(skip-chars-backward "^\n")
- (while (and (not (bobp)) (line-move-invisible-p (1- (point))))
+ (while (and (not (bobp)) (invisible-p (1- (point))))
(goto-char (previous-char-property-change (point)))
(skip-chars-backward "^\n"))
- (setq start (point))
;; Now find first visible char in the line
- (while (and (not (eobp)) (line-move-invisible-p (point)))
+ (while (and (not (eobp)) (invisible-p (point)))
(goto-char (next-char-property-change (point))))
(setq first-vis (point))
regexp)
:group 'fill)
-(defvar comment-line-break-function 'comment-indent-new-line
- "*Mode-specific function which line breaks and continues a comment.
-
-This function is only called during auto-filling of a comment section.
-The function should take a single optional argument, which is a flag
-indicating whether it should use soft newlines.")
-
;; This function is used as the auto-fill-function of a buffer
;; when Auto-Fill mode is enabled.
;; It returns t if it really did any work.
(if (save-excursion
(skip-chars-backward " \t")
(= (point) fill-point))
- (funcall comment-line-break-function t)
+ (default-indent-new-line t)
(save-excursion
(goto-char fill-point)
- (funcall comment-line-break-function t)))
+ (default-indent-new-line t)))
;; Now do justification, if required
(if (not (eq justify 'left))
(save-excursion
(justify-current-line justify t t)
t)))
+(defvar comment-line-break-function 'comment-indent-new-line
+ "*Mode-specific function which line breaks and continues a comment.
+This function is called during auto-filling when a comment syntax
+is defined.
+The function should take a single optional argument, which is a flag
+indicating whether it should use soft newlines.")
+
+(defun default-indent-new-line (&optional soft)
+ "Break line at point and indent.
+If a comment syntax is defined, call `comment-indent-new-line'.
+
+The inserted newline is marked hard if variable `use-hard-newlines' is true,
+unless optional argument SOFT is non-nil."
+ (interactive)
+ (if comment-start
+ (funcall comment-line-break-function soft)
+ ;; Insert the newline before removing empty space so that markers
+ ;; get preserved better.
+ (if soft (insert-and-inherit ?\n) (newline 1))
+ (save-excursion (forward-char -1) (delete-horizontal-space))
+ (delete-horizontal-space)
+
+ (if (and fill-prefix (not adaptive-fill-mode))
+ ;; Blindly trust a non-adaptive fill-prefix.
+ (progn
+ (indent-to-left-margin)
+ (insert-before-markers-and-inherit fill-prefix))
+
+ (cond
+ ;; If there's an adaptive prefix, use it unless we're inside
+ ;; a comment and the prefix is not a comment starter.
+ (fill-prefix
+ (indent-to-left-margin)
+ (insert-and-inherit fill-prefix))
+ ;; If we're not inside a comment, just try to indent.
+ (t (indent-according-to-mode))))))
+
(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.")
(defun toggle-truncate-lines (&optional arg)
"Toggle whether to fold or truncate long lines for the current buffer.
-With arg, truncate long lines iff arg is positive.
-Note that in side-by-side windows, truncation is always enabled."
+With prefix argument ARG, truncate long lines if ARG is positive,
+otherwise don't truncate them. Note that in side-by-side
+windows, truncation is always enabled."
(interactive "P")
(setq truncate-lines
(if (null arg)
(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
-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.
+With prefix argument ARG, turn overwrite mode on if ARG is positive,
+otherwise turn it off. In overwrite mode, printing characters typed
+in replace existing text 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")
(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.
+With prefix argument ARG, turn binary overwrite mode on if ARG is
+positive, otherwise turn it off. 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
(define-minor-mode line-number-mode
"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.
+With arg, turn Line Number mode on if arg is positive, otherwise
+turn it off. When Line Number mode is enabled, the line number
+appears in the mode line.
Line numbers do not appear for very large buffers and buffers
with very long lines; see variables `line-number-display-limit'
(define-minor-mode column-number-mode
"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."
+With arg, turn Column Number mode on if arg is positive,
+otherwise turn it off. When Column Number mode is enabled, the
+column number appears in the mode line."
:global t :group 'mode-line)
(define-minor-mode size-indication-mode
"Toggle Size Indication mode.
-With arg, turn Size Indication mode on iff arg is positive. When
-Size Indication mode is enabled, the size of the accessible part
-of the buffer appears in the mode line."
+With arg, turn Size Indication mode on if arg is positive,
+otherwise turn it off. When Size Indication mode is enabled, the
+size of the accessible part of the buffer appears in the mode line."
:global t :group 'mode-line)
\f
(defgroup paren-blinking nil
(skip-syntax-backward "/\\")
(point))))))
(let* ((oldpos (point))
- blinkpos
- message-log-max ; Don't log messages about paren matching.
- matching-paren
- open-paren-line-string)
- (save-excursion
- (save-restriction
- (if blink-matching-paren-distance
- (narrow-to-region (max (minibuffer-prompt-end)
- (- (point) blink-matching-paren-distance))
- oldpos))
- (condition-case ()
- (let ((parse-sexp-ignore-comments
- (and parse-sexp-ignore-comments
- (not blink-matching-paren-dont-ignore-comments))))
- (setq blinkpos (scan-sexps oldpos -1)))
- (error nil)))
- (and blinkpos
- ;; Not syntax '$'.
- (not (eq (syntax-class (syntax-after blinkpos)) 8))
- (setq matching-paren
- (let ((syntax (syntax-after blinkpos)))
- (and (consp syntax)
- (eq (syntax-class syntax) 4)
- (cdr syntax)))))
- (cond
- ((not (or (eq matching-paren (char-before oldpos))
- ;; The cdr might hold a new paren-class info rather than
- ;; a matching-char info, in which case the two CDRs
- ;; should match.
- (eq matching-paren (cdr (syntax-after (1- oldpos))))))
- (message "Mismatched parentheses"))
- ((not blinkpos)
- (if (not blink-matching-paren-distance)
- (message "Unmatched parenthesis")))
- ((pos-visible-in-window-p blinkpos)
- ;; Matching open within window, temporarily move to blinkpos but only
- ;; if `blink-matching-paren-on-screen' is non-nil.
- (and blink-matching-paren-on-screen
- (not show-paren-mode)
- (save-excursion
- (goto-char blinkpos)
- (sit-for blink-matching-delay))))
- (t
- (save-excursion
- (goto-char blinkpos)
- (setq open-paren-line-string
- ;; Show what precedes the open in its line, if anything.
- (if (save-excursion
- (skip-chars-backward " \t")
- (not (bolp)))
- (buffer-substring (line-beginning-position)
- (1+ blinkpos))
- ;; 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
- (line-end-position))
- ;; 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")
- (line-beginning-position))
- (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)))))))
- (message "Matches %s"
- (substring-no-properties open-paren-line-string))))))))
-
-;Turned off because it makes dbx bomb out.
+ (message-log-max nil) ; Don't log messages about paren matching.
+ (atdollar (eq (syntax-class (syntax-after (1- oldpos))) 8))
+ (isdollar)
+ (blinkpos
+ (save-excursion
+ (save-restriction
+ (if blink-matching-paren-distance
+ (narrow-to-region
+ (max (minibuffer-prompt-end) ;(point-min) unless minibuf.
+ (- (point) blink-matching-paren-distance))
+ oldpos))
+ (let ((parse-sexp-ignore-comments
+ (and parse-sexp-ignore-comments
+ (not blink-matching-paren-dont-ignore-comments))))
+ (condition-case ()
+ (scan-sexps oldpos -1)
+ (error nil))))))
+ (matching-paren
+ (and blinkpos
+ ;; Not syntax '$'.
+ (not (setq isdollar
+ (eq (syntax-class (syntax-after blinkpos)) 8)))
+ (let ((syntax (syntax-after blinkpos)))
+ (and (consp syntax)
+ (eq (syntax-class syntax) 4)
+ (cdr syntax))))))
+ (cond
+ ;; isdollar is for:
+ ;; http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00871.html
+ ((not (or (and isdollar blinkpos)
+ (and atdollar (not blinkpos)) ; see below
+ (eq matching-paren (char-before oldpos))
+ ;; The cdr might hold a new paren-class info rather than
+ ;; a matching-char info, in which case the two CDRs
+ ;; should match.
+ (eq matching-paren (cdr (syntax-after (1- oldpos))))))
+ (message "Mismatched parentheses"))
+ ((not blinkpos)
+ (or blink-matching-paren-distance
+ ;; Don't complain when `$' with no blinkpos, because it
+ ;; could just be the first one typed in the buffer.
+ atdollar
+ (message "Unmatched parenthesis")))
+ ((pos-visible-in-window-p blinkpos)
+ ;; Matching open within window, temporarily move to blinkpos but only
+ ;; if `blink-matching-paren-on-screen' is non-nil.
+ (and blink-matching-paren-on-screen
+ (not show-paren-mode)
+ (save-excursion
+ (goto-char blinkpos)
+ (sit-for blink-matching-delay))))
+ (t
+ (save-excursion
+ (goto-char blinkpos)
+ (let ((open-paren-line-string
+ ;; Show what precedes the open in its line, if anything.
+ (cond
+ ((save-excursion (skip-chars-backward " \t") (not (bolp)))
+ (buffer-substring (line-beginning-position)
+ (1+ blinkpos)))
+ ;; Show what follows the open in its line, if anything.
+ ((save-excursion
+ (forward-char 1)
+ (skip-chars-forward " \t")
+ (not (eolp)))
+ (buffer-substring blinkpos
+ (line-end-position)))
+ ;; Otherwise show the previous nonblank line,
+ ;; if there is one.
+ ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
+ (concat
+ (buffer-substring (progn
+ (skip-chars-backward "\n \t")
+ (line-beginning-position))
+ (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.
+ (t (buffer-substring blinkpos (1+ blinkpos))))))
+ (message "Matches %s"
+ (substring-no-properties open-paren-line-string)))))))))
+
+;; Turned off because it makes dbx bomb out.
(setq blink-paren-function 'blink-matching-open)
\f
;; This executes C-g typed while Emacs is waiting for a command.
These functions are called in order with four arguments:
CHOICE - the string to insert in the buffer,
BUFFER - the buffer in which the choice should be inserted,
-MINI-P - non-nil iff BUFFER is a minibuffer, and
+MINI-P - non-nil if BUFFER is a minibuffer, and
BASE-SIZE - the number of characters in BUFFER before
the string being completed.
(funcall mode)
;; Set up other local variables.
- (mapcar (lambda (v)
- (condition-case () ;in case var is read-only
- (if (symbolp v)
- (makunbound v)
- (set (make-local-variable (car v)) (cdr v)))
- (error nil)))
- lvars)
+ (mapc (lambda (v)
+ (condition-case () ;in case var is read-only
+ (if (symbolp v)
+ (makunbound v)
+ (set (make-local-variable (car v)) (cdr v)))
+ (error nil)))
+ lvars)
;; Run any hooks (typically set up by the major mode
;; for cloning to work properly).
\f
;;; Handling of Backspace and Delete keys.
-(defcustom normal-erase-is-backspace
- (and (not noninteractive)
- (or (memq system-type '(ms-dos windows-nt))
- (eq window-system 'mac)
- (and (memq window-system '(x))
- (fboundp 'x-backspace-delete-keys-p)
- (x-backspace-delete-keys-p))
- ;; If the terminal Emacs is running on has erase char
- ;; set to ^H, use the Backspace key for deleting
- ;; backward and, and the Delete key for deleting forward.
- (and (null window-system)
- (eq tty-erase-char ?\^H))))
- "If non-nil, Delete key deletes forward and Backspace key deletes backward.
-
-On window systems, the default value of this option is chosen
-according to the keyboard used. If the keyboard has both a Backspace
-key and a Delete key, and both are mapped to their usual meanings, the
-option's default value is set to t, so that Backspace can be used to
-delete backward, and Delete can be used to delete forward.
-
-If not running under a window system, customizing this option accomplishes
-a similar effect by mapping C-h, which is usually generated by the
-Backspace key, to DEL, and by mapping DEL to C-d via
-`keyboard-translate'. The former functionality of C-h is available on
-the F1 key. You should probably not use this setting if you don't
-have both Backspace, Delete and F1 keys.
+(defcustom normal-erase-is-backspace 'maybe
+ "Set the default behaviour of the Delete and Backspace keys.
+
+If set to t, Delete key deletes forward and Backspace key deletes
+backward.
+
+If set to nil, both Delete and Backspace keys delete backward.
+
+If set to 'maybe (which is the default), Emacs automatically
+selects a behaviour. On window systems, the behaviour depends on
+the keyboard used. If the keyboard has both a Backspace key and
+a Delete key, and both are mapped to their usual meanings, the
+option's default value is set to t, so that Backspace can be used
+to delete backward, and Delete can be used to delete forward.
+
+If not running under a window system, customizing this option
+accomplishes a similar effect by mapping C-h, which is usually
+generated by the Backspace key, to DEL, and by mapping DEL to C-d
+via `keyboard-translate'. The former functionality of C-h is
+available on the F1 key. You should probably not use this
+setting if you don't have both Backspace, Delete and F1 keys.
Setting this variable with setq doesn't take effect. Programmatically,
call `normal-erase-is-backspace-mode' (which see) instead."
- :type 'boolean
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "Maybe" maybe)
+ (other :tag "On" t))
:group 'editing-basics
:version "21.1"
:set (lambda (symbol value)
(normal-erase-is-backspace-mode (or value 0))
(set-default symbol value))))
+(defun normal-erase-is-backspace-setup-frame (&optional frame)
+ "Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
+ (unless frame (setq frame (selected-frame)))
+ (with-selected-frame frame
+ (unless (terminal-parameter nil 'normal-erase-is-backspace)
+ (normal-erase-is-backspace-mode
+ (if (if (eq normal-erase-is-backspace 'maybe)
+ (and (not noninteractive)
+ (or (memq system-type '(ms-dos windows-nt))
+ (eq window-system 'mac)
+ (and (memq window-system '(x))
+ (fboundp 'x-backspace-delete-keys-p)
+ (x-backspace-delete-keys-p))
+ ;; If the terminal Emacs is running on has erase char
+ ;; set to ^H, use the Backspace key for deleting
+ ;; backward, and the Delete key for deleting forward.
+ (and (null window-system)
+ (eq tty-erase-char ?\^H))))
+ normal-erase-is-backspace)
+ 1 0)))))
(defun normal-erase-is-backspace-mode (&optional arg)
"Toggle the Erase and Delete mode of the Backspace and Delete keys.
With numeric arg, turn the mode on if and only if ARG is positive.
-On window systems, when this mode is on, Delete is mapped to C-d and
-Backspace is mapped to DEL; when this mode is off, both Delete and
-Backspace are mapped to DEL. (The remapping goes via
-`function-key-map', so binding Delete or Backspace in the global or
-local keymap will override that.)
+On window systems, when this mode is on, Delete is mapped to C-d
+and Backspace is mapped to DEL; when this mode is off, both
+Delete and Backspace are mapped to DEL. (The remapping goes via
+`local-function-key-map', so binding Delete or Backspace in the
+global or local keymap will override that.)
In addition, on window systems, the bindings of C-Delete, M-Delete,
C-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in
See also `normal-erase-is-backspace'."
(interactive "P")
- (setq normal-erase-is-backspace
- (if arg
- (> (prefix-numeric-value arg) 0)
- (not normal-erase-is-backspace)))
-
- (cond ((or (memq window-system '(x w32 mac pc))
- (memq system-type '(ms-dos windows-nt)))
- (let ((bindings
- `(([C-delete] [C-backspace])
- ([M-delete] [M-backspace])
- ([C-M-delete] [C-M-backspace])
- (,esc-map
- [C-delete] [C-backspace])))
- (old-state (lookup-key function-key-map [delete])))
-
- (if normal-erase-is-backspace
+ (let ((enabled (or (and arg (> (prefix-numeric-value arg) 0))
+ (and (not arg)
+ (not (eq 1 (terminal-parameter
+ nil 'normal-erase-is-backspace)))))))
+ (set-terminal-parameter nil 'normal-erase-is-backspace
+ (if enabled 1 0))
+
+ (cond ((or (memq window-system '(x w32 mac pc))
+ (memq system-type '(ms-dos windows-nt)))
+ (let* ((bindings
+ `(([C-delete] [C-backspace])
+ ([M-delete] [M-backspace])
+ ([C-M-delete] [C-M-backspace])
+ (,esc-map
+ [C-delete] [C-backspace])))
+ (old-state (lookup-key local-function-key-map [delete])))
+
+ (if enabled
+ (progn
+ (define-key local-function-key-map [delete] [?\C-d])
+ (define-key local-function-key-map [kp-delete] [?\C-d])
+ (define-key local-function-key-map [backspace] [?\C-?]))
+ (define-key local-function-key-map [delete] [?\C-?])
+ (define-key local-function-key-map [kp-delete] [?\C-?])
+ (define-key local-function-key-map [backspace] [?\C-?]))
+
+ ;; Maybe swap bindings of C-delete and C-backspace, etc.
+ (unless (equal old-state (lookup-key local-function-key-map [delete]))
+ (dolist (binding bindings)
+ (let ((map global-map))
+ (when (keymapp (car binding))
+ (setq map (car binding) binding (cdr binding)))
+ (let* ((key1 (nth 0 binding))
+ (key2 (nth 1 binding))
+ (binding1 (lookup-key map key1))
+ (binding2 (lookup-key map key2)))
+ (define-key map key1 binding2)
+ (define-key map key2 binding1)))))))
+ (t
+ (if enabled
(progn
- (define-key function-key-map [delete] [?\C-d])
- (define-key function-key-map [kp-delete] [?\C-d])
- (define-key function-key-map [backspace] [?\C-?]))
- (define-key function-key-map [delete] [?\C-?])
- (define-key function-key-map [kp-delete] [?\C-?])
- (define-key function-key-map [backspace] [?\C-?]))
-
- ;; Maybe swap bindings of C-delete and C-backspace, etc.
- (unless (equal old-state (lookup-key function-key-map [delete]))
- (dolist (binding bindings)
- (let ((map global-map))
- (when (keymapp (car binding))
- (setq map (car binding) binding (cdr binding)))
- (let* ((key1 (nth 0 binding))
- (key2 (nth 1 binding))
- (binding1 (lookup-key map key1))
- (binding2 (lookup-key map key2)))
- (define-key map key1 binding2)
- (define-key map key2 binding1)))))))
- (t
- (if normal-erase-is-backspace
- (progn
- (keyboard-translate ?\C-h ?\C-?)
- (keyboard-translate ?\C-? ?\C-d))
- (keyboard-translate ?\C-h ?\C-h)
- (keyboard-translate ?\C-? ?\C-?))))
-
- (run-hooks 'normal-erase-is-backspace-hook)
- (if (interactive-p)
- (message "Delete key deletes %s"
- (if normal-erase-is-backspace "forward" "backward"))))
+ (keyboard-translate ?\C-h ?\C-?)
+ (keyboard-translate ?\C-? ?\C-d))
+ (keyboard-translate ?\C-h ?\C-h)
+ (keyboard-translate ?\C-? ?\C-?))))
+
+ (run-hooks 'normal-erase-is-backspace-hook)
+ (if (interactive-p)
+ (message "Delete key deletes %s"
+ (if (terminal-parameter nil 'normal-erase-is-backspace)
+ "forward" "backward")))))
\f
(defvar vis-mode-saved-buffer-invisibility-spec nil
"Saved value of `buffer-invisibility-spec' when Visible mode is on.")
(define-minor-mode visible-mode
"Toggle Visible mode.
-With argument ARG turn Visible mode on iff ARG is positive.
+With argument ARG turn Visible mode on if ARG is positive, otherwise
+turn it off.
Enabling Visible mode makes all invisible text temporarily visible.
Disabling Visible mode turns off that effect. Visible mode
; 'insert-in-front-hooks '(minibuffer-prompt-insertion)))
;
+\f
+;;;; Problematic external packages.
+
+;; rms says this should be done by specifying symbols that define
+;; versions together with bad values. This is therefore not as
+;; flexible as it could be. See the thread:
+;; http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00300.html
+(defconst bad-packages-alist
+ ;; Not sure exactly which semantic versions have problems.
+ ;; Definitely 2.0pre3, probably all 2.0pre's before this.
+ '((semantic semantic-version "\\`2\\.0pre[1-3]\\'"
+ "The version of `semantic' loaded does not work in Emacs 22.
+It can cause constant high CPU load.
+Upgrade to at least Semantic 2.0pre4 (distributed with CEDET 1.0pre4).")
+ ;; CUA-mode does not work with GNU Emacs version 22.1 and newer.
+ ;; Except for version 1.2, all of the 1.x and 2.x version of cua-mode
+ ;; provided the `CUA-mode' feature. Since this is no longer true,
+ ;; we can warn the user if the `CUA-mode' feature is ever provided.
+ (CUA-mode t nil
+"CUA-mode is now part of the standard GNU Emacs distribution,
+so you can now enable CUA via the Options menu or by customizing `cua-mode'.
+
+You have loaded an older version of CUA-mode which does not work
+correctly with this version of Emacs. You should remove the old
+version and use the one distributed with Emacs."))
+ "Alist of packages known to cause problems in this version of Emacs.
+Each element has the form (PACKAGE SYMBOL REGEXP STRING).
+PACKAGE is either a regular expression to match file names, or a
+symbol (a feature name); see the documentation of
+`after-load-alist', to which this variable adds functions.
+SYMBOL is either the name of a string variable, or `t'. Upon
+loading PACKAGE, if SYMBOL is t or matches REGEXP, display a
+warning using STRING as the message.")
+
+(defun bad-package-check (package)
+ "Run a check using the element from `bad-packages-alist' matching PACKAGE."
+ (condition-case nil
+ (let* ((list (assoc package bad-packages-alist))
+ (symbol (nth 1 list)))
+ (and list
+ (boundp symbol)
+ (or (eq symbol t)
+ (and (stringp (setq symbol (eval symbol)))
+ (string-match (nth 2 list) symbol)))
+ (display-warning :warning (nth 3 list))))
+ (error nil)))
+
+(mapc (lambda (elem)
+ (eval-after-load (car elem) `(bad-package-check ',(car elem))))
+ bad-packages-alist)
+
+
(provide 'simple)
;; arch-tag: 24af67c0-2a49-44f6-b3b1-312d8b570dfd