diff --git a/Nodejs/Product/Nodejs/Guids.cs b/Nodejs/Product/Nodejs/Guids.cs index 254d61c26..7772f7d75 100644 --- a/Nodejs/Product/Nodejs/Guids.cs +++ b/Nodejs/Product/Nodejs/Guids.cs @@ -33,7 +33,8 @@ static class Guids { public const string NodejsNpmCmdSetString = "9F4B31B4-09AC-4937-A2E7-F4BC02BB7DBA"; public const string NodejsProjectFactoryString = "3AF33F2E-1136-4D97-BBB7-1795711AC8B8"; public const string NodejsBaseProjectFactoryString = "9092AA53-FB77-4645-B42D-1CCCA6BD08BD"; - public const string TypeScriptLanguageInfoString = "87bdf188-e6e8-4fcf-a82a-9b8506e01847"; + public const string TypeScriptLanguageInfoString = "4a0dddb5-7a95-4fbf-97cc-616d07737a77"; + public const string TypeScriptDebuggerLanguageInfoString = "87bdf188-e6e8-4fcf-a82a-9b8506e01847"; public const string JadeEditorFactoryString = "6CB69EF8-1329-4DC0-84B4-FA134EA59BE3"; public const string DefaultLanguageServiceString = "{8239BEC4-EE87-11D0-8C98-00C04FC2AB22}"; @@ -60,7 +61,8 @@ static class Guids { public static readonly Guid NodejsEditorFactory = new Guid(NodejsEditorFactoryString); public static readonly Guid NodejsDebugLanguage = new Guid(NodejsDebugLanguageString); public static readonly Guid NodejsNpmCmdSet = new Guid(NodejsNpmCmdSetString); - public static readonly Guid TypeScriptDebugLanguage = new Guid(TypeScriptLanguageInfoString); + public static readonly Guid TypeScriptLanguageInfo = new Guid(TypeScriptLanguageInfoString); + public static readonly Guid TypeScriptDebugLanguage = new Guid(TypeScriptDebuggerLanguageInfoString); public static readonly Guid ScriptDebugLanguage = new Guid(ScriptDebugLanguageString); diff --git a/Nodejs/Product/Nodejs/LanguagePreferences.cs b/Nodejs/Product/Nodejs/LanguagePreferences.cs index fee4543a7..c1ed8a45d 100644 --- a/Nodejs/Product/Nodejs/LanguagePreferences.cs +++ b/Nodejs/Product/Nodejs/LanguagePreferences.cs @@ -14,14 +14,15 @@ // //*********************************************************// +using System; using Microsoft.VisualStudio; using Microsoft.VisualStudio.TextManager.Interop; namespace Microsoft.NodejsTools { - class LanguagePreferences : IVsTextManagerEvents2 { - LANGPREFERENCES _preferences; + class LanguagePreferences : IVsTextManagerEvents4 { + internal LANGPREFERENCES3 _preferences; - public LanguagePreferences(LANGPREFERENCES preferences) { + public LanguagePreferences(LANGPREFERENCES3 preferences) { _preferences = preferences; } @@ -47,12 +48,18 @@ public int OnUnregisterView(IVsTextView pView) { return VSConstants.S_OK; } - public int OnUserPreferencesChanged2(VIEWPREFERENCES2[] viewPrefs, FRAMEPREFERENCES2[] framePrefs, LANGPREFERENCES2[] langPrefs, FONTCOLORPREFERENCES2[] colorPrefs) { - if (langPrefs != null && langPrefs.Length > 0 && langPrefs[0].guidLang == this._preferences.guidLang) { - _preferences.IndentStyle = langPrefs[0].IndentStyle; - _preferences.fAutoListMembers = langPrefs[0].fAutoListMembers; - _preferences.fAutoListParams = langPrefs[0].fAutoListParams; - _preferences.fHideAdvancedAutoListMembers = langPrefs[0].fHideAdvancedAutoListMembers; + public int OnUserPreferencesChanged4(VIEWPREFERENCES3[] pViewPrefs, LANGPREFERENCES3[] pLangPrefs, FONTCOLORPREFERENCES2[] pColorPrefs) { + IVsTextManager4 textMgr = (IVsTextManager4)NodejsPackage.Instance.GetService(typeof(SVsTextManager)); + + if (pLangPrefs != null && pLangPrefs.Length > 0 && pLangPrefs[0].guidLang == _preferences.guidLang) { + _preferences.IndentStyle = pLangPrefs[0].IndentStyle; + _preferences.fAutoListMembers = pLangPrefs[0].fAutoListMembers; + _preferences.fAutoListParams = pLangPrefs[0].fAutoListParams; + _preferences.fHideAdvancedAutoListMembers = pLangPrefs[0].fHideAdvancedAutoListMembers; + + // Synchronize settings back to TS language service + pLangPrefs[0].guidLang = Guids.TypeScriptLanguageInfo; + textMgr.SetUserPreferences4(null, pLangPrefs, null); } return VSConstants.S_OK; } diff --git a/Nodejs/Product/Nodejs/Nodejs.csproj b/Nodejs/Product/Nodejs/Nodejs.csproj index 9bd43744d..58939377a 100644 --- a/Nodejs/Product/Nodejs/Nodejs.csproj +++ b/Nodejs/Product/Nodejs/Nodejs.csproj @@ -116,6 +116,12 @@ False + + True + + + True + True @@ -155,12 +161,8 @@ - - true - - - true - + + @@ -321,6 +323,10 @@ + + Component + + Component diff --git a/Nodejs/Product/Nodejs/NodejsPackage.cs b/Nodejs/Product/Nodejs/NodejsPackage.cs index 79412dcea..e8b159a61 100644 --- a/Nodejs/Product/Nodejs/NodejsPackage.cs +++ b/Nodejs/Product/Nodejs/NodejsPackage.cs @@ -21,12 +21,10 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Web.Script.Serialization; using System.Windows.Forms; -using Microsoft.NodejsTools.Analysis; using Microsoft.NodejsTools.Commands; using Microsoft.NodejsTools.Debugger.DataTips; using Microsoft.NodejsTools.Debugger.DebugEngine; @@ -41,7 +39,6 @@ using Microsoft.NodejsTools.Telemetry; using Microsoft.VisualStudio; using Microsoft.VisualStudio.ComponentModelHost; -using Microsoft.VisualStudio.Debugger.Interop; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; @@ -200,7 +197,7 @@ protected override void Initialize() { delegate { NewProjectFromExistingWizard.IsAddNewProjectCmd = false; } ); - var langService = new NodejsLanguageInfo(this); + var langService = new NodejsLanguageInfo(this); ((IServiceContainer)this).AddService(langService.GetType(), langService, true); ((IServiceContainer)this).AddService(typeof(ClipboardServiceBase), new ClipboardService(), true); @@ -225,14 +222,12 @@ protected override void Initialize() { } RegisterCommands(commands, Guids.NodejsCmdSet); - IVsTextManager textMgr = (IVsTextManager)Instance.GetService(typeof(SVsTextManager)); + IVsTextManager4 textMgr = (IVsTextManager4)Instance.GetService(typeof(SVsTextManager)); - var langPrefs = new LANGPREFERENCES[1]; - langPrefs[0].guidLang = typeof(NodejsLanguageInfo).GUID; - ErrorHandler.ThrowOnFailure(textMgr.GetUserPreferences(null, null, langPrefs, null)); + LANGPREFERENCES3[] langPrefs = GetNodejsLanguagePreferencesFromTypeScript(textMgr); _langPrefs = new LanguagePreferences(langPrefs[0]); - var textManagerEvents2Guid = typeof(IVsTextManagerEvents2).GUID; + var textManagerEvents2Guid = typeof(IVsTextManagerEvents4).GUID; IConnectionPoint textManagerEvents2ConnectionPoint; ((IConnectionPointContainer)textMgr).FindConnectionPoint(ref textManagerEvents2Guid, out textManagerEvents2ConnectionPoint); uint cookie; @@ -256,6 +251,15 @@ protected override void Initialize() { Environment.SetEnvironmentVariable(NodejsConstants.NodeToolsProcessIdEnvironmentVariable, Process.GetCurrentProcess().Id.ToString()); } + private static LANGPREFERENCES3[] GetNodejsLanguagePreferencesFromTypeScript(IVsTextManager4 textMgr) { + var langPrefs = new LANGPREFERENCES3[1]; + langPrefs[0].guidLang = Guids.TypeScriptLanguageInfo; + ErrorHandler.ThrowOnFailure(textMgr.GetUserPreferences4(null, langPrefs, null)); + langPrefs[0].guidLang = typeof(NodejsLanguageInfo).GUID; + textMgr.SetUserPreferences4(null, langPrefs, null); + return langPrefs; + } + private void SubscribeToVsCommandEvents( int eventId, EnvDTE._dispCommandEvents_BeforeExecuteEventHandler beforeExecute = null, diff --git a/Nodejs/Product/Nodejs/Options/NodejsDialogPage.cs b/Nodejs/Product/Nodejs/Options/NodejsDialogPage.cs index 74106a556..e7973ea74 100644 --- a/Nodejs/Product/Nodejs/Options/NodejsDialogPage.cs +++ b/Nodejs/Product/Nodejs/Options/NodejsDialogPage.cs @@ -37,7 +37,7 @@ internal NodejsDialogPage(string category) { _category = category; } - internal void SaveBool(string name, bool value) { + internal virtual void SaveBool(string name, bool value) { SaveString(name, value.ToString()); } @@ -80,7 +80,7 @@ internal void SaveDateTime(string name, DateTime value) { return null; } - internal bool? LoadBool(string name) { + internal virtual bool? LoadBool(string name) { string res = LoadString(name); if (res == null) { return null; diff --git a/Nodejs/Product/Nodejs/Options/NodejsFormattingBracesOptionsPage.cs b/Nodejs/Product/Nodejs/Options/NodejsFormattingBracesOptionsPage.cs index 6dd236a80..77d96c9ea 100644 --- a/Nodejs/Product/Nodejs/Options/NodejsFormattingBracesOptionsPage.cs +++ b/Nodejs/Product/Nodejs/Options/NodejsFormattingBracesOptionsPage.cs @@ -14,12 +14,11 @@ // //*********************************************************// -using System; using System.Runtime.InteropServices; namespace Microsoft.NodejsTools.Options { [ComVisible(true)] - public class NodejsFormattingBracesOptionsPage : NodejsDialogPage { + public class NodejsFormattingBracesOptionsPage : NodejsFormattingDialogPage { private NodejsFormattingBracesOptionsControl _window; public NodejsFormattingBracesOptionsPage() @@ -51,8 +50,8 @@ public override void ResetSettings(){ BraceOnNewLineForFunctions = BraceOnNewLineForControlBlocks = false; } - private const string BraceOnNewLineForFunctionsSetting = "BraceOnNewLineForFunctions"; - private const string BraceOnNewLineForControlBlocksSetting = "BraceOnNewLineForControlBlocks"; + private const string BraceOnNewLineForFunctionsSetting = TypeScriptRegistrySwitches.PlaceOpenBraceOnNewLineForFunctions; + private const string BraceOnNewLineForControlBlocksSetting = TypeScriptRegistrySwitches.PlaceOpenBraceOnNewLineForControlBlocks; public override void LoadSettingsFromStorage(){ // Load settings from storage. diff --git a/Nodejs/Product/Nodejs/Options/NodejsFormattingDialogPage.cs b/Nodejs/Product/Nodejs/Options/NodejsFormattingDialogPage.cs new file mode 100644 index 000000000..8956c9184 --- /dev/null +++ b/Nodejs/Product/Nodejs/Options/NodejsFormattingDialogPage.cs @@ -0,0 +1,60 @@ +//*********************************************************// +// Copyright (c) Microsoft. All rights reserved. +// +// Apache 2.0 License +// +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//*********************************************************// + +using System; +using System.Runtime.InteropServices; +using Microsoft.VisualStudio.Settings; +using Microsoft.VisualStudio.Shell.Interop; + +namespace Microsoft.NodejsTools.Options { + public class NodejsFormattingDialogPage : NodejsDialogPage { + private readonly ISettingsManager _settingsManager; + private const string TypeScriptBaseName = "TextEditor.TypeScript.Specific."; + + public NodejsFormattingDialogPage(string category) : base(category) { + uint handle; + string registryRoot; + var registry = NodejsPackage.Instance.GetService(typeof(SLocalRegistry)) as ILocalRegistry4; + var regKey = registry.GetLocalRegistryRootEx((uint)__VsLocalRegistryType.RegType_UserSettings, out handle, out registryRoot); + _settingsManager = (ISettingsManager)NodejsPackage.Instance.GetService(typeof(SVsSettingsPersistenceManager)); + } + + internal override void SaveBool(string name, bool value) { + var keyName = GetKeyName(name); + var registryValue = value ? 1 : 0; + _settingsManager.SetValueAsync(keyName, registryValue, isMachineLocal: false); + } + + internal override bool? LoadBool(string name) { + var value = _settingsManager.GetValueOrDefault(GetKeyName(name)); + if (value == null) { + return null; + } else { + return value != 0; + } + } + + private static string GetKeyName(string name) { + if (name.EndsWith("_TEMP")) { + name = name.Remove(name.Length - 5); + } + return TypeScriptBaseName + name; + } + + [Guid("9B164E40-C3A2-4363-9BC5-EB4039DEF653")] + private class SVsSettingsPersistenceManager { } + } +} diff --git a/Nodejs/Product/Nodejs/Options/NodejsFormattingGeneralOptionsPage.cs b/Nodejs/Product/Nodejs/Options/NodejsFormattingGeneralOptionsPage.cs index 43b0b024f..a49f313f8 100644 --- a/Nodejs/Product/Nodejs/Options/NodejsFormattingGeneralOptionsPage.cs +++ b/Nodejs/Product/Nodejs/Options/NodejsFormattingGeneralOptionsPage.cs @@ -14,12 +14,11 @@ // //*********************************************************// -using System; using System.Runtime.InteropServices; namespace Microsoft.NodejsTools.Options { [ComVisible(true)] - public class NodejsFormattingGeneralOptionsPage : NodejsDialogPage { + public class NodejsFormattingGeneralOptionsPage : NodejsFormattingDialogPage { private NodejsFormattingGeneralOptionsControl _window; public NodejsFormattingGeneralOptionsPage() @@ -51,10 +50,10 @@ public override void ResetSettings(){ FormatOnEnter = FormatOnSemiColon = FormatOnCloseBrace = FormatOnPaste = true; } - private const string FormatOnEnterSetting = "FormatOnEnter"; - private const string FormatOnSemiColonSetting = "FormatOnSemiColon"; - private const string FormatOnCloseBraceSetting = "FormatOnCloseBrace"; - private const string FormatOnPasteSetting = "FormatOnPaste"; + private const string FormatOnEnterSetting = TypeScriptRegistrySwitches.FormatCompletedLineOnEnter; + private const string FormatOnSemiColonSetting = TypeScriptRegistrySwitches.FormatCompletedStatementOnSemicolon; + private const string FormatOnCloseBraceSetting = TypeScriptRegistrySwitches.FormatCompletedBlockOnRightCurlyBrace; + private const string FormatOnPasteSetting = TypeScriptRegistrySwitches.FormatOnPaste; public override void LoadSettingsFromStorage(){ // Load settings from storage. diff --git a/Nodejs/Product/Nodejs/Options/NodejsFormattingSpacingOptionsPage.cs b/Nodejs/Product/Nodejs/Options/NodejsFormattingSpacingOptionsPage.cs index 0a95bd8a6..0f83fc9af 100644 --- a/Nodejs/Product/Nodejs/Options/NodejsFormattingSpacingOptionsPage.cs +++ b/Nodejs/Product/Nodejs/Options/NodejsFormattingSpacingOptionsPage.cs @@ -14,12 +14,11 @@ // //*********************************************************// -using System; using System.Runtime.InteropServices; namespace Microsoft.NodejsTools.Options { [ComVisible(true)] - public class NodejsFormattingSpacingOptionsPage : NodejsDialogPage { + public class NodejsFormattingSpacingOptionsPage : NodejsFormattingDialogPage { private NodejsFormattingSpacingOptionsControl _window; public NodejsFormattingSpacingOptionsPage() @@ -54,12 +53,12 @@ public override void ResetSettings() { SpaceAfterOpeningAndBeforeClosingNonEmptyParens = false; } - private const string SpaceAfterCommaSetting = "SpaceAfterComma"; - private const string SpaceAfterSemicolonInForSetting = "SpaceAfterSemicolonInFor"; - private const string SpaceBeforeAndAfterBinaryOperatorSetting = "SpaceBeforeAndAfterBinaryOperator"; - private const string SpaceAfterKeywordsInControlFlowSetting = "SpaceAfterKeywordsInControlFlow"; - private const string SpaceAfterFunctionKeywordForAnonymousFunctionsSetting = "SpaceAfterFunctionKeywordForAnonymousFunctions"; - private const string SpaceAfterOpeningAndBeforeClosingNonEmptyParensSetting = "SpaceAfterOpeningAndBeforeClosingNonEmptyParens"; + private const string SpaceAfterCommaSetting = TypeScriptRegistrySwitches.InsertSpaceAfterCommaDelimiter; + private const string SpaceAfterSemicolonInForSetting = TypeScriptRegistrySwitches.InsertSpaceAfterSemicolonInForStatements; + private const string SpaceBeforeAndAfterBinaryOperatorSetting = TypeScriptRegistrySwitches.InsertSpaceBeforeAndAfterBinaryOperators; + private const string SpaceAfterKeywordsInControlFlowSetting = TypeScriptRegistrySwitches.InsertSpaceAfterKeywordsInControlFlowStatements; + private const string SpaceAfterFunctionKeywordForAnonymousFunctionsSetting = TypeScriptRegistrySwitches.InsertSpaceAfterFunctionKeywordForAnonymousFunctions; + private const string SpaceAfterOpeningAndBeforeClosingNonEmptyParensSetting = TypeScriptRegistrySwitches.InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis; public override void LoadSettingsFromStorage() { // Load settings from storage. diff --git a/Nodejs/Product/Nodejs/Options/TypeScriptRegistrySwitches.cs b/Nodejs/Product/Nodejs/Options/TypeScriptRegistrySwitches.cs new file mode 100644 index 000000000..789a9d36b --- /dev/null +++ b/Nodejs/Product/Nodejs/Options/TypeScriptRegistrySwitches.cs @@ -0,0 +1,66 @@ +//*********************************************************// +// Copyright (c) Microsoft. All rights reserved. +// +// Apache 2.0 License +// +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//*********************************************************// + +namespace Microsoft.NodejsTools.Options { + /// + /// Copied from TypeScript\VS\LanguageService\TypeScriptLanguageService\ToolsOptions\Constants.cs + /// + public static class TypeScriptRegistrySwitches { + public const string TypeScriptLanguageServiceSubKey = "TypeScriptLanguageService"; + + public const string TerminateProcessOnException = "TerminateProcessOnException"; + public const string SimulateCrashOnCompletionRequest = "SimulateCrashOnCompletionRequest"; + public const string EnableDevMode = "EnableDevMode"; + public const string CustomTypeScriptServicesFileLocation = "CustomTypeScriptServicesFileLocation"; + public const string CustomDefaultLibraryLocation = "CustomDefaultLibraryLocation"; + public const string CustomDefaultES6LibraryLocation = "CustomDefaultES6LibraryLocation"; + + public const string FormatCompletedLineOnEnter = "FormatCompletedLineOnEnter_TEMP"; // TODO: Remove "TEMP" when option is supported + public const string FormatCompletedStatementOnSemicolon = "FormatCompletedStatementOnSemicolon"; + public const string FormatCompletedBlockOnRightCurlyBrace = "FormatCompletedBlockOnRightCurlyBrace"; + public const string FormatOnPaste = "FormatOnPaste_TEMP"; // TODO: Remove "TEMP" when option is supported + + public const string PlaceOpenBraceOnNewLineForFunctions = "PlaceOpenBraceOnNewLineForFunctions"; + public const string PlaceOpenBraceOnNewLineForControlBlocks = "PlaceOpenBraceOnNewLineForControlBlocks"; + + public const string InsertSpaceAfterCommaDelimiter = "InsertSpaceAfterCommaDelimiter"; + public const string InsertSpaceAfterSemicolonInForStatements = "InsertSpaceAfterSemicolonInForStatements"; + public const string InsertSpaceBeforeAndAfterBinaryOperators = "InsertSpaceBeforeAndAfterBinaryOperators"; + public const string InsertSpaceAfterKeywordsInControlFlowStatements = "InsertSpaceAfterKeywordsInControlFlowStatements"; + public const string InsertSpaceAfterFunctionKeywordForAnonymousFunctions = "InsertSpaceAfterFunctionKeywordForAnonymousFunctions"; + public const string InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis = "InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"; + + public const string ShowVirtualProjectsInSolutionExplorerWhenNoSolution = "ShowVirtualProjectsInSolutionExplorerWhenNoSolution"; + public const string ShowVirtualProjectsInSolutionExplorerWhenSolutionOpen = "ShowVirtualProjectsInSolutionExplorerWhenSolutionOpen"; + + public const string AutomaticallyCompileTypeScriptFilesWhenSavedWhenNoSolution = "AutomaticallyCompileTypeScriptFilesWhenSavedWhenNoSolution"; + public const string UseAMDCodeGenerationForModulesThatAreNotPartOfAProject = "UseAMDCodeGenerationForModulesThatAreNotPartOfAProject"; + public const string UseCommonJSCodeGenerationForModulesThatAreNotPartOfAProject = "UseCommonJSCodeGenerationForModulesThatAreNotPartOfAProject"; + public const string UseSystemCodeGenerationForModulesThatAreNotPartOfAProject = "UseSystemCodeGenerationForModulesThatAreNotPartOfAProject"; + public const string UseUMDCodeGenerationForModulesThatAreNotPartOfAProject = "UseUMDCodeGenerationForModulesThatAreNotPartOfAProject"; + public const string UseES2015CodeGenerationForModulesThatAreNotPartOfAProject = "UseES2015CodeGenerationForModulesThatAreNotPartOfAProject"; + + public const string UseTypeScriptExperimental = "UseTypeScriptExperimental"; + + public const string UseJsxReactForFilesThatAreNotPartOfAProject = "UseJsxReactForFilesThatAreNotPartOfAProject"; + public const string UseJsxPreserveForFilesThatAreNotPartOfAProject = "UseJsxPreserveForFilesThatAreNotPartOfAProject"; + + public const string ECMAScriptForFilesThatAreNotPartOfAProject = "ECMAScriptForFilesThatAreNotPartOfAProject"; + public const string ShowGruntGulpDialogForAspNet = "ShowGruntGulpDialogForAspNet"; + + public const string CompletionChars = "CompletionChars"; + } +} \ No newline at end of file