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

Open a file using system default application #95403

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/vs/platform/electron/electron-main/electronMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ export class ElectronMainService implements IElectronMainService {
shell.showItemInFolder(path);
}

async openItem(windowId: number | undefined, path: string): Promise<void> {
shell.openItem(path);
}

async setRepresentedFilename(windowId: number | undefined, path: string): Promise<void> {
const window = this.windowById(windowId);
if (window) {
Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/electron/node/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface IElectronService {

// OS
showItemInFolder(path: string): Promise<void>;
openItem(path: string): Promise<void>;
setRepresentedFilename(path: string): Promise<void>;
setDocumentEdited(edited: boolean): Promise<void>;
openExternal(url: string): Promise<boolean>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files';
import { IListService } from 'vs/platform/list/browser/listService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { revealResourcesInOS } from 'vs/workbench/contrib/files/electron-browser/fileCommands';
import { revealResourcesInOS, openWithDefaultApplication } from 'vs/workbench/contrib/files/electron-browser/fileCommands';
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import { ResourceContextKey } from 'vs/workbench/common/resources';
import { appendToCommandPalette, appendEditorTitleContextMenuItem } from 'vs/workbench/contrib/files/browser/fileActions.contribution';
Expand Down Expand Up @@ -82,3 +82,66 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {

const category = { value: nls.localize('filesCategory', "File"), original: 'File' };
appendToCommandPalette(REVEAL_IN_OS_COMMAND_ID, { value: REVEAL_IN_OS_LABEL, original: isWindows ? 'Reveal in File Explorer' : isMacintosh ? 'Reveal in Finder' : 'Open Containing Folder' }, category, ResourceContextKey.Scheme.isEqualTo(Schemas.file));





const OPEN_WITH_DEFAULT_APP_ID = 'openWithDefaultApp';
const OPEN_WITH_DEFAULT_APP_LABEL = nls.localize('openWithDefaultApp', "Open with default application");

KeybindingsRegistry.registerCommandAndKeybindingRule({
id: OPEN_WITH_DEFAULT_APP_ID,
weight: KeybindingWeight.WorkbenchContrib,
when: EditorContextKeys.focus.toNegated(),
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_O,
win: {
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_O
},
handler: (accessor: ServicesAccessor, resource: URI | object) => {
const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService), accessor.get(IExplorerService));
openWithDefaultApplication(resources, accessor.get(IElectronService), accessor.get(INotificationService), accessor.get(IWorkspaceContextService));
}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
weight: KeybindingWeight.WorkbenchContrib,
when: undefined,
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_O),
id: 'workbench.action.files.revealActiveFileInWindows',
handler: (accessor: ServicesAccessor) => {
const editorService = accessor.get(IEditorService);
const activeInput = editorService.activeEditor;
const resource = activeInput ? activeInput.resource : null;
const resources = resource ? [resource] : [];
openWithDefaultApplication(resources, accessor.get(IElectronService), accessor.get(INotificationService), accessor.get(IWorkspaceContextService));
}
});

appendEditorTitleContextMenuItem(OPEN_WITH_DEFAULT_APP_ID, OPEN_WITH_DEFAULT_APP_LABEL, ResourceContextKey.Scheme.isEqualTo(Schemas.file));

// Menu registration - open editors

const openWithDefaultAppCommand = {
id: OPEN_WITH_DEFAULT_APP_ID,
title: nls.localize('openWithDefaultApp', "Open with default application")
};
MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {
group: 'navigation',
order: 20,
command: openWithDefaultAppCommand,
when: ResourceContextKey.IsFileSystemResource
});

// Menu registration - explorer

MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
group: 'navigation',
order: 20,
command: openWithDefaultAppCommand,
when: ResourceContextKey.Scheme.isEqualTo(Schemas.file)
});

// Command Palette

appendToCommandPalette(OPEN_WITH_DEFAULT_APP_ID, { value: OPEN_WITH_DEFAULT_APP_LABEL, original: 'Open with default application' }, category, ResourceContextKey.Scheme.isEqualTo(Schemas.file));
17 changes: 17 additions & 0 deletions src/vs/workbench/contrib/files/electron-browser/fileCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,20 @@ export function revealResourcesInOS(resources: URI[], electronService: IElectron
notificationService.info(nls.localize('openFileToReveal', "Open a file first to reveal"));
}
}

export function openWithDefaultApplication(resources: URI[], electronService: IElectronService, notificationService: INotificationService, workspaceContextService: IWorkspaceContextService): void {
if (resources.length) {
sequence(resources.map(r => async () => {
if (r.scheme === Schemas.file) {
electronService.openItem(r.fsPath);
}
}));
} else if (workspaceContextService.getWorkspace().folders.length) {
const uri = workspaceContextService.getWorkspace().folders[0].uri;
if (uri.scheme === Schemas.file) {
electronService.openItem(uri.fsPath);
}
} else {
notificationService.info(nls.localize('openFileToReveal', "Open a file first to reveal"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ export class TestElectronService implements IElectronService {
async pickFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> { }
async pickWorkspaceAndOpen(options: INativeOpenDialogOptions): Promise<void> { }
async showItemInFolder(path: string): Promise<void> { }
async openItem(path: string): Promise<void> { }
async setRepresentedFilename(path: string): Promise<void> { }
async setDocumentEdited(edited: boolean): Promise<void> { }
async openExternal(url: string): Promise<boolean> { return false; }
Expand Down