;;; 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)
;; 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."
(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))))
"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.")
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.
(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)
(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
`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.")