Most of these elements are addressed by adding a custom IVsEditorFactory implementation for your language and using a combination of registration attributes to register it. The actual implementation of this interface is beyond the scope of this question, but the documentation is for the interface itself (and related to this page), as well as the DjangoEditorFactory example in The Python Tools for Visual Studio project helped me with my initial implementation.
To support the language of the example, I will make the following assumptions.
- You have implemented the abstract class
ExampleEditorFactory , which provides the main implementation of IVsEditorFactory . The class must have a protected constructor with a bool argument to indicate whether the factory should request the encoding from the user (similar to one of the DjangoEditorFactory constructors).- You have an
ExampleEditorFactoryWithoutEncoding class that extends ExampleEditorFactory and builds a base class that defines false for the promptForEncoding argument. This class must be marked with the [Guid] attribute. - You have an
ExampleEditorFactoryWithEncoding class that extends ExampleEditorFactory and creates a base class that defines true for the promptForEncoding argument. This class must be marked with the [Guid] attribute.
- The following entries have been added to the VSPackage.resx resource file. Constants can be changed, but keep in mind that I used the constant values ​​101 and 102 below.
101 = Language example
102 = Language example with encoding
Registration of editorial factories
The first thing to do is register your editors factories. This is done in two parts.
First use ProvideEditorFactoryAttribute . This attribute associates the resource identifier for the display name factory with the type factory itself.
[ProvideEditorFactory(typeof(ExampleEditorFactoryWithoutEncoding), 101)] [ProvideEditorFactory(typeof(ExampleEditorFactoryWithEncoding), 102)]
Next, in the Initialize method of ExampleLanguagePackage , add RegisterEditorFactory calls after calling base.Initialize() .
protected override void Initialize() { base.Initialize(); RegisterEditorFactory(new ExampleEditorFactoryWithoutEncoding(this)); RegisterEditorFactory(new ExampleEditorFactoryWithEncoding(this)); }
Associate Logical View with Editor Factories
I did not find all the information I would like to use for the ProvideEditorLogicalViewAttribute attributes, but it is important to include at least the following. Be sure to register a boolean view with both factories you created.
[ProvideEditorLogicalView(typeof(ExampleEditorFactoryWithoutEncoding), VSConstants.LOGVIEWID.TextView_string)] [ProvideEditorLogicalView(typeof(ExampleEditorFactoryWithEncoding), VSConstants.LOGVIEWID.TextView_string)]
If this step is not performed, the function in which double-clicking in the output window can lead you to a line of code will not work properly. For example, suppose the output window contains the following line.
c:\dev\file.e1(14,3): unexpected expression
Linking the logical view of TextView allows the IDE to use your factory by double-clicking on this output line to go to line 14, column 3 of the file c: \ dev \ file.e1. Otherwise, another factory will be used to open a new copy of your document, and a lot of functions will probably be missing in the new window.
Associate Standard .e1 and .e2 with Editor .e2
This step provides "Open With ..." support for the .e1 and .e2 files described in source question 1. This step is performed using ProvideEditorExtensionAttribute .
The default priority for the primary factory seems to be 50. An explicitly encoded factory should take precedence less than this, and 49 seems like a good choice. Please note that it is not necessary to specify the NameResourceID named parameter, as it was already specified when using the ProvideEditorFactoryAttribute above (the generated registry keys are identical).
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".e1", 50)] [ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".e2", 50)] [ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".e1", 49)] [ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".e2", 49)]
Associate an extension .* With editor factories
This step provides support for "Open With ..." for all other files and adds support for the file extension options described in source question 2. This step also uses the ProvideEditorExtensionAttribute attribute, but uses a much lower priority value to ensure that the default editor for other types of files will not be overridden by the setting. As in the previous step, a factory with explicit encoding gets a lower priority.
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".*", 2)] [ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".*", 1)]
Concluding notes
This answer does not contain a few details.