oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.01k stars 2.66k forks source link

implement completions for powershell #8939

Open paperdave opened 6 months ago

paperdave commented 6 months ago

It is possible to declare completions: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter?view=powershell-7.4

Probably wont have this for Bun 1.1, but logging the issue so it is not forgotten.

Tagging this as windows as almost all users use powershell on windows, and not on mac and linux, but this is technically an all-platforms situation.

bcdev-com commented 5 months ago

A consideration before accepting this.

As someone who uses PowerShell as their daily driver, if a tool silently adds a thousand lines of script to the end of my profile.ps1 without warning or consent, I'll instantly ban it from all systems I'm responsible for, no matter it's other merits.

Truth is, there's some pretty unpleasant PowerShell used in install.ps1 as well, but I could probably ignore the rest of it.

bcdev-com commented 5 months ago

Entirely separate from the previous comment, before installing completions at all, it is important to understand the difference between profile.ps1 and Microsoft.PowerShell_profile.ps1. It's probably the latter that you would want to offer to at a single line calling your external completion script to, not the former.

paperdave commented 5 months ago

if a tool silently adds a thousand lines of script to the end of my profile.ps1 without warning or consent, I'll instantly ban it from all systems I'm responsible for, no matter it's other merits.

interesting. bun's bash install script currently does this, which some people very much do not like.

Truth is, there's some pretty unpleasant PowerShell used in install.ps1 as well

i remember having to do many weird things in this script to get the script to work reliably on all testing devices as well as report helpful errors when possible (one example is irm is slow in powershell 5, but curl sometimes fails, and iwr can fail on newly installed systems). im very interested in what specifically you find unpleasant.

bcdev-com commented 5 months ago

interesting. bun's bash install script currently does this, which some people very much do not like.

The best practice version would be something more like the dotnet SDK does. PowerShell completions for their CLI are handled by invoking the CLI itself from a tiny bit of PowerShell. Like this:

Register-ArgumentCompleter -Native -CommandName dotnet {
    param($commandName, $wordToComplete, $cursorPosition)
    dotnet complete --position $cursorPosition "$wordToComplete" | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}

And PowerShell has differently named 'profile' scripts depending on which host is running PowerShell, if you really want to append stuff to the script automatically, it would probably be better to use the current value of $profile, which in the common interactive console host is Microsoft.PowerShell_profile.ps1, not profile.ps1. You certainly don't want your completions being loaded into non-interactive hosts.

i remember having to do many weird things in this script to get the script to work reliably on all testing devices as well as report helpful errors when possible (one example is irm is slow in powershell 5, but curl sometimes fails, and iwr can fail on newly installed systems). im very interested in what specifically you find unpleasant.

It is a long list. I'd like to see bun succeed on Windows though, so happy to help if you are interested. Do you want me to ramble on here, or is there a better place?

A big first question would be, are you sure there's merit in supporting PowerShell 5? It is a quite different environment, and yes, it's pre-installed, but I'd be surprised if many Windows developers who prefer command line environments are still using it instead of 6 or 7. And of course, if you are concerned about supporting older systems, the real curl wasn't included with Windows until three years into Windows 10s lifecycle. That may be why it is failing in some cases for you.

paperdave commented 4 months ago

The best practice version would be something more like the dotnet SDK does.

this is reasonable, so the powershell version of autocompletions for us would be implemented in zig. it reminds me there is already a bun getcompletes command but i dont think it is properly setup for this. it would have to be modified on windows.

Do you want me to ramble on here, or is there a better place?

maybe would be good as a separate issue. please tag me in it so it pops up in my inbox, otherwise i wont see it.

this issue will remain for implementing completions for windows

Are you sure there's merit in supporting PowerShell 5

I want to ensure that any version past Windows 10 1809 is able to install Bun without any extra work, though the c++ redistributable is required (see #8598 for eliminating this).

I'd be surprised if many Windows developers who prefer command line environments are still using it instead of 6 or 7

I would be too, but I expect that if this didn't work out of the box, people would report "bugs" about it, not even realizing what PowerShell 7 vs 5 means. Because of that, the script has to be idiot proof and impossible to fail, which means making it work on powershell 5

There used to be these sorts of things with the linux installer, where the mistake should be obvious, but a small percent of users are confused and ask for help.

real curl wasn't included with Windows until three years into Windows 10s lifecycle. That may be why it is failing in some cases for you.

that may be it. i have this weird fallback thing in the script right now that covers for it. i noticed curl.exe was faster than powershell 5 invoke-restmethod, so i still try it

paperdave commented 4 months ago

Also, if you would like to contribute to the install script, that would be appreciated. However, there was one done in the past, but I rejected it because it dropped PowerShell 5 support.

ShaunLawrie commented 4 months ago

I added another attempt at this using a slightly different approach. The completers for all shells seem to be manually maintained when it would be better long term for bun getcompletes to do most of the heavy lifting. https://github.com/oven-sh/bun/pull/10424

As someone who uses PowerShell as their daily driver, if a tool silently adds a thousand lines of script to the end of my profile.ps1 without warning or consent, I'll instantly ban it from all systems I'm responsible for, no matter it's other merits.

It uses the current profile so as not to pollute non-interactive hosts and is a one-liner to make it easier to cleanup. It's dot sourcing an external completion script stored in the users ~/.bun dir because there's no sane cross platform place to put completion scripts in pwsh.

try { . ~/.bun/bun.completion.ps1 } catch { Write-Warning 'Failed to load bun autocompletion' }

I'm not 100% sure on how dirty I feel extracting the flags output from bun --help but the alternative of hard coding the current state of the flags in the shell completion script is worse IMO.

this is reasonable, so the powershell version of autocompletions for us would be implemented in zig

You could do something like bun getcompletes "bun run --" from any shell and it would do the autocomplete in getcompletes then all the shell completion scripts would be very simple - I think this is how complete for things like kubectl/aws work at a high level. But the reality is that's a lot of work to do for what is not a huge ROI so the current state might be good enough until someone wants to tackle shell completion in a general sense.