;;; simple.el --- basic editing commands for Emacs
-;; Copyright (C) 1985-1987, 1993-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1987, 1993-2012 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: internal
(define-minor-mode next-error-follow-minor-mode
"Minor mode for compilation, occur and diff modes.
+With a prefix argument ARG, enable mode if ARG is positive, and
+disable it otherwise. If called from Lisp, enable mode if ARG is
+omitted or nil.
When turned on, cursor motion in the compilation, grep, occur or diff
-buffer causes automatic display of the corresponding source code
-location."
+buffer causes automatic display of the corresponding source code location."
:group 'next-error :init-value nil :lighter " Fol"
(if (not next-error-follow-minor-mode)
(remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t)
Other major modes are defined by comparison with this one."
(interactive)
(kill-all-local-variables)
- (run-mode-hooks 'fundamental-mode-hook))
+ (unless delay-mode-hooks
+ (run-hooks 'after-change-major-mode-hook)))
;; Special major modes to view specially formatted data rather than files.
(defun mark-whole-buffer ()
"Put point at beginning and mark at end of buffer.
+If narrowing is in effect, only uses the accessible part of the buffer.
You probably should not use this function in Lisp programs;
it is usually a mistake for a Lisp function to use any subroutine
that uses or sets the mark."
;; Counting lines, one way or another.
(defun goto-line (line &optional buffer)
- "Goto LINE, counting from line 1 at beginning of buffer.
-Normally, move point in the current buffer, and leave mark at the
-previous position. With just \\[universal-argument] as argument,
-move point in the most recently selected other buffer, and switch to it.
+ "Go to LINE, counting from line 1 at beginning of buffer.
+If called interactively, a numeric prefix argument specifies
+LINE; without a numeric prefix argument, read LINE from the
+minibuffer.
+
+If optional argument BUFFER is non-nil, switch to that buffer and
+move to line LINE there. If called interactively with \\[universal-argument]
+as argument, BUFFER is the most recently selected other buffer.
-If there's a number in the buffer at point, it is the default for LINE.
+Prior to moving point, this function sets the mark (without
+activating it), unless Transient Mark mode is enabled and the
+mark is already active.
This function is usually the wrong thing to use in a Lisp program.
What you probably want instead is something like:
- (goto-char (point-min)) (forward-line (1- N))
+ (goto-char (point-min))
+ (forward-line (1- N))
If at all possible, an even better solution is to use char counts
rather than line counts."
(interactive
(forward-line (1- line)))))
(defun count-words-region (start end)
- "Return the number of words between START and END.
+ "Count the number of words in the region.
If called interactively, print a message reporting the number of
-lines, words, and characters in the region."
+lines, words, and chars in the region.
+If called from Lisp, return the number of words between positions
+START and END."
(interactive "r")
- (let ((words 0))
- (save-excursion
- (save-restriction
- (narrow-to-region start end)
- (goto-char (point-min))
- (while (forward-word 1)
- (setq words (1+ words)))))
- (when (called-interactively-p 'interactive)
- (count-words--message "Region"
- (count-lines start end)
- words
- (- end start)))
- words))
-
-(defun count-words ()
- "Display the number of lines, words, and characters in the buffer.
-In Transient Mark mode when the mark is active, display the
-number of lines, words, and characters in the region."
- (interactive)
- (if (use-region-p)
- (call-interactively 'count-words-region)
- (let* ((beg (point-min))
- (end (point-max))
- (lines (count-lines beg end))
- (words (count-words-region beg end))
- (chars (- end beg)))
- (count-words--message "Buffer" lines words chars))))
-
-(defun count-words--message (str lines words chars)
- (message "%s has %d line%s, %d word%s, and %d character%s."
- str
- lines (if (= lines 1) "" "s")
- words (if (= words 1) "" "s")
- chars (if (= chars 1) "" "s")))
-
-(defalias 'count-lines-region 'count-words-region)
+ (if (called-interactively-p 'any)
+ (count-words--message "Region" start end)
+ (count-words start end)))
+
+(defun count-words (start end)
+ "Count words between START and END.
+If called interactively, START and END are normally the start and
+end of the buffer; but if the region is active, START and END are
+the start and end of the region. Print a message reporting the
+number of lines, words, and chars.
+
+If called from Lisp, return the number of words between START and
+END, without printing any message."
+ (interactive (list nil nil))
+ (cond ((not (called-interactively-p 'any))
+ (let ((words 0))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (while (forward-word 1)
+ (setq words (1+ words)))))
+ words))
+ ((use-region-p)
+ (call-interactively 'count-words-region))
+ (t
+ (count-words--message "Buffer" (point-min) (point-max)))))
+
+(defun count-words--message (str start end)
+ (let ((lines (count-lines start end))
+ (words (count-words start end))
+ (chars (- end start)))
+ (message "%s has %d line%s, %d word%s, and %d character%s."
+ str
+ lines (if (= lines 1) "" "s")
+ words (if (= words 1) "" "s")
+ chars (if (= chars 1) "" "s"))))
+
+(define-obsolete-function-alias 'count-lines-region 'count-words-region "24.1")
(defun what-line ()
"Print the current buffer line number and narrowed line number of point."
in *Help* buffer. See also the command `describe-char'."
(interactive "P")
(let* ((char (following-char))
- ;; If the character is one of LRE, LRO, RLE, RLO, it will
- ;; start a directional embedding, which could completely
- ;; disrupt the rest of the line (e.g., RLO will display the
- ;; rest of the line right-to-left). So we put an invisible
- ;; PDF character after these characters, to end the
- ;; embedding, which eliminates any effects on the rest of the
- ;; line.
- (pdf (if (memq char '(?\x202a ?\x202b ?\x202d ?\x202e))
- (propertize (string ?\x202c) 'invisible t)
- ""))
+ (bidi-fixer
+ (cond ((memq char '(?\x202a ?\x202b ?\x202d ?\x202e))
+ ;; If the character is one of LRE, LRO, RLE, RLO, it
+ ;; will start a directional embedding, which could
+ ;; completely disrupt the rest of the line (e.g., RLO
+ ;; will display the rest of the line right-to-left).
+ ;; So we put an invisible PDF character after these
+ ;; characters, to end the embedding, which eliminates
+ ;; any effects on the rest of the line.
+ (propertize (string ?\x202c) 'invisible t))
+ ;; Strong right-to-left characters cause reordering of
+ ;; the following numerical characters which show the
+ ;; codepoint, so append LRM to countermand that.
+ ((memq (get-char-code-property char 'bidi-class) '(R AL))
+ (propertize (string ?\x200e) 'invisible t))
+ (t
+ "")))
(beg (point-min))
(end (point-max))
(pos (point))
(if (< char 256)
(single-key-description char)
(buffer-substring-no-properties (point) (1+ (point))))
- pdf encoding-msg pos total percent beg end col hscroll)
+ bidi-fixer
+ encoding-msg pos total percent beg end col hscroll)
(message "Char: %s%s %s point=%d of %d (%d%%) column=%d%s"
(if enable-multibyte-characters
(if (< char 128)
(single-key-description char)
(buffer-substring-no-properties (point) (1+ (point))))
(single-key-description char))
- pdf encoding-msg pos total percent col hscroll))))))
+ bidi-fixer encoding-msg pos total percent col hscroll))))))
\f
;; Initialize read-expression-map. It is defined at C level.
(let ((m (make-sparse-keymap)))
(push (eval eval-expression-arg lexical-binding) values)
(let ((old-value (make-symbol "t")) new-value)
;; Bind debug-on-error to something unique so that we can
- ;; detect when evaled code changes it.
+ ;; detect when evalled code changes it.
(let ((debug-on-error old-value))
(push (eval eval-expression-arg lexical-binding) values)
(setq new-value debug-on-error))
- ;; If evaled code has changed the value of debug-on-error,
+ ;; If evalled code has changed the value of debug-on-error,
;; propagate that change to the global binding.
(unless (eq old-value new-value)
(setq debug-on-error new-value))))
n)
;; next-matching-history-element always puts us at (point-min).
;; Move to the position we were at before changing the buffer contents.
- ;; This is still sensical, because the text before point has not changed.
+ ;; This is still sensible, because the text before point has not changed.
(goto-char point-at-start)))
(defun previous-complete-history-element (n)
"Switch used to have the shell execute its command line argument.")
(defvar shell-command-default-error-buffer nil
- "*Buffer name for `shell-command' and `shell-command-on-region' error output.
+ "Buffer name for `shell-command' and `shell-command-on-region' error output.
This buffer is used when `shell-command' or `shell-command-on-region'
is run interactively. A value of nil means that output to stderr and
stdout will be intermixed in the output stream.")
1))
1)))
;; Don't use the echo area if the output buffer is
- ;; already dispayed in the selected frame.
+ ;; already displayed in the selected frame.
(not (get-buffer-window (current-buffer))))
;; Echo area
(goto-char (point-max))
To specify a coding system for converting non-ASCII characters
in the input and output to the shell command, use \\[universal-coding-system-argument]
before this command. By default, the input (from the current buffer)
-is encoded in the same coding system that will be used to save the file,
-`buffer-file-coding-system'. If the output is going to replace the region,
-then it is decoded from that same coding system.
+is encoded using coding-system specified by `process-coding-system-alist',
+falling back to `default-process-coding-system' if no match for COMMAND
+is found in `process-coding-system-alist'.
The noninteractive arguments are START, END, COMMAND,
OUTPUT-BUFFER, REPLACE, ERROR-BUFFER, and DISPLAY-ERROR-BUFFER.
Per default, this variable is always set to `t', meaning that a
call of `process-file' could potentially change any file on a
remote host. When set to `nil', a file handler could optimize
-its behaviour with respect to remote file attributes caching.
+its behavior with respect to remote file attributes caching.
This variable should never be changed by `setq'. Instead of, it
shall be set only by let-binding.")
(tabulated-list-init-header))
(defun list-processes--refresh ()
- "Recompute the list of processes for the Process List buffer."
+ "Recompute the list of processes for the Process List buffer.
+Also, delete any process that is exited or signaled."
(setq tabulated-list-entries nil)
(dolist (p (process-list))
- (when (or (not process-menu-query-only)
- (process-query-on-exit-flag p))
- (let* ((buf (process-buffer p))
- (type (process-type p))
- (name (process-name p))
- (status (symbol-name (process-status p)))
- (buf-label (if (buffer-live-p buf)
- `(,(buffer-name buf)
- face link
- help-echo ,(concat "Visit buffer `"
- (buffer-name buf) "'")
- follow-link t
- process-buffer ,buf
- action process-menu-visit-buffer)
- "--"))
- (tty (or (process-tty-name p) "--"))
- (cmd
- (if (memq type '(network serial))
- (let ((contact (process-contact p t)))
- (if (eq type 'network)
- (format "(%s %s)"
- (if (plist-get contact :type)
- "datagram"
- "network")
- (if (plist-get contact :server)
- (format "server on %s"
- (plist-get contact :server))
- (format "connection to %s"
- (plist-get contact :host))))
- (format "(serial port %s%s)"
- (or (plist-get contact :port) "?")
- (let ((speed (plist-get contact :speed)))
- (if speed
- (format " at %s b/s" speed)
- "")))))
- (mapconcat 'identity (process-command p) " "))))
- (push (list p (vector name status buf-label tty cmd))
- tabulated-list-entries)))))
+ (cond ((memq (process-status p) '(exit signal closed))
+ (delete-process p))
+ ((or (not process-menu-query-only)
+ (process-query-on-exit-flag p))
+ (let* ((buf (process-buffer p))
+ (type (process-type p))
+ (name (process-name p))
+ (status (symbol-name (process-status p)))
+ (buf-label (if (buffer-live-p buf)
+ `(,(buffer-name buf)
+ face link
+ help-echo ,(concat "Visit buffer `"
+ (buffer-name buf) "'")
+ follow-link t
+ process-buffer ,buf
+ action process-menu-visit-buffer)
+ "--"))
+ (tty (or (process-tty-name p) "--"))
+ (cmd
+ (if (memq type '(network serial))
+ (let ((contact (process-contact p t)))
+ (if (eq type 'network)
+ (format "(%s %s)"
+ (if (plist-get contact :type)
+ "datagram"
+ "network")
+ (if (plist-get contact :server)
+ (format "server on %s"
+ (plist-get contact :server))
+ (format "connection to %s"
+ (plist-get contact :host))))
+ (format "(serial port %s%s)"
+ (or (plist-get contact :port) "?")
+ (let ((speed (plist-get contact :speed)))
+ (if speed
+ (format " at %s b/s" speed)
+ "")))))
+ (mapconcat 'identity (process-command p) " "))))
+ (push (list p (vector name status buf-label tty cmd))
+ tabulated-list-entries))))))
(defun process-menu-visit-buffer (button)
(display-buffer (button-get button 'process-buffer)))
\f
(defvar filter-buffer-substring-functions nil
- "Wrapper hook around `filter-buffer-substring'.
-The functions on this special hook are called with 4 arguments:
- NEXT-FUN BEG END DELETE
-NEXT-FUN is a function of 3 arguments (BEG END DELETE)
-that performs the default operation. The other 3 arguments are like
-the ones passed to `filter-buffer-substring'.")
+ "This variable is a wrapper hook around `filter-buffer-substring'.
+Each member of the hook should be a function accepting four arguments:
+\(FUN BEG END DELETE), where FUN is itself a function of three arguments
+\(BEG END DELETE). The arguments BEG, END, and DELETE are the same
+as those of `filter-buffer-substring' in each case.
+
+The first hook function to be called receives a FUN equivalent
+to the default operation of `filter-buffer-substring',
+i.e. one that returns the buffer-substring between BEG and
+END (processed by any `buffer-substring-filters'). Normally,
+the hook function will call FUN and then do its own processing
+of the result. The next hook function receives a FUN equivalent
+to the previous hook function, calls it, and does its own
+processing, and so on. The overall result is that of all hook
+functions acting in sequence.
+
+Any hook may choose not to call FUN though, in which case it
+effectively replaces the default behavior with whatever it chooses.
+Of course, a later hook function may do the same thing.")
(defvar buffer-substring-filters nil
"List of filter functions for `filter-buffer-substring'.
Each function must accept a single argument, a string, and return
a string. The buffer substring is passed to the first function
in the list, and the return value of each function is passed to
-the next. The return value of the last function is used as the
-return value of `filter-buffer-substring'.
+the next. The final result (if `buffer-substring-filters' is
+nil, this is the unfiltered buffer-substring) is passed to the
+first function on `filter-buffer-substring-functions'.
-If this variable is nil, no filtering is performed.")
+As a special convention, point is set to the start of the buffer text
+being operated on (i.e., the first argument of `filter-buffer-substring')
+before these functions are called.")
(make-obsolete-variable 'buffer-substring-filters
'filter-buffer-substring-functions "24.1")
(defun filter-buffer-substring (beg end &optional delete)
"Return the buffer substring between BEG and END, after filtering.
-The filtering is performed by `filter-buffer-substring-functions'.
+The wrapper hook `filter-buffer-substring-functions' performs
+the actual filtering. The obsolete variable `buffer-substring-filters'
+is also consulted. If both of these are nil, no filtering is done.
If DELETE is non-nil, the text between BEG and END is deleted
from the buffer.
:version "23.2")
(defcustom kill-do-not-save-duplicates nil
- "Do not add a new string to `kill-ring' when it is the same as the last one."
+ "Do not add a new string to `kill-ring' if it duplicates the last one.
+The comparison is done using `equal-including-properties'."
:type 'boolean
:group 'killing
:version "23.2")
(signal 'args-out-of-range
(list string "yank-handler specified for empty string"))))
(unless (and kill-do-not-save-duplicates
- (equal string (car kill-ring)))
+ ;; Due to text properties such as 'yank-handler that
+ ;; can alter the contents to yank, comparison using
+ ;; `equal' is unsafe.
+ (equal-including-properties string (car kill-ring)))
(if (fboundp 'menu-bar-update-yank-menu)
(menu-bar-update-yank-menu string (and replace (car kill-ring)))))
(when save-interprogram-paste-before-kill
(nreverse interprogram-paste)
(list interprogram-paste)))
(unless (and kill-do-not-save-duplicates
- (equal s (car kill-ring)))
+ (equal-including-properties s (car kill-ring)))
(push s kill-ring))))))
(unless (and kill-do-not-save-duplicates
- (equal string (car kill-ring)))
+ (equal-including-properties string (car kill-ring)))
(if (and replace kill-ring)
(setcar kill-ring string)
(push string kill-ring)
((eq backward-delete-char-untabify-method 'all)
" \t\n\r")))
(n (if skip
- (let ((wh (- (point) (save-excursion (skip-chars-backward skip)
- (point)))))
+ (let* ((oldpt (point))
+ (wh (- oldpt (save-excursion
+ (skip-chars-backward skip)
+ (constrain-to-field nil oldpt)))))
(+ arg (if (zerop wh) 0 (1- wh))))
arg)))
;; Avoid warning about delete-backward-char
"Kill up to and including ARGth occurrence of CHAR.
Case is ignored if `case-fold-search' is non-nil in the current buffer.
Goes backward if ARG is negative; error if CHAR not found."
- (interactive "p\ncZap to char: ")
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ (read-char "Zap to char: " t)))
;; Avoid "obsolete" warnings for translation-table-for-input.
(with-no-warnings
(if (char-table-p translation-table-for-input)
(setq char (or (aref translation-table-for-input char) char))))
(kill-region (point) (progn
(search-forward (char-to-string char) nil nil arg)
-; (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
(point))))
;; kill-line and its subroutines.
(assq prop buffer-invisibility-spec))))))
(skip-chars-forward "^\n")
(if (get-text-property (point) 'invisible)
- (goto-char (next-single-property-change (point) 'invisible))
+ (goto-char (or (next-single-property-change (point) 'invisible)
+ (point-max)))
(goto-char (next-overlay-change (point))))
(end-of-line)))
\f
(signal 'mark-inactive nil)))
(defsubst deactivate-mark (&optional force)
- "Deactivate the mark by setting `mark-active' to nil.
-Unless FORCE is non-nil, this function does nothing if Transient
-Mark mode is disabled.
-This function also runs `deactivate-mark-hook'."
+ "Deactivate the mark.
+If Transient Mark mode is disabled, this function normally does
+nothing; but if FORCE is non-nil, it deactivates the mark anyway.
+
+Deactivating the mark sets `mark-active' to nil, updates the
+primary selection according to `select-active-regions', and runs
+`deactivate-mark-hook'.
+
+If Transient Mark mode was temporarily enabled, reset the value
+of the variable `transient-mark-mode'; if this causes Transient
+Mark mode to be disabled, don't change `mark-active' to nil or
+run `deactivate-mark-hook'."
(when (or transient-mark-mode force)
(when (and (if (eq select-active-regions 'only)
(eq (car-safe transient-mark-mode) 'only)
If nil, `line-move' moves point by logical lines.
A non-nil setting of `goal-column' overrides the value of this variable
and forces movement by logical lines.
-Disabling `auto-hscroll-mode' also overrides forces movement by logical
-lines when the window is horizontally scrolled."
+A window that is horizontally scrolled also forces movement by logical
+lines."
:type 'boolean
:group 'editing-basics
:version "23.1")
(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.
+ ;; but also vscroll one line so redisplay won't recenter.
((and (> vpos 0)
(= py (min (- (window-text-height) scroll-margin 1)
(1- vpos))))
(if (and line-move-visual
;; Display-based column are incompatible with goal-column.
(not goal-column)
- ;; When auto-hscroll-mode is turned off and the text in
- ;; the window is scrolled to the left, display-based
- ;; motion doesn't make sense (because each logical line
- ;; occupies exactly one screen line).
- (not (and (null auto-hscroll-mode)
- (> (window-hscroll) 0))))
+ ;; When the text in the window is scrolled to the left,
+ ;; display-based motion doesn't make sense (because each
+ ;; logical line occupies exactly one screen line).
+ (not (> (window-hscroll) 0)))
(line-move-visual arg noerror)
(line-move-1 arg noerror to-end))))
(let ((line-move-visual nil))
(line-move (1- arg) t)))
- ;; Move to beginning-of-line, ignoring fields and invisibles.
+ ;; Move to beginning-of-line, ignoring fields and invisible text.
(skip-chars-backward "^\n")
(while (and (not (bobp)) (invisible-p (1- (point))))
(goto-char (previous-char-property-change (point)))
t)))
(defvar comment-line-break-function 'comment-indent-new-line
- "*Mode-specific function which line breaks and continues a comment.
+ "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
(defvar buffer-quit-function nil
"Function to call to \"quit\" the current buffer, or nil if none.
\\[keyboard-escape-quit] calls this function when its more local actions
-\(such as cancelling a prefix argument, minibuffer or region) do not apply.")
+\(such as canceling a prefix argument, minibuffer or region) do not apply.")
(defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
`mh-e-user-agent' -- use the Emacs interface to the MH mail system.
See Info node `(mh-e)'.
`gnus-user-agent' -- like `message-user-agent', but with Gnus
- paraphernalia, particularly the Gcc: header for
- archiving.
+ paraphernalia if Gnus is running, particularly
+ the Gcc: header for archiving.
Additional valid symbols may be available; check with the author of
your package for details. The function should return non-nil if it
With a prefix argument, set VARIABLE to VALUE buffer-locally."
(interactive
(let* ((default-var (variable-at-point))
- (var (if (user-variable-p default-var)
+ (var (if (custom-variable-p default-var)
(read-variable (format "Set variable (default %s): " default-var)
default-var)
(read-variable "Set variable: ")))
(defvar completion-list-insert-choice-function #'completion--replace
"Function to use to insert the text chosen in *Completions*.
-Called with 3 arguments (BEG END TEXT), it should replace the text
+Called with three arguments (BEG END TEXT), it should replace the text
between BEG and END with TEXT. Expected to be set buffer-locally
in the *Completions* buffer.")
choice buffer base-position nil)
;; This remove-text-properties should be unnecessary since `choice'
;; comes from buffer-substring-no-properties.
- ;;(remove-text-properties 0 (lenth choice) '(mouse-face nil) choice)
+ ;;(remove-text-properties 0 (length choice) '(mouse-face nil) choice)
;; Insert the completion into the buffer where it was requested.
(funcall (or insert-function completion-list-insert-choice-function)
(or (car base-position) (point))