Completion List Behavior in SyntaxEditor for C# Language

SyntaxEditor .NET Languages Add-on for WPF Forum

The latest build of this product (v25.1.4) was released 1 month ago, which was before this thread was created.
Posted 5 days ago by miles
Version: 24.1.2
Platform: .NET 6
Environment: Windows 11 (64-bit)
Avatar
Hi, we are developing a C# script editor with IntelliSense capabilities in a WPF application.

## Background
* Environment: TargetFramework=net6.0-windows, Actipro=v24.1.2
* We would like the editor to support code completion equivalent to `RoslynPad` as much as possible.
* Additionally, our application has the following requirements:
  * Register assemblies containing our custom API and enable code completion without requiring users to write `using` directives.
  * Support host variables defined by the application, allowing users to use them in the editor without any special declarations.
  * Support top-level statement syntax in C# scripts.
  * Allow users to write custom `using` directives within the text.
    * However, code completion for classes in user-added namespaces is not required.

## Questions

**Question 1**

* In RoslynPad, by specifying a host object type when creating a project during control initialization, the properties defined on that type are recognized as host variables and appear in the code completion list.
  * https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.projectinfo.hostobjecttype?view=roslyn-dotnet-4.13.0#microsoft-codeanalysis-projectinfo-hostobjecttype
* Is it possible to specify a host object type in a similar way with SyntaxEditor to expose its members to the script?
* If so, could you provide a concrete implementation example?

* Additional notes:
  * We are currently achieving this through the following workaround.
  * However, with this approach, the host variables do not consistently appear as completion candidates, and we are unable to achieve stable code completion.
    * Immediately after opening the editor, typing the first character of a host variable as a top-level statement does not show it as a completion candidate.
    * After typing some other code, the host variable may eventually appear as a candidate in top-level statements.
    * In statements on the second line or later, the host variables appear as expected (as far as we have observed).

1. Define a container class for the host variables.
   For example, to make the host variable `App` available, define a static class like the following:
   ```cs
   public static class __ScriptHostVariableContainer
   {
      public static IApp App;       // Define a static field.
   }

   ```
2. Statically import the container class via the SyntaxEditor's header text.
   ```cs
   public void initializeEditor(SyntaxEditor editor, Type hostObjectType)
   {
      var header = new StringBuilder();
      // Use static imports to access static members of the container class.
      header.AppendLine($"using static {hostObjectType.FullName};");
      header.AppendLine();

      // It is hidden in the header text so that it is not displayed on the UI.
      editor.Document.SetHeaderAndFooterText(header.ToString(), string.Empty);
   }
   ```

**Question 2**

* In RoslynPad, code completion (including member completion) works inside `{}` expressions in interpolated strings.
* Is it possible to display the completion list for expressions inside `{}` in interpolated strings with SyntaxEditor as well?
* If so, could you provide a concrete implementation example?

```cs
var hoge = new Hoge("Alice");

// When I type "hoge." below, I want the members of the Hoge class to be displayed as suggestions, but they are not being displayed.
var message = $"Hello {hoge.Name}!";

return message;

class Hoge
{
    public string Name {get;}
    public string Prop1 {get;set;}
    public Hoge(string name){ Name = name;}
}

```
Thanks in advance!

Comments (2)

Posted 4 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Miles,

Thanks for the details. It looks like you’re working from an older version. I recommend testing your scenarios in the latest build, since you’ll be happy to see that for question #2, interpolated string expression syntax highlighting and IntelliPrompt features were added in v25.1. This blog post includes a screenshot of the new functionality.

Regarding question #1, I simplified the scenario into a small document you can paste directly into the main SDI Editor demo in the latest version. The sample includes a comment indicating where the "header" break would conceptually occur once this scenario is fully supported.

using static __ScriptHostVariableContainer;

public static class __ScriptHostVariableContainer
{
   public static string App;       // Define a static field.
}

// Header ends here

// "App" doesn't seem to be resolved here (top-level)

class Foo {
	void Bar() {
		// "App" completion works here:
		App.
	}
}

After pasting the code, I’m seeing that IntelliPrompt resolution for “App” does not work at the top level (near the comment), but it does resolve correctly inside a method. Are you seeing the same behavior on your side? If so, it seems that enabling top‑level resolution to behave like method‑level resolution would give you the result you’re looking for. Can you confirm that sort of update would meet your needs?

Best regards,

[Modified 4 days ago]


Actipro Software Support

Posted 4 days ago by miles
Avatar

Thank you for the prompt response.

After pasting the code, I'm seeing that IntelliPrompt resolution for "App" does not work at the top level (near the comment), but it does resolve correctly inside a method. Are you seeing the same behavior on your side?

Yes, we are seeing the same behavior on our side.

In addition, we have confirmed that "App" does appear as a completion candidate in the following cases:

  • Even in top-level statements, when a ";" or "{" exists later in the document (e.g., on a subsequent line), and the user begins typing at a position before that character.
  • Even in top-level statements, when a {} block scope is defined and the user begins typing inside that scope.

Based on the above observations, we also tried pre-setting {} in the footer text as a workaround, but this approach did not cause "App" to appear as a completion candidate.

If so, it seems that enabling top‑level resolution to behave like method‑level resolution would give you the result you're looking for. Can you confirm that sort of update would meet your needs?

Yes. Even without direct host variable support, that would meet our needs.

As a follow-up, could you confirm our understanding of the following?

  • There is currently no straightforward way to make top-level resolution behave like method-level resolution in either v24.1 (which we are currently using) or the released v25.1.
  • Support for making top-level resolution behave like method-level resolution would be included from the next release onward.

If there is a way to achieve this behavior in the current version, we would appreciate it if you could provide an implementation example.

Thanks,

Add Comment

Please log in to a validated account to post comments.