;;; comint.el --- general command interpreter in a window stuff
;; Copyright (C) 1988, 1990, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
;; Author: Olin Shivers <shivers@cs.cmu.edu>
;; Simon Marshall <simon@gnu.org>
"Non-nil if you are accumulating input lines to send as input together.
The command \\[comint-accumulate] sets this.")
+(defvar comint-stored-incomplete-input nil
+ "Stored input for history cycling.")
+
(put 'comint-replace-by-expanded-history 'menu-enable 'comint-input-autoexpand)
(put 'comint-input-ring 'permanent-local t)
(put 'comint-input-ring-index 'permanent-local t)
(make-local-variable 'comint-scroll-to-bottom-on-input)
(make-local-variable 'comint-move-point-for-output)
(make-local-variable 'comint-scroll-show-maximum-output)
+ (make-local-variable 'comint-stored-incomplete-input)
;; This makes it really work to keep point at the bottom.
(make-local-variable 'scroll-conservatively)
(setq scroll-conservatively 10000)
;; for events without parameters.
(interactive (list last-input-event))
(let ((pos (point)))
- (if event (mouse-set-point event))
+ (if event (posn-set-point (event-end event)))
(if (not (eq (get-char-property (point) 'field) 'input))
;; No input at POS, fall back to the global definition.
(let* ((keys (this-command-keys))
(t
arg)))
+(defun comint-restore-input ()
+ "Restore unfinished input."
+ (interactive)
+ (when comint-input-ring-index
+ (comint-delete-input)
+ (when (> (length comint-stored-incomplete-input) 0)
+ (insert comint-stored-incomplete-input)
+ (message "Input restored"))
+ (setq comint-input-ring-index nil)))
+
(defun comint-search-start (arg)
"Index to start a directional search, starting at `comint-input-ring-index'."
(if comint-input-ring-index
arg)))
(defun comint-previous-input (arg)
- "Cycle backwards through input history."
+ "Cycle backwards through input history, saving input."
(interactive "*p")
- (comint-previous-matching-input "." arg))
+ (if (and comint-input-ring-index
+ (or ;; leaving the "end" of the ring
+ (and (< arg 0) ; going down
+ (eq comint-input-ring-index 0))
+ (and (> arg 0) ; going up
+ (eq comint-input-ring-index
+ (1- (ring-length comint-input-ring)))))
+ comint-stored-incomplete-input)
+ (comint-restore-input)
+ (comint-previous-matching-input "." arg)))
(defun comint-next-input (arg)
"Cycle forwards through input history."
(if (string-match regexp (ring-ref comint-input-ring n))
n)))
+(defun comint-delete-input ()
+ "Delete all input between accumulation or process mark and point."
+ (delete-region
+ ;; Can't use kill-region as it sets this-command
+ (or (marker-position comint-accum-marker)
+ (process-mark (get-buffer-process (current-buffer))))
+ (point-max)))
+
(defun comint-previous-matching-input (regexp n)
"Search backwards through input history for match for REGEXP.
\(Previous history elements are earlier commands.)
;; Has a match been found?
(if (null pos)
(error "Not found")
+ ;; If leaving the edit line, save partial input
+ (if (null comint-input-ring-index) ;not yet on ring
+ (setq comint-stored-incomplete-input
+ (funcall comint-get-old-input)))
(setq comint-input-ring-index pos)
(message "History item: %d" (1+ pos))
- (delete-region
- ;; Can't use kill-region as it sets this-command
- (or (marker-position comint-accum-marker)
- (process-mark (get-buffer-process (current-buffer))))
- (point))
+ (comint-delete-input)
(insert (ring-ref comint-input-ring pos)))))
(defun comint-next-matching-input (regexp n)
;; problems when `comint-prompt-read-only' is non-nil.
(let ((inhibit-read-only t))
(delete-region comint-last-input-end
- (+ comint-last-input-end echo-len))))))
+ (+ comint-last-input-end echo-len))
+ (when comint-prompt-read-only
+ (save-excursion
+ (goto-char comint-last-input-end)
+ (comint-update-fence)))))))
;; This used to call comint-output-filter-functions,
;; but that scrolled the buffer in undesirable ways.
(set-window-start (selected-window) (point))
(comint-skip-prompt))
(t
- (goto-char (field-beginning pos))
+ (let* ((beg (field-beginning pos))
+ (pt (if (= (point-min) beg)
+ (point-min)
+ (1+ beg))))
+ (goto-char pt))
(set-window-start (selected-window) (point))))))
(progn
(mouse-choose-completion first)
(set-window-configuration comint-dynamic-list-completions-config))
- (unless (eq first ?\s)
- (setq unread-command-events (listify-key-sequence key)))
- (unless (eq first ?\t)
- (set-window-configuration comint-dynamic-list-completions-config))))))
+ (if (eq first ?\s)
+ (set-window-configuration comint-dynamic-list-completions-config)
+ (setq unread-command-events (listify-key-sequence key)))))))
\f
(defun comint-get-next-from-history ()
this value.")
(defvar comint-redirect-subvert-readonly nil
- "Non-nil means comint-redirect can insert into otherwise-readonly buffers.
-The readonly status is toggled around insertion.
+ "Non-nil means `comint-redirect' can insert into read-only buffers.
+This works by binding `inhibit-read-only' around the insertion.
This is useful, for instance, for insertion into Help mode buffers.
You probably want to set it locally to the output buffer.")