From 082428f7f97e1e15c76694d4349961b562c4a0a6 Mon Sep 17 00:00:00 2001 From: Jakub Ciesluk <323892@uwr.edu.pl> Date: Wed, 20 Mar 2024 09:55:59 +0100 Subject: [PATCH] improvement: New inlay hints options --- packages/metals-vscode/package.json | 60 ++++++++++++------ packages/metals-vscode/src/extension.ts | 84 ++++++++++++++----------- 2 files changed, 90 insertions(+), 54 deletions(-) diff --git a/packages/metals-vscode/package.json b/packages/metals-vscode/package.json index ae36c5cc..dbfb29d7 100644 --- a/packages/metals-vscode/package.json +++ b/packages/metals-vscode/package.json @@ -249,23 +249,27 @@ "default": [], "markdownDescription": "List of packages you'd like to be left out of completions, symbol searches, and code actions.\n\nEx. `akka.actor.typed.javadsl` will ensure nothing in the `javadsl` package gets recommended to you.\n\nYou can find the list of default exclusions [here on the Metals website](https://scalameta.org/metals/docs/editors/user-configuration/#excluded-packages).\n\nIf you need to remove one of the defaults, you can simply include it and preface it with `--`." }, - "metals.showInferredType": { - "type": "string", + "metals.inlayHints.inferredTypes.enable": { + "type": "boolean", "default": "false", - "enum": [ - "false", - "true", - "minimal" - ], - "markdownDescription": "When this option is set to true inferred type in all possible places will be shown. This includes types for values, definitions, cases, type parameters. With 'minimal' option Metals will not show inferred type for type parameters and more complicated pattern matches." + "markdownDescription": "Enable/disable inlay hints for inferred variable types and method return types.\n```scala \n\n val x/*: List[Int]*/ = List(1)\n def foo(x: Int)/*: Option[Int]*/ = Some(x)\n```" + + }, + "metals.inlayHints.implicitArguments.enable": { + "type": "boolean", + "markdownDescription": "Enable/disable inlay hints for implicit arguments. \n```scala \n\n given bar: Int = 123\n def foo(x: Int)(using Int) = ??? \n foo(1)/*(using bar)*/\n```" + }, + "metals.inlayHints.implicitConversions.enable": { + "type": "boolean", + "markdownDescription": "Enable/disable inlay hints for implicit conversions. \n```scala \n\n implicit class MInt(i: Int) {\n def incr: Int = i + 1\n }\n val x = /*MInt(*/1/*)*/.incr \n```" }, - "metals.showImplicitArguments": { + "metals.inlayHints.typeParameters.enable": { "type": "boolean", - "markdownDescription": "When this option is enabled, for each method that has implicit arguments they are displayed as additional decorations." + "markdownDescription": "Enable/disable inlay hints for type parameters. \n```scala \n\n val x = List[Int](1)\n def foo[T](x: T) = x\n foo/*[Int]*/(1)\n```" }, - "metals.showImplicitConversionsAndClasses": { + "metals.inlayHints.hintsInPatternMatch.enable": { "type": "boolean", - "markdownDescription": "When this option is enabled, each implicit method and class is displayed as additional decorations at the usage site." + "markdownDescription": "Enable/disable inlay hints in pattern matches. \n```scala \n\n case class Foo(a: Int, b: Int)\n val foo = Foo(1, 2)\n foo match {\n case Foo(a/*: Int*/, b/*: Int*/) =>\n }\n```" }, "metals.javaHome": { "type": "string", @@ -651,19 +655,29 @@ "title": "Stop Scala CLI BSP server" }, { - "command": "metals.toggle-implicit-conversions-and-classes", + "command": "metals.toggle-implicit-conversions", "category": "Metals", - "title": "Toggle showing implicit conversions and classes" + "title": "Toggle inlay hints for implicit conversions" }, { "command": "metals.toggle-implicit-parameters", "category": "Metals", - "title": "Toggle showing implicit parameters" + "title": "Toggle inlay hints for implicit parameters" + }, + { + "command": "metals.toggle-inferred-types", + "category": "Metals", + "title": "Toggle inlay hints for inferred type" }, { - "command": "metals.toggle-show-inferred-type", + "command": "metals.toggle-type-parameters", "category": "Metals", - "title": "Toggle showing inferred type" + "title": "Toggle inlay hints for type parameters" + }, + { + "command": "metals.toggle-hints-in-pattern-match", + "category": "Metals", + "title": "Toggle inlay hints in pattern matches" }, { "command": "metals.copy-worksheet-output", @@ -760,7 +774,7 @@ "when": "metals:enabled" }, { - "command": "metals.toggle-implicit-conversions-and-classes", + "command": "metals.toggle-implicit-conversions", "when": "metals:enabled" }, { @@ -768,7 +782,15 @@ "when": "metals:enabled" }, { - "command": "metals.toggle-show-inferred-type", + "command": "metals.toggle-inferred-types", + "when": "metals:enabled" + }, + { + "command": "metals.toggle-type-parameters", + "when": "metals:enabled" + }, + { + "command": "metals.toggle-hints-in-pattern-match", "when": "metals:enabled" }, { diff --git a/packages/metals-vscode/src/extension.ts b/packages/metals-vscode/src/extension.ts index 7d6ef014..4028f07d 100644 --- a/packages/metals-vscode/src/extension.ts +++ b/packages/metals-vscode/src/extension.ts @@ -155,15 +155,33 @@ export async function activate(context: ExtensionContext): Promise { } function migrateOldSettings(): void { - const setting = "showInferredType"; - const oldBooleanProperty = config.inspect(setting)?.workspaceValue; - if (oldBooleanProperty !== undefined) { - config.update( - setting, - `${oldBooleanProperty}`, - ConfigurationTarget.Workspace - ); - } + const inferredTypeSetting = "showInferredType"; + const oldStringProperty = + config.inspect(inferredTypeSetting)?.workspaceValue; + const inferredType = + oldStringProperty === "true" || oldStringProperty === "minimal"; + const typeParameters = oldStringProperty === "true"; + const implicitArgsSetting = "showImplicitArguments"; + const implicitArgs = config.get(implicitArgsSetting) ?? false; + const implicitConvSetting = "showImplicitConversionsAndClasses"; + const implicitConversions = config.get(implicitConvSetting) ?? false; + [inferredTypeSetting, implicitArgsSetting, implicitConvSetting].forEach( + (setting) => + config.update(setting, undefined, ConfigurationTarget.Workspace) +); + type SettingTuple = [string, boolean]; + const settings: SettingTuple[] = [ + ["inferredTypes", inferredType], + ["typeParameters", typeParameters], + ["implicitArguments", implicitArgs], + ["implicitConversions", implicitConversions], + ]; + settings.forEach(([key, enabled]: SettingTuple) => { + const newKey = `inlayHints.${key}.enable`; + if (enabled) { + config.update(newKey, true, ConfigurationTarget.Workspace); + } + }); } export function deactivate(): Thenable | undefined { return currentClient?.stop(); @@ -944,32 +962,24 @@ function launchMetals( }); }); - registerCommand("metals.toggle-implicit-conversions-and-classes", () => { - toggleBooleanWorkspaceSetting("showImplicitConversionsAndClasses"); + registerCommand("metals.toggle-implicit-parameters", () => { + toggleInlayHintsSetting("implicitArguments"); }); - registerCommand("metals.toggle-implicit-parameters", () => { - toggleBooleanWorkspaceSetting("showImplicitArguments"); + registerCommand("metals.toggle-implicit-conversions", () => { + toggleInlayHintsSetting("implicitConversions"); }); - registerCommand("metals.toggle-show-inferred-type", () => { - const setting = "showInferredType"; - const config = workspace.getConfiguration("metals"); - const configProperty = config.inspect(setting); - const currentValue = configProperty?.workspaceValue ?? "false"; - let newValue = "true"; - switch (currentValue) { - case "true": - newValue = "minimal"; - break; - case "minimal": - newValue = "false"; - break; - case "false": - newValue = "true"; - break; - } - config.update(setting, newValue, ConfigurationTarget.Workspace); + registerCommand("metals.toggle-inferred-types", () => { + toggleInlayHintsSetting("inferredTypes"); + }); + + registerCommand("metals.toggle-type-parameters", () => { + toggleInlayHintsSetting("typeParameters"); + }); + + registerCommand("metals.toggle-hints-in-pattern-match", () => { + toggleInlayHintsSetting("hintsInPatternMatch"); }); registerCommand( @@ -1368,11 +1378,15 @@ function configureSettingsDefaults() { ); } -function toggleBooleanWorkspaceSetting(setting: string) { - const config = workspace.getConfiguration("metals"); - const configProperty = config.inspect(setting); +function toggleInlayHintsSetting(setting: string) { + const config = workspace.getConfiguration("metals.inlayHints"); + const configProperty = config.inspect(`${setting}.enable`); const currentValues = configProperty?.workspaceValue ?? false; - config.update(setting, !currentValues, ConfigurationTarget.Workspace); + config.update( + `${setting}.enable`, + !currentValues, + ConfigurationTarget.Workspace + ); } function registerDebugEventListener(context: ExtensionContext) {