feat: add QuestLang VS Code extension with syntax highlighting and installation instructions

This commit is contained in:
2025-09-01 03:10:30 +07:00
parent 96d6131c2c
commit 65018dfcc6
8 changed files with 510 additions and 88 deletions

View File

@@ -14,14 +14,14 @@ A modern TypeScript interpreter for the QuestLang programming language - a domai
## Installation
```bash
npm install questlang-interpreter
npm install questlang
```
Or for development:
```bash
git clone <repo-url>
cd questlang-interpreter
cd questlang
npm install
```
@@ -43,30 +43,10 @@ questlang validate quest.ql
questlang analyze quest.ql
```
#### Enhanced Clack CLI (Beautiful Interactive Interface)
```bash
# Interactive mode with file picker and beautiful prompts
questlang-clack
# Direct commands with enhanced visual output
questlang-clack play quest.ql
questlang-clack validate quest.ql
questlang-clack analyze quest.ql
```
The clack CLI features:
- 🎨 Beautiful colored prompts with icons
- 📊 Enhanced visual output
- ⏳ Loading spinners
- 🎯 Interactive file selection
- 🔄 "Play again" functionality
See [CLI_GUIDE.md](./CLI_GUIDE.md) for detailed comparison.
### Programmatic API
```typescript
import { QuestLang } from 'questlang-interpreter';
import { QuestLang } from 'questlang';
// Parse quest source code
const ast = QuestLang.parse(sourceCode);
@@ -76,7 +56,7 @@ const interpreter = QuestLang.interpret(sourceCode);
// Get quest information
const questInfo = interpreter.getQuestInfo();
console.log(`Playing: \${questInfo.name}`);
console.log(`Playing: ${questInfo.name}`);
// Navigate through the quest
const currentNode = interpreter.getCurrentNode();
@@ -181,54 +161,6 @@ The interpreter follows best practices for language implementation:
- Validation and analysis tools
- Development utilities
## Development
```bash
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run coverage
# Type check
npm run type-check
# Lint code
npm run lint
# Format code
npm run format
# Build for production
npm run build
# Development mode
npm run dev quest.ql
```
## Testing
The project uses Vitest for testing with comprehensive coverage:
```bash
# Run all tests
npm test
# Run tests in watch mode
npm run test
# Generate coverage report
npm run coverage
```
Test categories:
- **Unit Tests**: Lexer, Parser, Interpreter components
- **Integration Tests**: Full quest parsing and execution
- **Example Tests**: Real quest scenarios
## Project Structure
```
@@ -247,16 +179,6 @@ src/
└── integration.test.ts
```
## Contributing
1. Fork the repository
2. Create a feature branch: \`git checkout -b feature/amazing-feature\`
3. Make your changes and add tests
4. Run the test suite: \`npm test\`
5. Commit your changes: \`git commit -m 'Add amazing feature'\`
6. Push to the branch: \`git push origin feature/amazing-feature\`
7. Open a Pull Request
## License
MIT License - see LICENSE file for details

13
vscode-extension/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
]
}
]
}

View File

@@ -0,0 +1,9 @@
**/.git
**/node_modules
**/.DS_Store
**/Thumbs.db
**/*.log
.vscode-test/
out/
dist/
*.vsix

108
vscode-extension/INSTALL.md Normal file
View File

@@ -0,0 +1,108 @@
# Инструкция по установке и использованию расширения QuestLang
## Способы установки
### 1. Установка из исходного кода (для разработки)
1. Убедитесь, что у вас установлен VS Code и Node.js
2. Установите глобально инструмент для работы с расширениями VS Code:
```bash
npm install -g @vscode/vsce
```
3. Перейдите в директорию расширения:
```bash
cd /Users/robonen/Projects/questlang/vscode-extension
```
4. Упакуйте расширение в файл .vsix:
```bash
vsce package
```
5. Установите расширение в VS Code:
```bash
code --install-extension questlang-syntax-1.0.0.vsix
```
### 2. Установка для разработки (без упаковки)
1. Откройте папку расширения в VS Code:
```bash
code /Users/robonen/Projects/questlang/vscode-extension
```
2. Нажмите F5 для запуска Extension Development Host
3. В новом окне VS Code откройте любой файл с расширением .ql
## Тестирование подсветки синтаксиса
1. Создайте файл с расширением `.ql`
2. Скопируйте содержимое из `example.ql` или используйте пример из README
3. Проверьте, что синтаксис подсвечивается правильно:
- Ключевые слова должны быть выделены цветом
- Строки в кавычках должны быть одного цвета
- Комментарии должны быть серыми/зелеными
- Имена узлов (перед двоеточием) должны выделяться
## Элементы подсветки
- **Ключевые слова структуры**: `квест`, `граф`, `узлы`, `начало`, `конец`
- **Ключевые слова свойств**: `тип`, `описание`, `переходы`, `варианты`, `название`
- **Типы узлов**: `начальный`, `действие`, `концовка`
- **Строки**: текст в двойных кавычках
- **Числа**: целые и десятичные числа
- **Комментарии**: строки, начинающиеся с `//`
- **Имена узлов**: идентификаторы перед двоеточием
- **Имя квеста**: название после ключевого слова `квест`
## Функции редактора
- Автоматическое закрытие скобок: `{}`, `[]`, `()`
- Автоматическое закрытие кавычек: `""`
- Автоматические отступы в блоках
- Сворачивание блоков кода
- Поддержка комментариев (Ctrl+/)
## Настройка цветовой схемы
Вы можете настроить цвета подсветки в своей теме VS Code, используя следующие селекторы:
```json
{
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": "keyword.control.quest.questlang",
"settings": {
"foreground": "#569cd6",
"fontStyle": "bold"
}
},
{
"scope": "entity.name.type.quest.questlang",
"settings": {
"foreground": "#4ec9b0"
}
},
{
"scope": "entity.name.function.node.questlang",
"settings": {
"foreground": "#dcdcaa"
}
}
]
}
}
```
## Устранение неполадок
### Расширение не активируется
- Проверьте, что файл имеет расширение `.ql`
- Перезапустите VS Code
- Проверьте, что расширение установлено в списке Extensions
### Подсветка работает неправильно
- Убедитесь, что синтаксис файла корректный
- Попробуйте команду "Reload Window" в VS Code
- Проверьте консоль разработчика (Help > Toggle Developer Tools)
### Автодополнение не работает
Данная версия расширения предоставляет только подсветку синтаксиса. Автодополнение можно добавить в будущих версиях, создав Language Server Protocol (LSP) сервер.

View File

@@ -0,0 +1,83 @@
# QuestLang Syntax Highlighting
Расширение VS Code для подсветки синтаксиса языка QuestLang - специализированного языка для создания интерактивных текстовых квестов.
## Возможности
-**Подсветка синтаксиса** для файлов `.ql`
- 🔤 **Поддержка русских ключевых слов**
- 💬 **Подсветка комментариев** (`//`)
- 🎨 **Цветовое выделение строк и чисел**
- 🔧 **Автоматическое закрытие скобок**
- 📐 **Автоматические отступы**
## Поддерживаемые элементы языка
### Ключевые слова
- `квест`, `цель`, `граф`, `узлы`, `начало`, `конец`
- `тип`, `описание`, `переходы`, `варианты`, `название`
- `начальный`, `действие`, `концовка`
### Синтаксические элементы
- Строки в двойных кавычках: `"Текст"`
- Числа: `123`, `45.67`
- Комментарии: `// это комментарий`
- Скобки: `{}`, `[]`, `()`
- Разделители: `;`, `:`, `,`
## Пример кода
```questlang
квест МойКвест;
цель "Описание цели квеста";
граф {
узлы {
старт: {
тип: начальный;
описание: "Начало приключения";
переходы: [выбор];
}
выбор: {
тип: действие;
описание: "Что вы будете делать?";
варианты: [
("Идти направо", правый_путь),
("Идти налево", левый_путь)
];
}
}
начало: старт;
}
конец;
```
## Установка
1. Откройте VS Code
2. Перейдите в Extensions (Ctrl+Shift+X)
3. Найдите "QuestLang Syntax Highlighting"
4. Нажмите Install
## Использование
После установки расширения все файлы с расширением `.ql` будут автоматически распознаваться как файлы QuestLang с подсветкой синтаксиса.
## Разработка
Для разработки расширения:
```bash
git clone <repo-url>
cd vscode-extension
npm install
```
Затем нажмите F5 в VS Code для запуска Extension Development Host.
## Лицензия
MIT

View File

@@ -0,0 +1,36 @@
{
"comments": {
"lineComment": "//",
"blockComment": ["/*", "*/"]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
],
"autoClosingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
],
"surroundingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
],
"indentationRules": {
"increaseIndentPattern": "^\\s*.*[{\\[]\\s*$",
"decreaseIndentPattern": "^\\s*[}\\]].*$"
},
"wordPattern": "[-?\\d*\\.\\w\\u0100-\\uffff]+",
"folding": {
"markers": {
"start": "^\\s*//\\s*#?region\\b",
"end": "^\\s*//\\s*#?endregion\\b"
}
}
}

View File

@@ -0,0 +1,46 @@
{
"publisher": "questlang",
"name": "questlang-syntax",
"displayName": "QuestLang Syntax Highlighting",
"version": "1.0.0",
"description": "Syntax highlighting for QuestLang - a domain-specific language for interactive quests",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/robonen/questlang.git"
},
"keywords": [
"questlang",
"quest",
"syntax highlighting",
"dsl"
],
"categories": [
"Programming Languages"
],
"engines": {
"vscode": "^1.60.0"
},
"contributes": {
"languages": [
{
"id": "questlang",
"aliases": [
"QuestLang",
"questlang"
],
"extensions": [
".ql"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "questlang",
"scopeName": "source.questlang",
"path": "./syntaxes/questlang.tmLanguage.json"
}
]
}
}

View File

@@ -0,0 +1,205 @@
{
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
"name": "QuestLang",
"scopeName": "source.questlang",
"patterns": [
{
"include": "#comments"
},
{
"include": "#quest-declaration"
},
{
"include": "#goal-declaration"
},
{
"include": "#keywords"
},
{
"include": "#strings"
},
{
"include": "#numbers"
},
{
"include": "#node-identifiers"
},
{
"include": "#identifiers"
},
{
"include": "#punctuation"
}
],
"repository": {
"comments": {
"patterns": [
{
"name": "comment.line.double-slash.questlang",
"begin": "//",
"end": "$",
"captures": {
"0": {
"name": "punctuation.definition.comment.questlang"
}
}
}
]
},
"quest-declaration": {
"patterns": [
{
"match": "(квест)\\s+([а-яёА-ЯЁa-zA-Z_][а-яёА-ЯЁa-zA-Z0-9_]*)",
"captures": {
"1": {
"name": "keyword.control.quest.questlang"
},
"2": {
"name": "entity.name.type.quest.questlang"
}
}
}
]
},
"goal-declaration": {
"patterns": [
{
"begin": "(цель)\\s+(\")",
"end": "\"",
"beginCaptures": {
"1": {
"name": "keyword.control.goal.questlang"
},
"2": {
"name": "punctuation.definition.string.begin.questlang"
}
},
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.questlang"
}
},
"contentName": "string.quoted.double.goal.questlang",
"patterns": [
{
"name": "constant.character.escape.questlang",
"match": "\\\\."
}
]
}
]
},
"keywords": {
"patterns": [
{
"name": "keyword.control.structure.questlang",
"match": "\\b(граф|узлы|начало|конец)\\b"
},
{
"name": "keyword.other.property.questlang",
"match": "\\b(тип|описание|переходы|варианты|название)\\b"
},
{
"name": "keyword.type.node.questlang",
"match": "\\b(начальный|действие|концовка)\\b"
}
]
},
"strings": {
"patterns": [
{
"name": "string.quoted.double.questlang",
"begin": "\"",
"end": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.questlang"
}
},
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.questlang"
}
},
"patterns": [
{
"name": "constant.character.escape.questlang",
"match": "\\\\."
}
]
}
]
},
"numbers": {
"patterns": [
{
"name": "constant.numeric.decimal.questlang",
"match": "\\b\\d+(\\.\\d+)?\\b"
}
]
},
"node-identifiers": {
"patterns": [
{
"match": "([а-яёА-ЯЁa-zA-Z_][а-яёА-ЯЁa-zA-Z0-9_]*)(:)",
"captures": {
"1": {
"name": "entity.name.function.node.questlang"
},
"2": {
"name": "punctuation.separator.colon.questlang"
}
}
}
]
},
"identifiers": {
"patterns": [
{
"name": "variable.other.questlang",
"match": "\\b[а-яёА-ЯЁ_][а-яёА-ЯЁ0-9_]*\\b"
},
{
"name": "variable.other.questlang",
"match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
}
]
},
"punctuation": {
"patterns": [
{
"name": "punctuation.terminator.statement.questlang",
"match": ";"
},
{
"name": "punctuation.separator.comma.questlang",
"match": ","
},
{
"name": "punctuation.section.braces.begin.questlang",
"match": "\\{"
},
{
"name": "punctuation.section.braces.end.questlang",
"match": "\\}"
},
{
"name": "punctuation.section.brackets.begin.questlang",
"match": "\\["
},
{
"name": "punctuation.section.brackets.end.questlang",
"match": "\\]"
},
{
"name": "punctuation.section.parens.begin.questlang",
"match": "\\("
},
{
"name": "punctuation.section.parens.end.questlang",
"match": "\\)"
}
]
}
}
}