- (let ((shell (file-name-nondirectory (car
- (process-command (get-buffer-process (current-buffer)))))))
- (setq comint-input-ring-file-name
- (or (getenv "HISTFILE")
- (cond ((string-equal shell "bash") "~/.bash_history")
- ((string-equal shell "ksh") "~/.sh_history")
- (t "~/.history"))))
- (if (or (equal comint-input-ring-file-name "")
- (equal (file-truename comint-input-ring-file-name)
- (file-truename "/dev/null")))
- (setq comint-input-ring-file-name nil))
- ;; Arrange to write out the input ring on exit, if the shell doesn't
- ;; do this itself.
- (if (and comint-input-ring-file-name
- (string-match shell-dumb-shell-regexp shell))
- (set-process-sentinel (get-buffer-process (current-buffer))
- #'shell-write-history-on-exit))
- (setq shell-dirstack-query
- (cond ((string-equal shell "sh") "pwd")
- ((string-equal shell "ksh") "echo $PWD ~-")
- (t "dirs"))))
- (comint-read-input-ring t))
+ (when (ring-empty-p comint-input-ring)
+ (let ((shell (file-name-nondirectory (car
+ (process-command (get-buffer-process (current-buffer)))))))
+ (setq comint-input-ring-file-name
+ (or (getenv "HISTFILE")
+ (cond ((string-equal shell "bash") "~/.bash_history")
+ ((string-equal shell "ksh") "~/.sh_history")
+ (t "~/.history"))))
+ (if (or (equal comint-input-ring-file-name "")
+ (equal (file-truename comint-input-ring-file-name)
+ (file-truename "/dev/null")))
+ (setq comint-input-ring-file-name nil))
+ ;; Arrange to write out the input ring on exit, if the shell doesn't
+ ;; do this itself.
+ (if (and comint-input-ring-file-name
+ (string-match shell-dumb-shell-regexp shell))
+ (set-process-sentinel (get-buffer-process (current-buffer))
+ #'shell-write-history-on-exit))
+ (setq shell-dirstack-query
+ (cond ((string-equal shell "sh") "pwd")
+ ((string-equal shell "ksh") "echo $PWD ~-")
+ (t "dirs")))
+ ;; Bypass a bug in certain versions of bash.
+ (when (string-equal shell "bash")
+ (add-hook 'comint-output-filter-functions
+ 'shell-filter-ctrl-a-ctrl-b nil t)))
+ (comint-read-input-ring t)))
+
+(defun shell-filter-ctrl-a-ctrl-b (string)
+ "Remove `^A' and `^B' characters from comint output.
+
+Bash uses these characters as internal quoting characters in its
+prompt. Due to a bug in some bash versions (including 2.03,
+2.04, and 2.05b), they may erroneously show up when bash is
+started with the `--noediting' option and Select Graphic
+Rendition (SGR) control sequences (formerly known as ANSI escape
+sequences) are used to color the prompt.
+
+This function can be put on `comint-output-filter-functions'.
+The argument STRING is ignored."
+ (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
+ (save-excursion
+ (goto-char (or comint-last-output-start (point-min)))
+ (while (re-search-forward "[\C-a\C-b]" pmark t)
+ (replace-match "")))))