2017-08-13 21:48:26 -04:00
|
|
|
|
2015-03-07 20:50:43 -06:00
|
|
|
Frequently Asked Questions
|
|
|
|
==========================
|
|
|
|
Ok, so, maybe no one actually asked them.
|
|
|
|
|
|
|
|
1. Why xonsh?
|
|
|
|
-------------
|
2016-06-04 15:36:21 -04:00
|
|
|
The idea for xonsh first struck while I was reviewing the Bash chapter
|
2015-03-07 22:41:47 -06:00
|
|
|
(written by my co-author `Katy Huff <http://katyhuff.github.io/>`_)
|
2016-02-15 21:09:54 +01:00
|
|
|
of `Effective Computation in Physics <http://physics.codes/>`_. In the book,
|
2015-07-25 01:46:15 -06:00
|
|
|
we spend a bunch of time describing important, but complex ideas, such
|
2016-06-04 15:36:21 -04:00
|
|
|
as piping. However, we don't even touch on more 'basic' aspects of the Bash
|
|
|
|
language, such as if-statements or loops. Even though I have been using Bash
|
2015-03-07 22:41:47 -06:00
|
|
|
for well over a decade, I am not even sure I *know how*
|
|
|
|
to add two numbers together in it or consistently create an array. This is
|
|
|
|
normal.
|
|
|
|
|
|
|
|
If the tool is so bad, then maybe we need a new tool. So xonsh is really meant
|
2015-07-25 01:46:15 -06:00
|
|
|
to solve the problem that other shells don't "fit your brain."
|
2016-02-15 21:09:54 +01:00
|
|
|
In some programming situations this is OK because of what you get
|
2015-03-07 22:41:47 -06:00
|
|
|
(an optimizing compiler, type safety, provable correctness, register access).
|
|
|
|
But a shell that doesn't fit your brain is only a liability.
|
|
|
|
|
2015-07-25 01:46:15 -06:00
|
|
|
Coincidentally, within the week, `an article floated to the top of Hacker News <http://stephen-brennan.com/2015/01/16/write-a-shell-in-c/>`_
|
|
|
|
that teaches you how to write a shell in C. So I thought, "It can't be
|
2015-03-07 22:41:47 -06:00
|
|
|
that hard..."
|
|
|
|
|
|
|
|
And thus, `again <http://exofrills.org>`_, I entered the danger zone.
|
|
|
|
|
2015-03-07 20:50:43 -06:00
|
|
|
|
|
|
|
2. Why not another exotic shell, such as ``fish``?
|
|
|
|
-----------------------------------------------------
|
|
|
|
While many other alternative shells have an amazing suite of features
|
2015-07-25 01:46:15 -06:00
|
|
|
as well as much improved syntax of traditional options, none of them
|
|
|
|
are quite as beautiful as Python. In xonsh, you get the best of all possible
|
|
|
|
worlds. A syntax that already fits your brain and any features that you
|
2015-03-07 20:50:43 -06:00
|
|
|
desire.
|
|
|
|
|
2015-03-07 22:41:47 -06:00
|
|
|
|
2015-03-07 20:50:43 -06:00
|
|
|
3. Why not just use the IPython command line interface?
|
|
|
|
-------------------------------------------------------
|
2016-02-15 21:09:54 +01:00
|
|
|
There are two serious drawbacks to this approach - though, believe me, I have
|
2015-07-25 01:46:15 -06:00
|
|
|
tried it.
|
2015-03-07 20:50:43 -06:00
|
|
|
|
2015-07-25 01:46:15 -06:00
|
|
|
The first is that typing ``!`` before every subprocess command is
|
|
|
|
extremely tedious. I think that this is because it is a prefix operator and
|
|
|
|
thus gets in the way of what you are trying to do right as you start to try
|
|
|
|
to do it. Making ``!`` a postfix operator could address some of this, but
|
2015-03-07 20:50:43 -06:00
|
|
|
would probably end up being annoying, though not nearly as jarring.
|
|
|
|
|
|
|
|
The second reason is that tab completion of subprocess commands after an ``!``
|
2015-07-25 01:46:15 -06:00
|
|
|
does not work. This is a deal breaker for day-to-day use.
|
2015-03-08 00:32:17 -06:00
|
|
|
|
|
|
|
|
|
|
|
4. So how does this all work?
|
|
|
|
-----------------------------
|
2015-07-25 01:46:15 -06:00
|
|
|
We use `PLY <http://www.dabeaz.com/ply/ply.html>`_ to tokenize and parse
|
2015-03-08 00:32:17 -06:00
|
|
|
xonsh code. This is heavily inspired by how `pycparser <https://github.com/eliben/pycparser>`_
|
|
|
|
used this PLY. From our parser, we construct an abstract syntax tree (AST)
|
2015-07-25 01:46:15 -06:00
|
|
|
only using nodes found in the Python ``ast`` standard library module.
|
2015-03-08 00:32:17 -06:00
|
|
|
This allows us to compile and execute the AST using the normal Python tools.
|
|
|
|
|
2015-07-25 01:46:15 -06:00
|
|
|
Of course, xonsh has special builtins, so the proper context
|
|
|
|
(builtins, globals, and locals) must be set up prior to actually executing
|
|
|
|
any code. However, the AST can be constructed completely independently of
|
|
|
|
any context...mostly.
|
|
|
|
|
|
|
|
While the grammar of the xonsh language is context-free, it was convenient
|
|
|
|
to write the executer in a way that is slightly context sensitive. This is
|
|
|
|
because certain expressions are ambiguous as to whether they belong to
|
|
|
|
Python-mode or subprocess-mode. For example, most people will look at
|
|
|
|
``ls -l`` and see a listing command. However, if ``ls`` and ``l`` were
|
|
|
|
Python variables, this could be transformed to the equivalent (Python)
|
|
|
|
expressions ``ls - l`` or ``ls-l``. Neither of which are valid listing
|
2015-03-08 00:32:17 -06:00
|
|
|
commands.
|
|
|
|
|
2016-08-21 14:58:07 -04:00
|
|
|
What xonsh does to overcome such ambiguity is to check if the names in the
|
|
|
|
expression (``ls`` and ``l`` above) are in the present Python context. If they are,
|
|
|
|
then it takes
|
|
|
|
the line to be valid xonsh as written. If one of the names cannot be found,
|
2015-07-25 01:46:15 -06:00
|
|
|
then xonsh assumes that the left-most name is an external command. It thus
|
|
|
|
attempts to parse the line after wrapping it in an uncaptured subprocess
|
2016-04-09 00:41:06 -04:00
|
|
|
call ``![]``. If wrapped version successfully parses, the ``![]`` version
|
2016-02-15 21:09:54 +01:00
|
|
|
stays. Otherwise, the original line is retained.
|
2015-03-08 00:32:17 -06:00
|
|
|
|
2015-07-25 01:46:15 -06:00
|
|
|
All of the context sensitive parsing occurs as an AST transformation prior to
|
2015-03-08 00:32:17 -06:00
|
|
|
any code is executed. This ensures that code will never be partially executed
|
|
|
|
before failing.
|
|
|
|
|
2015-07-25 01:46:15 -06:00
|
|
|
It is critical to note that the context sensitive parsing is a convenience
|
|
|
|
meant for humans. If ambiguity remains or exactness is required, simply
|
2016-04-09 00:41:06 -04:00
|
|
|
manually use the ``![]``, ``!()``, ``$[]`` or ``$()`` operators on your code.
|
2015-03-08 00:32:17 -06:00
|
|
|
|
|
|
|
|
|
|
|
5. Context-sensitive parsing is gross
|
|
|
|
--------------------------------------
|
2016-06-09 22:52:41 -04:00
|
|
|
Yes, context-sensitive parsing is gross. But the point of xonsh is that it uses
|
|
|
|
xontext-sensitive parsing and
|
2016-06-04 15:36:21 -04:00
|
|
|
is ultimately a lot less gross than other shell languages, such as Bash.
|
2015-03-08 01:01:59 -06:00
|
|
|
Furthermore, its use is heavily limited here.
|
2016-04-29 08:52:31 -07:00
|
|
|
|
|
|
|
|
2016-06-09 22:52:41 -04:00
|
|
|
6. My Branches are Timing Out?!
|
|
|
|
-------------------------------
|
|
|
|
Depending on you system, setup, and repository sizes, computing branch names
|
|
|
|
and colors (i.e. if the branch is dirty or not), can be a pretty slow operation.
|
|
|
|
This is bad news because xonsh can try to compute these each time it formats
|
|
|
|
the ``$PROMPT``.
|
2016-04-29 08:52:31 -07:00
|
|
|
|
2016-06-09 22:52:41 -04:00
|
|
|
In order to keep xonsh snappy, we have implemented branch computation timeouts.
|
|
|
|
This is set to a nominal value (usually 0.1 sec) via the ``$VC_BRANCH_TIMEOUT``
|
|
|
|
environment variable.
|
|
|
|
|
|
|
|
Feel free to set this to any limit that you feel comfortable with. So if you
|
|
|
|
don't mind a potentially slow prompt, set it to 1, 5, 20, 100 seconds! However,
|
|
|
|
if you never want to deal with a slow prompt or seeing this timeout message,
|
|
|
|
you can remove the ``{curr_branch}``, ``{branch_color}`` and ``{branch_bg_color}``
|
|
|
|
portions of your ``$PROMPT``, and these values will never be computed.
|
|
|
|
|
|
|
|
It is also worth noting that ``{branch_color}`` is usually the slow poke.
|
|
|
|
Just removing the color lookup from the ``$PROMPT`` can still provide the branch
|
|
|
|
name while being fast enough.
|
|
|
|
|
2016-08-13 22:25:33 -04:00
|
|
|
7. exec
|
|
|
|
-------
|
|
|
|
The notion of ``exec`` is a bit of a tricky beast in xonsh. Both Python and
|
|
|
|
basically every other shell language have an exec that perform radically
|
|
|
|
different operations.
|
|
|
|
|
|
|
|
* In Python, ``exec`` is a builtin function that executes strings, ASTs, or
|
|
|
|
code objects in a provided namespace.
|
|
|
|
* In sh-langs (and elsewhere), ``exec`` is a command the runs another command
|
|
|
|
directly in the current process.
|
|
|
|
|
|
|
|
These two ideas are central to both languages - without which most programs
|
|
|
|
cannot be run. Luckily, even though they share a name, they have distinct
|
|
|
|
syntax and don't share a namespace. Therefore, in xonsh,
|
|
|
|
|
|
|
|
.. code-block:: xonshcon
|
|
|
|
|
|
|
|
# exec() as a function is run as Python's exec
|
|
|
|
>>> exec('x = 41; x += 1', globals(), locals())
|
|
|
|
|
|
|
|
# while exec as a statement is like bash's exec
|
|
|
|
>>> exec gdb
|
|
|
|
(gdb)
|
|
|
|
|
2016-08-13 22:27:29 -04:00
|
|
|
Yes, this is potentially confusing. This is particularly true since earlier
|
2016-08-13 22:25:33 -04:00
|
|
|
versions of Python *had* an exec statement whose syntax would have clashed
|
|
|
|
with the sh-lang command form.
|
|
|
|
|
2016-08-15 12:03:04 -04:00
|
|
|
Yes, we are sorry. But the alternative is that important programs that use
|
2016-08-13 22:25:33 -04:00
|
|
|
exec under the covers, such as SSH and gdb, would not be usable when xonsh
|
|
|
|
is set as the default shell. (Note that we can't rename the exec() function
|
|
|
|
since Python would fail.) As usability is the most important aspect of a shell,
|
|
|
|
xonsh trades a small amount of potential confusion for large class of important
|
|
|
|
commands.
|
2016-06-09 22:52:41 -04:00
|
|
|
|
2016-08-13 22:25:33 -04:00
|
|
|
All of the above being true, if the exec duality is causing you problems there
|
|
|
|
a few operations that you can implement to mitigate the confusion. The first is
|
2016-08-13 22:27:29 -04:00
|
|
|
that you can remove the ``exec`` alias and use the ``xexec`` alias instead:
|
2016-08-13 22:25:33 -04:00
|
|
|
|
|
|
|
.. code-block:: xonshcon
|
|
|
|
|
|
|
|
>>> del aliases['exec']
|
|
|
|
>>> xexec ssh
|
|
|
|
|
|
|
|
Alternatively, you can always be sure to run the exec command explicitly in
|
|
|
|
subprocess mode with ``![]`` or ``!()``:
|
|
|
|
|
|
|
|
.. code-block:: xonshcon
|
2016-04-29 08:52:31 -07:00
|
|
|
|
2016-08-13 22:25:33 -04:00
|
|
|
>>> ![exec bash]
|
|
|
|
|
2016-08-13 22:27:29 -04:00
|
|
|
Lastly, you can assign the result of the exec() function to a throw away
|
2016-08-13 22:25:33 -04:00
|
|
|
variable (since the return is always None):
|
|
|
|
|
|
|
|
.. code-block:: xonshcon
|
|
|
|
|
|
|
|
>>> _ = exec('x = 42')
|
|
|
|
|
2016-08-13 22:27:29 -04:00
|
|
|
Hopefully, though, this trade-off makes sense and you never have to worry about
|
2016-08-13 22:25:33 -04:00
|
|
|
it...unless chimera slaying is your bag.
|
|
|
|
|
|
|
|
8. Gotchas
|
|
|
|
----------
|
2016-04-29 08:52:31 -07:00
|
|
|
There are a few gotchas when using xonsh across multiple versions of Python,
|
|
|
|
where some behavior can differ, as the underlying Python might behave
|
|
|
|
differently.
|
|
|
|
|
|
|
|
For example double star globbing `**` will only work on Python 3.5+ (ie not on 3.4)
|
|
|
|
as recursive globbing is `new in Python 3.5 <https://docs.python.org/3/library/glob.html#glob.glob>`_
|