diff --git a/docs/xonshrc.py b/docs/xonshrc.py new file mode 100644 index 000000000..9ef7ced90 --- /dev/null +++ b/docs/xonshrc.py @@ -0,0 +1,23 @@ +from xonsh.built_ins import XSH + +env = XSH.env +# adjust some paths +env["PATH"].append("/home/scopatz/sandbox/bin") +env["LD_LIBRARY_PATH"] = ["/home/scopatz/.local/lib", "/home/scopatz/miniconda3/lib"] + +# alias to quit AwesomeWM from the terminal +def _quit_awesome(args, stdin=None): + print("awesome python code") + + +XSH.aliases["qa"] = _quit_awesome +# setting aliases as list are faster since they don't involve parser. +XSH.aliases["gc"] = ["git", "commit"] + +# some customization options, see https://xon.sh/envvars.html for details +env["MULTILINE_PROMPT"] = "`·.,¸,.·*¯`·.,¸,.·*¯" +env["XONSH_SHOW_TRACEBACK"] = True +env["XONSH_STORE_STDOUT"] = True +env["XONSH_HISTORY_MATCH_ANYWHERE"] = True +env["COMPLETIONS_CONFIRM"] = True +env["XONSH_AUTOPAIR"] = True diff --git a/docs/xonshrc.rst b/docs/xonshrc.rst index fd0e6c03f..6bb4133bd 100644 --- a/docs/xonshrc.rst +++ b/docs/xonshrc.rst @@ -1,7 +1,9 @@ Run Control File ========================= Xonsh allows you to customize your shell behavior with run control files, called "xonshrc" files. -These files are written in the xonsh language (a superset of Python) and are executed exactly once at startup. +These files are written either in the Xonsh language (a superset of Python) or in Python and are executed +exactly once at startup. + The control file usually contains: * Assignment statements setting `environment variables `_. This includes standard OS environment variables that affect other programs and many that Xonsh uses for itself. @@ -19,7 +21,7 @@ The options set per user override settings in the system-wide control file. Xonsh also supports configuration directories, from which all ``.xsh`` files will be sourced in order. This allows for drop-in configuration where your configuration can be split across scripts and common and local configuration more easily separated. By default, if the directory ``~/.config/xonsh/rc.d`` -exists, any ``xsh`` files within will be sourced at startup. +exists, any ``*.xsh`` files within will be sourced at startup. Xonsh provides 2 wizards to create your own "xonshrc". ``xonfig web`` provides basic settings, and ``xonfig wizard`` steps you through all the available options. @@ -167,6 +169,18 @@ The following is a real-world example of such a file. :code: xonsh +Real world sample rc.py +------------------------- + +The following is a real-world example of such a file. +This can be set by ``env XONSHRC=rc.py xonsh`` or ``xonsh --rc=rc.py`` + +:download:`Download rc.py ` + +.. include:: xonshrc.py + :code: xonsh + + Snippets for xonshrc -------------------- diff --git a/news/py-rc-files.rst b/news/py-rc-files.rst new file mode 100644 index 000000000..36ccc1996 --- /dev/null +++ b/news/py-rc-files.rst @@ -0,0 +1,24 @@ +**Added:** + +* Pure Python control files are now supported when named ``*.py``. + Using python files may lower the startup time by a bit. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/requirements/tests.txt b/requirements/tests.txt index 058fde024..ebf0ceabc 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -5,6 +5,7 @@ flake8-docstrings flake8-bugbear restructuredtext_lint pytest-cov +pytest-mock pytest-timeout pytest-subprocess prompt-toolkit>=3.0 diff --git a/tests/test_main.py b/tests/test_main.py index b7ed24d1e..0f4385490 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -12,7 +12,7 @@ import sys import xonsh.main from xonsh.main import XonshMode import pytest -from tools import ON_WINDOWS, TEST_DIR, VER_FULL, skip_if_on_windows +from tools import ON_WINDOWS, TEST_DIR, skip_if_on_windows def Shell(*args, **kwargs): @@ -90,6 +90,30 @@ def test_rc_with_modules(shell, tmpdir, monkeypatch, capsys, xession): assert tmpdir.strpath not in sys.path +def test_python_rc(shell, tmpdir, monkeypatch, capsys, xession, mocker): + """Test that python based control files are executed using Python's parser""" + + monkeypatch.setattr(sys.stdin, "isatty", lambda: True) + monkeypatch.setitem(os.environ, "XONSH_CACHE_SCRIPTS", "False") + + # spy on xonsh's compile method + spy = mocker.spy(xession.execer, "compile") + + rc = tmpdir.join("rc.py") + rc.write("print('Hello World!')") + xonsh.main.premain(["--rc", rc.strpath]) + + assert rc.strpath in xession.rc_files + + stdout, stderr = capsys.readouterr() + assert "Hello World!" in stdout + assert len(stderr) == 0 + + # Check that the temporary rc's folder is not left behind on the path + assert tmpdir.strpath not in sys.path + assert spy.called == False + + def test_rcdir(shell, tmpdir, monkeypatch, capsys): """ Test that files are loaded from an rcdir, after a normal rc file, diff --git a/xonsh/codecache.py b/xonsh/codecache.py index 327e904d5..da7171ff8 100644 --- a/xonsh/codecache.py +++ b/xonsh/codecache.py @@ -105,6 +105,10 @@ def compile_code(filename, code, execer, glb, loc, mode): """ Wrapper for ``execer.compile`` to compile the given code """ + + if filename.endswith(".py") and mode == "exec": + return compile(code, filename, mode) + if not code.endswith("\n"): code += "\n" old_filename = execer.filename