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

Enhance shell autocompletion with a cool new user interface and shell completion protocol #3121

Open
anki-code opened this issue Oct 8, 2019 · 54 comments
Assignees
Labels
A11yMAS Accessibility tracking Area-Extensibility A feature that would ideally be fulfilled by us having an extension model. Area-Interop Communication between processes Area-UserInterface Issues pertaining to the user interface of the Console or Terminal Disability-All Accessibility tracking InclusionBacklog Accessibility tracking InclusionBacklog-Windows TerminalWin32 Accessibility tracking Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.

Comments

@anki-code
Copy link

anki-code commented Oct 8, 2019

Hello! Thank you for the new interesting project!

I just want to let you know about 🚀 Upterm — really great proof of concept but it stopped because maintainer was gone. This terminal looks like 21st century terminal. Very sad that it isn't supported.

image

up30485947-aeaa5398-9a37-11e7-927c-769304744844

up29716319-95f9a8d8-89b3-11e7-8515-fcb236eb4454

image

image

@anki-code anki-code added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Oct 8, 2019
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Oct 8, 2019
@DHowett-MSFT DHowett-MSFT changed the title Concept of 21st century terminal Enhance shell autocompletion with a cool new user interface and shell completion protocol Oct 10, 2019
@DHowett-MSFT DHowett-MSFT added Area-Extensibility A feature that would ideally be fulfilled by us having an extension model. Area-Interop Communication between processes Area-UserInterface Issues pertaining to the user interface of the Console or Terminal Product-Terminal The new Windows Terminal. and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Oct 10, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Oct 10, 2019
@DHowett-MSFT DHowett-MSFT added this to the Terminal Backlog milestone Oct 10, 2019
@zadjii-msft
Copy link
Member

This looks really cool, though this looks like something the shell would have to work with the terminal to achieve.

How was Upterm providing those autocomplete suggestions? Did they have their own shell they were using, or were they somehow pulling the auto-completions from bash/zsh/git somehow?

Presuming the shell provided a list of autocompletion suggestions to the terminal, drawing the UI shouldn't be that hard. Cmd would obviously never be able to support this, but powershell core sure could. I'd be curious what kind of perf there would be for something like that, with the shell emitting a list of auto-completion suggestions after some delay/on every character typed.

Doing the collapsible json thing might be quite a bit harder however :P that definitely seems like they had a custom rolled cat that worked directly with the terminal.

@huoyaoyuan
Copy link
Contributor

I think you can get inspired by Visual Studio's C# Interactive and PowerShell ISE.
PowerShell already has a mechanism to collect completions, which is used by dotnet.exe.
And also, don't forget the great Language Server Protocol by Visual Studio.

@n3wt0n
Copy link

n3wt0n commented Feb 4, 2020

That would be really cool, or something like the iTerm 2 autocompletion on Mac. (cmd + ;)

image

This works for both files/folder and commands

@remkop
Copy link

remkop commented May 19, 2020

@zadjii-msft

Cmd would obviously never be able to support this, but powershell core sure could.

Cmd could certainly achieve bash-like completion: clink enhances Cmd with tab completion, which users can customize with simple lua scripts.

While not as fancy looking as the screenshots above, it would be hugely valuable if Cmd would support this out of the box.

(More detail: see docs and pre-built completions for common tools.)

@zadjii-msft
Copy link
Member

I don't disagree, projects like clink and yori are great and I love them. It's just that we really can't accept any changes to cmd.exe safely 😕 This doc covers some of the reasons why.

@remkop
Copy link

remkop commented May 20, 2020

@zadjii-msft Thank you for the clarification. Makes sense and made me realize what a great job you and your team are doing. Keep it up! (Also thanks for pointing me to yori, I did not know about that project.)

@just1a-person
Copy link

Wish we had the Terminal of 2005:

image

@DHowett
Copy link
Member

DHowett commented Jun 23, 2021

You know, apart from the "graphical" bit, this sounds like PowerShell. It accepts C# (procedural and object-oriented), you can write prompt plugins, you can stream files (and objects!), and it supports multiple hosting interfaces such as the PowerShell ISE (which is graphical!)

@just1a-person
Copy link

There is this new terminal called Warp: https://twitter.com/zachlloydtweets/status/1415343353164599299

I wish Windows Terminal was that radical and not just try to match existing Unix terminals' functionality (which it already has most of)

@orcmid
Copy link

orcmid commented Jul 16, 2021

There is this new terminal called Warp: https://twitter.com/zachlloydtweets/status/1415343353164599299

I wish Windows Terminal was that radical and not just try to match existing Unix terminals' functionality (which it already has most of)

I think there is a confusion of shell versus terminal and how apps are wired in. So Warp seems more integrated and purpose-built. All the questions about how one uses a terminal are about session shell use. They focus on CLI.

Since there was such a thing as stealth mode, one must presume this is to be a commercial offering. There is no hint that the code is even in the open (although there is a statement about working in public). "Stable" releases are also ratcheting pretty quickly according to the Discord. warp.dev has more. There's a nice presentation of How Warp Works. I have not found any statement about licensing or commercial use, although having forked Alacritty might be relevant, depending on how the permissive Apache License is dealt with.

@just1a-person
Copy link

I think the PowerShell team (or PSReadLine) and the Windows Terminal team can work together to make something like this happen.

@zadjii-msft
Copy link
Member

  1. Op, I should probably make a note about ctrl+space, since lots of folks already use that for MenuComplete. You may want to pick different keys
  2. welp I forgot that Windows PowerShell (5.x) doesn't support `e as an escape character. I'll need to edit the sample to use the whole [char]0x1b thing for back-compat.
  3. @christianparpart Oh don't you worry, I think I've got almost all the same thoughts as you in this space. Sometime over the next few months I wanna take what we have here, mostly throw it out, and propose a different version to terminal-wg1. Shell-agnostic, client-agnostic, and terminal-agnostic.

Footnotes

  1. terminal-wg is of course, mostly dead, but it is still a place to go. I'm not sure that consensus building is something that'll happen there. I still think there's room for it to be informative, but not normative.

@sanket-bhalerao
Copy link

i still see the old prompt image

maybe you forgot to restart wtp?

i have restarted the terminal several times, but still see the same result.

@zadjii-msft
Copy link
Member

@sanket-bhalerao mind filing a new issue, with your settings.json file and your PowerShell profile? We can debug over there, and report findings back to this thread ☺️

@j4james
Copy link
Collaborator

j4james commented Sep 27, 2023

But IIRC there were terminals that didn't parse DCS correctly.

@christianparpart The Windows 10 console is one such terminal. The issue was fixed years ago, but I don't think Windows 10 gets updates anymore. But it's not a problem as long as apps use some form of feature detection before using the sequence. I wouldn't recommend apps use any string sequence without feature detection.

The big diff probably is, that OSC's by habbit seem to always start with a number as identifier, for DCS there is no such grouping (as of yet).

The DCS intermediate-final characters are the equivalent of the OSC number. You can think of it as a self terminating base-16 number, so you have something like 65 times more range for a 4 byte value.

@sanket-bhalerao
Copy link

sanket-bhalerao commented Sep 28, 2023

@sanket-bhalerao mind filing a new issue, with your settings.json file and your PowerShell profile? We can debug over there, and report findings back to this thread ☺️

@zadjii-msft I have raised a bug: #16053
UPDATE: I added incorrect configs at incorrect places. after @zadjii-msft pointed it out and I corrected the configs the feature is working as expected :)

@rsteube
Copy link

rsteube commented Sep 28, 2023

fyi Powershell supports colored completion using escape codes:

default

terminal

@jerkovicl
Copy link

@rsteube how did you configure this?

@rsteube
Copy link

rsteube commented Sep 29, 2023

@jerkovicl Windows Terminal according to the wiki, the completions are custom.
Shouldn't normally be an issue though, i'm using the powershell completions a bit differently.

@jerkovicl
Copy link

@rsteube yeah i have meant the color part and the command description

@rsteube
Copy link

rsteube commented Sep 29, 2023

I'm adding it to the ListItemText instead of the ToolTip.

using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Function _git_completer {
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingInvokeExpression", "", Scope="Function", Target="*")]
    param($wordToComplete, $commandAst, $cursorPosition)
    $commandElements = $commandAst.CommandElements

    # double quoted value works but seems single quoted needs some fixing (e.g. "example 'acti" -> "example acti")
    $elems = @()
    foreach ($_ in $commandElements) {
      if ($_.Extent.StartOffset -gt $cursorPosition) {
          break
      }
      $t = $_.Extent.Text
      if ($_.Extent.EndOffset -gt $cursorPosition) {
          $t = $t.Substring(0, $_.Extent.Text.get_Length() - ($_.Extent.EndOffset - $cursorPosition))
      }

      if ($t.Substring(0,1) -eq "'"){
        $t = $t.Substring(1)
      }
      if ($t.get_Length() -gt 0 -and $t.Substring($t.get_Length()-1) -eq "'"){
        $t = $t.Substring(0,$t.get_Length()-1)
      }
      if ($t.get_Length() -eq 0){
        $t = '""'
      }
      $elems += $t.replace('`,', ',') # quick fix
    }

    $completions = @(
      if (!$wordToComplete) {
        carapace git powershell $($elems| ForEach-Object {$_}) '' | ConvertFrom-Json | ForEach-Object { [CompletionResult]::new($_.CompletionText, $_.ListItemText.replace('`e[', "`e["), [CompletionResultType]::ParameterValue, $_.ToolTip) }
      } else {
        carapace git powershell $($elems| ForEach-Object {$_}) | ConvertFrom-Json | ForEach-Object { [CompletionResult]::new($_.CompletionText, $_.ListItemText.replace('`e[', "`e["), [CompletionResultType]::ParameterValue, $_.ToolTip) }
      }
    )

    if ($completions.count -eq 0) {
      return "" # prevent default file completion
    }

    $completions
}
Register-ArgumentCompleter -Native -CommandName 'git' -ScriptBlock (Get-Item "Function:_git_completer").ScriptBlock

@jerkovicl
Copy link

@rsteube oh cool, thx for snippet:)

@rsteube
Copy link

rsteube commented Sep 29, 2023

It's on scoop and winget if you want to try it yourself.
Just add this to your profile and it should work:

# ~/.config/powershell/Microsoft.PowerShell_profile.ps1
Set-PSReadLineOption -Colors @{ "Selection" = "`e[7m" }
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
carapace _carapace | Out-String | Invoke-Expression

@jerkovicl
Copy link

@rsteube thx, i installed and set it all up, it works:)

zadjii-msft added a commit that referenced this issue Oct 5, 2023
## Summary of the Pull Request

> ## Abstract
> 
> Multiple related scenarios have come up where it would be beneficial
to display
> actionable UI to the user within the context of the active terminal
itself. This
> UI would be akin to the Intellisense UI in Visual Studio. It appears
right where
> the user is typing, and can help provide immediate content for the
user, based
> on some context. The "Suggestions UI" is this new ephemeral UI within
the
> Windows Terminal that can display different types of actions, from
different
> sources.
> 


## Detailed Description of the Pull Request / Additional comments

_\*<sup>\*</sup><sub>\*</sub> read the spec
<sub>\*</sub><sup>\*</sup>\*_

Similar to #14792, a lot of this code is written. This stuff isn't
checked in though, so I'm presenting formally before I start yeeting PRs
out there.

## PR Checklist
- [x] This is a spec for #1595. It also references:
  * #3121
  * #10436
  * #12927
  * #12863
@Jaykul
Copy link
Contributor

Jaykul commented Dec 6, 2023

Is there any way to have the completion menu support typing to narrow down the list?

@Tyriar
Copy link
Member

Tyriar commented Dec 7, 2023

FYI thanks to some contributions from @cpendery you can once again enable suggest in VS Code's terminal ("terminal.integrated.shellIntegration.suggestEnabled": true) starting from the next insiders build which should ship sometime in the next few days:

Recording 2023-12-07 at 06 28 43

It's still rough around the edges and not close to feature complete, but I believe we fixed the show stopper bug that bricks the terminal 😅. Here's the issue tracking the feature microsoft/vscode#154662

@cereschen
Copy link

I have implemented the most basic fig like automatic completion, git.json is generated by the npm package @ withfig/autocomplete/build/git

import * as fig from '@withfig/autocomplete/build/git'
import { writeFileSync } from 'fs'
writeFileSync('./git.json',JSON.stringify(fig.default))

Note that I changed the shortcut key to ctrl+b

$directory = (Split-Path -Parent $PROFILE)
$jsonFilePath = Join-Path -Path $directory -ChildPath 'Completions/git.json'
$jsonContent = Get-Content -Raw -Path $jsonFilePath
$jsonObject = $jsonContent | ConvertFrom-Json
function Get-Items {
  param (
    $obj
  )
  $array = @()
  $mergedArray = $obj.subcommands + $obj.options
  $mergedArray | ForEach-Object {
    $name = $_.name
    $CompletionText = $_.name
    if ($_.name.GetType().BaseType.Name -eq "Array") {
      $name = $name -join "  "
      $CompletionText = $_.name[0]
    }
    $description = $_.description
    $newObject = New-Object PSObject -Property @{
      CompletionText = $CompletionText
      ListItemText   = $name + "   " + $description
      ResultType     = 2
      ToolTip        = $description
    }
    $array += $newObject
  }
  return $array
}
function Send-Completions {
  $commandLine = ""
  $cursorIndex = 0
  [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$commandLine, [ref]$cursorIndex)
  $completionPrefix = $commandLine
  $result2 = "`e]633;Completions"
  # $result = "`e]633;Completions"
  if ($completionPrefix.Length -gt 0) {
    $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex
    if ($null -ne $completions.CompletionMatches) {
      # $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);"
      # $result += $completions.CompletionMatches | ConvertTo-Json -Compress
      $result2 += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);"
      $subStr = $completionPrefix.Substring(0, $cursorIndex)
      $strArray = $subStr -split '\s+'
      $pushItem = $jsonObject.subcommands | Where-Object { $_.name -eq $strArray[1] }
      if ($null -ne $pushItem) {
        $res = Get-Items -obj $pushItem
        $result2 += $res | ConvertTo-Json -Compress
      }
      else {
        $res = Get-Items -obj $jsonObject
        $result2 += $res | ConvertTo-Json -Compress
      }
    }
  }
  # $result += "`a"
  $result2 += "`a"
  Write-Host -NoNewLine $result2
}

function Set-MappedKeyHandlers {
  # Terminal suggest - always on keybindings
  Set-PSReadLineKeyHandler -Chord 'Ctrl+b' -ScriptBlock {
    Send-Completions
  }
}

# Register key handlers if PSReadLine is available
if (Get-Module -Name PSReadLine) {
  Set-MappedKeyHandlers
}
else {
  Write-Host "PsReadline was disabled. Shell Completion was not enabled."
}

@rsteube
Copy link

rsteube commented Dec 23, 2023

@cereschen have a look at microsoft/inshellisense.
With microsoft/inshellisense#78 you can invoke the fig completions with inshellisense complete 'command args...'.
I've got a bridge for it at carapace-bridge as well which will be include in the next release of carapace-bin.

Things to note though:

Inshellisense uses a lexer to split the command which which is very basic.
E.g. at the moment it can't handle spaces, redirects, quotes, and so on.
The fig completions got quite a lot of issues as well.
So a lot of things don't work yet (and won't for quite a long time).

@cereschen
Copy link

cereschen commented Dec 24, 2023

@cereschen看看microsoft/inshellisense。 使用microsoft/inshellisense#78,您可以使用 调用无花果补全inshellisense complete 'command args...'我在carapace-bridge 上也有一个桥,它将包含在下一版本的carapace-bin中。

但需要注意的事项:

Inshellisense 使用词法分析器来拆分命令,这是非常基本的。 例如,目前它无法处理空格、重定向、引号等。 无花果的完成也遇到了很多问题。 所以很多事情还不起作用(而且在很长一段时间内都不起作用)。

I successfully used is today, but it took me too much time to call is using Invoke Expression. Perhaps there is a better way, as I am not proficient in Powershell

This seems to be an issue with IS, as it will take some time for it to end..

@Welding-Torch
Copy link

I just started using Warp for WSL and it feels like it's lightyears ahead of this stuff. I think it would be great if Windows Terminal took some notes from it, especially on this feature request that's been open since 2019.

Also mentioned earlier in this thread by: @just1a-person in 2021 and @orcmid.

github-merge-queue bot pushed a commit that referenced this issue Jun 12, 2024
This adds a `"description"` property to actions. Notably, the shell
completion protocol (#3121) will now also populate that.

The suggestions UI can then use those descriptions to display an
additional tooltip with that information.

TeachingTip was kinda an abject disaster last time I tried this, so this
_isn't_ a TeachingTip. It's literally a text block.

xlinks:
* #13000
* #15845 
* #14939 - the last abandoned attempt at this
github-merge-queue bot pushed a commit that referenced this issue Jun 22, 2024
This specs out a lot of plans for snippets. We've already got these in
the sxnui as "tasks", but we can do so very much more.

This spec is a few years old now, but it's time for it to get promoted
out of my draft branch.

References: 
* #1595
* #7039
* #3121
* #10436
* #12927
* #12857
* #5790
* #15845

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
@carlos-zamora carlos-zamora modified the milestones: Up Next, Terminal v1.23 Aug 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A11yMAS Accessibility tracking Area-Extensibility A feature that would ideally be fulfilled by us having an extension model. Area-Interop Communication between processes Area-UserInterface Issues pertaining to the user interface of the Console or Terminal Disability-All Accessibility tracking InclusionBacklog Accessibility tracking InclusionBacklog-Windows TerminalWin32 Accessibility tracking Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

No branches or pull requests