monaco-editor icon indicating copy to clipboard operation
monaco-editor copied to clipboard

[Bug] Color not applied in registerHoverProvider

Open hpvcodeDev opened this issue 11 months ago • 3 comments

Reproducible in vscode.dev or in VS Code Desktop?

  • [x] Not reproducible in vscode.dev or VS Code Desktop

Reproducible in the monaco editor playground?

Monaco Editor Playground Link

Hello, I am implementing my hoover tool to see the description of my TOKENs using monaco.languages.registerHoverProvider, it works very well for me when they are default languages ​​in monaco editor but if I use a custom language the content of the hoover panel is not painted with it color of my token assigned when creating my theme.

// Registrar el Hover Provider para el lenguaje 'ppl'
monaco.languages.registerHoverProvider('ppl', {
  provideHover: function (model, position) {
    const word = model.getWordAtPosition(position);
    if (!word) {
      return null; // Si no hay ninguna palabra bajo el cursor, no mostramos nada.
    }

    // Aquí puedes personalizar las palabras clave que quieres que tengan un hover especial
    if (word.word === 'FOR') {
      return {
        range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn),
        contents: [
          { value: '**FOR**: Esta es una declaración de bucle en PPL.' },
          { value: '---' }, // Esto crea una línea horizontal (separador)
          { value: 'Sintaxis: `FOR variable := 1 TO max DO`' },
          { value: '---' }, // Esto crea una línea horizontal (separador)
          { value: '**Documentación**: Permite iterar sobre un rango de valores.' }
        ]
      };
    }

    // Si no se encuentra una palabra clave, devolvemos null
    return null;
  }
});

Image

In theory it should use the colors that were assigned in my monaco.editor.defineTheme('ppl-theme-light', { and it doesn't, I don't know how to activate it if there is an option to do that.

For example, in VSCode, when you implement a custom language and add hoover, the color of your custom language is automatically assigned.

Image

Well I hope someone can help me achieve my goal, I leave you my code in Monaco editor Custom Code

Monaco Editor Playground Code


Reproduction Steps

No response

Actual (Problematic) Behavior

No response

Expected Behavior

No response

Additional Context

No response

hpvcodeDev avatar Jan 19 '25 23:01 hpvcodeDev

I met the problem also, anyone can help me?

benjenpoetry avatar Apr 10 '25 11:04 benjenpoetry

Image

return {
  range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn),
  contents: [
    { value: '```ppl\nFOR variable := 1 TO max DO\n```' },
  ]
};

If you have an entire line of text then declaring the language when you create the fenced code block should work as shown here.

rcjsuen avatar Apr 10 '25 12:04 rcjsuen

I met the problem also, anyone can help me?

I had the same issue and solved it using a similar function. It includes checks to avoid showing hover tooltips inside strings or comments, and organizes the keywords in a dictionary for easier management and extension.

This approach worked well for me, in case it helps you too:

monaco.languages.registerHoverProvider('ppl', {
  provideHover(model, position) {
    // Get the word under the cursor
    const word = model.getWordAtPosition(position);
    if (!word) return null;

    // Get the full line and the text before the current position
    const lineContent = model.getLineContent(position.lineNumber);
    const textBeforePosition = lineContent.substring(0, position.column - 1);

    // Check if cursor is inside a string (simple check based on quotes)
    const inString = (textBeforePosition.match(/"/g) || []).length % 2 === 1;

    // Check if cursor is inside a single-line comment
    const commentIndex = lineContent.indexOf('//');
    const inLineComment = commentIndex !== -1 && commentIndex < position.column - 1;

    // Don't show hover if inside a string or comment
    if (inString || inLineComment) return null;

    // Dictionary of keywords and their hover content
    const hoverData = {
      FOR: {
        contents: [
          { value: '```ppl\nFOR var FROM start TO end STEP step DO commands END;\n```' },
          { value: 'Marks the beginning of a FOR ... DO ... END loop. Executes commands for values of var from start to end, incremented by step.' },
        ],
      },
      COS: {
        contents: [
          { value: '```ppl\nCOS(Value)\n```' },
          {
            value:
              'Returns the cosine of Value. Value is interpreted as radians, degrees or gradians, depending on the setting of Angle Measure in Home Settings, CAS Settings, or Symbolic Setup.',
          },
        ],
      },
      // Add more commands here as needed...
    };

    // Normalize the keyword to uppercase and look it up
    const keyword = word.word.toUpperCase();
    const entry = hoverData[keyword];
    if (!entry) return null;

    // Return the hover info with correct range
    return {
      range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn),
      contents: entry.contents,
    };
  },
});

You can review the corrected version in the following link to guide you better: Monaco Example

hpvcodeDev avatar Apr 11 '25 13:04 hpvcodeDev