Vue Language Server: Basic Completion and Diagnostics
This challenge tasks you with building a rudimentary Language Server Protocol (LSP) server for Vue.js components, specifically focusing on providing basic code completion suggestions and diagnostic error reporting for Vue template syntax. A language server enhances the developer experience by providing features like autocompletion, error checking, and go-to-definition, all without needing a full IDE.
Problem Description
You are to create a TypeScript-based Language Server that provides the following functionalities for Vue.js single-file components (.vue files):
- Completion: When the user types within the
<template>section of a Vue component, the server should suggest valid HTML attributes and event listeners. For simplicity, assume a limited set of attributes and listeners. - Diagnostics: The server should identify and report errors in the
<template>section, specifically looking for unbalanced tags (e.g., an opening<p>tag without a closing</p>).
Key Requirements:
- The server must adhere to the Language Server Protocol (LSP).
- The server should be able to handle a single Vue component file at a time.
- The completion suggestions should be relevant to the context within the
<template>section. - Diagnostics should be reported with appropriate severity (e.g., Error).
- The server should be able to respond to
initialize,textDocument/didOpen,textDocument/didChange,completion, andtextDocument/validaterequests.
Expected Behavior:
- Upon receiving the
initializerequest, the server should respond with a successful initialization response. - Upon receiving the
textDocument/didOpenrequest, the server should parse the document content. - Upon receiving the
textDocument/didChangerequest, the server should re-parse the document content and update any diagnostics or completion state. - When the
completionrequest is received within the<template>section, the server should return a list of completion items (e.g.,class,id,@click,@mouseover). - When the
textDocument/validaterequest is received, the server should return a list of diagnostics, indicating any unbalanced tags found in the<template>section.
Edge Cases to Consider:
- Nested tags (e.g.,
<p><span></p><span>). - Self-closing tags (e.g.,
<img src="image.jpg" />). - Comments within the
<template>section. - Handling large Vue component files (performance).
- Empty
<template>sections.
Examples
Example 1:
Input:
```vue
<template>
<div class="container">
<p>Hello, world!</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
};
</script>
Output (Completion Request at class="):
[
{
"label": "container",
"kind": 1 // Text
}
]
Explanation: The server suggests "container" as a possible class name.
Example 2:
Input:
```vue
<template>
<p>Hello, world!
</template>
Output (Validation Request):
[
{
"range": {
"start": { "line": 2, "character": 0 },
"end": { "line": 2, "character": 14 }
},
"message": "Unbalanced tag: <p>",
"severity": 2 // Error
}
]
Explanation: The server detects an unbalanced <p> tag and reports an error.
Example 3:
Input:
```vue
<template>
<div @click="handleClick">Click me</div>
</template>
Output (Completion Request at @click="):
[
{
"label": "handleClick",
"kind": 1 // Text
}
]
Explanation: The server suggests handleClick as a possible event handler.
Constraints
- Language: TypeScript
- LSP Version: Focus on a basic implementation compatible with standard LSP clients.
- Vue Syntax: Assume a simplified Vue template syntax. You don't need to handle complex directives or components.
- Completion Items: Limit completion suggestions to HTML attributes (e.g.,
class,id,src) and event listeners (e.g.,@click,@mouseover). - Diagnostics: Focus on detecting unbalanced tags.
- Performance: The server should be able to handle files up to 10,000 lines of code without significant performance degradation.
- Error Handling: Gracefully handle invalid Vue component files.
Notes
- You can use a library like
vscode-languageserverormonaco-languageclientto simplify the implementation of the LSP server. - Start with a minimal implementation that handles only the
initialize,textDocument/didOpen,completion, andtextDocument/validaterequests. - Consider using a simple parser or regular expressions to analyze the Vue template syntax. A full-fledged Vue parser is not required for this challenge.
- Focus on the core functionality of providing completion suggestions and diagnostic error reporting. Advanced features like go-to-definition or symbol resolution are beyond the scope of this challenge.
- The goal is to demonstrate an understanding of the LSP and how to apply it to a specific language (Vue).