diff --git a/extensions/markdown-language-features/src/extension.ts b/extensions/markdown-language-features/src/extension.ts index 812d61af9d5..254a3302074 100644 --- a/extensions/markdown-language-features/src/extension.ts +++ b/extensions/markdown-language-features/src/extension.ts @@ -40,6 +40,9 @@ export function activate(context: vscode.ExtensionContext) { const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions); context.subscriptions.push(previewManager); + context.subscriptions.push(vscode.languages.setLanguageConfiguration('markdown', { + wordPattern: /(\p{Alphabetic}|\p{Number})+/ug + })); context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider)); context.subscriptions.push(vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider())); context.subscriptions.push(vscode.languages.registerFoldingRangeProvider(selector, new MarkdownFoldingProvider(engine))); diff --git a/src/vs/base/common/marshalling.ts b/src/vs/base/common/marshalling.ts index 5acdcab444c..e479a2db973 100644 --- a/src/vs/base/common/marshalling.ts +++ b/src/vs/base/common/marshalling.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; +import { regExpFlags } from 'vs/base/common/strings'; export function stringify(obj: any): string { return JSON.stringify(obj, replacer); @@ -24,8 +25,8 @@ function replacer(key: string, value: any): any { if (value instanceof RegExp) { return { $mid: 2, - source: (value).source, - flags: ((value).global ? 'g' : '') + ((value).ignoreCase ? 'i' : '') + ((value).multiline ? 'm' : ''), + source: value.source, + flags: regExpFlags(value), }; } return value; diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index e3206199e6b..e46f0ee3937 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -188,6 +188,7 @@ export interface RegExpOptions { wholeWord?: boolean; multiline?: boolean; global?: boolean; + unicode?: boolean; } export function createRegExp(searchString: string, isRegex: boolean, options: RegExpOptions = {}): RegExp { @@ -215,6 +216,9 @@ export function createRegExp(searchString: string, isRegex: boolean, options: Re if (options.multiline) { modifiers += 'm'; } + if (options.unicode) { + modifiers += 'u'; + } return new RegExp(searchString, modifiers); } @@ -236,6 +240,13 @@ export function regExpContainsBackreference(regexpValue: string): boolean { return !!regexpValue.match(/([^\\]|^)(\\\\)*\\\d+/); } +export function regExpFlags(regexp: RegExp): string { + return (regexp.global ? 'g' : '') + + (regexp.ignoreCase ? 'i' : '') + + (regexp.multiline ? 'm' : '') + + ((regexp as any).unicode ? 'u' : ''); +} + /** * Returns first index of the string that is not whitespace. * If string is empty or contains only whitespaces, returns -1 diff --git a/src/vs/editor/common/model/wordHelper.ts b/src/vs/editor/common/model/wordHelper.ts index 46d2a719310..c08e53805de 100644 --- a/src/vs/editor/common/model/wordHelper.ts +++ b/src/vs/editor/common/model/wordHelper.ts @@ -41,6 +41,9 @@ export function ensureValidWordDefinition(wordDefinition?: RegExp | null): RegEx if (wordDefinition.multiline) { flags += 'm'; } + if ((wordDefinition as any).unicode) { + flags += 'u'; + } result = new RegExp(wordDefinition.source, flags); } else { result = wordDefinition; diff --git a/src/vs/editor/common/services/editorWorkerServiceImpl.ts b/src/vs/editor/common/services/editorWorkerServiceImpl.ts index 3943f5f69fe..648c9e4ad0e 100644 --- a/src/vs/editor/common/services/editorWorkerServiceImpl.ts +++ b/src/vs/editor/common/services/editorWorkerServiceImpl.ts @@ -19,6 +19,7 @@ import { EditorSimpleWorkerImpl } from 'vs/editor/common/services/editorSimpleWo import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; +import { regExpFlags } from 'vs/base/common/strings'; /** * Stop syncing a model to the worker if it was not needed for 1 min. @@ -413,7 +414,7 @@ export class EditorWorkerClient extends Disposable { } let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id); let wordDef = wordDefRegExp.source; - let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : ''); + let wordDefFlags = regExpFlags(wordDefRegExp); return proxy.textualSuggest(resource.toString(), position, wordDef, wordDefFlags); }); } @@ -426,7 +427,7 @@ export class EditorWorkerClient extends Disposable { } let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id); let wordDef = wordDefRegExp.source; - let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : ''); + let wordDefFlags = regExpFlags(wordDefRegExp); return proxy.computeWordRanges(resource.toString(), range, wordDef, wordDefFlags); }); } @@ -439,7 +440,7 @@ export class EditorWorkerClient extends Disposable { } let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id); let wordDef = wordDefRegExp.source; - let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : ''); + let wordDefFlags = regExpFlags(wordDefRegExp); return proxy.navigateValueSet(resource.toString(), range, up, wordDef, wordDefFlags); }); } diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 81573591d3b..8f9f92b6d31 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -16,7 +16,7 @@ import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHos import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics'; import { asThenable } from 'vs/base/common/async'; import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, SuggestionDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata } from './extHost.protocol'; -import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings'; +import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange, Range as EditorRange } from 'vs/editor/common/core/range'; import { isFalsyOrEmpty, isNonEmptyArray } from 'vs/base/common/arrays'; @@ -1299,7 +1299,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { } return { pattern: regExp.source, - flags: (regExp.global ? 'g' : '') + (regExp.ignoreCase ? 'i' : '') + (regExp.multiline ? 'm' : ''), + flags: regExpFlags(regExp), }; }