From 286a12edd106bb8c23c40ca020c449b3673a6dbb Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Sun, 18 Sep 2016 21:14:39 -0700 Subject: [PATCH] defer settings format options on file until it is explicitly requested (#10971) --- .../unittests/tsserverProjectSystem.ts | 41 +++++++++++++++++++ src/server/editorServices.ts | 6 +-- src/server/scriptInfo.ts | 10 ++++- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index cf5208628c..4575ce06b4 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1909,4 +1909,45 @@ namespace ts.projectSystem { checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, barTypings.path]); }); }); + + describe("format settings", () => { + it("can be set globally", () => { + const f1 = { + path: "/a/b/app.ts", + content: "let x;" + }; + const host = createServerHost([f1]); + const projectService = createProjectService(host); + projectService.openClientFile(f1.path); + + const defaultSettings = projectService.getFormatCodeOptions(); + + // set global settings + const newGlobalSettings1 = clone(defaultSettings); + newGlobalSettings1.placeOpenBraceOnNewLineForControlBlocks = !newGlobalSettings1.placeOpenBraceOnNewLineForControlBlocks; + projectService.setHostConfiguration({ formatOptions: newGlobalSettings1 }); + + // get format options for file - should be equal to new global settings + const s1 = projectService.getFormatCodeOptions(server.toNormalizedPath(f1.path)); + assert.deepEqual(s1, newGlobalSettings1, "file settings should be the same with global settings"); + + // set per file format options + const newPerFileSettings = clone(defaultSettings); + newPerFileSettings.insertSpaceAfterCommaDelimiter = !newPerFileSettings.insertSpaceAfterCommaDelimiter; + projectService.setHostConfiguration({ formatOptions: newPerFileSettings, file: f1.path }); + + // get format options for file - should be equal to new per-file settings + const s2 = projectService.getFormatCodeOptions(server.toNormalizedPath(f1.path)); + assert.deepEqual(s2, newPerFileSettings, "file settings should be the same with per-file settings"); + + // set new global settings - they should not affect ones that were set per-file + const newGlobalSettings2 = clone(defaultSettings); + newGlobalSettings2.insertSpaceAfterSemicolonInForStatements = !newGlobalSettings2.insertSpaceAfterSemicolonInForStatements; + projectService.setHostConfiguration({ formatOptions: newGlobalSettings2 }); + + // get format options for file - should be equal to new per-file settings + const s3 = projectService.getFormatCodeOptions(server.toNormalizedPath(f1.path)); + assert.deepEqual(s3, newPerFileSettings, "file settings should still be the same with per-file settings"); + }); + }); } \ No newline at end of file diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 099409ca4a..34e438d37f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -290,13 +290,14 @@ namespace ts.server { } getFormatCodeOptions(file?: NormalizedPath) { + let formatCodeSettings: FormatCodeSettings; if (file) { const info = this.getScriptInfoForNormalizedPath(file); if (info) { - return info.formatCodeSettings; + formatCodeSettings = info.getFormatCodeSettings(); } } - return this.hostConfiguration.formatCodeOptions; + return formatCodeSettings || this.hostConfiguration.formatCodeOptions; } private updateProjectGraphs(projects: Project[]) { @@ -969,7 +970,6 @@ namespace ts.server { } if (content !== undefined) { info = new ScriptInfo(this.host, fileName, content, scriptKind, openedByClient, hasMixedContent); - info.setFormatOptions(toEditorSettings(this.getFormatCodeOptions())); // do not watch files with mixed content - server doesn't know how to interpret it this.filenameToScriptInfo.set(info.path, info); if (!info.isOpen && !hasMixedContent) { diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index ceb879a40c..410382a9ca 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -7,7 +7,7 @@ namespace ts.server { * All projects that include this file */ readonly containingProjects: Project[] = []; - readonly formatCodeSettings: ts.FormatCodeSettings; + private formatCodeSettings: ts.FormatCodeSettings; readonly path: Path; private fileWatcher: FileWatcher; @@ -24,12 +24,15 @@ namespace ts.server { this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames)); this.svc = ScriptVersionCache.fromString(host, content); - this.formatCodeSettings = getDefaultFormatCodeSettings(this.host); this.scriptKind = scriptKind ? scriptKind : getScriptKindFromFileName(fileName); } + getFormatCodeSettings() { + return this.formatCodeSettings; + } + attachToProject(project: Project): boolean { const isNew = !this.isAttached(project); if (isNew) { @@ -90,6 +93,9 @@ namespace ts.server { setFormatOptions(formatSettings: protocol.FormatOptions): void { if (formatSettings) { + if (!this.formatCodeSettings) { + this.formatCodeSettings = getDefaultFormatCodeSettings(this.host); + } mergeMaps(this.formatCodeSettings, formatSettings); } }