Skip to content

ToCodeInput() drops its language parameter — syntax highlighting silently never activates #4718

Description

@rencoivy

Summary

CodeInputExtensions.ToCodeInput(...) accepts a Languages language parameter but never applies it to the created widget. The Language prop stays null, so the frontend never loads a CodeMirror language extension and syntax highlighting silently never happens for any ToCodeInput(language: ...) call.

Where

src/Ivy/Widgets/Inputs/CodeInput.cs:

public static CodeInputBase ToCodeInput(this IAnyState state, string? placeholder = null,
    bool disabled = false, CodeInputVariant variant = CodeInputVariant.Default,
    Languages language = Languages.Json)
{
    var type = state.GetStateType();
    Type genericType = typeof(CodeInput<>).MakeGenericType(type);
    CodeInputBase input = (CodeInputBase)Activator.CreateInstance(genericType,
        BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null,
        new object?[] { state, placeholder, disabled, variant }, null)!;   // <-- `language` is dropped here
    var nullableProperty = genericType.GetProperty("Nullable", ...);
    nullableProperty?.SetValue(input, type.IsNullableType());
    return input;
}

The language argument is not in the constructor args array and is never assigned afterwards.

Observed behavior (verified with a headless browser against a running app)

For an editor created with state.ToCodeInput("Enter SQL…", language: Languages.Sql):

  • The serialized widget props contain no language key (the prop is null and stripped as default).
  • The frontend CodeInputWidget therefore never resolves an entry in languageExtensions, and the lazy import("@codemirror/lang-sql") chunk is never fetched (confirmed via network capture — no request for the chunk).
  • The rendered .cm-line content contains zero token spans — plain text, no highlighting.

The createIvyCodeTheme highlight style and the chromatic CSS variables are all fine — they just never get tokens to color.

Workaround

Chain the Language extension method, which does set the prop:

state.ToCodeInput("Enter SQL…").Language(Languages.Sql)

Suggested fix

Set the property on the created instance before returning, e.g.:

CodeInputBase input = (CodeInputBase)Activator.CreateInstance(...)!;
input = input with { Language = language };

(or include it in the constructor args if the CodeInput<T> constructor is extended to take it).

Note the parameter's default is Languages.Json, so after the fix every existing ToCodeInput() call will start sending language: "Json" — that appears to be the intended behavior, but worth a release note since editors that today render un-highlighted will begin highlighting as JSON.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions