Package: zsh2xonsh
zsh2xonshHave you heard ofxonsh? It's a Python-powered shell.You can do amazing things like this:# Interpolate python -> shell
echo @(i for i in range(42))

# Interpolate shell -> python
for filename in `.*`:
    print(filename)
    du -sh @(filename)

# Execute regular shell commands too
cat /etc/passwd | grep rootAs you can immagine, this awesomeness is not POSIX-compliant :(This makes it difficult to setup your$PATHand do things likeeval $(brew shellenv)This package exists to translate traditionalzshscripts intoxonshcode.Compatibility (and how it works)The goal is 100% compatibility for asubsetof shell.Compatibility is achived by delegating most of the work to zsh.That is,export FOO="$(echo bar)"in a shell script becomes (essentially)$FOO=$(zsh -c 'echo bar')in xonsh.We havezshhandle all the globbing/quoting/bizzare POSIX quirks.In the face of ambiguity, or if we encounter an unsupported feature (like aforloop), then we fail-fast.This is the most important feature. If something can't be supported 100%, then it will throw a descriptive error. Anything else is a bug :)FeaturesThe included shell features include:Quoted expressions"$VAR glob/*"(zsh does expansion here)Unquoted literals12,foo~/foo(mostly translated directly)Command substitutions "$(cat file.txt | grep bar)"zsh does all the work hereSupports both quoted and unquoted formsIf/then statementsConditionals are executed by zsh (so[[ -d "foo" ]]works perfectly)Translated into python if (so body will not run unless conditional passes)Exporting variablesexport FOO=$BARTranslates$PATHcorrectly (xonsh thinks it's a list, zsh thinks it's a string)This is where the subprocess approach doesn't work blindly....We support it cleanly by doing the left-hand assignment xonsh, and the right-hand expression inzsh:)Local variables (local var=x) are supported too :)All of these behaviors are 100% compatible with their zsh equivalents.
If you try anything else (or encounter an unsupported corner case), then you will get a descripitive error :)Installation & UsageThis is a pypi package, install it withpip install zsh2xonsh.The API is simple, runtranslate_to_xonsh(str) -> strto translate fromzsh->xonshcode.
This does not require xonsh at runtime, and can be done ahead of time.If you want to evaluate the code immediately after translating it (for example in a.xonshrc), you can use
. This requires xonsh at runtime (obviously) and uses theevalxbuiltin.Additionally you can use the CLI (python -m zsh2xonsh), which accepts an import.If you want to provide extra utility functions to your code, you can defineextra_builtins.ExampleIn my.xonshrc, I dynamically translate and evaluate the output ofbrew shellenv:zsh2xonsh.translate_to_xonsh_and_eval($(/opt/homebrew/bin/brew shellenv))MotiviationFirst of all, I need support foreval $(brew shellenv).Second of all, I still usezshas my backup shell.This means I need to setup$PATHand other enviornment variables for both of these shells.The natural way to set these up is by using shell scripts.
I have a seperate one for each of my different machines (server, macbook, old lapotop, etc)For each of these (tiny) shell scripts,zsh2xonshworks very well :)So in addition to properly translating$(brew shellenv),
it also needs to translate basic shell "environement files".