Now last executed CommandPipeline is available in `__xonsh__.last` (#5422)

### Motivation

There is no way to access to the CommandPipeline of executed command in
uncaptured mode. This causes:
 * No chance to get return code in one universal way.
 * Barrier to trace and inspection.

### Before

```xsh
$(ls nofile)
# No way to access to the CommandPipeline of executed command.
```

### After
```xsh
$(ls nofile)
__xonsh__.last.rtn  # In interactive or not interactive.
# 2
```
```xsh
# Sugar sir:
last = type('LastCP', (object,), {'__getattr__':lambda self, name: getattr(__xonsh__.last, name) })()

ls nofile
last.rtn
# 2
```

JFYI #5342

## For community
⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍
comment**

---------

Co-authored-by: a <1@1.1>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Andy Kipp 2024-05-22 15:25:35 +02:00 committed by GitHub
parent f50a9e577c
commit aa69ce868a
Failed to generate hash of commit
4 changed files with 36 additions and 9 deletions

View file

@ -101,10 +101,10 @@ line is ``#!/usr/bin/env xonsh``.
- ``os.getpid()`` - ``os.getpid()``
- Get PID of the current shell. - Get PID of the current shell.
* - ``$?`` * - ``$?``
- ``_.rtn`` - ``__xonsh__.last.rtn`` anywhere or ``_.rtn`` in prompt mode
- Returns the exit code, or status, of the previous command. The underscore ``_`` is working - Returns the exit code, or status, of the previous command. The underscore ``_`` is working
in the prompt mode. To get the exit code of the command in xonsh script in the prompt mode. To get the exit code of the command in xonsh script
use captured subprocess ``!().rtn``. use ``!().rtn`` for not interactive processes.
* - ``!$`` * - ``!$``
- ``__xonsh__.history[-1, -1]`` - ``__xonsh__.history[-1, -1]``
- Get the last argument of the last command - Get the last argument of the last command
@ -116,17 +116,15 @@ line is ``#!/usr/bin/env xonsh``.
- ``$ARGS`` - ``$ARGS``
- List of all command line argument and parameter strings. - List of all command line argument and parameter strings.
* - ``while getopts`` * - ``while getopts``
- ``import argparse`` - Use `argparse <https://docs.python.org/3/library/argparse.html>`_ or `click <https://click.palletsprojects.com>`_.
- Start from `argparse <https://docs.python.org/3/library/argparse.html>`_ library to describe - See also `awesome-cli-app <https://github.com/anki-code/xonsh-awesome-cli-app>`_ and
the command line arguments in your script. Next try `xontrib-argcomplete <https://github.com/anki-code/xontrib-argcomplete>`_ .
`xontrib-argcomplete <https://github.com/anki-code/xontrib-argcomplete>`_ to activate
tab completion for your script.
* - ``complete`` * - ``complete``
- ``completer list`` - ``completer list``
- As with many other shells, xonsh ships with the ability to complete partially-specified arguments - As with many other shells, xonsh ships with the ability to complete partially-specified arguments
upon hitting the “tab” key. upon hitting the “tab” key.
* - OhMyBash or BashIt * - OhMyBash or BashIt
- `Xontribs <https://xon.sh/xontribs.html>`_ - `awesome-xontribs <https://github.com/xonsh/awesome-xontribs>`_
- Xontributions, or ``xontribs``, are a set of tools and conventions for extending the functionality - Xontributions, or ``xontribs``, are a set of tools and conventions for extending the functionality
of xonsh beyond what is provided by default. of xonsh beyond what is provided by default.
* - Display completions as list * - Display completions as list

23
news/last_cp.rst Normal file
View file

@ -0,0 +1,23 @@
**Added:**
* Now last executed CommandPipeline is available in ``__xonsh__.last``.
**Changed:**
* <news item>
**Deprecated:**
* <news item>
**Removed:**
* <news item>
**Fixed:**
* <news item>
**Security:**
* <news item>

View file

@ -566,6 +566,7 @@ class XonshSession:
self._completers = None self._completers = None
self.builtins = None self.builtins = None
self._initial_builtin_names = None self._initial_builtin_names = None
self.last = None # Last executed CommandPipeline.
@property @property
def aliases(self): def aliases(self):

View file

@ -966,7 +966,12 @@ def _run_command_pipeline(specs, cmds):
def _run_specs(specs, cmds): def _run_specs(specs, cmds):
cp = _run_command_pipeline(specs, cmds) cp = _run_command_pipeline(specs, cmds)
proc, captured, background = cp.proc, specs[-1].captured, cp.spec.background XSH.last, proc, captured, background = (
cp,
cp.proc,
specs[-1].captured,
cp.spec.background,
)
# For some reason, some programs are in a stopped state when the flow # For some reason, some programs are in a stopped state when the flow
# reaches this point, hence a SIGCONT should be sent to `proc` to make # reaches this point, hence a SIGCONT should be sent to `proc` to make