* lisp/eshell/em-ls.el (eshell-ls-directory, eshell-ls-symlink): Fix doc typos.
[bpt/emacs.git] / lisp / eshell / esh-arg.el
index ccb0701..f791ad6 100644 (file)
@@ -1,16 +1,15 @@
-;;; esh-arg.el --- argument processing
+;;; esh-arg.el --- argument processing  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2013 Free Software Foundation, Inc.
 
 ;; Author: John Wiegley <johnw@gnu.org>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Parsing of arguments can be extended by adding functions to the
+;; hook `eshell-parse-argument-hook'.  For a good example of this, see
+;; `eshell-parse-drive-letter', defined in eshell-dirs.el.
 
 (provide 'esh-arg)
 
-(eval-when-compile (require 'esh-maint))
+(require 'esh-mode)
 
 (defgroup eshell-arg nil
   "Argument parsing involves transforming the arguments passed on the
@@ -33,12 +36,6 @@ yield the values intended."
   :tag "Argument parsing"
   :group 'eshell)
 
-;;; Commentary:
-
-;; Parsing of arguments can be extended by adding functions to the
-;; hook `eshell-parse-argument-hook'.  For a good example of this, see
-;; `eshell-parse-drive-letter', defined in eshell-dirs.el.
-
 (defcustom eshell-parse-argument-hook
   (list
    ;; a term such as #<buffer NAME>, or #<process NAME> is a buffer
@@ -55,7 +52,7 @@ yield the values intended."
        (goto-char (match-end 0))
        (let ((str (match-string 0)))
          (if (> (length str) 0)
-             (add-text-properties 0 1 '(number t) str))
+             (add-text-properties 0 (length str) '(number t) str))
          str))))
 
    ;; parse any non-special characters, based on the current context
@@ -103,7 +100,7 @@ yield the values intended."
 
    ;; argument delimiter
    'eshell-parse-delimiter)
-  "*Define how to process Eshell command line arguments.
+  "Define how to process Eshell command line arguments.
 When each function on this hook is called, point will be at the
 current position within the argument list.  The function should either
 return nil, meaning that it did no argument parsing, or it should
@@ -120,24 +117,25 @@ treated as a literal character."
 
 ;;; User Variables:
 
-(defcustom eshell-arg-load-hook '(eshell-arg-initialize)
-  "*A hook that gets run when `eshell-arg' is loaded."
+(defcustom eshell-arg-load-hook nil
+  "A hook that gets run when `eshell-arg' is loaded."
+  :version "24.1"                     ; removed eshell-arg-initialize
   :type 'hook
   :group 'eshell-arg)
 
-(defcustom eshell-delimiter-argument-list '(?\; ?& ?\| ?\> ?  ?\t ?\n)
+(defcustom eshell-delimiter-argument-list '(?\; ?& ?\| ?\> ?\s ?\t ?\n)
   "List of characters to recognize as argument separators."
   :type '(repeat character)
   :group 'eshell-arg)
 
 (defcustom eshell-special-chars-inside-quoting '(?\\ ?\")
-  "*Characters which are still special inside double quotes."
+  "Characters which are still special inside double quotes."
   :type '(repeat character)
   :group 'eshell-arg)
 
 (defcustom eshell-special-chars-outside-quoting
   (append eshell-delimiter-argument-list '(?# ?! ?\\ ?\" ?\'))
-  "*Characters that require escaping outside of double quotes.
+  "Characters that require escaping outside of double quotes.
 Without escaping them, they will introduce a change in the argument."
   :type '(repeat character)
   :group 'eshell-arg)
@@ -204,6 +202,18 @@ If POS is nil, the location of point is checked."
     (or (= pos (point-max))
        (memq (char-after pos) eshell-delimiter-argument-list))))
 
+(defun eshell-quote-argument (string)
+  "Return STRING with magic characters quoted.
+Magic characters are those in `eshell-special-chars-outside-quoting'."
+  (let ((index 0))
+    (mapconcat (lambda (c)
+                (prog1
+                    (or (eshell-quote-backslash string index)
+                        (char-to-string c))
+                  (setq index (1+ index))))
+              string
+              "")))
+
 ;; Argument parsing
 
 (defun eshell-parse-arguments (beg end)
@@ -216,25 +226,24 @@ Point is left at the end of the arguments."
       (narrow-to-region beg end)
       (let ((inhibit-point-motion-hooks t)
            (args (list t))
-           after-change-functions
            delim)
-       (remove-text-properties (point-min) (point-max)
-                               '(arg-begin nil arg-end nil))
-       (if (setq
-            delim
-            (catch 'eshell-incomplete
-              (while (not (eobp))
-                (let* ((here (point))
-                       (arg (eshell-parse-argument)))
-                  (if (= (point) here)
-                      (error "Failed to parse argument '%s'"
-                             (buffer-substring here (point-max))))
-                  (and arg (nconc args (list arg)))))))
-           (if (listp delim)
-               (throw 'eshell-incomplete delim)
-             (throw 'eshell-incomplete
-                    (list delim (point) (cdr args)))))
-       (cdr args)))))
+        (with-silent-modifications
+          (remove-text-properties (point-min) (point-max)
+                                  '(arg-begin nil arg-end nil))
+          (if (setq
+               delim
+               (catch 'eshell-incomplete
+                 (while (not (eobp))
+                   (let* ((here (point))
+                          (arg (eshell-parse-argument)))
+                     (if (= (point) here)
+                         (error "Failed to parse argument '%s'"
+                                (buffer-substring here (point-max))))
+                     (and arg (nconc args (list arg)))))))
+              (throw 'eshell-incomplete (if (listp delim)
+                                            delim
+                                          (list delim (point) (cdr args)))))
+          (cdr args))))))
 
 (defun eshell-parse-argument ()
   "Get the next argument.  Leave point after it."
@@ -269,7 +278,7 @@ Point is left at the end of the arguments."
     (eshell-resolve-current-argument)
     eshell-current-argument))
 
-(defsubst eshell-operator (&rest args)
+(defsubst eshell-operator (&rest _args)
   "A stub function that generates an error if a floating operator is found."
   (error "Unhandled operator in input text"))
 
@@ -284,7 +293,13 @@ Point is left at the end of the arguments."
   "Intelligently backslash the character occurring in STRING at INDEX.
 If the character is itself a backslash, it needs no escaping."
   (let ((char (aref string index)))
-    (if (eq char ?\\)
+    (if (and (eq char ?\\)
+            ;; In Emacs directory-sep-char is always ?/, so this does nothing.
+            (not (and (featurep 'xemacs)
+                      (featurep 'mswindows)
+                      (eq directory-sep-char ?\\)
+                      (eq (1- (string-width string))
+                          index))))
        (char-to-string char)
       (if (memq char eshell-special-chars-outside-quoting)
          (string ?\\ char)))))
@@ -308,7 +323,7 @@ special character that is not itself a backslash."
                  (char-to-string (char-before))))
        ;; allow \\<RET> to mean a literal "\" character followed by a
        ;; normal return, rather than a backslash followed by a line
-       ;; continuator (i.e., "\\ + \n" rather than "\ + \\n").  This
+       ;; continuation (i.e., "\\ + \n" rather than "\ + \\n").  This
        ;; is necessary because backslashes in Eshell are not special
        ;; unless they either precede something special, or precede a
        ;; backslash that precedes something special.  (Mainly this is
@@ -388,5 +403,4 @@ special character that is not itself a backslash."
                   (char-to-string (char-after)))))
         (goto-char end)))))))
 
-;;; arch-tag: 7f593a2b-8fc1-4def-8f84-8f51ed0198d6
 ;;; esh-arg.el ends here