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

Allow dropdown menu customization in profiles.json #1571

Closed
JBanks opened this issue Jun 25, 2019 · 27 comments · Fixed by #13763
Closed

Allow dropdown menu customization in profiles.json #1571

JBanks opened this issue Jun 25, 2019 · 27 comments · Fixed by #13763
Labels
Area-Settings Issues related to settings and customizability, for console or terminal Help Wanted We encourage anyone to jump in on these. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.

Comments

@JBanks
Copy link
Contributor

JBanks commented Jun 25, 2019

We'll probably need a settings redesign that allows you to specify the contents of the menu instead of adding a new profile type.


original content

Summary of the new feature/enhancement

Allow MenuFlyoutSeparator to be programmed in profiles.json

Proposed technical implementation details (optional)

My thoughts are to have a flag that allows a "profile" in the profiles.json to be interpreted as a MenuFlyoutSeparator in App::_CreateNewTabFlyout()

@JBanks JBanks added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Jun 25, 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 Jun 25, 2019
@carlos-zamora carlos-zamora added Area-Settings Issues related to settings and customizability, for console or terminal Product-Terminal The new Windows Terminal. and removed Needs-Tag-Fix Doesn't match tag requirements labels Jun 25, 2019
@DHowett-MSFT
Copy link
Contributor

We'll probably need a settings redesign that allows you to specify the contents of the menu instead of adding a new profile type.

I'm just gonna mark this as out of scope for 1.0. 😄

@DHowett-MSFT DHowett-MSFT changed the title MenuFlyoutSeparator in profiles.json Allow dropdown menu customization in profiles.json Jun 26, 2019
@DHowett-MSFT DHowett-MSFT removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Jun 26, 2019
@DHowett-MSFT DHowett-MSFT added this to the Terminal Backlog milestone Jun 26, 2019
@zadjii-msft zadjii-msft added the Help Wanted We encourage anyone to jump in on these. label Jul 2, 2019
@zadjii-msft
Copy link
Member

(directly including the request from #2330 here cause it's a great idea)

Right now I have 5 profiles I use. I just played a bit with adding a ssh-profile and it works fine. But when I want to add all the profiles I have in Putty in WT I need to add another 20+ ssh-profiles. This means the list is going to be really long.

So being able to make submenus and put my profiles in a multiple submenus would be much welcomed.

Initially the menu looks like this:

PowerShell
CMD
WSL
SSH-Group1 > 
SSH-Group2 > 

When a submenu is selected, something like this

PowerShell
CMD
WSL
SSH-Group1 >
SSH-Group2 > +--------+
             | Host 1 |
             | Host 2 |
             | Host 3 |
             +--------+

@thorsig
Copy link

thorsig commented Apr 13, 2020

I was just about to create a new ticket when I stumbled upon this one. I wish to add "mee too" on this - it's very important to a subgroup of the Terminal power-users - namely the administrators. Currently we are using MobaXTerm which does a wonderful job at storing 100s of distinct host entries (profiles) each with their own access and communication parameters. On MacOS we have a toolbar menu and on Linux simply a very large aliases file. In Terminal, I'd love to see this change:

Instead of doing like this:

"profiles":
    [
        {
            "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee0}",
            "hidden": false,
            "name": "Company 1, Server X",
            "commandline": "ssh root@serverX.company1.com",
        },
        {
            "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1}",
            "hidden": false,
            "name": "Company 1, Server Y",
            "commandline": "ssh root@serverY.company1.com",
        },
        {
            "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee2}",
            "hidden": false,
            "name": "Company 2, Server X",
            "commandline": "ssh root@serverX.company2.com",
        },
        {
            "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee3}",
            "hidden": false,
            "name": "Company 2, Server Y",
            "commandline": "ssh root@serverY.company2.com",
        },
        {
            "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee4}",
            "hidden": false,
            "name": "PowerShell 7 Preview",
            "source": "Windows.Terminal.PowershellCore"
        }
    ],

I would rather like to do (something like) this:

    "profiles":
    [
        {
            "folder": "Company 1",
            "items": [
                {
                    "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee0}",
                    "hidden": false,
                    "name": "Server X",
                    "commandline": "ssh root@serverX.company1.com",
                },
                {
                    "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1}",
                    "hidden": false,
                    "name": "Server Y",
                    "commandline": "ssh root@serverY.company1.com",
                }
            ]
        },
        {
            "folder": "Company 2",
            "items": [
                {
                    "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee2}",
                    "hidden": false,
                    "name": "Server X",
                    "commandline": "ssh root@serverX.company2.com",
                },
                {
                    "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee3}",
                    "hidden": false,
                    "name": "Server Y",
                    "commandline": "ssh root@serverY.company2.com",
                }
            ]
        },
        {
            "guid": "{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee4}",
            "hidden": false,
            "name": "PowerShell 7 Preview",
            "source": "Windows.Terminal.PowershellCore"
        }
    ],

Which would help very much in organizing and accessing a configuration with tens or hundreds of defined servers and several companies/categories of servers.

@tiksn
Copy link

tiksn commented Apr 19, 2020

I would propose something like this

{
    "profiles": {
        "defaults": {},
        "list": [
            {
                "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
                "name": "Windows PowerShell",
                "commandline": "powershell.exe",
                "hidden": false
            },
            {
                "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
                "name": "Command Prompt",
                "commandline": "cmd.exe",
                "hidden": false
            },
            {
                "guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
                "hidden": false,
                "name": "PowerShell",
                "source": "Windows.Terminal.PowershellCore"
            },
            {
                "guid": "{58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530}",
                "hidden": false,
                "name": "Debian",
                "source": "Windows.Terminal.Wsl"
            },
            {
                "name": "Company Project 1",
                "hidden": false,
                "defaults": {
                    // Put settings here that you want to apply to all profiles in 'Company Project 1'.
                    // Proposal - inherit from parent "defaults"
                },
                "list": [
                    {
                        "guid": "{a3a2e83a-884a-5379-baa8-16f193a13b21}",
                        "hidden": false,
                        "name": "PowerShell 7 Preview",
                        "source": "Windows.Terminal.PowershellCore"
                    },
                    {
                        "commandline": "nu.exe",
                        "guid": "{2b372ca1-1ee2-403d-a839-6d63077ad871}",
                        "hidden": false,
                        "name": "Nu Shell",
                    },
                    {
                        "commandline": "elvish.exe",
                        "guid": "{6ddf0352-a8c2-46c3-9734-0034762b954c}",
                        "hidden": false,
                        "name": "Elvish"
                    }
                ]
            }
        ]
    }
}

By doing so each group/folder will pretty much be like "profiles" section containing defaults (which will be inherited hierarchically) and "list" of profiles.

We can have groups inside of groups.

@tiksn
Copy link

tiksn commented Apr 27, 2020

Forked repo, implementing it in my fork

@zadjii-msft
Copy link
Member

As a follow up to my previous comment:

  • add enum for NewTabMenuEntryType
  • add deserialization for enum to TerminalSettingsSerializationHelpers
  • add winrt class for NewTabMenuEntry { NewTabMenuEntryType Type; }
  • class for ProfileEntry : NewTabMenuEntry { String Profile; } (.cpp, .h, .idl)
  • class for SeparatorEntry : NewTabMenuEntry (.cpp, .h, .idl)
  • class for FolderEntry : NewTabMenuEntry { IVector<NewTabMenuEntry> Entries; } (.cpp, .h, .idl)
  • You might be able to get away with all those classes being in one idl, but you'd probably want separate files for the h's and cpp's
  • cpp implementations for those Entry's
    • Not sure there's too much to do for those. WINRT_PROPERTY should likely take care of most of that
  • ConversionTrait's for entries (a la the one in ApplicationState.cpp)
  • a newTabMenu property in GlobalAppSettings of type IVector<NewTabMenuEntry>
  • Build the actual menu in TerminalPage::_CreateNewTabFlyout if that property is set (or fall back to the one we currently have if it isn't)
    • parsing the string names -> profiles might be the hardest part

That would be enough for an initial PR, I'd think

@FWest98
Copy link
Contributor

FWest98 commented Aug 16, 2022

Ok I've been at this for a few days now, and I am not getting the simplest things to work and I'm out of ideas, so I would be very grateful if anyone could offer some help.

My problem is that after adding cpp/h/idl for SeparatorEntry, I am no longer able to link Microsoft.Terminal.Settings.Model (the .Lib builds and links fine). It gives this error:

Microsoft.Terminal.Settings.Model.Lib.lib(module.g.obj) : error LNK2019: unresolved external symbol "void * __cdecl winrt_make_Microsoft_Terminal_Settings_Model_SeparatorEntry(void)" (?winrt_make_Microsoft_Terminal_Settings_Model_SeparatorEntry@@YAPEAXXZ) referenced in function "void * __cdecl winrt_get_activation_factory(class std::basic_string_view<wchar_t,struct std::char_traits<wchar_t> > const &)" (?winrt_get_activation_factory@@YAPEAXAEBV?$basic_string_view@_WU?$char_traits@_W@std@@@std@@@Z)

I interpret this as meaning it did not find the factory for SeparatorEntry. However, the code is just there in the header file, it has the exact same style as all other factories for other idls, and I have no clue what goes wrong.
88a336b is the commit that breaks my build and I am out of ideas honestly.

Does anyone have any thoughts? Or is it better to discuss this issue separately from this thread?

@zadjii-msft
Copy link
Member

@FWest98 I got chu. This was a copypasta error I make all the time:

diff --git a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj
index 80e0cb0ec..83f331876 100644
--- a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj
+++ b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj
@@ -166,12 +166,12 @@
     <ClCompile Include="EnumMappings.cpp">
       <DependentUpon>EnumMappings.idl</DependentUpon>
     </ClCompile>
-    <ClInclude Include="NewTabMenuEntry.cpp">
+    <ClCompile Include="NewTabMenuEntry.cpp">
       <DependentUpon>NewTabMenuEntry.idl</DependentUpon>
-    </ClInclude>
-    <ClInclude Include="SeparatorEntry.cpp">
+    </ClCompile>
+    <ClCompile Include="SeparatorEntry.cpp">
       <DependentUpon>SeparatorEntry.idl</DependentUpon>
-    </ClInclude>
+    </ClCompile>
     <ClCompile Include="VsDevCmdGenerator.cpp" />
     <ClCompile Include="VsDevShellGenerator.cpp" />
     <ClCompile Include="VsSetupConfiguration.cpp" />

You had the c++'s marked as "Include" files, not "Compile" ones. I do that all the time when I'm hand-editing the vcxproj's (which I do exclusively).

That should get you unblocked 😉

@ghost ghost added the In-PR This issue has a related PR label Aug 17, 2022
@zadjii-msft zadjii-msft modified the milestones: Up Next, Terminal v1.17 Sep 9, 2022
zadjii-msft added a commit that referenced this issue Nov 18, 2022
Doc updated in response to some discussion in [#11326] and
[#7774]. In those PRs, it became clear that there needs to be a simple way of
collecting up a whole group of profiles automatically for sorting in these
menus. Although discussion centered on how hard it would be for extensions to
provide that customization themselves, the `match` statement was added as a way
to allow the user to easily filter those profiles themselves.

This was something we had originally considered as a "future consideration", but
ultimately deemed it to be out of scope for the initial spec review.

References:

* #1571
* #11326
* #7774
@ghost ghost closed this as completed in #13763 Dec 9, 2022
ghost pushed a commit that referenced this issue Dec 9, 2022
Implements an initial version of #1571 as it has been specified, the
only big thing missing now is the possibility to add actions, which
depends on #6899.

Further upcoming spec tracked in #12584 

Implemented according to [instructions by @zadjii-msft]. Mostly
relatively straightforward, but some notable details:
- In accordance with the spec, the counting/indexing of profiles is
  based on their index in the json (so the index of the profile, not of
  the entry in the menu).
- Resolving a profile name to an actual profile is done in a similar
  fashion as how currently the `DefaultProfile` field is populated: the
  `CascadiaSettings` constructor now has an extra `_resolve` function
  that will iterate over all entries and resolve the names to instances;
  this same function will compute all profile sets (the set of all
  profiles from source "x", and the set of all remaining profiles)
- ~Fun~ fact: I spent two whole afternoons and evenings trying to add 2
  classes (which turned out to be a trivial `.vcxproj` error), and then
  managed to finish the entire rest of it in another afternoon and
  evening...

## Validation Steps Performed
A lot of manual testing; as mentioned above I was not able to run any
tests so I could not add them for now. However, the logic is not too
tricky so it should be relatively safe.

Closes #1571

[instructions by @zadjii-msft]: #1571 (comment)
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Dec 9, 2022
@ghost
Copy link

ghost commented Jan 24, 2023

🎉This issue was addressed in #13763, which has now been successfully released as Windows Terminal Preview v1.17.1023.:tada:

Handy links:

@Jan1torEarl
Copy link

This is so incredibly awesome. Thanks for all the hard work!

@nclemons78
Copy link

Is there a good document on how to create these new folders and move profiles into them? I was looking at the spec, but it was somewhat confusing to me, especially given that it referenced multiple approaches that weren't pursued. Can anyone point me at how to set up what was actually implemented?

@zadjii-msft
Copy link
Member

In lieu of me writing something longer, try starting here:

    "newTabMenu": [
        { "type": "remainingProfiles" },
        {
            "type": "folder",
            "name": "WSLs",
            "entries": [
                {
                    "source": "Windows.Terminal.Wsl",
                    "type": "matchProfiles"
                },
            ]
        },
        {
            "type": "folder",
            "name": "misc",
            "entries": [
                { "type": "profile", "profile": "Ubuntu-18.04" },
                { "type": "profile", "profile": "Ubuntu-22.04" },
                { "type": "profile", "profile": "AlmaLinux-8" }
            ]
        },
        {
            "type": "folder",
            "name": "VS",
            "entries": [
                {
                    "source": "Windows.Terminal.VisualStudio",
                    "type": "matchProfiles"
                },
                { "type": "profile", "profile": "VS 2019 (CMD)" },
            ]
        },
        {
            "type": "folder",
            "name": "Canonical",
            "entries": [
                {
                    "source": "CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc",
                    "type": "matchProfiles"
                },
                {
                    "source": "CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc",
                    "type": "matchProfiles"
                },
                {
                    "source": "CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc",
                    "type": "matchProfiles"
                }
            ]
        },
    ],

Admittedly, you likely won't have all those profiles, but that should point you in the right direction

DHowett pushed a commit that referenced this issue Apr 25, 2023
Original bug report #15049
Relates to feature #1571 

MenuFlyoutSubItem, when collapsing from profile selection, move focus
back to the titlebar.
An extra Closing event handler is needed to keep focus on the command
shell.

Closes #15049
DHowett pushed a commit that referenced this issue Apr 25, 2023
Original bug report #15049
Relates to feature #1571

MenuFlyoutSubItem, when collapsing from profile selection, move focus
back to the titlebar.
An extra Closing event handler is needed to keep focus on the command
shell.

Closes #15049

(cherry picked from commit def3742)
Service-Card-Id: 89002014
Service-Version: 1.17
nguyen-dows pushed a commit to MicrosoftDocs/terminal that referenced this issue Aug 31, 2023
As tracked in microsoft/terminal#1571
As added in microsoft/terminal#13763

This shipped in 1.17 😬 

Closes #667 

_big props to copilot for somehow writing 99% of this for me_
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Settings Issues related to settings and customizability, for console or terminal Help Wanted We encourage anyone to jump in on these. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.