(imenu-use-keymap-menu): New variable.
[bpt/emacs.git] / lisp / simple.el
index bdac6be..abe7421 100644 (file)
@@ -563,8 +563,9 @@ If N is negative, find the next or Nth next match."
                                        'minibuffer-history-search-history)))
      ;; Use the last regexp specified, by default, if input is empty.
      (list (if (string= regexp "")
-              (setcar minibuffer-history-search-history
-                      (nth 1 minibuffer-history-search-history))
+              (if minibuffer-history-search-history
+                  (car minibuffer-history-search-history)
+                (error "No previous history search regexp"))
             regexp)
           (prefix-numeric-value current-prefix-arg))))
   (let ((history (symbol-value minibuffer-history-variable))
@@ -934,6 +935,102 @@ In either case, the output is inserted after point (leaving mark after it)."
                (t 
                 (set-window-start (display-buffer buffer) 1))))))))
 \f
+(defconst universal-argument-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [t] 'universal-argument-other-key)
+    (define-key map (vector meta-prefix-char t) 'universal-argument-other-key)
+    (define-key map [switch-frame] nil)
+    (define-key map [?\C-u] 'universal-argument-more)
+    (define-key map [?-] 'universal-argument-minus)
+    (define-key map [?0] 'digit-argument)
+    (define-key map [?1] 'digit-argument)
+    (define-key map [?2] 'digit-argument)
+    (define-key map [?3] 'digit-argument)
+    (define-key map [?4] 'digit-argument)
+    (define-key map [?5] 'digit-argument)
+    (define-key map [?6] 'digit-argument)
+    (define-key map [?7] 'digit-argument)
+    (define-key map [?8] 'digit-argument)
+    (define-key map [?9] 'digit-argument)
+    map)
+  "Keymap used while processing \\[universal-argument].")
+
+(defvar universal-argument-num-events nil
+  "Number of argument-specifying events read by `universal-argument'.
+`universal-argument-other-key' uses this to discard those events
+from (this-command-keys), and reread only the final command.")
+
+(defun universal-argument ()
+  "Begin a numeric argument for the following command.
+Digits or minus sign following \\[universal-argument] make up the numeric argument.
+\\[universal-argument] following the digits or minus sign ends the argument.
+\\[universal-argument] without digits or minus sign provides 4 as argument.
+Repeating \\[universal-argument] without digits or minus sign
+ multiplies the argument by 4 each time."
+  (interactive)
+  (setq prefix-arg (list 4))
+  (setq universal-argument-num-events (length (this-command-keys)))
+  (setq overriding-terminal-local-map universal-argument-map))
+
+;; A subsequent C-u means to multiply the factor by 4 if we've typed
+;; nothing but C-u's; otherwise it means to terminate the prefix arg.
+(defun universal-argument-more (arg)
+  (interactive "P")
+  (if (consp arg)
+      (setq prefix-arg (list (* 4 (car arg))))
+    (setq prefix-arg arg)
+    (setq overriding-terminal-local-map nil))
+  (setq universal-argument-num-events (length (this-command-keys))))
+
+(defun negative-argument (arg)
+  "Begin a negative numeric argument for the next command.
+\\[universal-argument] following digits or minus sign ends the argument."
+  (interactive "P")
+  (cond ((integerp arg)
+        (setq prefix-arg (- arg)))
+       ((eq arg '-)
+        (setq prefix-arg nil))
+       (t
+        (setq prefix-arg '-)))
+  (setq universal-argument-num-events (length (this-command-keys)))
+  (setq overriding-terminal-local-map universal-argument-map))
+
+(defun digit-argument (arg)
+  "Part of the numeric argument for the next command.
+\\[universal-argument] following digits or minus sign ends the argument."
+  (interactive "P")
+  (let ((digit (- (logand last-command-char ?\177) ?0)))
+    (cond ((integerp arg)
+          (setq prefix-arg (+ (* arg 10)
+                              (if (< arg 0) (- digit) digit))))
+         ((eq arg '-)
+          ;; Treat -0 as just -, so that -01 will work.
+          (setq prefix-arg (if (zerop digit) '- (- digit))))
+         (t
+          (setq prefix-arg digit))))
+  (setq universal-argument-num-events (length (this-command-keys)))
+  (setq overriding-terminal-local-map universal-argument-map))
+
+;; For backward compatibility, minus with no modifiers is an ordinary
+;; command if digits have already been entered.
+(defun universal-argument-minus (arg)
+  (interactive "P")
+  (if (integerp arg)
+      (universal-argument-other-key arg)
+    (negative-argument arg)))
+
+;; Anything else terminates the argument and is left in the queue to be
+;; executed as a command.
+(defun universal-argument-other-key (arg)
+  (interactive "P")
+  (setq prefix-arg arg)
+  (let* ((key (this-command-keys))
+        (keylist (listify-key-sequence key)))
+    (setq unread-command-events
+         (nthcdr universal-argument-num-events keylist)))
+  (reset-this-command-lengths)
+  (setq overriding-terminal-local-map nil))
+\f
 (defun forward-to-indentation (arg)
   "Move forward ARG lines and position at first nonblank character."
   (interactive "p")
@@ -1334,13 +1431,6 @@ START and END specify the portion of the current buffer to be copied."
       (save-excursion
        (insert-buffer-substring oldbuf start end)))))
 \f
-(defvar mark-even-if-inactive nil
-  "*Non-nil means you can use the mark even when inactive.
-This option makes a difference in Transient Mark mode.
-When the option is non-nil, deactivation of the mark
-turns off region highlighting, but commands that use the mark
-behave as if the mark were still active.")
-
 (put 'mark-inactive 'error-conditions '(mark-inactive error))
 (put 'mark-inactive 'error-message "The mark is not active now")
 
@@ -1606,75 +1696,81 @@ Outline mode sets this.")
 ;; This is the guts of next-line and previous-line.
 ;; Arg says how many lines to move.
 (defun line-move (arg)
-  (let (new)
-    ;; Don't run any point-motion hooks, and disregard intangibility,
-    ;; for intermediate positions.
-    (let ((inhibit-point-motion-hooks t))
-      (save-excursion
-       (if (not (or (eq last-command 'next-line)
-                    (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
-                          ;; unless we just did explicit end-of-line.
-                          (or (not (bolp)) (eq last-command 'end-of-line)))
-                     9999
-                   (current-column))))
-       (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
-                          ;; 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))
-                      (bolp)))
-               (signal (if (< arg 0)
-                           'beginning-of-buffer
-                         'end-of-buffer)
-                       nil))
-         ;; Move by arg lines, but ignore invisible ones.
-         (while (> arg 0)
-           (end-of-line)
-           (and (zerop (vertical-motion 1))
-                (signal 'end-of-buffer nil))
-           ;; If the following character is currently invisible,
-           ;; skip all characters with that same `invisible' property value.
-           (while (and (not (eobp))
-                       (let ((prop
-                              (get-char-property (point) 'invisible)))
-                         (if (eq buffer-invisibility-spec t)
-                             prop
-                           (or (memq prop buffer-invisibility-spec)
-                               (assq prop buffer-invisibility-spec)))))
-             (if (get-text-property (point) 'invisible)
-                 (goto-char (next-single-property-change (point) 'invisible))
-               (goto-char (next-overlay-change (point)))))
-           (setq arg (1- arg)))
-         (while (< arg 0)
-           (beginning-of-line)
-           (and (zerop (vertical-motion -1))
-                (signal 'beginning-of-buffer nil))
-           (while (and (not (bobp))
-                       (let ((prop
-                              (get-char-property (1- (point)) 'invisible)))
-                         (if (eq buffer-invisibility-spec t)
-                             prop
-                           (or (memq prop buffer-invisibility-spec)
-                               (assq prop buffer-invisibility-spec)))))
-             (if (get-text-property (1- (point)) 'invisible)
-                 (goto-char (previous-single-property-change (point) 'invisible))
-               (goto-char (previous-overlay-change (point)))))
-           (setq arg (1+ arg))))
-       (move-to-column (or goal-column temporary-goal-column))
-       (setq new (point))))
-    ;; Run any point-motion hooks, deal with intangible text, etc.,
-    ;; once and for all, for the entire motion we did.
-    (goto-char new)
-    nil))
+  ;; Don't run any point-motion hooks, and disregard intangibility,
+  ;; for intermediate positions.
+  (let ((inhibit-point-motion-hooks t)
+       (opoint (point))
+       new)
+    (unwind-protect
+       (progn
+         (if (not (or (eq last-command 'next-line)
+                      (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
+                            ;; unless we just did explicit end-of-line.
+                            (or (not (bolp)) (eq last-command 'end-of-line)))
+                       9999
+                     (current-column))))
+         (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
+                            ;; 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))
+                        (bolp)))
+                 (signal (if (< arg 0)
+                             'beginning-of-buffer
+                           'end-of-buffer)
+                         nil))
+           ;; Move by arg lines, but ignore invisible ones.
+           (while (> arg 0)
+             (end-of-line)
+             (and (zerop (vertical-motion 1))
+                  (signal 'end-of-buffer nil))
+             ;; If the following character is currently invisible,
+             ;; skip all characters with that same `invisible' property value.
+             (while (and (not (eobp))
+                         (let ((prop
+                                (get-char-property (point) 'invisible)))
+                           (if (eq buffer-invisibility-spec t)
+                               prop
+                             (or (memq prop buffer-invisibility-spec)
+                                 (assq prop buffer-invisibility-spec)))))
+               (if (get-text-property (point) 'invisible)
+                   (goto-char (next-single-property-change (point) 'invisible))
+                 (goto-char (next-overlay-change (point)))))
+             (setq arg (1- arg)))
+           (while (< arg 0)
+             (beginning-of-line)
+             (and (zerop (vertical-motion -1))
+                  (signal 'beginning-of-buffer nil))
+             (while (and (not (bobp))
+                         (let ((prop
+                                (get-char-property (1- (point)) 'invisible)))
+                           (if (eq buffer-invisibility-spec t)
+                               prop
+                             (or (memq prop buffer-invisibility-spec)
+                                 (assq prop buffer-invisibility-spec)))))
+               (if (get-text-property (1- (point)) 'invisible)
+                   (goto-char (previous-single-property-change (point) 'invisible))
+                 (goto-char (previous-overlay-change (point)))))
+             (setq arg (1+ arg))))
+         (move-to-column (or goal-column temporary-goal-column)))
+      ;; Remember where we moved to, go back home,
+      ;; then do the motion over again
+      ;; in just one step, with intangibility and point-motion hooks
+      ;; enabled this time.
+      (setq new (point))
+      (goto-char opoint)
+      (setq inhibit-point-motion-hooks nil)
+      (goto-char new)))
+  nil)
 
 ;;; Many people have said they rarely use this feature, and often type
 ;;; it by accident.  Maybe it shouldn't even be on a key.
@@ -1985,7 +2081,6 @@ If nil, use `comment-end' instead.")
 (defun indent-for-comment ()
   "Indent this line's comment to comment column, or insert an empty comment."
   (interactive "*")
-  (beginning-of-line 1)
   (let* ((empty (save-excursion (beginning-of-line)
                                (looking-at "[ \t]*$")))
         (starter (or (and empty block-comment-start) comment-start))
@@ -1994,6 +2089,7 @@ If nil, use `comment-end' instead.")
        (error "No comment syntax defined")
       (let* ((eolpos (save-excursion (end-of-line) (point)))
             cpos indent begpos)
+       (beginning-of-line)
        (if (re-search-forward comment-start-skip eolpos 'move)
            (progn (setq cpos (point-marker))
                   ;; Find the start of the comment delimiter.
@@ -2314,8 +2410,7 @@ automatically breaks the line at a previous space."
                       (> (prefix-numeric-value arg) 0))
                   'do-auto-fill
                   nil))
-    ;; update mode-line
-    (set-buffer-modified-p (buffer-modified-p))))
+    (force-mode-line-update)))
 
 ;; This holds a document string used to document auto-fill-mode.
 (defun auto-fill-function ()