how to get tab autocompletion to echo all possible options like bash? - powershell

In bash there's a nice feature that when a string is partially completed (like a path) and we use tab for autocompletion, we get ALL the possible options echoed out at once to aid the next character we might want to type.
In PowerShell, it just cycles through one option at a time, so you are relatively blind where numerous possibilities are involved.
Is equivalent behaviour possible in PowerShell?

Use Set-PSReadLineKeyHandler to redefine what happens when you press Tab as follows:
Set-PSReadLineKeyHandler Tab MenuComplete
Note that you'll have to add this command to your $PROFILE file in order to make it take effect in future sessions too.
The behavior of the MenuComplete function is as follows:
If there is no possible completion, no action is taken.
If there is only one possible completion, it is performed instantly, in-line.
If there are two or more possible completions, an interactive menu of the possible completions is shown below the input line:[1]
Use Tab or the arrow keys to cycle through the completions and press Enter to select one, which completes what was typed based on that selection and closes the menu.
Alternatively, continue typing, which prefix-matches against the parameter names and shrinks the menu dynamically (delete characters to expand it again).
Note that the highlighted menu item also shows that parameter's data type below the menu.
Once a parameter name has been completed, if you want data-type information plus a verbal description of that parameter, you can use the ShowParameterHelp function, available in PowerShell (Core) 7.2+, which is bound to Alt+h by default.
Additional PSReadLine tips:
To see a list of available functions:
Consult the about_PSReadLine_Functions help topic; if it isn't available locally (with Get-Help about_PSReadLine_Functions), run Update-Help -Module PSReadLine.
To list all functions grouped by functional category, using Get-PSReadLineKeyHandler:
Get-PSReadLineKeyHandler -Bound -Unbound
To see a flat list sorted by function name instead:
Get-PSReadLineKeyHandler -Bound -Unbound |
Sort-Object Function |
Select-Object Function, Key, Description
To check what key chord(s) a given function is currently bound to:
# This example looks for function names that contain the word "menu"
# Use -eq with a full function name, if known.
Get-PSReadLineKeyHandler | Where-Object Function -like *Menu*
To discover what function is currently bound to a given key chord:
Use the WhatIsKey function, which on Windows is bound to Alt+? by default; on Unix-like platforms, where the range of usable key chords is limited, there is no default binding, but you can define one as follows, using Alt+w as an example:
Set-PSReadLineKeyHandler Alt+w WhatIsKey
Pressing the key chord that WhatIsKey is bound to then prompts for pressing the key chord of interest, which, if it is bound, prints the bound function name and its description.
[1] The possible completions are not shown in alphabetical order; instead, the order appears to be based on the parameter definition order, combined with some additional logic: an exact match is listed first, alias names are listed after their original names, dynamic parameters are listed after static ones, and matching common parameter names come last.

Related

Powershell 7.3.0 Tab completion not working

I've recently upgraded PowerShell to version 7.3.0 version and now, when I type a command, I see its suggestions like when I'm typing pip it adds list like in this image. Or when I type start of the command it suggests its full name.
The problem is that when I press Tab it doesn't complete the command, instead it just starts listing current directories, i.e. here is an image after pressing Tab once.
Also even when I start typing the full name of the command like pip li it still shows the ending, but when pressing Tab it just does nothing.
I expected this to complete the current command with the suggestion after Tab is pressed.
I've tried to google this problem but haven't found the exact same case I have with 7.3.0 version.
Just press -> (right arrow) key
If you want to change key bindings:
source: https://devblogs.microsoft.com/powershell/announcing-psreadline-2-1-with-predictive-intellisense/
Key Bindings for Predictions
Key bindings control cursor movement and additional features within the prediction. To support users running Predictive IntelliSense on multiple platforms, key bindings are user-settable from the command line or your profile script.
PSReadLine contains functions to navigate and accept predictions. As an example, to accept a displayed prediction, PSReadLine contains functions:
AcceptSuggestion – Accept the current inline suggestion
AcceptNextSuggestionWord – Accept the next word of the inline suggestion
AcceptSuggestion is built within ForwardChar, which by default is bound to RightArrow. Pressing RightArrow accepts an inline suggestion when the cursor is at the end of the current line.
AcceptNextSuggestionWord is built within the function ForwardWord, which can be bound with Ctrl+f by Set-PSReadLineKeyHandler -Chord "Ctrl+f" -Function ForwardWord. Pressing Ctrl+f accepts the next word of an inline suggestion when the cursor is at the end of current editing line.
As a user, you can bound other keys to AcceptSuggestion and AcceptNextSuggestionWord for similar functionalities. Search for ForwardCharAndAcceptNextSuggestionWord in SamplePSReadLineProfile.ps1 for an example to make RightArrow accept the next word from inline suggestion, instead of the whole suggestion line.
List of additional suggested key bindings defined in PSReadLine SamplePSReadLineProfile.ps1

How to type a tab (indent) in comments in PowerShell ISE?

This is weird.
I know tab is for command completion in the PowerShell ISE and fine so. But, it also messes up the editing pane.
Do this:
File > New (Untitled1.ps1 opens)
Press tab (all fine, you get an indent)
type enter, # (comment) and press tab after it
expected: one would get indentation after the hash
actual: one gets the hash replaced by $PSVersionTable or whatever the command prompt has in its history! (tab and Shift-tab circle through those)
Does this mean no-one uses tabs within comments in PowerShell scripts, or that no-one uses comments in PowerShell scripts?
Can I turn off this behavior anywhere?
Also, the behavior seems to be inconsistent. If I e.g. type ##, sometimes tab does not do the completion (it does not enter a tab either).
Can others reproduce this?
System:
Windows 8.1 Pro
PowerShell ISE
To answer the main question, you can enter Alt+09 (using numeric keypad) to enter <Tab>.
For the behavior described, I see this as expected behavior. You can get history completion by typing # and part of a previous command then pressing Tab repeatedly will cycle backwards through matching history. Typing # alone will match all history starting with the last command.
Does this mean no-one uses tabs within comments in PowerShell scripts?
Anecdotal, but I've never used tabs in a single line comment, but I do often use tabs within multiline comments which are bracketed by <# and #>. E.g.
<#
Functions
Get-Foo
Get-Bar
Variables
$Foo
$Bar
#>
Function Get-Foo { ...
With multiline comments, the auto-completion will not be an issue.
, or that no-one uses comments in PowerShell scripts?
I don't know why this would be implied by the behavior; I always use a single space to start a line comment.
I find this helpful when developing a script as I often try expressions in the command pane if I'm unsure of the behavior, then add the expression to the script if it works.
So, my workflow would be:
Ctrl-D to go to the Command Pane
Type a command
If the command did what I wanted, Ctrl-I to go to the Script Pane
Type #<Tab>, and the line is added to the script.

What does # (hash) mean when it doesn't mean Windows key?

Not sure where to search or how to define the keywords. What is the difference between the following?
#IfWinActive, Some Window Title
IfWinActive, Some Window Title
What is the # doing there? I know that in shortcuts, # stands for Windows key, but surely this has to mean something else.
I had been trying to make up a script and the If-else blocks did not work at all. Finally I figured out that it's because I added the # symbol. But I don't find any documentation regarding this kind of use of the # symbol.
The hash is a totally different command. If you search the index in the autohotkey documentation, you will find an entry for both IfWinActive and #IfWinActive.
[The hash...] Creates context-sensitive hotkeys and hotstrings. Such hotkeys perform
a different action (or none at all) depending on the type of window
that is active or exists.
The #IfWin directives are positional: they affect all hotkeys and
hotstrings physically beneath them in the script. They are also
mutually exclusive; that is, only the most recent one will be in effect.
The # only represents the windows key when you use it as a hotkey assignment designation. In AutoHotkey, any time you see a # at the beginning of a command it has something to do with AutoHotkey directives.
Conclusion:
If you just want regular if-else statemens and don't need to affect the context of hotkeys, then don't use the #.

In emacs, make dabbrev-expand only do partial completions like minibuffer-expand?

Currently, in C-mode, if I start typing a word such as:
namespace_module_
dabbrev-expand will cycle through a million full completions of this identifier...
namespace_module_typea_foo <TAB>
namespace_module_typea_bar <TAB>
namespace_module_typea_goo_start <TAB>
...
With many possible words, it is tedious to navigate through all of these. However, minibuffer completion seems to work differently. It only completes until the first difference among the possible matches. It would have completed to (assuming there were no other matches to something like typeb_, etc):
namespace_module_typea_
At this point, I need only type one character to remove the ambiguity, and it is very likely that autocompletion's next guess will be correct. Is it possible to use this completion mode in-buffer with dabbrev-expand? Or hippie-expand? Or even icicles? I've not been able to find anything.
Have you tried dabbrev-completion (bound to C-M-/ by default)? It should do just what you're asking.
Yes, icicle-dabbrev-completion, which by default is bound to C-M-/ (replacing dabbrev-completion) gives you what dabbrev-completion gives you, but with Icicles completion features whenever there is more than one completion. IOW, you can match using a substring, regexp etc.; you can use progressive completion; you can sort and cycle candidates; and so on.
See the doc about this, here.

Tab in Emacs-helm (anything) does not autocomplete with current best match

While trying to autocomplete a file (e.g. to open a file with C-x C-f) Emacs-helm shows a list of possible candidates.
If I then press Tab (which I would hope it would help me choose the first/closest match), I get the following in the minibuffer:
It looks like the minibuffer gets confused with escape characters, and it does not choose the file that I actually want to open (the top choice).
Helm requires this conceptual jump from the default Emacs completion, which is not so obvious:
You don't need to press a key to complete. The completion buffer refreshes
with new results after every input.
This is called "incremental" completion.
The normal tab functionality is not needed in "incremental"
completion. So tab was rebound to helm-select-action, which allows you to
choose an alternative action with the selection. But there is only one action
in read-file-name.
The error you're seeing could be clearer though, I've filed this issue on github.
Additionally, note Helm treats each space separated term as a filtering
regular expression. So, pressing space foo will filter
the current list down to those that contain foo in the name.