* 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.
* test/lisp/eshell/em-pred-tests.el
(eshell-parse-file-name-attributes): Use t instead of nil as
second argument to 'time-convert'.
Suggested by Stefan Monnier <monnier@iro.umontreal.ca>.
* src/lisp.h (emacs_spawn):
* src/callproc.c (emacs_spawn): Add PTY_IN and PTY_OUT arguments to
specify which streams should be set up as a PTY.
(call_process): Adjust call to 'emacs_spawn'.
* src/process.h (Lisp_Process): Replace 'pty_flag' with 'pty_in' and
'pty_out'.
* src/process.c (is_pty_from_symbol): New function.
(make-process): Allow :connection-type to be a cons cell, and allow
using a stderr process with a PTY for stdin/stdout.
(create_process): Handle creating a process where only one of stdin or
stdout is a PTY.
* lisp/eshell/esh-proc.el (eshell-needs-pipe, eshell-needs-pipe-p):
Remove.
(eshell-gather-process-output): Use 'make-process' and set
':connection-type' as needed by the value of 'eshell-in-pipeline-p'.
* lisp/net/tramp.el (tramp-handle-make-process):
* lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
* lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Don't signal an
error when ':connection-type' is a cons cell.
* test/src/process-tests.el
(process-test-sentinel-wait-function-working-p): Allow passing PROC
in, and rework into...
(process-test-wait-for-sentinel): ... this.
(process-test-sentinel-accept-process-output)
(process-test-sentinel-sit-for, process-test-quoted-batfile)
(process-test-stderr-filter): Use 'process-test-wait-for-sentinel'.
(make/process/test-connection-type): New function.
(make-process/connection-type/pty, make-process/connection-type/pty-2)
(make-process/connection-type/pipe)
(make-process/connection-type/pipe-2)
(make-process/connection-type/in-pty)
(make-process/connection-type/out-pty)
(make-process/connection-type/pty-with-stderr-buffer)
(make-process/connection-type/out-pty-with-stderr-buffer): New tests.
* test/lisp/eshell/esh-proc-tests.el (esh-proc-test--detect-pty-cmd):
New variable.
(esh-proc-test/pipeline-connection-type/no-pipeline)
(esh-proc-test/pipeline-connection-type/first)
(esh-proc-test/pipeline-connection-type/middle)
(esh-proc-test/pipeline-connection-type/last): New tests.
* doc/lispref/processes.texi (Asynchronous Processes): Document new
':connection-type' behavior.
(Output from Processes): Remove caveat about ':stderr' forcing
'make-process' to use pipes.
* etc/NEWS: Announce this change (bug#56025).
In particular, this resolves an issue where '$+' referenced the real
environment variable '$PWD' instead of the Eshell variable alias of
the same name. This meant that changing directories in Eshell
wouldn't update the value of '$+'.
* lisp/eshell/esh-var.el (eshell-get-variable): Allow Eshell variable
aliaes to point to other aliases.
* test/lisp/eshell/em-dirs-tests.el (em-dirs-test/pwd-var)
(em-dirs-test/short-pwd-var): Adapt tests to check this case
(bug#56509).
* 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/esh-io.el (eshell-close-target): Send EOF 3 times.
* test/lisp/eshell/em-extpipe-tests.el (em-extpipe-tests--deftest):
Re-enable these tests on EMBA.
This patch is adapted by one from Ken Brown, who uncovered the reason
for this bug (bug#56025).
* lisp/eshell/em-glob.el (eshell-glob-convert): Return whether to
match directories only.
(eshell-glob-entries): Add ONLY-DIRS argument.
* test/lisp/eshell/em-glob-tests.el
(em-glob-test/match-any-directory): New test.
(em-glob-test/match-recursive)
(em-glob-test/match-recursive-follow-symlinks): Add test cases for
when "**/" or "***/" are the last components in a glob.
* etc/NEWS: Announce this change (bug#56227).
* lisp/eshell/em-glob.el (eshell-glob-recursive): New variable.
(eshell-glob-convert-1, eshell-glob-convert): New functions.
(eshell-extended-glob): Use 'eshell-glob-convert'.
(eshell-glob-entries): Adapt function to use pre-converted globs.
* test/lisp/eshell-em-glob-tests.el (em-glob-test/match-dot-files):
New test.
* 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.
When executed like a command, 'list' looks for external programs named
'list' first before falling back to the Lisp function of the same
name. This causes unexpected behavior, since the Lisp function is
what we want in these tests.
* test/lisp/eshell/esh-var-tests.el (esh-var-test/interp-cmd-indices)
(esh-var-test/quoted-interp-cmd-indices): Use 'listify' instead of
'list'.
* src/window.h (window_body_unit): New enum...
(window_body_width): ... use it.
* src/window.c (window_body_unit_from_symbol): New function.
(window_body_height, window_body_width): Make PIXELWISE a
'window_body_unit'.
(window-body-height, window-body-width): Accept 'remap' for PIXELWISE.
(window-lines-pixel-dimensions, window_change_record_windows)
(run_window_change_functions, resize_frame_windows, grow_mini_window)
(shrink_mini_window, scroll-left, scroll-right): Update calls to
'window_body_height' and 'window_body_width'.
* src/indent.c (compute_motion): Update calls to 'window_body_width'.
* lisp/eshell/em-ls.el (eshell-ls-find-column-widths)
(eshell-ls-find-column-lengths): Use 'window-body-width'.
* lisp/eshell/esh-var.el (eshell-variable-aliases-list): Use
'window-body-width' and 'window-body-height'.
* test/lisp/eshell/esh-var-tests.el (esh-var-test/window-height)
(esh-var-test/window-width): Rename to...
(esh-var-test/lines-var, esh-var-test/columns-var): ... and update
expected value.
* doc/lispref/windows.texi (Window Sizes): Document new behavior of
PIXELWISE argument for 'window-body-width' and 'window-body-height'.
* etc/NEWS: Announce this change (bug#55696).
* lisp/eshell/esh-var.el (eshell-apply-indices): Use
'eshell-convert-to-number' instead of 'eshell-convert'.
* test/lisp/eshell/esh-var-tests.el
(esh-var-test/interp-convert-var-split-indices): Expand test
(bug#55838).
* lisp/eshell/esh-cmd.el (eshell-subcommand-bindings)
(eshell-command-to-value): Set 'eshell-in-pipeline-p' to nil.
* test/lisp/eshell/eshell-tests.el
(eshell-test/subcommand-reset-in-pipeline)
(eshell-test/lisp-reset-in-pipeline): New tests (bug#55620).
* 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.
Previously, Eshell would get confused and think the following command
was unterminated due to the second double-quote looking like it was
escaped:
echo "\\"
* lisp/eshell/esh-util.el (eshell-find-delimiter): Correct docstring
and treat '\' as an escapeable character when using backslash escapes.
* test/lisp/eshell/eshell-tests.el
(eshell-test/escape-special-quoted): Adapt test.
* lisp/eshell/em-extpipe.el (em-extpipe--or-with-catch): New macro.
(eshell-parse-external-pipeline): Use new macro to treat
`eshell-incomplete' as a failure of the parse function to move us
forward (Bug#54603). Thanks to Jim Porter <jporterbugs@gmail.com> for
the report and for help isolating the problem.
* test/lisp/eshell/eshell-tests.el
(eshell-test/lisp-command-with-quote): New test for Bug#54603, thanks
to Jim Porter <jporterbugs@gmail.com> (bug#54603).
'em-basic-test/umask-set' fails when passing an actual number to the
command, but this is fixed in the subsequent commit.
test/lisp/eshell/em-basic-tests.el: New file.
* test/lisp/eshell/esh-proc-tests.el (esh-proc-test/kill-pipeline):
Add pattern matching output when killing a process on macOS (and
possibly other BSDs).
For example, '${echo -e "hi\nbye"}[1]' should expand to "bye".
* lisp/eshell/esh-var.el (eshell-parse-variable-ref): Support applying
indices to '${}', '$()', and '$<>' forms.
(Bug#54227)
* lisp/eshell/esh-var-tests.el (esh-var-test/interp-lisp-indices)
(esh-var-test/interp-cmd-indices)
(esh-var-test/interp-cmd-external-indices)
(esh-var-test/quoted-interp-lisp-indices)
(esh-var-test/quoted-interp-cmd-indices): New tests.
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.
For example,
echo "${echo hi}"
previously tried to run the program named 'echo hi', instead of 'echo'
with the argument 'hi'.
* lisp/eshell/esh-arg.el (eshell-parse-inner-double-quote):
New function.
* lisp/eshell/esh-var.el (eshell-parse-variable-ref): Support parsing
when wrapped in double-quiotes.
* test/lisp/eshell/esh-var-tests.el (esh-var-test/interp-var)
(esh-var-test/interp-quoted-var)
(esh-var-test/interp-quoted-var-concat)
(esh-var-test/quoted-interp-var)
(esh-var-test/quoted-interp-quoted-var)
(esh-var-test/quoted-interp-lisp, esh-var-test/quoted-interp-cmd)
(esh-var-test/quoted-interp-temp-cmd): New tests.
That commit regressed '$<command>' forms in Eshell, due to a
limitation/bug in how 'eshell-do-eval' works. This fixes
bug#54190.
* lisp/eshell/esh-var.el (eshell-parse-variable-ref): Quote a lambda.
* test/lisp/eshell/eshell-tests.el (eshell-test/interp-temp-cmd):
New test.
* lisp/eshell/esh-proc.el (eshell-kill-process-function): Only reset
the prompt if PROC is writing to the terminal.
(eshell-sentinel): Only write the exit message if PROC is writing to
the terminal (bug#54136).
* test/lisp/eshell/esh-proc-tests.el (esh-proc-test/kill-pipeline)
(esh-proc-test/kill-pipeline-head)
(esh-proc-test/kill-background-process): New tests.
* lisp/eshell/esh-io.el (eshell-pipe-broken): New error.
(eshell-output-object-to-target): Signal 'eshell-pipe-broken' if the
target is an exited/signaled process.
* lisp/eshell/esh-proc.el (eshell-insertion-filter): Handle
'eshell-pipe-broken'.
* test/lisp/eshell/esh-proc-tests.el: New test.
Previously, if a non-process was piped to a process, this could end up
being nil, which isn't correct. 'eshell-last-async-procs' should just
ignore non-process commands in a pipeline.
* lisp/eshell/esh-cmd.el (eshell-do-pipelines): Set 'headproc'
correctly.
* test/lisp/eshell/eshell-tests.el (eshell-test/pipe-headproc): New test.
* test/lisp/eshell/eshell-tests.el
* test/lisp/eshell/em-extpipe-tests.el: Load eshell-tests-helpers with
'require'.
* test/lisp/eshell/eshell-tests-helpers.el (eshell-history-file-name):
Define this here so individual test files don't have to.
Previously, input was sent to the last process in the pipeline,
resulting in unexpected behavior when running commands like
'tr a-z A-Z | rev'.
* lisp/eshell/esh-util.el (eshell-process-pair-p)
(eshell-make-process-pair): New functions.
* lisp/eshell/esh-cmd.el (eshell-last-async-proc): Rename to...
(eshell-last-async-procs): ... this, and store a pair of processes.
(eshell-interactive-process): Replace with...
(eshell-interactive-process-p, eshell-head-process)
(eshell-tail-process): ... these.
(eshell-cmd-initialize): Set 'eshell-last-async-procs'.
(eshell-do-pipelines): Set 'headproc'.
(eshell-execute-pipeline): Return 'headproc' and 'tailproc'.
(eshell-resume-eval): Use 'eshell-last-async-procs'.
(eshell-do-eval): Make sure we work with a pair of processes.
* lisp/eshell/esh-proc.el (eshell-send-eof-to-process): Move from
here...
* lisp/eshell/esh-mode.el (eshell-send-eof-to-process): ... to here,
and only send EOF to the head process.
* lisp/eshell/em-cmpl.el (eshell-complete-parse-arguments)
* lisp/eshell/esh-mode.el (eshell-intercept-commands)
(eshell-watch-for-password-prompt):
Use 'eshell-interactive-process-p'.
* lisp/eshell/em-rebind.el (eshell-delchar-or-maybe-eof)
* lisp/eshell/em-term.el (eshell-term-send-raw-string)
* lisp/eshell/esh-mode.el (eshell-self-insert-command)
(eshell-send-input, eshell-send-invisible):
Use 'eshell-head-process'.
* lisp/eshell/esh-cmd.el (eshell-as-subcommand):
Use 'eshell-tail-process'.
* lisp/eshell/eshell.el (eshell-command):
* test/lisp/eshell/eshell-tests-helpers.el
(eshell-wait-for-subprocess):
Use 'eshell-interactive-process-p' and 'eshell-tail-process'.
* test/lisp/eshell/eshell-tests.el (eshell-test/pipe-headproc-stdin):
New test.