JetBrains / resharper-unity

Unity support for both ReSharper and Rider
Apache License 2.0
1.21k stars 134 forks source link

How can I support custom file types as shaders? #2392

Closed weichx closed 1 year ago

weichx commented 1 year ago

Hi there,

I'm writing a shader plugin for Unity and in doing so have created a new file extension for use with ScriptableImporters. This works great but I don't get any completion in my custom file type even though I've registered it with Rider in the same way hlsl files are registered (via c++ in file types). I think this isn't working because of this list of file types being hard coded. Is there anyway to inject my file type into this list? I don't need any custom behavior other than what Rider already does for standard hlsl files.

Thanks for all your hard work, I've been super happy with this plugin for years now.

citizenmatt commented 1 year ago

Unfortunately, some languages do not allow for registering new file extensions. While they might get some simple functionality, like basic syntax highlighting, more advanced features are not wired up.

This is due to Rider's architecture. Most JetBrains IDEs are built on the IntelliJ Platform, which provides a framework for building advanced language analysis, navigation and so on. However, Rider doesn't directly implement C# and C++ inside IntelliJ, but registers an IntelliJ language that is then implemented out of process, in an app based on ReSharper. In other words, C# is registered twice - once in IntelliJ and once in the ReSharper language engine.

Shaders work in the same way - we register the file type with IntelliJ so that it knows to route language features to the ReSharper language engine. And within ReSharper, we need to register the file type so that ReSharper knows what to do with these files.

So it's possible to register a file extension as a shader in the Rider UI (IntelliJ), but because there's no registration in the ReSharper language engine, ReSharper doesn't know to treat it as a shader file.

We have an outstanding issue (and several duplicate issues linked from it) that captures this feature request, and which you can vote for: RIDER-57727. I'm going to close this issue in favour of that ticket.

In the mean time, it would also be possible to write a small plugin to Rider that would add the registration in the ReSharper engine, but that would require a separate install in Rider.

weichx commented 1 year ago

Thanks for your reply @citizenmatt, I've actually already got a custom rider plugin for my project (I am not the developer of that though so I don't know all the gory details). Would extracting just the shader portion of this plugin and customizing it / adding it to my plugin be a viable approach here?

In the mean time, it would also be possible to write a small plugin to Rider that would add the registration in the ReSharper engine, but that would require a separate install in Rider.

Can you shed a little more light on this statement? How would that work?

citizenmatt commented 1 year ago

It might not be super simple. You can register the file type in the IntelliJ frontend by adding something like this to the plugin's plugin.xml file.

You also need to register your file extension with an existing file type in the dotnet side of things, for the ReSharper based plugin. Unfortunately, we hard code the extensions for a file type, and don't provide a nice API to extend it. You can try adding a component similar to this, which will register a new file type that is an instance of the C++ file type, but I'm not 100% sure it'll work:

[ProjectFileTypeDefinition(Name)]
public class MyNewFileType : CppProjectFileType
{
  private const string Name = "MY_NEW_FILE_TYPE";

  [CanBeNull, UsedImplicitly]
  public new static MyNewFileType Instance { get; private set; }

  private CppProjectFileType()
    : base(Name, "MyNewFileType", new[] { ".whatever" })
  {
  }
}
weichx commented 1 year ago

Thanks a lot, I'll give this a try