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

[Bug] new support for Python f-strings breaks with multi-line f-strings

Open dylanscott opened this issue 1 year ago • 2 comments

Reproducible in vscode.dev or in VS Code Desktop?

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

Reproducible in the monaco editor playground?

Monaco Editor Playground Link

Link

CleanShot 2024-07-12 at 11 08 38@2x

Monaco Editor Playground Code

single_line_f_string f'''nothing {'to see'} here'''

multi_line_f_string = f"""first line looks fine
{'uh oh'}
now the highlighting is broken down here :(
"""

also = "it's broken highlighting for everything after"
four = 2 + 2

Reproduction Steps

  1. Configure an editor using the built-in python language
  2. Enter a multi-line f-string which has an expression after the 1st line

Actual (Problematic) Behavior

The portion of the f-string after the expression is highlighted as python code instead of a string, and then the closing f-string delimiter causes code after that to be highlighted as if it were a string

Expected Behavior

Self evident

Additional Context

I believe this was added with #4401, which notably does not have multi-line f-strings in its test coverage.

dylanscott avatar Jul 12 '24 18:07 dylanscott

It is reproducible for me too

ivanksh avatar Aug 16 '24 10:08 ivanksh

Reproducible for us too at windmill.dev, it seems a pretty severe bug for the editing experience

rubenfiszel avatar Sep 05 '24 13:09 rubenfiszel

Affects me too.

PaGrom avatar Oct 22 '24 14:10 PaGrom

This affects us as well, and is a pretty bad bug for UX on our code editor.

charliemeyer avatar Dec 17 '24 14:12 charliemeyer

FWIW I was able to disable the broken syntax highlighting (at the cost of not getting any highlighting within template segments) with a hack like:

import { languages as Languages } from "monaco-editor";
import { language as pythonMonarchLanguage } from "monaco-editor/esm/vs/basic-languages/python/python.js";

// here or on an initialization path:
fixFStringBug(pythonMonarchLanguage);

function fixFStringBug({ tokenizer }: Languages.IMonarchLanguage): void {
  // HACK: unbreak highlighting in the presence of multiline f-strings until
  // https://github.com/microsoft/monaco-editor/issues/4601 is fixed
  const badRules = ["fStringBody", "fDblStringBody", "fStringDetail"];
  for (const rule of badRules) {
    delete tokenizer[rule];
  }

  const badReferences = new Set(badRules.map((rule) => `@${rule}`));
  const isBadRule = (rule: Languages.IMonarchLanguageRule): boolean =>
    Array.isArray(rule) && rule.length === 3 && badReferences.has(rule[2]);
  for (const name of Object.keys(tokenizer)) {
    tokenizer[name] = tokenizer[name].filter((rule) => !isBadRule(rule));
  }
}

You may need to ignore a type error from the 2nd import, or you can add a type stub like

declare module "monaco-editor/esm/vs/basic-languages/python/python.js" {
  export const language: IMonarchLanguage;
}

dylanscott avatar Dec 17 '24 18:12 dylanscott

Proposed solution in PR #4827 Additionally, other f-string usages were added, like lambda function, walrus operator, and more. Details in the PR.

samstrohkorbatt avatar Feb 10 '25 20:02 samstrohkorbatt

Any progress on this?

ivanksh avatar Jun 26 '25 10:06 ivanksh