public ICompletionSource TryCreateCompletionSource(ITextBuffer buffer)
 {
     if (!buffer.Properties.TryGetProperty(nameof(ALanguageCompletionSource), out ALanguageCompletionSource source))
     {
         source = new ALanguageCompletionSource(buffer);
         buffer.Properties.AddProperty(nameof(ALanguageCompletionSource), source);
     }
     return(source);
 }
Ejemplo n.º 2
0
        public void QueryKeyWordCompletion(string input, List <ALanguageCompletionInfo> list)
        {
            if (input.Length == 1 && ALanguageCompletionSource.IsSpecialChar(input[0]))
            {
                input = "";
            }

            foreach (var key in m_rule.GetKeySet())
            {
                if (key.StartsWith(input))
                {
                    list.Add(new ALanguageCompletionInfo(key, null));
                }
            }
        }
        bool Complete(bool force)
        {
            if (m_session == null)
            {
                return(false);
            }

            if (!m_session.SelectedCompletionSet.SelectionStatus.IsSelected && !force)
            {
                m_session.Dismiss();
                return(false);
            }

            var completion = m_session.SelectedCompletionSet.SelectionStatus.Completion;

            if (completion != null)
            {
                ALanguageCompletionSource.UserSelected(completion.InsertionText);
            }

            m_session.Commit();
            return(true);
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            bool handled          = false;
            int  hresult          = VSConstants.S_OK;
            bool update_reference = false;
            int  paste_before     = -1;

            // 1. Pre-process
            if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.COMMENT_BLOCK:
                {
                    var info = GetUIViewItem();
                    if (info != null)
                    {
                        handled = info.Comment(m_view, true);
                    }
                }
                break;

                case VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK:
                {
                    var info = GetUIViewItem();
                    if (info != null)
                    {
                        handled = info.Comment(m_view, false);
                    }
                }
                break;

                case VSConstants.VSStd2KCmdID.AUTOCOMPLETE:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    // handled = StartSession();
                    break;

                case VSConstants.VSStd2KCmdID.RETURN:
                    update_reference = true;
                    handled          = Complete(false);
                    if (!handled)
                    {
                        handled = HandleStringPair();
                    }
                    break;

                case VSConstants.VSStd2KCmdID.TAB:
                    handled = Cancel();
                    break;

                case VSConstants.VSStd2KCmdID.CANCEL:
                    handled = Cancel();
                    break;

                case VSConstants.VSStd2KCmdID.FORMATDOCUMENT:
                {
                    var info = GetUIViewItem();
                    if (info != null)
                    {
                        info.FormatDocument();
                        handled = true;
                    }
                }
                break;

                case VSConstants.VSStd2KCmdID.COMPILE:
                {
                    var info = GetUIViewItem();
                    if (info != null)
                    {
                        info.CompileDocument();
                        handled = true;
                    }
                }
                break;

                case VSConstants.VSStd2KCmdID.BACKSPACE:
                case VSConstants.VSStd2KCmdID.DELETE:
                {
                    if (m_view.Selection.IsEmpty)
                    {
                        var position = m_view.Caret.Position.BufferPosition.Position + 1;
                        if (position >= 0 && position < m_view.TextSnapshot.Length)
                        {
                            update_reference = m_view.TextSnapshot[position] == '\n';
                        }
                    }
                    else
                    {
                        var text = m_view.TextSnapshot.GetText(m_view.Selection.Start.Position, m_view.Selection.End.Position - m_view.Selection.Start.Position);
                        update_reference = text.IndexOf('\n') >= 0;
                    }
                }
                break;
                }
            }
            else if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Paste:
                {
                    paste_before = m_view.Caret.Position.BufferPosition.Position;
                }
                break;
                }
            }

            if (!handled)
            {
                hresult = Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            }

            if (ErrorHandler.Succeeded(hresult))
            {
                UIViewItem info = null;

                if (update_reference)
                {
                    info = GetUIViewItem();
                    if (info != null)
                    {
                        info.UpdateReference();
                    }
                }

                if (pguidCmdGroup == VSConstants.VSStd2K)
                {
                    switch ((VSConstants.VSStd2KCmdID)nCmdID)
                    {
                    case VSConstants.VSStd2KCmdID.TYPECHAR:
                        info = GetUIViewItem();

                        char c = GetTypeChar(pvaIn);
                        if (m_session == null)
                        {
                            if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' ||
                                ALanguageCompletionSource.IsSpecialChar(c))
                            {
                                QueryCompletion(c);
                            }
                        }
                        else
                        {
                            if (c == ' ')
                            {
                                Cancel();
                            }
                            else if (ALanguageCompletionSource.IsSpecialChar(c))
                            {
                                Cancel();
                                QueryCompletion(c);
                            }
                            else
                            {
                                Filter();
                            }
                        }

                        if (info != null)
                        {
                            var position = m_view.Caret.Position.BufferPosition.Position;
                            var handle   = false;
                            // 尝试填补配对字符
                            if (m_string_pair.TryGetValue(c, out string out_pair))
                            {
                                handle = info.PushAutoPair(position, c, out_pair);
                            }

                            if (m_view.Properties.TryGetProperty(nameof(ALanguageController), out ALanguageController controller))
                            {
                                controller.OnTextInput(position - 1);
                            }

                            if (!handle)
                            {
                                info.TypeChar(position, c);
                            }
                        }

                        break;

                    case VSConstants.VSStd2KCmdID.BACKSPACE:
                    {
                        if (m_view.Caret.Position.BufferPosition.Position == m_session_offset)
                        {
                            Cancel();
                        }
                        else
                        {
                            Filter();
                        }
                    }
                    break;
                    }
                }
                else if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
                {
                    switch ((VSConstants.VSStd97CmdID)nCmdID)
                    {
                    case VSConstants.VSStd97CmdID.Paste:
                    {
                        if (info == null)
                        {
                            info = GetUIViewItem();
                        }
                        if (info != null && info.CalcLineNumbers(paste_before, m_view.Caret.Position.BufferPosition.Position, out int line_start, out int line_end))
                        {
                            info.RejustMultiLineIndentation(line_start, line_end);
                        }
                    }
                    break;
                    }
                }
            }

            return(hresult);
        }
        public void VsTextViewCreated(IVsTextView text_view)
        {
            if (ALanguageUtility.s_service_provider == null)
            {
                ALanguageUtility.s_service_provider = m_service_provider;
            }

            if (m_factory == null)
            {
                return;
            }

            SaveAdapterFactory();
            m_factory.Init(m_service_provider, m_adapters_factory);

            // 获取系统单例,用于打开文件
            if (m_open_document == null)
            {
                m_open_document = m_service_provider.GetService(typeof(SVsUIShellOpenDocument)) as IVsUIShellOpenDocument;
            }

            // 获取视窗
            IWpfTextView view = m_adapters_factory.GetWpfTextView(text_view);

            if (view == null)
            {
                return;
            }

            // 添加关闭监听
            view.Closed += OnViewClosed;

            // 创建ABnf
            if (m_abnf == null)
            {
                m_abnf = ALanguageUtility.CreateABnf(m_factory);
            }
            if (m_abnf == null)
            {
                return;
            }
            if (m_abnf_ui == null)
            {
                m_abnf_ui = ALanguageUtility.CreateABnf(m_factory);
            }
            if (m_abnf_ui == null)
            {
                return;
            }

            // 获取高亮tag
            if (m_highlight_tag == null)
            {
                m_highlight_tag = m_factory.CreateTextMarkerTag();
            }

            if (m_highlight_tag != null)
            {
                view.Properties.AddProperty(nameof(TextMarkerTag), m_highlight_tag);
            }

            // 获取全路径
            string full_path = ALanguageUtility.GetFilePath(view);

            if (full_path == null)
            {
                return;
            }

            var solution = m_factory.GetSolution();

            if (solution == null)
            {
                return;
            }

            var server = solution.GetServer();

            if (server != null)
            {
                view.Properties.AddProperty(nameof(ALanguageServer), server);
                view.TextBuffer.Properties.AddProperty(nameof(ALanguageServer), server);
            }
            view.Properties.AddProperty(nameof(IVsTextView), text_view);

            // 获取所在的工程
            m_open_document.IsDocumentInAProject(full_path, out IVsUIHierarchy project, out uint item_id, out Microsoft.VisualStudio.OLE.Interop.IServiceProvider _ppSP, out int _pDocInProj);
            UIProjectInfo project_info = null;

            if (project != null)
            {
                solution.GetProjects().TryGetValue(project, out project_info);
            }

            // 创建信息,并作为属性给view
            var info = new UIViewItem(m_abnf, m_abnf_ui, view, m_service_provider, m_adapters_factory, project_info, item_id, full_path, m_factory, m_factory.GetLineCommentBegin());

            view.Properties.AddProperty(nameof(UIViewItem), info);
            view.TextBuffer.Properties.AddProperty(nameof(UIViewItem), info);

            // 提前添加各种source
            {
                if (!view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageCompletionSource), out ALanguageCompletionSource source))
                {
                    source = new ALanguageCompletionSource(view.TextBuffer);
                    view.TextBuffer.Properties.AddProperty(nameof(ALanguageCompletionSource), source);
                }
            }
            {
                if (!view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageQuickInfoSource), out ALanguageQuickInfoSource source))
                {
                    source = new ALanguageQuickInfoSource(view.TextBuffer);
                    view.TextBuffer.Properties.AddProperty(nameof(ALanguageQuickInfoSource), source);
                }
            }
            {
                if (!view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageSignatureHelpSource), out ALanguageSignatureHelpSource source))
                {
                    source = new ALanguageSignatureHelpSource(view.TextBuffer);
                    view.TextBuffer.Properties.AddProperty(nameof(ALanguageSignatureHelpSource), source);
                }
            }

            {
                if (!view.Properties.TryGetProperty(nameof(ALanguageErrorTagger), out ALanguageErrorTagger tagger))
                {
                    tagger = new ALanguageErrorTagger(view);
                    view.Properties.AddProperty(nameof(ALanguageErrorTagger), tagger);
                }
            }

            {
                if (!view.Properties.TryGetProperty(nameof(ALanguageReferenceTagger), out ALanguageReferenceTagger tagger))
                {
                    tagger = new ALanguageReferenceTagger(view);
                    view.Properties.AddProperty(nameof(ALanguageReferenceTagger), tagger);
                }
            }

            {
                if (!view.Properties.TryGetProperty(nameof(ALanguageHighlightWordTagger), out ALanguageHighlightWordTagger tagger))
                {
                    tagger = new ALanguageHighlightWordTagger(view);
                    view.Properties.AddProperty(nameof(ALanguageHighlightWordTagger), tagger);
                }
            }

            // 添加命令
            {
                ALanguageGotoDefinitionCommand filter = new ALanguageGotoDefinitionCommand(view);
                text_view.AddCommandFilter(filter, out IOleCommandTarget next);
                filter.Next = next;
                view.Properties.AddProperty(nameof(ALanguageGotoDefinitionCommand) + "Target", next);
            }

            {
                ALanguageCompletionCommand filter = new ALanguageCompletionCommand(view, m_completion_broker);
                text_view.AddCommandFilter(filter, out IOleCommandTarget next);
                filter.Next = next;
                view.Properties.AddProperty(nameof(ALanguageCompletionCommand) + "Target", next);
                view.Properties.AddProperty(nameof(ALanguageCompletionCommand), filter);
            }
        }