Repository: effekt-lang/effekt-vscode
Pull request #68: Handle InlayHint filtering clientside and allow the user to choose InlayHints
Author: login: JakubSchwenkbeck
Created: 2025-04-29T14:49:43Z | Merged: 2025-05-07T11:07:57Z

## Summary
Regarding #64 
This pull request adds a new `InlayHintProvider` class to our VSCode extension, enabling the extension to request and filter inlay hints from the language server on the client side. The `InlayHintProvider` respects both global VSCode settings (e.g., `editor.inlayHints.enabled`) and user-defined configuration options for toggling specific hint types (e.g., and for now the only:  `effekt.inlayHints.captures`).

## Changes
- **New `InlayHintProvider` class:**
  - Implements the `vscode.InlayHintsProvider` interface. [VSCode Doc InlayHintProvider](https://code.visualstudio.com/api/references/vscode-api#InlayHintsProvider) , [VSCode Doc InlayHints](https://code.visualstudio.com/api/references/vscode-api#InlayHint)
  
 
  - Fetches inlay hints using the `textDocument/inlayHint` request from the language server.
  - Filters and displays hints based on user-defined settings:
    - `effektLang.inlayHints.captures`: Toggles capture hints. (which is the only one for now)
  - Respects VSCode's global `editor.inlayHints.enabled` setting:
    - `on`: Displays all hints.
    - `off`: Disables all hints.
    - `offUnlessPressed`: Displays hints only when the relevant modifier key is pressed.

- **Extension Changes (extension.ts):**
  - Registers the new `InlayHintProvider` for files with the `effekt` and `literate effekt` languages.

- **Configuration Updates (package.json):**
  - Adds new settings for inlay hints:
    - `effekt.inlayHints.captures`: Default is `true`.

## Problem : 
For now, the legacy InlayHints are still displayed (without obeying the new rules) and therefore we have double Inlayhints...duh

## Screenshots:
#### InlayHints: on, show captures Inlay: on (double because of the old one)
![Screenshot from 2025-04-29 16-49-07](https://github.com/user-attachments/assets/9521febe-ab3f-416b-8eb6-bdbb7b7ec386)

#### InlayHints: on, show captures Inlay: off ( we see the legacy InlayHint does not get filtered)
![Screenshot from 2025-04-29 16-48-42](https://github.com/user-attachments/assets/69703fd7-f7af-4f73-a93a-bf3eb951b29d)

## Todo:
 - [x] Remove duplicate InlayHints
 - [x] Update the effekt.InlayHints settings to look more like the examples in the Issue
 - [x] (write doc for this? ((where)) )



Diff:
diff --git a/README.md b/README.md
index a3b2d907..808c97cd 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ With this setup the extension should start the server when an Effekt file is ope
 This extension supports inlay hints that can display useful information about Effekt programs that is not explicitly written out in the source code.
 For example, this includes showing inferred types and [Effekt captures](https://effekt-lang.org/tour/captures).
 You can enable inlay hints in the [VSCode settings](vscode://settings/editor.inlayHints.enabled) at `Editor › Inlay Hints: Enabled`.
+Currently you can choose if you want to display the capture inlay hints at `Effekt › Inlay Hints: Captures`.
 
 ## License
 
diff --git a/package.json b/package.json
index f8c24c2d..516ef4fc 100644
--- a/package.json
+++ b/package.json
@@ -148,6 +148,11 @@
                     "type": "boolean",
                     "default": false,
                     "markdownDescription": "Connect to a running LSP server in debug mode. This setting is only for development of the VSCode plugin and the Effekt compiler.\n\n⚠️ **WARNING:** For this option to work, you first need to start `effekt --server --debug` as a separate process."
+                },
+                "effekt.inlayHints.captures": {
+                    "type": "boolean",
+                    "default": true,
+                    "markdownDescription": "Show capture inlay hints:\n\n ```effekt\n'{io}' def main(): Unit = { println(\" Hello Effekt! \") }\n```"
                 }
             }
         },
diff --git a/src/extension.ts b/src/extension.ts
index 83a2187b..cbcf3740 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -10,10 +10,32 @@ import {
 } from 'vscode-languageclient/node';
 import { EffektManager } from './effektManager';
 import { EffektIRContentProvider } from './irProvider';
-
+import { InlayHintProvider } from './inlayHintsProvider';
 import * as net from 'net';
 
-let client: LanguageClient;
+/**
+ * Overrides the `registerFeature` method to disable the built-in inlay hints feature.
+ *
+ * By default the LanguageClient provides inlay hints automatically, which does not allow 
+ * for filtering Inlay Hints based on their 'data'-field. We use the 'data'-field to allow
+ * the user to select which inlay hints the extension should show.
+ * 
+ * By doing this, we retain full control over how inlay hints are displayed, allowing us to
+ * implement custom logic.
+ *
+ * Note: This approach relies on identifying the inlay hints feature by its constructor name
+ * (`InlayHintsFeature`). If the LSP implementation changes, this logic may need to be updated.
+ */
+class EffektLanguageClient extends LanguageClient {
+    public registerFeature(feature: any) {
+        if (feature.constructor.name === 'InlayHintsFeature') { 
+            return; 
+        }
+        super.registerFeature(feature);
+    }
+}
+
+let client: EffektLanguageClient;
 let effektManager: EffektManager;
 
 function registerCommands(context: vscode.ExtensionContext) {
@@ -160,7 +182,7 @@ export async function activate(context: vscode.ExtensionContext) {
         diagnosticCollectionName: "effekt"
     };
 
-    client = new LanguageClient(
+    client = new EffektLanguageClient(
         'effektLanguageServer',
         'Effekt Language Server',
         serverOptions,
@@ -258,6 +280,16 @@ export async function activate(context: vscode.ExtensionContext) {
 
     await client.start();
     context.subscriptions.push(client);
+
+    vscode.languages.registerInlayHintsProvider(
+        { scheme: 'file', language: 'effekt' },
+        new InlayHintProvider(client)
+    );
+
+    vscode.languages.registerInlayHintsProvider(
+        { scheme: 'file', language: 'literate effekt' },
+        new InlayHintProvider(client)
+    );
 }
 
 export function deactivate(): Thenable<void> | undefined {
diff --git a/src/inlayHintsProvider.ts b/src/inlayHintsProvider.ts
new file mode 100644
index 00000000..04fa94cc
--- /dev/null
+++ b/src/inlayHintsProvider.ts
@@ -0,0 +1,56 @@
+import * as vscode from 'vscode';
+import { Code2ProtocolConverter, LanguageClient, Protocol2CodeConverter } from 'vscode-languageclient/node';
+import {
+  InlayHintRequest,
+  InlayHintParams,
+  InlayHint as LspInlayHint
+} from 'vscode-languageserver-protocol';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+  private client: LanguageClient;
+  private protocol2code: Protocol2CodeConverter;
+  private code2protocol : Code2ProtocolConverter;
+
+  constructor(client: LanguageClient) {
+    this.client = client;
+    this.protocol2code = client.protocol2CodeConverter;
+    this.code2protocol = client.code2ProtocolConverter;
+  }
+
+  async provideInlayHints(
+    document: vscode.TextDocument,
+    range: vscode.Range,
+    _token: vscode.CancellationToken
+  ): Promise<vscode.InlayHint[]> {
+    const config = vscode.workspace.getConfiguration('effekt');
+    const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+    const editorHintsEnabled = vscode.workspace
+      .getConfiguration('editor.inlayHints')
+      .get<string>('enabled', 'on');
+    if (editorHintsEnabled === 'off') {
+      return [];
+    }
+
+    const params: InlayHintParams = {
+      textDocument: this.code2protocol.asTextDocumentIdentifier(document),
+      range: this.code2protocol.asRange(range)
+    };
+
+    const response = (await this.client.sendRequest(
+      InlayHintRequest.type,
+      params
+    )) as LspInlayHint[] | null | undefined;
+
+    if (!response) {
+      return [];
+    }
+
+    const filtered = response.filter(h => {
+      return !(h.data === 'capture' && !showCaptureHints);
+    });
+
+    const hints = await this.protocol2code.asInlayHints(filtered, _token);
+    return hints || [];
+  }
+}
\ No newline at end of file


Reviews:
user: login: jiribenes
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T08:39:09Z
user: login: JakubSchwenkbeck
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T08:50:48Z
user: login: jiribenes
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T09:21:44Z
user: login: jiribenes
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T09:26:02Z
user: login: JakubSchwenkbeck
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T10:05:58Z
user: login: timsueberkrueb
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-07T10:17:32Z
user: login: jiribenes
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T18:00:39Z

Review comments:
diff_hunk: @@ -0,0 +1,50 @@
+import * as vscode from 'vscode';
+import { LanguageClient } from 'vscode-languageclient/node';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+    private client: LanguageClient;
+
+    constructor(client: LanguageClient) {
+        this.client = client;
+    }
+
+    async provideInlayHints(
+        document: vscode.TextDocument,
+        range: vscode.Range,
+        _token: vscode.CancellationToken
+    ): Promise<vscode.InlayHint[]> {
+        const config = vscode.workspace.getConfiguration('effekt');
+        const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+        // Check if inlay hints are globally disabled (VSCode settings)
+        const editorHintsEnabled = vscode.workspace.getConfiguration('editor.inlayHints').get<string>('enabled', 'on');
+        if (editorHintsEnabled === 'off') {
+            return [];
+        }
+
+        // Fetch inlay hints from the language server
+        const response = await this.client.sendRequest('textDocument/inlayHint', {
+            textDocument: { uri: document.uri.toString() },
+            range: {
+                start: { line: range.start.line, character: range.start.character },
+                end: { line: range.end.line, character: range.end.character }
+            }
+        }) as { position: { line: number, character: number }, label: string, kind?: vscode.InlayHintKind, tooltip?: string, data?: string }[];
+
+        // Filter inlay hints based on user preferences
+        const hints: vscode.InlayHint[] = [];
+        for (const hint of response) {
+            if (hint.data === 'capture' && !showCaptureHints) continue;
+
+            const inlayHint = new vscode.InlayHint(
+                new vscode.Position(hint.position.line, hint.position.character),
+                hint.label + ' ' // add a whitespace to restore legacy layout
path: src/InlayHintsProvider.ts
user: login: jiribenes
body: This seems pretty weird, the inlay hints have a left- or right- or left-and-right- padding, no?
https://vscode-api.js.org/classes/vscode.InlayHint.html#paddingLeft
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHint

---


We currently set it here (only padRight for now, but there are situations where we want to pad left like return types):
https://github.com/effekt-lang/effekt/blob/7fc0b8b24ae9db54649e7ba2b9b1b02f86c1c511/effekt/jvm/src/main/scala/effekt/Server.scala#L400
Could you instead parse it from the response?
created_at: 2025-05-07T08:39:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,50 @@
+import * as vscode from 'vscode';
+import { LanguageClient } from 'vscode-languageclient/node';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+    private client: LanguageClient;
+
+    constructor(client: LanguageClient) {
+        this.client = client;
+    }
+
+    async provideInlayHints(
+        document: vscode.TextDocument,
+        range: vscode.Range,
+        _token: vscode.CancellationToken
+    ): Promise<vscode.InlayHint[]> {
+        const config = vscode.workspace.getConfiguration('effekt');
+        const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+        // Check if inlay hints are globally disabled (VSCode settings)
+        const editorHintsEnabled = vscode.workspace.getConfiguration('editor.inlayHints').get<string>('enabled', 'on');
+        if (editorHintsEnabled === 'off') {
+            return [];
+        }
+
+        // Fetch inlay hints from the language server
+        const response = await this.client.sendRequest('textDocument/inlayHint', {
+            textDocument: { uri: document.uri.toString() },
+            range: {
+                start: { line: range.start.line, character: range.start.character },
+                end: { line: range.end.line, character: range.end.character }
+            }
+        }) as { position: { line: number, character: number }, label: string, kind?: vscode.InlayHintKind, tooltip?: string, data?: string }[];
+
+        // Filter inlay hints based on user preferences
+        const hints: vscode.InlayHint[] = [];
+        for (const hint of response) {
+            if (hint.data === 'capture' && !showCaptureHints) continue;
+
+            const inlayHint = new vscode.InlayHint(
+                new vscode.Position(hint.position.line, hint.position.character),
+                hint.label + ' ' // add a whitespace to restore legacy layout
path: src/InlayHintsProvider.ts
user: login: JakubSchwenkbeck
body: Somethings weird here, is there no option to set a padding on the left?
created_at: 2025-05-07T08:50:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,65 @@
+import * as vscode from 'vscode';
+import { LanguageClient } from 'vscode-languageclient/node';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+    private client: LanguageClient;
+
+    constructor(client: LanguageClient) {
+        this.client = client;
+    }
+
+    async provideInlayHints(
+        document: vscode.TextDocument,
+        range: vscode.Range,
+        _token: vscode.CancellationToken
+    ): Promise<vscode.InlayHint[]> {
+        const config = vscode.workspace.getConfiguration('effekt');
+        const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+        // Check if inlay hints are globally disabled (VSCode settings)
+        const editorHintsEnabled = vscode.workspace.getConfiguration('editor.inlayHints').get<string>('enabled', 'on');
+        if (editorHintsEnabled === 'off') {
+            return [];
+        }
+
+        // Fetch inlay hints from the language server
+        const response = await this.client.sendRequest('textDocument/inlayHint', {
+            textDocument: { uri: document.uri.toString() },
+            range: {
+                start: { line: range.start.line, character: range.start.character },
+                end: { line: range.end.line, character: range.end.character }
+            }
+        }) as { 
+            position: { line: number, character: number }, 
+            label: string, 
+            kind?: vscode.InlayHintKind, 
+            tooltip?: string, 
+            data?: string,
+            paddingRight?: boolean, 
+            paddingLeft? : boolean
+        }[];
+
+        // Filter inlay hints based on user preferences
+        const hints: vscode.InlayHint[] = [];
+        for (const hint of response) {
+            if (hint.data === 'capture' && !showCaptureHints) continue;
+
+            // Apply padding based on the response
+            if (hint.paddingRight) {
+                hint.label = hint.label + ' ';
+            }
+            if (hint.paddingLeft) {
+                hint.label = ' ' + hint.label;
+            }
path: src/inlayHintsProvider.ts
user: login: jiribenes
body: This is very ad-hoc, let the editor do it instead. `vscode.InlayHint` created below does have `paddingLeft` and `paddingRight` fields that you can just set...
https://vscode-api.js.org/classes/vscode.InlayHint.html#paddingLeft
created_at: 2025-05-07T09:21:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,65 @@
+import * as vscode from 'vscode';
+import { LanguageClient } from 'vscode-languageclient/node';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+    private client: LanguageClient;
+
+    constructor(client: LanguageClient) {
+        this.client = client;
+    }
+
+    async provideInlayHints(
+        document: vscode.TextDocument,
+        range: vscode.Range,
+        _token: vscode.CancellationToken
+    ): Promise<vscode.InlayHint[]> {
+        const config = vscode.workspace.getConfiguration('effekt');
+        const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+        // Check if inlay hints are globally disabled (VSCode settings)
+        const editorHintsEnabled = vscode.workspace.getConfiguration('editor.inlayHints').get<string>('enabled', 'on');
+        if (editorHintsEnabled === 'off') {
+            return [];
+        }
+
+        // Fetch inlay hints from the language server
+        const response = await this.client.sendRequest('textDocument/inlayHint', {
+            textDocument: { uri: document.uri.toString() },
+            range: {
+                start: { line: range.start.line, character: range.start.character },
+                end: { line: range.end.line, character: range.end.character }
+            }
+        }) as { 
+            position: { line: number, character: number }, 
+            label: string, 
+            kind?: vscode.InlayHintKind, 
+            tooltip?: string, 
+            data?: string,
+            paddingRight?: boolean, 
+            paddingLeft? : boolean
+        }[];
+
+        // Filter inlay hints based on user preferences
+        const hints: vscode.InlayHint[] = [];
+        for (const hint of response) {
+            if (hint.data === 'capture' && !showCaptureHints) continue;
+
+            // Apply padding based on the response
+            if (hint.paddingRight) {
+                hint.label = hint.label + ' ';
+            }
+            if (hint.paddingLeft) {
+                hint.label = ' ' + hint.label;
+            }
path: src/inlayHintsProvider.ts
user: login: jiribenes
body: ```
inlayHint.paddingLeft = hint.paddingLeft
...
```
created_at: 2025-05-07T09:26:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,65 @@
+import * as vscode from 'vscode';
+import { LanguageClient } from 'vscode-languageclient/node';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+    private client: LanguageClient;
+
+    constructor(client: LanguageClient) {
+        this.client = client;
+    }
+
+    async provideInlayHints(
+        document: vscode.TextDocument,
+        range: vscode.Range,
+        _token: vscode.CancellationToken
+    ): Promise<vscode.InlayHint[]> {
+        const config = vscode.workspace.getConfiguration('effekt');
+        const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+        // Check if inlay hints are globally disabled (VSCode settings)
+        const editorHintsEnabled = vscode.workspace.getConfiguration('editor.inlayHints').get<string>('enabled', 'on');
+        if (editorHintsEnabled === 'off') {
+            return [];
+        }
+
+        // Fetch inlay hints from the language server
+        const response = await this.client.sendRequest('textDocument/inlayHint', {
+            textDocument: { uri: document.uri.toString() },
+            range: {
+                start: { line: range.start.line, character: range.start.character },
+                end: { line: range.end.line, character: range.end.character }
+            }
+        }) as { 
+            position: { line: number, character: number }, 
+            label: string, 
+            kind?: vscode.InlayHintKind, 
+            tooltip?: string, 
+            data?: string,
+            paddingRight?: boolean, 
+            paddingLeft? : boolean
+        }[];
+
+        // Filter inlay hints based on user preferences
+        const hints: vscode.InlayHint[] = [];
+        for (const hint of response) {
+            if (hint.data === 'capture' && !showCaptureHints) continue;
+
+            // Apply padding based on the response
+            if (hint.paddingRight) {
+                hint.label = hint.label + ' ';
+            }
+            if (hint.paddingLeft) {
+                hint.label = ' ' + hint.label;
+            }
path: src/inlayHintsProvider.ts
user: login: JakubSchwenkbeck
body: This is now completly obsolet as we use the provided converter:)
created_at: 2025-05-07T10:05:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,56 @@
+import * as vscode from 'vscode';
+import { Code2ProtocolConverter, LanguageClient, Protocol2CodeConverter } from 'vscode-languageclient/node';
+import {
+  InlayHintRequest,
+  InlayHintParams,
+  InlayHint as LspInlayHint
+} from 'vscode-languageserver-protocol';
+
+export class InlayHintProvider implements vscode.InlayHintsProvider {
+  private client: LanguageClient;
+  private protocol2code: Protocol2CodeConverter;
+  private code2protocol : Code2ProtocolConverter;
+
+  constructor(client: LanguageClient) {
+    this.client = client;
+    this.protocol2code = client.protocol2CodeConverter;
+    this.code2protocol = client.code2ProtocolConverter;
+  }
+
+  async provideInlayHints(
+    document: vscode.TextDocument,
+    range: vscode.Range,
+    _token: vscode.CancellationToken
+  ): Promise<vscode.InlayHint[]> {
+    const config = vscode.workspace.getConfiguration('effekt');
+    const showCaptureHints = config.get<boolean>('inlayHints.captures', true);
+
+    const editorHintsEnabled = vscode.workspace
+      .getConfiguration('editor.inlayHints')
+      .get<string>('enabled', 'on');
+    if (editorHintsEnabled === 'off') {
+      return [];
+    }
path: src/inlayHintsProvider.ts
user: login: jiribenes
body: Quick post-hoc question: is this needed? I'd naively assume that the editor just handles it by itself 🤔 
created_at: 2025-05-12T18:00:39Z
author_association: CONTRIBUTOR

PR comments:
user: login: JakubSchwenkbeck
created_at: 2025-04-29T14:51:31Z
body: @jiribenes Is this what you would have in mind?  Having the general InlayHints settings be the ones you set in VSCode and the filtering done clientside? 

And if yes, do you perhaps know how I can get rid of the legacy InlayHints? :)
author_association: CONTRIBUTOR
user: login: jiribenes
created_at: 2025-04-30T08:46:51Z
body: > @jiribenes Is this what you would have in mind? Having the general InlayHints settings be the ones you set in VSCode and the filtering done clientside?

From an operational point of view of the user, yes, however the proposed way seems pretty inefficient as we query inlay hints twice...

> And if yes, do you perhaps know how I can get rid of the legacy InlayHints? :)

Nope, that's unfortunately the whole point of the issue.
What I would assume should work is to override some "afterInlayHints: InlayHint[] => InlayHint[]` callback on the `LanguageClient` itself when it's getting InlayHints, and filtering there...
author_association: CONTRIBUTOR
user: login: timsueberkrueb
created_at: 2025-05-05T10:25:30Z
body: I just looked at this. It seems that if we want to filter hints client-site it is not possible to use the middleware approach:

```ts
let clientOptions: LanguageClientOptions = {
    middleware: {
        provideInlayHints: async (document, range, token, next) => {
            const hints = await next(document, range, token);
            return filterInlayHints(hints)
        }
    },
    diagnosticCollectionName: "effekt"
};
```

because the `vscode.InlayHint` class is view-oriented and doesn't have access to the `data` field.
Therefore, I don't currently see a client-side alternative to the approach proposed in this PR.

ChatGPT proposed the following solution for disabling the built-in inlay hints provider:

```ts
import {
  LanguageClient,
  LanguageClientOptions,
  InlayHintsFeature
} from 'vscode-languageclient/node';

class MyLanguageClient extends LanguageClient {
  // override registerFeature to skip the inlay-hints feature
  protected registerFeature(feature: any) {
    if (feature.constructor === InlayHintsFeature) {
      return; // do nothing, so no auto-provider
    }
    super.registerFeature(feature);
  }
}

let clientOptions: LanguageClientOptions = {
  documentSelector: [{ language: 'effekt' }],
  initializationOptions: { /* ... */ }
};

const client = new MyLanguageClient(
  'effekt',
  'Effekt Language Server',
  serverOptions,
  clientOptions
);
client.start();

// now register only your custom provider:
vscode.languages.registerInlayHintsProvider(
  { scheme: 'file', language: 'effekt' },
  new MyInlayHintProvider(client)
);
```

When just looking at the amount of code necessary, it seems to be easier to implement it on the server side: we already have the extension settings available on the server (via `initializationOptions` and `didChangeConfiguration`. This would also allow us to get rid of the `data` field and avoid hacks such as the one above.

However, from an architectural perspective, it seems to be a violation of concerns to add view-related logic to the language server (even using the extension settings on the server is an architectural smell IMHO), so from that perspective, one might argue for the hack on the client side.

author_association: COLLABORATOR
user: login: jiribenes
created_at: 2025-05-05T12:05:10Z
body: The only constraint from my side is that as a user, I'd like to be able to turn specific kinds of captures on/off when I need to without needing to go through some complicated process. [I'm fine with having to go to settings, clicking a button, then doing something else to restart the state if I really have to]
Specifically, it's very worth it for me during lectures or demos...
author_association: CONTRIBUTOR
user: login: timsueberkrueb
created_at: 2025-05-05T12:17:06Z
body: >  (write doc for this? ((where)) )

Regarding docs:

The `README.md` file is displayed in VSCode and the [extensions marketplace](https://marketplace.visualstudio.com/items?itemName=effekt-lang.effekt). There is already a section about inlay hints we could amend.

https://github.com/effekt-lang/effekt-vscode?tab=readme-ov-file#inlay-hints
author_association: COLLABORATOR
user: login: JakubSchwenkbeck
created_at: 2025-05-05T12:20:56Z
body: So how I read this thread, we dismiss the idea of client-side filtering?
author_association: CONTRIBUTOR
user: login: timsueberkrueb
created_at: 2025-05-05T12:25:39Z
body: I would try if disabling the default inlay hints provider works (see message above), if so, I'm fine with this approach. If it doesn't work, I'd say we implement it server-side.
author_association: COLLABORATOR