Вход на сайт

Просмотр новости

Найдите то, что Вас интересует

CraftHub: научил свой JSON-редактор работать с папкой проекта — и перестал открывать файлы по одному

Дата публикации: 09-07-2026 13:09:53

Знаете это чувство, когда правишь JSON и ищешь, где же ты забыл запятую? Я устал и сделал редактор, где JSON — это таблица. А теперь он ещё и открывает папку проекта целиком: дерево файлов, Ctrl+S прямо в файл, drag & drop. Как в VS Code, только заточено под данные. Читать далее

Основное содержимое страницы с новостью.

Краткое описание: Продолжаю историю CraftHub — кроссплатформенного редактора, который показывает JSON как таблицу. В прошлых частях мы разбирались с табличным редактированием и расширением для VS Code. В этот раз — самое частое пожелание из issue: «дайте работать с директорией, а не открывать файлы через диалог каждый раз». Рассказываю, как я прикрутил файловый проводник в стиле VS Code, почему сохранение в файл оказалось не таким тривиальным, и на какие грабли Avalonia наступил по дороге.

Для тех, кто пропустил предыдущие серии

CraftHub — это open-source редактор JSON, который открывает массив объектов не как «простыню» текста, а как таблицу: колонки — это поля, строки — элементы массива. Есть десктопная версия на Avalonia (Windows/macOS/Linux) и расширение для VS Code. Идея простая: перестать редактировать данные вручную в текстовом виде и ошибаться в запятых.

Проект живёт за счёт обратной связи. И самое частое, что просили в последнее время, звучало примерно так:

«Неудобно каждый раз открывать файл через диалог. Хочу видеть папку проекта и переключаться между файлами, как в VS Code».

Это стало issue про работу в директории. В этой статье — как я его закрывал.

Проблема: диалог открытия файла — это трение

Раньше цикл работы выглядел так: «Импорт JSON» → системный диалог → найти файл → открыть → поправить → «Экспорт» → снова диалог → выбрать путь. Если файлов в проекте десяток и ты прыгаешь между ними, это утомляет. Каждое переключение — несколько кликов и потеря контекста.

По сути не хватало двух вещей:

  1. Навигации — видеть дерево файлов проекта и открывать их в один-два клика.

  2. Нормального сохранения — чтобы Ctrl+S писал в тот же файл, а не спрашивал путь заново.

Звучит как «просто добавь панель слева». На практике вторая часть оказалась интереснее первой.

Решение: панель проводника в стиле VS Code

Первое — сама панель. Выбираешь корневую папку проекта, и слева появляется дерево: папки и .json-файлы. Двойной клик — файл открывается во вкладке. Есть фильтр (по умолчанию показываем только JSON, чтобы не тонуть в мусоре), поиск по файлам и кнопка показать/скрыть панель. Состояние — корневая папка, ширина, видимость — запоминается между запусками.

Ленивое дерево, чтобы не подвешивать UI

Наивная реализация — рекурсивно обойти всю папку при открытии — умрёт на большом проекте (привет, node_modules). Поэтому дерево грузится лениво, как в нормальных проводниках: у папки, в которой есть содержимое, добавляется «пустышка»-заглушка, чтобы отрисовать стрелку раскрытия, а реальные дети подгружаются только в момент разворачивания.

partial void OnIsExpandedChanged(bool value)
{
    if (value && IsDirectory && !_childrenLoaded)
        LoadChildren(); // читаем диск только когда узел реально раскрыли
}
Самое интересное: сохранение обратно в файл

Вот тут пришлось подумать про модель. У вкладки раньше не было понятия «я привязана к файлу на диске». Импорт просто читал содержимое, экспорт каждый раз спрашивал путь. Чтобы Ctrl+S работал как в редакторе, я ввёл у вкладки состояние «связана с файлом»:

  • Открыл файл (из проводника или через «Импорт») → вкладка запоминает путь.

  • Ctrl+S сериализует данные и пишет в этот же файл, без диалога.

  • Если файла ещё нет (новая вкладка) → Ctrl+S предлагает «Сохранить как», по умолчанию в текущую папку проекта, и после этого вкладка привязывается к новому файлу.

Дальше пошли нюансы, без которых «сохранение» ощущается сломанным:

Индикатор несохранённого. На вкладке загорается точка ●, если данные изменены. Сначала я хотел ловить это через события коллекций строк — но они срабатывают и при импорте, и пришлось бы городить флаги «сейчас идёт загрузка». В итоге сигналом «данные поменялись» стал сам сервис Undo/Redo: раз действие попало в историю — значит, пользователь что-то изменил.

Внешние изменения. Если файл на диске поменяли другой программой (сравниваю время модификации), перед перезаписью честно спрашиваю, а не молча затираю чужие правки.

Переименование = переименование файла. Логичное следствие модели: переименовал вкладку — переименовался и файл на диске (с сохранением расширения), а дерево обновилось. Иначе получается враньё: подпись одна, файл другой.

Файловые операции: как в проводнике

Раз уж есть дерево — от него ждут поведения файлового менеджера. Добавил прямо в панель:

  • создание нового файла (в корне или в конкретной папке);

  • удаление — через контекстное меню и по клавише Delete;

  • копирование / вырезание / вставку файлов (Ctrl+C / Ctrl+X / Ctrl+V);

  • drag & drop — перетащить файл или папку в другую папку;

  • «показать в системном проводнике» и «скопировать путь».

Копирование-вставка и drag & drop под капотом ходят в один и тот же движок переноса: он разруливает конфликты имён (создаёт name copy.json), не даёт бросить папку саму в себя или в свою подпапку, и обновляет только те узлы дерева, которых коснулись, а не перестраивает всё целиком.

Что дальше

Дорожную карту во многом рисует не мой список, а ваши issue. Если чего-то не хватает или что-то раздражает — заходите в репозиторий и напишите. Ровно так появилась и эта фича.

  • GitHub: https://github.com/c3n9/CraftHub

  • Прошлые части — про табличное редактирование и расширение для VS Code — в моём профиле.

Спасибо, что читаете и подсказываете.

Схожие новости

#Наименование новостиТональностьИнформативностьДата публикации
1CraftHub: я устал редактировать JSON руками — а сообщество помогло превратить это в удобный инструмент010.3103-07-2026
2Почему JSON на практике — быстрый формат для баз данных (если выкинуть лишние абстракции)5707-07-2026
3Метод, которого не существовало: как я собрал локальный RAG для CAD API07.2410-07-2026
4Мне надоело писать один и тот же код. Поэтому я сделал Featuregen3609-07-2026
5Ночной джоб, который сам нарезает партиции: cron, SQL-функция и сплиттер011.5521-07-2026
6Видеомонтаж в blender, бесплатный и надёжный09.4410-07-2026
7Когда контекстное окно кончается, а проект — нет5723-06-2026
8[Перевод] Рисуем ASCII-арт в Vim08.8224-07-2026
9Я делал свой продукт, пока работал в найме — и вот что получилось0512-07-2026
10Как я создаю «Черный ящик»: почему разработчику не подходят Jira, Битрикс24 и другие трекеры «для маркетологов»5722-06-2026

Классификация: Пресс-релизы. Схожих патентов: 0. Схожих новостей: 10. Тональность: 0. Информативность: 7.44. Источник: habr.com.