Only show breadcrumb editor picker for default-capable editors (which excludes hex editor)

This commit is contained in:
Henning Dieterichs
2026-07-10 18:03:46 +02:00
committed by Henning Dieterichs
parent 609aa64d3f
commit f406891d5b
3 changed files with 85 additions and 3 deletions
@@ -51,7 +51,7 @@ import { BreadcrumbsConfig, IBreadcrumbsService } from './breadcrumbs.js';
import { BreadcrumbsModel, FileElement, OutlineElement2 } from './breadcrumbsModel.js';
import { BreadcrumbsFilePicker, BreadcrumbsOutlinePicker } from './breadcrumbsPicker.js';
import { IEditorGroupView } from './editor.js';
import { createEditorTypeActions, editorTypeDisplayLabel, getAvailableEditorTypes } from './editorTypePicker.js';
import { createEditorTypeActions, editorTypeDisplayLabel, getAvailableEditorTypes, hasDefaultEditorAssociation } from './editorTypePicker.js';
import './media/breadcrumbscontrol.css';
import { ScrollbarVisibility } from '../../../../base/common/scrollable.js';
import { CancellationToken } from '../../../../base/common/cancellation.js';
@@ -534,7 +534,8 @@ export class BreadcrumbsControl {
const previousWidth = wasHidden ? 0 : this._editorTypeNode.offsetWidth;
const available = (this._options.showEditorTypePicker && this._cfShowEditorType.getValue()) ? getAvailableEditorTypes(this._editorGroup.activeEditor, this._editorResolverService) : undefined;
if (!available) {
const configuredDefaultEditor = available ? this._editorResolverService.getConfiguredDefaultEditor(available.resource, available.isDiffEditor) : undefined;
if (!available || !hasDefaultEditorAssociation(available, configuredDefaultEditor)) {
this._editorTypeNode.classList.toggle('hidden', true);
} else {
const current = available.editors.find(editor => editor.id === available.currentId);
@@ -10,7 +10,7 @@ import { localize } from '../../../../nls.js';
import { ICommandService } from '../../../../platform/commands/common/commands.js';
import { DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, SideBySideEditor, isDiffEditorInput } from '../../../common/editor.js';
import { EditorInput } from '../../../common/editor/editorInput.js';
import { IEditorResolverService, RegisteredEditorInfo } from '../../../services/editor/common/editorResolverService.js';
import { IEditorResolverService, RegisteredEditorInfo, RegisteredEditorPriority, priorityToRank } from '../../../services/editor/common/editorResolverService.js';
import { IEditorService } from '../../../services/editor/common/editorService.js';
import { REOPEN_ACTIVE_EDITOR_WITH_COMMAND_ID } from './editorCommands.js';
@@ -52,6 +52,22 @@ export function getAvailableEditorTypes(activeEditor: EditorInput | null | undef
};
}
/** Whether a custom editor can be selected by default for the resource. */
export function hasDefaultEditorAssociation(available: IAvailableEditorTypes, configuredDefaultEditor: string | undefined): boolean {
if (configuredDefaultEditor !== undefined && configuredDefaultEditor !== DEFAULT_EDITOR_ASSOCIATION.id) {
return true;
}
return available.editors.some(editor => {
if (editor.id === DEFAULT_EDITOR_ASSOCIATION.id) {
return false;
}
const priority = available.isDiffEditor ? editor.priority.diff : editor.priority.editor;
return priorityToRank(priority) >= priorityToRank(RegisteredEditorPriority.builtin);
});
}
/**
* The label to show for an editor type. In a diff context the default text editor is presented as
* "Text Diff Editor" to match how it actually opens.
@@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import assert from 'assert';
import { URI } from '../../../../../base/common/uri.js';
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
import { DEFAULT_EDITOR_ASSOCIATION } from '../../../../common/editor.js';
import { IAvailableEditorTypes, hasDefaultEditorAssociation } from '../../../../browser/parts/editor/editorTypePicker.js';
import { RegisteredEditorInfo, RegisteredEditorPriority } from '../../../../services/editor/common/editorResolverService.js';
suite('Editor Type Picker', () => {
ensureNoDisposablesAreLeakedInTestSuite();
function editor(id: string, editorPriority: RegisteredEditorPriority, diffPriority = editorPriority): RegisteredEditorInfo {
return {
id,
label: id,
priority: {
editor: editorPriority,
diff: diffPriority,
merge: editorPriority,
}
};
}
function available(customEditor: RegisteredEditorInfo, isDiffEditor = false): IAvailableEditorTypes {
return {
resource: URI.file('/test.txt'),
isDiffEditor,
currentId: DEFAULT_EDITOR_ASSOCIATION.id,
editors: [
editor(DEFAULT_EDITOR_ASSOCIATION.id, RegisteredEditorPriority.builtin),
customEditor,
]
};
}
test('default editor association visibility', () => {
const optionalEditor = available(editor('test.optionalEditor', RegisteredEditorPriority.option));
const defaultEditor = available(editor('test.defaultEditor', RegisteredEditorPriority.default));
const builtinEditor = available(editor('test.builtinEditor', RegisteredEditorPriority.builtin));
const diffDefaultEditor = available(editor('test.diffDefaultEditor', RegisteredEditorPriority.option, RegisteredEditorPriority.default), true);
assert.deepStrictEqual({
optionalEditor: hasDefaultEditorAssociation(optionalEditor, undefined),
configuredOptionalEditor: hasDefaultEditorAssociation(optionalEditor, 'test.optionalEditor'),
configuredTextEditor: hasDefaultEditorAssociation(optionalEditor, DEFAULT_EDITOR_ASSOCIATION.id),
defaultEditor: hasDefaultEditorAssociation(defaultEditor, undefined),
defaultEditorOverriddenWithText: hasDefaultEditorAssociation(defaultEditor, DEFAULT_EDITOR_ASSOCIATION.id),
builtinEditor: hasDefaultEditorAssociation(builtinEditor, undefined),
diffDefaultEditor: hasDefaultEditorAssociation(diffDefaultEditor, undefined),
}, {
optionalEditor: false,
configuredOptionalEditor: true,
configuredTextEditor: false,
defaultEditor: true,
defaultEditorOverriddenWithText: true,
builtinEditor: true,
diffDefaultEditor: true,
});
});
});