Add an action to "Open in File Explorer"
Kinda the opposite of the context menu. Open the CWD in file explorer. Trick here, shell needs to have been configured for path integration.
Maybe there's a way to make the action do nothing if the active Terminal hasn't set one?
Also relevant: #3337, #5916
Other thoughts: What if the user has a path selected? Check if that text is a path, that path exists, and if so, then open that path in explorer maybe?
It seems like this ought to be a feature of the shell. START . works in CMD, PowerShell, and TCC. In TCC I can assign it to a keystroke.
shell needs to have been configured for path integration
What does that mean? Does it refer to some mechanism that already exists?
I mean, theoretically, yea. This is super doable in the shell. I'm more tracking this as a sub-task of the right-click context menu, or as a trigger. We need an action internally to hook up the context menu entry.
What does that mean? Does it refer to some mechanism that already exists
Yea I'm talking about the OSC9;9 shell integration, as described in https://docs.microsoft.com/en-us/windows/terminal/tutorials/new-tab-same-directory
Yea I'm talking about the OSC9;9 shell integration
That's pretty neat and works as advertized (along with Ctrl+Shift+d). It's the sort of thing I don't often want to do. Most likely, by the next time I want to duplicate a tab, I'll have forgotten about the keystroke (and this thread).
Are there other benefits that could come from a shell using OSC9;9 to send a string to WT?
Is OSC9;9 documented anywhere other then the tutorial you mentioned? I didn't find it in https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences.
Are there other benefits that could come from a shell using OSC9;9 to send a string to WT?
At the moment not really, but who knows what we might do with it in the future. Like, maybe #12863.
OSC9;9 was originally authored by ConEmu so they've got slightly better docs https://conemu.github.io/en/ShellWorkDir.html
Like, maybe https://github.com/microsoft/terminal/issues/12863
That I already have in TCC (popup history and dirhistory). New TCCs use GUI windows for this by default and that doesn't work very well with WT because TCC has no clue where the command line interface window IS. So I use the older option to create the popups in the console screen buffer.
I'm aware of another thread that deals with console apps creating windows. I'm in favor of any improvements on that front, in particular, getting such "popup" windows to have a position which is based on the position of WT's tab. As it is, can WT convey such information to conhost and, if so, can a console app get it?
in particular, getting such "popup" windows to have a position which is based on the position of WT's tab
I'm interested in this as well. We can get the WT position with GetWindowRect (winuser.h) on TerminalPage::_hostingHwnd, then it's just a question of starting the explorer window in a secure way.
Any suggestions? I'm considering CreateProcess from processthreadsapi.h.
Here's what a potential handler in AppActionHandlers could look like (albeit untested), I used the current implementation of #8330 's code for retrieving the CWD:
void TerminalPage::_HandleOpenInFileExplorer(const IInspectable& /* sender */,
const ActionEventArgs& actionArgs)
{
const auto focusedTab{ _GetFocusedTabImpl() };
if (focusedTab)
{
const auto workingDirectory = focusedTab->GetActiveTerminalControl().WorkingDirectory();
const auto validWorkingDirectory = !workingDirectory.empty();
if (validWorkingDirectory && _hostingHwnd.has_value())
{
LPRECT lpRect;
GetWindowRect(TerminalPage::_hostingHwnd.value(), lpRect);
// Spawn Explorer
}
}
}
Quick update: spawning Explorer with ShellExecuteW is trivial. However, obtaining the HWND to call MoveWindow is not. I'm open to suggestions on how to proceed, I really don't want to do the established solution of "wait for new process to idle -> enumerate windows -> get window by pid" because that little stutter (which could be a big stutter on weaker systems) followed by an enumeration drops performance shockingly quickly.
I'm also lost on trying to add my handler to the Command Palette. It's registered as an action in the X-macros and I've been testing it through a Command in defaults-universal.json as well as a tab flyout context menu item which looks quite nifty:
However, I do think it needs to be in Command Palette for ease of use. Could someone please point me in the right direction? Thanks!
However, obtaining the
HWNDto callMoveWindowis not
Wait hold up why do we need to do that at all? I think it's perfectly fine to just ShellExecute({the path}) and let explorer just do it's thing. At least for a first version of the feature, yea?
a Command in
defaults-universal.json
Whoops, we should probably just delete that file - it's not actually used anymore 😅 defaults.json is the file you're looking for, that one should have many, MANY more actions.
we should probably just delete that file - it's not actually used anymore 😅
defaults.jsonis the file you're looking for
Hmm. I definitely put it in defaults.json as well. Here's what I used:
{ "command": "openInFileExplorer", "keys": "ctrl+shift+alt+e" },
The keyboard shortcut works, but it still doesn't show up in command palette. Do I have to add it to another place?
Side note, someone should really make a tutorial for registering an action to command palette. I'll open an issue for it when I finish figuring this one out. Thanks!
Do I have to add it to another place?
Ah, probably. There's a pile of places you need to add this stuff, though, fewer than there used to be. I bet you're missing an entry in ActionAndArgs::GenerateName. That's what generates the names for actions in the command palette.
Side note, someone should really make a tutorial for registering an action to command palette
You know, there actually is a guide, but it's pretty out of date: https://github.com/microsoft/terminal/blob/main/doc/cascadia/AddASetting.md#adding-an-action. We've since added some x-macros to the project that take care of a LOT of the boilerplate, but clearly not all of it.
I might have you also refer to #12097 - looks like that was the most recent merged PR to add an action. That one also needed action args, which I don't think we need in this case, so that should simplify things a bit.
If I'm understanding the OP correctly, then the following command will open a file manager at the current CLI working directory:
explorer .
that is; launch explorer with the first argument matching (expanded to) the current path (. = current directory, compare .. = parent directory).
Been using this for years (decades?), to great effect.
I'm not sure what the equivalent for PowerShell syntax is.
There's an actual shortcut which is ii (invoke-item).
What about instead of having a hidden away menu button, we detect file paths and turning them into hyperlinks?
It would then also work with not just the current working directory, but any path from any output. Lets say you run a compiler and it spits out a log containing multiple paths, it would be handy to be able to ctrl+click on them to go right to the URI:
Microsoft Windows [Version 10.0.19045.4717]
(c) Microsoft Corporation. All rights reserved.
C:\Users\Kieran Devlin> compiler.exe run
Compiling 28 source files...
Binary generated in C:\Users\Kieran Devlin\sources\app1\dist\bin\my-bin.exe
Full output log: C:\Users\Kieran Devlin\sources\app1\logs\compiler\2024-08-16 12-01-56.txt
I made a commit 07ab3d945e4576f8b5c8289eff356298b1a4164b to add this as an action, but I don't see it in the command palette. It works when I attach it to the right click fly out menu though. What am I missing?
I believe it could be because you're missing an "id" in the defaults.json. DecreaseFontSize for instance doesn't really have anything else on top of your changes.
Thank you that fixed the problem. I made a PR.
I saw in https://github.com/microsoft/terminal/pull/13526 that the team believes actions related to CWD don't have too much value at the moment since most people don't path integration set up. Is there value in working on an action to open a highlighted directory instead?