xonsh/docs/faq.rst

192 lines
8.3 KiB
ReStructuredText
Raw Normal View History

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.
2015-07-25 01:46:15 -06:00
What xonsh does to overcome such ambiguity is to check if the left-most
2015-03-08 00:32:17 -06:00
name (``ls`` above) is in the present Python context. If it is, then it takes
the line to be valid xonsh as written. If the left-most name 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>`_