don't use function-equal in nadvice
[bpt/emacs.git] / lisp / eshell / em-term.el
index 7d5fbbe..4a8f368 100644 (file)
@@ -1,6 +1,6 @@
-;;; em-term.el --- running visual commands
+;;; em-term.el --- running visual commands  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1999-201 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2014 Free Software Foundation, Inc.
 
 ;; Author: John Wiegley <johnw@gnu.org>
 
 ;; At the moment, eshell is stream-based in its interactive input and
 ;; output.  This means that full-screen commands, such as "vi" or
 ;; "lynx", will not display correctly.  These are therefore thought of
-;; as "visual" programs.  In order to run these progrem under Emacs,
+;; as "visual" programs.  In order to run these programs under Emacs,
 ;; Eshell uses the term.el package, and invokes them in a separate
 ;; buffer, giving the illusion that Eshell itself is allowing these
 ;; visual processes to execute.
 
 ;;; Code:
 
+(require 'cl-lib)
+(require 'esh-util)
+(require 'esh-ext)
 (eval-when-compile (require 'eshell))
 (require 'term)
 
 ;;;###autoload
-(eshell-defgroup eshell-term nil
+(progn
+(defgroup eshell-term nil
   "This module causes visual commands (e.g., 'vi') to be executed by
 the `term' package, which comes with Emacs.  This package handles most
 of the ANSI control codes, allowing curses-based applications to run
 within an Emacs window.  The variable `eshell-visual-commands' defines
 which commands are considered visual in nature."
   :tag "Running visual commands"
-  :group 'eshell-module)
+  :group 'eshell-module))
 
 ;;; User Variables:
 
@@ -58,21 +62,73 @@ which commands are considered visual in nature."
     "less" "more"                       ; M-x view-file
     "lynx" "ncftp"                      ; w3.el, ange-ftp
     "pine" "tin" "trn" "elm")           ; GNUS!!
-  "A list of commands that present their output in a visual fashion."
+  "A list of commands that present their output in a visual fashion.
+
+Commands listed here are run in a term buffer.
+
+See also `eshell-visual-subcommands' and `eshell-visual-options'."
   :type '(repeat string)
   :group 'eshell-term)
 
-(defcustom eshell-term-name "eterm"
+(defcustom eshell-visual-subcommands
+  nil
+  "An alist of subcommands that present their output in a visual fashion.
+
+An alist of the form
+
+  ((COMMAND1 SUBCOMMAND1 SUBCOMMAND2...)
+   (COMMAND2 SUBCOMMAND1 ...))
+
+of commands with subcommands that present their output in a
+visual fashion.  A likely entry is
+
+  (\"git\" \"log\" \"diff\" \"show\")
+
+because git shows logs and diffs using a pager by default.
+
+See also `eshell-visual-commands' and `eshell-visual-options'."
+  :type '(repeat (cons (string :tag "Command")
+                      (repeat (string :tag "Subcommand"))))
+  :version "24.4"
+  :group 'eshell-term)
+
+(defcustom eshell-visual-options
+  nil
+  "An alist of the form
+
+  ((COMMAND1 OPTION1 OPTION2...)
+   (COMMAND2 OPTION1 ...))
+
+of commands with options that present their output in a visual
+fashion.  For example, a sensible entry would be
+
+  (\"git\" \"--help\")
+
+because \"git <command> --help\" shows the command's
+documentation with a pager.
+
+See also `eshell-visual-commands' and `eshell-visual-subcommands'."
+  :type '(repeat (cons (string :tag "Command")
+                      (repeat (string :tag "Option"))))
+  :version "24.4"
+  :group 'eshell-term)
+
+;; If you change this from term-term-name, you need to ensure that the
+;; value you choose exists in the system's terminfo database.  (Bug#12485)
+(defcustom eshell-term-name term-term-name
   "Name to use for the TERM variable when running visual commands.
 See `term-term-name' in term.el for more information on how this is
 used."
+  :version "24.3"             ; eterm -> term-term-name = eterm-color
   :type 'string
   :group 'eshell-term)
 
 (defcustom eshell-escape-control-x t
   "If non-nil, allow <C-x> to be handled by Emacs key in visual buffers.
-See the variable `eshell-visual-commands'.  If this variable is set to
-nil, <C-x> will send that control character to the invoked process."
+See the variables `eshell-visual-commands',
+`eshell-visual-subcommands', and `eshell-visual-options'.  If
+this variable is set to nil, <C-x> will send that control
+character to the invoked process."
   :type 'boolean
   :group 'eshell-term)
 
@@ -86,19 +142,29 @@ nil, <C-x> will send that control character to the invoked process."
   "Initialize the `term' interface code."
   (make-local-variable 'eshell-interpreter-alist)
   (setq eshell-interpreter-alist
-       (cons (cons (function
-                    (lambda (command)
-                      (member (file-name-nondirectory command)
-                              eshell-visual-commands)))
+       (cons (cons #'eshell-visual-command-p
                    'eshell-exec-visual)
              eshell-interpreter-alist)))
 
+(defun eshell-visual-command-p (command args)
+  "Returns non-nil when given a visual command.
+If either COMMAND or a subcommand in ARGS (e.g. git log) is a
+visual command, returns non-nil."
+  (let ((command (file-name-nondirectory command)))
+    (and (eshell-interactive-output-p)
+         (or (member command eshell-visual-commands)
+             (member (car args)
+                     (cdr (assoc command eshell-visual-subcommands)))
+             (cl-intersection args
+                              (cdr (assoc command eshell-visual-options))
+                              :test 'string=)))))
+
 (defun eshell-exec-visual (&rest args)
   "Run the specified PROGRAM in a terminal emulation buffer.
 ARGS are passed to the program.  At the moment, no piping of input is
 allowed."
   (let* (eshell-interpreter-alist
-        (interp (eshell-find-interpreter (car args)))
+        (interp (eshell-find-interpreter (car args) (cdr args)))
         (program (car interp))
         (args (eshell-flatten-list
                (eshell-stringify-list (append (cdr interp)
@@ -123,7 +189,8 @@ allowed."
          (term-set-escape-char ?\C-x))))
   nil)
 
-(defun eshell-term-sentinel (proc string)
+;; Process sentinels receive two arguments.
+(defun eshell-term-sentinel (proc _string)
   "Destroy the buffer visiting PROC."
   (let ((proc-buf (process-buffer proc)))
     (when (and proc-buf (buffer-live-p proc-buf)