Change:
We don't want to officially have the hex editor be recommended for non-textual files, but what about a setting like that can be used to open a binary file in a given editor instead of showing the "binary file" message? ! I would love it if I could have all non-text files automatically opened in the hex editor.
To verify ensure the setting works as expected. Setting it to a custom editor should automatically have that editor be opened when a file is detected as binary.

Discussion:
import { Codicon } from 'vs/base/common/codicons'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { UntitledTextEditorInputSerializer, UntitledTextEditorWorkingCopyEditorHandler } from 'vs/workbench/services/untitled/common/untitledTextEditorHandler'; <del> import { DynamicEditorGroupAutoLockConfiguration } from 'vs/workbench/browser/parts/editor/editorConfiguration'; </del> <ins> import { DefaultBinaryEditorConfiguration, DynamicEditorGroupAutoLockConfiguration } from 'vs/workbench/browser/parts/editor/editorConfiguration'; </ins> //#region Editor Registrations

Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(EditorStatus, LifecyclePhase.Ready); Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(UntitledTextEditorWorkingCopyEditorHandler, LifecyclePhase.Ready); Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DynamicEditorGroupAutoLockConfiguration, LifecyclePhase.Ready); <ins> Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DefaultBinaryEditorConfiguration, LifecyclePhase.Ready); </ins> registerEditorContribution(OpenWorkspaceButtonContribution.ID, OpenWorkspaceButtonContribution);

this.configurationRegistry.updateConfigurations({ add: [this.configurationNode], remove: oldConfigurationNode ? [oldConfigurationNode] : [] }); } } <ins> export class DefaultBinaryEditorConfiguration extends Disposable implements IWorkbenchContribution { private configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration); private configurationNode: IConfigurationNode | undefined; constructor( @IEditorResolverService private readonly editorResolverService: IEditorResolverService, @IExtensionService extensionService: IExtensionService, ) { super(); // Editor configurations are getting updated very aggressively // (atleast 20 times) while the extensions are getting registered. // As such push out the default binary editor configuration // until after extensions registered. (async () => { await extensionService.whenInstalledExtensionsRegistered(); this.updateConfiguration(); this.registerListeners(); })(); } private registerListeners(): void { // Registered editors this._register(this.editorResolverService.onDidChangeEditorRegistrations(() => this.updateConfiguration())); } private updateConfiguration(): void { // Get registered editors const editorIds = this.editorResolverService.getEditors().filter(e => e.priority !== RegisteredEditorPriority.exclusive).map(editor => editor.id); const oldConfigurationNode = this.configurationNode; this.configurationNode = { ...workbenchConfigurationNodeBase, properties: { 'workbench.editor.defaultBinaryEditor': { type: 'string', // This allows for intellisense autocompletion enum: editorIds, description: localize('workbench.editor.defaultBinaryEditor', "The default editor for files detected as binary. If undefined the user will be presented with a picker."), } } }; this.configurationRegistry.updateConfigurations({ add: [this.configurationNode], remove: oldConfigurationNode ? [oldConfigurationNode] : [] }); } } </ins>

import { MutableDisposable } from 'vs/base/common/lifecycle'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; import { ViewContainerLocation } from 'vs/workbench/common/views'; <ins> import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; </ins> /** * An implementation of editor for file system resources.

@ITextFileService private readonly textFileService: ITextFileService, @IExplorerService private readonly explorerService: IExplorerService, @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, <del> @IPathService private readonly pathService: IPathService </del> <ins> @IPathService private readonly pathService: IPathService, @IConfigurationService private readonly configurationService: IConfigurationService </ins> ) { super(TextFileEditor.ID, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorService, editorGroupService);

private openAsBinary(input: FileEditorInput, options: ITextEditorOptions | undefined): void { <del> // Mark file input for forced binary opening input.setForceOpenAsBinary(); // Open in group (this.group ?? this.editorGroupService.activeGroup).openEditor(input, { </del> <ins> const defaultBinaryEditor = this.configurationService.getValue<string | undefined>('workbench.editor.defaultBinaryEditor'); const groupToOpen = this.group ?? this.editorGroupService.activeGroup; const editorOptions = { </ins> ...options, // Make sure to not steal away the currently active group // because we are triggering another openEditor() call // and do not control the initial intent that resulted // in us now opening as binary. activation: EditorActivation.PRESERVE <del> }); </del> <ins> }; // If we the user setting specifies a default binary editor we use that. if (defaultBinaryEditor && defaultBinaryEditor !== '') { this.editorService.replaceEditors([{ editor: input, replacement: { resource: input.resource, options: { ...editorOptions, override: defaultBinaryEditor } } }], groupToOpen); } else { // Mark file input for forced binary opening input.setForceOpenAsBinary(); // Open in group groupToOpen.openEditor(input, editorOptions); } </ins> } private async openAsFolder(input: FileEditorInput): Promise<void> {

import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; <ins> import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; </ins> /** * An implementation of editor for file system resources.

@IExplorerService explorerService: IExplorerService, @IUriIdentityService uriIdentityService: IUriIdentityService, @IProductService private readonly productService: IProductService, <del> @IPathService pathService: IPathService </del> <ins> @IPathService pathService: IPathService, @IConfigurationService configurationService: IConfigurationService, </ins> ) { <del> super(telemetryService, fileService, paneCompositeService, instantiationService, contextService, storageService, textResourceConfigurationService, editorService, themeService, editorGroupService, textFileService, explorerService, uriIdentityService, pathService); </del> <ins> super(telemetryService, fileService, paneCompositeService, instantiationService, contextService, storageService, textResourceConfigurationService, editorService, themeService, editorGroupService, textFileService, explorerService, uriIdentityService, pathService, configurationService); </ins> } protected override handleSetInputError(error: Error, input: FileEditorInput, options: ITextEditorOptions | undefined): Promise<void> {