mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-28 09:35:38 -05:00
Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 (#7206)
* Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 * fix config changes * fix strictnull checks
This commit is contained in:
@@ -13,8 +13,14 @@ import { isMarkdownFile } from '../util/file';
|
||||
|
||||
|
||||
export interface OpenDocumentLinkArgs {
|
||||
path: string;
|
||||
fragment: string;
|
||||
readonly path: string;
|
||||
readonly fragment: string;
|
||||
readonly fromResource: any;
|
||||
}
|
||||
|
||||
enum OpenMarkdownLinks {
|
||||
beside = 'beside',
|
||||
currentGroup = 'currentGroup',
|
||||
}
|
||||
|
||||
export class OpenDocumentLinkCommand implements Command {
|
||||
@@ -22,10 +28,15 @@ export class OpenDocumentLinkCommand implements Command {
|
||||
public readonly id = OpenDocumentLinkCommand.id;
|
||||
|
||||
public static createCommandUri(
|
||||
fromResource: vscode.Uri,
|
||||
path: string,
|
||||
fragment: string
|
||||
fragment: string,
|
||||
): vscode.Uri {
|
||||
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify({ path: encodeURIComponent(path), fragment }))}`);
|
||||
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify(<OpenDocumentLinkArgs>{
|
||||
path: encodeURIComponent(path),
|
||||
fragment,
|
||||
fromResource: encodeURIComponent(fromResource.toString(true)),
|
||||
}))}`);
|
||||
}
|
||||
|
||||
public constructor(
|
||||
@@ -33,30 +44,45 @@ export class OpenDocumentLinkCommand implements Command {
|
||||
) { }
|
||||
|
||||
public execute(args: OpenDocumentLinkArgs) {
|
||||
const p = decodeURIComponent(args.path);
|
||||
return this.tryOpen(p, args).catch(() => {
|
||||
if (p && extname(p) === '') {
|
||||
return this.tryOpen(p + '.md', args);
|
||||
const fromResource = vscode.Uri.parse(decodeURIComponent(args.fromResource));
|
||||
const targetPath = decodeURIComponent(args.path);
|
||||
const column = this.getViewColumn(fromResource);
|
||||
return this.tryOpen(targetPath, args, column).catch(() => {
|
||||
if (targetPath && extname(targetPath) === '') {
|
||||
return this.tryOpen(targetPath + '.md', args, column);
|
||||
}
|
||||
const resource = vscode.Uri.file(p);
|
||||
const targetResource = vscode.Uri.file(targetPath);
|
||||
return Promise.resolve(undefined)
|
||||
.then(() => vscode.commands.executeCommand('vscode.open', resource))
|
||||
.then(() => vscode.commands.executeCommand('vscode.open', targetResource, column))
|
||||
.then(() => undefined);
|
||||
});
|
||||
}
|
||||
|
||||
private async tryOpen(path: string, args: OpenDocumentLinkArgs) {
|
||||
private async tryOpen(path: string, args: OpenDocumentLinkArgs, column: vscode.ViewColumn) {
|
||||
const resource = vscode.Uri.file(path);
|
||||
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document)) {
|
||||
if (!path || vscode.window.activeTextEditor.document.uri.fsPath === resource.fsPath) {
|
||||
return this.tryRevealLine(vscode.window.activeTextEditor, args.fragment);
|
||||
}
|
||||
}
|
||||
|
||||
return vscode.workspace.openTextDocument(resource)
|
||||
.then(vscode.window.showTextDocument)
|
||||
.then(document => vscode.window.showTextDocument(document, column))
|
||||
.then(editor => this.tryRevealLine(editor, args.fragment));
|
||||
}
|
||||
|
||||
private getViewColumn(resource: vscode.Uri): vscode.ViewColumn {
|
||||
const config = vscode.workspace.getConfiguration('markdown', resource);
|
||||
const openLinks = config.get<OpenMarkdownLinks>('links.openLocation', OpenMarkdownLinks.currentGroup);
|
||||
switch (openLinks) {
|
||||
case OpenMarkdownLinks.beside:
|
||||
return vscode.ViewColumn.Beside;
|
||||
case OpenMarkdownLinks.currentGroup:
|
||||
default:
|
||||
return vscode.ViewColumn.Active;
|
||||
}
|
||||
}
|
||||
|
||||
private async tryRevealLine(editor: vscode.TextEditor, fragment?: string) {
|
||||
if (editor && fragment) {
|
||||
const toc = new TableOfContentsProvider(this.engine, editor.document);
|
||||
@@ -107,4 +133,4 @@ async function tryResolveLinkToMarkdownFile(path: string): Promise<vscode.Uri |
|
||||
return document.uri;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
50
extensions/markdown-language-features/src/docIndex.ts
Normal file
50
extensions/markdown-language-features/src/docIndex.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable } from './util/dispose';
|
||||
|
||||
|
||||
export class DocumentIndex extends Disposable {
|
||||
private readonly _uriMap = new Map();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
for (let doc of vscode.workspace.textDocuments) {
|
||||
this._registerDoc(doc);
|
||||
}
|
||||
|
||||
this._register(
|
||||
vscode.workspace.onDidOpenTextDocument((doc) => {
|
||||
this._registerDoc(doc);
|
||||
})
|
||||
);
|
||||
this._register(
|
||||
vscode.workspace.onDidCloseTextDocument((doc) => {
|
||||
this._unregisterDoc(doc.uri);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getByUri(uri: vscode.Uri): vscode.TextDocument | undefined {
|
||||
return this._uriMap.get(uri.toString());
|
||||
}
|
||||
|
||||
private _registerDoc(doc: vscode.TextDocument) {
|
||||
const uri = doc.uri.toString();
|
||||
if (this._uriMap.has(uri)) {
|
||||
throw new Error(`The document ${uri} is already registered.`);
|
||||
}
|
||||
this._uriMap.set(uri, doc);
|
||||
}
|
||||
|
||||
private _unregisterDoc(uri: vscode.Uri) {
|
||||
if (!this._uriMap.has(uri.toString())) {
|
||||
throw new Error(`The document ${uri.toString()} is not registered.`);
|
||||
}
|
||||
this._uriMap.delete(uri.toString());
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ function parseLink(
|
||||
}
|
||||
|
||||
return {
|
||||
uri: OpenDocumentLinkCommand.createCommandUri(resourcePath, tempUri.fragment),
|
||||
uri: OpenDocumentLinkCommand.createCommandUri(document.uri, resourcePath, tempUri.fragment),
|
||||
tooltip: localize('documentLink.tooltip', 'Follow link')
|
||||
};
|
||||
}
|
||||
@@ -183,4 +183,4 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,9 +140,9 @@ export class MarkdownPreview extends Disposable {
|
||||
MarkdownPreview.viewType,
|
||||
MarkdownPreview.getPreviewTitle(resource, locked),
|
||||
previewColumn, {
|
||||
enableFindWidget: true,
|
||||
...MarkdownPreview.getWebviewOptions(resource, contributionProvider.contributions)
|
||||
});
|
||||
enableFindWidget: true,
|
||||
...MarkdownPreview.getWebviewOptions(resource, contributionProvider.contributions)
|
||||
});
|
||||
|
||||
return new MarkdownPreview(
|
||||
webview,
|
||||
@@ -288,12 +288,15 @@ export class MarkdownPreview extends Disposable {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
// Reposition scroll preview, position scroll to the top if active text editor
|
||||
// doesn't corresponds with preview
|
||||
if (editor && editor.document.uri.fsPath === resource.fsPath) {
|
||||
this.line = getVisibleLine(editor);
|
||||
} else {
|
||||
this.line = 0;
|
||||
if (editor) {
|
||||
if (editor.document.uri.fsPath === resource.fsPath) {
|
||||
this.line = getVisibleLine(editor);
|
||||
} else {
|
||||
this.line = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we have changed resources, cancel any pending updates
|
||||
const isResourceChange = resource.fsPath !== this._resource.fsPath;
|
||||
if (isResourceChange) {
|
||||
@@ -540,7 +543,7 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
vscode.commands.executeCommand('_markdown.openDocumentLink', { path, fragment });
|
||||
vscode.commands.executeCommand('_markdown.openDocumentLink', { path, fragment, fromResource: this.resource });
|
||||
}
|
||||
|
||||
private async onCacheImageSizes(imageInfo: { id: string, width: number, height: number }[]) {
|
||||
|
||||
@@ -8,8 +8,9 @@ import { Disposable } from '../util/dispose';
|
||||
import { isMarkdownFile } from '../util/file';
|
||||
import { Lazy, lazy } from '../util/lazy';
|
||||
import MDDocumentSymbolProvider from './documentSymbolProvider';
|
||||
import { SkinnyTextDocument } from '../tableOfContentsProvider';
|
||||
import { SkinnyTextDocument, SkinnyTextLine } from '../tableOfContentsProvider';
|
||||
import { flatten } from '../util/arrays';
|
||||
import { DocumentIndex } from '../docIndex';
|
||||
|
||||
export interface WorkspaceMarkdownDocumentProvider {
|
||||
getAllMarkdownDocuments(): Thenable<Iterable<SkinnyTextDocument>>;
|
||||
@@ -26,6 +27,7 @@ class VSCodeWorkspaceMarkdownDocumentProvider extends Disposable implements Work
|
||||
private readonly _onDidDeleteMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<vscode.Uri>());
|
||||
|
||||
private _watcher: vscode.FileSystemWatcher | undefined;
|
||||
private _docIndex: DocumentIndex = this._register(new DocumentIndex());
|
||||
|
||||
async getAllMarkdownDocuments() {
|
||||
const resources = await vscode.workspace.findFiles('**/*.md', '**/node_modules/**');
|
||||
@@ -81,12 +83,39 @@ class VSCodeWorkspaceMarkdownDocumentProvider extends Disposable implements Work
|
||||
}
|
||||
|
||||
private async getMarkdownDocument(resource: vscode.Uri): Promise<SkinnyTextDocument | undefined> {
|
||||
const doc = await vscode.workspace.openTextDocument(resource);
|
||||
return doc && isMarkdownFile(doc) ? doc : undefined;
|
||||
const existingDocument = this._docIndex.getByUri(resource);
|
||||
if (existingDocument) {
|
||||
return existingDocument;
|
||||
}
|
||||
|
||||
const bytes = await vscode.workspace.fs.readFile(resource);
|
||||
|
||||
// We assume that markdown is in UTF-8
|
||||
const text = Buffer.from(bytes).toString('utf-8');
|
||||
|
||||
const lines: SkinnyTextLine[] = [];
|
||||
const parts = text.split(/(\r?\n)/);
|
||||
const lineCount = Math.floor(parts.length / 2) + 1;
|
||||
for (let line = 0; line < lineCount; line++) {
|
||||
lines.push({
|
||||
text: parts[line * 2]
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
uri: resource,
|
||||
version: 0,
|
||||
lineCount: lineCount,
|
||||
lineAt: (index) => {
|
||||
return lines[index];
|
||||
},
|
||||
getText: () => {
|
||||
return text;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class MarkdownWorkspaceSymbolProvider extends Disposable implements vscode.WorkspaceSymbolProvider {
|
||||
private _symbolCache = new Map<string, Lazy<Thenable<vscode.SymbolInformation[]>>>();
|
||||
private _symbolCachePopulated: boolean = false;
|
||||
|
||||
@@ -134,10 +134,10 @@ export class PreviewSecuritySelector {
|
||||
description: localize('toggleSecurityWarning.description', 'Does not affect the content security level')
|
||||
},
|
||||
], {
|
||||
placeHolder: localize(
|
||||
'preview.showPreviewSecuritySelector.title',
|
||||
'Select security settings for Markdown previews in this workspace'),
|
||||
});
|
||||
placeHolder: localize(
|
||||
'preview.showPreviewSecuritySelector.title',
|
||||
'Select security settings for Markdown previews in this workspace'),
|
||||
});
|
||||
if (!selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,12 +15,17 @@ export interface TocEntry {
|
||||
readonly location: vscode.Location;
|
||||
}
|
||||
|
||||
export interface SkinnyTextLine {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface SkinnyTextDocument {
|
||||
readonly uri: vscode.Uri;
|
||||
readonly version: number;
|
||||
readonly lineCount: number;
|
||||
|
||||
lineAt(line: number): SkinnyTextLine;
|
||||
getText(): string;
|
||||
lineAt(line: number): vscode.TextLine;
|
||||
}
|
||||
|
||||
export class TableOfContentsProvider {
|
||||
@@ -72,7 +77,8 @@ export class TableOfContentsProvider {
|
||||
text: TableOfContentsProvider.getHeaderText(line.text),
|
||||
level: TableOfContentsProvider.getHeaderLevel(heading.markup),
|
||||
line: lineNumber,
|
||||
location: new vscode.Location(document.uri, line.range)
|
||||
location: new vscode.Location(document.uri,
|
||||
new vscode.Range(lineNumber, 0, lineNumber, line.text.length))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -85,13 +91,13 @@ export class TableOfContentsProvider {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const endLine = typeof end === 'number' ? end : document.lineCount - 1;
|
||||
const endLine = end !== undefined ? end : document.lineCount - 1;
|
||||
return {
|
||||
...entry,
|
||||
location: new vscode.Location(document.uri,
|
||||
new vscode.Range(
|
||||
entry.location.range.start,
|
||||
new vscode.Position(endLine, document.lineAt(endLine).range.end.character)))
|
||||
new vscode.Position(endLine, document.lineAt(endLine).text.length)))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user