프로그래밍 방식 언어 기능
프로그래밍 언어 기능은 vscode.languages.* API로 구동되는 스마트 편집 기능 세트입니다. Visual Studio Code에서 동적 언어 기능을 제공하는 두 가지 일반적인 방법이 있습니다. 호버를 예로 들어 보겠습니다.
vscode.languages.registerHoverProvider('javascript', {
provideHover(document, position, token) {
return {
contents: ['Hover Content']
};
}
});
위에서 보듯이, vscode.languages.registerHoverProvider API는 JavaScript 파일에 대한 호버 콘텐츠를 제공하는 쉬운 방법을 제공합니다. 이 확장이 활성화된 후, JavaScript 코드 위로 마우스를 가져가면 VS Code는 JavaScript에 대한 모든 HoverProvider를 쿼리하고 결과를 호버 위젯에 표시합니다. 언어 기능 목록과 아래의 그림화된 GIF는 확장에 필요한 VS Code API/LSP 메서드를 찾는 쉬운 방법을 제공합니다.
또 다른 접근 방식은 언어 서버 프로토콜을 사용하는 언어 서버를 구현하는 것입니다. 작동 방식은 다음과 같습니다.
- 확장은 JavaScript용 언어 클라이언트와 언어 서버를 제공합니다.
- 언어 클라이언트는 Node.js 확장 호스트 컨텍스트에서 실행되는 다른 VS Code 확장과 같습니다. 활성화되면 다른 프로세스에서 언어 서버를 시작하고 언어 서버 프로토콜을 통해 통신합니다.
- VS Code에서 JavaScript 코드로 마우스를 가져갑니다.
- VS Code가 언어 클라이언트에게 호버를 알립니다.
- 언어 클라이언트는 언어 서버에 호버 결과를 쿼리하고 VS Code로 다시 보냅니다.
- VS Code가 호버 위젯에 호버 결과를 표시합니다.
프로세스는 더 복잡해 보이지만 두 가지 주요 이점을 제공합니다.
- 언어 서버는 어떤 언어로든 작성할 수 있습니다.
- 언어 서버는 여러 편집기에서 스마트 편집 기능을 제공하기 위해 재사용할 수 있습니다.
더 자세한 안내는 언어 서버 확장 안내를 참조하십시오.
언어 기능 목록
이 목록에는 각 언어 기능에 대한 다음 항목이 포함됩니다.
- VS Code에서 언어 기능 일러스트
- 관련 VS Code API
- 관련 LSP 메서드
진단 제공
진단은 코드의 문제를 나타내는 방법입니다.

언어 서버 프로토콜
언어 서버는 textDocument/publishDiagnostics 메시지를 언어 클라이언트로 보냅니다. 메시지에는 리소스 URI에 대한 진단 항목 배열이 포함됩니다.
참고: 클라이언트는 서버에 진단을 요청하지 않습니다. 서버가 진단 정보를 클라이언트로 푸시합니다.
직접 구현
let diagnosticCollection: vscode.DiagnosticCollection;
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(getDisposable());
diagnosticCollection = vscode.languages.createDiagnosticCollection('go');
ctx.subscriptions.push(diagnosticCollection);
...
}
function onChange() {
let uri = document.uri;
check(uri.fsPath, goConfig).then(errors => {
diagnosticCollection.clear();
let diagnosticMap: Map<string, vscode.Diagnostic[]> = new Map();
errors.forEach(error => {
let canonicalFile = vscode.Uri.file(error.file).toString();
let range = new vscode.Range(error.line-1, error.startColumn, error.line-1, error.endColumn);
let diagnostics = diagnosticMap.get(canonicalFile);
if (!diagnostics) { diagnostics = []; }
diagnostics.push(new vscode.Diagnostic(range, error.msg, error.severity));
diagnosticMap.set(canonicalFile, diagnostics);
});
diagnosticMap.forEach((diags, file) => {
diagnosticCollection.set(vscode.Uri.parse(file), diags);
});
})
}
기본
열려 있는 편집기에 대한 진단을 보고합니다. 최소한, 이는 각 저장 시 발생해야 합니다. 더 나아가, 진단은 편집기의 저장되지 않은 내용을 기반으로 계산되어야 합니다.
고급
열려 있는 편집기뿐만 아니라 폴더의 모든 리소스에 대한 진단을 보고합니다. 편집기에서 한 번도 열린 적이 없더라도 상관없습니다.
코드 완성 제안 표시
코드 완성은 사용자에게 문맥에 맞는 제안을 제공합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 완성을 제공한다는 사실과 계산된 완성 항목에 대한 추가 정보를 제공하기 위해 completionItem\resolve 메서드를 지원하는지 여부를 알려야 합니다.
{
...
"capabilities" : {
"completionProvider" : {
"resolveProvider": "true",
"triggerCharacters": [ '.' ]
}
...
}
}
직접 구현
class GoCompletionItemProvider implements vscode.CompletionItemProvider {
public provideCompletionItems(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Thenable<vscode.CompletionItem[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(getDisposable());
ctx.subscriptions.push(
vscode.languages.registerCompletionItemProvider(
GO_MODE, new GoCompletionItemProvider(), '.', '\"'));
...
}
기본
해결 제공자를 지원하지 않습니다.
고급
사용자가 선택한 완성 제안에 대한 추가 정보를 계산하는 해결 제공자를 지원합니다. 이 정보는 선택한 항목과 함께 표시됩니다.
인라인 완성 표시
인라인 완성은 편집기에서 직접 여러 토큰 제안(유령 텍스트)을 표시합니다.

직접 구현
vscode.languages.registerInlineCompletionItemProvider({ language: 'javascript' }, {
provideInlineCompletionItems(document, position, context, token) {
const result: vscode.InlineCompletionList = {
items: [],
commands: [],
};
...
return result;
}
});
완전한 예제는 인라인 완성 샘플 확장에서 탐색할 수 있습니다.
기본
특정 언어의 현재 줄 내용을 기반으로 잘 알려진 패턴 목록에 대한 인라인 완성만 반환합니다.
고급
전체 문서 또는 작업 공간의 내용을 기반으로 하는 인라인 완성 및 더 복잡한 패턴을 반환합니다.
호버 표시
호버는 마우스 커서 아래에 있는 기호/객체에 대한 정보를 표시합니다. 일반적으로 기호의 유형과 설명입니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 호버를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"hoverProvider" : "true",
...
}
}
또한 언어 서버는 textDocument/hover 요청에 응답해야 합니다.
직접 구현
class GoHoverProvider implements HoverProvider {
public provideHover(
document: TextDocument, position: Position, token: CancellationToken):
Thenable<Hover> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerHoverProvider(
GO_MODE, new GoHoverProvider()));
...
}
기본
유형 정보를 표시하고 가능한 경우 문서를 포함합니다.
고급
코드 색상 지정 방식과 동일한 스타일로 메서드 시그니처의 색상을 지정합니다.
함수 및 메서드 시그니처 도움말
사용자가 함수 또는 메서드를 입력할 때 호출되는 함수/메서드에 대한 정보를 표시합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 시그니처 도움말을 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"signatureHelpProvider" : {
"triggerCharacters": [ '(' ]
}
...
}
}
또한 언어 서버는 textDocument/signatureHelp 요청에 응답해야 합니다.
직접 구현
class GoSignatureHelpProvider implements SignatureHelpProvider {
public provideSignatureHelp(
document: TextDocument, position: Position, token: CancellationToken):
Promise<SignatureHelp> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerSignatureHelpProvider(
GO_MODE, new GoSignatureHelpProvider(), '(', ','));
...
}
기본
시그니처 도움말에 함수 또는 메서드 매개변수의 문서가 포함되도록 합니다.
고급
추가 없음.
기호 정의 표시
사용자가 변수/함수/메서드가 사용되는 곳에서 바로 변수/함수/메서드의 정의를 볼 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 정의 위치를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"definitionProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/definition 요청에 응답해야 합니다.
직접 구현
class GoDefinitionProvider implements vscode.DefinitionProvider {
public provideDefinition(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Thenable<vscode.Location> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDefinitionProvider(
GO_MODE, new GoDefinitionProvider()));
...
}
기본
기호가 모호한 경우 여러 정의를 표시할 수 있습니다.
고급
추가 없음.
기호의 모든 참조 찾기
사용자가 특정 변수/함수/메서드/기호가 사용되는 모든 소스 코드 위치를 볼 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 기호 참조 위치를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"referencesProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/references 요청에 응답해야 합니다.
직접 구현
class GoReferenceProvider implements vscode.ReferenceProvider {
public provideReferences(
document: vscode.TextDocument, position: vscode.Position,
options: { includeDeclaration: boolean }, token: vscode.CancellationToken):
Thenable<vscode.Location[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerReferenceProvider(
GO_MODE, new GoReferenceProvider()));
...
}
기본
모든 참조에 대한 위치(리소스 URI 및 범위)를 반환합니다.
고급
추가 없음.
문서 내 기호의 모든 발생 강조 표시
사용자가 열려 있는 편집기에서 기호의 모든 발생을 볼 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 기호 문서 위치를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"documentHighlightProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/documentHighlight 요청에 응답해야 합니다.
직접 구현
class GoDocumentHighlightProvider implements vscode.DocumentHighlightProvider {
public provideDocumentHighlights(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
vscode.DocumentHighlight[] | Thenable<vscode.DocumentHighlight[]>;
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentHighlightProvider(
GO_MODE, new GoDocumentHighlightProvider()));
...
}
기본
참조가 발견된 편집기 문서의 범위를 반환합니다.
고급
추가 없음.
문서 내 모든 기호 정의 표시
사용자가 열려 있는 편집기에서 기호 정의로 빠르게 이동할 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 기호 문서 위치를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"documentSymbolProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/documentSymbol 요청에 응답해야 합니다.
직접 구현
class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(
document: vscode.TextDocument, token: vscode.CancellationToken):
Thenable<vscode.SymbolInformation[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentSymbolProvider(
GO_MODE, new GoDocumentSymbolProvider()));
...
}
기본
문서의 모든 기호를 반환합니다. 변수, 함수, 클래스, 메서드 등과 같은 기호의 종류를 정의합니다.
고급
추가 없음.
폴더 내 모든 기호 정의 표시
사용자가 VS Code에서 열린 폴더(작업 영역) 어디에서든 기호 정의로 빠르게 이동할 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 전역 기호 위치를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"workspaceSymbolProvider" : "true"
...
}
}
또한 언어 서버는 workspace/symbol 요청에 응답해야 합니다.
직접 구현
class GoWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
public provideWorkspaceSymbols(
query: string, token: vscode.CancellationToken):
Thenable<vscode.SymbolInformation[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerWorkspaceSymbolProvider(
new GoWorkspaceSymbolProvider()));
...
}
기본
열려 있는 폴더 내 소스 코드로 정의된 모든 기호를 반환합니다. 변수, 함수, 클래스, 메서드 등과 같은 기호의 종류를 정의합니다.
고급
추가 없음.
오류 또는 경고에 대한 가능한 작업
오류 또는 경고 옆에 가능한 수정 작업을 사용자에게 제공합니다. 작업이 사용 가능한 경우 오류 또는 경고 옆에 전구 아이콘이 나타납니다. 사용자가 전구 아이콘을 클릭하면 사용 가능한 코드 작업 목록이 표시됩니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 코드 작업을 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"codeActionProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/codeAction 요청에 응답해야 합니다.
직접 구현
class GoCodeActionProvider implements vscode.CodeActionProvider<vscode.CodeAction> {
public provideCodeActions(
document: vscode.TextDocument, range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext, token: vscode.CancellationToken):
Thenable<vscode.CodeAction[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
GO_MODE, new GoCodeActionProvider()));
...
}
기본
오류/경고 수정 작업을 위한 코드 작업 제공.
고급
또한 리팩토링과 같은 소스 코드 조작 작업을 제공합니다. 예를 들어, 메서드 추출.
CodeLens - 소스 코드 내에서 실행 가능한 컨텍스트 정보 표시
소스 코드와 함께 표시되는 실행 가능한 컨텍스트 정보를 사용자에게 제공합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 CodeLens 결과를 제공한다는 사실과 CodeLens를 명령에 바인딩하기 위해 codeLens\resolve 메서드를 지원하는지 여부를 알려야 합니다.
{
...
"capabilities" : {
"codeLensProvider" : {
"resolveProvider": "true"
}
...
}
}
또한 언어 서버는 textDocument/codeLens 요청에 응답해야 합니다.
직접 구현
class GoCodeLensProvider implements vscode.CodeLensProvider {
public provideCodeLenses(document: TextDocument, token: CancellationToken):
CodeLens[] | Thenable<CodeLens[]> {
...
}
public resolveCodeLens?(codeLens: CodeLens, token: CancellationToken):
CodeLens | Thenable<CodeLens> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerCodeLensProvider(
GO_MODE, new GoCodeLensProvider()));
...
}
기본
문서에 사용할 수 있는 CodeLens 결과를 정의합니다.
고급
codeLens/resolve에 응답하여 CodeLens 결과를 명령에 바인딩합니다.
색상 구분 기호 표시
사용자가 문서에서 색상을 미리 보고 수정할 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 색상 정보를 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"colorProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/documentColor 및 textDocument/colorPresentation 요청에 응답해야 합니다.
직접 구현
class GoColorProvider implements vscode.DocumentColorProvider {
public provideDocumentColors(
document: vscode.TextDocument, token: vscode.CancellationToken):
Thenable<vscode.ColorInformation[]> {
...
}
public provideColorPresentations(
color: Color, context: { document: TextDocument, range: Range }, token: vscode.CancellationToken):
Thenable<vscode.ColorPresentation[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerColorProvider(
GO_MODE, new GoColorProvider()));
...
}
기본
문서의 모든 색상 참조를 반환합니다. 지원되는 색상 형식(예: rgb(...), hsl(...))에 대한 색상 프레젠테이션을 제공합니다.
고급
추가 없음.
편집기에서 소스 코드 서식 지정
사용자에게 전체 문서 서식을 지정하는 지원을 제공합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 문서 서식을 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"documentFormattingProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/formatting 요청에 응답해야 합니다.
직접 구현
class GoDocumentFormatter implements vscode.DocumentFormattingEditProvider {
provideDocumentFormattingEdits(
document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken)
: vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentFormattingEditProvider(
GO_MODE, new GoDocumentFormatter()));
...
}
기본
서식 지원을 제공하지 않습니다.
고급
소스 코드가 올바르게 서식이 지정되어 진단 결과와 같은 마커가 올바르게 조정되고 손실되지 않도록 하려면 가능한 가장 작은 텍스트 편집만 반환해야 합니다. 이는 매우 중요합니다.
편집기에서 선택한 줄 서식 지정
사용자에게 문서에서 선택한 줄 범위를 서식 지정하는 지원을 제공합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 줄 범위에 대한 서식 지원을 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"documentRangeFormattingProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/rangeFormatting 요청에 응답해야 합니다.
직접 구현
class GoDocumentRangeFormatter implements vscode.DocumentRangeFormattingEditProvider{
public provideDocumentRangeFormattingEdits(
document: vscode.TextDocument, range: vscode.Range,
options: vscode.FormattingOptions, token: vscode.CancellationToken):
vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentRangeFormattingEditProvider(
GO_MODE, new GoDocumentRangeFormatter()));
...
}
기본
서식 지원을 제공하지 않습니다.
고급
소스 코드가 올바르게 서식이 지정되어 진단 결과와 같은 마커가 올바르게 조정되고 손실되지 않도록 하려면 가능한 가장 작은 텍스트 편집만 반환해야 합니다. 이는 매우 중요합니다.
사용자가 입력할 때 코드 점진적 서식 지정
사용자에게 입력 시 텍스트 서식을 지정하는 지원을 제공합니다.
참고: editor.formatOnType 설정은 사용자가 입력할 때 소스 코드가 서식이 지정되는지 여부를 제어합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 사용자가 입력할 때 서식을 제공한다는 사실을 알려야 합니다. 또한 서식을 트리거해야 하는 문자를 클라이언트에 알려야 합니다. moreTriggerCharacters는 선택 사항입니다.
{
...
"capabilities" : {
"documentOnTypeFormattingProvider" : {
"firstTriggerCharacter": "}",
"moreTriggerCharacter": [";", ","]
}
...
}
}
또한 언어 서버는 textDocument/onTypeFormatting 요청에 응답해야 합니다.
직접 구현
class GoOnTypingFormatter implements vscode.OnTypeFormattingEditProvider{
public provideOnTypeFormattingEdits(
document: vscode.TextDocument, position: vscode.Position,
ch: string, options: vscode.FormattingOptions, token: vscode.CancellationToken):
vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerOnTypeFormattingEditProvider(
GO_MODE, new GoOnTypingFormatter()));
...
}
기본
서식 지원을 제공하지 않습니다.
고급
소스 코드가 올바르게 서식이 지정되어 진단 결과와 같은 마커가 올바르게 조정되고 손실되지 않도록 하려면 가능한 가장 작은 텍스트 편집만 반환해야 합니다. 이는 매우 중요합니다.
기호 이름 바꾸기
사용자가 기호의 이름을 바꾸고 해당 기호에 대한 모든 참조를 업데이트할 수 있도록 합니다.

언어 서버 프로토콜
initialize 메서드에 대한 응답에서 언어 서버는 이름 바꾸기 지원을 제공한다는 사실을 알려야 합니다.
{
...
"capabilities" : {
"renameProvider" : "true"
...
}
}
또한 언어 서버는 textDocument/rename 요청에 응답해야 합니다.
직접 구현
class GoRenameProvider implements vscode.RenameProvider {
public provideRenameEdits(
document: vscode.TextDocument, position: vscode.Position,
newName: string, token: vscode.CancellationToken):
Thenable<vscode.WorkspaceEdit> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerRenameProvider(
GO_MODE, new GoRenameProvider()));
...
}
기본
이름 바꾸기 지원을 제공하지 않습니다.
고급
기호를 참조하는 모든 파일의 모든 편집과 같이 수행해야 하는 모든 작업 영역 편집 목록을 반환합니다.