Skip to content

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

Open

Description

@TylerLeonhardt

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 Rob Holt (@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

Activity

  1. p0W3RH311 commented on Jun 14, 2020

    @p0W3RH311
    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.

  2. SeeminglyScience commented on Jun 16, 2020

    @SeeminglyScience
    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.

    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
  3. doctordns commented on Jun 16, 2020

    @doctordns
    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.

    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.

  4. rjmholt commented on Jun 16, 2020

    @rjmholt
    Collaborator

    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.

  5. SeeminglyScience commented on Jun 16, 2020

    @SeeminglyScience
    Contributor

    Rob Holt (@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.

  6. TylerLeonhardt commented on Jun 16, 2020

    @TylerLeonhardt
    MemberAuthor

    Thomas Lee (@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`.
  7. SeeminglyScience commented on Jun 16, 2020

    @SeeminglyScience
    Contributor

    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.

  8. rkeithhill commented on Jul 8, 2020

    @rkeithhill
    Collaborator

    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"
  9. doctordns commented on Jul 8, 2020

    @doctordns
    Collaborator

    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.

  10. vexx32 commented on Jul 8, 2020

    @vexx32
    Collaborator

    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.

  11. 7 remaining items

  12. ratijas commented on Jun 26, 2021

    @ratijas

    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"

    Thomas Lee (@doctordns)

  13. liang2zhu1 commented on Aug 2, 2021

    @liang2zhu1

    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

  14. iSazonov commented on Aug 3, 2021

    @iSazonov
    Collaborator

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

    "filter" function works more fast. :-)

  15. kilasuit commented on Feb 13, 2024

    @kilasuit
    Collaborator

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

  16. mklement0 commented on May 6, 2024

    @mklement0
    Contributor

    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.

    • 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.

  17. iRon7 commented on Jul 3, 2025

    @iRon7

    Another benefit would be that the PSScriptAnalyzer is able to identify and (automatically) replace aliases (in an IDE as VSCode) in formal scripts.

    Besides, a possible other way to implement such a feature could be by adding a -Definition parameter that is mutual exclusive with the -Value parameter, also resides at position 1, and only accepts ScriptBlocks. Which would than support syntaxes as:

    Set-Alias gc { git -parameters commit, "--a" }

    (I guess this is also safer which regards to code injections)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugKeepOpenThe bot will ignore these and not auto-closeWG-Enginecore PowerShell engine, interpreter, and runtimeWG-NeedsReviewNeeds a review by the labeled Working Group

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions