语法突出显示不适用于IVsInvisibleEditor [英] Syntax Highlight doesn't work for IVsInvisibleEditor

查看:61
本文介绍了语法突出显示不适用于IVsInvisibleEditor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了IVsInvisibleEditor的实例.我已经使用以下代码实现了这一点:

I have created an instance of IVsInvisibleEditor. I've used following code to achieve this:

    public IWpfTextViewHost CreateEditor(string targetFile)
    {
        var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel));
        var editorAdapter = componentModel.GetService<IVsEditorAdaptersFactoryService>();
        var editorFactoryService = componentModel.GetService<ITextEditorFactoryService>();
        var invisibleEditorManager = (IVsInvisibleEditorManager)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsInvisibleEditorManager));

        IVsInvisibleEditor invisibleEditor;
        ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(
            targetFile,
            pProject: null,
            dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING,
            pFactory: null,
            ppEditor: out invisibleEditor));

        var docDataPointer = IntPtr.Zero;
        Guid guidIVsTextLines = typeof(IVsTextLines).GUID;

        ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData(
            fEnsureWritable: 1,
            riid: ref guidIVsTextLines,
            ppDocData: out docDataPointer));

        //Create a code window adapter
        IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer);           
        var codeWindow = editorAdapter.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider);
        ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData));
        IVsTextView textView;
        ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView));

        var userData = (IVsUserData)codeWindow;
        var uniqueMoniker = Guid.NewGuid().ToString();
        Guid bufferMonikerGuid = typeof(IVsUserData).GUID;
        userData.SetData(ref bufferMonikerGuid, uniqueMoniker);
        var guid = VSConstants.VsTextBufferUserDataGuid.VsTextViewRoles_guid;
        userData.SetData(ref guid, editorFactoryService.CreateTextViewRoleSet(editorFactoryService.DefaultRoles).ToString());

        var  host = editorAdapter.GetWpfTextViewHost(textView);
        host.TextView.Options.SetOptionValue(DefaultTextViewHostOptions.ZoomControlId, false);

        return host;
    }

一切正常,除了没有语法高亮显示,例如,如果我使用C#(.cs)文件在不可见的编辑器中显示.经过一些研究,我发现我还需要向RDT添加一个文档,该文档是通过以下功能完成的:

It all works, except there is no syntax highlighting if, for instance, I use C# (.cs) file to display inside the invisible editor. After some research I've found that I need also to add a document to the RDT, which I did with following function:

    uint RegisterDocument(string targetFile)
    {
        //Then when creating the IVsInvisibleEditor, find and lock the document 
        uint itemID;
        IntPtr docData;
        uint docCookie;
        IVsHierarchy hierarchy;
        var runningDocTable = (IVsRunningDocumentTable)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsRunningDocumentTable));

        var result = runningDocTable.FindAndLockDocument(
            dwRDTLockType: (uint)_VSRDTFLAGS.RDT_EditLock, 
            pszMkDocument: targetFile,
            ppHier: out hierarchy,
            pitemid: out itemID,
            ppunkDocData: out docData,
            pdwCookie: out docCookie);

        return docCookie;
    }

现在,如果我显示C#文件,则显示高亮显示(并且intelisense也起作用),但是例如,如果我显示sql文件,则再次没有语法高亮显示.现在,我进一步研究了一下,发现可能应该在文档上附加语言服务,因此我使用以下代码实现了这一目标:

Now, if I display C# file, then highlight is shown (and also intelisense works), but if I for instance display a sql file, then once again I don't have syntax highlighting. Now, I investigated a little bit further and realized that maybe I should attach a language service on a document, so I used this code to achieve this:

        Guid sqlGuid = LanguageServices.Guids.TSQL;
        docData.SetLanguageServiceID(ref sqlGuid);

,瞧,它可以工作,现在语法高亮也可以在sql文件上使用,但是现在我又遇到了一个问题,对sql文件的多视图无法正常工作.例如,如果我有一个MyQuery.sql文件,并使用不可见的编辑器打开它,它将被打开,语法将显示,并且一切都按预期工作,但是现在,如果我尝试打开相同的文件(而不可见的编辑器是仍然打开),那么我会收到以下消息:

and voila, it works, now syntax highlighting is also working on sql files, but now I have another problem, multi-view on sql file won't work. For instance, if I have a file MyQuery.sql and I open it with invisible editor, it will be opened, syntax will be shown and everything works as expected, but now, if I try to open the same file (while invisible editor is still open) then I get the following message:

我认为,使用sql文件时,带有RDT的内容不正确,似乎在未附加语言服务时,以某种方式忽略了添加到RDT中,这很奇怪,因为相同的代码可用于C#文件.还有什么其他方法可以使用隐形编辑器打开特定文件(可以是任何类型),我丢失了什么吗?

I believe that something with RDT is not OK when using sql file, it seems that when language services are not attached, then adding to RDT is somehow ignored, which is strange, because same code works with C# files. Is there some other way to open particular file (can be of any type) using invisible editor, am I missing something?

推荐答案

花了几天时间在这个问题上,我终于找到了问题所在.因此,以防万一其他人对此有疑问,请按以下说明进行操作:

After spending days on this issue, I finally found what was the problem. So, in case that someone else also have trouble with it here is the explanation:

在创建InvisibleEditor时,下面"发生了很多事情,应该设置的一件事就是特定ITextBuffer的ContentType.当使用sql文件(作为moniker参数传递给RegisterInvisibleEditor方法)时,ContentType设置为纯文本(但对于csharp文件,它设置为CSharp ContentType),但是显然是错误的,调用:

When creating the InvisibleEditor, a lot of things are happening "underneath", one thing that should be set is also the ContentType for particular ITextBuffer. When sql file (which is passed as moniker parameter to RegisterInvisibleEditor method) is used, ContentType is set to plain text (but in case of csharp files, it is set to CSharp ContentType), which is clearly wrong, however, calling:

    Guid sqlGuid = LanguageServices.Guids.TSQL;
    docData.SetLanguageServiceID(ref sqlGuid);

应该解决此问题,设置语言服务将设置正确的ContentType,但由于某种原因,在我看来,此方法不起作用.经过一些调试后,我发现ContentType在解决方案资源管理器中通过dbl单击打开时,与预期的有所不同.它是"Sql Server Tools"的ContentType而不是"T-SQL90",因此,我尝试使用IVsTextBuffer查找该类型的guid:

should solve this issue, setting language service will set the correct ContentType, but for some reason in my case this didn't work. After some debugging I found that ContentType, when it is opened by dbl click in the solution explorer, is different one than anticipated. It was "Sql Server Tools" ContentType not "T-SQL90", so, I tried to find guid of that type using IVsTextBuffer:

        Guid langId;
        vsTextBuffer.GetLanguageServiceID(out langId);

这给了我正确的向导,所以当用我的tsql languange服务替换时,它按预期工作.如果有人需要这些指导,可以在以下位置找到它们 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ VisualStudio \ 10.0 \ Languages (取决于VS安装).

this gave me correct guid, so when replaced with my tsql languange service, it worked as expected. In case that someone needs these guids, they can be found at HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Languages (depending on VS installation).

最后,这是我用来映射这些向导的帮助程序类:

At the end, here is the helper class which I used to map these guids:

    public static class LanguageServices
    {
        public static class Guids
        {
            public static Guid VisualBasic = new Guid("E34ACDC0-BAAE-11D0-88BF-00A0C9110049");
            public static Guid CSharp = new Guid("694DD9B6-B865-4C5B-AD85-86356E9C88DC");
            public static Guid FSharp = new Guid("bc6dd5a5-d4d6-4dab-a00d-a51242dbaf1b");
            public static Guid CPlusPlus = new Guid("B2F072B0-ABC1-11D0-9D62-00C04FD9DFD9");
            public static Guid Css = new Guid("A764E898-518D-11d2-9A89-00C04F79EFC3");
            public static Guid Html = new Guid("58E975A0-F8FE-11D2-A6AE-00104BCC7269");
            public static Guid JavaScript = new Guid("59E2F421-410A-4fc9-9803-1F4E79216BE8");
            public static Guid TSQL = new Guid("43AF1158-FED5-432e-8E8F-23B6FD592857");
            public static Guid SQL = new Guid("ed1a9c1c-d95c-4dc1-8db8-e5a28707a864");
            public static Guid Xaml = new Guid("c9164055-039b-4669-832d-f257bd5554d4");
            public static Guid Xml = new Guid("f6819a78-a205-47b5-be1c-675b3c7f0b8e");
        }
    }

这篇关于语法突出显示不适用于IVsInvisibleEditor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆