;;; comint.el --- general command interpreter in a window stuff
-;; Copyright (C) 1988,90,92,93,94,95,96,97,98,99,2000,01,02,03,2004
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1988, 1990, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+;; 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Author: Olin Shivers <shivers@cs.cmu.edu>
;; Simon Marshall <simon@gnu.org>
(defcustom comint-prompt-read-only nil
"If non-nil, the comint prompt is read only.
+The read only region includes the newline before the prompt.
This does not affect existing prompts.
-Certain derived modes may override this option."
+Certain derived modes may override this option.
+
+If you set this option to t, then the safe way to temporarily
+override the read-only-ness of comint prompts is to call
+`comint-kill-whole-line' or `comint-kill-region' with no
+narrowing in effect. This way you will be certain that none of
+the remaining prompts will be accidentally messed up. You may
+wish to put something like the following in your `.emacs' file:
+
+\(add-hook 'comint-mode-hook
+ (lambda ()
+ (define-key comint-mode-map \"\C-w\" 'comint-kill-region)
+ (define-key comint-mode-map [C-S-backspace]
+ 'comint-kill-whole-line)))
+
+If you sometimes use comint-mode on text-only terminals or with `emacs-nw',
+you might wish to use another binding for `comint-kill-whole-line'."
:type 'boolean
:group 'comint
:version "21.4")
history list. Default is to save anything that isn't all whitespace.")
(defvar comint-input-filter-functions '()
- "Functions to call before input is sent to the process.
-These functions get one argument, a string containing the text to send.
+ "Abnormal hook run before input is sent to the process.
+These functions get one argument, a string containing the text to send.")
-You can use `add-hook' to add functions to this list
-either globally or locally.")
-
-(defvar comint-output-filter-functions '(comint-postoutput-scroll-to-bottom)
+(defvar comint-output-filter-functions '(comint-postoutput-scroll-to-bottom comint-watch-for-password-prompt)
"Functions to call after output is inserted into the buffer.
One possible function is `comint-postoutput-scroll-to-bottom'.
These functions get one argument, a string containing the text as originally
(defcustom comint-use-prompt-regexp-instead-of-fields nil
"*If non-nil, use `comint-prompt-regexp' to distinguish prompts from user-input.
If nil, then program output and user-input are given different `field'
-properties, which emacs commands can use to distinguish them (in
+properties, which Emacs commands can use to distinguish them (in
particular, common movement commands such as begining-of-line respect
field boundaries in a natural way)."
:type 'boolean
:type 'hook
:group 'comint)
-(defvar comint-mode-map nil)
+(defvar comint-mode-map
+ (let ((map (make-sparse-keymap)))
+ ;; Keys:
+ (define-key map "\ep" 'comint-previous-input)
+ (define-key map "\en" 'comint-next-input)
+ (define-key map [C-up] 'comint-previous-input)
+ (define-key map [C-down] 'comint-next-input)
+ (define-key map "\er" 'comint-previous-matching-input)
+ (define-key map "\es" 'comint-next-matching-input)
+ (define-key map [?\C-c ?\M-r] 'comint-previous-matching-input-from-input)
+ (define-key map [?\C-c ?\M-s] 'comint-next-matching-input-from-input)
+ (define-key map "\e\C-l" 'comint-show-output)
+ (define-key map "\C-m" 'comint-send-input)
+ (define-key map "\C-d" 'comint-delchar-or-maybe-eof)
+ (define-key map "\C-c " 'comint-accumulate)
+ (define-key map "\C-c\C-x" 'comint-get-next-from-history)
+ (define-key map "\C-c\C-a" 'comint-bol-or-process-mark)
+ (define-key map "\C-c\C-u" 'comint-kill-input)
+ (define-key map "\C-c\C-w" 'backward-kill-word)
+ (define-key map "\C-c\C-c" 'comint-interrupt-subjob)
+ (define-key map "\C-c\C-z" 'comint-stop-subjob)
+ (define-key map "\C-c\C-\\" 'comint-quit-subjob)
+ (define-key map "\C-c\C-m" 'comint-insert-input)
+ (define-key map "\C-c\C-o" 'comint-delete-output)
+ (define-key map "\C-c\C-r" 'comint-show-output)
+ (define-key map "\C-c\C-e" 'comint-show-maximum-output)
+ (define-key map "\C-c\C-l" 'comint-dynamic-list-input-ring)
+ (define-key map "\C-c\C-n" 'comint-next-prompt)
+ (define-key map "\C-c\C-p" 'comint-previous-prompt)
+ (define-key map "\C-c\C-d" 'comint-send-eof)
+ (define-key map "\C-c\C-s" 'comint-write-output)
+ (define-key map "\C-c." 'comint-insert-previous-argument)
+ ;; Mouse Buttons:
+ (define-key map [mouse-2] 'comint-insert-input)
+ ;; Menu bars:
+ ;; completion:
+ (define-key map [menu-bar completion]
+ (cons "Complete" (make-sparse-keymap "Complete")))
+ (define-key map [menu-bar completion complete-expand]
+ '("Expand File Name" . comint-replace-by-expanded-filename))
+ (define-key map [menu-bar completion complete-listing]
+ '("File Completion Listing" . comint-dynamic-list-filename-completions))
+ (define-key map [menu-bar completion complete-file]
+ '("Complete File Name" . comint-dynamic-complete-filename))
+ (define-key map [menu-bar completion complete]
+ '("Complete Before Point" . comint-dynamic-complete))
+ ;; Input history:
+ (define-key map [menu-bar inout]
+ (cons "In/Out" (make-sparse-keymap "In/Out")))
+ (define-key map [menu-bar inout delete-output]
+ '("Delete Current Output Group" . comint-delete-output))
+ (define-key map [menu-bar inout append-output-to-file]
+ '("Append Current Output Group to File" . comint-append-output-to-file))
+ (define-key map [menu-bar inout write-output]
+ '("Write Current Output Group to File" . comint-write-output))
+ (define-key map [menu-bar inout next-prompt]
+ '("Forward Output Group" . comint-next-prompt))
+ (define-key map [menu-bar inout previous-prompt]
+ '("Backward Output Group" . comint-previous-prompt))
+ (define-key map [menu-bar inout show-maximum-output]
+ '("Show Maximum Output" . comint-show-maximum-output))
+ (define-key map [menu-bar inout show-output]
+ '("Show Current Output Group" . comint-show-output))
+ (define-key map [menu-bar inout kill-input]
+ '("Kill Current Input" . comint-kill-input))
+ (define-key map [menu-bar inout copy-input]
+ '("Copy Old Input" . comint-insert-input))
+ (define-key map [menu-bar inout forward-matching-history]
+ '("Forward Matching Input..." . comint-forward-matching-input))
+ (define-key map [menu-bar inout backward-matching-history]
+ '("Backward Matching Input..." . comint-backward-matching-input))
+ (define-key map [menu-bar inout next-matching-history]
+ '("Next Matching Input..." . comint-next-matching-input))
+ (define-key map [menu-bar inout previous-matching-history]
+ '("Previous Matching Input..." . comint-previous-matching-input))
+ (define-key map [menu-bar inout next-matching-history-from-input]
+ '("Next Matching Current Input" . comint-next-matching-input-from-input))
+ (define-key map [menu-bar inout previous-matching-history-from-input]
+ '("Previous Matching Current Input" . comint-previous-matching-input-from-input))
+ (define-key map [menu-bar inout next-history]
+ '("Next Input" . comint-next-input))
+ (define-key map [menu-bar inout previous-history]
+ '("Previous Input" . comint-previous-input))
+ (define-key map [menu-bar inout list-history]
+ '("List Input History" . comint-dynamic-list-input-ring))
+ (define-key map [menu-bar inout expand-history]
+ '("Expand History Before Point" . comint-replace-by-expanded-history))
+ ;; Signals
+ (let ((signals-map (make-sparse-keymap "Signals")))
+ (define-key map [menu-bar signals] (cons "Signals" signals-map))
+ (define-key signals-map [eof] '("EOF" . comint-send-eof))
+ (define-key signals-map [kill] '("KILL" . comint-kill-subjob))
+ (define-key signals-map [quit] '("QUIT" . comint-quit-subjob))
+ (define-key signals-map [cont] '("CONT" . comint-continue-subjob))
+ (define-key signals-map [stop] '("STOP" . comint-stop-subjob))
+ (define-key signals-map [break] '("BREAK" . comint-interrupt-subjob)))
+ ;; Put them in the menu bar:
+ (setq menu-bar-final-items (append '(completion inout signals)
+ menu-bar-final-items))
+ map))
;; Fixme: Is this still relevant?
(defvar comint-ptyp t
;; This behavior is not useful in comint buffers, and is annoying
(set (make-local-variable 'next-line-add-newlines) nil))
-(if comint-mode-map
- nil
- ;; Keys:
- (setq comint-mode-map (make-sparse-keymap))
- (define-key comint-mode-map "\ep" 'comint-previous-input)
- (define-key comint-mode-map "\en" 'comint-next-input)
- (define-key comint-mode-map [C-up] 'comint-previous-input)
- (define-key comint-mode-map [C-down] 'comint-next-input)
- (define-key comint-mode-map "\er" 'comint-previous-matching-input)
- (define-key comint-mode-map "\es" 'comint-next-matching-input)
- (define-key comint-mode-map [?\C-c ?\M-r] 'comint-previous-matching-input-from-input)
- (define-key comint-mode-map [?\C-c ?\M-s] 'comint-next-matching-input-from-input)
- (define-key comint-mode-map "\e\C-l" 'comint-show-output)
- (define-key comint-mode-map "\C-m" 'comint-send-input)
- (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof)
- (define-key comint-mode-map "\C-c " 'comint-accumulate)
- (define-key comint-mode-map "\C-c\C-x" 'comint-get-next-from-history)
- (define-key comint-mode-map "\C-c\C-a" 'comint-bol-or-process-mark)
- (define-key comint-mode-map "\C-c\C-u" 'comint-kill-input)
- (define-key comint-mode-map "\C-c\C-w" 'backward-kill-word)
- (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob)
- (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob)
- (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob)
- (define-key comint-mode-map "\C-c\C-m" 'comint-copy-old-input)
- (define-key comint-mode-map "\C-c\C-o" 'comint-delete-output)
- (define-key comint-mode-map "\C-c\C-r" 'comint-show-output)
- (define-key comint-mode-map "\C-c\C-e" 'comint-show-maximum-output)
- (define-key comint-mode-map "\C-c\C-l" 'comint-dynamic-list-input-ring)
- (define-key comint-mode-map "\C-c\C-n" 'comint-next-prompt)
- (define-key comint-mode-map "\C-c\C-p" 'comint-previous-prompt)
- (define-key comint-mode-map "\C-c\C-d" 'comint-send-eof)
- (define-key comint-mode-map "\C-c\C-s" 'comint-write-output)
- (define-key comint-mode-map "\C-c." 'comint-insert-previous-argument)
- ;; Mouse Buttons:
- (define-key comint-mode-map [mouse-2] 'comint-insert-clicked-input)
- ;; Menu bars:
- ;; completion:
- (define-key comint-mode-map [menu-bar completion]
- (cons "Complete" (make-sparse-keymap "Complete")))
- (define-key comint-mode-map [menu-bar completion complete-expand]
- '("Expand File Name" . comint-replace-by-expanded-filename))
- (define-key comint-mode-map [menu-bar completion complete-listing]
- '("File Completion Listing" . comint-dynamic-list-filename-completions))
- (define-key comint-mode-map [menu-bar completion complete-file]
- '("Complete File Name" . comint-dynamic-complete-filename))
- (define-key comint-mode-map [menu-bar completion complete]
- '("Complete Before Point" . comint-dynamic-complete))
- ;; Input history:
- (define-key comint-mode-map [menu-bar inout]
- (cons "In/Out" (make-sparse-keymap "In/Out")))
- (define-key comint-mode-map [menu-bar inout delete-output]
- '("Delete Current Output Group" . comint-delete-output))
- (define-key comint-mode-map [menu-bar inout append-output-to-file]
- '("Append Current Output Group to File" . comint-append-output-to-file))
- (define-key comint-mode-map [menu-bar inout write-output]
- '("Write Current Output Group to File" . comint-write-output))
- (define-key comint-mode-map [menu-bar inout next-prompt]
- '("Forward Output Group" . comint-next-prompt))
- (define-key comint-mode-map [menu-bar inout previous-prompt]
- '("Backward Output Group" . comint-previous-prompt))
- (define-key comint-mode-map [menu-bar inout show-maximum-output]
- '("Show Maximum Output" . comint-show-maximum-output))
- (define-key comint-mode-map [menu-bar inout show-output]
- '("Show Current Output Group" . comint-show-output))
- (define-key comint-mode-map [menu-bar inout kill-input]
- '("Kill Current Input" . comint-kill-input))
- (define-key comint-mode-map [menu-bar inout copy-input]
- '("Copy Old Input" . comint-copy-old-input))
- (define-key comint-mode-map [menu-bar inout forward-matching-history]
- '("Forward Matching Input..." . comint-forward-matching-input))
- (define-key comint-mode-map [menu-bar inout backward-matching-history]
- '("Backward Matching Input..." . comint-backward-matching-input))
- (define-key comint-mode-map [menu-bar inout next-matching-history]
- '("Next Matching Input..." . comint-next-matching-input))
- (define-key comint-mode-map [menu-bar inout previous-matching-history]
- '("Previous Matching Input..." . comint-previous-matching-input))
- (define-key comint-mode-map [menu-bar inout next-matching-history-from-input]
- '("Next Matching Current Input" . comint-next-matching-input-from-input))
- (define-key comint-mode-map [menu-bar inout previous-matching-history-from-input]
- '("Previous Matching Current Input" . comint-previous-matching-input-from-input))
- (define-key comint-mode-map [menu-bar inout next-history]
- '("Next Input" . comint-next-input))
- (define-key comint-mode-map [menu-bar inout previous-history]
- '("Previous Input" . comint-previous-input))
- (define-key comint-mode-map [menu-bar inout list-history]
- '("List Input History" . comint-dynamic-list-input-ring))
- (define-key comint-mode-map [menu-bar inout expand-history]
- '("Expand History Before Point" . comint-replace-by-expanded-history))
- ;; Signals
- (define-key comint-mode-map [menu-bar signals]
- (cons "Signals" (make-sparse-keymap "Signals")))
- (define-key comint-mode-map [menu-bar signals eof]
- '("EOF" . comint-send-eof))
- (define-key comint-mode-map [menu-bar signals kill]
- '("KILL" . comint-kill-subjob))
- (define-key comint-mode-map [menu-bar signals quit]
- '("QUIT" . comint-quit-subjob))
- (define-key comint-mode-map [menu-bar signals cont]
- '("CONT" . comint-continue-subjob))
- (define-key comint-mode-map [menu-bar signals stop]
- '("STOP" . comint-stop-subjob))
- (define-key comint-mode-map [menu-bar signals break]
- '("BREAK" . comint-interrupt-subjob))
- ;; Put them in the menu bar:
- (setq menu-bar-final-items (append '(completion inout signals)
- menu-bar-final-items))
- )
-
(defun comint-check-proc (buffer)
"Return t if there is a living process associated w/buffer BUFFER.
Living means the status is `open', `run', or `stop'.
(set-process-coding-system proc decoding encoding))
proc))
-
-(defun comint-insert-clicked-input (event)
- "In a Comint buffer, set the current input to the clicked-on previous input."
- (interactive "e")
- (let ((pos (posn-point (event-end event))))
+(defun comint-insert-input (&optional event)
+ "In a Comint buffer, set the current input to the previous input at point."
+ (interactive "@")
+ (if event (mouse-set-point event))
+ (let ((pos (point)))
(if (not (eq (get-char-property pos 'field) 'input))
;; No input at POS, fall back to the global definition.
(let* ((keys (this-command-keys))
(or (marker-position comint-accum-marker)
(process-mark (get-buffer-process (current-buffer))))
(point))
- ;; Insert the clicked-upon input
+ ;; Insert the input at point
(insert (buffer-substring-no-properties
(previous-single-char-property-change (1+ pos) 'field)
- (next-single-char-property-change pos 'field))))))
-
+ (next-single-char-property-change pos 'field))))))
\f
;; Input history processing in a buffer
than the logical beginning of line."
(save-excursion
(let ((toend (- (line-end-position) (point)))
- (start (comint-line-beginning-position)))
+ (start (or start (comint-line-beginning-position))))
(goto-char start)
(while (progn
(skip-chars-forward "^!^" (- (line-end-position) toend))
(concat input "\n")))
(let ((beg (marker-position pmark))
- (end (if no-newline (point) (1- (point)))))
+ (end (if no-newline (point) (1- (point))))
+ (inhibit-modification-hooks t))
(when (> end beg)
;; Set text-properties for the input field
(add-text-properties
freeze its attributes in place, even when more input comes a long
and moves the prompt overlay."
(when comint-last-prompt-overlay
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t)
+ (inhibit-modification-hooks t))
(add-text-properties (overlay-start comint-last-prompt-overlay)
(overlay-end comint-last-prompt-overlay)
(overlay-properties comint-last-prompt-overlay)))))
(goto-char (process-mark process)) ; in case a filter moved it
(unless comint-use-prompt-regexp-instead-of-fields
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t)
+ (inhibit-modification-hooks t))
(add-text-properties comint-last-output-start (point)
'(rear-nonsticky t
field output
;; Highlight the prompt, where we define `prompt' to mean
;; the most recent output that doesn't end with a newline.
(let ((prompt-start (save-excursion (forward-line 0) (point)))
- (inhibit-read-only t))
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t))
(when comint-prompt-read-only
(or (= (point-min) prompt-start)
(get-text-property (1- prompt-start) 'read-only)
(1- prompt-start) prompt-start 'read-only 'fence))
(add-text-properties
prompt-start (point)
- '(read-only t rear-non-sticky t front-sticky (read-only))))
+ '(read-only t rear-nonsticky t front-sticky (read-only))))
(unless (and (bolp) (null comint-last-prompt-overlay))
;; Need to create or move the prompt overlay (in the case
;; where there is no prompt ((bolp) == t), we still do
(comint-bol)
(buffer-substring-no-properties (point) (line-end-position)))))
-(defun comint-copy-old-input ()
- "Insert after prompt old input at point as new input to be edited.
-Calls `comint-get-old-input' to get old input."
- (interactive)
- (let ((input (funcall comint-get-old-input))
- (process (get-buffer-process (current-buffer))))
- (if (not process)
- (error "Current buffer has no process")
- (goto-char (process-mark process))
- (insert input))))
-
(defun comint-skip-prompt ()
"Skip past the text matching regexp `comint-prompt-regexp'.
If this takes us past the end of the current line, don't skip at all."
;; These three functions are for entering text you don't want echoed or
;; saved -- typically passwords to ftp, telnet, or somesuch.
-;; Just enter m-x send-invisible and type in your line, or add
-;; `comint-watch-for-password-prompt' to `comint-output-filter-functions'.
-
-(defun comint-read-noecho (prompt &optional stars)
- "Read a single line of text from user without echoing, and return it.
-Prompt with argument PROMPT, a string. Optional argument STARS causes
-input to be echoed with '*' characters on the prompt line. Input ends with
-RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line. C-g aborts (if
-`inhibit-quit' is set because e.g. this function was called from a process
-filter and C-g is pressed, this function returns nil rather than a string).
-
-Note that the keystrokes comprising the text can still be recovered
-\(temporarily) with \\[view-lossage]. Some people find this worrisome (see,
-however, `clear-this-command-keys').
-Once the caller uses the password, it can erase the password
-by doing (clear-string STRING)."
- (let ((ans "")
- (newans nil)
- (c 0)
- (echo-keystrokes 0)
- (cursor-in-echo-area t)
- (message-log-max nil)
- (done nil))
- (while (not done)
- (if stars
- (message "%s%s" prompt (make-string (length ans) ?*))
- (message "%s" prompt))
- ;; Use this instead of `read-char' to avoid "Non-character input-event".
- (setq c (read-char-exclusive))
- (cond ((= c ?\C-g)
- ;; This function may get called from a process filter, where
- ;; inhibit-quit is set. In later versions of emacs read-char
- ;; may clear quit-flag itself and return C-g. That would make
- ;; it impossible to quit this loop in a simple way, so
- ;; re-enable it here (for backward-compatibility the check for
- ;; quit-flag below would still be necessary, so this seems
- ;; like the simplest way to do things).
- (setq quit-flag t
- done t))
- ((or (= c ?\r) (= c ?\n) (= c ?\e))
- (setq done t))
- ((= c ?\C-u)
- (clear-string ans)
- (setq ans ""))
- ((and (/= c ?\b) (/= c ?\177))
- (setq newans (concat ans (char-to-string c)))
- (clear-string ans)
- (setq ans newans))
- ((> (length ans) 0)
- (aset ans (1- (length ans)) 0)
- (setq ans (substring ans 0 -1)))))
- (if quit-flag
- ;; Emulate a true quit, except that we have to return a value.
- (prog1
- (setq quit-flag nil)
- (message "Quit")
- (beep t))
- (message "")
- ans)))
+;; Just enter m-x send-invisible and type in your line.
(defun send-invisible (&optional prompt)
"Read a string without echoing.
(interactive "P") ; Defeat snooping via C-x ESC ESC
(let ((proc (get-buffer-process (current-buffer))))
(if proc
- (let ((str (comint-read-noecho (or prompt "Non-echoed text: ") t)))
+ (let ((str (read-passwd (or prompt "Non-echoed text: "))))
(if (stringp str)
(progn
(comint-snapshot-last-prompt)
between the process mark and point.
WARNING: if there is no current subjob, you can end up suspending
-the top-level process running in the buffer. If you accidentally do
-this, use \\[comint-continue-subjob] to resume the process. (This
+the top-level process running in the buffer. If you accidentally do
+this, use \\[comint-continue-subjob] to resume the process. (This
is not a problem with most shells, since they ignore this signal.)"
(interactive)
(comint-skip-input)
(just-one-space)))
\f
+;; Support editing with `comint-prompt-read-only' set to t.
+
+(defun comint-update-fence ()
+ "Update read-only status of newline before point.
+The `fence' read-only property is used to indicate that a newline
+is read-only for no other reason than to \"fence off\" a
+following front-sticky read-only region. This is used to
+implement comint read-only prompts. If the text after a newline
+changes, the read-only status of that newline may need updating.
+That is what this function does.
+
+This function does nothing if point is not at the beginning of a
+line, or is at the beginning of the accessible portion of the buffer.
+Otherwise, if the character after point has a front-sticky
+read-only property, then the preceding newline is given a
+read-only property of `fence', unless it already is read-only.
+If the character after point does not have a front-sticky
+read-only property, any read-only property of `fence' on the
+preceding newline is removed."
+ (let* ((pt (point)) (lst (get-text-property pt 'front-sticky))
+ (inhibit-modification-hooks t))
+ (and (bolp)
+ (not (bobp))
+ (if (and (get-text-property pt 'read-only)
+ (if (listp lst) (memq 'read-only lst) t))
+ (unless (get-text-property (1- pt) 'read-only)
+ (put-text-property (1- pt) pt 'read-only 'fence))
+ (when (eq (get-text-property (1- pt) 'read-only) 'fence)
+ (remove-list-of-text-properties (1- pt) pt '(read-only)))))))
+
+(defun comint-kill-whole-line (&optional arg)
+ "Kill current line, ignoring read-only and field properties.
+With prefix arg, kill that many lines starting from the current line.
+If arg is negative, kill backward. Also kill the preceding newline,
+instead of the trailing one. \(This is meant to make \\[repeat] work well
+with negative arguments.)
+If arg is zero, kill current line but exclude the trailing newline.
+The read-only status of newlines is updated with `comint-update-fence',
+if necessary."
+ (interactive "p")
+ (let ((inhibit-read-only t) (inhibit-field-text-motion t))
+ (kill-whole-line arg)
+ (when (>= arg 0) (comint-update-fence))))
+
+(defun comint-kill-region (beg end &optional yank-handler)
+ "Like `kill-region', but ignores read-only properties, if safe.
+This command assumes that the buffer contains read-only
+\"prompts\" which are regions with front-sticky read-only
+properties at the beginning of a line, with the preceding newline
+being read-only to protect the prompt. This is true of the
+comint prompts if `comint-prompt-read-only' is non-nil. This
+command will not delete the region if this would create mutilated
+or out of place prompts. That is, if any part of a prompt is
+deleted, the entire prompt must be deleted and all remaining
+prompts should stay at the beginning of a line. If this is not
+the case, this command just calls `kill-region' with all
+read-only properties intact. The read-only status of newlines is
+updated using `comint-update-fence', if necessary."
+ (interactive "r")
+ (save-excursion
+ (let* ((true-beg (min beg end))
+ (true-end (max beg end))
+ (beg-bolp (progn (goto-char true-beg) (bolp)))
+ (beg-lst (get-text-property true-beg 'front-sticky))
+ (beg-bad (and (get-text-property true-beg 'read-only)
+ (if (listp beg-lst) (memq 'read-only beg-lst) t)))
+ (end-bolp (progn (goto-char true-end) (bolp)))
+ (end-lst (get-text-property true-end 'front-sticky))
+ (end-bad (and (get-text-property true-end 'read-only)
+ (if (listp end-lst) (memq 'read-only end-lst) t))))
+ (if (or (and (not beg-bolp) (or beg-bad end-bad))
+ (and (not end-bolp) end-bad))
+ (kill-region beg end yank-handler)
+ (let ((inhibit-read-only t))
+ (kill-region beg end yank-handler)
+ (comint-update-fence))))))
+
+\f
;; Support for source-file processing commands.
;;============================================================================
;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have
See `comint-source-default' for more on determining defaults.
-PROMPT is the prompt string. PREV-DIR/FILE is the (directory . file) pair
+PROMPT is the prompt string. PREV-DIR/FILE is the (DIRECTORY . FILE) pair
from the last source processing command. SOURCE-MODES is a list of major
modes used to determine what file buffers contain source files. (These
two arguments are used for determining defaults). If MUSTMATCH-P is true,
;; Read the next key, to process SPC.
(let (key first)
- (if (save-excursion
- (set-buffer (get-buffer "*Completions*"))
- (set (make-local-variable
- 'comint-displayed-dynamic-completions)
+ (if (with-current-buffer (get-buffer "*Completions*")
+ (set (make-local-variable 'comint-displayed-dynamic-completions)
completions)
(setq key (read-key-sequence nil)
first (aref key 0))
(provide 'comint)
-;;; arch-tag: 1793314c-09db-40be-9549-9aeae3e75164
+;; arch-tag: 1793314c-09db-40be-9549-9aeae3e75164
;;; comint.el ends here