From 17a550b2c47aa171cc786da58aad6016a542408e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 24 Apr 2026 13:45:24 +0000 Subject: [PATCH 1/3] Bump version to 0.2.1+3 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a3181b24..1af0c98f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: querya_desktop description: Lightweight desktop SQL/NoSQL client. Flutter (Dart). -version: 0.2.0+2 +version: 0.2.1+3 From 6ddbbc6e7b5c8d2a4e3ac806ae4b77ea8d2c50ec Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Thu, 28 May 2026 10:01:03 +0300 Subject: [PATCH 2/3] docs: adapt Cursor gitflow rules for Querya Desktop --- .cursor/rules/gitflow.md | 136 +++++++++++++++++++++++++++++++++++++++ .gitignore | 32 +++++++-- 2 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 .cursor/rules/gitflow.md diff --git a/.cursor/rules/gitflow.md b/.cursor/rules/gitflow.md new file mode 100644 index 00000000..1cbdce4d --- /dev/null +++ b/.cursor/rules/gitflow.md @@ -0,0 +1,136 @@ +--- +description: Querya Desktop GitFlow, branching, commits, and PR workflow +alwaysApply: true +--- + +# Querya Desktop — agent workflow + +Desktop SQL/NoSQL client (PostgreSQL, MySQL, Redis, MongoDB). +Стек: **Flutter** (Dart 3.5+), **shadcn_flutter** (vendored в `third_party/`), локальный SQLite + OS secure storage для секретов. + +Remote: `git@github.com:QueryaHub/Querya-Desktop.git` + +## Sync with remote (always) + +Before checkout, branch, push, or PR — and **after** merge to `dev`: + +```bash +git fetch --all --prune +git checkout dev +git pull --ff-only origin dev +``` + +Before push on a feature branch: `git fetch origin`, then rebase or merge remote. + +**Full checks** before PR (локально, как в CI): + +```bash +flutter pub get +flutter analyze +flutter test +``` + +Опционально перед релизом / крупным UI-PR: + +```bash +flutter build linux --release # или windows / macos +``` + +На Linux при `errno = 24` на analyze: `ulimit -n 8192` (см. [CONTRIBUTING.md](CONTRIBUTING.md)). + +## Git branches + +- **`main`**: production-ready; релизные теги (`X.Y.Z`) ставятся на коммиты, готовые к бинарникам. +- **`dev`**: интеграция; **все feature PR → `dev`**. +- **Feature**: `issue/-` или `feat/` от актуального `dev`. + +```bash +git fetch --all --prune && git checkout dev && git pull --ff-only origin dev +git checkout -b issue/38-querya-workbench-theme-models +# или: git checkout -b feat/postgres-sql-workspace-toolbar +``` + +Долгоживущие ветки по подсистемам (если согласовано с командой): `postgres-ench`, `mongo-ench`, `my_sql`, `design` — не создавать без необходимости; предпочитать короткие `issue/*` / `feat/*`. + +**Hotfix** только по явному запросу: `hotfix/` от `main` → PR в `main`, затем back-merge в `dev`. + +**Release**: версия в `pubspec.yaml`, тег на нужном коммите, workflow Release — см. [docs/tags-and-releases.md](docs/tags-and-releases.md), [docs/release-checklist.md](docs/release-checklist.md). + +## Issue priority & roadmap + +Живой roadmap: [docs/roadmap.md](docs/roadmap.md). Крупные темы (пример — epic **#37** theming): дочерние issues #38–#60. + +| Область | Фокус | +|---------|--------| +| Connections | Tree, new connection, drivers, secure storage | +| PostgreSQL / MySQL | Browser, SQL workspace, grids, timeouts | +| Redis / MongoDB | Explorer, keys/collections, document editor | +| Theme / UI | `lib/core/theme/`, shadcn tokens, SQL editor (#37 epic) | +| CI / release | `.github/workflows/`, Linux deps, signing (macOS) | + +Один issue → одна ветка → один PR. Scope = issue only — без drive-by рефакторинга. + +## GitHub labels & milestones + +На **issues** и **PRs** через `gh`: + +```bash +gh issue edit 38 --add-label "theme,enhancement" +gh pr create --base dev --label "theme,enhancement" \ + --body "Closes #38" --title "feat(theme): QueryaWorkbenchTheme models (#38)" +``` + +Актуальные labels в репо: `bug`, `enhancement`, `documentation`, `theme`, `editor`, `epic`, … +Для темизации: `theme`, `editor`, `epic` (см. epic [#37](https://github.com/QueryaHub/Querya-Desktop/issues/37)). + +После merge: issue `CLOSED`; `git fetch` + `git pull --ff-only` на `dev`. + +## Commits and PRs + +- [Conventional Commits](https://www.conventionalcommits.org/): `feat`, `fix`, `perf`, `docs`, `test`, `ci`, `chore`, `refactor` + scope. +- Scopes (примеры): `postgresql`, `mysql`, `mongodb`, `redis`, `connections`, `theme`, `editor`, `settings`, `ci`, `deps`, `ui`. +- Атомарные коммиты; не коммитить без явной просьбы пользователя. +- PR body: `Closes #N` когда применимо. +- **Не коммитить:** `.env`, ключи, `credentials.json`, экспортированные connection secrets. + +Примеры: + +``` +feat(theme): add QueryaWorkbenchTheme and editor tokens +fix(postgresql): pass right-clicked table into Open in SQL +feat(mysql): SQL workspace statement timeout from settings +test(connections): panel layout with in-memory secrets +chore(release): bump version to 0.2.2+4 +``` + +## Layout & checks + +| Area | Path | +|------|------| +| Entry | `lib/main.dart`, `lib/app/app.dart` | +| Theme | `lib/core/theme/` | +| DB / pools | `lib/core/database/` | +| Storage / settings | `lib/core/storage/` | +| Features | `lib/features//` | +| Shared UI | `lib/shared/widgets/` | +| Vendored UI | `third_party/shadcn_flutter/` (override в `pubspec.yaml`) | +| Tests | `test/` (mirror `lib/` where possible) | +| Docs | `docs/` | +| CI / release | `.github/workflows/` | + +Зависимости: `pubspec.yaml`; lockfile **не** в git (см. `.gitignore`). + +## Flutter conventions + +- UI: **shadcn** `Theme.of(context).colorScheme`, не смешивать с Material без нужды (`material.` prefix где уже есть). +- Патчи shadcn — только в `third_party/shadcn_flutter`, с комментарием в `pubspec.yaml` `dependency_overrides`. +- Секреты: `flutter_secure_storage` / `connection_secrets_store` — без паролей в SQLite и логах ([docs/security.md](docs/security.md)). +- SQL editor: пока `TextField` / `QueryEditorTab`; подсветка — по issues #47–#50, не раздувать `TextField` ad hoc. +- Новый код: `flutter analyze` clean, тесты для нетривиальной логики (парсеры, storage, SQL helpers). + +## Out of scope (unless issue says otherwise) + +- Backend-сервисы, облачный sync аккаунтов. +- JDBC-драйверы (только встроенные Dart/native пути). +- Полная VS Code theme compatibility в одном PR (см. epic #37, поэтапно). +- Force-push на `main` / `dev` без явного запроса. diff --git a/.gitignore b/.gitignore index 229ea50b..22dd42e8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,21 +4,41 @@ build/ *.iml pubspec.lock +.flutter-plugins +.flutter-plugins-dependencies -# IDE +# Generated (platform) +**/flutter/ephemeral/ +**/Flutter/ephemeral/ +**/GeneratedPluginRegistrant.* +linux/flutter/generated_* +windows/flutter/generated_* +macos/Flutter/ephemeral/ + +# IDE — track Cursor rules, ignore the rest .idea/ -.cursor/ -*.iml +.cursor/* +!.cursor/rules/ +!.cursor/rules/** # OS .DS_Store Thumbs.db -# Old C++/Qt (if still present) +# Logs & coverage +*.log +flutter_*.log +coverage/ + +# Secrets / local env (never commit) +.env +.env.* +!.env.example + +# Old C++/Qt / design mockups (local only) *.o *.a *.so *.dll *.exe -flutter_*.log -design-front +design-front/ From 8319eaea872f3ded79dbe6f632ad3f3a8d29c452 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Thu, 28 May 2026 10:01:36 +0300 Subject: [PATCH 3/3] research --- docs/research_theme.md | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/research_theme.md diff --git a/docs/research_theme.md b/docs/research_theme.md new file mode 100644 index 00000000..79de054d --- /dev/null +++ b/docs/research_theme.md @@ -0,0 +1,70 @@ +Архитектура и реализация системы темизации в стиле Visual Studio Code для десктопных интегрированных сред разработки на базе FlutterРазработка современных интегрированных сред разработки (IDE) требует создания масштабируемой, высокопроизводительной и визуально гибкой архитектуры, способной адаптироваться под индивидуальные предпочтения разработчиков. Проблема внедрения глубокой поддержки пользовательских тем оформления, аналогичных тем, что используются в Visual Studio Code (VS Code), в десктопное приложение, написанное на фреймворке Flutter (например, в корпоративный продукт «querya desktop» организации «queryahub»), представляет собой комплексную инженерную задачу. Данная задача охватывает сразу несколько сложнейших областей компьютерных наук: лексический и семантический анализ исходного кода, парсинг нестрогих структур данных (JSONC), управление графами цветовых палитр, маппинг абстрактных дизайн-токенов на конкретные элементы пользовательского интерфейса, а также обеспечение высокопроизводительного рендеринга огромных массивов текста без потери частоты кадров.Глубокое исследование данного вопроса показывает, что экосистема языка Dart и фреймворка Flutter в настоящий момент достигла того уровня зрелости, когда реализация полнофункциональной поддержки тем VS Code не просто возможна, но и может быть выполнена с использованием уже существующих, проверенных сообществом архитектурных паттернов и библиотек. Реализация этой функциональности открывает доступ к колоссальной базе существующих пользовательских тем (таких как Dracula, Tokyo Night, Atom One Dark, Monokai Pro, GitHub Theme, Ayu, Gruvbox Material и Synthwave x fluoromachine), которые годами создавались сообществом для оптимизации читаемости кода и снижения когнитивной нагрузки на разработчиков. В данном исчерпывающем отчете представлен детальный анализ внутренних механизмов темизации ведущих IDE, подробный обзор доступных библиотек в экосистеме Dart, глубокий разбор архитектурных паттернов Flutter и пошаговая стратегия интеграции этой сложной подсистемы в существующий продукт.Анатомия и архитектурные принципы системы темизации Visual Studio CodeЧтобы успешно реплицировать систему темизации VS Code во Flutter-приложении, необходимо на фундаментальном уровне понимать её внутреннее устройство. Система конфигурации внешнего вида VS Code базируется на строгом и логичном разделении ответственности между оформлением структурных компонентов пользовательского интерфейса (так называемый Workbench) и механизмами раскраски исходного кода (Syntax Highlighting). Это разделение позволяет темам быть максимально универсальными, не привязывая оформление боковых панелей к логике парсинга конкретных языков программирования.Разделение визуальных пространств: Workbench и EditorКонфигурация абсолютно любой темы в экосистеме VS Code представляет собой текстовый файл в формате JSON (часто с использованием комментариев, что классифицируется как JSONC), который концептуально и структурно разделен на две фундаментальные секции :Workbench Color Customizations (Глобальные цвета интерфейса): Эта секция, управляемая ключом workbench.colorCustomizations в пользовательских настройках или объектом colors в файле самой темы, отвечает за цветовое кодирование всех структурных элементов окна редактора, не относящихся напрямую к редактируемому тексту. К этим элементам относятся боковая панель (Side Bar), панель активности (Activity Bar), вкладки открытых файлов (Tabs), строка состояния (Status Bar), всплывающие подсказки, списки файлового менеджера и элементы системы контроля версий. Внутренняя архитектура VS Code определяет сотни уникальных ключей для тонкой настройки. Например, ключи sideBar.background, tab.activeBorderTop, statusBarItem.warningBackground, gitDecoration.modifiedResourceForeground и activityBarBadge.background управляют заливкой, границами и текстом конкретных пиксельных зон интерфейса. В контексте разработки десктопного приложения на Flutter это напрямую коррелирует с параметрами свойств color, border, background стандартных и кастомных виджетов.Token Color Customizations (Токенизация и подсветка синтаксиса): Эта секция, определяемая ключом editor.tokenColorCustomizations в пользовательских настройках или объектом tokenColors в манифесте темы, задает правила, по которым раскрашивается сам исходный код в области редактора. Эта подсистема значительно сложнее обычного маппинга "ключ-значение", поскольку она базируется на концепции грамматик TextMate. Механизм токенизации заключается в том, что весь текст разбивается на логические сегменты (токены), и каждому сегменту присваивается определенный тип или область видимости (scope).Механизмы токенизации и наследие TextMateИсторически редактор VS Code унаследовал свою базовую систему подсветки синтаксиса от редактора TextMate, а также от Atom, который также использовал порт этого движка. Механизм токенизации текста на базе TextMate основан на применении сложного набора регулярных выражений, сгруппированных в грамматики.Грамматики TextMate представляют собой строго структурированную коллекцию регулярных выражений, которые традиционно записываются в форматах XML (plist) или JSON. Движок токенизации VS Code, изначально написанный на C++ (в оригинальном TextMate) и впоследствии портированный на JavaScript/WASM, выполняет парсинг этих грамматик в том же процессе, что и рендерер UI, обновляя токены инкрементально по мере ввода текста пользователем.Когда регулярное выражение совпадает с фрагментом текста, этому фрагменту присваивается семантическое имя области видимости (scope name). Иерархия этих имен имеет строгую структуру, разделенную точками. Например, при парсинге языка C++ пустой блочный комментарий может получить область видимости comment.block.empty.java.Архитектура тем оформления использует эти области видимости для применения конкретных стилей (цвета текста, жирности, курсива). Если разработчик темы определяет цветовое правило для базового идентификатора comment, то все токены в документе, чья область видимости начинается с префикса comment. (включая упомянутый comment.block.empty.java), автоматически унаследуют этот цвет, например, зеленый (#608b4e в стандартной темной теме VS Code Dark+). В то же время, тема может определить более специфичное правило, например, для variable.other.property, задав ему цвет #BD93F9. Движок рендеринга всегда применяет правило с наиболее точным (длинным) совпадением области видимости, что обеспечивает колоссальную гибкость: авторы языковых грамматик могут создавать максимально детализированные токены, а авторы тем могут писать как обобщенные правила для поддержки любых языков, так и узкоспециализированные стили для конкретных конструкций конкретного языка.Эволюция к семантическому выделению (Semantic Highlighting)Несмотря на гибкость грамматик TextMate, лексический анализ на основе регулярных выражений имеет фундаментальные ограничения. Регулярные выражения не способны понимать контекст программы, область видимости переменных в памяти или абстрактное синтаксическое дерево (AST). В связи с этим, начиная с релиза 1.43, архитектура VS Code была радикально расширена за счет внедрения поддержки семантического выделения (Semantic Tokens).Семантические провайдеры токенизации интегрируются с серверами протокола языковых серверов (Language Server Protocol — LSP). В отличие от регулярных выражений, LSP-сервер обладает полным, глубоким пониманием семантики исходного файла. Он анализирует проект целиком и может точно классифицировать каждый символ в контексте. Например, языковой сервер Dart может однозначно определить, что конкретный идентификатор является константой, классом, локальной переменной или вызовом метода.Семантическое выделение не заменяет, а накладывается поверх базовой синтаксической подсветки TextMate, уточняя и корректируя цвета там, где регулярные выражения бессильны. Внедрение этого механизма в экосистему Dart привело к изменениям в отображении тем: после активации LSP-токенов в расширении Dart Code для VS Code многие переменные, которые ранее отображались белым цветом из-за ограничений TextMate, стали окрашиваться в светло-голубой цвет, что первоначально вызывало путаницу у некоторых разработчиков, но объективно улучшило читаемость кода, отделяя переменные от операторов (таких как => или круглые скобки). Для полнофункциональной десктопной IDE, разрабатываемой в "queryahub", архитектура в идеале должна поддерживать оба этих слоя токенизации.Анализ экосистемы Dart и Flutter: Инфраструктура текстовых редакторовДля того чтобы реализовать функциональность редактора кода с поддержкой тем VS Code в "querya desktop", необходимо убедиться, что фреймворк Flutter обладает требуемым инструментарием для парсинга TextMate-грамматик, высокопроизводительного рендеринга больших объемов моноширинного текста и динамического управления темами интерфейса. Анализ показывает, что за последние годы экосистема значительно эволюционировала, перейдя от базовых виджетов к узкоспециализированным решениям.Проблема производительности стандартных виджетов FlutterСтандартный виджет TextField (или TextFormField) во Flutter, хоть и является мощным инструментом для создания форм авторизации, чатов и коротких сообщений, фундаментально не предназначен для использования в качестве полномасштабного редактора исходного кода. Архитектура TextField предполагает управление текстом как единой, непрерывной строкой. При применении синтаксической подсветки эта строка должна быть преобразована в сложное дерево объектов TextSpan, где каждый токен имеет свой собственный стиль.При увеличении размера редактируемого файла (например, до нескольких тысяч строк кода) перестроение всего дерева TextSpan при каждом нажатии клавиши (onChanged) приводит к экспоненциальному росту времени вычислений на главном потоке (UI Isolate). Это вызывает катастрофическое падение частоты кадров (FPS), зависания интерфейса (jank) и блокировку обработки пользовательского ввода.В связи с этим для создания десктопной IDE требуются специализированные архитектурные решения, которые абстрагируются от высокоуровневого TextField и реализуют собственные, глубоко оптимизированные механизмы виртуализации строк, компоновки (layout) и отрисовки (painting). Для достижения производительности нативных редакторов, эти решения часто обращаются к низкоуровневым API Flutter, таким как RenderBox, TextPainter и ParagraphBuilder, обходя стандартный конвейер виджетов.Сравнительный анализ библиотек текстовых редакторов во FlutterДля решения проблемы рендеринга и подсветки синтаксиса в экосистеме pub.dev существует несколько зрелых пакетов, каждый из которых использует свой подход к токенизации и управлению памятью. Выбор правильного фундаментального пакета — это наиболее критичный архитектурный шаг для "querya desktop", так как он определит дальнейшую судьбу всего проекта.Характеристика / Пакетsyntax_highlight re_editor & re_highlight code_forge flutter_code_editor Базовый механизм подсветкиTextMate (Нативная поддержка правил VS Code)Портировано с популярной JS-библиотеки highlight.jsTextMate + Семантические токены через LSPhighlight.js / кастомная реализация поверх TextFieldПоддержка языков программированияРасширяемая через JSON/XML грамматики (встроены CSS, Dart, Go, HTML, Java, JSON, YAML и др.)Около 100 языков (жестко закодированные грамматики)180+ языковОграниченный набор, зависимый от highlight.jsАрхитектура данных в памятиОбычная Dart-строка, преобразуемая в TextSpanОптимизировано для больших текстов, двунаправленный скроллингСтруктура данных Rope (оптимизировано для алгоритмов $O(\log n)$)Базируется на стандартном контроллере TextFieldПрямая поддержка VS Code ТемНативная поддержка TextMate тем через класс HighlighterThemeСобственные стили, транслированные из форматов highlight.jsПолная поддержка тем VS CodeОграничено конфигурацией и темами highlight.jsLSP интеграция (Language Server)ОтсутствуетОтсутствуетПрисутствует (встроенный LSP клиент, Hover, Diagnostics)ОтсутствуетДетальный разбор архитектурных решений1. Инфраструктура пакета syntax_highlight +Данный пакет является концептуально наиболее близким к парадигме VS Code с точки зрения парсинга синтаксиса. Разработанный командой Serverpod, он напрямую использует классические грамматики TextMate для токенизации исходного кода и обладает встроенной поддержкой инициализации пользовательских тем. Разработчик "querya desktop" может загрузить файл грамматики (например, dart.json, который содержит поддержку Dart 3.x, паттернов, записей и макросов ) и применить к нему тему оформления, инстанцировав класс HighlighterTheme. Пакет асинхронно обрабатывает текст и возвращает отформатированный TextSpan, который можно беспрепятственно интегрировать в любой RichText виджет. Главным недостатком этого пакета является то, что он представляет собой исключительно механизм лексической подсветки (highlighter), а не полнофункциональный редактор с курсором, выделением и автодополнением. Для создания IDE поверх него потребуется написать всю логику управления вводом с нуля.2. Экосистема re_editor и re_highlight +Пакет re_editor позиционируется как мощный, легковесный виджет редактора, написанный с нуля. Его архитектура сознательно не зависит от TextField, что позволяет избежать проблем с производительностью. Он самостоятельно реализует сложнейшую логику компоновки текста, отрисовки курсора и обработки событий клавиатуры, поддерживая двунаправленный скроллинг, интеллектуальное сворачивание кода (code folding), шорткаты и виртуализацию строк. В качестве базового движка подсветки используется пакет re_highlight, который представляет собой скрупулезный прямой порт популярной веб-библиотеки highlight.js на язык Dart. Это дает отличную производительность и поддержку почти сотни языков. Однако, этот выбор усложняет прямую трансляцию тем VS Code. Библиотека highlight.js использует совершенно иную архитектуру токенов (базирующуюся на CSS-классах, а не на TextMate scopes), поэтому для интеграции тем VS Code потребуется сложный промежуточный слой-адаптер.3. Библиотека code_forge +Это решение представляет собой квинтэссенцию развития текстовых редакторов во Flutter на данный момент. Пакет code_forge решает проблему управления гигантскими строками путем внедрения структуры данных Rope (веревки) вместо классического плоского массива символов. Структура Rope представляет текст в виде сбалансированного бинарного дерева, где листья содержат короткие подстроки. Это позволяет выполнять операции вставки и удаления символов в файлах любого размера за логарифмическое время $O(\log n)$, тогда как плоская строка требует линейного времени $O(n)$ для сдвига всех последующих символов. Виджет полностью обходит TextField, взаимодействуя с графическим процессором напрямую через RenderBox. Наиболее важным аспектом для "querya desktop" является то, что code_forge обладает встроенным клиентом Language Server Protocol (LSP). Это означает, что он способен "из коробки" запрашивать у языкового сервера семантические токены в реальном времени, обеспечивая ту самую подсветку переменных и классов, к которой привыкли пользователи VS Code, а также поддерживает интеграцию с AI-ассистентами (например, Gemini).Стратегический вывод по выбору ядра: Если для "querya desktop" первостепенной задачей является абсолютная, пиксельная точность цветопередачи оригинальных тем VS Code (включая возможность импорта .json файлов без сложной конвертации), архитектура должна базироваться на парсинге TextMate (используя пакеты вроде syntax_highlight внутри кастомного скроллера или интегрируя их в flutter_code_editor или flutter_deck ). Если же в приоритете находится производительность редактирования мегабайтных файлов, наличие семантической LSP-подсветки, автодополнения и архитектурная стабильность, то code_forge является безальтернативным оптимальным ядром. В этом случае маппинг пользовательских тем VS Code на его внутренний формат потребует разработки транслятора токенов.Архитектура подсистемы парсинга и внедрения стилей для querya desktopДля того чтобы интегрировать поддержку тем VS Code во Flutter-приложение, недостаточно просто выбрать виджет редактора. Необходимо спроектировать и разработать комплексную подсистему парсинга JSON-файлов, разрешения цветовых конфликтов и динамического внедрения стилей в дерево виджетов Flutter. Архитектура этого решения распадается на три независимых модуля: парсер форматов тем, инжектор Workbench-стилей (для пользовательского интерфейса вокруг редактора) и инжектор синтаксических стилей (для самого редактора кода).Модуль 1: Разработка парсера VS Code тем (JSON/JSONC Parser и Color Parser)Темы VS Code распространяются в виде текстовых манифестов. Хотя они имеют расширение .json, фактически они часто написаны в формате JSONC (JSON with Comments). Стандартная библиотека Dart dart:convert (а именно функция jsonDecode) реализует строгую спецификацию JSON и не поддерживает комментарии. Попытка распарсить оригинальный файл темы (например, загруженный напрямую из репозитория расширения на GitHub) гарантированно приведет к фатальному исключению FormatException.Для "querya desktop" требуется реализация кастомного препроцессора или использование пакетов на основе регулярных выражений для очистки файла от невалидных структур перед его передачей в стандартный декодер:Удаление однострочных комментариев: Поиск и удаление всех строк, начинающихся с //, с учетом того, что // может встречаться внутри строковых литералов (где его удалять нельзя).Удаление многострочных комментариев: Обработка блоков /*... */.Очистка висячих запятых (trailing commas): В JSONC допускается оставлять запятую после последнего элемента массива или объекта, что недопустимо в строгом JSON. Препроцессор должен находить паттерны ,} и , ] и заменять их на } и ].Декодирование: Передача очищенной валидной строки в jsonDecode, который вернет древовидную структуру Map.Полученная структура (Map) будет содержать все ключевые узлы. Самыми важными для нас являются объект colors (в котором хранятся настройки Workbench) и массив tokenColors (в котором хранятся правила TextMate).Следующим шагом является парсинг самих цветов. Цвета в темах VS Code могут быть заданы в различных форматах: #RGB, #RGBA, #RRGGBB, #RRGGBBAA. Для надежного преобразования этих строковых представлений в нативные объекты Color фреймворка Flutter необходимо использовать специализированные пакеты, такие как color_parser. Этот пакет способен принимать на вход строку (например, parser = ColorParser.hex('#00bfff')) и возвращать объект Color, который может быть напрямую использован в виджетах Flutter. Если в редакторе планируется реализация терминала или системы логирования (подобно расширению flutter-log-fold, которое использует ANSI-цвета для логов пакетов Talker и logger ), потребуется также интеграция парсера ANSI-кодов, такого как terminal_color_parser , для преобразования конструкций вида `\x1BМодуль 2: Инжектор стилей интерфейса (Workbench) и ThemeExtensionВ стандартной парадигме разработки на Flutter всей дизайн-системой управляет глобальный класс ThemeData, который инкапсулирует в себе ColorScheme (цветовую схему, основанную на спецификации Material Design). Однако класс ColorScheme концептуально ограничен. Он содержит лишь базовый набор абстрактных семантических токенов (таких как primary, secondary, surface, error, onBackground и т.д.). Этого абсолютно недостаточно для покрытия сотен узкоспециализированных ключей интерфейса VS Code. Невозможно логично привязать цвет activityBarBadge.background или gitDecoration.untrackedResourceForeground к стандартному Theme.of(context).colorScheme.secondary без создания запутанного и хрупкого кода.Для элегантного решения этой архитектурной проблемы в последних версиях Flutter был внедрен механизм ThemeExtension. Механизм ThemeExtension позволяет инженерам определять свои собственные, строго типизированные объекты тем с неограниченным количеством кастомных токенов и бесшовно внедрять их непосредственно в глобальный объект ThemeData.Архитектурная реализация WorkbenchThemeExtensionДля успешного внедрения в "querya desktop" необходимо спроектировать класс WorkbenchTheme, наследующийся от ThemeExtension, который будет содержать иммутабельные переменные для всех активно используемых элементов интерфейса:Dartclass WorkbenchTheme extends ThemeExtension { + final Color activityBarBackground; + final Color activityBarForeground; + final Color activityBarBadgeBackground; + final Color sideBarBackground; + final Color editorBackground; + final Color statusBarBackground; + final Color statusBarForeground; + final Color gitDecorationModified; + final Color gitDecorationUntracked; + //... десятки других токенов, соответствующих спецификации VS Code + + const WorkbenchTheme({ + required this.activityBarBackground, + required this.activityBarForeground, + required this.activityBarBadgeBackground, + required this.sideBarBackground, + required this.editorBackground, + required this.statusBarBackground, + required this.statusBarForeground, + required this.gitDecorationModified, + required this.gitDecorationUntracked, + }); + + @override + ThemeExtension copyWith({ + Color? activityBarBackground, + //... + }) { + return WorkbenchTheme( + activityBarBackground: activityBarBackground?? this.activityBarBackground, + //... + ); + } + + @override + ThemeExtension lerp(ThemeExtension? other, double t) { + if (other is! WorkbenchTheme) return this; + // Реализация линейной интерполяции для всех свойств + return WorkbenchTheme( + activityBarBackground: Color.lerp(activityBarBackground, other.activityBarBackground, t)!, + activityBarForeground: Color.lerp(activityBarForeground, other.activityBarForeground, t)!, + sideBarBackground: Color.lerp(sideBarBackground, other.sideBarBackground, t)!, + //... + ); + } +} +Процесс парсинга темы в рантайме (при запуске приложения или смене темы) будет осуществлять трансляцию строковых ключей из распарсенной JSON-мапы в этот строго типизированный объект. Например, функция-маппер будет читать значение ключа sideBar.background (допустим, это цвет #13141f из конфигурации темы Dracula ), парсить HEX-строку в объект Color и инициализировать им поле sideBarBackground при создании экземпляра WorkbenchTheme. В случае отсутствия ключа в JSON-файле темы (что часто бывает в неполных темах), маппер должен использовать заранее определенный Fallback-цвет.Фундаментальное преимущество такого подхода заключается в том, что ThemeExtension нативно интегрируется с системой анимаций Flutter. Благодаря обязательной реализации метода lerp (линейная интерполяция), при переключении пользователем темы (например, с темной "Tokyo Night" на светлую "Atom One Light" ), интерфейс "querya desktop" автоматически и плавно анимирует переход всех цветов с частотой 60 или 120 кадров в секунду, без необходимости писать сложный код анимации вручную и без жесткой перезагрузки дерева виджетов.Для доступа к этим кастомным цветам в любом месте огромного дерева виджетов разработчики будут использовать лаконичный и безопасный вызов:Theme.of(context).extension()!.sideBarBackground.Модуль 3: Инжектор синтаксических стилей (Токенизация редактора)Вторая критически важная часть конфигурационной мапы — это массив tokenColors, который содержит список объектов, описывающих правила подсветки синтаксиса для движка TextMate. Типичное правило в файле темы выглядит следующим образом :JSON{ + "scope": "variable.other.property", + "settings": { + "foreground": "#BD93F9", + "fontStyle": "italic" + } +} +Если "querya desktop" выбирает архитектурный путь использования библиотеки syntax_highlight (что является логичным для обеспечения максимальной совместимости с грамматиками TextMate), инженерам потребуется написать класс-конвертер, который переведет этот сырой JSON-массив во внутреннюю структуру данных HighlighterTheme.Библиотека syntax_highlight обладает встроенными механизмами для работы с подобными конфигурациями. В официальной документации указано, что разработчик может загрузить стандартную светлую или темную тему (HighlighterTheme.loadLightTheme()). Анализ исходного кода этого пакета показывает наличие структур для маппинга скоупов на цвета. Если публичный API пакета не предоставляет метода для прямой инициализации из сырого Map, потребуется реализовать собственный алгоритм обхода правил TextMate.Алгоритм разрешения цветов TextMate: +Механизм разрешения цветов в TextMate напоминает алгоритм специфичности в CSS. Когда парсер текста определяет область видимости для конкретного слова (например, токен punctuation.definition.comment.java ), движок тем должен найти для него цвет.Алгоритм ищет в массиве tokenColors наиболее точное и специфичное совпадение (полную строку punctuation.definition.comment.java).Если правило не найдено, алгоритм отбрасывает последний сегмент иерархии (удаляет .java), превращая строку в punctuation.definition.comment, и повторяет поиск.Процесс усечения продолжается (punctuation.definition, затем просто punctuation), пока не будет найдено правило.Если правило найдено на любом этапе, его настройки (foreground, background, fontStyle) применяются к TextSpan.Если ни одно правило не подошло, применяется дефолтный цвет текста редактора.Для обеспечения высокой частоты кадров при наборе текста, результаты поиска для уникальных имен областей видимости должны кэшироваться в HashMap внутри HighlighterTheme, чтобы избежать дорогостоящего перебора массива правил при каждом нажатии клавиши.Глубокие аналитические выводы (Второго и третьего порядка)Проектирование столь сложного механизма для Flutter-приложения открывает ряд стратегических и технических аспектов, которые далеко не очевидны при базовом рассмотрении архитектуры и требуют глубокого понимания принципов работы компилятора Dart.1. Фундаментальное влияние регулярных выражений на Event Loop во FlutterПарсинг сложных TextMate-грамматик сопряжен с серьезной алгоритмической проблемой. Эти грамматики могут содержать сотни рекурсивных и тяжеловесных регулярных выражений, некоторые из которых подвержены проблеме "катастрофического возврата" (catastrophic backtracking), известной как regex-бомбы. В языке Dart выполнение регулярных выражений происходит строго синхронно в рамках текущего изолята.Если "querya desktop" попытается выполнять токенизацию файла на 5000 строк непосредственно в основном потоке выполнения Dart (Main UI Isolate), это неминуемо приведет к блокировке Event Loop на сотни миллисекунд. В результате приложение потеряет кадры, курсор перестанет мигать, а ввод текста пользователем будет отставать от нажатий на клавиатуре.Архитектурный инсайт: Чтобы "querya desktop" ощущался пользователем так же плавно и отзывчиво, как нативный VS Code (который выполняет тяжелую токенизацию в эффективном движке, написанном на C++, или в высокооптимизированном WebAssembly-контейнере ), процесс токенизации должен быть жестко изолирован. Инженерам необходимо делегировать лексический анализ в отдельный фоновый Isolate (используя пакет isolate_parser или функцию compute в Dart). При каждом значительном изменении текста в редакторе, снимок текста или дельта изменений передается в фоновый Isolate. Там безопасно выполняется парсинг, генерация метаданных токенов, после чего обратно в UI-изолят отправляется легковесный бинарный массив или список легко сериализуемых структур данных с индексами стилей. На стороне UI-изолята этот массив предельно быстро транслируется в вызовы ParagraphBuilder или перестроение TextSpan. Именно такой подход позволяет достичь бескомпромиссной производительности.2. Смена парадигмы: Tree-sitter против TextMateХотя VS Code исторически опирается на грамматики TextMate из-за огромного наследия существующих конфигураций, вся индустрия разработки инструментов (включая Neovim, Atom и GitHub) неуклонно движется в сторону технологии Tree-sitter. Tree-sitter — это инструмент инкрементального парсинга, который, в отличие от TextMate, не использует регулярные выражения, а создает полноценные и строгие абстрактные синтаксические деревья (AST), которые способны обновляться за микросекунды даже в гигантских файлах при каждом нажатии клавиши.Опыт создателей различных парсеров доказывает, что Tree-sitter обеспечивает несоизмеримо большую надежность, точность семантической подсветки и скорость, нежели хрупкая система регулярных выражений, которая часто критически ошибается в многострочных контекстах, таких как вложенные комментарии или интерполяция строк.В контексте языка Dart прямая интеграция Tree-sitter возможна, однако она требует использования FFI (Foreign Function Interface) для вызова нативных библиотек, написанных на языке C. Это значительно усложняет конвейер CI/CD и дистрибуцию десктопного приложения, так как инженерам "queryahub" придется компилировать и поставлять нативные динамические библиотеки (.dll для Windows, .so для Linux, .dylib для macOS) вместе с Flutter-приложением. Следовательно, на первом этапе разработки "querya desktop" использование укоренившейся экосистемы TextMate (посредством пакетов вроде syntax_highlight или re_highlight ) является стратегически верным решением с точки зрения минимизации затрат и обеспечения 100% совместимости с темами. Недостатки точности лексического анализа TextMate должны компенсироваться интеграцией LSP-серверов и семантических токенов (как это реализовано в продвинутом виджете code_forge ).3. Расширяемость, A/B тестирование и дизайн-токены в корпоративной средеВнедрение парсера JSON-тем VS Code во Flutter-приложение обладает колоссальным скрытым преимуществом для всей организации "queryahub", выходящим далеко за рамки простого редактора кода. Как отмечается в современных исследованиях и лучших практиках управления многотемными дизайн-системами во Flutter, использование JSON-файлов в качестве единственного источника истины (Single Source of Truth) для дизайн-токенов (отступы, шрифты, размеры иконок, палитры) является передовым подходом.Поддержка формата тем VS Code может стать мостом между отделом дизайна и разработки. Дизайнеры организации могут использовать плагины для Figma (например, Figdart ), чтобы экспортировать цветовые палитры напрямую в формат JSON Theme. Приложение "querya desktop" сможет скачивать эти манифесты из удаленного API или считывать из локальных файлов при запуске. Это позволяет динамически обновлять оформление интерфейса, проводить A/B-тестирование различных визуальных концепций, адаптироваться под сегменты пользователей или применять white-labeling (брендирование под конкретного корпоративного клиента) абсолютно без необходимости перекомпиляции исходного кода и перевыпуска приложения. Использование пакетов Freezed для генерации иммутабельных классов и архитектурных паттернов типа BLoC или Riverpod позволит организовать надежное реактивное управление состоянием темы, делая UI абсолютно независимым от жестко закодированных констант.4. Сложная иерархия переопределения цветов (Color Overrides)Архитектура VS Code имеет чрезвычайно сложную, многоуровневую каскадную модель применения настроек. Пользовательская настройка, прописанная вручную в файле settings.json (например, в блоке "workbench.colorCustomizations"), обладает абсолютным приоритетом и всегда переопределяет цвета, зашитые в манифесте активной темы (будь то Dracula, Tokyo Night или встроенная Dark+). +Более того, некоторые расширения (например, Dart Code) внедряют свои собственные кастомные ключи в эту систему. Так, ключ dart.closingLabels отвечает за цвет аннотаций закрывающих скобок, а dart.flutterUiGuides — за цвет направляющих линий дерева виджетов в редакторе. Эти ключи также можно переопределять в workbench.colorCustomizations.Архитектура WorkbenchTheme во Flutter должна в точности повторять этот паттерн "Глубокого слияния" (Deep Merge).Конвейер загрузки и слияния стилей:Фаза инициализации: Загрузить в память Default Theme (встроенные в "querya desktop" fallback-значения для всех известных токенов, чтобы избежать null reference exceptions в UI).Фаза применения темы: Распарсить JSON-файл выбранной пользователем темы (например, dracula.json). Выполнить глубокое слияние распарсенной мапы с дефолтными значениями, заменяя дефолты там, где тема предоставляет свой цвет.Фаза переопределения: Распарсить глобальные настройки пользователя (аналог settings.json внутри "querya desktop"), извлечь узел workbench.colorCustomizations.Фаза наложения (Override): Выполнить финальное наложение пользовательских значений поверх результата предыдущего шага. Если пользователь явно захотел сделать sideBar.background ярко-красным, это значение должно перезаписать значение из темы Dracula.Фаза инстанцирования: Инициализировать класс WorkbenchTheme с получившимся графом и передать его в корневой MaterialApp.Эта многоуровневая структура наложения диктует абсолютную необходимость использования иммутабельных структур данных (Data Classes с методами copyWith) во Flutter для предотвращения случайного загрязнения глобального состояния приложения и обеспечения предсказуемости рендеринга.Стратегический план внедрения для организации queryahubНа основе проведенного масштабного исследования можно сформулировать конкретный, пошаговый технический roadmap для команды "queryahub" по разработке данной функциональности в проекте "querya desktop".Этап 1: Подготовка изолированной инфраструктуры и структур данных +Первоочередной задачей является создание независимого Dart-пакета (например, querya_theme_parser), который будет полностью абстрагирован от Flutter UI (то есть не будет зависеть от библиотеки flutter). В этом пакете необходимо определить строгие Dart-модели данных (VsCodeTheme, TokenColorRule, WorkbenchColors), используя механизмы кодогенерации (пакеты json_serializable и freezed для обеспечения иммутабельности ). В этом же модуле разрабатывается надежный препроцессор-очиститель JSONC (для поддержки комментариев и висячих запятых) и интегрируется парсер HEX-кодов для надежного преобразования строк в Color.Этап 2: Проектирование и интеграция ThemeExtension в UI +На втором этапе команда UI разрабатывает обширный класс QueryaWorkbenchTheme extends ThemeExtension, реализующий методы copyWith и lerp. Этот класс будет содержать поля для всех элементов интерфейса IDE (тулбары, боковые панели, терминал, статус-бар). Затем этот экстеншен регистрируется в корневом виджете приложения:DartMaterialApp( + theme: ThemeData( + extensions: >, + ), + //... +) +После этого все виджеты "querya desktop" (кнопки, контейнеры, списки файлов) должны быть рефакторены для получения своих цветов не из жестко заданных констант, а через вызов Theme.of(context).extension().Этап 3: Замена ядра редактора и внедрение синтаксических тем +Это наиболее сложный этап, на котором стандартные TextField заменяются на профессиональный движок. Стратегически рекомендуется использовать библиотеку code_forge , так как она решает проблему редактирования гигантских файлов с помощью структуры Rope и имеет поддержку LSP. Если архитектура "querya desktop" требует максимальной кастомизации скроллинга, можно рассмотреть re_editor. В ядро интегрируется вторая часть распарсенной темы (массив tokenColors). Если используется движок на базе TextMate (как syntax_highlight), настраивается мост между загруженной грамматикой и правилами темы. Также настраивается отображение дополнительных элементов редактора, таких как цветные скобки (bracket pair colorization ) и направляющие линии.Этап 4: Разработка менеджера настроек и реактивности (Settings Manager) +Финальный этап заключается в реализации файлового наблюдателя (File Watcher), который будет непрерывно мониторить изменения в локальном конфигурационном файле пользователя. При ручном изменении пользователем ключа в workbench.colorCustomizations , менеджер должен мгновенно пересобирать экземпляр ThemeExtension, применять алгоритм глубокого слияния и отправлять новое событие в систему управления состоянием (BLoC или Riverpod). Дерево виджетов Flutter реактивно отреагирует на изменение ThemeData, а благодаря правильно реализованному методу lerp , весь интерфейс IDE бесшовно и плавно анимирует переход к новым цветам.Реализация описанной архитектуры не только обеспечит "querya desktop" беспрецедентно мощной функциональностью динамической смены тем, полностью сопоставимой с отраслевым стандартом VS Code, но и предоставит разработчикам доступ к богатейшему наследию тысяч кастомных тем. Это стратегическое решение радикально минимизирует затраты организации "queryahub" на внутренний UI/UX дизайн, позволяя сосредоточить инженерные ресурсы на разработке уникального функционала IDE, предоставляя при этом пользователям эстетически безупречный, привычный и высокопроизводительный инструмент, полностью написанный на фреймворке Flutter. \ No newline at end of file