You can use --
to tell eshell
not to interpret arguments that follow as command-line switches. This is the standard way of passing an argument (such as a file name) starting with a dash to GNU tools.
In summary: try
echo -- "-------------"
or just
echo -- -------------
(as far as I can tell all arguments are interpreted as strings).
There are two issues (I would even say bugs here):
eshell--process-args
uses "^-\\(-\\)?\\(.*\\)"
to match switches, i.e. anything starting with one or two dashes is treated as a switch and removed from the list of arguments. If we disallow switches starting with three dashes and use "^-\\(-\\)?\\([^-].*\\)"
, echo ---
works as expected.
eshell--process-option
has a bug that prevents it from printing an error message when an unrecognized switch is passed to an eshell
command without an "external" equivalent.
See the code block below for the fixed version. (Note that (error ...)
is outside (when extcmd ...)
.
(defun eshell--process-option (name switch kind ai options opt-vals)
"For NAME, process SWITCH (of type KIND), from args at index AI.
The SWITCH will be looked up in the set of OPTIONS.
SWITCH should be either a string or character. KIND should be the
integer 0 if it's a character, or 1 if it's a string.
The SWITCH is then be matched against OPTIONS. If no matching handler
is found, and an :external command is defined (and available), it will
be called; otherwise, an error will be triggered to say that the
switch is unrecognized."
(let* ((opts options)
found)
(while opts
(if (and (listp (car opts))
(nth kind (car opts))
(equal switch (nth kind (car opts))))
(progn
(eshell--set-option name ai (car opts) options opt-vals)
(setq found t opts nil))
(setq opts (cdr opts))))
(unless found
(let ((extcmd (memq ':external options)))
(when extcmd
(setq extcmd (eshell-search-path (cadr extcmd)))
(if extcmd
(throw 'eshell-ext-command extcmd)))
(error (if (characterp switch) "%s: unrecognized option -%c"
"%s: unrecognized option --%s")
name switch)))))
PS: I'm using GNU Emacs 24.5.1
.