Change:
install "markdown notebook" extension make sure the default editor for MD files is the text editor open a MD file (opens as text) re-open with markdown notebook select an entry from outline or breadcrumbs :bug: a text editor opens
It looks like our editor contribution point isn't called
The same happens with the "references view" and the "problems panel" (use GH issue notebooks and make text editor default for its type)
Debugged this a little: everything works nice up to the point where the user setting is read and . That "steels" the resource from notebooks and re-routes it into the "normal" editor land... This code is novel to me so I might not have the best suggestions how to fix it. One idea is that my contribution marks a scheme as "winner scheme" and resources with that scheme will always use that contribution. Tho, I don't know what side effects that will have

Discussion:
import * as glob from 'vs/base/common/glob'; import { sep } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; <ins> import { URI } from 'vs/base/common/uri'; </ins> suite('Glob', () => {

assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs'); } }); <ins> test('URI match', () => { let p = 'scheme:/**/*.md'; assertGlobMatch(p, URI.file('super/duper/long/some/file.md').with({ scheme: 'scheme' }).toString()); }); </ins> });

import { IResourceEditorInput } from 'vs/platform/editor/common/editor'; import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditorInput'; import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput'; <del> import { ContributedEditorPriority, IEditorAssociationsRegistry, IEditorOverrideService, IEditorType, IEditorTypesHandler } from 'vs/workbench/services/editor/common/editorOverrideService'; import { EditorExtensions } from 'vs/workbench/common/editor'; </del> <ins> import { ContributedEditorPriority, DiffEditorInputFactoryFunction, EditorInputFactoryFunction, IEditorAssociationsRegistry, IEditorOverrideService, IEditorType, IEditorTypesHandler } from 'vs/workbench/services/editor/common/editorOverrideService'; import { EditorExtensions, IEditorInput } from 'vs/workbench/common/editor'; </ins> import { IFileService } from 'vs/platform/files/common/files'; <ins> import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; </ins> export class NotebookProviderInfoStore extends Disposable {

private _registerContributionPoint(notebookProviderInfo: NotebookProviderInfo): void { for (const selector of notebookProviderInfo.selectors) { const globPattern = (selector as INotebookExclusiveDocumentFilter).include || selector as glob.IRelativePattern | string; <ins> const notebookEditorInfo = { id: notebookProviderInfo.id, label: notebookProviderInfo.displayName, detail: notebookProviderInfo.providerDisplayName, describes: (currentEditor: IEditorInput) => currentEditor instanceof NotebookEditorInput && currentEditor.viewType === notebookProviderInfo.id, priority: notebookProviderInfo.exclusive ? ContributedEditorPriority.exclusive : notebookProviderInfo.priority, }; const notebookEditorOptions = { canHandleDiff: () => !!this._configurationService.getValue(NotebookTextDiffEditorPreview) && !this._accessibilityService.isScreenReaderOptimized(), canSupportResource: (resource: URI) => resource.scheme === Schemas.untitled || resource.scheme === Schemas.vscodeNotebookCell || this._fileService.canHandleResource(resource) }; const notebookEditorInputFactory: EditorInputFactoryFunction = (resource, options, group) => { const data = CellUri.parse(resource); let notebookUri: URI = resource; let cellOptions: IResourceEditorInput | undefined; if (data) { notebookUri = data.notebook; cellOptions = { resource: resource }; } const notebookOptions = new NotebookEditorOptions({ ...options, cellOptions }); return { editor: NotebookEditorInput.create(this._instantiationService, notebookUri, notebookProviderInfo.id), options: notebookOptions }; }; const notebookEditorDiffFactory: DiffEditorInputFactoryFunction = (diffEditorInput: DiffEditorInput, options, group) => { const modifiedInput = diffEditorInput.modifiedInput; const originalInput = diffEditorInput.originalInput; const notebookUri = modifiedInput.resource!; const originalNotebookUri = originalInput.resource!; return { editor: NotebookDiffEditorInput.create(this._instantiationService, notebookUri, modifiedInput.getName(), originalNotebookUri, originalInput.getName(), diffEditorInput.getName(), notebookProviderInfo.id) }; }; // Register the notebook editor </ins> this._contributedEditorDisposables.add(this._editorOverrideService.registerContributionPoint( globPattern, <del> { id: notebookProviderInfo.id, label: notebookProviderInfo.displayName, detail: notebookProviderInfo.providerDisplayName, describes: (currentEditor) => currentEditor instanceof NotebookEditorInput && currentEditor.viewType === notebookProviderInfo.id, priority: notebookProviderInfo.exclusive ? ContributedEditorPriority.exclusive : notebookProviderInfo.priority, }, { canHandleDiff: () => !!this._configurationService.getValue(NotebookTextDiffEditorPreview) && !this._accessibilityService.isScreenReaderOptimized(), canSupportResource: resource => resource.scheme === Schemas.untitled || resource.scheme === Schemas.vscodeNotebookCell || this._fileService.canHandleResource(resource) }, (resource, options, group) => { const data = CellUri.parse(resource); let notebookUri: URI = resource; let cellOptions: IResourceEditorInput | undefined; if (data) { notebookUri = data.notebook; cellOptions = { resource: resource }; } const notebookOptions = new NotebookEditorOptions({ ...options, cellOptions }); return { editor: NotebookEditorInput.create(this._instantiationService, notebookUri, notebookProviderInfo.id), options: notebookOptions }; }, (diffEditorInput, group) => { const modifiedInput = diffEditorInput.modifiedInput; const originalInput = diffEditorInput.originalInput; const notebookUri = modifiedInput.resource!; const originalNotebookUri = originalInput.resource!; return { editor: NotebookDiffEditorInput.create(this._instantiationService, notebookUri, modifiedInput.getName(), originalNotebookUri, originalInput.getName(), diffEditorInput.getName(), notebookProviderInfo.id) }; } </del> <ins> notebookEditorInfo, notebookEditorOptions, notebookEditorInputFactory, notebookEditorDiffFactory )); // Then register the schema handler as exclusive for that notebook this._contributedEditorDisposables.add(this._editorOverrideService.registerContributionPoint( `${Schemas.vscodeNotebookCell}:/**/${globPattern}`, { ...notebookEditorInfo, priority: ContributedEditorPriority.exclusive }, notebookEditorOptions, notebookEditorInputFactory, notebookEditorDiffFactory </ins> )); } }

const associationsFromSetting = this.getAssociationsForResource(resource); // We only want built-in+ if no user defined setting is found, else we won't override const possibleContributionPoints = contributionPoints.filter(contribPoint => priorityToRank(contribPoint.editorInfo.priority) >= priorityToRank(ContributedEditorPriority.builtin) && contribPoint.editorInfo.id !== DEFAULT_EDITOR_ASSOCIATION.id); <del> // If the user has a setting we use that, else choose the highest priority editor that is built-in+ const selectedViewType = associationsFromSetting[0]?.viewType || possibleContributionPoints[0]?.editorInfo.id; </del> <ins> // If the contribution is exclusive we use that, else use the user setting, else use the built-in+ contribution const selectedViewType = possibleContributionPoints[0]?.editorInfo.priority === ContributedEditorPriority.exclusive ? possibleContributionPoints[0]?.editorInfo.id : associationsFromSetting[0]?.viewType || possibleContributionPoints[0]?.editorInfo.id; </ins> let conflictingDefault = false; if (associationsFromSetting.length === 0 && possibleContributionPoints.length > 1) {

return false; } const matchOnPath = typeof globPattern === 'string' && globPattern.indexOf(posix.sep) >= 0; <del> const target = matchOnPath ? resource.path : basename(resource); </del> <ins> const target = matchOnPath ? `${resource.scheme}:${resource.path}` : basename(resource); </ins> return glob.match(globPattern, target.toLowerCase()); } //#endregion