提交 e6200af9 编写于 作者: P Pine Wu

Merge branch 'master' of github.com:Microsoft/vscode

......@@ -9,7 +9,7 @@
},
"dependencies": {
"vscode-css-languageservice": "^3.0.6",
"vscode-emmet-helper": "^1.1.34",
"vscode-emmet-helper": "^1.1.37",
"vscode-languageserver": "4.0.0-next.4"
},
"devDependencies": {
......
......@@ -2,9 +2,9 @@
# yarn lockfile v1
"@emmetio/extract-abbreviation@^0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.4.tgz#f5be070db97901ecc37e5204f2ace68242cdcefa"
"@emmetio/extract-abbreviation@0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.6.tgz#e4a9856c1057f0aff7d443b8536477c243abe28c"
"@types/mocha@2.2.33":
version "2.2.33"
......@@ -25,11 +25,11 @@ vscode-css-languageservice@^3.0.6:
vscode-languageserver-types "^3.6.0-next.1"
vscode-nls "^2.0.1"
vscode-emmet-helper@^1.1.34:
version "1.1.35"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.35.tgz#1a704811d573df55cb313e232d5b2e6ea6dca96c"
vscode-emmet-helper@^1.1.37:
version "1.1.37"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.37.tgz#239636ec559d98b23994394028dd1535f49e8a53"
dependencies:
"@emmetio/extract-abbreviation" "^0.1.4"
"@emmetio/extract-abbreviation" "0.1.6"
jsonc-parser "^1.0.0"
vscode-languageserver-types "^3.6.0-next.1"
......
......@@ -337,7 +337,7 @@
"@emmetio/html-matcher": "^0.3.3",
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
"@emmetio/math-expression": "^0.1.1",
"vscode-emmet-helper": "^1.1.36",
"vscode-emmet-helper": "^1.1.37",
"vscode-languageserver-types": "^3.5.0",
"image-size": "^0.5.2",
"vscode-nls": "3.2.1"
......
......@@ -9,9 +9,9 @@
"@emmetio/stream-reader" "^2.2.0"
"@emmetio/stream-reader-utils" "^0.1.0"
"@emmetio/extract-abbreviation@^0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.4.tgz#f5be070db97901ecc37e5204f2ace68242cdcefa"
"@emmetio/extract-abbreviation@0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.6.tgz#e4a9856c1057f0aff7d443b8536477c243abe28c"
"@emmetio/html-matcher@^0.3.3":
version "0.3.3"
......@@ -2052,11 +2052,11 @@ vinyl@~2.0.1:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
vscode-emmet-helper@^1.1.36:
version "1.1.36"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.36.tgz#537cbf91041a3d426f6f24dd9834550a26e61685"
vscode-emmet-helper@^1.1.37:
version "1.1.37"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.37.tgz#239636ec559d98b23994394028dd1535f49e8a53"
dependencies:
"@emmetio/extract-abbreviation" "^0.1.4"
"@emmetio/extract-abbreviation" "0.1.6"
jsonc-parser "^1.0.0"
vscode-languageserver-types "^3.6.0-next.1"
......
......@@ -9,7 +9,7 @@
},
"dependencies": {
"vscode-css-languageservice": "^3.0.6",
"vscode-emmet-helper": "^1.1.34",
"vscode-emmet-helper": "^1.1.37",
"vscode-html-languageservice": "^2.0.17-next.3",
"vscode-languageserver": "4.0.0-next.4",
"vscode-languageserver-types": "^3.6.0-next.1",
......
......@@ -2,9 +2,9 @@
# yarn lockfile v1
"@emmetio/extract-abbreviation@^0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.4.tgz#f5be070db97901ecc37e5204f2ace68242cdcefa"
"@emmetio/extract-abbreviation@0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.6.tgz#e4a9856c1057f0aff7d443b8536477c243abe28c"
"@types/mocha@2.2.33":
version "2.2.33"
......@@ -25,11 +25,11 @@ vscode-css-languageservice@^3.0.6:
vscode-languageserver-types "^3.6.0-next.1"
vscode-nls "^2.0.1"
vscode-emmet-helper@^1.1.34:
version "1.1.35"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.35.tgz#1a704811d573df55cb313e232d5b2e6ea6dca96c"
vscode-emmet-helper@^1.1.37:
version "1.1.37"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.37.tgz#239636ec559d98b23994394028dd1535f49e8a53"
dependencies:
"@emmetio/extract-abbreviation" "^0.1.4"
"@emmetio/extract-abbreviation" "0.1.6"
jsonc-parser "^1.0.0"
vscode-languageserver-types "^3.6.0-next.1"
......
......@@ -395,6 +395,11 @@
"default": null,
"description": "%typescript.locale%",
"scope": "window"
},
"typescript.experimental.syntaxFolding": {
"type": "boolean",
"default": false,
"description": "%typescript.experimental.syntaxFolding%"
}
}
},
......
......@@ -48,5 +48,6 @@
"typescript.quickSuggestionsForPaths": "Enable/disable quick suggestions when typing out an import path.",
"typescript.locale": "Sets the locale used to report TypeScript errors. Requires TypeScript >= 2.6.0. Default of 'null' uses VS Code's locale for TypeScript errors.",
"javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable 'experimentalDecorators' for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires TypeScript >=2.3.1.",
"typescript.autoImportSuggestions.enabled": "Enable/disable auto import suggestions. Requires TypeScript >=2.6.1"
"typescript.autoImportSuggestions.enabled": "Enable/disable auto import suggestions. Requires TypeScript >=2.6.1",
"typescript.experimental.syntaxFolding": "Enables/disables syntax aware folding markers."
}
\ No newline at end of file
......@@ -20,6 +20,7 @@ import * as fileSchemes from './utils/fileSchemes';
import { CachedNavTreeResponse } from './features/baseCodeLensProvider';
const validateSetting = 'validate.enable';
const foldingSetting = 'typescript.experimental.syntaxFolding';
export default class LanguageProvider {
private readonly diagnosticsManager: DiagnosticsManager;
......@@ -35,6 +36,8 @@ export default class LanguageProvider {
private readonly disposables: Disposable[] = [];
private readonly versionDependentDisposables: Disposable[] = [];
private foldingProviderRegistration: Disposable | undefined = void 0;
constructor(
private readonly client: TypeScriptServiceClient,
private readonly description: LanguageDescription,
......@@ -126,9 +129,13 @@ export default class LanguageProvider {
this.disposables.push(languages.registerCodeActionsProvider(selector, new (await import('./features/quickFixProvider')).default(client, this.formattingOptionsManager, commandManager, this.diagnosticsManager)));
this.disposables.push(languages.registerCodeActionsProvider(selector, new (await import('./features/refactorProvider')).default(client, this.formattingOptionsManager, commandManager)));
if (workspace.getConfiguration('typescript').get('enableExperimentalFolding', false)) {
this.disposables.push(languages.registerFoldingProvider(selector, new (await import('./features/folderingProvider')).default(client)));
}
await this.initFoldingProvider();
this.disposables.push(workspace.onDidChangeConfiguration(c => {
if (c.affectsConfiguration(foldingSetting)) {
this.initFoldingProvider();
}
}));
this.disposables.push({ dispose: () => this.foldingProviderRegistration && this.foldingProviderRegistration.dispose() });
this.registerVersionDependentProviders();
......@@ -153,6 +160,20 @@ export default class LanguageProvider {
}
}
private async initFoldingProvider(): Promise<void> {
let enable = workspace.getConfiguration().get(foldingSetting, false);
if (enable) {
if (!this.foldingProviderRegistration) {
this.foldingProviderRegistration = languages.registerFoldingProvider(this.documentSelector, new (await import('./features/folderingProvider')).default(this.client));
}
} else {
if (this.foldingProviderRegistration) {
this.foldingProviderRegistration.dispose();
this.foldingProviderRegistration = void 0;
}
}
}
private configurationChanged(): void {
const config = workspace.getConfiguration(this.id);
this.updateValidate(config.get(validateSetting, true));
......
......@@ -581,7 +581,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
if (resource.scheme === fileSchemes.walkThroughSnippet || resource.scheme === fileSchemes.untitled) {
const dirName = path.dirname(resource.path);
const fileName = this.inMemoryResourcePrefix + path.basename(resource.path);
return resource.with({ path: path.join(dirName, fileName) }).toString(true);
return resource.with({ path: path.posix.join(dirName, fileName) }).toString(true);
}
}
......@@ -611,7 +611,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
const dirName = path.dirname(resource.path);
const fileName = path.basename(resource.path);
if (fileName.startsWith(this.inMemoryResourcePrefix)) {
resource = resource.with({ path: path.join(dirName, fileName.slice(this.inMemoryResourcePrefix.length)) });
resource = resource.with({ path: path.posix.join(dirName, fileName.slice(this.inMemoryResourcePrefix.length)) });
}
}
return resource;
......
......@@ -128,8 +128,12 @@ export default (): string => `
</div>
</div>
</div>
<div class="instructions">${escape(localize('disableExtensionsLabel', "Try to reproduce the problem after "))}<span tabIndex=0 role="button" id="disableExtensions" class="workbenchCommand">${escape(localize('disableExtensions', "disabling all extensions and reloading the window"))}</span>.</div>
<div class="instructions">${escape(localize('showRunningExtensionsLabel', "If you suspect it's an extension issue, "))}<span tabIndex=0 role="button"id="showRunning" class="workbenchCommand">${escape(localize('showRunningExtensions', "see all running extensions"))}</span>.</div>
<div class="instructions">${escape(localize('disableExtensionsLabel', "Try to reproduce the problem after {0}."))
.replace('{0}', `<span tabIndex=0 role="button" id="disableExtensions" class="workbenchCommand">${escape(localize('disableExtensions', "disabling all extensions and reloading the window"))}</span>`)}
</div>
<div class="instructions">${escape(localize('showRunningExtensionsLabel', "If you suspect it's an extension issue, {0} to report the issue on the extension."))
.replace('{0}', `<span tabIndex=0 role="button"id="showRunning" class="workbenchCommand">${escape(localize('showRunningExtensions', "view all running extensions"))}</span>`)}
</div>
</div>
</div>
......
......@@ -24,11 +24,10 @@ import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions';
import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry';
import { IModelLanguageChangedEvent } from 'vs/editor/common/model/textModelEvents';
import { ClassName } from 'vs/editor/common/model/intervalTree';
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { themeColorFromId, ThemeColor } from 'vs/platform/theme/common/themeService';
import { overviewRulerWarning, overviewRulerError, overviewRulerInfo } from 'vs/editor/common/view/editorColorRegistry';
import { ITextModel, IModelDeltaDecoration, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, DefaultEndOfLine, ITextModelCreationOptions, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBufferFactory, ITextBuffer } from 'vs/editor/common/model';
import { ITextModel, IModelDeltaDecoration, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, DefaultEndOfLine, ITextModelCreationOptions, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBufferFactory, ITextBuffer, EndOfLinePreference } from 'vs/editor/common/model';
function MODEL_ID(resource: URI): string {
return resource.toString();
......@@ -393,94 +392,54 @@ export class ModelServiceImpl implements IModelService {
);
}
private static _commonPrefix(a: ILineSequence, aLen: number, aDelta: number, b: ILineSequence, bLen: number, bDelta: number): number {
const maxResult = Math.min(aLen, bLen);
let result = 0;
for (let i = 0; i < maxResult && a.getLineContent(aDelta + i) === b.getLineContent(bDelta + i); i++) {
result++;
}
return result;
}
private static _commonSuffix(a: ILineSequence, aLen: number, aDelta: number, b: ILineSequence, bLen: number, bDelta: number): number {
const maxResult = Math.min(aLen, bLen);
let result = 0;
for (let i = 0; i < maxResult && a.getLineContent(aDelta + aLen - i) === b.getLineContent(bDelta + bLen - i); i++) {
result++;
}
return result;
}
/**
* Compute edits to bring `model` to the state of `textSource`.
*/
public static _computeEdits(model: ITextModel, textBuffer: ITextBuffer): IIdentifiedSingleEditOperation[] {
const modelLineSequence = new class implements ISequence {
public getLength(): number {
return model.getLineCount();
}
public getElementHash(index: number): string {
return model.getLineContent(index + 1);
}
};
const textSourceLineSequence = new class implements ISequence {
public getLength(): number {
return textBuffer.getLineCount();
}
public getElementHash(index: number): string {
return textBuffer.getLineContent(index + 1);
}
};
const diffResult = new LcsDiff(modelLineSequence, textSourceLineSequence).ComputeDiff(false);
let edits: IIdentifiedSingleEditOperation[] = [], editsLen = 0;
const modelLineCount = model.getLineCount();
for (let i = 0, len = diffResult.length; i < len; i++) {
const diff = diffResult[i];
const originalStart = diff.originalStart;
const originalLength = diff.originalLength;
const modifiedStart = diff.modifiedStart;
const modifiedLength = diff.modifiedLength;
let lines: string[] = [];
for (let j = 0; j < modifiedLength; j++) {
lines[j] = textBuffer.getLineContent(modifiedStart + j + 1);
}
let text = lines.join('\n');
let range: Range;
if (originalLength === 0) {
// insertion
if (originalStart === modelLineCount) {
// insert at the end
const maxLineColumn = model.getLineMaxColumn(modelLineCount);
range = new Range(
modelLineCount, maxLineColumn,
modelLineCount, maxLineColumn
);
text = '\n' + text;
} else {
// insert
range = new Range(
originalStart + 1, 1,
originalStart + 1, 1
);
text = text + '\n';
}
} else if (modifiedLength === 0) {
// deletion
const textBufferLineCount = textBuffer.getLineCount();
const commonPrefix = this._commonPrefix(model, modelLineCount, 1, textBuffer, textBufferLineCount, 1);
if (originalStart + originalLength >= modelLineCount) {
// delete at the end
range = new Range(
originalStart, model.getLineMaxColumn(originalStart),
originalStart + originalLength, model.getLineMaxColumn(originalStart + originalLength)
);
} else {
// delete
range = new Range(
originalStart + 1, 1,
originalStart + originalLength + 1, 1
);
}
if (modelLineCount === textBufferLineCount && commonPrefix === modelLineCount) {
// equality case
return [];
}
} else {
// modification
range = new Range(
originalStart + 1, 1,
originalStart + originalLength, model.getLineMaxColumn(originalStart + originalLength)
);
}
const commonSuffix = this._commonSuffix(model, modelLineCount - commonPrefix, commonPrefix, textBuffer, textBufferLineCount - commonPrefix, commonPrefix);
edits[editsLen++] = EditOperation.replace(range, text);
let oldRange: Range, newRange: Range;
if (commonSuffix > 0) {
oldRange = new Range(commonPrefix + 1, 1, modelLineCount - commonSuffix + 1, 1);
newRange = new Range(commonPrefix + 1, 1, textBufferLineCount - commonSuffix + 1, 1);
} else if (commonPrefix > 0) {
oldRange = new Range(commonPrefix, model.getLineMaxColumn(commonPrefix), modelLineCount, model.getLineMaxColumn(modelLineCount));
newRange = new Range(commonPrefix, 1 + textBuffer.getLineLength(commonPrefix), textBufferLineCount, 1 + textBuffer.getLineLength(textBufferLineCount));
} else {
oldRange = new Range(1, 1, modelLineCount, model.getLineMaxColumn(modelLineCount));
newRange = new Range(1, 1, textBufferLineCount, 1 + textBuffer.getLineLength(textBufferLineCount));
}
return edits;
return [EditOperation.replace(oldRange, textBuffer.getValueInRange(newRange, EndOfLinePreference.TextDefined))];
}
public createModel(value: string | ITextBufferFactory, modeOrPromise: TPromise<IMode> | IMode, resource: URI): ITextModel {
......@@ -582,3 +541,7 @@ export class ModelServiceImpl implements IModelService {
this._onModelModeChanged.fire({ model, oldModeId });
}
}
export interface ILineSequence {
getLineContent(lineNumber: number): string;
}
......@@ -43,6 +43,32 @@ suite('ModelService', () => {
assert.equal(model3.getOptions().defaultEOL, DefaultEndOfLine.LF);
});
test('_computeEdits no change', function () {
const model = TextModel.createFromString(
[
'This is line one', //16
'and this is line number two', //27
'it is followed by #3', //20
'and finished with the fourth.', //29
].join('\n')
);
const textBuffer = createTextBuffer(
[
'This is line one', //16
'and this is line number two', //27
'it is followed by #3', //20
'and finished with the fourth.', //29
].join('\n'),
DefaultEndOfLine.LF
);
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
assert.deepEqual(actual, []);
});
test('_computeEdits first line changed', function () {
const model = TextModel.createFromString(
......@@ -67,7 +93,7 @@ suite('ModelService', () => {
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
assert.deepEqual(actual, [
EditOperation.replace(new Range(1, 1, 1, 17), 'This is line One')
EditOperation.replace(new Range(1, 1, 2, 1), 'This is line One\n')
]);
});
......@@ -121,8 +147,15 @@ suite('ModelService', () => {
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
assert.deepEqual(actual, [
EditOperation.replace(new Range(1, 1, 1, 17), 'This is line One'),
EditOperation.replace(new Range(3, 1, 3, 21), 'It is followed by #3')
EditOperation.replace(
new Range(1, 1, 4, 1),
[
'This is line One',
'and this is line number two',
'It is followed by #3',
''
].join('\r\n')
)
]);
});
......@@ -149,7 +182,7 @@ suite('ModelService', () => {
const actual = ModelServiceImpl._computeEdits(model, textBuffer);
assert.deepEqual(actual, [
EditOperation.replace(new Range(3, 2, 3, 2), '\n')
EditOperation.replace(new Range(3, 2, 3, 2), '\r\n')
]);
});
......
......@@ -39,6 +39,7 @@ import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspac
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ILogService } from 'vs/platform/log/common/log';
/** The amount of time to consider terminal errors to be related to the launch */
const LAUNCHING_DURATION = 500;
......@@ -129,7 +130,8 @@ export class TerminalInstance implements ITerminalInstance {
@IThemeService private readonly _themeService: IThemeService,
@IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService,
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ILogService private _logService: ILogService
) {
this._instanceDisposables = [];
this._processDisposables = [];
......@@ -144,6 +146,8 @@ export class TerminalInstance implements ITerminalInstance {
this._terminalHasTextContextKey = KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED.bindTo(this._contextKeyService);
this._preLaunchInputQueue = '';
this._logService.trace(`terminalInstance#ctor (id: ${this.id})`, this._shellLaunchConfig);
this._onDisposed = new Emitter<TerminalInstance>();
this._onFocused = new Emitter<TerminalInstance>();
this._onProcessIdReady = new Emitter<TerminalInstance>();
......@@ -151,7 +155,10 @@ export class TerminalInstance implements ITerminalInstance {
// Create a promise that resolves when the pty is ready
this._processReady = new TPromise<void>(c => {
this.onProcessIdReady(() => c(void 0));
this.onProcessIdReady(() => {
this._logService.debug(`Terminal process ready (id: ${this.id}, processId: ${this.processId})`);
c(void 0);
});
});
this._initDimensions();
......@@ -505,6 +512,8 @@ export class TerminalInstance implements ITerminalInstance {
}
public dispose(): void {
this._logService.trace(`terminalInstance#dispose (id: ${this.id})`);
if (this._windowsShellHelper) {
this._windowsShellHelper.dispose();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册