다음을 통해 공유


연습: 문 완성 표시

완료 되 면 제공 하려는 식별자를 정의 하 고 다음 완료 세션 트리거하는 문 완성 등의 언어를 기반으로 기능을 구현할 수 있습니다. 문 완성 언어 서비스의 컨텍스트를 정의할 수 있습니다 또는 직접 파일 이름 확장명 및 콘텐츠 형식의 정의 하 고 해당 형식에 대 한 완료를 표시할 수 있습니다 또는 기존 콘텐츠 형식 (예: "일반 텍스트")에 대 한 완료를 트리거할 수 있습니다. 이 연습에서는 텍스트 파일 콘텐츠 형식이 "일반 텍스트" 콘텐츠 형식에 대 한 문 완성을 트리거하는 방법을 보여 줍니다. "텍스트" 콘텐츠 형식 코드 및 XML 파일을 비롯 한 모든 콘텐츠 형식에의 상위 항목입니다.

일반적으로 문 완성 기능 "사용"과 같은 식별자의 시작 부분을 입력 하 여 특정 문자를 입력 하 여 실행 됩니다. 일반적으로 스페이스바, 탭 또는 ENTER 커밋을 선택 키를 눌러이 닫힙니다. 키 입력에 대 한 명령 처리기를 사용 하 여 문자를 입력 하 여 트리거되는 IntelliSense 기능을 구현할 수 있습니다 (는 IOleCommandTarget 인터페이스) 및 구현 하는 처리기 공급자는 IVsTextViewCreationListener 인터페이스입니다. 완성에 참여 하는 식별자의 목록에서 완료 소스를 만들기 위해 구현할는 ICompletionSource 인터페이스 및 완료 원본 공급자 (해당 ICompletionSourceProvider 인터페이스). 공급자 확장 프레임 워크 (MEF) 관리 되는 구성 요소 이며 소스 및 컨트롤러 클래스를 내보낼 및 서비스 및 중개업 자, 예를 들어, 가져오기에 대 한 책임이 있습니다는 ITextStructureNavigatorSelectorService, 텍스트 버퍼에서를 탐색할 수 및 해당 ICompletionBroker, 완성 세션을 트리거합니다.

이 연습에서는 하드 코드 된 일련의 식별자에 대 한 문 완성 기능을 구현 하는 방법을 보여 줍니다. 모든 구현에서 언어 서비스 및 언어 문서 콘텐츠 제공할 책임이 있습니다.

사전 요구 사항

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

참고

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

MEF 프로젝트 만들기

MEF 프로젝트를 만들려면

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

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

  3. 콘텐츠 머리글 포함는 MEF 구성 요소 형식 및 해당 콘텐츠를 경로 로 설정 됩니다 CompletionTest.dll.

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

  5. 다음 참조를 프로젝트에 추가 하 고 있는지 확인 CopyLocal 로 설정 된 false:

    Microsoft.VisualStudio.Editor

    Microsoft.VisualStudio.Language.Intellisense

    Microsoft.VisualStudio.OLE.Interop

    Microsoft.VisualStudio.Shell.10.0

    Microsoft.VisualStudio.Shell.Immutable.10.0

    Microsoft.VisualStudio.TextManager.Interop

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

완료 소스 구현

완료 소스 식별자 집합을 수집 하 고 사용자 식별자의 첫 번째 글자와 같은 완성 트리거를 입력 하면 콘텐츠가 완료 창에 추가 하는 작업을 담당 합니다. 이 예에서는 하드 코딩 식별자 및 그에 대 한 수의AugmentCompletionSession 메서드. 대부분의 실제 사용에 완성 목록을 채우는 토큰을 가져오려면 해당 언어 파서를 사용 합니다.

완료 소스를 구현 하려면

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

  2. 다음 imports 추가 합니다.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio.Language.Intellisense
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Operations
    Imports Microsoft.VisualStudio.Utilities
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Operations;
    using Microsoft.VisualStudio.Utilities;
    
  3. 클래스 선언에 대 한 수정 TestCompletionSource 구현 되도록 ICompletionSource.

    Friend Class TestCompletionSource
        Implements ICompletionSource
    
    internal class TestCompletionSource : ICompletionSource
    
  4. Private 필드를 추가 하 여 원본 공급자가, 텍스트 버퍼 및 목록에 대 한 Completion (완료 세션에 참여 해야 하는 식별자에 해당) 개체입니다.

    Private m_sourceProvider As TestCompletionSourceProvider
    Private m_textBuffer As ITextBuffer
    Private m_compList As List(Of Completion)
    
    private TestCompletionSourceProvider m_sourceProvider;
    private ITextBuffer m_textBuffer;
    private List<Completion> m_compList;
    
  5. 원본 공급자와 버퍼를 설정 하는 생성자를 추가 합니다. TestCompletionSourceProvider 클래스는 다음 단계에서 정의 됩니다.

    Public Sub New(ByVal sourceProvider As TestCompletionSourceProvider, ByVal textBuffer As ITextBuffer)
        m_sourceProvider = sourceProvider
        m_textBuffer = textBuffer
    End Sub
    
    public TestCompletionSource(TestCompletionSourceProvider sourceProvider, ITextBuffer textBuffer)
    {
        m_sourceProvider = sourceProvider;
        m_textBuffer = textBuffer;
    }
    
  6. 구현에서 AugmentCompletionSession 메서드는 완료가 들어 있는 완성 집합을 추가 하 여 원하는 컨텍스트를 제공 합니다. 각 집합을 완료 포함 Completion 완성을 및 완료 창이 있는 탭에 해당 합니다. (Visual Basic 프로젝트에서 완료 창이 탭 이름은 일반적인모든입니다.) FindTokenSpanAtPosition 메서드는 다음 단계에서 정의 됩니다.

    Private Sub AugmentCompletionSession(ByVal session As ICompletionSession, ByVal completionSets As IList(Of CompletionSet)) Implements ICompletionSource.AugmentCompletionSession
        Dim strList As New List(Of String)()
        strList.Add("addition")
        strList.Add("adaptation")
        strList.Add("subtraction")
        strList.Add("summation")
    
        m_compList = New List(Of Completion)()
        For Each str As String In strList
            m_compList.Add(New Completion(str, str, str, Nothing, Nothing))
        Next str
    
        completionSets.Add(New CompletionSet(
            "Tokens",
            "Tokens",
            FindTokenSpanAtPosition(session.GetTriggerPoint(m_textBuffer),
                session),
            m_compList,
            Nothing))
    End Sub
    
    void ICompletionSource.AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
    {
        List<string> strList = new List<string>();
        strList.Add("addition");
        strList.Add("adaptation");
        strList.Add("subtraction");
        strList.Add("summation");
        m_compList = new List<Completion>();
        foreach (string str in strList)
            m_compList.Add(new Completion(str, str, str, null, null));
    
        completionSets.Add(new CompletionSet(
            "Tokens",    //the non-localized title of the tab 
            "Tokens",    //the display title of the tab
            FindTokenSpanAtPosition(session.GetTriggerPoint(m_textBuffer),
                session),
            m_compList,
            null));
    }
    
  7. 캐럿 위치에서 현재 단어를 찾으려면 다음 메서드가 사용 됩니다.

    Private Function FindTokenSpanAtPosition(ByVal point As ITrackingPoint, ByVal session As ICompletionSession) As ITrackingSpan
        Dim currentPoint As SnapshotPoint = (session.TextView.Caret.Position.BufferPosition) - 1
        Dim navigator As ITextStructureNavigator = m_sourceProvider.NavigatorService.GetTextStructureNavigator(m_textBuffer)
        Dim extent As TextExtent = navigator.GetExtentOfWord(currentPoint)
        Return currentPoint.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive)
    End Function
    
    private ITrackingSpan FindTokenSpanAtPosition(ITrackingPoint point, ICompletionSession session)
    {
        SnapshotPoint currentPoint = (session.TextView.Caret.Position.BufferPosition) - 1;
        ITextStructureNavigator navigator = m_sourceProvider.NavigatorService.GetTextStructureNavigator(m_textBuffer);
        TextExtent extent = navigator.GetExtentOfWord(currentPoint);
        return currentPoint.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive);
    }
    
  8. Dispose () 메서드를 구현 합니다.

    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 컴포넌트 부품입니다.

완료 원본 공급자를 구현 하려면

  1. 라는 클래스를 추가 합니다. TestCompletionSourceProvider 는 구현 ICompletionSourceProvider. 이 클래스를 내보낼는 ContentTypeAttribute "일반 텍스트"와 a NameAttribute "테스트 완료"입니다.

    <Export(GetType(ICompletionSourceProvider)), ContentType("plaintext"), Name("token completion")>
    Friend Class TestCompletionSourceProvider
        Implements ICompletionSourceProvider
    
    [Export(typeof(ICompletionSourceProvider))]
    [ContentType("plaintext")]
    [Name("token completion")]
    internal class TestCompletionSourceProvider : ICompletionSourceProvider
    
  2. 가져오기는 ITextStructureNavigatorSelectorService, 현재 단어 완성 소스를 찾는 데 사용할 수 있는.

    <Import()>
    Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
    
    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
  3. 구현에 TryCreateCompletionSource 메서드 완료 소스를 인스턴스화할 수 있습니다.

    Public Function TryCreateCompletionSource(ByVal textBuffer As ITextBuffer) As ICompletionSource Implements ICompletionSourceProvider.TryCreateCompletionSource
        Return New TestCompletionSource(Me, textBuffer)
    End Function
    
    public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
    {
        return new TestCompletionSource(this, textBuffer);
    }
    

완료 명령 처리기 공급자 구현

완료 명령 처리기 공급자에서 파생 되는 IVsTextViewCreationListener, 텍스트 뷰 만들기 이벤트를 수신 하 고는 뷰의 변환는 IVsTextView (있습니다 Visual Studio 셸 명령 체인에 추가할 명령)에 ITextView. 이 클래스는 MEF 내보내기 이므로 명령 처리기가 필요 합니다 서비스를 가져올 수도 사용할 수 있습니다.

완료 명령 처리기 공급자를 구현 하려면

  1. TestCompletionCommandHandler 라는 파일을 추가 합니다.

  2. 다음 추가 문을 사용 합니다.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.ComponentModel.Composition
    Imports System.Runtime.InteropServices
    Imports Microsoft.VisualStudio
    Imports Microsoft.VisualStudio.Editor
    Imports Microsoft.VisualStudio.Language.Intellisense
    Imports Microsoft.VisualStudio.OLE.Interop
    Imports Microsoft.VisualStudio.Shell
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.TextManager.Interop
    Imports Microsoft.VisualStudio.Utilities
    
    using System;
    using System.ComponentModel.Composition;
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Editor;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.TextManager.Interop;
    using Microsoft.VisualStudio.Utilities;
    
  3. 라는 클래스를 추가 합니다. TestCompletionHandlerProvider 는 구현 IVsTextViewCreationListener. 이 클래스를 내보낼는 NameAttribute "토큰 완료 처리기"는 ContentTypeAttribute "일반 텍스트"와 a TextViewRoleAttributeEditable.

    <Export(GetType(IVsTextViewCreationListener))>
    <Name("token completion handler")>
    <ContentType("plaintext")> <TextViewRole(PredefinedTextViewRoles.Editable)>
    Friend Class TestCompletionHandlerProvider
        Implements IVsTextViewCreationListener
    
    [Export(typeof(IVsTextViewCreationListener))]
    [Name("token completion handler")]
    [ContentType("plaintext")]
    [TextViewRole(PredefinedTextViewRoles.Editable)]
    internal class TestCompletionHandlerProvider : IVsTextViewCreationListener
    
  4. 가져오기는 IVsEditorAdaptersFactoryService에서 변환 수를 IVsTextViewITextViewa ICompletionBroker, 하는 SVsServiceProvider, 표준 Visual Studio 서비스에 액세스할 수 있습니다.

    <Import()>
    Friend AdapterService As IVsEditorAdaptersFactoryService = Nothing
    <Import()>
    Friend Property CompletionBroker() As ICompletionBroker
    <Import()>
    Friend Property ServiceProvider() As SVsServiceProvider
    
    [Import]
    internal IVsEditorAdaptersFactoryService AdapterService = null;
    [Import]
    internal ICompletionBroker CompletionBroker { get; set; }
    [Import]
    internal SVsServiceProvider ServiceProvider { get; set; }
    
  5. 구현에서 VsTextViewCreated 메서드가 명령 처리기를 인스턴스화할 수 있습니다.

    Public Sub VsTextViewCreated(ByVal textViewAdapter As IVsTextView) Implements IVsTextViewCreationListener.VsTextViewCreated
        Dim textView As ITextView = AdapterService.GetWpfTextView(textViewAdapter)
        If textView Is Nothing Then 
            Return 
        End If 
    
        Dim createCommandHandler As Func(Of TestCompletionCommandHandler) = Function() New TestCompletionCommandHandler(textViewAdapter, textView, Me)
        textView.Properties.GetOrCreateSingletonProperty(createCommandHandler)
    End Sub
    
    public void VsTextViewCreated(IVsTextView textViewAdapter)
    {
        ITextView textView = AdapterService.GetWpfTextView(textViewAdapter);
        if (textView == null)
            return;
    
        Func<TestCompletionCommandHandler> createCommandHandler = delegate() { return new TestCompletionCommandHandler(textViewAdapter, textView, this); };
        textView.Properties.GetOrCreateSingletonProperty(createCommandHandler);
    }
    

완료 명령 처리기 구현

문 완성 키 입력으로 트리거되는 때문에 반드시 구현 해야는 IOleCommandTarget 인터페이스를 받고 시작, 커밋 및 완료 세션을 해제 하는 키 입력을 처리할 수 있습니다.

완료 명령 처리기를 구현 하려면

  1. 라는 클래스를 추가 합니다. TestCompletionCommandHandler 는 구현 IOleCommandTarget.

    Friend Class TestCompletionCommandHandler
        Implements IOleCommandTarget
    
    internal class TestCompletionCommandHandler : IOleCommandTarget
    
  2. 추가 전용 필드 (를 전달 하 여 명령) 다음 명령 처리기, 텍스트 뷰, (를 통해 다양 한 서비스에 액세스할 수 있습니다) 명령 처리기 공급자 및 세션이 완료.

    Private m_nextCommandHandler As IOleCommandTarget
    Private m_textView As ITextView
    Private m_provider As TestCompletionHandlerProvider
    Private m_session As ICompletionSession
    
    private IOleCommandTarget m_nextCommandHandler;
    private ITextView m_textView;
    private TestCompletionHandlerProvider m_provider;
    private ICompletionSession m_session;
    
  3. 텍스트 보기 및 공급자 필드를 설정 하 고 명령을 명령 체인을 추가 하는 생성자를 추가 합니다.

    Friend Sub New(ByVal textViewAdapter As IVsTextView, ByVal textView As ITextView, ByVal provider As TestCompletionHandlerProvider)
        Me.m_textView = textView
        Me.m_provider = provider
    
        'add the command to the command chain
        textViewAdapter.AddCommandFilter(Me, m_nextCommandHandler)
    End Sub
    
    internal TestCompletionCommandHandler(IVsTextView textViewAdapter, ITextView textView, TestCompletionHandlerProvider provider)
    {
        this.m_textView = textView;
        this.m_provider = provider;
    
        //add the command to the command chain
        textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler);
    }
    
  4. 구현에서 QueryStatus 는 따라 명령을 전달 하는 방법입니다.

    Public Function QueryStatus(ByRef pguidCmdGroup As Guid, ByVal cCmds As UInteger, ByVal prgCmds() As OLECMD, ByVal pCmdText As IntPtr) As Integer Implements IOleCommandTarget.QueryStatus
        Return m_nextCommandHandler.QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText)
    End Function
    
    public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        return m_nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }
    
  5. Exec 메서드를 구현합니다. 이 메서드는 키 입력을 받으면 이러한 작업 중 하나를 수행 해야 합니다.

    • 버퍼에 쓸 수 및 다음 시작 또는 완료 (문자 인쇄 하십시오)를 필터링 하는 문자를 허용 합니다.

    • 완료 되 면 커밋할 수 있지만 문자 (공백, 탭 및 완료 세션에 표시 될 때이 ENTER) 버퍼에 쓸 수 없도록 하십시오.

    • (모든 다른 명령) 다음 처리기에 전달 되는 명령을 수 있습니다.

    이 메서드는 UI 표시 될 수 있습니다 있으므로 자동화 컨텍스트에서 호출 하 여 호출 되지 않습니다는 있는지 확인 해야 IsInAutomationFunction.

    Public Function Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdID As UInteger, ByVal nCmdexecopt As UInteger, ByVal pvaIn As IntPtr, ByVal pvaOut As IntPtr) As Integer Implements IOleCommandTarget.Exec
        If VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider) Then 
            Return m_nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)
        End If 
        'make a copy of this so we can look at it after forwarding some commands 
        Dim commandID As UInteger = nCmdID
        Dim typedChar As Char = Char.MinValue
        'make sure the input is a char before getting it 
        If pguidCmdGroup = VSConstants.VSStd2K AndAlso nCmdID = CUInt(VSConstants.VSStd2KCmdID.TYPECHAR) Then
            typedChar = CChar(ChrW(CUShort(Marshal.GetObjectForNativeVariant(pvaIn))))
        End If 
    
        'check for a commit character 
        If nCmdID = CUInt(VSConstants.VSStd2KCmdID.RETURN) OrElse nCmdID = CUInt(VSConstants.VSStd2KCmdID.TAB) OrElse (Char.IsWhiteSpace(typedChar) OrElse Char.IsPunctuation(typedChar)) Then 
            'check for a a selection 
            If m_session IsNot Nothing AndAlso (Not m_session.IsDismissed) Then 
                'if the selection is fully selected, commit the current session 
                If m_session.SelectedCompletionSet.SelectionStatus.IsSelected Then
                    m_session.Commit()
                    'also, don't add the character to the buffer 
                    Return VSConstants.S_OK
                Else 
                    'if there is no selection, dismiss the session
                    m_session.Dismiss()
                End If 
            End If 
        End If 
    
        'pass along the command so the char is added to the buffer 
        Dim retVal As Integer = m_nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)
        Dim handled As Boolean = False 
        If (Not typedChar.Equals(Char.MinValue)) AndAlso Char.IsLetterOrDigit(typedChar) Then 
            If m_session Is Nothing OrElse m_session.IsDismissed Then ' If there is no active session, bring up completion
                Me.TriggerCompletion()
                m_session.Filter()
            Else 'the completion session is already active, so just filter
                m_session.Filter()
            End If
            handled = True 
        ElseIf commandID = CUInt(VSConstants.VSStd2KCmdID.BACKSPACE) OrElse commandID = CUInt(VSConstants.VSStd2KCmdID.DELETE) Then 'redo the filter if there is a deletion
            If m_session IsNot Nothing AndAlso (Not m_session.IsDismissed) Then
                m_session.Filter()
            End If
            handled = True 
        End If 
        If handled Then 
            Return VSConstants.S_OK
        End If 
        Return retVal
    End Function
    
    public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
        if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
        {
            return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
        }
        //make a copy of this so we can look at it after forwarding some commands 
        uint commandID = nCmdID;
        char typedChar = char.MinValue;
        //make sure the input is a char before getting it 
        if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
        {
            typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
        }
    
        //check for a commit character 
        if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN
            || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB
            || (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar)))
        {
            //check for a a selection 
            if (m_session != null && !m_session.IsDismissed)
            {
                //if the selection is fully selected, commit the current session 
                if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                {
                    m_session.Commit();
                    //also, don't add the character to the buffer 
                    return VSConstants.S_OK;
                }
                else
                {
                    //if there is no selection, dismiss the session
                    m_session.Dismiss();
                }
            }
        }
    
        //pass along the command so the char is added to the buffer 
        int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
        bool handled = false;
        if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar))
        {
            if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
            {
                this.TriggerCompletion();
                m_session.Filter();
            }
            else     //the completion session is already active, so just filter
            {
                m_session.Filter();
            }
            handled = true;
        }
        else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE   //redo the filter if there is a deletion
            || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE)
        {
            if (m_session != null && !m_session.IsDismissed)
                m_session.Filter();
            handled = true;
        }
        if (handled) return VSConstants.S_OK;
        return retVal;
    }
    
  6. 다음 코드 완성 세션을 트리거하는 개인 메서드입니다.

    Private Function TriggerCompletion() As Boolean 
        'the caret must be in a non-projection location  
        Dim caretPoint As SnapshotPoint? = m_textView.Caret.Position.Point.GetPoint(Function(textBuffer) ((Not textBuffer.ContentType.IsOfType("projection"))), PositionAffinity.Predecessor)
        If Not caretPoint.HasValue Then 
            Return False 
        End If
    
        m_session = m_provider.CompletionBroker.CreateCompletionSession(m_textView, caretPoint.Value.Snapshot.CreateTrackingPoint(caretPoint.Value.Position, PointTrackingMode.Positive), True)
    
        'subscribe to the Dismissed event on the session  
        AddHandler m_session.Dismissed, AddressOf OnSessionDismissed
        m_session.Start()
    
        Return True 
    End Function
    
    private bool TriggerCompletion()
    {
        //the caret must be in a non-projection location 
        SnapshotPoint? caretPoint =
        m_textView.Caret.Position.Point.GetPoint(
        textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor);
        if (!caretPoint.HasValue)
        {
            return false;
        }
    
        m_session = m_provider.CompletionBroker.CreateCompletionSession
     (m_textView,
            caretPoint.Value.Snapshot.CreateTrackingPoint(caretPoint.Value.Position, PointTrackingMode.Positive),
            true);
    
        //subscribe to the Dismissed event on the session 
        m_session.Dismissed += this.OnSessionDismissed;
        m_session.Start();
    
        return true;
    }
    
  7. 다음 코드에서 등록을 취소 하는 private 메서드입니다 있는 Dismissed 이벤트입니다.

    Private Sub OnSessionDismissed(ByVal sender As Object, ByVal e As EventArgs)
        RemoveHandler m_session.Dismissed, AddressOf OnSessionDismissed
        m_session = Nothing 
    End Sub
    
    private void OnSessionDismissed(object sender, EventArgs e)
    {
        m_session.Dismissed -= this.OnSessionDismissed;
        m_session = null;
    }
    

빌드 및 코드 테스트

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

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

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

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

  3. 텍스트 파일을 만들고 "추가" 라는 단어를 포함 하는 텍스트를 입력 합니다.

  4. 먼저 후 "d" 및 "a"를 입력 하면 "적용" 및 "추가"를 포함 하는 목록을 표시 합니다. 또한 선택 되어 있습니다. 다른 "d"를 입력 하면 "는 이제 선택입니다만 또한" 목록을 포함 해야 합니다. 스페이스바, 탭 또는 ENTER 키를 눌러 "추가"를 적용 하거나 esc 키 또는 다른 문자를 입력 하 여 목록 해제 수 있습니다.

참고 항목

작업

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