;;; 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 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,
:group 'next-error
:version "22.1")
-(defcustom next-error-highlight 0.1
+(defcustom next-error-highlight 0.5
"*Highlighting of locations in selected source buffers.
-If number, highlight the locus in `next-error' face for given time in seconds.
-If t, use persistent overlays fontified in `next-error' face.
+If a number, highlight the locus in `next-error' face for the given time
+in seconds, or until the next command is executed.
+If t, highlight the locus until the next command is executed, or until
+some other locus replaces it.
If nil, don't highlight the locus in the source buffer.
If `fringe-arrow', indicate the locus by the fringe arrow."
- :type '(choice (number :tag "Delay")
- (const :tag "Persistent overlay" t)
+ :type '(choice (number :tag "Highlight for specified time")
+ (const :tag "Semipermanent highlighting" t)
(const :tag "No highlighting" nil)
- (const :tag "Fringe arrow" 'fringe-arrow))
+ (const :tag "Fringe arrow" fringe-arrow))
:group 'next-error
:version "22.1")
-(defcustom next-error-highlight-no-select 0.1
- "*Highlighting of locations in non-selected source buffers.
+(defcustom next-error-highlight-no-select 0.5
+ "*Highlighting of locations in `next-error-no-select'.
If number, highlight the locus in `next-error' face for given time in seconds.
-If t, use persistent overlays fontified in `next-error' face.
+If t, highlight the locus indefinitely until some other locus replaces it.
If nil, don't highlight the locus in the source buffer.
If `fringe-arrow', indicate the locus by the fringe arrow."
- :type '(choice (number :tag "Delay")
- (const :tag "Persistent overlay" t)
+ :type '(choice (number :tag "Highlight for specified time")
+ (const :tag "Semipermanent highlighting" t)
(const :tag "No highlighting" nil)
- (const :tag "Fringe arrow" 'fringe-arrow))
+ (const :tag "Fringe arrow" fringe-arrow))
:group 'next-error
:version "22.1")
(next-error-buffer-p (current-buffer) nil
extra-test-inclusive extra-test-exclusive)
(progn
- (message "This is the only next-error capable buffer")
+ (message "This is the only buffer with error message locations")
(current-buffer)))
;; 6. Give up.
- (error "No next-error capable buffer found")))
+ (error "No buffers contain error message locations")))
(defun next-error (&optional arg reset)
"Visit next `next-error' message and corresponding source code.
(defun delete-horizontal-space (&optional backward-only)
"Delete all spaces and tabs around point.
-If BACKWARD-ONLY is non-nil, only delete spaces before point."
- (interactive "*")
+If BACKWARD-ONLY is non-nil, only delete them before point."
+ (interactive "*P")
(let ((orig-pos (point)))
(delete-region
(if backward-only
(/ size 10))
(/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
(point-min))))
- (if arg (forward-line 1)))
+ (if (and arg (not (consp arg))) (forward-line 1)))
(defun end-of-buffer (&optional arg)
"Move point to the end of the buffer; leave mark at previous position.
(point-max))))
;; If we went to a place in the middle of the buffer,
;; adjust it to the beginning of a line.
- (cond (arg (forward-line 1))
+ (cond ((and arg (not (consp arg))) (forward-line 1))
((> (point) (window-end nil t))
;; If the end of the buffer is not already on the screen,
;; then scroll specially to put it near, but not at, the bottom.
(defun line-number-at-pos (&optional pos)
"Return (narrowed) buffer line number at position POS.
-If POS is nil, use current buffer location."
+If POS is nil, use current buffer location.
+Counting starts at (point-min), so the value refers
+to the contents of the accessible portion of the buffer."
(let ((opoint (or pos (point))) start)
(save-excursion
(goto-char (point-min))
(single-key-description char))
encoding-msg pos total percent col hscroll))))))
\f
-(defvar read-expression-map
- (let ((m (make-sparse-keymap)))
- (define-key m "\M-\t" 'lisp-complete-symbol)
- (set-keymap-parent m minibuffer-local-map)
- m)
- "Minibuffer keymap used for reading Lisp expressions.")
+;; Initialize read-expression-map. It is defined at C level.
+(let ((m (make-sparse-keymap)))
+ (define-key m "\M-\t" 'lisp-complete-symbol)
+ (set-keymap-parent m minibuffer-local-map)
+ (setq read-expression-map m))
(defvar read-expression-history nil)
+(defvar minibuffer-completing-symbol nil
+ "Non-nil means completing a Lisp symbol in the minibuffer.")
+
(defcustom eval-expression-print-level 4
"Value for `print-level' while printing value in `eval-expression'.
A value of nil means no limit."
(format " (#o%o, #x%x)" value value)))))
;; We define this, rather than making `eval' interactive,
-;; for the sake of completion of names like eval-region, eval-current-buffer.
+;; for the sake of completion of names like eval-region, eval-buffer.
(defun eval-expression (eval-expression-arg
&optional eval-expression-insert-value)
"Evaluate EVAL-EXPRESSION-ARG and print value in the echo area.
If `eval-expression-debug-on-error' is non-nil, which is the default,
this command arranges for all errors to enter the debugger."
(interactive
- (list (read-from-minibuffer "Eval: "
- nil read-expression-map t
- 'read-expression-history)
+ (list (let ((minibuffer-completing-symbol t))
+ (read-from-minibuffer "Eval: "
+ nil read-expression-map t
+ 'read-expression-history))
current-prefix-arg))
(if (null eval-expression-debug-on-error)
(if eval-expression-insert-value
(with-no-warnings
(let ((standard-output (current-buffer)))
- (eval-last-sexp-print-value (car values))))
+ (prin1 (car values))))
(prog1
(prin1 (car values) t)
(let ((str (eval-expression-print-format (car values))))
\(That convention is designed to do the right thing for
recursive uses of the minibuffer.)")
(setq minibuffer-history-variable 'minibuffer-history)
-(setq minibuffer-history-position nil)
+(setq minibuffer-history-position nil) ;; Defvar is in C code.
(defvar minibuffer-history-search-history nil)
(defvar minibuffer-text-before-history nil
(defvar minibuffer-temporary-goal-position nil)
(defun next-history-element (n)
- "Insert the next element of the minibuffer history into the minibuffer."
+ "Puts next element of the minibuffer history in the minibuffer.
+With argument N, it uses the Nth following element."
(interactive "p")
(or (zerop n)
(let ((narg (- minibuffer-history-position n))
(goto-char (or minibuffer-temporary-goal-position (point-max))))))
(defun previous-history-element (n)
- "Inserts the previous element of the minibuffer history into the minibuffer."
+ "Puts previous element of the minibuffer history in the minibuffer.
+With argument N, it uses the Nth previous element."
(interactive "p")
(next-history-element (- n)))
then call `undo-more' one or more times to undo them."
(or (listp pending-undo-list)
(error (concat "No further undo information"
- (and transient-mark-mode mark-active
- " for region"))))
+ (and undo-in-region " for region"))))
(let ((undo-in-progress t))
(setq pending-undo-list (primitive-undo n pending-undo-list))
(if (null pending-undo-list)
((null (car undo-elt))
;; (nil PROPERTY VALUE BEG . END)
(let ((tail (nthcdr 3 undo-elt)))
- (not (or (< (car tail) end)
- (> (cdr tail) start)))))
+ (and (< (car tail) end)
+ (> (cdr tail) start))))
((integerp (car undo-elt))
;; (BEGIN . END)
- (not (or (< (car undo-elt) end)
- (> (cdr undo-elt) start))))))
+ (and (< (car undo-elt) end)
+ (> (cdr undo-elt) start)))))
;; Return the first affected buffer position and the delta for an undo element
;; delta is defined as the change in subsequent buffer positions if we *did*
'(0 . 0)))
'(0 . 0)))
-(defcustom undo-ask-before-discard t
+(defcustom undo-ask-before-discard nil
"If non-nil ask about discarding undo info for the current command.
Normally, Emacs discards the undo info for the current command if
it exceeds `undo-outer-limit'. But if you set this option
non-nil, it asks in the echo area whether to discard the info.
-If you answer no, there a slight risk that Emacs might crash, so
+If you answer no, there is a slight risk that Emacs might crash, so
only do it if you really want to undo the command.
This option is mainly intended for debugging. You have to be
;; but we don't want to ask the question again.
(setq undo-extra-outer-limit (+ size 50000))
(if (let (use-dialog-box track-mouse executing-kbd-macro )
- (yes-or-no-p (format "Buffer %s undo info is %d bytes long; discard it? "
+ (yes-or-no-p (format "Buffer `%s' undo info is %d bytes long; discard it? "
(buffer-name) size)))
(progn (setq buffer-undo-list nil)
(setq undo-extra-outer-limit nil)
nil))
(display-warning '(undo discard-info)
(concat
- (format "Buffer %s undo info was %d bytes long.\n"
+ (format "Buffer `%s' undo info was %d bytes long.\n"
(buffer-name) size)
"The undo info was discarded because it exceeded \
`undo-outer-limit'.
Optional arguments NOT-THIS-WINDOW and FRAME are as for `display-buffer',
and only used if a buffer is displayed."
- (cond ((and (stringp message)
- (not (string-match "\n" message))
- (<= (length message) (frame-width)))
+ (cond ((and (stringp message) (not (string-match "\n" message)))
;; Trivial case where we can use the echo area
(message "%s" message))
((and (stringp message)
- (= (string-match "\n" message) (1- (length message)))
- (<= (1- (length message)) (frame-width)))
+ (= (string-match "\n" message) (1- (length message))))
;; Trivial case where we can just remove single trailing newline
(message "%s" (substring message 0 (1- (length message)))))
(t
In Lisp code, optional third arg YANK-HANDLER, if non-nil,
specifies the yank-handler text property to be set on the killed
text. See `insert-for-yank'."
- (interactive "r")
+ ;; Pass point first, then mark, because the order matters
+ ;; when calling kill-append.
+ (interactive (list (point) (mark)))
+ (unless (and beg end)
+ (error "The mark is not set now, so there is no region"))
(condition-case nil
(let ((string (filter-buffer-substring beg end t)))
(when string ;STRING is nil if BEG = END
;; This is actually used in subr.el but defcustom does not work there.
(defcustom yank-excluded-properties
'(read-only invisible intangible field mouse-face help-echo local-map keymap
- yank-handler follow-link)
+ yank-handler follow-link fontified)
"*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."
`yank-excluded-properties' and `yank-handler' as described in the
doc string for `insert-for-yank-1', which see.
-See also the command \\[yank-pop]."
+See also the command `yank-pop' (\\[yank-pop])."
(interactive "*P")
(setq yank-window-start (window-start))
;; If we don't get all the way thru, make last-command indicate that
a number counts as a prefix arg.
To kill a whole line, when point is not at the beginning, type \
-\\[beginning-of-line] \\[kill-line] \\[kill-line].
+\\[move-beginning-of-line] \\[kill-line] \\[kill-line].
If `kill-whole-line' is non-nil, then this command kills the whole line
including its terminating newline, when used at the beginning of a line
with no argument. As a consequence, you can always kill a whole line
-by typing \\[beginning-of-line] \\[kill-line].
+by typing \\[move-beginning-of-line] \\[kill-line].
If you want to append the killed line to the last killed text,
use \\[append-next-kill] before \\[kill-line].
(defvar activate-mark-hook nil
"Hook run when the mark becomes active.
It is also run at the end of a command, if the mark is active and
-it is possible that the region may have changed")
+it is possible that the region may have changed.")
(defvar deactivate-mark-hook nil
"Hook run when the mark becomes inactive.")
(interactive)
(if (null (mark t))
(error "No mark set in this buffer")
+ (if (= (point) (mark t))
+ (message "Mark popped"))
(goto-char (mark t))
(pop-mark)))
(message "Mark activated")))))
(defcustom set-mark-command-repeat-pop nil
- "*Non-nil means that repeating \\[set-mark-command] after popping will pop.
-This means that if you type C-u \\[set-mark-command] \\[set-mark-command]
-will pop twice."
+ "*Non-nil means repeating \\[set-mark-command] after popping mark pops it again.
+That means that C-u \\[set-mark-command] \\[set-mark-command]
+will pop the mark twice, and
+C-u \\[set-mark-command] \\[set-mark-command] \\[set-mark-command]
+will pop the mark three times.
+
+A value of nil means \\[set-mark-command]'s behavior does not change
+after C-u \\[set-mark-command]."
:type 'boolean
- :group 'editing)
+ :group 'editing-basics)
(defun set-mark-command (arg)
- "Set mark at where point is, or jump to mark.
-With no prefix argument, set mark, and push old mark position on local
-mark ring; also push mark on global mark ring if last mark was set in
-another buffer. Immediately repeating the command activates
-`transient-mark-mode' temporarily.
-
-With argument, e.g. \\[universal-argument] \\[set-mark-command], \
-jump to mark, and pop a new position
-for mark off the local mark ring \(this does not affect the global
-mark ring\). Use \\[pop-global-mark] to jump to a mark off the global
+ "Set the mark where point is, or jump to the mark.
+Setting the mark also alters the region, which is the text
+between point and mark; this is the closest equivalent in
+Emacs to what some editors call the \"selection\".
+
+With no prefix argument, set the mark at point, and push the
+old mark position on local mark ring. Also push the old mark on
+global mark ring, if the previous mark was set in another buffer.
+
+Immediately repeating this command activates `transient-mark-mode' temporarily.
+
+With prefix argument \(e.g., \\[universal-argument] \\[set-mark-command]\), \
+jump to the mark, and set the mark from
+position popped off the local mark ring \(this does not affect the global
+mark ring\). Use \\[pop-global-mark] to jump to a mark popped off the global
mark ring \(see `pop-global-mark'\).
If `set-mark-command-repeat-pop' is non-nil, repeating
-the \\[set-mark-command] command with no prefix pops the next position
+the \\[set-mark-command] command with no prefix argument pops the next position
off the local (or global) mark ring and jumps there.
-With a double \\[universal-argument] prefix argument, e.g. \\[universal-argument] \
-\\[universal-argument] \\[set-mark-command], unconditionally
-set mark where point is.
-
-Setting the mark also sets the \"region\", which is the closest
-equivalent in Emacs to what some editors call the \"selection\".
+With \\[universal-argument] \\[universal-argument] as prefix
+argument, unconditionally set mark where point is, even if
+`set-mark-command-repeat-pop' is 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."
If the last global mark pushed was not in the current buffer,
also push LOCATION on the global mark ring.
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.
-In Transient Mark mode, this does not activate the mark."
+In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil."
(unless (null (mark t))
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
(when (> (length mark-ring) mark-ring-max)
:type 'boolean
:group 'editing-basics)
-(defun line-move-invisible-p (pos)
+(defun invisible-p (pos)
"Return non-nil if the character after POS is currently invisible."
(let ((prop
(get-char-property pos 'invisible)))
prop
(or (memq prop buffer-invisibility-spec)
(assq prop buffer-invisibility-spec)))))
+(define-obsolete-function-alias 'line-move-invisible-p 'invisible-p)
+
+;; Returns non-nil if partial move was done.
+(defun line-move-partial (arg noerror to-end)
+ (if (< arg 0)
+ ;; Move backward (up).
+ ;; If already vscrolled, reduce vscroll
+ (let ((vs (window-vscroll nil t)))
+ (when (> vs (frame-char-height))
+ (set-window-vscroll nil (- vs (frame-char-height)) t)))
+
+ ;; Move forward (down).
+ (let* ((lh (window-line-height -1))
+ (vpos (nth 1 lh))
+ (ypos (nth 2 lh))
+ (rbot (nth 3 lh))
+ ppos py vs)
+ (when (or (null lh)
+ (>= rbot (frame-char-height))
+ (<= ypos (- (frame-char-height))))
+ (unless lh
+ (let ((wend (pos-visible-in-window-p t nil t)))
+ (setq rbot (nth 3 wend)
+ vpos (nth 5 wend))))
+ (cond
+ ;; If last line of window is fully visible, move forward.
+ ((or (null rbot) (= rbot 0))
+ nil)
+ ;; If cursor is not in the bottom scroll margin, move forward.
+ ((and (> vpos 0)
+ (< (setq py
+ (or (nth 1 (window-line-height))
+ (let ((ppos (posn-at-point)))
+ (cdr (or (posn-actual-col-row ppos)
+ (posn-col-row ppos))))))
+ (min (- (window-text-height) scroll-margin 1) (1- vpos))))
+ nil)
+ ;; When already vscrolled, we vscroll some more if we can,
+ ;; or clear vscroll and move forward at end of tall image.
+ ((> (setq vs (window-vscroll nil t)) 0)
+ (when (> rbot 0)
+ (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t)))
+ ;; If cursor just entered the bottom scroll margin, move forward,
+ ;; but also vscroll one line so redisplay wont recenter.
+ ((and (> vpos 0)
+ (= py (min (- (window-text-height) scroll-margin 1)
+ (1- vpos))))
+ (set-window-vscroll nil (frame-char-height) t)
+ (line-move-1 arg noerror to-end)
+ t)
+ ;; If there are lines above the last line, scroll-up one line.
+ ((> vpos 0)
+ (scroll-up 1)
+ t)
+ ;; Finally, start vscroll.
+ (t
+ (set-window-vscroll nil (frame-char-height) t)))))))
+
;; This is like line-move-1 except that it also performs
;; vertical scrolling of tall images if appropriate.
;; a cleaner solution to the problem of making C-n do something
;; useful given a tall image.
(defun line-move (arg &optional noerror to-end try-vscroll)
- (if (and auto-window-vscroll try-vscroll
- ;; But don't vscroll in a keyboard macro.
- (not defining-kbd-macro)
- (not executing-kbd-macro))
- (let ((forward (> arg 0))
- (part (nth 2 (pos-visible-in-window-p (point) nil t))))
- (if (and (consp part)
- (> (if forward (cdr part) (car part)) 0))
- (set-window-vscroll nil
- (if forward
- (+ (window-vscroll nil t)
- (min (cdr part)
- (* (frame-char-height) arg)))
- (max 0
- (- (window-vscroll nil t)
- (min (car part)
- (* (frame-char-height) (- arg))))))
- t)
- (set-window-vscroll nil 0)
- (when (line-move-1 arg noerror to-end)
- (when (not forward)
- ;; Update display before calling pos-visible-in-window-p,
- ;; because it depends on window-start being up-to-date.
- (sit-for 0)
- ;; If the current line is partly hidden at the bottom,
- ;; scroll it partially up so as to unhide the bottom.
- (if (and (setq part (nth 2 (pos-visible-in-window-p
- (line-beginning-position) nil t)))
- (> (cdr part) 0))
- (set-window-vscroll nil (cdr part) t)))
- t)))
+ (unless (and auto-window-vscroll try-vscroll
+ ;; Only vscroll for single line moves
+ (= (abs arg) 1)
+ ;; But don't vscroll in a keyboard macro.
+ (not defining-kbd-macro)
+ (not executing-kbd-macro)
+ (line-move-partial arg noerror to-end))
+ (set-window-vscroll nil 0 t)
(line-move-1 arg noerror to-end)))
;; This is the guts of next-line and previous-line.
;; for intermediate positions.
(let ((inhibit-point-motion-hooks t)
(opoint (point))
- (forward (> arg 0)))
+ (orig-arg arg))
(unwind-protect
(progn
(if (not (memq last-command '(next-line previous-line)))
(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)))
+ (or (not (bolp)) (eq last-command 'move-end-of-line)))
9999
(current-column))))
(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))))
- ;; Now move a line.
- (end-of-line)
+ ;; Move a line.
+ ;; We don't use `end-of-line', since we want to escape
+ ;; from field boundaries ocurring exactly at point.
+ (goto-char (constrain-to-field
+ (let ((inhibit-field-text-motion t))
+ (line-end-position))
+ (point) t t
+ 'inhibit-line-move-field-capture))
;; If there's no invisibility here, move over the newline.
(cond
((eobp)
(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))
;; The logic of this is the same as the loop above,
;; it just goes in the other direction.
(while (and (< arg 0) (not done))
- (beginning-of-line)
+ ;; For completely consistency with the forward-motion
+ ;; case, we should call beginning-of-line here.
+ ;; However, if point is inside a field and on a
+ ;; continued line, the call to (vertical-motion -1)
+ ;; below won't move us back far enough; then we return
+ ;; to the same column in line-move-finish, and point
+ ;; gets stuck -- cyd
+ (forward-line 0)
(cond
((bobp)
(if (not noerror)
(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))
(beginning-of-line))
(t
(line-move-finish (or goal-column temporary-goal-column)
- opoint forward))))))
+ opoint (> orig-arg 0)))))))
(defun line-move-finish (column opoint forward)
(let ((repeat t))
(setq repeat nil)
(let (new
+ (old (point))
(line-beg (save-excursion (beginning-of-line) (point)))
(line-end
;; Compute the end of the line
(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 the desired column.
(line-move-to-column column)
+
+ ;; Corner case: suppose we start out in a field boundary in
+ ;; the middle of a continued line. When we get to
+ ;; line-move-finish, point is at the start of a new *screen*
+ ;; line but the same text line; then line-move-to-column would
+ ;; move us backwards. Test using C-n with point on the "x" in
+ ;; (insert "a" (propertize "x" 'field t) (make-string 89 ?y))
+ (and forward
+ (< (point) old)
+ (goto-char old))
+
(setq new (point))
;; Process intangibility within a line.
- ;; Move to the chosen destination position from above,
- ;; with intangibility processing enabled.
-
- (goto-char (point-min))
+ ;; With inhibit-point-motion-hooks bound to nil, a call to
+ ;; goto-char moves point past intangible text.
+
+ ;; However, inhibit-point-motion-hooks controls both the
+ ;; intangibility and the point-entered/point-left hooks. The
+ ;; following hack avoids calling the point-* hooks
+ ;; unnecessarily. Note that we move *forward* past intangible
+ ;; text when the initial and final points are the same.
+ (goto-char new)
(let ((inhibit-point-motion-hooks nil))
(goto-char new)
(goto-char opoint)
(let ((inhibit-point-motion-hooks nil))
(goto-char
- (constrain-to-field new opoint nil t
- 'inhibit-line-move-field-capture)))
+ ;; Ignore field boundaries if the initial and final
+ ;; positions have the same `field' property, even if the
+ ;; fields are non-contiguous. This seems to be "nicer"
+ ;; behavior in many situations.
+ (if (eq (get-char-property new 'field)
+ (get-char-property opoint 'field))
+ new
+ (constrain-to-field new opoint t t
+ 'inhibit-line-move-field-capture))))
;; If all this moved us to a different line,
;; retry everything within that new line.
(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))))
+ (while (and (not (bobp)) (invisible-p (1- (point))))
(goto-char (previous-char-property-change (point))))
(backward-char 1)))
(point)))))
(interactive "p")
(or arg (setq arg 1))
- (let ((orig (point)))
+ (let ((orig (point))
+ start 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)) (invisible-p (point)))
+ (goto-char (next-char-property-change (point))))
+ (setq first-vis (point))
- ;; Take care of fields.
- (goto-char (constrain-to-field (point) orig
- (/= arg 1) t nil))))
+ ;; See if fields would stop us from reaching FIRST-VIS.
+ (setq first-vis-field-value
+ (constrain-to-field first-vis orig (/= arg 1) t nil))
+
+ (goto-char (if (/= first-vis-field-value first-vis)
+ ;; If yes, obey them.
+ first-vis-field-value
+ ;; Otherwise, move to START with attention to fields.
+ ;; (It is possible that fields never matter in this case.)
+ (constrain-to-field (point) orig
+ (/= arg 1) t nil)))))
;;; Many people have said they rarely use this feature, and often type
(kill-region (point) (progn (forward-word arg) (point))))
(defun backward-kill-word (arg)
- "Kill characters backward until encountering the end of a word.
+ "Kill characters backward until encountering the beginning of a word.
With argument, do this that many times."
(interactive "p")
(kill-word (- arg)))
string)
:group 'fill)
(make-variable-buffer-local 'fill-prefix)
+;;;###autoload(put 'fill-prefix 'safe-local-variable 'string-or-null-p)
(defcustom auto-fill-inhibit-regexp nil
"*Regexp to match lines which should not be auto-filled."
(defvaralias 'indicate-unused-lines 'indicate-empty-lines)
(defvaralias 'default-indicate-unused-lines 'default-indicate-empty-lines)
-(defun toggle-truncate-lines (arg)
- "Toggle whether to fold or truncate long lines on the screen.
-With arg, truncate long lines iff arg is positive.
-Note that in side-by-side windows, truncation is always enabled."
+(defun toggle-truncate-lines (&optional arg)
+ "Toggle whether to fold or truncate long lines for the current buffer.
+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'
and `line-number-display-limit-width'."
- :init-value t :global t :group 'editing-basics)
+ :init-value t :global t :group 'mode-line)
(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."
- :global t :group 'editing-basics)
+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."
- :global t :group 'editing-basics)
+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
"Blinking matching of parens and expressions."
(defcustom blink-matching-paren-on-screen t
"*Non-nil means show matching open-paren when it is on screen.
-If nil, means don't show it (but the open-paren can still be shown
+If nil, don't show it (but the open-paren can still be shown
when it is off screen).
This variable has no effect if `blink-matching-paren' is nil.
:group 'paren-blinking)
(defcustom blink-matching-paren-dont-ignore-comments nil
- "*nil means `blink-matching-paren' ignores comments.
+ "*If nil, `blink-matching-paren' ignores comments.
More precisely, when looking for the matching parenthesis,
it skips the contents of comments that end before point."
:type 'boolean
(save-excursion
(save-restriction
(if blink-matching-paren-distance
- (narrow-to-region (max (point-min)
+ (narrow-to-region (max (minibuffer-prompt-end)
(- (point) blink-matching-paren-distance))
oldpos))
(condition-case ()
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.
;; Variables and faces used in `completion-setup-function'.
+(defcustom completion-show-help t
+ "Non-nil means show help message in *Completions* buffer."
+ :type 'boolean
+ :version "22.1"
+ :group 'completion)
+
(defface completions-first-difference
'((t (:inherit bold)))
"Face put on the first uncommon character in completions in *Completions* buffer."
;; so it will get copied into the completion list buffer.
(if minibuffer-completing-file-name
(with-current-buffer mainbuf
- (setq default-directory (file-name-directory mbuf-contents))))
+ (setq default-directory
+ (file-name-directory (expand-file-name mbuf-contents)))))
(with-current-buffer standard-output
(completion-list-mode)
(set (make-local-variable 'completion-reference-buffer) mainbuf)
(save-excursion
(skip-chars-backward completion-root-regexp)
(- (point) (minibuffer-prompt-end)))))
+ (minibuffer-completing-symbol nil)
;; Otherwise, in minibuffer, the base size is 0.
((minibufferp mainbuf) 0)))
(setq common-string-length
(if (get-char-property element-common-end 'mouse-face)
(put-text-property element-common-end (1+ element-common-end)
'font-lock-face 'completions-first-difference))))))
- ;; Insert help string.
- (goto-char (point-min))
- (if (display-mouse-p)
- (insert (substitute-command-keys
- "Click \\[mouse-choose-completion] on a completion to select it.\n")))
- (insert (substitute-command-keys
- "In this buffer, type \\[choose-completion] to \
-select the completion near point.\n\n")))))
+ ;; Maybe insert help string.
+ (when completion-show-help
+ (goto-char (point-min))
+ (if (display-mouse-p)
+ (insert (substitute-command-keys
+ "Click \\[mouse-choose-completion] on a completion to select it.\n")))
+ (insert (substitute-command-keys
+ "In this buffer, type \\[choose-completion] to \
+select the completion near point.\n\n"))))))
(add-hook 'completion-setup-hook 'completion-setup-function)
(when window
(select-window window)
(goto-char (point-min))
- (search-forward "\n\n")
+ (search-forward "\n\n" nil t)
(forward-line 1))))
\f
;;; Support keyboard commands to turn on various modifiers.
(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 2.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