Skip to content
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

Support bash style alias's to support tab completion in command string aliases #12962

Open
TylerLeonhardt opened this issue Jun 14, 2020 · 20 comments
Labels
Issue-Enhancement the issue is more of a feature request than a bug KeepOpen The bot will ignore these and not auto-close WG-Engine core PowerShell engine, interpreter, and runtime WG-NeedsReview Needs a review by the labeled Working Group

Comments

@TylerLeonhardt
Copy link
Member

Summary of the new feature/enhancement

In bash, you can do alias's like so:

alias gb="git branch"

which is really useful for typing less.

In PowerShell we can do:

function gb {
    git branch @args
}

But here's why bash's are so much better:
image

tab completion still works. Where as for PowerShell they don't.

By not supporting this in some way, it means that alias's to native executables are better in bash because the experience is more fluid.

Also, the function approach that we have means we lose out on the work @rjmholt did in UnixCompleters.

Proposed technical implementation details (optional)

Perhaps a new kind of alias that will funnel tab completion all the way down to the alias'd command string?

Set-Alias gb 'git branch' -AliasType CommandString # vs ... CommandLiteral or something... naming is hard but you get the idea
@TylerLeonhardt TylerLeonhardt added the Issue-Enhancement the issue is more of a feature request than a bug label Jun 14, 2020
@p0W3RH311
Copy link

In PowerShell we can do:

function gb {
    git branch @args
}

and if someone add gb alias it shadow your gb function. dont work as expected.

@iSazonov iSazonov added the WG-Engine core PowerShell engine, interpreter, and runtime label Jun 15, 2020
@SeeminglyScience
Copy link
Collaborator

This is pretty much the first thing people (including myself) try to do with aliases. I've seen countless threads/discord conversations with a ton of folks tripping on this.

I'm tempted to say that Set-Alias should do this automatically if the definition:

  1. Has spaces
  2. Doesn't resolve to a existing command
  3. Has a first "part" that does resolve

@doctordns
Copy link
Contributor

This is pretty much the first thing people (including myself) try to do with aliases. I've seen countless threads/discord conversations with a ton of folks tripping on this.

Really? The first thing you do is to do complex aliasing?

An alias is a short cut to a command name only and has been since V1. And in all the years I have moderated the PowerShell forum on Spiceworks this is not a highly requested feature. There have been requests but certainly not many.

I'd say this might be a nice to have - but only if the implementation does not break things.

@rjmholt
Copy link
Collaborator

rjmholt commented Jun 16, 2020

If we pull on this string a bit:

  • How does the AST capture something like set-alias gb 'git branch', what gets passed in to existing mechanisms for argument completion or pseudoparameterbinding?
  • What happens in the following cases:
    • set-alias gb 'git bran'
    • set-alias gc 'git commit --a'
    • set-alias gc 'git commit --'
    • set-alias gi 'get-item -path'
    • set-alias gi 'get-item -f'
    • set-alias gi 'get-item -'
    • set-alias gi 'get-item @('

Basically, I'd like to understand where the breakdown lies between PowerShell's parser/AST design vs bash's expand and execute approach. Once we have a better understanding of that, we'll be better placed to evaluate whether this feature is achievable.

@SeeminglyScience
Copy link
Collaborator

@rjmholt I don't think the parser would need to change. Just the parameter binder and possibly a new CommandInfo (or alternatively, just some different code in AliasInfo.Parameters). Well I say "just" but it's a pretty substantial work item, though I think it's worth it.

For native command argument completers, it might be fine to just expand the text and reparse before invoking them. Kinda dirty, but maybe doable just for completions.

@TylerLeonhardt
Copy link
Member Author

TylerLeonhardt commented Jun 16, 2020

@doctordns

Really? The first thing you do is to do complex aliasing?

Yes. People who came from bash/zsh/fish will do this.

Take a look at this guide:
https://www.netlify.com/blog/2020/04/12/speed-up-productivity-with-terminal-aliases/

every single example is complex in the sense that it's a command string and not a particular command.

Netlify
Want to increase developer productivity? Then create terminal aliases! Check out this guide to learn how to create bash aliases for git commands and more, making full use of your `.bash_profile`.

@rjmholt rjmholt modified the milestone: 6.2-approved Jun 16, 2020
@SeeminglyScience
Copy link
Collaborator

Really? The first thing you do is to do complex aliasing?

I'm pretty sure the first alias I tried to make way back when was to ipconfig /all. I know that fits well into a function as well, but I don't think I'd call Set-Alias dap 'dotnet add package' all that complex.

And in all the years I have moderated the PowerShell forum on Spiceworks this is not a highly requested feature. There have been requests but certainly not many.

Haven't heard of Spiceworks, but I see it a lot on reddit/discord. It's up there with Select-Object -Property vs ExpandProperty in starter walls.

I'd say this might be a nice to have - but only if the implementation does not break things.

That's fair, luckily I'm pretty sure breaks won't be needed for it.

@rjmholt
Copy link
Collaborator

rjmholt commented Jun 16, 2020

@rkeithhill
Copy link
Collaborator

rkeithhill commented Jul 8, 2020

Perhaps a more PowerShelly way to implement this would be to add a parameter like -Parameters e.g:

set-alias gc git -parameters commit, "--a"
# OR maybe -Parameters allows a single string with all parameters?
set-alias gc git -parameters "commit --a"

@doctordns
Copy link
Contributor

That would work for many cases, but doesn't handle 'weird' syntax, so you probably still need to have --% for those any way. I like the & --% idea as it reuses the existing operator.

@vexx32
Copy link
Collaborator

vexx32 commented Jul 8, 2020

It would handle it just the same way as you'd need to handle it even if there wasn't a separate -Parameters thing to work with.

You'd probably have to wrap everything in quotes there; you can't directly use %-- for this since you're passing data to a cmdlet, not a native executable, so you don't really have the option of not using PS's parsing rules for the input.

@r-darwish
Copy link

Another approach is Fish abbreviations. Implementing them might be simpler in terms of auto completion because they work by expanding the alias at the prompt itself.

@daxian-dbw
Copy link
Member

Quote from PowerShell/PSReadLine#1753 (comment):

IMO this is more of an editor feature (command line or other) that shouldn't require any PowerShell engine support.

We may consider supporting this in PSReadLine instead of PowerShell engine, so that it stays as an interactive feature only and won't be supported in a script execution.

@SteveL-MSFT SteveL-MSFT modified the milestones: 7.2-Consider, 7.3-Consider Dec 7, 2020
@TylerLeonhardt
Copy link
Member Author

@daxian-dbw this means that intellisense in vscode won't get this feature.

@rkeithhill
Copy link
Collaborator

@TylerLeonhardt True, but then PSSA will just turn around and tell you that you shouldn't be using aliases in scripts. 😉

@ratijas
Copy link

ratijas commented Jun 26, 2021

Really? The first thing you do is to do complex aliasing?

Yes. People who came from bash/zsh/fish will do this.

I'd like to add, this difference in mindsets comes from the fact that commands in UNIX land (unlike PowerShell) are usually already short enough that you won't need to alias them. So the primary use case indeed is for stacking up some commonly used arguments.

This one might as well be my favorite one:

alias glola="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all"

@doctordns

@liang2zhu1
Copy link

Just want to add a pressing scenario that can't easily implement without aliasing -

Ttrying to implement a 'Take top one' function and following would only work functionally but have bad perf.

PS C:\Users\liangzhu> function toponef {$input | Select-Object -First 1}
PS C:\Users\liangzhu> 1,2,3 | toponef
1

This brings a performance penalty in the case of pipeline input - if I run dir c:\ -s | topeonef it will get to wait for the base stream completes (Compare to that - dir c:\ -s | Selelct-Object -First 1 works just fine doing early termination)

More in #15855 on the technical challenge to get parity in function

@iSazonov
Copy link
Collaborator

iSazonov commented Aug 3, 2021

Just want to add a pressing scenario that can't easily implement without aliasing -

"filter" function works more fast. :-)

@microsoft-github-policy-service microsoft-github-policy-service bot added Resolution-No Activity Issue has had no activity for 6 months or more labels Nov 16, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot removed this from the 7.3-Consider milestone Nov 23, 2023
@kilasuit kilasuit reopened this Feb 13, 2024
@kilasuit
Copy link
Collaborator

reopening as I think there is value in having this in future irrespective of however it gets implemented

@microsoft-github-policy-service microsoft-github-policy-service bot removed the Resolution-No Activity Issue has had no activity for 6 months or more label Feb 13, 2024
@SteveL-MSFT SteveL-MSFT added KeepOpen The bot will ignore these and not auto-close WG-NeedsReview Needs a review by the labeled Working Group labels Apr 29, 2024
@mklement0
Copy link
Contributor

mklement0 commented May 6, 2024

Let me try a summary of sorts:

Supporting Bash-style alias definitions would provide the following benefits:

  • Ease of definition, closer alignment with POSIX-compatible shells.

    • The most frictionless syntax is the one suggested by @SeeminglyScience above, so that, say,
      Set-alias gb 'git branch' would just work, with no need for additional parameters.
  • If implemented as such, such enhanced aliases could provide implicit pipeline-input support with support for streaming processing (line by line), whereas using a function to support that currently requires a cumbersome implementation as a proxy function based on a steppable pipeline (because a function based on $input invariably collects all input up front; note that use of a filter is not an option in this case).

The tab-completion aspect is really an independent one, and for current aliases, which are merely name mappings, already works for PowerShell target commands, but not for external (native) programs.

Given that the proposal at hand also requires the enhanced aliases to know the external executable name, fixing the above asymmetry could also provide tab-completion support for enhanced aliases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement the issue is more of a feature request than a bug KeepOpen The bot will ignore these and not auto-close WG-Engine core PowerShell engine, interpreter, and runtime WG-NeedsReview Needs a review by the labeled Working Group
Projects
None yet
Development

No branches or pull requests

16 participants