diff --git a/src/vs/base/common/htmlContent.ts b/src/vs/base/common/htmlContent.ts
index 9e8a13a3a39375ed779e8a922ecd9fa8d13bef0a..663274bc6927aac0a2d6aa2bf0c9adba9a69ca0a 100644
--- a/src/vs/base/common/htmlContent.ts
+++ b/src/vs/base/common/htmlContent.ts
@@ -16,52 +16,52 @@ export interface IMarkdownString {
}
export class MarkdownString implements IMarkdownString {
- private readonly _isTrusted: boolean;
- private readonly _supportThemeIcons: boolean;
+
+ public value: string;
+ public isTrusted?: boolean;
+ public supportThemeIcons?: boolean;
constructor(
- private _value: string = '',
+ value: string = '',
isTrustedOrOptions: boolean | { isTrusted?: boolean, supportThemeIcons?: boolean } = false,
) {
- if (typeof this._value !== 'string') {
+ this.value = value;
+ if (typeof this.value !== 'string') {
throw illegalArgument('value');
}
if (typeof isTrustedOrOptions === 'boolean') {
- this._isTrusted = isTrustedOrOptions;
- this._supportThemeIcons = false;
+ this.isTrusted = isTrustedOrOptions;
+ this.supportThemeIcons = false;
}
else {
- this._isTrusted = isTrustedOrOptions.isTrusted ?? false;
- this._supportThemeIcons = isTrustedOrOptions.supportThemeIcons ?? false;
+ this.isTrusted = isTrustedOrOptions.isTrusted ?? false;
+ this.supportThemeIcons = isTrustedOrOptions.supportThemeIcons ?? false;
}
}
- get value() { return this._value; }
- get isTrusted() { return this._isTrusted; }
- get supportThemeIcons() { return this._supportThemeIcons; }
-
appendText(value: string): MarkdownString {
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
- this._value += (this._supportThemeIcons ? escapeCodicons(value) : value)
+ this.value += (this.supportThemeIcons ? escapeCodicons(value) : value)
.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
+ .replace(/^([ \t]+)(.+)$/gm, (_match, g1, g2) => ' '.repeat(g1.length) + g2)
+ .replace(/^>/gm, '\\>')
.replace(/\n/g, '\n\n');
return this;
}
appendMarkdown(value: string): MarkdownString {
- this._value += value;
-
+ this.value += value;
return this;
}
appendCodeblock(langId: string, code: string): MarkdownString {
- this._value += '\n```';
- this._value += langId;
- this._value += '\n';
- this._value += code;
- this._value += '\n```\n';
+ this.value += '\n```';
+ this.value += langId;
+ this.value += '\n';
+ this.value += code;
+ this.value += '\n```\n';
return this;
}
}
diff --git a/src/vs/base/test/common/markdownString.test.ts b/src/vs/base/test/common/markdownString.test.ts
index f33f741f624ad6e118f90666541746d032424ff5..a76c30f2cc57c2fc4aca485760943fb57da03851 100644
--- a/src/vs/base/test/common/markdownString.test.ts
+++ b/src/vs/base/test/common/markdownString.test.ts
@@ -8,6 +8,18 @@ import { MarkdownString } from 'vs/base/common/htmlContent';
suite('MarkdownString', () => {
+ test('Escape leading whitespace', function () {
+ const mds = new MarkdownString();
+ mds.appendText('Hello\n Not a code block');
+ assert.equal(mds.value, 'Hello\n\n Not a code block');
+ });
+
+ test('MarkdownString.appendText doesn\'t escape quote #109040', function () {
+ const mds = new MarkdownString();
+ mds.appendText('> Text\n>More');
+ assert.equal(mds.value, '\\> Text\n\n\\>More');
+ });
+
test('appendText', () => {
const mds = new MarkdownString();
diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts
index 6eb858eee8415a6fb521bf3e8c0ad514e2c4834e..158eb96407d36bf7a9bc44112b33396203fbeac1 100644
--- a/src/vs/workbench/api/common/extHostTypes.ts
+++ b/src/vs/workbench/api/common/extHostTypes.ts
@@ -4,10 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { coalesceInPlace, equals } from 'vs/base/common/arrays';
-import { escapeCodicons } from 'vs/base/common/codicons';
import { illegalArgument } from 'vs/base/common/errors';
import { IRelativePattern } from 'vs/base/common/glob';
-import { isMarkdownString } from 'vs/base/common/htmlContent';
+import { isMarkdownString, MarkdownString as BaseMarkdownString } from 'vs/base/common/htmlContent';
import { ResourceMap } from 'vs/base/common/map';
import { isStringArray } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
@@ -1290,40 +1289,7 @@ export class CodeInset {
@es5ClassCompat
-export class MarkdownString {
-
- value: string;
- isTrusted?: boolean;
- readonly supportThemeIcons?: boolean;
-
- constructor(value?: string, supportThemeIcons: boolean = false) {
- this.value = value ?? '';
- this.supportThemeIcons = supportThemeIcons;
- }
-
- appendText(value: string): MarkdownString {
- // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
- this.value += (this.supportThemeIcons ? escapeCodicons(value) : value)
- .replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
- .replace(/\n/, '\n\n');
-
- return this;
- }
-
- appendMarkdown(value: string): MarkdownString {
- this.value += value;
-
- return this;
- }
-
- appendCodeblock(code: string, language: string = ''): MarkdownString {
- this.value += '\n```';
- this.value += language;
- this.value += '\n';
- this.value += code;
- this.value += '\n```\n';
- return this;
- }
+export class MarkdownString extends BaseMarkdownString implements vscode.MarkdownString {
static isMarkdownString(thing: any): thing is vscode.MarkdownString {
if (thing instanceof MarkdownString) {
@@ -1331,6 +1297,11 @@ export class MarkdownString {
}
return thing && thing.appendCodeblock && thing.appendMarkdown && thing.appendText && (thing.value !== undefined);
}
+
+ constructor(value?: string, supportThemeIcons: boolean = false) {
+ super(value ?? '', { supportThemeIcons });
+ }
+
}
@es5ClassCompat