;; Copyright (C) 1985-7, 1993-5, 1997 Free Software Foundation, Inc.
;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
+;; Copyright (C) 2000 Ben Wing.
;; Maintainer: XEmacs Development Team
;; Keywords: lisp, extensions, internal, dumped
;; Mule-2.3, and could probably use some feature additions (like additional wrap
;; styles, etc)
-;; 97/06/11 Steve Baur (steve@altair.xemacs.org) Convert use of
+;; 97/06/11 Steve Baur (steve@xemacs.org) Convert use of
;; (preceding|following)-char to char-(after|before).
;;; Code:
If REGEXP-FLAG is non-nil, disregard letters preceded by `\\' (but not `\\\\')
since they have special meaning in a regexp."
(let ((case-fold-search nil))
- (not (string-match (if regexp-flag
+ (not (string-match (if regexp-flag
"\\(^\\|\\\\\\\\\\|[^\\]\\)[A-Z]"
"[A-Z]")
string))
))
(defmacro with-search-caps-disable-folding (string regexp-flag &rest body) "\
-Eval BODY with `case-fold-search' let to nil if `search-caps-disable-folding'
+Eval BODY with `case-fold-search' let to nil if `search-caps-disable-folding'
is non-nil, and if STRING (either a string or a regular expression according
to REGEXP-FLAG) contains uppercase letters."
`(let ((case-fold-search
case-fold-search)))
,@body))
(put 'with-search-caps-disable-folding 'lisp-indent-function 2)
-(put 'with-search-caps-disable-folding 'edebug-form-spec
+(put 'with-search-caps-disable-folding 'edebug-form-spec
'(sexp sexp &rest form))
-(defmacro with-interactive-search-caps-disable-folding (string regexp-flag
+(defmacro with-interactive-search-caps-disable-folding (string regexp-flag
&rest body)
"Same as `with-search-caps-disable-folding', but only in the case of a
function called interactively."
`(let ((case-fold-search
- (if (and (interactive-p)
+ (if (and (interactive-p)
case-fold-search search-caps-disable-folding)
(no-upper-case-p ,string ,regexp-flag)
case-fold-search)))
,@body))
(put 'with-interactive-search-caps-disable-folding 'lisp-indent-function 2)
-(put 'with-interactive-search-caps-disable-folding 'edebug-form-spec
+(put 'with-interactive-search-caps-disable-folding 'edebug-form-spec
'(sexp sexp &rest form))
-(defun newline (&optional arg)
+(defun newline (&optional n)
"Insert a newline, and move to left margin of the new line if it's blank.
The newline is marked with the text-property `hard'.
-With arg, insert that many newlines.
+With optional arg N, insert that many newlines.
In Auto Fill mode, if no numeric arg, break the preceding line if it's long."
(interactive "*P")
(barf-if-buffer-read-only nil (point))
;; Don't auto-fill if we have a numeric argument.
;; Also not if flag is true (it would fill wrong line);
;; there is no need to since we're at BOL.
- (auto-fill-function (if (or arg flag) nil auto-fill-function)))
+ (auto-fill-function (if (or n flag) nil auto-fill-function)))
(unwind-protect
- (self-insert-command (prefix-numeric-value arg))
+ (self-insert-command (prefix-numeric-value n))
;; If we get an error in self-insert-command, put point at right place.
(if flag (forward-char 1))))
;; If we did *not* get an error, cancel that forward-char.
(if flag (backward-char 1))
;; Mark the newline(s) `hard'.
(if use-hard-newlines
- (let* ((from (- (point) (if arg (prefix-numeric-value arg) 1)))
+ (let* ((from (- (point) (if n (prefix-numeric-value n) 1)))
(sticky (get-text-property from 'end-open))) ; XEmacs
(put-text-property from (point) 'hard 't)
;; If end-open is not "t", add 'hard to end-open list
(put-text-property from (point) 'rear-nonsticky
(cons 'hard sticky)))))
-(defun open-line (arg)
+(defun open-line (n)
"Insert a newline and leave point before it.
If there is a fill prefix and/or a left-margin, insert them on the new line
if the line would have been blank.
(let* ((do-fill-prefix (and fill-prefix (bolp)))
(do-left-margin (and (bolp) (> (current-left-margin) 0)))
(loc (point)))
- (newline arg)
+ (newline n)
(goto-char loc)
- (while (> arg 0)
+ (while (> n 0)
(cond ((bolp)
(if do-left-margin (indent-to (current-left-margin)))
(if do-fill-prefix (insert fill-prefix))))
(forward-line 1)
- (setq arg (1- arg)))
+ (setq n (1- n)))
(goto-char loc)
(end-of-line)))
(save-excursion
(delete-horizontal-space)
(if (or (looking-at "^\\|\\s)")
- (save-excursion (forward-char -1)
+ (save-excursion (backward-char 1)
(looking-at "$\\|\\s(\\|\\s'")))
nil
(insert ?\ ))))
(while (and (> count 0) (not (bobp)))
(if (eq (char-before (point)) ?\t) ; XEmacs
(let ((col (current-column)))
- (forward-char -1)
+ (backward-char 1)
(setq col (- col (current-column)))
(insert-char ?\ col)
(delete-char 1)))
- (forward-char -1)
+ (backward-char 1)
(setq count (1- count)))))
(delete-backward-char arg killp)
;; XEmacs: In overwrite mode, back over columns while clearing them out,
(and overwrite-mode (not (eolp))
(save-excursion (insert-char ?\ arg))))
-(defcustom delete-key-deletes-forward nil
+(defcustom delete-key-deletes-forward t
"*If non-nil, the DEL key will erase one character forwards.
If nil, the DEL key will erase one character backwards."
:type 'boolean
:group 'editing-basics)
-(defcustom backward-delete-function 'backward-delete-char
+(defcustom backward-delete-function 'delete-backward-char
"*Function called to delete backwards on a delete keypress.
If `delete-key-deletes-forward' is nil, `backward-or-forward-delete-char'
calls this function to erase one character backwards. Default value
-is 'backward-delete-char, with 'backward-delete-char-untabify being a
+is `delete-backward-char', with `backward-delete-char-untabify' being a
popular alternate setting."
:type 'function
:group 'editing-basics)
If the buffer is narrowed, this command uses the beginning and size
of the accessible part of the buffer.
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
+
Don't use this command in Lisp programs!
\(goto-char (point-min)) is faster and avoids clobbering the mark."
;; XEmacs change
If the buffer is narrowed, this command uses the beginning and size
of the accessible part of the buffer.
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
+
Don't use this command in Lisp programs!
\(goto-char (point-max)) is faster and avoids clobbering the mark."
;; XEmacs change
cnt)))
;;; Modified by Bob Weiner, 8/24/95, to print narrowed line number also.
-;;; Expanded by Bob Weiner, Altrasoft, on 02/12/1997
+;;; Expanded by Bob Weiner, BeOpen, on 02/12/1997
(defun what-line ()
"Print the following variants of the line number of point:
Region line - displayed line within the active region
(message "Line %d" buffer-line)))))))
(setq zmacs-region-stays t))
-;;; Bob Weiner, Altrasoft, 02/12/1998
-;;; Added the 3rd arg in `count-lines' to conditionalize the counting of
-;;; collapsed lines.
+;; new in XEmacs 21.2 (not in FSF).
+(defun line-number (&optional pos respect-narrowing)
+ "Return the line number of POS (defaults to point).
+If RESPECT-NARROWING is non-nil, then the narrowed line number is returned;
+otherwise, the absolute line number is returned. The returned line can always
+be given to `goto-line' to get back to the current line."
+ (if (and pos (/= pos (point)))
+ (save-excursion
+ (goto-char pos)
+ (line-number nil respect-narrowing))
+ (1+ (count-lines (if respect-narrowing (point-min) 1) (point-at-bol)))))
+
(defun count-lines (start end &optional ignore-invisible-lines-flag)
"Return number of lines between START and END.
This is usually the number of newlines between them,
and the greater of them is not at the start of a line.
With optional IGNORE-INVISIBLE-LINES-FLAG non-nil, lines collapsed with
-selective-display are excluded from the line count."
+selective-display are excluded from the line count.
+
+NOTE: The expression to return the current line number is not obvious:
+
+(1+ (count-lines 1 (point-at-bol)))
+
+See also `line-number'."
(save-excursion
(save-restriction
(narrow-to-region start end)
(if eval-expression-insert-value (current-buffer) t)))
;; XEmacs -- extra parameter (variant, but equivalent logic)
-(defun edit-and-eval-command (prompt command &optional history)
- "Prompting with PROMPT, let user edit COMMAND and eval result.
-COMMAND is a Lisp expression. Let user edit that expression in
+(defun edit-and-eval-command (prompt form &optional history)
+ "Prompting with PROMPT, let user edit FORM and eval result.
+FORM is a Lisp expression. Let user edit that expression in
the minibuffer, then read and evaluate the result."
- (let ((command (read-expression prompt
- ;; first try to format the thing readably;
- ;; and if that fails, print it normally.
- (condition-case ()
- (let ((print-readably t))
- (prin1-to-string command))
- (error (prin1-to-string command)))
- (or history '(command-history . 1)))))
+ (let ((form (read-expression prompt
+ ;; first try to format the thing readably;
+ ;; and if that fails, print it normally.
+ (condition-case ()
+ (let ((print-readably t))
+ (prin1-to-string form))
+ (error (prin1-to-string form)))
+ (or history '(command-history . 1)))))
(or history (setq history 'command-history))
(if (consp history)
(setq history (car history)))
(if (eq history t)
nil
- ;; If command was added to the history as a string,
+ ;; If form was added to the history as a string,
;; get rid of that. We want only evallable expressions there.
(if (stringp (car (symbol-value history)))
(set history (cdr (symbol-value history))))
- ;; If command to be redone does not match front of history,
+ ;; If form to be redone does not match front of history,
;; add it to the history.
- (or (equal command (car (symbol-value history)))
- (set history (cons command (symbol-value history)))))
- (eval command)))
+ (or (equal form (car (symbol-value history)))
+ (set history (cons form (symbol-value history)))))
+ (eval form)))
(defun repeat-complex-command (arg)
"Edit and re-evaluate last complex command, or ARGth from last.
;; next-complete-history-element
;; previous-complete-history-element
\f
-(defun goto-line (arg)
- "Goto line ARG, counting from line 1 at beginning of buffer."
+(defun goto-line (line)
+ "Goto line LINE, counting from line 1 at beginning of buffer."
(interactive "NGoto line: ")
- (setq arg (prefix-numeric-value arg))
+ (setq line (prefix-numeric-value line))
(save-restriction
(widen)
(goto-char 1)
(if (eq selective-display t)
- (re-search-forward "[\n\C-m]" nil 'end (1- arg))
- (forward-line (1- arg)))))
+ (re-search-forward "[\n\C-m]" nil 'end (1- line))
+ (forward-line (1- line)))))
;Put this on C-x u, so we can force that rather than C-_ into startup msg
(define-function 'advertised-undo 'undo)
-(defun undo (&optional arg)
+(defun undo (&optional count)
"Undo some previous changes.
Repeat this command to undo more changes.
A numeric argument serves as a repeat count."
(eq (current-buffer) last-undo-buffer)) ; XEmacs
(progn (undo-start)
(undo-more 1)))
- (undo-more (or arg 1))
+ (undo-more (or count 1))
;; Don't specify a position in the undo record for the undo command.
;; Instead, undoing this should move point to where the change is.
(let ((tail buffer-undo-list)
\f
;; XEmacs -- keep zmacs-region active.
-(defun forward-to-indentation (arg)
- "Move forward ARG lines and position at first nonblank character."
+(defun forward-to-indentation (count)
+ "Move forward COUNT lines and position at first nonblank character."
(interactive "_p")
- (forward-line arg)
+ (forward-line count)
(skip-chars-forward " \t"))
-(defun backward-to-indentation (arg)
- "Move backward ARG lines and position at first nonblank character."
+(defun backward-to-indentation (count)
+ "Move backward COUNT lines and position at first nonblank character."
(interactive "_p")
- (forward-line (- arg))
+ (forward-line (- count))
(skip-chars-forward " \t"))
(defcustom kill-whole-line nil
- "*If non-nil, `kill-line' with no arg at beg of line kills the whole line."
+ "*If non-nil, kill the whole line if point is at the beginning.
+Otherwise, `kill-line' kills only up to the end of the line, but not
+the terminating newline. Note: This only applies when `kill-line' is
+called interactively.
+
+WARNING: This is a misnamed variable! It should be called something
+like `kill-whole-line-when-at-beginning'. If you simply want
+\\[kill-line] to kill the entire current line, bind it to the function
+`kill-entire-line'. "
:type 'boolean
:group 'killing)
-(defun kill-line (&optional arg)
- "Kill the rest of the current line; if no nonblanks there, kill thru newline.
-With prefix argument, kill that many lines from point.
-Negative arguments kill lines backward.
-
-When calling from a program, nil means \"no arg\",
-a number counts as a prefix arg.
-
-If `kill-whole-line' is non-nil, then kill the whole line
-when given no argument at the beginning of a line."
- (interactive "*P")
- (kill-region (point)
+(defun kill-line-1 (arg entire-line interactive-p)
+ (kill-region (if entire-line
+ (save-excursion
+ (beginning-of-line)
+ (point))
+ (point))
;; Don't shift point before doing the delete; that way,
;; undo will record the right position of point.
;; FSF
(forward-line (prefix-numeric-value arg))
(if (eobp)
(signal 'end-of-buffer nil))
- (if (or (looking-at "[ \t]*$") (and kill-whole-line (bolp)))
+ (if (or (looking-at "[ \t]*$")
+ (or entire-line
+ (and interactive-p
+ (and kill-whole-line (bolp)))))
(forward-line 1)
(end-of-line)))
(point))))
+(defun kill-entire-line (&optional arg)
+ "Kill the entire line.
+With prefix argument, kill that many lines from point. Negative
+arguments kill lines backward.
+
+When calling from a program, nil means \"no arg\",
+a number counts as a prefix arg."
+ (interactive "*P")
+ (kill-line-1 arg t (interactive-p)))
+
+(defun kill-line (&optional arg)
+ "Kill the rest of the current line, or the entire line.
+If no nonblanks there, kill thru newline. If called interactively,
+may kill the entire line when given no argument at the beginning of a
+line; see `kill-whole-line'. With prefix argument, kill that many
+lines from point. Negative arguments kill lines backward.
+
+WARNING: This is a misnamed function! It should be called something
+like `kill-to-end-of-line'. If you simply want to kill the entire
+current line, use `kill-entire-line'.
+
+When calling from a program, nil means \"no arg\",
+a number counts as a prefix arg."
+ (interactive "*P")
+ (kill-line-1 arg nil (interactive-p)))
+
;; XEmacs
(defun backward-kill-line nil
"Kill back to the beginning of the line."
;;; the cut buffers. I'm afraid to change interface of `kill-hooks',
;;; so I add it. (1997-11-03 by MORIOKA Tomohiko)
-(defvar interprogram-cut-function nil
+(defcustom interprogram-cut-function 'own-clipboard
"Function to call to make a killed region available to other programs.
Most window systems provide some sort of facility for cutting and
The first argument, TEXT, is a string containing
the text which should be made available.
The second, PUSH, if non-nil means this is a \"new\" kill;
-nil means appending to an \"old\" kill.")
+nil means appending to an \"old\" kill."
+ :type '(radio (function-item :tag "Send to Clipboard"
+ :format "%t\n"
+ own-clipboard)
+ (const :tag "None" nil)
+ (function :tag "Other"))
+ :group 'killing)
-(defvar interprogram-paste-function nil
+(defcustom interprogram-paste-function 'get-clipboard
"Function to call to get text cut from other programs.
Most window systems provide some sort of facility for cutting and
most recent string, the function should return nil. If it is
difficult to tell whether Emacs or some other program provided the
current string, it is probably good enough to return nil if the string
-is equal (according to `string=') to the last text Emacs provided.")
+is equal (according to `string=') to the last text Emacs provided."
+ :type '(radio (function-item :tag "Get from Clipboard"
+ :format "%t\n"
+ get-clipboard)
+ (const :tag "None" nil)
+ (function :tag "Other"))
+ :group 'killing)
\f
;;;; The kill ring data structure.
(defun kill-new (string &optional replace)
"Make STRING the latest kill in the kill ring.
-Set the kill-ring-yank pointer to point to it.
+Set `kill-ring-yank-pointer' to point to it.
Run `kill-hooks'.
Optional second argument REPLACE non-nil means that STRING will replace
the front of the kill ring, rather than being added to the list."
;(defvar kill-read-only-ok nil
; "*Non-nil means don't signal an error for killing read-only text.")
-(defun kill-region (beg end &optional verbose) ; verbose is XEmacs addition
+(defun kill-region (start end &optional verbose) ; verbose is XEmacs addition
"Kill between point and mark.
The text is deleted but saved in the kill ring.
The command \\[yank] can retrieve it from there.
; (prog1
; (list (point) (mark) current-prefix-arg)
; (if region-hack (zmacs-deactivate-region)))))
- ;; beg and end can be markers but the rest of this function is
+ ;; start and end can be markers but the rest of this function is
;; written as if they are only integers
- (if (markerp beg) (setq beg (marker-position beg)))
+ (if (markerp start) (setq start (marker-position start)))
(if (markerp end) (setq end (marker-position end)))
- (or (and beg end) (if zmacs-regions ;; rewritten for I18N3 snarfing
+ (or (and start end) (if zmacs-regions ;; rewritten for I18N3 snarfing
(error "The region is not active now")
(error "The mark is not set now")))
(if verbose (if buffer-read-only
(lmessage 'command "Copying %d characters"
- (- (max beg end) (min beg end)))
+ (- (max start end) (min start end)))
(lmessage 'command "Killing %d characters"
- (- (max beg end) (min beg end)))))
+ (- (max start end) (min start end)))))
(cond
;; I don't like this large change in behavior -- jwz
;; just isn't aware of this. However, there's no harm in putting
;; the region's text in the kill ring, anyway.
((or (and buffer-read-only (not inhibit-read-only))
- (text-property-not-all (min beg end) (max beg end) 'read-only nil))
+ (text-property-not-all (min start end) (max start end) 'read-only nil))
;; This is redundant.
;; (if verbose (message "Copying %d characters"
- ;; (- (max beg end) (min beg end))))
- (copy-region-as-kill beg end)
+ ;; (- (max start end) (min start end))))
+ (copy-region-as-kill start end)
;; ;; This should always barf, and give us the correct error.
;; (if kill-read-only-ok
;; (message "Read only text copied to kill ring")
((not (or (eq buffer-undo-list t)
(eq last-command 'kill-region)
;; Use = since positions may be numbers or markers.
- (= beg end)))
+ (= start end)))
;; Don't let the undo list be truncated before we can even access it.
;; FSF calls this `undo-strong-limit'
- (let ((undo-high-threshold (+ (- end beg) 100))
+ (let ((undo-high-threshold (+ (- end start) 100))
;(old-list buffer-undo-list)
tail)
- (delete-region beg end)
+ (delete-region start end)
;; Search back in buffer-undo-list for this string,
;; in case a change hook made property changes.
(setq tail buffer-undo-list)
(t
;; if undo is not kept, grab the string then delete it (which won't
;; add another string to the undo list).
- (copy-region-as-kill beg end)
- (delete-region beg end)))
+ (copy-region-as-kill start end)
+ (delete-region start end)))
(setq this-command 'kill-region))
;; copy-region-as-kill no longer sets this-command, because it's confusing
;; to get two copies of the text when the user accidentally types M-w and
;; then corrects it with the intended C-w.
-(defun copy-region-as-kill (beg end)
+(defun copy-region-as-kill (start end)
"Save the region as if killed, but don't kill it.
Run `kill-hooks'."
(interactive "r")
(if (eq last-command 'kill-region)
- (kill-append (buffer-substring beg end) (< end beg))
- (kill-new (buffer-substring beg end)))
+ (kill-append (buffer-substring start end) (< end start))
+ (kill-new (buffer-substring start end)))
nil)
-(defun kill-ring-save (beg end)
+(defun kill-ring-save (start end)
"Save the region as if killed, but don't kill it.
This command is similar to `copy-region-as-kill', except that it gives
visual feedback indicating the extent of the region being copied."
(interactive "r")
- (copy-region-as-kill beg end)
+ (copy-region-as-kill start end)
;; copy before delay, for xclipboard's benefit
(if (interactive-p)
- (let ((other-end (if (= (point) beg) end beg))
+ (let ((other-end (if (= (point) start) end start))
(opoint (point))
;; Inhibit quitting so we can make a quit here
;; look like a C-g typed as a command.
;; too noisy. -- jwz
; (let* ((killed-text (current-kill 0))
; (message-len (min (length killed-text) 40)))
-; (if (= (point) beg)
+; (if (= (point) start)
; ;; Don't say "killed"; that is misleading.
; (message "Saved text until \"%s\""
; (substring killed-text (- message-len)))
mark position to be lost.
Normally, when a new mark is set, the old one should go on the stack.
-This is why most applications should use push-mark, not set-mark.
+This is why most applications should use `push-mark', not `set-mark'.
Novice Emacs Lisp programmers often try to use the mark for the wrong
purposes. The mark saves a location for the user's convenience.
To remember a location for internal use in the Lisp program,
store it in a Lisp variable. Example:
- (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
+ (let ((start (point))) (forward-line 1) (delete-region start (point)))."
(setq buffer (decode-buffer buffer))
(set-marker (mark-marker t buffer) pos buffer))
; (set-marker (mark-marker) nil)))
(defvar mark-ring nil
- "The list of former marks of the current buffer, most recent first.")
+ "The list of former marks of the current buffer, most recent first.
+This variable is automatically buffer-local.")
(make-variable-buffer-local 'mark-ring)
(put 'mark-ring 'permanent-local t)
+(defvar dont-record-current-mark nil
+ "If set to t, the current mark value should not be recorded on the mark ring.
+This is set by commands that manipulate the mark incidentally, to avoid
+cluttering the mark ring unnecessarily. Under most circumstances, you do
+not need to set this directly; it is automatically reset each time
+`push-mark' is called, according to `mark-ring-unrecorded-commands'. This
+variable is automatically buffer-local.")
+(make-variable-buffer-local 'dont-record-current-mark)
+(put 'dont-record-current-mark 'permanent-local t)
+
+;; a conspiracy between push-mark and handle-pre-motion-command
+(defvar in-shifted-motion-command nil)
+
+(defcustom mark-ring-unrecorded-commands '(shifted-motion-commands
+ yank
+ mark-beginning-of-buffer
+ mark-bob
+ mark-defun
+ mark-end-of-buffer
+ mark-end-of-line
+ mark-end-of-sentence
+ mark-eob
+ mark-marker
+ mark-page
+ mark-paragraph
+ mark-sexp
+ mark-whole-buffer
+ mark-word)
+ "*List of commands whose marks should not be recorded on the mark stack.
+Many commands set the mark as part of their action. Normally, all such
+marks get recorded onto the mark stack. However, this tends to clutter up
+the mark stack unnecessarily. You can control this by putting a command
+onto this list. Then, any marks set by the function will not be recorded.
+
+The special value `shifted-motion-commands' causes marks set as a result
+of selection using any shifted motion commands to not be recorded.
+
+The value `yank' affects all yank-like commands, as well as just `yank'."
+ :type '(repeat (choice (const :tag "shifted motion commands"
+ shifted-motion-commands)
+ (const :tag "functions that select text"
+ :inline t
+ (mark-beginning-of-buffer
+ mark-bob
+ mark-defun
+ mark-end-of-buffer
+ mark-end-of-line
+ mark-end-of-sentence
+ mark-eob
+ mark-marker
+ mark-page
+ mark-paragraph
+ mark-sexp
+ mark-whole-buffer
+ mark-word))
+ (const :tag "functions that paste text"
+ yank)
+ function))
+ :group 'killing)
+
(defcustom mark-ring-max 16
"*Maximum size of mark ring. Start discarding off end if gets this big."
:type 'integer
With argument, jump to mark, and pop a new position for mark off the ring
\(does not affect global mark ring\).
+The mark ring is a per-buffer stack of marks, most recent first. Its
+maximum length is controlled by `mark-ring-max'. Generally, when new
+marks are set, the current mark is pushed onto the stack. You can pop
+marks off the stack using \\[universal-argument] \\[set-mark-command]. The term \"ring\" is used because when
+you pop a mark off the stack, the current mark value is pushed onto the
+far end of the stack. If this is confusing, just think of the mark ring
+as a stack.
+
Novice Emacs Lisp programmers often try to use the mark for the wrong
purposes. See the documentation of `set-mark' for more information."
(interactive "P")
(push-mark nil nil t)
(if (null (mark t))
(error "No mark set in this buffer")
+ (if dont-record-current-mark (pop-mark))
(goto-char (mark t))
(pop-mark))))
Novice Emacs Lisp programmers often try to use the mark for the wrong
purposes. See the documentation of `set-mark' for more information."
(setq buffer (decode-buffer buffer)) ; XEmacs
- (if (null (mark t buffer)) ; XEmacs
+ (if (or dont-record-current-mark (null (mark t buffer))) ; XEmacs
nil
;; The save-excursion / set-buffer is necessary because mark-ring
;; is a buffer local variable
(set-mark (or location (point buffer)) buffer)
; (set-marker (mark-marker) (or location (point)) (current-buffer)) ; FSF
;; Now push the mark on the global mark ring.
- (if (or (null global-mark-ring)
- (not (eq (marker-buffer (car global-mark-ring)) buffer)))
+ (if (and (not dont-record-current-mark)
+ (or (null global-mark-ring)
+ (not (eq (marker-buffer (car global-mark-ring)) buffer))))
;; The last global mark pushed wasn't in this same buffer.
(progn
(setq global-mark-ring (cons (copy-marker (mark-marker t buffer))
(move-marker (car (nthcdr global-mark-ring-max global-mark-ring))
nil buffer)
(setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil)))))
- (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
+ (setq dont-record-current-mark
+ (not (not (or (and in-shifted-motion-command
+ (memq 'shifted-motion-commands
+ mark-ring-unrecorded-commands))
+ (memq this-command mark-ring-unrecorded-commands)))))
+ (or dont-record-current-mark nomsg executing-kbd-macro
+ (> (minibuffer-depth) 0)
(display-message 'command "Mark set"))
(if activate-region
(progn
\f
(defcustom signal-error-on-buffer-boundary t
- "*Non-nil value causes XEmacs to beep or signal an error when certain interactive commands would move point past (point-min) or (point-max).
+ "*If Non-nil, beep or signal an error when moving past buffer boundary.
The commands that honor this variable are
forward-char-command
:type 'boolean
:group 'editing-basics)
+(defcustom shifted-motion-keys-select-region t
+ "*If non-nil, shifted motion keys select text, like in MS Windows.
+
+More specifically, if a keystroke that matches one of the key
+specifications in `motion-keys-for-shifted-motion' is pressed along
+with the Shift key, and the command invoked moves the cursor and
+preserves the active region (see `zmacs-region-stays'), the
+intervening text will be added to the active region.
+
+When the region has been enabled or augmented as a result of a shifted
+motion key, an unshifted motion key will normally deselect the region.
+However, if `unshifted-motion-keys-deselect-region' is t, the region
+will remain active, augmented by the characters moved over by this
+motion key.
+
+This functionality is specifically interpreted in terms of keys, and
+*NOT* in terms of particular commands, because that produces the most
+intuitive behavior: `forward-char' will work with shifted motion
+when invoked by `right' but not `C-f', and user-written motion commands
+bound to motion keys will automatically work with shifted motion."
+ :type 'boolean
+ :group 'editing-basics)
+
+(defcustom unshifted-motion-keys-deselect-region t
+ "*If non-nil, unshifted motion keys deselect a shifted-motion region.
+This only occurs after a region has been selected or augmented using
+shifted motion keys (not when using the traditional set-mark-then-move
+method), and has no effect if `shifted-motion-keys-select-region' is
+nil."
+ :type 'boolean
+ :group 'editing-basics)
+
+(defcustom motion-keys-for-shifted-motion
+ '(left right up down home end prior next
+ kp-left kp-right kp-up kp-down kp-home kp-end kp-prior kp-next)
+ "*List of keys considered motion keys for the purpose of shifted selection.
+When one of these keys is pressed along with the Shift key, and the
+command invoked moves the cursor and preserves the active region (see
+`zmacs-region-stays'), the intervening text will be added to the active
+region. See `shifted-motion-keys-select-region' for more details.
+
+Each entry should be a keysym or a list (MODIFIERS ... KEYSYM),
+i.e. zero or more modifiers followed by a keysym. When a keysym alone
+is given, a keystroke consisting of that keysym, with or without any
+modifiers, is considered a motion key. When the list form is given,
+only a keystroke with exactly those modifiers and no others (with the
+exception of the Shift key) is considered a motion key.
+
+NOTE: Currently, the keysym cannot be a non-alphabetic character key
+such as the `=/+' key. In any case, the shifted-motion paradigm does
+not make much sense with those keys. The keysym can, however, be an
+alphabetic key without problem, and you can specify the key using
+either a character or a symbol, uppercase or lowercase."
+ :type '(repeat (choice (const :tag "normal cursor-pad (\"gray\") keys"
+ :inline t
+ (left right up down home end prior next))
+ (const :tag "keypad motion keys"
+ :inline t
+ (kp-left kp-right kp-up kp-down
+ kp-home kp-end kp-prior kp-next))
+ (const :tag "alphabetic motion keys"
+ :inline t
+ ((control b) (control f)
+ (control p) (control n)
+ (control a) (control e)
+ (control v) (meta v)
+ (meta b) (meta f)
+ (meta a) (meta e)
+ (meta m) ; back-to-indentation
+ (meta r) ; move-to-window-line
+ (meta control b) (meta control f)
+ (meta control p) (meta control n)
+ (meta control a) (meta control e)
+ (meta control d) ;; down-list
+ (meta control u) ;; backward-up-list
+ ))
+ symbol))
+ :group 'editing-basics)
+
+(defun handle-pre-motion-command-current-command-is-motion ()
+ (and (key-press-event-p last-input-event)
+ (let ((key (event-key last-input-event))
+ (mods (delq 'shift (event-modifiers last-input-event))))
+ ;(princ (format "key: %s mods: %s\n" key mods) 'external-debugging-output)
+ (catch 'handle-pre-motion-command-current-command-is-motion
+ (flet ((keysyms-equal (a b)
+ (if (characterp a)
+ (setq a (intern (char-to-string (downcase a)))))
+ (if (characterp b)
+ (setq b (intern (char-to-string (downcase b)))))
+ (eq a b)))
+ (mapc #'(lambda (keysym)
+ (when (if (listp keysym)
+ (and (equal mods (butlast keysym))
+ (keysyms-equal key (car (last keysym))))
+ (keysyms-equal key keysym))
+ (throw
+ 'handle-pre-motion-command-current-command-is-motion
+ t)))
+ motion-keys-for-shifted-motion)
+ nil)))))
+
+(defun handle-pre-motion-command ()
+ (if (and
+ (handle-pre-motion-command-current-command-is-motion)
+ zmacs-regions
+ shifted-motion-keys-select-region
+ (not (region-active-p))
+ ;; Special-case alphabetic keysyms, because the `shift'
+ ;; modifier does not appear on them. (Unfortunately, we have no
+ ;; way of determining Shift-key status on non-alphabetic ASCII
+ ;; keysyms. However, in this case, using Shift will invoke a
+ ;; separate command from the non-shifted version, so the
+ ;; "shifted motion" paradigm makes no sense.)
+ (or (memq 'shift (event-modifiers last-input-event))
+ (let ((key (event-key last-input-event)))
+ (and (characterp key)
+ (not (eq key (downcase key)))))))
+ (let ((in-shifted-motion-command t))
+ (push-mark nil nil t))))
+
+(defun handle-post-motion-command ()
+ (if
+ (and
+ (handle-pre-motion-command-current-command-is-motion)
+ zmacs-regions
+ (region-active-p))
+ ;; Special-case alphabetic keysyms, because the `shift'
+ ;; modifier does not appear on them. See above.
+ (cond ((or (memq 'shift (event-modifiers last-input-event))
+ (let ((key (event-key last-input-event)))
+ (and (characterp key)
+ (not (eq key (downcase key))))))
+ (if shifted-motion-keys-select-region
+ (putf this-command-properties 'shifted-motion-command t))
+ (setq zmacs-region-stays t))
+ ((and (getf last-command-properties 'shifted-motion-command)
+ unshifted-motion-keys-deselect-region)
+ (setq zmacs-region-stays nil))
+ (t
+ (setq zmacs-region-stays t)))))
+
(defun forward-char-command (&optional arg buffer)
"Move point right ARG characters (left if ARG negative) in BUFFER.
On attempt to pass end of buffer, stop and signal `end-of-buffer'.
On attempt to pass beginning of buffer, stop and signal `beginning-of-buffer'.
Error signaling is suppressed if `signal-error-on-buffer-boundary'
-is nil. If BUFFER is nil, the current buffer is assumed."
+is nil. If BUFFER is nil, the current buffer is assumed.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details."
(interactive "_p")
(if signal-error-on-buffer-boundary
(forward-char arg buffer)
On attempt to pass end of buffer, stop and signal `end-of-buffer'.
On attempt to pass beginning of buffer, stop and signal `beginning-of-buffer'.
Error signaling is suppressed if `signal-error-on-buffer-boundary'
-is nil. If BUFFER is nil, the current buffer is assumed."
+is nil. If BUFFER is nil, the current buffer is assumed.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details."
(interactive "_p")
(if signal-error-on-buffer-boundary
(backward-char arg buffer)
(beginning-of-buffer nil)
(end-of-buffer nil))))
+(defun scroll-up-one ()
+ "Scroll text of current window upward one line.
+On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
+On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
+signaled.
+
+If `signal-error-on-buffer-boundary' is nil, attempts to scroll past buffer
+boundaries do not cause an error to be signaled."
+ (interactive "_")
+ (scroll-up-command 1))
+
(defun scroll-up-command (&optional n)
- "Scroll text of current window upward ARG lines; or near full screen if no ARG.
+ "Scroll current window upward N lines; or near full screen if N is nil.
A near full screen is `next-screen-context-lines' less than a full screen.
-Negative ARG means scroll downward.
+Negative N means scroll downward.
When calling from a program, supply a number as argument or nil.
On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
signaled.
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
+
If `signal-error-on-buffer-boundary' is nil, attempts to scroll past buffer
boundaries do not cause an error to be signaled."
(interactive "_P")
(beginning-of-buffer nil)
(end-of-buffer nil))))
+(defun scroll-down-one ()
+ "Scroll text of current window downward one line.
+On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
+On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
+signaled.
+
+If `signal-error-on-buffer-boundary' is nil, attempts to scroll past buffer
+boundaries do not cause an error to be signaled."
+ (interactive "_")
+ (scroll-down-command 1))
+
(defun scroll-down-command (&optional n)
- "Scroll text of current window downward ARG lines; or near full screen if no ARG.
+ "Scroll current window downward N lines; or near full screen if N is nil.
A near full screen is `next-screen-context-lines' less than a full screen.
-Negative ARG means scroll upward.
+Negative N means scroll upward.
When calling from a program, supply a number as argument or nil.
On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
signaled.
If `signal-error-on-buffer-boundary' is nil, attempts to scroll past buffer
-boundaries do not cause an error to be signaled."
+boundaries do not cause an error to be signaled.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details."
(interactive "_P")
(if signal-error-on-buffer-boundary
(scroll-down n)
(beginning-of-buffer nil)
(end-of-buffer nil))))
-(defun next-line (arg)
- "Move cursor vertically down ARG lines.
+(defun next-line (count)
+ "Move cursor vertically down COUNT lines.
If there is no character in the target line exactly under the current column,
the cursor is positioned after the character in that line which spans this
column, or at the end of the line if it is not long enough.
Then it does not try to move vertically. This goal column is stored
in `goal-column', which is nil when there is none.
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
+
If you are thinking of using this in a Lisp program, consider
using `forward-line' instead. It is usually easier to use
and more reliable (no dependence on goal column, etc.)."
- (interactive "_p") ; XEmacs
- (if (and next-line-add-newlines (= arg 1))
+ (interactive "_p")
+ (if (and next-line-add-newlines (= count 1))
(let ((opoint (point)))
(end-of-line)
(if (eobp)
(newline 1)
(goto-char opoint)
- (line-move arg)))
+ (line-move count)))
(if (interactive-p)
;; XEmacs: Not sure what to do about this. It's inconsistent. -sb
(condition-case nil
- (line-move arg)
+ (line-move count)
((beginning-of-buffer end-of-buffer)
(when signal-error-on-buffer-boundary
(ding nil 'buffer-bound))))
- (line-move arg)))
+ (line-move count)))
nil)
-(defun previous-line (arg)
- "Move cursor vertically up ARG lines.
+(defun previous-line (count)
+ "Move cursor vertically up COUNT lines.
If there is no character in the target line exactly over the current column,
the cursor is positioned after the character in that line which spans this
column, or at the end of the line if it is not long enough.
a semipermanent goal column to which this command always moves.
Then it does not try to move vertically.
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
+
If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.)."
- (interactive "_p") ; XEmacs
+ (interactive "_p")
(if (interactive-p)
(condition-case nil
- (line-move (- arg))
+ (line-move (- count))
((beginning-of-buffer end-of-buffer)
(when signal-error-on-buffer-boundary ; XEmacs
(ding nil 'buffer-bound))))
- (line-move (- arg)))
+ (line-move (- count)))
nil)
+(defcustom block-movement-size 6
+ "*Number of lines that \"block movement\" commands (\\[forward-block-of-lines], \\[backward-block-of-lines]) move by."
+ :type 'integer
+ :group 'editing-basics)
+
+(defun backward-block-of-lines ()
+ "Move backward by one \"block\" of lines.
+The number of lines that make up a block is controlled by
+`block-movement-size', which defaults to 6.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details."
+ (interactive "_")
+ (forward-line (- block-movement-size)))
+
+(defun forward-block-of-lines ()
+ "Move forward by one \"block\" of lines.
+The number of lines that make up a block is controlled by
+`block-movement-size', which defaults to 6.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details."
+ (interactive "_")
+ (forward-line block-movement-size))
+
(defcustom track-eol nil
"*Non-nil means vertical motion starting at end of line keeps to ends of lines.
This means moving to the end of each line moved onto.
:group 'editing-basics)
;; This is the guts of next-line and previous-line.
-;; Arg says how many lines to move.
-(defun line-move (arg)
+;; Count says how many lines to move.
+(defun line-move (count)
;; Don't run any point-motion hooks, and disregard intangibility,
;; for intermediate positions.
(let ((inhibit-point-motion-hooks t)
(eq last-command 'previous-line)))
(setq temporary-goal-column
(if (and track-eol (eolp)
- ;; Don't count beg of empty line as end of line
+ ;; Don't count start of empty line as end of line
;; unless we just did explicit end-of-line.
(or (not (bolp)) (eq last-command 'end-of-line)))
9999
(if (and (not (integerp selective-display))
(not line-move-ignore-invisible))
;; Use just newline characters.
- (or (if (> arg 0)
- (progn (if (> arg 1) (forward-line (1- arg)))
- ;; This way of moving forward ARG lines
+ (or (if (> count 0)
+ (progn (if (> count 1) (forward-line (1- count)))
+ ;; This way of moving forward COUNT lines
;; verifies that we have a newline after the last one.
;; It doesn't get confused by intangible text.
(end-of-line)
(zerop (forward-line 1)))
- (and (zerop (forward-line arg))
+ (and (zerop (forward-line count))
(bolp)))
- (signal (if (< arg 0)
+ (signal (if (< count 0)
'beginning-of-buffer
'end-of-buffer)
nil))
- ;; Move by arg lines, but ignore invisible ones.
- (while (> arg 0)
+ ;; Move by count lines, but ignore invisible ones.
+ (while (> count 0)
(end-of-line)
(and (zerop (vertical-motion 1))
(signal 'end-of-buffer nil))
(if (get-text-property (point) 'invisible)
(goto-char (next-single-property-change (point) 'invisible))
(goto-char (next-extent-change (point))))) ; XEmacs
- (setq arg (1- arg)))
- (while (< arg 0)
+ (setq count (1- count)))
+ (while (< count 0)
(beginning-of-line)
(and (zerop (vertical-motion -1))
(signal 'beginning-of-buffer nil))
(if (get-text-property (1- (point)) 'invisible)
(goto-char (previous-single-property-change (point) 'invisible))
(goto-char (previous-extent-change (point))))) ; XEmacs
- (setq arg (1+ arg))))
+ (setq count (1+ count))))
(move-to-column (or goal-column temporary-goal-column)))
;; Remember where we moved to, go back home,
;; then do the motion over again
;; It's not on a key, as of 20.2. So no need for this.
;(put 'set-goal-column 'disabled t)
-(defun set-goal-column (arg)
+(defun set-goal-column (column)
"Set the current horizontal position as a goal for \\[next-line] and \\[previous-line].
Those commands will move to this position in the line moved to
rather than trying to keep the same horizontal position.
so that \\[next-line] and \\[previous-line] resume vertical motion.
The goal column is stored in the variable `goal-column'."
(interactive "_P") ; XEmacs
- (if arg
+ (if column
(progn
(setq goal-column nil)
(display-message 'command "No goal column"))
(setq goal-column (current-column))
(lmessage 'command
- "Goal column %d (use %s with an arg to unset it)"
+ "Goal column %d (use %s with a prefix arg to unset it)"
goal-column
(substitute-command-keys "\\[set-goal-column]")))
nil)
and drag it forward past ARG other characters (backward if ARG negative).
If no argument and at end of line, the previous two chars are exchanged."
(interactive "*P")
- (and (null arg) (eolp) (forward-char -1))
+ (and (null arg) (eolp) (backward-char 1))
(transpose-subr 'forward-char (prefix-numeric-value arg)))
;;; A very old implementation of transpose-chars from the old days ...
and drag it forward past ARG other characters (backward if ARG negative).
If no argument and not at start of line, the previous two chars are exchanged."
(interactive "*P")
- (and (null arg) (not (bolp)) (forward-char -1))
+ (and (null arg) (not (bolp)) (backward-char 1))
(transpose-subr 'forward-char (prefix-numeric-value arg)))
(forward-line arg)))
arg))
-(eval-when-compile
- ;; avoid byte-compiler warnings...
- (defvar start1)
- (defvar start2)
- (defvar end1)
- (defvar end2))
+(defun transpose-line-up (arg)
+ "Move current line one line up, leaving point at beginning of that line.
+This can be run repeatedly to move the current line up a number of lines."
+ (interactive "*p")
+ ;; Move forward over a line,
+ ;; but create a newline if none exists yet.
+ (end-of-line)
+ (if (eobp)
+ (newline)
+ (forward-char 1))
+ (transpose-lines (- arg))
+ (forward-line -1))
+
+(defun transpose-line-down (arg)
+ "Move current line one line down, leaving point at beginning of that line.
+This can be run repeatedly to move the current line down a number of lines."
+ (interactive "*p")
+ ;; Move forward over a line,
+ ;; but create a newline if none exists yet.
+ (end-of-line)
+ (if (eobp)
+ (newline)
+ (forward-char 1))
+ (transpose-lines arg)
+ (forward-line -1))
-; start[12] and end[12] used in transpose-subr-1 below
(defun transpose-subr (mover arg)
(let (start1 end1 start2 end2)
- (if (= arg 0)
- (progn
- (save-excursion
- (funcall mover 1)
- (setq end2 (point))
- (funcall mover -1)
- (setq start2 (point))
- (goto-char (mark t)) ; XEmacs
- (funcall mover 1)
- (setq end1 (point))
- (funcall mover -1)
- (setq start1 (point))
- (transpose-subr-1))
- (exchange-point-and-mark t))) ; XEmacs
- (while (> arg 0)
- (funcall mover -1)
- (setq start1 (point))
- (funcall mover 1)
- (setq end1 (point))
- (funcall mover 1)
- (setq end2 (point))
- (funcall mover -1)
- (setq start2 (point))
- (transpose-subr-1)
- (goto-char end2)
- (setq arg (1- arg)))
- (while (< arg 0)
- (funcall mover -1)
- (setq start2 (point))
- (funcall mover -1)
- (setq start1 (point))
- (funcall mover 1)
- (setq end1 (point))
- (funcall mover 1)
- (setq end2 (point))
- (transpose-subr-1)
- (setq arg (1+ arg)))))
-
-; start[12] and end[12] used free
-(defun transpose-subr-1 ()
- (if (> (min end1 end2) (max start1 start2))
- (error "Don't have two things to transpose"))
- (let ((word1 (buffer-substring start1 end1))
- (word2 (buffer-substring start2 end2)))
- (delete-region start2 end2)
- (goto-char start2)
- (insert word1)
- (goto-char (if (< start1 start2) start1
- (+ start1 (- (length word1) (length word2)))))
- (delete-char (length word1))
- (insert word2)))
+ ;; XEmacs -- use flet instead of defining a separate function and
+ ;; relying on dynamic scope!!!
+ (flet ((transpose-subr-1 ()
+ (if (> (min end1 end2) (max start1 start2))
+ (error "Don't have two things to transpose"))
+ (let ((word1 (buffer-substring start1 end1))
+ (word2 (buffer-substring start2 end2)))
+ (delete-region start2 end2)
+ (goto-char start2)
+ (insert word1)
+ (goto-char (if (< start1 start2) start1
+ (+ start1 (- (length word1) (length word2)))))
+ (delete-char (length word1))
+ (insert word2))))
+ (if (= arg 0)
+ (progn
+ (save-excursion
+ (funcall mover 1)
+ (setq end2 (point))
+ (funcall mover -1)
+ (setq start2 (point))
+ (goto-char (mark t)) ; XEmacs
+ (funcall mover 1)
+ (setq end1 (point))
+ (funcall mover -1)
+ (setq start1 (point))
+ (transpose-subr-1))
+ (exchange-point-and-mark t))) ; XEmacs
+ (while (> arg 0)
+ (funcall mover -1)
+ (setq start1 (point))
+ (funcall mover 1)
+ (setq end1 (point))
+ (funcall mover 1)
+ (setq end2 (point))
+ (funcall mover -1)
+ (setq start2 (point))
+ (transpose-subr-1)
+ (goto-char end2)
+ (setq arg (1- arg)))
+ (while (< arg 0)
+ (funcall mover -1)
+ (setq start2 (point))
+ (funcall mover -1)
+ (setq start1 (point))
+ (funcall mover 1)
+ (setq end1 (point))
+ (funcall mover 1)
+ (setq end2 (point))
+ (transpose-subr-1)
+ (setq arg (1+ arg))))))
+
\f
(defcustom comment-column 32
"*Column to indent right-margin comments to.
:group 'fill-comments)
(defun indent-for-comment ()
- "Indent this line's comment to comment column, or insert an empty comment."
+ "Indent this line's comment to comment column, or insert an empty
+comment. Comments starting in column 0 are not moved."
(interactive "*")
(let* ((empty (save-excursion (beginning-of-line)
(looking-at "[ \t]*$")))
(skip-syntax-backward "^ " (match-beginning 0)))))
(setq begpos (point))
;; Compute desired indent.
- (if (= (current-column)
- (setq indent (funcall comment-indent-function)))
- (goto-char begpos)
+ ;; XEmacs change: Preserve indentation of comments starting in
+ ;; column 0, as documented.
+ (cond
+ ((= (current-column) 0)
+ (goto-char begpos))
+ ((= (current-column)
+ (setq indent (funcall comment-indent-function)))
+ (goto-char begpos))
+ (t
;; If that's different from current, change it.
(skip-chars-backward " \t")
(delete-region (point) begpos)
- (indent-to indent))
+ (indent-to indent)))
;; An existing comment?
(if cpos
(progn (goto-char cpos)
(defun kill-comment (arg)
"Kill the comment on this line, if any.
With argument, kill comments on that many lines starting with this one."
- ;; this function loses in a lot of situations. it incorrectly recognises
+ ;; this function loses in a lot of situations. it incorrectly recognizes
;; comment delimiters sometimes (ergo, inside a string), doesn't work
;; with multi-line comments, can kill extra whitespace if comment wasn't
;; through end-of-line, et cetera.
(if arg (forward-line 1))
(setq count (1- count)))))
-(defun comment-region (beg end &optional arg)
+(defun comment-region (start end &optional arg)
"Comment or uncomment each line in the region.
With just C-u prefix arg, uncomment each line in region.
Numeric prefix arg ARG means use ARG comment characters.
;; every line.
(interactive "r\nP")
(or comment-start (error "No comment syntax is defined"))
- (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
+ (if (> start end) (let (mid) (setq mid start start end end mid)))
(save-excursion
(save-restriction
(let ((cs comment-start) (ce comment-end)
(setq cs (concat cs comment-start)
ce (concat ce comment-end))
(setq numarg (1- numarg))))
- ;; Loop over all lines from BEG to END.
- (narrow-to-region beg end)
- (goto-char beg)
+ ;; Loop over all lines from START to END.
+ (narrow-to-region start end)
+ (goto-char start)
(while (not (eobp))
(if (or (eq numarg t) (< numarg 0))
(progn
(forward-char 1)))))
\f
-;; XEmacs - extra parameter
-(defun backward-word (arg &optional buffer)
- "Move backward until encountering the end of a word.
-With argument, do this that many times.
-In programs, it is faster to call `forward-word' with negative arg."
- (interactive "_p") ; XEmacs
- (forward-word (- arg) buffer))
-
-(defun mark-word (arg)
- "Set mark arg words away from point."
+(defun backward-word (&optional count buffer)
+ "Move point backward COUNT words (forward if COUNT is negative).
+Normally t is returned, but if an edge of the buffer is reached,
+point is left there and nil is returned.
+
+COUNT defaults to 1, and BUFFER defaults to the current buffer.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details."
+ (interactive "_p")
+ (forward-word (- (or count 1)) buffer))
+
+(defun mark-word (&optional count)
+ "Mark the text from point until encountering the end of a word.
+With optional argument COUNT, mark COUNT words."
(interactive "p")
- (mark-something 'mark-word 'forward-word arg))
+ (mark-something 'mark-word 'forward-word count))
-;; XEmacs modified
-(defun kill-word (arg)
+(defun kill-word (&optional count)
"Kill characters forward until encountering the end of a word.
-With argument, do this that many times."
+With optional argument COUNT, do this that many times."
(interactive "*p")
- (kill-region (point) (save-excursion (forward-word arg) (point))))
+ (kill-region (point) (save-excursion (forward-word count) (point))))
-(defun backward-kill-word (arg)
+(defun backward-kill-word (&optional count)
"Kill characters backward until encountering the end of a word.
With argument, do this that many times."
- (interactive "*p") ; XEmacs
- (kill-word (- arg)))
+ (interactive "*p")
+ (kill-word (- (or count 1))))
(defun current-word (&optional strict)
"Return the word point is on (or a nearby word) as a string.
bounce
;; 97/3/14 jhod: Kinsoku
(re-break-point (if (featurep 'mule)
- (concat "[ \t\n]\\|" word-across-newline)
+ (concat "[ \t\n]\\|" word-across-newline
+ ".\\|." word-across-newline)
"[ \t\n]"))
;; end patch
(first t))
(and (not (bobp))
(not bounce)
sentence-end-double-space
- (save-excursion (forward-char -1)
+ (save-excursion (backward-char 1)
(and (looking-at "\\. ")
(not (looking-at "\\. "))))))
(setq first nil)
(if (save-excursion
(skip-chars-backward " \t")
(= (point) fill-point))
+ ;; 1999-09-17 hniksic: turn off Kinsoku until
+ ;; it's debugged.
+ (funcall comment-line-break-function)
;; 97/3/14 jhod: Kinsoku processing
- ;(indent-new-comment-line)
- (let ((spacep (memq (char-before (point)) '(?\ ?\t))))
- (funcall comment-line-break-function)
- ;; if user type space explicitly, leave SPC
- ;; even if there is no WAN.
- (if spacep
- (save-excursion
- (goto-char fill-point)
- ;; put SPC except that there is SPC
- ;; already or there is sentence end.
- (or (memq (char-after (point)) '(?\ ?\t))
- (fill-end-of-sentence-p)
- (insert ?\ )))))
+; ;(indent-new-comment-line)
+; (let ((spacep (memq (char-before (point)) '(?\ ?\t))))
+; (funcall comment-line-break-function)
+; ;; if user type space explicitly, leave SPC
+; ;; even if there is no WAN.
+; (if spacep
+; (save-excursion
+; (goto-char fill-point)
+; ;; put SPC except that there is SPC
+; ;; already or there is sentence end.
+; (or (memq (char-after (point)) '(?\ ?\t))
+; (fill-end-of-sentence-p)
+; (insert ?\ )))))
(save-excursion
(goto-char fill-point)
(funcall comment-line-break-function)))
; (and (not (bobp))
; (not bounce)
; sentence-end-double-space
-; (save-excursion (forward-char -1)
+; (save-excursion (backward-char 1)
; (and (looking-at "\\. ")
; (not (looking-at "\\. "))))))
; (setq first nil)
(defun turn-on-auto-fill ()
"Unconditionally turn on Auto Fill mode."
+ (interactive)
(auto-fill-mode 1))
(defun set-fill-column (arg)
(if (and comcol (not fill-prefix)) ; XEmacs - (ENE) from fa-extras.
(let ((comment-column comcol)
(comment-start comstart)
+ (block-comment-start comstart)
(comment-end comment-end))
(and comment-end (not (equal comment-end ""))
; (if (not comment-multi-line)
(progn
- (forward-char -1)
+ (backward-char 1)
(insert comment-end)
(forward-char 1))
; (setq comment-column (+ comment-column (length comment-start))
(if (not (eolp))
(setq comment-end ""))
(insert ?\n)
- (forward-char -1)
+ (backward-char 1)
(indent-for-comment)
(save-excursion
;; Make sure we delete the newline inserted above.
(add-hook 'change-major-mode-hook 'nuke-selective-display)
-(defconst overwrite-mode-textual (purecopy " Ovwrt")
+(defconst overwrite-mode-textual " Ovwrt"
"The string displayed in the mode line when in overwrite mode.")
-(defconst overwrite-mode-binary (purecopy " Bin Ovwrt")
+(defconst overwrite-mode-binary " Bin Ovwrt"
"The string displayed in the mode line when in binary overwrite mode.")
(defun overwrite-mode (arg)
"Toggle overwrite mode.
-With arg, turn overwrite mode on iff arg is positive.
+With arg, enable overwrite mode if arg is positive, else disable.
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,
(defun binary-overwrite-mode (arg)
"Toggle binary overwrite mode.
-With arg, turn binary overwrite mode on iff arg is positive.
+With arg, enable binary overwrite mode if arg is positive, else disable.
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
(defun line-number-mode (arg)
"Toggle Line Number mode.
-With arg, turn Line Number mode on iff arg is positive.
+With arg, enable Line Number mode if arg is positive, else disable.
When Line Number mode is enabled, the line number appears
in the mode line."
(interactive "P")
(defun column-number-mode (arg)
"Toggle Column Number mode.
-With arg, turn Column Number mode on iff arg is positive.
+With arg, enable Column Number mode if arg is positive, else disable.
When Column Number mode is enabled, the column number appears
in the mode line."
(interactive "P")
;; Verify an even number of quoting characters precede the close.
(= 1 (logand 1 (- (point)
(save-excursion
- (forward-char -1)
+ (backward-char 1)
(skip-syntax-backward "/\\")
(point)))))
(let* ((oldpos (point))
;Turned off because it makes dbx bomb out.
(setq blink-paren-function 'blink-matching-open)
\f
-(eval-when-compile (defvar myhelp)) ; suppress compiler warning
;; XEmacs: Some functions moved to cmdloop.el:
;; keyboard-quit
element))
\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; mail composition code ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defcustom mail-user-agent 'sendmail-user-agent
"*Your preference for a mail composition package.
Various Emacs Lisp packages (e.g. reporter) require you to compose an
'switch-to-buffer-other-frame yank-action send-actions))
\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; set variable ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defun set-variable (var val)
"Set VARIABLE to VALUE. VALUE is a Lisp object.
When using this interactively, supply a Lisp expression for VALUE.
(let* ((var (read-variable "Set variable: "))
;; #### - yucky code replication here. This should use something
;; from help.el or hyper-apropos.el
- (minibuffer-help-form
- '(funcall myhelp))
(myhelp
#'(lambda ()
(with-output-to-temp-buffer "*Help*"
(save-excursion
(set-buffer standard-output)
(help-mode))
- nil))))
+ nil)))
+ (minibuffer-help-form
+ '(funcall myhelp)))
(list var
(let ((prop (get var 'variable-interactive)))
(if prop
(if (and (boundp var) (specifierp (symbol-value var)))
(set-specifier (symbol-value var) val)
(set var val)))
-\f
-;; XEmacs
-(defun activate-region ()
- "Activate the region, if `zmacs-regions' is true.
-Setting `zmacs-regions' to true causes LISPM-style active regions to be used.
-This function has no effect if `zmacs-regions' is false."
- (interactive)
- (and zmacs-regions (zmacs-activate-region)))
-
-;; XEmacs
-(defsubst region-exists-p ()
- "Return t if the region exists.
-If active regions are in use (i.e. `zmacs-regions' is true), this means that
- the region is active. Otherwise, this means that the user has pushed
- a mark in this buffer at some point in the past.
-The functions `region-beginning' and `region-end' can be used to find the
- limits of the region."
- (not (null (mark))))
-;; XEmacs
-(defun region-active-p ()
- "Return non-nil if the region is active.
-If `zmacs-regions' is true, this is equivalent to `region-exists-p'.
-Otherwise, this function always returns false."
- (and zmacs-regions zmacs-region-extent))
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; case changing code ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; A bunch of stuff was moved elsewhere:
;; completion-list-mode-map
(downcase-region (region-beginning) (region-end))
(downcase-word arg)))
+;; #### not localized
+(defvar uncapitalized-title-words
+ '("the" "a" "an" "in" "of" "for" "to" "and" "but" "at" "on" "as" "by"))
+
+(defvar uncapitalized-title-word-regexp
+ (concat "[ \t]*\\(" (mapconcat #'identity uncapitalized-title-words "\\|")
+ "\\)\\>"))
+
+(defun capitalize-string-as-title (string)
+ "Capitalize the words in the string, except for small words (as in titles).
+The words not capitalized are specified in `uncapitalized-title-words'."
+ (let ((buffer (get-buffer-create " *capitalize-string-as-title*")))
+ (unwind-protect
+ (progn
+ (insert-string string buffer)
+ (capitalize-region-as-title 1 (point-max buffer) buffer)
+ (buffer-string buffer))
+ (kill-buffer buffer))))
+
+(defun capitalize-region-as-title (b e &optional buffer)
+ "Capitalize the words in the region, except for small words (as in titles).
+The words not capitalized are specified in `uncapitalized-title-words'."
+ (interactive "r")
+ (save-excursion
+ (and buffer
+ (set-buffer buffer))
+ (save-restriction
+ (narrow-to-region b e)
+ (goto-char (point-min))
+ (let ((first t))
+ (while (< (point) (point-max))
+ (if (or first
+ (not (looking-at uncapitalized-title-word-regexp)))
+ (capitalize-word 1)
+ (forward-word 1))
+ (setq first nil))))))
+
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; zmacs active region code ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
;; Most of the zmacs code is now in elisp. The only thing left in C
;; are the variables zmacs-regions, zmacs-region-active-p and
;; zmacs-region-stays plus the function zmacs_update_region which
;; simply calls the lisp level zmacs-update-region. It must remain
;; for convenience, since it is called by core C code.
+;; XEmacs
+(defun activate-region ()
+ "Activate the region, if `zmacs-regions' is true.
+Setting `zmacs-regions' to true causes LISPM-style active regions to be used.
+This function has no effect if `zmacs-regions' is false."
+ (interactive)
+ (and zmacs-regions (zmacs-activate-region)))
+
+;; XEmacs
+(defsubst region-exists-p ()
+ "Return t if the region exists.
+If active regions are in use (i.e. `zmacs-regions' is true), this means that
+ the region is active. Otherwise, this means that the user has pushed
+ a mark in this buffer at some point in the past.
+The functions `region-beginning' and `region-end' can be used to find the
+ limits of the region."
+ (not (null (mark))))
+
+;; XEmacs
+(defun region-active-p ()
+ "Return non-nil if the region is active.
+If `zmacs-regions' is true, this is equivalent to `region-exists-p'.
+Otherwise, this function always returns false."
+ (and zmacs-regions zmacs-region-extent))
+
(defvar zmacs-activate-region-hook nil
"Function or functions called when the region becomes active;
see the variable `zmacs-regions'.")
(mark-marker t))))
(run-hooks 'zmacs-update-region-hook)))
-;;;;;;
-;;;;;; echo area stuff
-;;;;;;
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; message logging code ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; #### Should this be moved to a separate file, for clarity?
;;; -hniksic
;; --hniksic
(defcustom log-message-ignore-regexps
'(;; Note: adding entries to this list slows down messaging
- ;; significantly. Wherever possible, use message lables.
+ ;; significantly. Wherever possible, use message labels.
;; Often-seen messages
"\\`\\'" ; empty message
(display-message label str)
str)))
-
-;;;;;;
-;;;;;; warning stuff
-;;;;;;
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; warning code ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defcustom log-warning-minimum-level 'info
"Minimum level of warnings that should be logged.
(setq warning-marker (make-marker))
(set-marker warning-marker 1 buffer))
(if temp-buffer-show-function
- (let ((show-buffer (get-buffer-create "*Warnings-Show*")))
- (save-excursion
- (set-buffer show-buffer)
- (setq buffer-read-only nil)
- (erase-buffer))
- (save-excursion
- (set-buffer buffer)
- (copy-to-buffer show-buffer
- (marker-position warning-marker)
- (point-max)))
- (funcall temp-buffer-show-function show-buffer))
+ (progn
+ (funcall temp-buffer-show-function buffer)
+ (mapc #'(lambda (win) (set-window-start win warning-marker))
+ (windows-of-buffer buffer nil t)))
(set-window-start (display-buffer buffer) warning-marker))
(set-marker warning-marker (point-max buffer) buffer)))
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; misc junk ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defun emacs-name ()
"Return the printable name of this instance of Emacs."
(cond ((featurep 'infodock) "InfoDock")
((featurep 'xemacs) "XEmacs")
(t "Emacs")))
+(defun debug-print (format &rest args)
+ "Send a string to the debugging output.
+The string is formatted using (apply #'format FORMAT ARGS)."
+ (princ (apply #'format format args) 'external-debugging-output))
+
;;; simple.el ends here