* lisp/eshell/esh-arg.el: Require cl-lib.
(eshell-finish-arg): Allow passing multiple ARGUMENTS.
(eshell-quote-argument): Handle the case when 'eshell-finish-arg' was
passed multiple arguments.
* lisp/eshell/esh-cmd.el (eshell-do-pipelines)
(eshell-do-pipelines-synchronously): Only set stdout output handle.
* lisp/eshell/esh-io.el (eshell-redirection-operators-alist): New
constant.
(eshell-io-initialize): Prefer sharp quotes for functions.
(eshell-parse-redirection, eshell-strip-redirections): Add support for
more redirection forms.
(eshell-copy-output-handle, eshell-set-all-output-handles): New
functions.
* test/lisp/eshell/esh-io-tests.el
(esh-io-test/redirect-all/overwrite, esh-io-test/redirect-all/append)
(esh-io-test/redirect-all/insert, esh-io-test/redirect-copy)
(esh-io-test/redirect-copy-first, esh-io-test/redirect-pipe): New
tests.
* doc/misc/eshell.texi (Redirection): Document new redirection syntax.
(Pipelines): Document '|&' syntax.
(Bugs and ideas): Update item about redirection syntax.
* etc/NEWS: Announce this change.
* lisp/eshell/esh-arg.el (eshell-parse-argument-hook): Explain how to
use 'eshell-finish-arg'.
* lisp/eshell/esh-io.el (eshell-create-handles): Only call
'eshell-get-target' for stderr if necessary.
(eshell-protect-handles): Use 'dotimes'.
(eshell-set-output-handle): Pass HANDLES and fix an edge case with
setting a duplicate TARGET.
* test/lisp/eshell/eshell-tests-helpers.el (eshell-with-temp-buffer):
New macro.
* test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/quoted-lisp-form)
(esh-cmd-test/backquoted-lisp-form)
(esh-cmd-test/backquoted-lisp-form/splice): New tests.
* test/lisp/eshell/eshell-tests.el (eshell-test/redirect-buffer)
(eshell-test/redirect-buffer-escaped): Move to...
* test/lisp/eshell/esh-io-tests.el: ... here, and add other I/O tests.
* doc/misc/eshell.texi (Arguments): Add documentation for special
argument types.
(Input/Output): Expand documentation for redirection and pipelines.
Previously, '$?' (last exit code) was only useful for external
commands, and '$$' (last result) was only useful for Lisp commands.
* lisp/eshell/esh-cmd.el (eshell-lisp-form-nil-is-failure): New
option.
(eshell-lisp-command): Set last exit code to 1 when the command
signals an error, and 2 if it returns nil (for Lisp forms only).
* lisp/eshell/esh-proc.el (eshell-sentinel): Set last result to t if
the command succeeded.
* test/lisp/eshell/esh-cmd-tests.el
(esh-cmd-test/while-loop-lisp-form, esh-cmd-test/until-loop-lisp-form)
(esh-cmd-test/if-else-statement-lisp-form)
(esh-cmd-test/if-else-statement-lisp-form-2)
(esh-cmd-test/unless-else-statement-lisp-form): New tests.
* test/lisp/eshell/esh-var-tests.el
(esh-var-test/last-status-var-lisp-command)
(esh-var-test/last-status-var-lisp-form)
(esh-var-test/last-status-var-lisp-form-2)
(esh-var-test/last-status-var-ext-cmd)
(esh-var-test/last-status-var-ext-cmd): New tests.
(esh-var-test/last-result-var2): Rename from this...
( esh-var-test/last-result-var-twice): ... to this.
* doc/misc/eshell.texi (Variables): Update documentation about '$?'
and '$$'.
(Control Flow): Mention that '(lisp forms)' can be used as
conditionals.
* etc/NEWS: Announce this change (bug#57129).
* lisp/eshell/esh-cmd.el (eshell-structure-basic-command): Forms
beginning with 'eshell-escape-arg' are "data-wise".
* test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/while-loop)
(esh-cmd-test/until-loop, esh-cmd-test/if-statement)
(esh-cmd-test/if-else-statement, esh-cmd-test/unless-statement)
(esh-cmd-test/unless-else-statement): Use variable interpolation.
(esh-cmd-test/while-loop-ext-cmd, esh-cmd-test/until-loop-ext-cmd)
(esh-cmd-test/if-else-statement-ext-cmd)
(esh-cmd-test/unless-else-statement-ext-cmd): New tests, adapted from
the existing ones.
* doc/misc/eshell.texi (Control Flow): Update documentation for
conditionals (bug#57129).
This simplifies usage of 'eshell-close-handles' in several places and
makes it work more like the docstring indicated it would.
* lisp/eshell/esh-io.el (eshell-close-handles): Only store EXIT-CODE
and RESULT if they're non-nil. Also, use 'dotimes' and 'dolist' to
simplify the implementation.
* lisp/eshell/em-alias.el (eshell-write-aliases-list):
* lisp/eshell/esh-cmd.el (eshell-rewrite-for-command)
(eshell-structure-basic-command): Adapt calls to
'eshell-close-handles'.
* test/lisp/eshell/eshell-tests.el (eshell-test/simple-command-result)
(eshell-test/lisp-command, eshell-test/lisp-command-with-quote)
(eshell-test/for-loop, eshell-test/for-name-loop)
(eshell-test/for-name-shadow-loop, eshell-test/lisp-command-args)
(eshell-test/subcommand, eshell-test/subcommand-args)
(eshell-test/subcommand-lisp): Move from here...
* test/lisp/eshell/esh-cmd-tests.el
(esh-cmd-test/simple-command-result, esh-cmd-test/lisp-command)
(esh-cmd-test/lisp-command-with-quote, esh-cmd-test/for-loop)
(esh-cmd-test/for-name-loop, esh-cmd-test/for-name-shadow-loop)
(esh-cmd-test/lisp-command-args, esh-cmd-test/subcommand)
(esh-cmd-test/subcommand-args, esh-cmd-test/subcommand-lisp): ... to
here.
(esh-cmd-test/and-operator, esh-cmd-test/or-operator)
(esh-cmd-test/for-loop-list, esh-cmd-test/for-loop-multiple-args)
(esh-cmd-test/while-loop, esh-cmd-test/until-loop)
(esh-cmd-test/if-statement, esh-cmd-test/if-else-statement)
(esh-cmd-test/unless-statement, esh-cmd-test/unless-else-statement):
New tests.
* doc/misc/eshell.texi (Invocation): Explain '&&' and '||'.
(for loop): Move from here...
(Control Flow): ... to here, and add documentation for other control
flow forms.
* lisp/eshell/em-dirs.el (eshell-inside-emacs)
(eshell-dirs-initialize): Move 'INSIDE_EMACS' from here...
* lisp/eshell/esh-var.el (eshell-inside-emacs)
(eshell-variable-aliases-alist): ... to here, and improve doc string.
* test/lisp/eshell/eshell-tests.el (eshell-test/inside-emacs-var):
Move from here...
* test/lisp/eshell/esh-var-tests.el (esh-var-test/inside-emacs-var):
... to here.
(esh-var-test/last-arg-var-indices)
(esh-var-test/last-arg-var-split-indices): New tests.
* test/lisp/eshell/em-alias-tests.el:
* test/lisp/eshell/em-dirs-tests.el:
* test/lisp/eshell-em-script-tests.el: New files.
* doc/misc/eshell.texi (Built-ins): Fix 'cd' documentation; it works
with the directory ring, not the directory stack. Move built-in
variables documentation from here...
(Variables): ... to here, and add documentation for missing built-in
variables.
* lisp/eshell/em-pred.el (eshell-error-if-no-glob): Declare it.
(eshell-apply-modifiers): Add STRING-DESC argument and signal an error
if there are no matches and 'eshell-error-if-no-glob' is set.
(eshell-parse-arg-modifier): Pass modifier string to
'eshell-apply-modifiers'.
* test/lisp/eshell/em-pred-tests.el (eshell-eval-predicate): Simplify.
(em-pred-test/no-matches): New test.
* doc/misc/eshell.texi (Bugs and ideas): Remove todo entry about this
change.
* lisp/eshell/esh-cmd.el (eshell-execute-pipeline): Use 'make-symbol'
for headproc and tailproc.
(eshell-do-pipelines, eshell-do-pipelines-synchronously): Adapt to the
above.
* test/lisp/eshell/eshell-tests.el (eshell-test/pipe-subcommand)
(eshell-test/pipe-subcommand-with-pipe): New test.
* doc/misc/eshell.texi (Bugs and ideas): Remove item about piping to
process from loop; this commit fixes it (bug#55590).
Previously, concatenating a list to a string would first convert the
list to a string. Now, the string is concatenated with the last
element of the list.
* lisp/eshell/esh-util.el (eshell-to-flat-string): Make obsolete.
* lisp/eshell/esh-arg.el (eshell-concat, eshell-concat-1): New
functions.
(eshell-resolve-current-argument): Use 'eshell-concat'.
* test/lisp/eshell/esh-var-tests.el (esh-var-test/interp-concat-cmd):
Add check for concatenation of multiline output of subcommands.
(esh-var-test/quoted-interp-concat-cmd): New test.
* test/lisp/eshell/em-extpipe-tests.el (em-extpipe-test-13): Use
'eshell-concat'.
* doc/misc/eshell.texi (Expansion): Document this behavior.
* etc/NEWS: Announce the change (bug#55236).
This is closer in behavior to regular shells, and gives Eshell users
greater flexibility in how variables are expanded.
* lisp/eshell/esh-util.el (eshell-convert): Add TO-STRING argument.
* lisp/eshell/esh-var.el (eshell-parse-variable-ref): Add MODIFIER-P
argument and adjust how 'eshell-convert' and 'eshell-apply-indices'
are called.
(eshell-get-variable, eshell-apply-indices): Add QUOTED argument.
* test/lisp/eshell/esh-var-tests.el (eshell-test-value): New defvar.
(esh-var-test/interp-convert-var-number)
(esh-var-test/interp-convert-var-split-indices)
(esh-var-test/interp-convert-quoted-var-number)
(esh-var-test/interp-convert-quoted-var-split-indices)
(esh-var-test/interp-convert-cmd-string-newline)
(esh-var-test/interp-convert-cmd-multiline)
(esh-var-test/interp-convert-cmd-number)
(esh-var-test/interp-convert-cmd-split-indices)
(esh-var-test/quoted-interp-convert-var-number)
(esh-var-test/quoted-interp-convert-var-split-indices)
(esh-var-test/quoted-interp-convert-quoted-var-number)
(esh-var-test/quoted-interp-convert-quoted-var-split-indices)
(esh-var-test/quoted-interp-convert-cmd-string-newline)
(esh-var-test/quoted-interp-convert-cmd-multiline)
(esh-var-test/quoted-interp-convert-cmd-number)
(esh-var-test/quoted-interp-convert-cmd-split-indices): New tests.
* doc/misc/eshell.texi (Arguments): Expand this section, and document
the new behavior.
(Dollars Expansion): Provide more detail about '$(lisp)' and
'${command}' forms.
* etc/NEWS (Eshell): Announce this change (bug#55236).
* lisp/eshell/em-pred.el (eshell-pred-delimiter-pairs): New variable.
(eshell-get-comparison-modifier-argument)
(eshell-get-numeric-modifier-argument)
(eshell-get-delimited-modifier-argument): New functions...
(eshell-pred-user-or-group, eshell-pred-file-time)
(eshell-pred-file-links, eshell-pred-file-size)
(eshell-pred-substitute, eshell-join-memebers, eshell-split-members):
... and use them here.
(eshell-include-members): Pass 'mod-char' and use
'eshell-get-delimited-modifier-argument'.
(eshell-pred-file-type, eshell-pred-file-mode): Use 'when-let'.
(eshell-modifier-alist): Pass modifier char to
'eshell-include-members'.
* test/lisp/eshell/em-pred-tests.el
(em-pred-test/predicate-delimiters): New test.
(em-pred-test/predicate-uid, em-pred-test/predicate-gid,
em-pred-test/modifier-include, em-pred-test/modifier-exclude): Remove
cases covered by 'em-pred-test/predicate-delimiters'.
(em-pred-test/modifier-substitute): Add test cases for new delimiter
styles.
* doc/misc/eshell.texi (Argument Predication and Modification):
Explain how string parameters are delimited.
(Argument Modifiers): Document some special delimiter behavior with
the 's/PATTERN/REPLACE/' modifier (bug#55204).
* etc/NEWS: Announce this change, and move the
'eshell-eval-using-options' entry to the Eshell section.
* lisp/eshell/esh-cmd.el (eshell-eval-argument): New function.
* lisp/eshell/esh-util.el (eshell-file-attributes): Pass original
value of FILE to 'file-attributes'.
* lisp/eshell/em-pred.el (eshell-predicate-alist): Change socket char
to '=', since 's' conflicts with setuid.
(eshell-modifier-alist): Fix 'E' (eval) modifier by using
'eshell-eval-argument'. Also improve performance of 'O' (reversed
sort) modifier.
(eshell-modifier-help-string): Fix documentation of global
substitution modifier.
(eshell-pred-substitute): Fix infinite loop in some global
substitutions.
(eshell-join-members): Fix joining with implicit " " delimiter.
(Bug#54470)
* test/lisp/eshell/em-pred-tests.el: New file.
* doc/misc/eshell.texi (Argument Predication): New section.
* lisp/eshell/em-glob.el (eshell-extended-glob): Fix docstring.
(eshell-glob-entries): Refer to '**/' in error (technically, '**' can
end a glob, but it means the same thing as '*'). (Bug#54470)
* test/lisp/eshell/em-glob-tests.el: New file.
* doc/misc/eshell.texi (Globbing): Document pattern-based globs.
Since '$var[hello 0]' doesn't make sense when 'var' is a string, the
previous restriction was unnecessary.
* lisp/eshell/esh-var.el (Commentary): Update documentation.
(eshell-apply-indices): Allow "plain" strings to split strings.
* test/lisp/eshell/esh-var-test.el
(esh-var-test/interp-var-string-split-indices)
(esh-var-test/quoted-interp-var-string-split-indices): Update tests.
* doc/misc/eshell.texi (Dollars expansion): Update documentation.
Previously, more-complex index expansions, like '$var[":" 0]' or
'$var[$(expr) 0]' failed to parse correctly.
* lisp/eshell/esh-var.el (Commentary): Clarify indexing and length
expansions.
(eshell-parse-indices): Expand docstring and support parsing inside
double-quotes.
(eshell-eval-indices): New function.
(eshell-parse-variable): Use it.
* test/lisp/eshell/esh-var-tests.el (eshell-test-value): New defvar.
(esh-var-test/interp-var-indices,
(esh-var-test/interp-var-split-indices)
(esh-var-test/interp-var-string-split-indices)
(esh-var-test/interp-var-regexp-split-indices)
(esh-var-test/interp-var-assoc, esh-var-test/interp-var-length-list)
(esh-var-test/interp-var-length-string)
(esh-var-test/interp-var-length-alist)
(esh-var-test/quoted-interp-var-indices)
(esh-var-test/quoted-interp-var-split-indices)
(esh-var-test/quoted-interp-var-string-split-indices)
(esh-var-test/quoted-interp-var-regexp-split-indices)
(esh-var-test/quoted-interp-var-assoc)
(esh-var-test/quoted-interp-var-length-list)
(esh-var-test/quoted-interp-var-length-string)
(esh-var-test/quoted-interp-var-length-alist): New tests.
* doc/misc/eshell.texi (Dollars Expansion): Expand and reword
documentation for indexing and length expansions.
* doc/misc/eshell.texi (Built-in commands): Expand on the
documentation of echo (bug#27361).
* lisp/eshell/em-basic.el (eshell-echo): Respect OUTPUT-NEWLINE even
when 'eshell-plain-echo-behavior' is non-nil.
(eshell/echo): Add "-N" option and recommend its use over "-n" in
Lisp-friendly echo.
(eshell/printnl): Simplify; 'eshell-stringify' is equivalent to
calling 'eshell-echo' here.
* lisp/eshell/esh-opt.el (eshell--split-switch): New function.
(eshell-set-option): Allow setting a supplied value instead of always
consuming from 'eshell--args'.
(eshell--process-option): Support consuming option values specified as
a single token.
(eshell--process-args): For short options, pass full switch token to
'eshell--process-option'.
* test/lisp/eshell/esh-opt-tests.el (esh-opt-process-args-test): Fix
test.
(test-eshell-eval-using-options): Add tests for various types of
options.
* doc/misc/eshell.texi (Defining new built-in commands): New
subsection, describe how to use 'eshell-eval-using-options'.
* etc/NEWS: Announce the change.
* doc/misc/eshell.texi (Built-in commands): Add the remaining
built-in Eshell commands to the list of built-ins. Expand some of
the descriptions and mention user options affecting command
behavior. Sort these commands in alphabetical order (bug#52289).
* doc/misc/eshell.texi (Writing a module, Module testing)
(Directory handling, Key rebinding, Smart scrolling)
(Terminal emulation): Explicitly say that these sections remain to
be written. (Bug#49306)
(eshell-cmpl-initialize): Refrain from binding to the `tab` key,
which prevents the tab -> TAB remapping.
Use completion-at-point and completion-help-at-point.
(eshell-complete-commands-list): Use `fboundp` test instead of ugly
gymnastics to try and hide the function call from the compiler.
(eshell-pcomplete): Make it an alias of completion-at-point.
* doc/misc/eshell.texi (Completion): Change wording to reflect
different default behavior.