다음을 통해 공유


연습: 요약 정보 도구 설명 표시

요약 정보는 메서드 시그니처를 표시 하는 IntelliSense 기능 이므로 설명을 경우 메서드 이름 위에 마우스 포인터 이동. 요약 정보를 설명에 사용할 식별자를 정의 하 고 다음 내용을 표시 하는 도구 설명을 만들어 요약 정보 등의 언어를 기반으로 기능을 구현할 수 있습니다. 언어 서비스의 컨텍스트 내에서 요약 정보를 정의할 수 있습니다 또는 직접 파일 이름 확장명 및 콘텐츠 형식을 정의할 수 있고는 해당 형식에 대 한 요약 정보를 표시 하거나 기존 콘텐츠 형식 (예: "text")에 대 한 요약 정보를 표시할 수 있습니다. 이 연습에서는 "텍스트" 콘텐츠 형식에 대 한 요약 정보를 표시 하는 방법을 보여 줍니다.

메서드 이름 위로 포인터를 이동할 때 도구 설명을이 연습 과정에서는 예제 요약 정보를 표시 합니다. 이러한 네 가지 인터페이스를 구현 해야 하는이 디자인:

  • 소스 인터페이스

  • 원본 공급자 인터페이스

  • 컨트롤러 인터페이스

  • 컨트롤러 공급자 인터페이스

소스 및 컨트롤러 공급자 확장 프레임 워크 (MEF) 관리 되는 구성 요소 이며 소스 및 컨트롤러 클래스를 내보낼 수 있도록 하는 역할을 담당 하 고 같이 brokers를 가져오고 서비스의 ITextBufferFactoryService, 도구 설명 텍스트 버퍼를 만듭니다와 IQuickInfoBroker, 요약 정보 세션을 트리거합니다.

이 예제에서는 하드 코드 된 메서드 이름, 설명 목록을 요약 정보 소스를 사용 하 여 언어 서비스 및 해당 언어의 설명서 전체 구현에서 해당 내용을 기재 해야 됩니다.

사전 요구 사항

이 연습을 완료 하려면 설치 해야 해당 Visual Studio 2010 SDK.

참고

Visual Studio SDK에 대 한 자세한 내용은 참조 하십시오. Visual Studio 개요를 확장합니다..Visual Studio SDK를 다운로드 하는 방법를 참조 하십시오. Visual Studio 확장성 개발자 센터 MSDN 웹 사이트에서.

MEF 프로젝트 만들기

MEF 프로젝트를 만들려면

  1. 편집기 분류자 프로젝트를 만듭니다. 솔루션의 이름을 QuickInfoTest.

  2. VSIX 매니페스트 편집기에서 Source.extension.vsixmanifest 파일을 엽니다.

  3. Content MEF 구성 요소 콘텐츠 형식 및 해당 제목 포함은 Path Quickinfotest.dll으로 설정 됩니다.

  4. 저장 하 고 source.extension.vsixmanifest를 닫습니다.

  5. 다음 참조를 프로젝트에 추가 하 고 설정 CopyLocal 에 false:

    Microsoft.VisualStudio.Language.Intellisense

  6. 기존 클래스 파일을 삭제 합니다.

요약 정보 소스 구현

요약 정보 식별자 중 하나를 발견 한 경우 도구 설명 텍스트 버퍼에 콘텐츠를 추가 하 고 식별자 및 그에 대 한 수집입니다. 이 예에서는 식별자 및 그에 대 한 단지 소스 생성자에 추가 됩니다.

요약 정보 소스를 구현 하려면

  1. 클래스 파일을 추가 하 고 이름을 TestQuickInfoSource.

  2. 다음 imports 추가 합니다.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.Collections.ObjectModel
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio.Language.Intellisense
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.Text.Operations
    Imports Microsoft.VisualStudio.Text.Tagging
    Imports Microsoft.VisualStudio.Utilities
    
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Operations;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Utilities;
    
  3. 구현 하는 클래스를 선언 합니다. IQuickInfoSource를 하 고 이름을 TestQuickInfoSource.

    Friend Class TestQuickInfoSource
        Implements IQuickInfoSource
    
    internal class TestQuickInfoSource : IQuickInfoSource
    
  4. 필드에 요약 정보 소스 공급자, 텍스트 버퍼 및 메서드 이름 및 메서드 시그니처를 추가 합니다. 이 예제에서 메서드 이름 및 시그니처를 초기화 되는 TestQuickInfoSource 생성자입니다.

    Private m_provider As TestQuickInfoSourceProvider
    Private m_subjectBuffer As ITextBuffer
    Private m_dictionary As Dictionary(Of String, String)
    
    private TestQuickInfoSourceProvider m_provider;
    private ITextBuffer m_subjectBuffer;
    private Dictionary<string, string> m_dictionary;
    
  5. 요약 정보 소스 공급자와 텍스트 버퍼를 설정 하 고 메서드 이름 및 메서드 시그니처 및 설명의 집합을 채우고 있는 생성자를 추가 합니다.

    Public Sub New(ByVal provider As TestQuickInfoSourceProvider, ByVal subjectBuffer As ITextBuffer)
        m_provider = provider
        m_subjectBuffer = subjectBuffer
    
        'these are the method names and their descriptions
        m_dictionary = New Dictionary(Of String, String)()
        m_dictionary.Add("add", "int add(int firstInt, int secondInt)" & vbLf & "Adds one integer to another.")
        m_dictionary.Add("subtract", "int subtract(int firstInt, int secondInt)" & vbLf & "Subtracts one integer from another.")
        m_dictionary.Add("multiply", "int multiply(int firstInt, int secondInt)" & vbLf & "Multiplies one integer by another.")
        m_dictionary.Add("divide", "int divide(int firstInt, int secondInt)" & vbLf & "Divides one integer by another.")
    End Sub
    
    public TestQuickInfoSource(TestQuickInfoSourceProvider provider, ITextBuffer subjectBuffer)
    {
        m_provider = provider;
        m_subjectBuffer = subjectBuffer;
    
        //these are the method names and their descriptions
        m_dictionary = new Dictionary<string, string>();
        m_dictionary.Add("add", "int add(int firstInt, int secondInt)\nAdds one integer to another.");
        m_dictionary.Add("subtract", "int subtract(int firstInt, int secondInt)\nSubtracts one integer from another.");
        m_dictionary.Add("multiply", "int multiply(int firstInt, int secondInt)\nMultiplies one integer by another.");
        m_dictionary.Add("divide", "int divide(int firstInt, int secondInt)\nDivides one integer by another.");
    }
    
  6. AugmentQuickInfoSession 메서드를 구현합니다. 선 또는 텍스트 버퍼의 끝에 커서가 있을 경우이 예제에서 현재 단어 또는 이전 단어 메서드를 찾습니다. 단어 메서드 이름 중 하나 이면 해당 메서드 이름에 대 한 설명은 요약 정보 내용에 추가 됩니다.

    Public Sub AugmentQuickInfoSession(ByVal session As IQuickInfoSession, ByVal qiContent As IList(Of Object), ByRef applicableToSpan As ITrackingSpan) Implements IQuickInfoSource.AugmentQuickInfoSession
        ' Map the trigger point down to our buffer. 
        Dim subjectTriggerPoint As System.Nullable(Of SnapshotPoint) = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot)
        If Not subjectTriggerPoint.HasValue Then
            applicableToSpan = Nothing 
            Exit Sub 
        End If 
    
        Dim currentSnapshot As ITextSnapshot = subjectTriggerPoint.Value.Snapshot
        Dim querySpan As New SnapshotSpan(subjectTriggerPoint.Value, 0)
    
        'look for occurrences of our QuickInfo words in the span 
        Dim navigator As ITextStructureNavigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer)
        Dim extent As TextExtent = navigator.GetExtentOfWord(subjectTriggerPoint.Value)
        Dim searchText As String = extent.Span.GetText()
    
        For Each key As String In m_dictionary.Keys
            Dim foundIndex As Integer = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase)
            If foundIndex > -1 Then
                applicableToSpan = currentSnapshot.CreateTrackingSpan(querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive)
    
                Dim value As String = ""
                m_dictionary.TryGetValue(key, value)
                If value IsNot Nothing Then
                    qiContent.Add(value)
                Else
                    qiContent.Add("")
                End If 
    
                Exit Sub 
            End If 
        Next
    
        applicableToSpan = Nothing 
    End Sub
    
    public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan)
    {
        // Map the trigger point down to our buffer.
        SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot);
        if (!subjectTriggerPoint.HasValue)
        {
            applicableToSpan = null;
            return;
        }
    
        ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot;
        SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0);
    
        //look for occurrences of our QuickInfo words in the span
        ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer);
        TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value);
        string searchText = extent.Span.GetText();
    
        foreach (string key in m_dictionary.Keys)
        {
            int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase);
            if (foundIndex > -1)
            {
                applicableToSpan = currentSnapshot.CreateTrackingSpan
                    (
                    querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive
                    );
    
                string value;
                m_dictionary.TryGetValue(key, out value);
                if (value != null)
                    qiContent.Add(value);
                else
                    qiContent.Add("");
    
                return;
            }
        }
    
        applicableToSpan = null;
    }
    
  7. 또한 dispose () 메서드를 이후에 구현 해야 IQuickInfoSource 을 구현 IDisposable:

    Private m_isDisposed As Boolean 
    Public Sub Dispose() Implements IDisposable.Dispose
        If Not m_isDisposed Then
            GC.SuppressFinalize(Me)
            m_isDisposed = True 
        End If 
    End Sub
    
    private bool m_isDisposed;
    public void Dispose()
    {
        if (!m_isDisposed)
        {
            GC.SuppressFinalize(this);
            m_isDisposed = true;
        }
    }
    

요약 정보 소스 공급자 구현

기본적으로 자체 MEF 구성 요소 부분으로 내보내고 요약 정보 소스를 인스턴스화할 수 요약 정보 소스 공급자 역할을 합니다. MEF 컴포넌트 부품 이기 때문에 다른 MEF 구성 요소를 가져올 수 있습니다.

요약 정보 소스 공급자를 구현 하려면

  1. 이라는 요약 정보 소스 공급자를 선언 TestQuickInfoSourceProvider 는 구현 IQuickInfoSourceProvider, 함께 내보낼는 NameAttribute "도구 설명 요약 정보 소스"는 OrderAttribute 의 전 "기본" = a ContentTypeAttribute "텍스트".

    <Export(GetType(IQuickInfoSourceProvider))> _
    <Name("ToolTip QuickInfo Source")> _
    <Order(Before:=" Default Quick Info Presenter")> _
    <ContentType("text")> _
    Friend Class TestQuickInfoSourceProvider
        Implements IQuickInfoSourceProvider
    
    [Export(typeof(IQuickInfoSourceProvider))]
    [Name("ToolTip QuickInfo Source")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("text")]
    internal class TestQuickInfoSourceProvider : IQuickInfoSourceProvider
    
  2. 가져오기 두 편집기 서비스 ITextStructureNavigatorSelectorServiceITextBufferFactoryService를 속성으로 TestQuickInfoSourceProvider.

    Private _NavigatorService As ITextStructureNavigatorSelectorService
    <Import()> _
    Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
        Get 
            Return _NavigatorService
        End Get 
        Set(ByVal value As ITextStructureNavigatorSelectorService)
            _NavigatorService = value
        End Set 
    End Property 
    
    Private _TextBufferFactoryService As ITextBufferFactoryService
    <Import()> _
    Friend Property TextBufferFactoryService() As ITextBufferFactoryService
        Get 
            Return _TextBufferFactoryService
        End Get 
        Set(ByVal value As ITextBufferFactoryService)
            _TextBufferFactoryService = value
        End Set 
    End Property
    
    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
    [Import]
    internal ITextBufferFactoryService TextBufferFactoryService { get; set; }
    
  3. 구현 TryCreateQuickInfoSource 새 반환 합니다 TestQuickInfoSource.

    Public Function TryCreateQuickInfoSource(ByVal textBuffer As ITextBuffer) As IQuickInfoSource Implements IQuickInfoSourceProvider.TryCreateQuickInfoSource
        Return New TestQuickInfoSource(Me, textBuffer)
    End Function
    
    public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
    {
        return new TestQuickInfoSource(this, textBuffer);
    }
    

요약 정보 컨트롤러 구현

요약 정보를 표시 할 때 컨트롤러 요약 정보를 확인 합니다. 메서드 이름 중 하나에 해당 하는 단어 위에 마우스 포인터가 있을 때이 예제에서는 요약 정보에 표시 됩니다. 요약 정보 컨트롤러 요약 정보 세션을 트리거하는 마우스 호버 이벤트 처리기를 구현 합니다.

요약 정보 컨트롤러 구현 하기

  1. 구현 하는 클래스를 선언 합니다. IIntellisenseController를 하 고 이름을 TestQuickInfoController.

    Friend Class TestQuickInfoController
        Implements IIntellisenseController
    
    internal class TestQuickInfoController : IIntellisenseController
    
  2. Private 필드 텍스트 보기, 요약 정보 세션 및 컨트롤러 요약 정보 공급자에서 표시 되는 텍스트 버퍼에 텍스트 보기를 추가 합니다.

    Private m_textView As ITextView
    Private m_subjectBuffers As IList(Of ITextBuffer)
    Private m_provider As TestQuickInfoControllerProvider
    Private m_session As IQuickInfoSession
    
    private ITextView m_textView;
    private IList<ITextBuffer> m_subjectBuffers;
    private TestQuickInfoControllerProvider m_provider;
    private IQuickInfoSession m_session;
    
  3. 마우스 호버 이벤트 처리기를 추가 하 고 필드를 설정 하는 생성자를 추가 합니다.

    Friend Sub New(ByVal textView As ITextView, ByVal subjectBuffers As IList(Of ITextBuffer), ByVal provider As TestQuickInfoControllerProvider)
        m_textView = textView
        m_subjectBuffers = subjectBuffers
        m_provider = provider
    
        AddHandler m_textView.MouseHover, AddressOf Me.OnTextViewMouseHover
    End Sub
    
    internal TestQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, TestQuickInfoControllerProvider provider)
    {
        m_textView = textView;
        m_subjectBuffers = subjectBuffers;
        m_provider = provider;
    
        m_textView.MouseHover += this.OnTextViewMouseHover;
    }
    
  4. 요약 정보 세션을 트리거하는 마우스 호버 이벤트 처리기를 추가 합니다.

    Private Sub OnTextViewMouseHover(ByVal sender As Object, ByVal e As MouseHoverEventArgs)
        'find the mouse position by mapping down to the subject buffer 
        Dim point As System.Nullable(Of SnapshotPoint) = m_textView.BufferGraph.MapDownToFirstMatch(New SnapshotPoint(m_textView.TextSnapshot, e.Position), PointTrackingMode.Positive, Function(snapshot) m_subjectBuffers.Contains(snapshot.TextBuffer), PositionAffinity.Predecessor)
    
        If point IsNot Nothing Then 
            Dim triggerPoint As ITrackingPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, PointTrackingMode.Positive)
    
            If Not m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView) Then
                m_session = m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, True)
            End If 
        End If 
    End Sub
    
    private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e)
    {
        //find the mouse position by mapping down to the subject buffer
        SnapshotPoint? point = m_textView.BufferGraph.MapDownToFirstMatch
             (new SnapshotPoint(m_textView.TextSnapshot, e.Position),
            PointTrackingMode.Positive,
            snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer),
            PositionAffinity.Predecessor);
    
        if (point != null)
        {
            ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position,
            PointTrackingMode.Positive);
    
            if (!m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView))
            {
                m_session = m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true);
            }
        }
    }
    
  5. 구현에서 Detach 컨트롤러를 텍스트 보기에서 분리 될 때이 마우스 호버 이벤트 처리기를 제거 하도록 하는 방법.

    Public Sub Detach(ByVal textView As ITextView) Implements IIntellisenseController.Detach
        If m_textView Is textView Then 
            AddHandler m_textView.MouseHover, AddressOf Me.OnTextViewMouseHover
            m_textView = Nothing 
        End If 
    End Sub
    
    public void Detach(ITextView textView)
    {
        if (m_textView == textView)
        {
            m_textView.MouseHover -= this.OnTextViewMouseHover;
            m_textView = null;
        }
    }
    
  6. 구현에서 ConnectSubjectBuffer 메서드 및 DisconnectSubjectBuffer 메서드에 빈 메서드를이 예제로.

    Public Sub ConnectSubjectBuffer(ByVal subjectBuffer As ITextBuffer) Implements IIntellisenseController.ConnectSubjectBuffer
    
    End Sub 
    
    Public Sub DisconnectSubjectBuffer(ByVal subjectBuffer As ITextBuffer) Implements IIntellisenseController.DisconnectSubjectBuffer
    
    End Sub
    
    public void ConnectSubjectBuffer(ITextBuffer subjectBuffer)
    {
    }
    
    public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer)
    {
    }
    

컨트롤러 요약 정보 공급자 구현

기본적으로 자체 MEF 구성 요소 부분으로 내보내고 컨트롤러 요약 정보를 인스턴스화할 수 요약 정보 컨트롤러의 공급자 역할을 합니다. MEF 컴포넌트 부품 이기 때문에 다른 MEF 구성 요소를 가져올 수 있습니다.

요약 정보 컨트롤러가 공급자를 구현 하려면

  1. 라는 클래스를 선언 합니다. TestQuickInfoControllerProvider 는 구현 IIntellisenseControllerProvider, 함께 내보낼는 NameAttribute "요약 정보 도구 설명 컨트롤러" 하는 ContentTypeAttribute "텍스트":

    <Export(GetType(IIntellisenseControllerProvider))> _
    <Name("ToolTip QuickInfo Controller")> _
    <ContentType("text")> _
    Friend Class TestQuickInfoControllerProvider
        Implements IIntellisenseControllerProvider
    
    [Export(typeof(IIntellisenseControllerProvider))]
    [Name("ToolTip QuickInfo Controller")]
    [ContentType("text")]
    internal class TestQuickInfoControllerProvider : IIntellisenseControllerProvider
    
  2. 가져오기는 IQuickInfoBroker 속성으로.

    Private _QuickInfoBroker As IQuickInfoBroker
    <Import()> _
    Friend Property QuickInfoBroker() As IQuickInfoBroker
        Get 
            Return _QuickInfoBroker
        End Get 
        Set(ByVal value As IQuickInfoBroker)
            _QuickInfoBroker = value
        End Set 
    End Property
    
    [Import]
    internal IQuickInfoBroker QuickInfoBroker { get; set; }
    
  3. 구현에서 TryCreateIntellisenseController 에서 컨트롤러 요약 정보를 인스턴스화하는 방법.

    Public Function TryCreateIntellisenseController(ByVal textView As ITextView, ByVal subjectBuffers As IList(Of ITextBuffer)) As IIntellisenseController Implements IIntellisenseControllerProvider.TryCreateIntellisenseController
        Return New TestQuickInfoController(textView, subjectBuffers, Me)
    End Function
    
    public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList<ITextBuffer> subjectBuffers)
    {
        return new TestQuickInfoController(textView, subjectBuffers, this);
    }
    

빌드 및 코드 테스트

이 코드를 테스트 하려면 QuickInfoTest 솔루션을 빌드하고 실험 인스턴스를 실행 합니다.

빌드 및 QuickInfoTest 솔루션을 테스트 하려면

  1. 솔루션을 빌드합니다.

  2. 이 프로젝트를 디버거에서 실행할 때 Visual Studio 두 번째 인스턴스를 인스턴스화합니다.

  3. 텍스트 파일 형식의 단어를 포함 하는 텍스트를 "추가" 및 "빼기"를 만듭니다.

  4. 항목의 "추가" 중 하나 위로 포인터를 이동 합니다. 서명에 대 한 설명의 add 메서드를 표시 해야 합니다.

참고 항목

작업

연습: 콘텐츠 형식의 파일 이름 확장명에 연결