194

Let's say I have the following files in my current directory:

buildBar.bat
buildFoo.bat
buildHouse.bat

And I type the following at my command prompt, ./bu and then TAB.

  • In Bash, it gets expanded to ./build

  • In PowerShell, it gets expanded to ./buildBar.bat -- the first item in the list.

  • In Cmd, the behavior is the same as PowerShell.

I prefer the Bash behaviour - is there a way to make PowerShell behave like Bash?

RobSiklos
  • 8,348
  • 5
  • 47
  • 77
  • 14
    Yes - that's what I've been doing for the last decade or so, but I'm trying to transition to PowerShell, because I want to be able to fly on the command line on systems other than my own, where Cygwin isn't installed. – RobSiklos Nov 28 '11 at 13:41

8 Answers8

311

New versions of PowerShell include PSReadline, which can be used to do this:

Set-PSReadlineKeyHandler -Key Tab -Function Complete

or, to make it even more like bash where you can use arrow-keys to navigate available options:

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete

To make it permanent, put this command into your powershell profile, defined by $PROFILE (usually %UserProfile%\Documents\WindowsPowerShell\profile.ps1 for Windows PowerShell 5.x and %UserProfile%\Documents\PowerShell\profile.ps1 for PowerShell 6+).

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
svick
  • 236,525
  • 50
  • 385
  • 514
  • I am missing the completion as far as the completion could be done with this approach. Example: Having a list of commands "Start-Service", "Start-Job" and "Stop-Service" and typing "S" + TAB I except to get a completion to "St" and no list. – Adrian Dymorz Apr 10 '17 at 10:50
  • 68
    `MenuComplete` instead of `Complete` is more like bash, it lets you use the arrow keys to choose from the available options – stib Aug 17 '17 at 02:28
  • This was not included in PowerShell 5.1, I think you need to Import-Module PSReadline or Install-Module PSReadline first. – LeBleu Oct 31 '17 at 23:15
  • 1
    @LeBleu That's weird, because my brand new Windows 10 machine came with PSReadline. I thought the module was from Microsoft. – Franklin Yu Nov 09 '17 at 17:59
  • 17
    BTW, if the profile.ps1 file does not exist on your machine, you can generate one with a command `new-item $profile -itemtype file -force` – Reinis Dec 12 '17 at 12:09
  • "New versions" What numbers? 4? 5? – jpmc26 May 11 '18 at 09:50
  • 5
    It is very likely that your machine will not have `C:\Users\[User]\Documents\WindowsPowerShell\profile.ps1.` You actually need to run `new-item $profile -itemtype file -force` – R.F Jan 18 '19 at 00:34
  • Running this on Windows 10 1809, I get the error `Set-PSReadlineKeyHandler : The type initializer for 'Microsoft.PowerShell.PSConsoleReadLine' threw an exception.`, with no other information. I verified that the module is installed. What have done wrong? – Hey Jan 28 '19 at 15:09
  • 31
    That's a really inconvenient spelling for `touch` :-( – SamB May 15 '19 at 02:59
  • 4
    Instead of needing to generate a new profile, can't you just do `notepad $profile` and save it? It'll complain about it not existing but you'll be good once you save the file. – Ben Thul Feb 25 '20 at 15:37
  • @BenThul not if the directory the file goes into also doens't exist (which is also where `touch` would fail so SamB's comment isn't entirely accurate). That's what the `-Force` does. The `-ItemType File` isn't strictly needed here. – stijn Apr 01 '21 at 18:46
  • @stib it is not – IC_ Apr 21 '21 at 02:54
  • @BenThul is right. And if you have VS Code installed, you can likewise do `code $profile` and then edit/save to create the file. – jschmitter Sep 30 '21 at 18:54
  • Thanks, this is awesome, made my day! I was wondering why the Powershell had this weird behaviour in the first place (picking the first file by default). Just does not make sense (and coming from bash, it was just annoying) – Ingmar Aug 08 '22 at 11:20
30

tab only completes the command name not its previous arguments/parameters.

to also autocomplete the complete command with arguments from history set the below keybinding.

Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward

Now, type few characters of command name and use up/down arrow to autocomplete this command (with arguments) from history.

real time saver.


See more: Power up your PowerShell

GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
29

It is now possible to get PowerShell to do Bash-style completion, using PSReadline.

Check out blog post Bash-like tab completion in PowerShell.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
  • 4
    The link in the blogpost is broken, however at the end of the day it brings you to [PsReadline (last commit in 2012)](https://bitbucket.org/oising/psreadline/) which has been [forked (last commit in 2013)](https://github.com/lzybkr/PSReadLine) – GameScripting Oct 17 '13 at 08:00
  • 6
    Nowadays you can do this with a one-liner, as described here: http://stackoverflow.com/a/37715242/24874 – Drew Noakes Nov 06 '16 at 00:36
15

Take a look here, not really your desiderata:

PowerTab

but I think is the best tab expansion feature for PowerShell console!!!

Animesh
  • 4,926
  • 14
  • 68
  • 110
CB.
  • 58,865
  • 9
  • 159
  • 159
  • Interesting. If there's a way to do something like that, then it seems quite possible to make the expansion work like in bash. I'm far from being an expert in PowerShell, though, so may be missing something. – Andriy M Nov 25 '11 at 09:57
  • Sure! Start studying the PowerTab Module's code to try doing your expansion needs. But PowerTab offers expansions for almost any command, wmi, comobject, assembly with a easy selection way! – CB. Nov 25 '11 at 10:04
12
# keep or reset to powershell default
Set-PSReadlineKeyHandler -Key Shift+Tab -Function TabCompletePrevious

# define Ctrl+Tab like default Tab behavior
Set-PSReadlineKeyHandler -Key Ctrl+Tab -Function TabCompleteNext

# define Tab like bash
Set-PSReadlineKeyHandler -Key Tab -Function Complete
徐志鹏
  • 121
  • 1
  • 3
6

Modify the TabExpansion function to achieve what you want. Remember that perhaps it completes till the end if you press tab again the new suggestion modify from where you originally press the key. I strongly prefer the actual behaviour, I want the line writted as fast as possible. Finally don't forget the wildcard expansion, for example: bu*h[Tab] automatically completes to buildHouse.bat

mjsr
  • 7,410
  • 18
  • 57
  • 83
  • Modifying the TabExpansion function is probably the way to go, still a lot more complicated than what I was looking for though. I think I'll need to get way more fluent in powershell before I'm able to mess around with that. – RobSiklos Nov 25 '11 at 14:18
4

With Powershell Core we can set the PredictionSource property for PSReadLine as History to get auto suggestion. Refer to the YouTube video for more details https://youtu.be/I0iIZe0dUNw

Nilesh Gule
  • 1,511
  • 12
  • 13
1

Actually, bash behavior is governed by /etc/inputrc, which varies heavily from distro to distro.

So here's how to make PowerShell behave more like a bash with sane defaults (Gentoo, CentOS)

# Press tab key to get a list of possible completions (also on Ctrl+Space)

Set-PSReadlineKeyHandler -Chord Tab -Function PossibleCompletions


# Search history based on input on PageUp/PageDown

Set-PSReadlineKeyHandler -Key PageUp -Function  HistorySearchBackward
Set-PSReadlineKeyHandler -Key PageDown -Function HistorySearchForward


# If you feel cursor should be at the end of the line after pressing PageUp/PageDown (saving you an End press), you may add:

Set-PSReadLineOption -HistorySearchCursorMovesToEnd

# Set-PSReadLineOption -HistorySearchCursorMovesToEnd:$False to remove
Anubioz
  • 435
  • 7
  • 13