Skip to content

Commit

Permalink
improvement: New inlay hints options
Browse files Browse the repository at this point in the history
  • Loading branch information
jkciesluk committed Mar 20, 2024
1 parent ff552bb commit 082428f
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 54 deletions.
60 changes: 41 additions & 19 deletions packages/metals-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -760,15 +774,23 @@
"when": "metals:enabled"
},
{
"command": "metals.toggle-implicit-conversions-and-classes",
"command": "metals.toggle-implicit-conversions",
"when": "metals:enabled"
},
{
"command": "metals.toggle-implicit-parameters",
"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"
},
{
Expand Down
84 changes: 49 additions & 35 deletions packages/metals-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,33 @@ export async function activate(context: ExtensionContext): Promise<void> {
}

function migrateOldSettings(): void {
const setting = "showInferredType";
const oldBooleanProperty = config.inspect<boolean>(setting)?.workspaceValue;
if (oldBooleanProperty !== undefined) {
config.update(
setting,
`${oldBooleanProperty}`,
ConfigurationTarget.Workspace
);
}
const inferredTypeSetting = "showInferredType";
const oldStringProperty =
config.inspect<string>(inferredTypeSetting)?.workspaceValue;
const inferredType =
oldStringProperty === "true" || oldStringProperty === "minimal";
const typeParameters = oldStringProperty === "true";
const implicitArgsSetting = "showImplicitArguments";
const implicitArgs = config.get<boolean>(implicitArgsSetting) ?? false;
const implicitConvSetting = "showImplicitConversionsAndClasses";
const implicitConversions = config.get<boolean>(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<void> | undefined {
return currentClient?.stop();
Expand Down Expand Up @@ -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<string>(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(
Expand Down Expand Up @@ -1368,11 +1378,15 @@ function configureSettingsDefaults() {
);
}

function toggleBooleanWorkspaceSetting(setting: string) {
const config = workspace.getConfiguration("metals");
const configProperty = config.inspect<boolean>(setting);
function toggleInlayHintsSetting(setting: string) {
const config = workspace.getConfiguration("metals.inlayHints");
const configProperty = config.inspect<boolean>(`${setting}.enable`);
const currentValues = configProperty?.workspaceValue ?? false;
config.update(setting, !currentValues, ConfigurationTarget.Workspace);
config.update(
`${setting}.enable`,
!currentValues,
ConfigurationTarget.Workspace
);
}

function registerDebugEventListener(context: ExtensionContext) {
Expand Down

0 comments on commit 082428f

Please sign in to comment.