편집기에서 텍스트 작업
확장 코드는 다양한 진입점(사용자가 Visual Studio와 상호 작용할 때 발생하는 상황)에 대한 응답으로 실행되도록 구성할 수 있습니다. 편집기 확장성은 현재 수신기, EditorExtensibility 서비스 개체 및 명령의 세 가지 진입점을 지원합니다.
이벤트 수신기는 편집기 창에서 특정 작업이 발생할 때 트리거되며 TextView
코드로 표시됩니다. 예를 들어 사용자가 편집기에 항목을 입력하면 TextViewChanged
이벤트가 발생합니다. 편집기 창을 열거나 닫으면 TextViewOpened
및 TextViewClosed
이벤트가 발생합니다.
편집기 서비스 개체는 텍스트 편집 수행과 같은 실시간 편집기 기능을 노출하는 EditorExtensibility
클래스의 인스턴스입니다.
명령 메뉴, 상황에 맞는 메뉴 또는 도구 모음에 배치할 수 있는 항목을 클릭하여 사용자가 시작합니다.
텍스트 보기 수신기 추가
두 가지 유형의 수신기가 있습니다: ITextViewChangedListener와 ITextViewOpenClosedListener입니다. 이러한 수신기를 함께 사용하여 텍스트 편집기의 열기, 닫기 및 수정을 관찰할 수 있습니다.
그런 다음 새 클래스를 만들고 ExtensionPart 기본 클래스 및 ITextViewChangedListener
, ITextViewOpenClosedListener
또는 둘 다를 구현하고 VisualStudioContribution 특성을 추가합니다.
그런 다음, C# 파일을 편집할 때 리스너가 적용되도록 ITextViewChangedListener 및 ITextViewOpenClosedListener필요에 따라 TextViewExtensionConfiguration 속성을 구현합니다.
public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
{
AppliesTo = new[] { DocumentFilter.FromDocumentType("CSharp") },
};
다른 프로그래밍 언어 및 파일 형식에 사용할 수 있는 문서 형식은 이 문서 뒷부분에나열되며 필요한 경우 사용자 지정 파일 형식도 정의할 수 있습니다.
두 수신기를 모두 구현하기로 결정한 경우 완성된 클래스 선언은 다음과 같아야 합니다.
[VisualStudioContribution]
public sealed class TextViewOperationListener :
ExtensionPart, // This is the extension part base class containing infrastructure necessary to use VS services.
ITextViewOpenClosedListener, // Indicates this part listens for text view lifetime events.
ITextViewChangedListener // Indicates this part listens to text view changes.
{
public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
{
// Indicates this part should only light up in C# files.
AppliesTo = new[] { DocumentFilter.FromDocumentType("CSharp") },
};
...
ITextViewOpenClosedListener 및 ITextViewChangedListenerTextViewExtensionConfiguration 속성을 선언하므로 구성은 두 수신기에 모두 적용됩니다.
확장을 실행하면 다음이 표시됩니다.
- 사용자가 텍스트 보기를 열 때마다 ITextViewOpenClosedListener.TextViewOpenedAsync 호출됩니다.
- 사용자가 텍스트 보기를 닫을 때마다 ITextViewOpenClosedListener.TextViewClosedAsync 호출됩니다.
- ITextViewChangedListener.TextViewChangedAsync 사용자가 텍스트 보기로 표시되는 텍스트 문서를 텍스트로 변경할 때마다 호출됩니다.
이러한 각 메서드는 사용자가 작업을 호출할 때 텍스트 보기 및 텍스트 문서의 상태를 포함하는 ITextViewSnapshot 전달되고 IDE가 보류 중인 작업을 취소하려고 할 때 IsCancellationRequested == true
CancellationToken이 전달됩니다.
확장이 관련 있는 시기 정의
확장은 일반적으로 지원되는 특정 문서 유형 및 시나리오와만 관련이 있으므로 해당 적용 가능성을 명확하게 정의하는 것이 중요합니다. 여러 가지 방법으로 AppliesTo 구성)을 사용하여 확장의 적용 가능성을 명확하게 정의할 수 있습니다. 확장 프로그램에서 지원하는 코드 언어와 같은 파일 형식을 지정하거나 파일 이름 또는 경로에 따라 패턴에 일치하여 확장 프로그램의 적용 가능성을 더욱 구체화할 수 있습니다.
AppliesTo 구성을 사용하여 프로그래밍 언어 지정
AppliesTo 구성은 확장이 활성화되어야 하는 프로그래밍 언어 시나리오를 나타냅니다. 기록 형식은 AppliesTo = new[] { DocumentFilter.FromDocumentType("CSharp") }
으로, Visual Studio에 내장된 언어의 알려진 이름이거나 Visual Studio 확장에서 사용자 정의한 것입니다.
잘 알려진 문서 유형은 다음 표에 나와 있습니다.
문서 유형 | 묘사 |
---|---|
"CSharp" | C# |
"C/C++" | C, C++, 헤더 및 IDL |
"TypeScript" | TypeScript 및 JavaScript 형식 언어입니다. |
"HTML" | HTML |
"JSON" | JSON |
"텍스트" | "text"에서 내림차순인 "code"의 계층적 하위 항목을 포함하는 텍스트 파일입니다. |
코드 | C, C++, C#등입니다. |
DocumentType은 계층적입니다. 즉, C# 및 C++는 모두 "코드"에서 내림차순이므로 "코드"를 선언하면 모든 코드 언어, C#, C, C++등에 대해 확장이 활성화됩니다.
새 문서 형식 정의
예를 들어 확장 프로젝트의 모든 클래스에 정적 DocumentTypeConfiguration 속성을 추가하고 속성을 VisualStudioContribution
특성으로 표시하여 사용자 지정 코드 언어를 지원하기 위해 새 문서 형식을 정의할 수 있습니다.
DocumentTypeConfiguration
새 문서 형식을 정의하고, 하나 이상의 다른 문서 형식을 상속하도록 지정하고, 파일 형식을 식별하는 데 사용되는 파일 확장자를 하나 이상 지정할 수 있습니다.
using Microsoft.VisualStudio.Extensibility.Editor;
internal static class MyDocumentTypes
{
[VisualStudioContribution]
internal static DocumentTypeConfiguration MarkdownDocumentType => new("markdown")
{
FileExtensions = new[] { ".md", ".mdk", ".markdown" },
BaseDocumentType = DocumentType.KnownValues.Text,
};
}
문서 형식 정의는 레거시 Visual Studio 확장성에서 제공하는 콘텐츠 형식 정의와 병합되므로 추가 파일 확장자를 기존 문서 형식에 매핑할 수 있습니다.
문서 선택기
DocumentFilter.FromDocumentType 외에도 documentFilter.FromGlobPattern 문서의 파일 경로가 glob(와일드카드) 패턴과 일치하는 경우에만 활성화하여 확장의 적용 가능성을 추가로 제한할 수 있습니다.
[VisualStudioContribution]
public sealed class TextViewOperationListener
: ExtensionPart, ITextViewOpenClosedListener, ITextViewChangedListener
{
public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
{
AppliesTo = new[]
{
DocumentFilter.FromDocumentType("CSharp"),
DocumentFilter.FromGlobPattern("**/tests/*.cs"),
},
};
[VisualStudioContribution]
public sealed class TextViewOperationListener
: ExtensionPart, ITextViewOpenClosedListener, ITextViewChangedListener
{
public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
{
AppliesTo = new[]
{
DocumentFilter.FromDocumentType(MyDocumentTypes.MarkdownDocumentType),
DocumentFilter.FromGlobPattern("docs/*.md", relativePath: true),
},
};
pattern
매개 변수는 문서의 절대 경로와 일치하는 glob 패턴을 나타냅니다.
Glob 패턴에는 다음 구문이 있을 수 있습니다.
-
*
는 경로 세그먼트에서 0개 이상의 문자와 일치하도록 합니다. - 경로 세그먼트 내에서 한 문자를 일치시키는 데 사용되는
?
- 경로 세그먼트가 없거나 여러 개일 수 있는 경우를 포함하여
**
과(와) 일치하도록 - 그룹 조건에
{}
(예: 모든 TypeScript 및 JavaScript 파일과 일치하는**/*.{ts,js}
) - 경로 세그먼트에서 일치시킬 문자 범위를 선언하기 위한
[]
(예:example.0
,example.1
, ...에서 일치하도록example.[0-9]
). - 경로 세그먼트에서 일치시킬 문자 범위를 부정하는
[!...]
(예:example.a
,example.b
example.[!0-9]
일치하지만example.0
아님)
백슬래시(\
)는 glob 패턴 내에서 유효하지 않습니다. glob 패턴을 만들 때 백슬래시를 슬래시로 변환해야 합니다.
편집기의 기능에 접근하기
편집기 확장 클래스가 ExtensionPart를 상속합니다.
ExtensionPart
클래스는 확장성 속성을 노출합니다. 이 속성을 사용하여 EditorExtensibility 개체의 인스턴스를 요청할 수 있습니다. 이 개체를 사용하여 편집 수행과 같은 실시간 편집기 기능에 액세스할 수 있습니다.
EditorExtensibility editorService = this.Extensibility.Editor();
명령 내의 편집기 상태 액세스
각 Command
에서 ExecuteCommandAsync()
는 명령이 호출될 때 IDE 상태의 스냅샷을 포함하는 IClientContext
를 전달받습니다. 비동기 메서드 GetActiveTextViewAsync
를 호출하여 EditorExtensibility
개체에서 가져온 ITextViewSnapshot
인터페이스를 통해 활성 문서에 액세스할 수 있습니다.
using ITextViewSnapshot textView = await this.Extensibility.Editor().GetActiveTextViewAsync(clientContext, cancellationToken);
ITextViewSnapshot
있으면 편집기 상태에 액세스할 수 있습니다.
ITextViewSnapshot
특정 시점에 편집기 상태를 변경할 수 없는 보기이므로 편집을 위해 Editor 개체 모델 다른 인터페이스를 사용해야 합니다.