microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
94.88k stars 8.22k forks source link

Allow dropdown menu customization in profiles.json #1571

Closed JBanks closed 1 year ago

JBanks commented 5 years ago

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 MenuFlyoutSeparatorto 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 MenuFlyoutSeparatorin App::_CreateNewTabFlyout()

DHowett-MSFT commented 5 years ago

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. :smile:

zadjii-msft commented 5 years ago

(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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

Forked repo, implementing it in my fork

tiksn commented 4 years ago

Partial (working) implementation exists in this branch. Branch is bit lagging from master.

timparker183 commented 4 years ago

I'll add another 'me too' for this one - and a twist... I'd like to be able to reference one or more external files for my 'profiles.list' section. My need is similar to several examples above, but I'd like to be able to share 'customer' folders with other users without having to share out my entire configuration (and, since I have the information I need in a database already, I'd like to generate this JSON from there instead of having to edit it manually)

BrunoBlanes commented 3 years ago

Hello there. I've been searching for the possibility to save my panes in a profile and ended up with the following:

{
    "command": {
        "action": "wt",
        "commandline": "wsl.exe ~ ; sp -H ssh bruno@10.254.0.254; mf up; sp -V wsl.exe ~ ; sp -V; mf down; sp -H; mf up; sp -V ssh bruno@10.254.0.254; mf down; sp -V; sp -V; sp -H"
    },
    "keys": "ctrl+shift+w",
    "name": "Work Layout"
}

There are nine panes in there which is quite complex, and even though this works fine as a shortcut, I still need to close the original tab since this opens a new one and there is no resizePane subcommand for wt. I was wondering when we're going to be able to test the proposed profile structure in a preview build and if there's going to be a solution for programmatically resizing panes. Thanks in advance, love your open-source work!

BrunoBlanes commented 3 years ago

LOL I just found out that there's an argument for splitPane which resizes it.

zadjii-msft commented 3 years ago

I was wondering when we're going to be able to test the proposed profile structure in a preview build

Probably not for a long time. One of the key features we want is for people to be able to nest profile entries, but there's currently a bug in Xaml Islands that causes the whole application to crash when you use nested menuflyouts. (see #8238 for details) We'll need to move over to WinUI 3 to get the fix for that, which will take time and engineering effort that we're not prepared to commit to before polishing up and finishing 2.0.

rouke-broersma commented 2 years ago

I was wondering when we're going to be able to test the proposed profile structure in a preview build

Probably not for a long time. One of the key features we want is for people to be able to nest profile entries, but there's currently a bug in Xaml Islands that causes the whole application to crash when you use nested menuflyouts. (see #8238 for details) We'll need to move over to WinUI 3 to get the fix for that, which will take time and engineering effort that we're not prepared to commit to before polishing up and finishing 2.0.

Could this feature perhaps be MVP'd in a simpler way? For my personal use case I would already be mostly unblocked if I could change the single existing menu entry to not open my default profile since my default profile is my wsl distro and I would not want to use this on the windows filesystem. If we could set a default for terminal open and a separate default for the explorer context menu (powershell/powershell core) I think a lot of use cases are already covered.

Holding off on this until it can be fully implemented for power users with submenu's and the like would be a shame imo.

zadjii-msft commented 2 years ago

@rouke-broersma You know, the part of this that you're looking for is actually better tracked over at #6111.

In other news, I think the OS-side of this bug should be getting serviced to earlier Windows versions sometime this month, so hopefully we can get a start on this sometime early next year.

rouke-broersma commented 2 years ago

@zadjii-msft I got here from there! Because the first note in that issue links to this I was assuming that changing the context menu was depending on being able to configure the dropdown, and since this is on-hold due to some OS bug I thought the 'main' issue was also waiting on that bug. That's why I thought I would ask for a more MVP solution to the problem. But from your reaction I gather that it was the wrong assumption :)

zadjii-msft commented 2 years ago

Ah, yea, so the two are a little intertwined. There's a bit of architecture we want to do beneath both issues, which is described over at #6899 - Action IDs.md. I suppose #6899 is the common parent to both these features ☺️

kzhangkzhang commented 2 years ago

When this feature can be implemented? I am having 20+ profiles and list is continuously growing, I am desperately waiting a solution for this.

Thanks! Kevin

zadjii-msft commented 2 years ago

I'd love to get to work on this one, but unfortunately there are some higher priorities at the moment. We're in a bugfix push right now. After that I'm hoping to get back to tear out (#1256). Once that's made an appreciable level of progress then I'm planning on getting to #6899 and this. So it's pretty high up on the backlog, but still a few months away at least.

If someone in the community is interested in working on this sooner than that I can try and give them some pointers. Thinking about it more, all the non-actions bits of New Tab Menu Customization are probably doable without #6899. So that might be even easier to start with.

andreffonseca commented 2 years ago

Hello to all. I hope everything is fine.

Do you know when this feature will be available/implemented? I really need it because I've like a thousand profiles. If I can help with anything.

Thank you very much.

zadjii-msft commented 2 years ago

I don't believe that anyone on the team will have the bandwidth to get to this any time soon, unfortunately πŸ˜•. If anyone would like to help contribute this, I'd be more than happy to give pointers on how I'd go about this.

nclemons78 commented 2 years ago

Is it possible to manually re-arrange the profiles by editing the JSON file? If so, I'm assuming Windows Terminal would need to be closed first in order to do so?

zadjii-msft commented 2 years ago

Is it possible to manually re-arrange the profiles by editing the JSON file? If so, I'm assuming Windows Terminal would need to be closed first in order to do so?

Yes, that's always been possible. You shouldn't need to close the Terminal either - that should hot-reload

zadjii-msft commented 2 years ago

As a follow up to my previous comment:

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

FWest98 commented 2 years ago

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. https://github.com/microsoft/terminal/commit/88a336b7cd88bfc2c7da5eac846c3d2f6250769a 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 commented 2 years ago

@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 commented 1 year ago

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

Handy links:

Jan1torEarl commented 1 year ago

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

nclemons78 commented 1 year ago

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 commented 1 year ago

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