Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / lisp / eshell / esh-mode.el
index e8f6a98..7432053 100644 (file)
@@ -1,7 +1,6 @@
 ;;; esh-mode.el --- user interface
 
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2012  Free Software Foundation, Inc.
 
 ;; Author: John Wiegley <johnw@gnu.org>
 
@@ -57,6 +56,8 @@
 ;;
 ;; @ <C-c C-b> will move backward a complete shell argument.
 
+;;; Code:
+
 (provide 'esh-mode)
 
 (eval-when-compile (require 'esh-util))
 ;;; User Variables:
 
 (defcustom eshell-mode-unload-hook nil
-  "*A hook that gets run when `eshell-mode' is unloaded."
+  "A hook that gets run when `eshell-mode' is unloaded."
   :type 'hook
   :group 'eshell-mode)
 
 (defcustom eshell-mode-hook nil
-  "*A hook that gets run when `eshell-mode' is entered."
+  "A hook that gets run when `eshell-mode' is entered."
   :type 'hook
   :group 'eshell-mode)
 
 (defcustom eshell-first-time-mode-hook nil
-  "*A hook that gets run the first time `eshell-mode' is entered.
+  "A hook that gets run the first time `eshell-mode' is entered.
 That is to say, the first time during an Emacs session."
   :type 'hook
   :group 'eshell-mode)
 
-(defcustom eshell-exit-hook '(eshell-query-kill-processes)
-  "*A hook that is run whenever `eshell' is exited.
+(defcustom eshell-exit-hook nil
+  "A hook that is run whenever `eshell' is exited.
 This hook is only run if exiting actually kills the buffer."
+  :version "24.1"                       ; removed eshell-query-kill-processes
   :type 'hook
   :group 'eshell-mode)
 
 (defcustom eshell-kill-on-exit t
-  "*If non-nil, kill the Eshell buffer on the `exit' command.
+  "If non-nil, kill the Eshell buffer on the `exit' command.
 Otherwise, the buffer will simply be buried."
   :type 'boolean
   :group 'eshell-mode)
 
 (defcustom eshell-input-filter-functions nil
-  "*Functions to call before input is processed.
+  "Functions to call before input is processed.
 The input is contained in the region from `eshell-last-input-start' to
 `eshell-last-input-end'."
   :type 'hook
   :group 'eshell-mode)
 
 (defcustom eshell-send-direct-to-subprocesses nil
-  "*If t, send any input immediately to a subprocess."
+  "If t, send any input immediately to a subprocess."
   :type 'boolean
   :group 'eshell-mode)
 
 (defcustom eshell-expand-input-functions nil
-  "*Functions to call before input is parsed.
+  "Functions to call before input is parsed.
 Each function is passed two arguments, which bounds the region of the
 current input text."
   :type 'hook
   :group 'eshell-mode)
 
 (defcustom eshell-scroll-to-bottom-on-input nil
-  "*Controls whether input to interpreter causes window to scroll.
+  "Controls whether input to interpreter causes window to scroll.
 If nil, then do not scroll.  If t or `all', scroll all windows showing
 buffer.  If `this', scroll only the selected window.
 
@@ -131,7 +133,7 @@ See `eshell-preinput-scroll-to-bottom'."
   :group 'eshell-mode)
 
 (defcustom eshell-scroll-to-bottom-on-output nil
-  "*Controls whether interpreter output causes window to scroll.
+  "Controls whether interpreter output causes window to scroll.
 If nil, then do not scroll.  If t or `all', scroll all windows showing
 buffer.  If `this', scroll only the selected window.  If `others',
 scroll only those that are not the selected window.
@@ -145,7 +147,7 @@ See variable `eshell-scroll-show-maximum-output' and function
   :group 'eshell-mode)
 
 (defcustom eshell-scroll-show-maximum-output t
-  "*Controls how interpreter output causes window to scroll.
+  "Controls how interpreter output causes window to scroll.
 If non-nil, then show the maximum output when the window is scrolled.
 
 See variable `eshell-scroll-to-bottom-on-output' and function
@@ -154,7 +156,7 @@ See variable `eshell-scroll-to-bottom-on-output' and function
   :group 'eshell-mode)
 
 (defcustom eshell-buffer-maximum-lines 1024
-  "*The maximum size in lines for eshell buffers.
+  "The maximum size in lines for eshell buffers.
 Eshell buffers are truncated from the top to be no greater than this
 number, if the function `eshell-truncate-buffer' is on
 `eshell-output-filter-functions'."
@@ -164,15 +166,16 @@ number, if the function `eshell-truncate-buffer' is on
 (defcustom eshell-output-filter-functions
   '(eshell-postoutput-scroll-to-bottom
     eshell-handle-control-codes
+    eshell-handle-ansi-color
     eshell-watch-for-password-prompt)
-  "*Functions to call before output is displayed.
+  "Functions to call before output is displayed.
 These functions are only called for output that is displayed
 interactively, and not for output which is redirected."
   :type 'hook
   :group 'eshell-mode)
 
 (defcustom eshell-preoutput-filter-functions nil
-  "*Functions to call before output is inserted into the buffer.
+  "Functions to call before output is inserted into the buffer.
 These functions get one argument, a string containing the text to be
 inserted.  They return the string as it should be inserted."
   :type 'hook
@@ -180,18 +183,18 @@ inserted.  They return the string as it should be inserted."
 
 (defcustom eshell-password-prompt-regexp
   "[Pp]ass\\(word\\|phrase\\).*:\\s *\\'"
-  "*Regexp matching prompts for passwords in the inferior process.
+  "Regexp matching prompts for passwords in the inferior process.
 This is used by `eshell-watch-for-password-prompt'."
   :type 'regexp
   :group 'eshell-mode)
 
 (defcustom eshell-skip-prompt-function nil
-  "*A function called from beginning of line to skip the prompt."
+  "A function called from beginning of line to skip the prompt."
   :type '(choice (const nil) function)
   :group 'eshell-mode)
 
 (defcustom eshell-status-in-modeline t
-  "*If non-nil, let the user know a command is running in the modeline."
+  "If non-nil, let the user know a command is running in the modeline."
   :type 'boolean
   :group 'eshell-mode)
 
@@ -285,6 +288,17 @@ This is used by `eshell-watch-for-password-prompt'."
 
 ;;; User Functions:
 
+(defun eshell-kill-buffer-function ()
+  "Function added to `kill-buffer-hook' in Eshell buffers.
+This runs the function `eshell-kill-processes-on-exit',
+and the hook `eshell-exit-hook'."
+  ;; It's fine to run this unconditionally since it can be customized
+  ;; via the `eshell-kill-processes-on-exit' variable.
+  (and (fboundp 'eshell-query-kill-processes)
+       (not (memq 'eshell-query-kill-processes eshell-exit-hook))
+       (eshell-query-kill-processes))
+  (run-hooks 'eshell-exit-hook))
+
 ;;;###autoload
 (defun eshell-mode ()
   "Emacs shell interactive mode.
@@ -315,6 +329,7 @@ This is used by `eshell-watch-for-password-prompt'."
   (define-key eshell-mode-map [(meta return)] 'eshell-queue-input)
   (define-key eshell-mode-map [(meta control ?m)] 'eshell-queue-input)
   (define-key eshell-mode-map [(meta control ?l)] 'eshell-show-output)
+  (define-key eshell-mode-map [(control ?a)] 'eshell-bol)
 
   (set (make-local-variable 'eshell-command-prefix)
        (make-symbol "eshell-command-prefix"))
@@ -386,7 +401,7 @@ This is used by `eshell-watch-for-password-prompt'."
   ;; load extension modules into memory.  This will cause any global
   ;; variables they define to be visible, since some of the core
   ;; modules sometimes take advantage of their functionality if used.
-  (eshell-for module eshell-modules-list
+  (dolist (module eshell-modules-list)
     (let ((module-fullname (symbol-name module))
          module-shortname)
       (if (string-match "^eshell-\\(.*\\)" module-fullname)
@@ -400,17 +415,15 @@ This is used by `eshell-watch-for-password-prompt'."
   (unless (file-exists-p eshell-directory-name)
     (eshell-make-private-directory eshell-directory-name t))
 
-  ;; load core Eshell modules for this session
-  (eshell-for module (eshell-subgroups 'eshell)
-    (run-hooks (intern-soft (concat (symbol-name module)
-                                   "-load-hook"))))
-
-  ;; load extension modules for this session
-  (eshell-for module eshell-modules-list
-    (let ((load-hook (intern-soft (concat (symbol-name module)
-                                         "-load-hook"))))
-      (if (and load-hook (boundp load-hook))
-         (run-hooks load-hook))))
+  ;; Load core Eshell modules, then extension modules, for this session.
+  (dolist (module (append (eshell-subgroups 'eshell) eshell-modules-list))
+    (let ((load-hook (intern-soft (format "%s-load-hook" module)))
+          (initfunc (intern-soft (format "%s-initialize" module))))
+      (when (and load-hook (boundp load-hook))
+        (if (memq initfunc (symbol-value load-hook)) (setq initfunc nil))
+        (run-hooks load-hook))
+      ;; So we don't need the -initialize functions on the hooks (b#5375).
+      (and initfunc (fboundp initfunc) (funcall initfunc))))
 
   (if eshell-send-direct-to-subprocesses
       (add-hook 'pre-command-hook 'eshell-intercept-commands t t))
@@ -425,10 +438,7 @@ This is used by `eshell-watch-for-password-prompt'."
     (add-hook 'eshell-pre-command-hook 'eshell-command-started nil t)
     (add-hook 'eshell-post-command-hook 'eshell-command-finished nil t))
 
-  (add-hook 'kill-buffer-hook
-           (function
-            (lambda ()
-              (run-hooks 'eshell-exit-hook))) t t)
+  (add-hook 'kill-buffer-hook 'eshell-kill-buffer-function t t)
 
   (if eshell-first-time-p
       (run-hooks 'eshell-first-time-mode-hook))
@@ -437,19 +447,6 @@ This is used by `eshell-watch-for-password-prompt'."
 
 (put 'eshell-mode 'mode-class 'special)
 
-(eshell-deftest mode major-mode
-  "Major mode is correct"
-  (eq major-mode 'eshell-mode))
-
-(eshell-deftest mode eshell-mode-variable
-  "`eshell-mode' is true"
-  (eq eshell-mode t))
-
-(eshell-deftest var window-height
-  "LINES equals window height"
-  (let ((eshell-stringify-t t))
-    (eshell-command-result-p "= $LINES (window-height)" "t\n")))
-
 (defun eshell-command-started ()
   "Indicate in the modeline that a command has started."
   (setq eshell-command-running-string "**")
@@ -460,13 +457,6 @@ This is used by `eshell-watch-for-password-prompt'."
   (setq eshell-command-running-string "--")
   (force-mode-line-update))
 
-(eshell-deftest mode command-running-p
-  "Modeline shows no command running"
-  (or (featurep 'xemacs)
-      (not eshell-status-in-modeline)
-      (and (memq 'eshell-command-running-string mode-line-format)
-          (equal eshell-command-running-string "--"))))
-
 ;;; Internal Functions:
 
 (defun eshell-toggle-direct-send ()
@@ -484,9 +474,9 @@ This is used by `eshell-watch-for-password-prompt'."
   (interactive "i")
   (process-send-string
    (eshell-interactive-process)
-   (char-to-string (if (symbolp last-command-char)
-                      (get last-command-char 'ascii-character)
-                    last-command-char))))
+   (char-to-string (if (symbolp last-command-event)
+                      (get last-command-event 'ascii-character)
+                    last-command-event))))
 
 (defun eshell-intercept-commands ()
   (when (and (eshell-interactive-process)
@@ -507,6 +497,8 @@ This is used by `eshell-watch-for-password-prompt'."
       (if intercept
          (setq this-command 'eshell-self-insert-command)))))
 
+(declare-function find-tag-interactive "etags" (prompt &optional no-default))
+
 (defun eshell-find-tag (&optional tagname next-p regexp-p)
   "A special version of `find-tag' that ignores read-onlyness."
   (interactive)
@@ -514,8 +506,7 @@ This is used by `eshell-watch-for-password-prompt'."
   (let ((inhibit-read-only t)
        (no-default (eobp))
        (find-tag-default-function 'ignore))
-    (with-no-warnings
-      (setq tagname (car (find-tag-interactive "Find tag: "))))
+    (setq tagname (car (find-tag-interactive "Find tag: " no-default)))
     (find-tag tagname next-p regexp-p)))
 
 (defun eshell-move-argument (limit func property arg)
@@ -536,20 +527,6 @@ This is used by `eshell-watch-for-password-prompt'."
             (= (1+ pos) limit))
        (forward-char 1))))
 
-(eshell-deftest arg forward-arg
-  "Move across command arguments"
-  (eshell-insert-command "echo $(+ 1 (- 4 3)) \"alpha beta\" file" 'ignore)
-  (let ((here (point)) begin valid)
-    (eshell-bol)
-    (setq begin (point))
-    (eshell-forward-argument 4)
-    (setq valid (= here (point)))
-    (eshell-backward-argument 4)
-    (prog1
-       (and valid (= begin (point)))
-      (eshell-bol)
-      (delete-region (point) (point-max)))))
-
 (defun eshell-forward-argument (&optional arg)
   "Move forward ARG arguments."
   (interactive "p")
@@ -630,7 +607,7 @@ will return the parsed command."
                 (setq command (eshell-parse-command (cons beg end)
                                                     args t)))))
        (ignore
-        (message "Expecting completion of delimeter %c ..."
+        (message "Expecting completion of delimiter %c ..."
                  (if (listp delim)
                      (car delim)
                    delim)))
@@ -649,17 +626,6 @@ waiting for input."
   (interactive "P")
   (eshell-send-input use-region t))
 
-(eshell-deftest mode queue-input
-  "Queue command input"
-  (eshell-insert-command "sleep 2")
-  (eshell-insert-command "echo alpha" 'eshell-queue-input)
-  (let ((count 10))
-    (while (and eshell-current-command
-               (> count 0))
-      (sit-for 1 0)
-      (setq count (1- count))))
-  (eshell-match-result "alpha\n"))
-
 (defun eshell-send-input (&optional use-region queue-p no-newline)
   "Send the input received to Eshell for parsing and processing.
 After `eshell-last-output-end', sends all text from that marker to
@@ -738,20 +704,6 @@ newline."
               (run-hooks 'eshell-post-command-hook)
               (insert-and-inherit input)))))))))
 
-; (eshell-deftest proc send-to-subprocess
-;   "Send input to a subprocess"
-;   ;; jww (1999-12-06): what about when bc is unavailable?
-;   (if (not (eshell-search-path "bc"))
-;       t
-;     (eshell-insert-command "bc")
-;     (eshell-insert-command "1 + 2")
-;     (sit-for 1 0)
-;     (forward-line -1)
-;     (prog1
-;      (looking-at "3\n")
-;       (eshell-insert-command "quit")
-;       (sit-for 1 0))))
-
 (defsubst eshell-kill-new ()
   "Add the last input text to the kill ring."
   (kill-ring-save eshell-last-input-start eshell-last-input-end))
@@ -897,14 +849,6 @@ Does not delete the prompt."
     (insert "*** output flushed ***\n")
     (delete-region (point) (eshell-end-of-output))))
 
-(eshell-deftest io flush-output
-  "Flush previous output"
-  (eshell-insert-command "echo alpha")
-  (eshell-kill-output)
-  (and (eshell-match-result (regexp-quote "*** output flushed ***\n"))
-       (forward-line)
-       (= (point) eshell-last-output-start)))
-
 (defun eshell-show-output (&optional arg)
   "Display start of this batch of interpreter output at top of window.
 Sets mark to the value of point when this command is run.
@@ -965,12 +909,6 @@ When run interactively, widen the buffer first."
     (goto-char eshell-last-output-end)
     (insert-and-inherit input)))
 
-(eshell-deftest mode run-old-command
-  "Re-run an old command"
-  (eshell-insert-command "echo alpha")
-  (goto-char eshell-last-input-start)
-  (string= (eshell-get-old-input) "echo alpha"))
-
 (defun eshell/exit ()
   "Leave or kill the Eshell buffer, depending on `eshell-kill-on-exit'."
   (throw 'eshell-terminal t))
@@ -995,10 +933,10 @@ a key."
       (beginning-of-line)
       (let ((pos (point)))
        (if (bobp)
-           (if (interactive-p)
+           (if (called-interactively-p 'interactive)
                (message "Buffer too short to truncate"))
          (delete-region (point-min) (point))
-         (if (interactive-p)
+         (if (called-interactively-p 'interactive)
              (message "Truncated buffer from %d to %d lines (%.1fk freed)"
                       lines eshell-buffer-maximum-lines
                       (/ pos 1024.0))))))))
@@ -1069,16 +1007,14 @@ This function could be in the list `eshell-output-filter-functions'."
 (custom-add-option 'eshell-output-filter-functions
                   'eshell-handle-control-codes)
 
+(autoload 'ansi-color-apply-on-region "ansi-color")
+
 (defun eshell-handle-ansi-color ()
   "Handle ANSI color codes."
-  (eval-and-compile (require 'ansi-color))
   (ansi-color-apply-on-region eshell-last-output-start
                               eshell-last-output-end))
 
 (custom-add-option 'eshell-output-filter-functions
                   'eshell-handle-ansi-color)
 
-;;; Code:
-
-;; arch-tag: ec65bc2b-da14-4547-81d3-a32af3a4dc57
 ;;; esh-mode.el ends here