-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for xonsh #2807
Conversation
I'm using a local build of starship while I'm waiting for starship/starship#2807 to be merged. The debug build is slower-enough that I can sometimes notice the delay.
Merging to pick up lint fixes.
starship does not have built-in support for xonsh yet, but there are multiple open efforts to add it, including a PR I opened recently: starship/starship#2807 Until that PR lands, I'm switching to using my patched version. (I was already using a patched version on my mac, which I built locally. Better to override it in the nix config so I automatically get it on other machines too.)
@vladimyr and @anki-code you have both been working on xonsh support would you be able to take a quick look at this and add your thoughts. |
@andytom looks good! Thank you for this! You can also take a short look into xontrib-prompt-starship to compare your and my implementation. |
Thanks @anki-code! The two implementations are very similar. For reference, here they are side-by-side. def starship_prompt():
last_cmd = __xonsh__.history[-1] if __xonsh__.history else None
status = last_cmd.rtn if last_cmd else 0
jobs = len(__xonsh__.all_jobs)
duration = round((last_cmd.ts[1] - last_cmd.ts[0]) * 1000) if last_cmd else 0
return $(::STARSHIP:: prompt --status=@(status) --jobs=@(jobs) --cmd-duration=@(duration)) def _starship_prompt(cfg=None):
with __xonsh__.env.swap({'STARSHIP_CONFIG': cfg} if cfg else {}):
return __xonsh__.subproc_captured_stdout([
'starship', 'prompt',
'--status', str(int( __xonsh__.history[-1].rtn)) if len(__xonsh__.history) > 0 else '0',
'--cmd-duration' , str(int((__xonsh__.history[-1].ts[1] - __xonsh__.history[-1].ts[0])*1000)) if len(__xonsh__.history) > 0 else '0',
'--jobs', str(len(__xonsh__.all_jobs))
]) |
Also please take a look into these fixes: __xonsh__.env['STARSHIP_SHELL'] = 'sh' # Fix https://github.com/anki-code/xontrib-prompt-starship/issues/1
__xonsh__.env['STARSHIP_SESSION_KEY'] = __xonsh__.subproc_captured_stdout(['starship','session']).strip() |
And I'm using xonsh subprocess call from the library ( |
Thanks for the pointers. I added This PR already sets Re: pure python, I don't understand how starship benefits from having this code be translatable to python bytecode. Is there any immediate benefit to starship? If not, I think it makes sense to leave the init script here in xonsh syntax, since that syntax is cleaner. |
Nope, you can leave the xonsh syntax.
Good! Thanks! |
src/init/starship.xsh
Outdated
|
||
$PROMPT = starship_prompt | ||
$STARSHIP_SHELL = "xonsh" | ||
$STARSHIP_SESSION_KEY = "".join(random.choice(string.ascii_letters + string.digits) for _ in range(16)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting a NameError: name 'random' is not defined
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reproduced on my end.
I'm pretty confused by xonsh's behavior here. I've reduced some of the surprising behavior to a minimal example and asked about it on the xonsh gitter: https://gitter.im/xonsh/xonsh?at=60e7d763951c58084ecb7108
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a work around you could use the uuid module from the python std library. I think this would be enough we just need a unique id for each session
srt(uuid.uuid4())
# or
uuid.uuid4().hex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks for that suggestion.
src/init/starship.xsh
Outdated
def starship_prompt(): | ||
last_cmd = __xonsh__.history[-1] if __xonsh__.history else None | ||
status = last_cmd.rtn if last_cmd else 0 | ||
jobs = len(__xonsh__.all_jobs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After running any command the jobs will sometimes display for me, with only the starship init in my .xonshrc
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting job accounting right in xonsh apparently requires regularly calling _clear_dead_jobs
.
We could accomplish that here by calling get_next_job_number
. In fact, #1265 did exactly that.
Unfortunately, due to what I believe is the same issue as above, we're pretty limited here: we can't use any imported functions or even any names we define outside of this function. As a workaround, I've duplicated enough of the relevant logic in _clear_dead_jobs
to ignore dead jobs in our count here.
After running any command the jobs will sometimes display for me, with only the starship init in my .xonshrc.
Incidentally, I reproduced this on xonsh 0.9.27 but not on xonsh's latest main branch. But I don't understand why they would be different. 🤷🏻♂️
src/init/starship.xsh
Outdated
# but we can't use that function because of https://gitter.im/xonsh/xonsh?at=60e8832d82dd9050f5e0c96a | ||
jobs = sum(1 for job in __xonsh__.all_jobs.values() if job['obj'] and job['obj'].poll() is None) | ||
duration = round((last_cmd.ts[1] - last_cmd.ts[0]) * 1000) if last_cmd else 0 | ||
return $(::STARSHIP:: prompt --status=@(status) --jobs=@(jobs) --cmd-duration=@(duration)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that $STARSHIP_SESSION_KEY
works I've found another issue:
Log messages (stderr) from starship don't get displayed (invalid config file). Maybe it needs a workaround like this for PowerShell?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems to work for me when using https://github.com/anki-code/xontrib-prompt-starship latest and
@ xonsh --version
xonsh/0.9.27
@ python -V
Python 3.9.2
@ starship --version
starship 0.55.0
tag:v0.55.0
commit_hash:09b12a52
build_time:2021-06-20 18:31:06
build_env:rustc 1.53.0 (53cb7b09b 2021-06-17)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, @davidkna.
This was fixed upstream in xonsh just three weeks ago: xonsh/xonsh#4336
But since no released versions of xonsh contain that fix, we should probably work around it here. I've added a workaround: 1e0bc8d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Description
Adds
xonsh
init script.Motivation and Context
This is basically #1265 with merge conflicts resolved and a slightly different implementation of job count.
#1265 got stuck on two issues, which I believe are both now resolved:
NameError: name 'get_next_job_number' is not defined
I worked around this by using
len(__xonsh__.all_jobs)
rather thanget_next_job_number
. h/t @anki-code for that implementation.Seems to now be resolved upstream? The upstream issue isn't closed, but some fix PRs have been merged, and I didn't encounter this problem while testing.
Closes #2704
Closes #1265
Closes #272
Screenshots (if appropriate):
How Has This Been Tested?
Checklist: