사용자 지정 편집기 API
사용자 지정 편집기를 사용하면 확장에서 특정 유형의 리소스에 대한 VS Code의 표준 텍스트 편집기를 대체하는 완전히 사용자 지정 가능한 읽기/쓰기 편집기를 만들 수 있습니다. 다음과 같은 다양한 사용 사례가 있습니다.
- 셰이더 또는 3D 모델과 같은 에셋을 VS Code에서 직접 미리 봅니다.
- Markdown 또는 XAML과 같은 언어에 대한 WYSIWYG 편집기를 만듭니다.
- CSV, JSON 또는 XML과 같은 데이터 파일에 대한 대체 시각적 렌더링을 제공합니다.
- 바이너리 또는 텍스트 파일에 대한 완전히 사용자 지정 가능한 편집 환경을 구축합니다.
이 문서에서는 사용자 지정 편집기 API와 사용자 지정 편집기를 구현하는 기본 사항을 살펴봅니다. 두 가지 유형의 사용자 지정 편집기와 그 차이점, 그리고 어떤 것이 사용 사례에 적합한지 살펴보겠습니다. 그런 다음 이러한 각 사용자 지정 편집기 유형에 대해 잘 작동하는 사용자 지정 편집기를 구축하는 기본 사항을 다룹니다.
사용자 지정 편집기는 강력한 새로운 확장 지점이지만 기본적인 사용자 지정 편집기를 구현하는 것은 실제로 어렵지 않습니다! 그럼에도 불구하고 첫 VS Code 확장을 작업 중이라면 VS Code API의 기본 사항에 더 익숙해질 때까지 사용자 지정 편집기로 바로 들어가는 것을 보류하는 것을 고려해 보십시오. 사용자 지정 편집기는 웹뷰 및 텍스트 문서와 같은 많은 VS Code 개념을 기반으로 하므로 이러한 모든 새로운 아이디어를 동시에 배우면 다소 부담스러울 수 있습니다.
하지만 준비가 되었다고 느끼고 만들 멋진 사용자 지정 편집기에 대해 생각하고 있다면 시작해 봅시다! 사용자 지정 편집기 확장 샘플을 다운로드하여 문서를 따라가면서 사용자 지정 편집기 API가 어떻게 통합되는지 확인할 수 있습니다.
링크
VS Code API 사용
사용자 지정 편집기 API 기본 사항
사용자 지정 편집기는 특정 리소스에 대해 VS Code의 표준 텍스트 편집기를 대체하여 표시되는 대체 보기입니다. 사용자 지정 편집기에는 두 가지 부분이 있습니다. 사용자가 상호 작용하는 보기와 확장이 기본 리소스와 상호 작용하는 데 사용하는 문서 모델입니다.
사용자 지정 편집기의 보기 측은 웹뷰를 사용하여 구현됩니다. 이를 통해 표준 HTML, CSS 및 JavaScript를 사용하여 사용자 지정 편집기의 사용자 인터페이스를 구축할 수 있습니다. 웹뷰는 VS Code API에 직접 액세스할 수 없지만 메시지를 주고받아 확장과 통신할 수 있습니다. 웹뷰 및 작업 모범 사례에 대한 자세한 내용은 웹뷰 설명서를 참조하세요.
사용자 지정 편집기의 다른 부분은 문서 모델입니다. 이 모델은 확장이 작업 중인 리소스(파일)를 이해하는 방법입니다. CustomTextEditorProvider는 VS Code의 표준 TextDocument를 문서 모델로 사용하며 파일에 대한 모든 변경은 VS Code의 표준 텍스트 편집 API를 사용하여 표현됩니다. 반면에 CustomReadonlyEditorProvider 및 CustomEditorProvider는 사용자 지정 문서 모델을 제공하므로 텍스트가 아닌 파일 형식에 사용할 수 있습니다.
사용자 지정 편집기에는 리소스당 하나의 문서 모델이 있지만 이 문서에 대한 여러 편집기 인스턴스(보기)가 있을 수 있습니다. 예를 들어 CustomTextEditorProvider가 있는 파일을 열고 **보기: 편집기 분할** 명령을 실행한다고 가정합니다. 이 경우 워크스페이스에 리소스의 단일 복사본이 여전히 하나이므로 여전히 단일 TextDocument가 있지만 이제 해당 리소스에 대한 두 개의 웹뷰가 있습니다.
CustomEditor 대 CustomTextEditor
사용자 지정 편집기에는 사용자 지정 텍스트 편집기와 사용자 지정 편집기의 두 가지 클래스가 있습니다. 이들 간의 주요 차이점은 문서 모델을 정의하는 방식입니다.
CustomTextEditorProvider는 VS Code의 표준 TextDocument를 데이터 모델로 사용합니다. CustomTextEditor는 텍스트 기반 파일 형식에 사용할 수 있습니다. VS Code는 이미 텍스트 파일을 다루는 방법을 알고 있으므로 저장 및 파일 백업과 같은 작업을 핫 재시드를 위해 구현할 수 있으므로 CustomTextEditor는 구현하기가 훨씬 쉽습니다.
반면에 CustomEditorProvider를 사용하면 확장에서 자체 문서 모델을 가져옵니다. 이는 CustomEditor를 이미지와 같은 바이너리 형식에 사용할 수 있음을 의미하지만 확장 프로그램이 저장 및 백업 구현을 포함하여 더 많은 작업을 담당해야 함을 의미합니다. 사용자 지정 편집기가 미리 보기와 같은 읽기 전용인 경우 이러한 복잡성의 상당 부분을 건너뛸 수 있습니다.
사용할 사용자 지정 편집기 유형을 결정할 때 결정은 일반적으로 간단합니다. 텍스트 기반 파일 형식을 다루는 경우 CustomTextEditorProvider를 사용하고, 바이너리 파일 형식의 경우 CustomEditorProvider를 사용합니다.
기여 지점
customEditors 기여 지점은 확장이 VS Code에 제공하는 사용자 지정 편집기에 대해 알리는 방법입니다. 예를 들어 VS Code는 사용자 지정 편집기가 어떤 유형의 파일과 함께 작동하는지, 그리고 UI에서 사용자 지정 편집기를 식별하는 방법을 알아야 합니다.
사용자 지정 편집기 확장 샘플에 대한 기본적인 customEditor 기여는 다음과 같습니다.
"contributes": {
"customEditors": [
{
"viewType": "catEdit.catScratch",
"displayName": "Cat Scratch",
"selector": [
{
"filenamePattern": "*.cscratch"
}
],
"priority": "default"
}
]
}
customEditors는 배열이므로 확장에서 여러 사용자 지정 편집기를 기여할 수 있습니다. 사용자 지정 편집기 항목 자체를 자세히 살펴보겠습니다.
-
viewType- 사용자 지정 편집기의 고유 식별자입니다.이것은 VS Code가
package.json의 사용자 지정 편집기 기여와 코드의 사용자 지정 편집기 구현을 연결하는 방법입니다. 이는 모든 확장 프로그램에서 고유해야 하므로"preview"와 같은 일반적인viewType대신 확장 프로그램에 고유한 것을 사용해야 합니다. 예를 들어"viewType": "myAmazingExtension.svgPreview"입니다. -
displayName- VS Code UI에서 사용자 지정 편집기를 식별하는 이름입니다.표시 이름은 **보기: 다시 열기** 드롭다운과 같은 VS Code UI에서 사용자에게 표시됩니다.
-
selector- 사용자 지정 편집기가 활성화되는 파일을 지정합니다.selector는 하나 이상의 glob 패턴 배열입니다. 이러한 glob 패턴은 파일 이름과 일치하여 사용자 지정 편집기를 사용할 수 있는지 여부를 결정합니다.*.png와 같은filenamePattern은 모든 PNG 파일에 대해 사용자 지정 편집기를 활성화합니다.예를 들어
**/translations/*.json과 같이 파일 또는 디렉토리 이름과 일치하는 더 구체적인 패턴을 만들 수도 있습니다. -
priority- (선택 사항) 사용자 지정 편집기가 사용되는 시점을 지정합니다.priority는 리소스가 열려 있을 때 사용자 지정 편집기가 사용되는 시점을 제어합니다. 가능한 값은 다음과 같습니다."default"- 사용자 지정 편집기의selector와 일치하는 모든 파일에 대해 사용자 지정 편집기를 사용하려고 시도합니다. 특정 파일에 대해 여러 사용자 지정 편집기가 있는 경우 사용자가 원하는 사용자 지정 편집기를 선택해야 합니다."option"- 사용자 지정 편집기를 기본적으로 사용하지 않지만 사용자가 전환하거나 기본값으로 구성할 수 있습니다.
사용자 지정 편집기 활성화
사용자가 사용자 지정 편집기 중 하나를 열면 VS Code는 onCustomEditor:VIEW_TYPE 활성화 이벤트를 발생시킵니다. 활성화 중에 확장 프로그램은 예상 viewType에 대해 사용자 지정 편집기를 등록하기 위해 registerCustomEditorProvider를 호출해야 합니다.
onCustomEditor는 VS Code가 사용자 지정 편집기 인스턴스를 생성해야 할 때만 호출된다는 점에 유의하는 것이 중요합니다. VS Code가 사용자와 사용 가능한 사용자 지정 편집기에 대한 정보를 표시하는 경우(예: **보기: 다시 열기** 명령) 확장 프로그램은 활성화되지 않습니다.
사용자 지정 텍스트 편집기
사용자 지정 텍스트 편집기를 사용하면 텍스트 파일에 대한 사용자 지정 편집기를 만들 수 있습니다. 이는 일반적인 구조화되지 않은 텍스트부터 CSV, JSON 또는 XML에 이르기까지 무엇이든 될 수 있습니다. 사용자 지정 텍스트 편집기는 VS Code의 표준 TextDocument를 문서 모델로 사용합니다.
사용자 지정 편집기 확장 샘플에는 고양이 스크래치 파일(.cscratch 파일 확장자로 끝나는 JSON 파일)에 대한 간단한 예제 사용자 지정 텍스트 편집기가 포함되어 있습니다. 사용자 지정 텍스트 편집기를 구현하는 중요한 부분들을 살펴보겠습니다.
사용자 지정 텍스트 편집기 수명 주기
VS Code는 사용자 지정 텍스트 편집기의 보기 구성 요소(웹뷰)와 모델 구성 요소(TextDocument)의 수명을 모두 처리합니다. VS Code는 새 사용자 지정 편집기 인스턴스를 생성해야 할 때 확장 프로그램에 알리고 사용자가 탭을 닫을 때 편집기 인스턴스와 문서 모델을 정리합니다.
이 모든 것이 실제로 어떻게 작동하는지 이해하기 위해 사용자가 사용자 지정 텍스트 편집기를 열 때 그리고 사용자가 사용자 지정 텍스트 편집기를 닫을 때 확장 프로그램의 관점에서 발생하는 일을 살펴보겠습니다.
사용자 지정 텍스트 편집기 열기
사용자 지정 편집기 확장 샘플을 사용하여 사용자가 .cscratch 파일을 처음 열 때 발생하는 일은 다음과 같습니다.
-
VS Code는
onCustomEditor:catCustoms.catScratch활성화 이벤트를 발생시킵니다.아직 활성화되지 않았다면 확장 프로그램을 활성화합니다. 활성화 중에 확장 프로그램은
registerCustomEditorProvider를 호출하여catCustoms.catScratch에 대한CustomTextEditorProvider를 등록해야 합니다. -
VS Code는 등록된
CustomTextEditorProvider에서catCustoms.catScratch에 대한resolveCustomTextEditor를 호출합니다.이 메서드는 열리고 있는 리소스의
TextDocument와WebviewPanel을 받습니다. 확장 프로그램은 이 웹뷰 패널에 대한 초기 HTML 내용을 채워야 합니다.
resolveCustomTextEditor가 반환되면 사용자에게 사용자 지정 편집기가 표시됩니다. 웹뷰 내부에 그려지는 것은 전적으로 확장 프로그램에 달려 있습니다.
이 동일한 흐름은 사용자 지정 편집기가 열릴 때마다 발생하며, 사용자 지정 편집기를 분할하는 경우에도 마찬가지입니다. 사용자 지정 편집기의 각 인스턴스는 자체 WebviewPanel을 가지지만, 여러 사용자 지정 텍스트 편집기는 동일한 리소스에 대한 경우 동일한 TextDocument를 공유합니다. 기억하십시오. TextDocument는 리소스의 모델이고 웹뷰 패널은 해당 모델의 보기라고 생각하십시오.
사용자 지정 텍스트 편집기 닫기
사용자가 사용자 지정 텍스트 편집기를 닫으면 VS Code는 WebviewPanel에서 WebviewPanel.onDidDispose 이벤트를 발생시킵니다. 이때 확장 프로그램은 해당 편집기와 관련된 모든 리소스(이벤트 구독, 파일 감시자 등)를 정리해야 합니다.
특정 리소스에 대한 마지막 사용자 지정 편집기가 닫히면 다른 편집기에서 사용하지 않거나 다른 확장 프로그램에서 사용하지 않는 경우 해당 리소스에 대한 TextDocument도 삭제됩니다. TextDocument.isClosed 속성을 확인하여 TextDocument가 닫혔는지 확인할 수 있습니다. TextDocument가 닫히면 사용자 지정 편집기를 사용하여 동일한 리소스를 열면 새 TextDocument가 열립니다.
TextDocument와 변경 사항 동기화
사용자 지정 텍스트 편집기는 TextDocument를 문서 모델로 사용하므로 사용자 지정 편집기에서 편집이 발생할 때마다 TextDocument를 업데이트하고 TextDocument가 변경될 때마다 자체를 업데이트할 책임이 있습니다.
웹뷰에서 TextDocument로
사용자 지정 텍스트 편집기의 편집은 버튼 클릭, 텍스트 변경, 항목 끌어서 놓기 등 다양한 형태를 띨 수 있습니다. 사용자가 사용자 지정 편집기 내에서 파일을 편집할 때마다 확장 프로그램은 TextDocument를 업데이트해야 합니다. 고양이 스크래치 확장 프로그램이 이 작업을 구현하는 방법은 다음과 같습니다.
-
사용자가 웹뷰에서 **스크래치 추가** 버튼을 클릭합니다. 이 메시지를 게시하여 웹뷰에서 확장 프로그램으로 다시 보냅니다.
-
확장 프로그램이 메시지를 받습니다. 그런 다음 문서의 내부 모델을 업데이트합니다(고양이 스크래치 예제에서는 JSON에 새 항목을 추가하는 것입니다).
-
확장 프로그램은 업데이트된 JSON을 문서에 쓰는
WorkspaceEdit을 생성합니다. 이 편집은vscode.workspace.applyEdit을 사용하여 적용됩니다.
작업 편집을 문서 업데이트에 필요한 최소한의 변경으로 유지하려고 노력하십시오. 또한 JSON이나 XML과 같은 언어를 다루는 경우 확장 프로그램이 사용자의 기존 서식 규칙(공백 대 탭, 들여쓰기 크기 등)을 준수하려고 노력해야 한다는 점도 염두에 두십시오.
TextDocument에서 웹뷰로
TextDocument가 변경되면 확장 프로그램은 웹뷰가 문서의 새 상태를 반영하도록 해야 합니다. TextDocument는 실행 취소, 다시 실행 또는 파일 되돌리기와 같은 사용자 작업, WorkspaceEdit을 사용하는 다른 확장 프로그램, 또는 VS Code의 기본 텍스트 편집기에서 파일을 여는 사용자에 의해 변경될 수 있습니다. 고양이 스크래치 확장 프로그램이 이 작업을 구현하는 방법은 다음과 같습니다.
-
확장 프로그램에서
vscode.workspace.onDidChangeTextDocument이벤트에 구독합니다. 이 이벤트는TextDocument의 모든 변경 사항(사용자 지정 편집기가 수행하는 변경 사항 포함!)에 대해 발생합니다. -
편집기가 있는 문서에 대한 변경이 오면 웹뷰에 새 문서 상태를 알리는 메시지를 보냅니다. 그런 다음 이 웹뷰는 업데이트된 문서를 렌더링하도록 자체를 업데이트합니다.
사용자 지정 편집기가 트리거하는 모든 파일 편집은 onDidChangeTextDocument를 발생시킨다는 점을 기억하는 것이 중요합니다. 사용자 편집이 웹뷰에서 발생하여 onDidChangeTextDocument를 발생시키고, 웹뷰가 업데이트를 유발하고, 웹뷰가 확장 프로그램에 대한 다른 업데이트를 트리거하여 onDidChangeTextDocument를 발생시키는 등의 업데이트 루프에 확장 프로그램이 빠지지 않도록 하십시오.
또한 JSON 또는 XML과 같은 구조화된 언어를 다루는 경우 문서가 항상 유효한 상태는 아닐 수 있다는 점을 기억하십시오. 확장 프로그램은 오류를 정상적으로 처리하거나 사용자에게 오류 메시지를 표시하여 무엇이 잘못되었고 어떻게 수정해야 하는지 이해할 수 있도록 해야 합니다.
마지막으로 웹뷰를 업데이트하는 것이 비용이 많이 드는 경우 웹뷰 업데이트를 디바운싱하는 것을 고려하십시오.
사용자 지정 편집기
CustomEditorProvider 및 CustomReadonlyEditorProvider를 사용하면 바이너리 파일 형식에 대한 사용자 지정 편집기를 만들 수 있습니다. 이 API를 사용하면 파일이 사용자에게 표시되는 방식, 파일 편집 방법 등에 대한 완전한 제어를 할 수 있으며 확장 프로그램이 save 및 기타 파일 작업에 후킹할 수 있습니다. 다시 말하지만, 텍스트 기반 파일 형식에 대한 편집기를 구축하는 경우 CustomTextEditor를 사용하는 것을 강력히 고려하십시오. 훨씬 구현하기가 간단합니다.
사용자 지정 편집기 확장 샘플에는 고양이 그리기 파일(.pawdraw 파일 확장자로 끝나는 JPEG 파일)에 대한 간단한 예제 사용자 지정 바이너리 편집기가 포함되어 있습니다. 바이너리 파일에 대한 사용자 지정 편집기를 구축하는 데 필요한 사항을 살펴보겠습니다.
CustomDocument
사용자 지정 편집기를 사용하면 확장 프로그램에서 자체 문서 모델을 CustomDocument 인터페이스로 구현해야 합니다. 이를 통해 확장 프로그램은 사용자 지정 편집기와 상호 작용하기 위해 필요한 모든 데이터를 CustomDocument에 저장할 수 있지만, 저장 및 핫 재시드를 위한 파일 데이터 백업과 같은 기본 문서 작업을 구현해야 한다는 의미이기도 합니다.
열린 파일당 하나의 CustomDocument가 있습니다. 사용자는 단일 리소스에 대해 여러 편집기를 열 수 있습니다(예: 현재 사용자 지정 편집기를 분할하여). 그러나 이러한 모든 편집기는 동일한 CustomDocument로 백업됩니다.
사용자 지정 편집기 수명 주기
supportsMultipleEditorsPerDocument
기본적으로 VS Code는 각 사용자 지정 문서에 대해 하나의 편집기만 허용합니다. 이 제한은 여러 사용자 지정 편집기 인스턴스 간의 동기화에 대해 걱정할 필요가 없기 때문에 사용자 지정 편집기를 올바르게 구현하는 데 도움이 됩니다.
그러나 확장 프로그램에서 지원할 수 있는 경우 여러 편집기 인스턴스를 동일한 문서에 대해 열 수 있도록 사용자 지정 편집기를 등록할 때 supportsMultipleEditorsPerDocument: true를 설정하는 것이 좋습니다. 이렇게 하면 사용자 지정 편집기가 VS Code의 일반 텍스트 편집기처럼 작동합니다.
사용자 지정 편집기 열기 사용자가 customEditor 기여 지점과 일치하는 파일을 열면 VS Code는 onCustomEditor 활성화 이벤트를 발생시키고 제공된 보기 유형에 대해 등록된 공급자를 호출합니다. CustomEditorProvider에는 두 가지 역할이 있습니다. 사용자 지정 편집기에 대한 문서를 제공하고 편집기 자체를 제공합니다. 사용자 지정 편집기 확장 샘플의 catCustoms.pawDraw 편집기에 대해 발생하는 일은 다음과 같습니다.
-
VS Code는
onCustomEditor:catCustoms.pawDraw활성화 이벤트를 발생시킵니다.아직 활성화되지 않았다면 확장 프로그램을 활성화합니다. 또한 활성화 중에
catCustoms.pawDraw에 대해CustomReadonlyEditorProvider또는CustomEditorProvider를 등록하도록 확장 프로그램에서 확인해야 합니다. -
VS Code는
catCustoms.pawDraw편집기에 대해 등록된CustomReadonlyEditorProvider또는CustomEditorProvider에서openCustomDocument를 호출합니다.여기서 확장 프로그램에 리소스 URI가 제공되며 해당 리소스에 대한 새
CustomDocument를 반환해야 합니다. 이때 확장 프로그램은 해당 리소스에 대한 내부 문서 모델을 만들어야 합니다. 여기에는 디스크에서 초기 리소스 상태를 읽고 구문 분석하거나 새CustomDocument를 초기화하는 작업이 포함될 수 있습니다.확장 프로그램은
CustomDocument를 구현하는 새 클래스를 만들어 이 모델을 정의할 수 있습니다. 확장 프로그램이CustomDocument에 저장하는 추가 정보는 VS Code에서 신경 쓰지 않는다는 점을 기억하십시오. -
VS Code는 2단계의
CustomDocument와 새WebviewPanel로resolveCustomEditor를 호출합니다.여기서 확장 프로그램은 사용자 지정 편집기에 대한 초기 HTML을 채워야 합니다. 필요한 경우 나중에 참조할 수 있도록
WebviewPanel에 대한 참조를 유지할 수 있습니다. 예를 들어 명령 내에서 사용됩니다.
resolveCustomEditor가 반환되면 사용자에게 사용자 지정 편집기가 표시됩니다.
사용자가 다른 편집기 그룹에서 사용자 지정 편집기를 사용하여 동일한 리소스를 열면(예: 첫 번째 편집기를 분할하여) 확장 프로그램의 작업이 단순화됩니다. 이 경우 VS Code는 첫 번째 편집기가 열릴 때 만든 것과 동일한 CustomDocument로 resolveCustomEditor를 호출합니다.
사용자 지정 편집기 닫기
동일한 리소스에 대해 사용자 지정 편집기 두 개를 열었다고 가정해 보겠습니다. 사용자가 이러한 편집기를 닫으면 VS Code가 확장 프로그램에 신호를 보내 편집기와 관련된 리소스를 정리할 수 있도록 합니다.
첫 번째 편집기 인스턴스가 닫히면 VS Code는 닫힌 편집기의 WebviewPanel에서 WebviewPanel.onDidDispose 이벤트를 발생시킵니다. 이때 확장 프로그램은 해당 특정 편집기 인스턴스와 관련된 모든 리소스를 정리해야 합니다.
두 번째 편집기가 닫히면 VS Code는 다시 WebviewPanel.onDidDispose를 발생시킵니다. 하지만 이제 CustomDocument와 관련된 모든 편집기도 닫았습니다. CustomDocument에 대한 편집기가 더 이상 없으면 VS Code는 CustomDocument.dispose를 호출합니다. 확장 프로그램의 dispose 구현은 문서와 관련된 모든 리소스를 정리해야 합니다.
그런 다음 사용자가 사용자 지정 편집기를 사용하여 동일한 리소스를 다시 열면 새 CustomDocument로 전체 openCustomDocument, resolveCustomEditor 흐름으로 돌아갑니다.
읽기 전용 사용자 지정 편집기
다음 섹션 중 많은 부분이 편집을 지원하는 사용자 지정 편집기에만 적용되며, 역설적으로 들릴 수 있지만 많은 사용자 지정 편집기에는 편집 기능이 필요하지 않습니다. 예를 들어 이미지 미리 보기를 생각해 보세요. 또는 메모리 덤프의 시각적 렌더링. 둘 다 사용자 지정 편집기를 사용하여 구현할 수 있지만 편집할 필요는 없습니다. 이때 CustomReadonlyEditorProvider가 사용됩니다.
CustomReadonlyEditorProvider를 사용하면 편집을 지원하지 않는 사용자 지정 편집기를 만들 수 있습니다. 여전히 대화형일 수 있지만 실행 취소 및 저장과 같은 작업은 지원하지 않습니다. 또한 편집 가능한 사용자 지정 편집기보다 읽기 전용 사용자 지정 편집기를 구현하는 것이 훨씬 간단합니다.
편집 가능한 사용자 지정 편집기 기본 사항
편집 가능한 사용자 지정 편집기를 사용하면 실행 취소 및 다시 실행, 저장, 핫 재시드와 같은 표준 VS Code 작업에 후킹할 수 있습니다. 이를 통해 편집 가능한 사용자 지정 편집기는 매우 강력해지지만, 제대로 구현하는 것은 편집 가능한 사용자 지정 텍스트 편집기 또는 읽기 전용 사용자 지정 편집기를 구현하는 것보다 훨씬 복잡합니다.
편집 가능한 사용자 지정 편집기는 CustomEditorProvider를 사용하여 구현됩니다. 이 인터페이스는 CustomReadonlyEditorProvider를 확장하므로 openCustomDocument 및 resolveCustomEditor와 같은 기본 작업을 구현해야 하며, 편집 관련 작업 세트도 포함해야 합니다. CustomEditorProvider의 편집 관련 부분을 살펴보겠습니다.
편집
편집 가능한 사용자 지정 문서의 변경 사항은 편집을 통해 표현됩니다. 편집은 텍스트 변경, 이미지 회전, 목록 재정렬 등 무엇이든 될 수 있습니다. VS Code는 편집이 무엇을 하는지에 대한 세부 정보를 확장 프로그램에 전적으로 맡기지만, VS Code는 편집이 발생했을 때를 알아야 합니다. 편집은 VS Code가 문서를 더럽게 표시하는 방식이며, 이는 자동 저장 및 백업을 가능하게 합니다.
사용자가 사용자 지정 편집기의 웹뷰에서 편집을 할 때마다 확장 프로그램은 CustomEditorProvider에서 onDidChangeCustomDocument 이벤트를 발생시켜야 합니다. onDidChangeCustomDocument 이벤트는 사용자 지정 편집기 구현에 따라 두 가지 이벤트 유형을 발생시킬 수 있습니다. CustomDocumentContentChangeEvent 및 CustomDocumentEditEvent.
CustomDocumentContentChangeEvent
CustomDocumentContentChangeEvent는 기본 편집입니다. 유일한 기능은 VS Code에 문서가 편집되었음을 알리는 것입니다.
확장 프로그램이 onDidChangeCustomDocument에서 CustomDocumentContentChangeEvent를 발생시키면 VS Code는 연결된 문서를 더럽게 표시합니다. 이때 문서가 더럽지 않게 되는 유일한 방법은 사용자가 저장하거나 되돌리는 것입니다. CustomDocumentContentChangeEvent를 사용하는 사용자 지정 편집기는 실행 취소/다시 실행을 지원하지 않습니다.
CustomDocumentEditEvent
CustomDocumentEditEvent는 실행 취소/다시 실행을 지원하는 더 복잡한 편집입니다. 실행 취소/다시 실행을 구현할 수 없는 경우에만 CustomDocumentContentChangeEvent를 사용하는 것으로 대체하고 항상 CustomDocumentEditEvent를 사용하여 사용자 지정 편집기를 구현하려고 노력해야 합니다.
CustomDocumentEditEvent는 다음과 같은 필드를 가집니다.
document- 편집이 해당되는CustomDocument입니다.label- 편집 유형을 설명하는 선택적 텍스트입니다(예: "자르기", "삽입" 등).undo- 편집을 실행 취소해야 할 때 VS Code에서 호출하는 함수입니다.redo- 편집을 다시 적용해야 할 때 VS Code에서 호출하는 함수입니다.
확장 프로그램이 onDidChangeCustomDocument에서 CustomDocumentEditEvent를 발생시키면 VS Code는 연결된 문서를 더럽게 표시합니다. 문서를 더럽지 않게 만들려면 사용자가 문서를 저장하거나 되돌리거나, 편집/다시 실행하여 마지막으로 저장된 상태로 되돌릴 수 있습니다.
편집기의 undo 및 redo 메서드는 해당 특정 편집을 실행 취소하거나 다시 적용해야 할 때 VS Code에서 호출됩니다. VS Code는 편집의 내부 스택을 유지하므로 확장 프로그램이 세 개의 편집(a, b, c라고 가정)으로 onDidChangeCustomDocument를 발생시키면
onDidChangeCustomDocument(a);
onDidChangeCustomDocument(b);
onDidChangeCustomDocument(c);
다음 사용자 작업 시퀀스는 이러한 호출을 초래합니다.
undo — c.undo()
undo — b.undo()
redo — b.redo()
redo — c.redo()
redo — no op, no more edits
실행 취소/다시 실행을 구현하려면 확장 프로그램은 연결된 사용자 지정 문서의 내부 상태를 업데이트하고 문서의 새 상태를 반영하도록 연결된 모든 웹뷰를 업데이트해야 합니다. 단일 리소스에 대해 여러 웹뷰가 있을 수 있다는 점을 명심하십시오. 이러한 웹뷰는 항상 동일한 문서 데이터를 표시해야 합니다. 예를 들어 이미지 편집기의 여러 인스턴스는 항상 동일한 픽셀 데이터를 표시해야 하지만 각 편집기 인스턴스가 자체 확대/축소 수준 및 UI 상태를 갖도록 허용할 수 있습니다.
저장
사용자가 사용자 지정 편집기를 저장하면 확장 프로그램은 저장된 리소스를 현재 상태로 디스크에 기록할 책임이 있습니다. 사용자 지정 편집기가 이를 수행하는 방법은 확장 프로그램의 CustomDocument 유형과 확장 프로그램이 내부적으로 편집을 추적하는 방법에 크게 좌우됩니다.
저장의 첫 번째 단계는 디스크에 쓸 데이터 스트림을 얻는 것입니다. 일반적인 접근 방식은 다음과 같습니다.
-
리소스의 상태를 추적하여 빠르게 직렬화할 수 있습니다.
예를 들어 기본 이미지 편집기는 픽셀 데이터 버퍼를 유지할 수 있습니다.
-
마지막 저장 이후의 편집을 다시 실행하여 새 파일을 생성합니다.
예를 들어 더 효율적인 이미지 편집기는 마지막 저장 이후의 편집(예:
crop,rotate,scale)을 추적할 수 있습니다. 저장 시 이러한 편집을 파일의 마지막 저장 상태에 적용하여 새 파일을 생성합니다. -
저장할 파일 데이터에 대한 사용자 지정 편집기의
WebviewPanel에 묻습니다.하지만 사용자 지정 편집기는 표시되지 않을 때도 저장될 수 있다는 점을 명심하십시오. 이러한 이유로
save구현이WebviewPanel에 의존하지 않는 것이 좋습니다. 불가능한 경우WebviewPanelOptions.retainContextWhenHidden설정을 사용하여 웹뷰가 숨겨져 있을 때도 웹뷰가 계속 활성 상태를 유지하도록 할 수 있습니다.retainContextWhenHidden은 상당한 메모리 오버헤드가 있으므로 신중하게 사용하십시오.
리소스에 대한 데이터를 가져온 후 일반적으로 작업 공간 FS API를 사용하여 디스크에 씁니다. FS API는 데이터의 UInt8Array를 사용하며 바이너리 및 텍스트 기반 파일을 모두 쓸 수 있습니다. 바이너리 파일 데이터의 경우 바이너리 데이터를 UInt8Array에 넣으면 됩니다. 텍스트 파일 데이터의 경우 Buffer를 사용하여 문자열을 UInt8Array로 변환합니다.
const writeData = Buffer.from('my text data', 'utf8');
vscode.workspace.fs.writeFile(fileUri, writeData);
다음 단계
VS Code 확장에 대해 더 알고 싶으시면 다음 주제를 시도해 보세요.