Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customize variable presentation using tools options page #6337

Merged
merged 6 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -25,6 +26,7 @@
using Microsoft.PythonTools.Infrastructure;
using Microsoft.VisualStudio.Debugger.DebugAdapterHost.Interfaces;
using Microsoft.VisualStudio.Shell;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.PythonTools.Debugger {
Expand Down Expand Up @@ -201,13 +203,13 @@ private static void AddDebuggerOptions(IAdapterLaunchInfo adapterLaunchInfo, Deb
launchJson.DebugStdLib = debugService.DebugStdLib;
launchJson.ShowReturnValue = debugService.ShowFunctionReturnValue;

// Disable grouping functionality for now, later we'll add an option to control this
launchJson.VariablePresentation = new VariablePresentation {
Special = PresentationMode.Inline,
Function = PresentationMode.Inline,
Class = PresentationMode.Inline,
Protected = PresentationMode.Inline
};
try {
var adapterLaunchInfoJson = JObject.Parse(adapterLaunchInfo.LaunchJson);
AddVariablePresentationOptions(adapterLaunchInfoJson, launchJson);
} catch (JsonReaderException) {
// this should never happen
Debug.Fail("adapterLaunchInfo is not valid json");
}

var excludePTVSInstallDirectory = new PathRule() {
Path = PathUtils.GetParent(typeof(DebugAdapterLauncher).Assembly.Location),
Expand Down Expand Up @@ -241,5 +243,55 @@ private static IEnumerable<string> GetParsedCommandLineArguments(string command)
Marshal.FreeHGlobal(argPointer);
}
}

/// <summary>
/// Adds variable presentation options to the json that will be passed to the debugger when launched.
/// </summary>
/// <param name="adapterLaunchInfoJson">Launch info json that comes from the interpreter and/or the user</param>
/// <param name="launchJson">The json that will be passed to the debugger</param>
private static void AddVariablePresentationOptions(JObject adapterLaunchInfoJson, DebugInfo launchJson) {

if (adapterLaunchInfoJson == null) throw new ArgumentNullException(nameof(adapterLaunchInfoJson));
if (launchJson == null) throw new ArgumentNullException(nameof(launchJson));

// create a default variable presentation and add it to the launchJson
var variablePresentation = new VariablePresentation();
launchJson.VariablePresentation = variablePresentation;

// if no variable presentation is provided, we're done
var varPresJson = adapterLaunchInfoJson.Value<JObject>("variablePresentation");
if (varPresJson == null) {
return;
}

// otherwise, update the launchJson with the provided presentation values
var classModeStr = varPresJson.Value<string>("class");
if (classModeStr != null) {
if (Enum.TryParse(classModeStr, ignoreCase: true, out PresentationMode classMode)) {
variablePresentation.Class = classMode;
}
}

var functionModeStr = varPresJson.Value<string>("function");
if (functionModeStr != null) {
if (Enum.TryParse(functionModeStr, ignoreCase: true, out PresentationMode functionMode)) {
variablePresentation.Function = functionMode;
}
}

var protectedModeStr = varPresJson.Value<string>("protected");
if (protectedModeStr != null) {
if (Enum.TryParse(protectedModeStr, ignoreCase: true, out PresentationMode protectedMode)) {
variablePresentation.Protected = protectedMode;
}
}

var specialModeStr = varPresJson.Value<string>("special");
if (specialModeStr != null) {
if (Enum.TryParse(specialModeStr, ignoreCase: true, out PresentationMode specialMode)) {
variablePresentation.Special = specialMode;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,24 +113,39 @@ public class PathRule {
}

public class VariablePresentation {
[JsonProperty("special")]
public PresentationMode Special { get; set; }

[JsonProperty("function")]
public PresentationMode Function { get; set; }
// default to group, which is the current vscode behavior
public static PresentationMode DefaultPresentationMode = PresentationMode.Group;

[JsonProperty("class_")]
public PresentationMode Class { get; set; }

[JsonProperty("function")]
public PresentationMode Function { get; set; }

[JsonProperty("protected")]
public PresentationMode Protected { get; set; }

[JsonProperty("special")]
public PresentationMode Special { get; set; }

public VariablePresentation() {

Class = DefaultPresentationMode;
Function = DefaultPresentationMode;
Protected = DefaultPresentationMode;
Special = DefaultPresentationMode;
}
}

[JsonConverter(typeof(StringEnumConverter))]
public enum PresentationMode {
[EnumMember(Value="group")]
[EnumMember(Value = "group")]
Group,

[EnumMember(Value = "hide")]
Hide,

[EnumMember(Value = "inline")]
Inline,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ private static string GetLaunchJsonForVsCodeDebugAdapter(IServiceProvider provid
envArray.Add(pair);
}

// get the variable presentation options from Tools -> Options -> Python -> Debugging
var pyService = provider.GetPythonToolsService();
JObject variablePresentationObj = new JObject {
["class"] = pyService.DebuggerOptions.VariablePresentationForClasses.ToString().ToLower(),
["function"] = pyService.DebuggerOptions.VariablePresentationForFunctions.ToString().ToLower(),
["protected"] = pyService.DebuggerOptions.VariablePresentationForProtected.ToString().ToLower(),
["special"] = pyService.DebuggerOptions.VariablePresentationForSpecial.ToString().ToLower(),
};

JObject jsonObj = new JObject {
["exe"] = config.GetInterpreterPath(),
["cwd"] = string.IsNullOrEmpty(config.WorkingDirectory) ? PathUtils.GetParent(config.ScriptName) : config.WorkingDirectory,
Expand All @@ -132,6 +141,7 @@ private static string GetLaunchJsonForVsCodeDebugAdapter(IServiceProvider provid
["options"] = GetOptions(provider, config),
["env"] = envArray,
["interpreterArgs"] = config.InterpreterArguments,
["variablePresentation"] = variablePresentationObj,
};

if (config.Environment == null) {
Expand Down
48 changes: 48 additions & 0 deletions Python/Product/PythonTools/PythonTools/Options/DebuggerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.

using Microsoft.PythonTools.Debugger;
using System;

namespace Microsoft.PythonTools.Options {
Expand All @@ -33,6 +34,12 @@ public sealed class DebuggerOptions {
private const string ShowFunctionReturnValueSetting = "ShowReturnValue";
private const string UseLegacyDebuggerSetting = "UseLegacyDebugger";

// variable presentation
private const string VariablePresentationForClassesSetting = "VariablePresentationForClasses";
private const string VariablePresentationForFunctionsSetting = "VariablePresentationForFunctions";
private const string VariablePresentationForProtectedSetting = "VariablePresentationForProtected";
private const string VariablePresentationForSpecialSetting = "VariablePresentationForSpecial";

internal DebuggerOptions(PythonToolsService service) {
_service = service;
Load();
Expand All @@ -47,6 +54,13 @@ public void Load() {
DebugStdLib = _service.LoadBool(DebugStdLibSetting, Category) ?? false;
ShowFunctionReturnValue = _service.LoadBool(ShowFunctionReturnValueSetting, Category) ?? true;
UseLegacyDebugger = _service.LoadBool(UseLegacyDebuggerSetting, Category) ?? false;

// variable presentation
VariablePresentationForClasses = _service.LoadEnum<PresentationMode>(VariablePresentationForClassesSetting, Category) ?? VariablePresentation.DefaultPresentationMode;
VariablePresentationForFunctions = _service.LoadEnum<PresentationMode>(VariablePresentationForFunctionsSetting, Category) ?? VariablePresentation.DefaultPresentationMode;
VariablePresentationForProtected = _service.LoadEnum<PresentationMode>(VariablePresentationForProtectedSetting, Category) ?? VariablePresentation.DefaultPresentationMode;
VariablePresentationForSpecial = _service.LoadEnum<PresentationMode>(VariablePresentationForSpecialSetting, Category) ?? VariablePresentation.DefaultPresentationMode;

Changed?.Invoke(this, EventArgs.Empty);
}

Expand All @@ -59,6 +73,13 @@ public void Save() {
_service.SaveBool(DebugStdLibSetting, Category, DebugStdLib);
_service.SaveBool(ShowFunctionReturnValueSetting, Category, ShowFunctionReturnValue);
_service.SaveBool(UseLegacyDebuggerSetting, Category, UseLegacyDebugger);

// variable presentation
_service.SaveEnum<PresentationMode>(VariablePresentationForClassesSetting, Category, VariablePresentationForClasses);
_service.SaveEnum<PresentationMode>(VariablePresentationForFunctionsSetting, Category, VariablePresentationForFunctions);
_service.SaveEnum<PresentationMode>(VariablePresentationForProtectedSetting, Category, VariablePresentationForProtected);
_service.SaveEnum<PresentationMode>(VariablePresentationForSpecialSetting, Category, VariablePresentationForSpecial);

Changed?.Invoke(this, EventArgs.Empty);
}

Expand All @@ -71,6 +92,13 @@ public void Reset() {
DebugStdLib = false;
ShowFunctionReturnValue = true;
UseLegacyDebugger = false;

// variable presentation
VariablePresentationForClasses = VariablePresentation.DefaultPresentationMode;
VariablePresentationForFunctions = VariablePresentation.DefaultPresentationMode;
VariablePresentationForProtected = VariablePresentation.DefaultPresentationMode;
VariablePresentationForSpecial = VariablePresentation.DefaultPresentationMode;

Changed?.Invoke(this, EventArgs.Empty);
}

Expand Down Expand Up @@ -147,5 +175,25 @@ public bool UseLegacyDebugger {
get;
set;
}

public PresentationMode VariablePresentationForClasses {
get;
set;
}

public PresentationMode VariablePresentationForFunctions {
get;
set;
}

public PresentationMode VariablePresentationForProtected {
get;
set;
}

public PresentationMode VariablePresentationForSpecial {
get;
set;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading