Metadata-Version: 2.4
Name: bslfmt
Version: 0.20.1
Summary: Детерминированный форматтер кода 1С (BSL): отступы и пробелы по стандартам 1С
Author: AzeevAN
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/AzeevAN/bslfmt
Project-URL: Repository, https://github.com/AzeevAN/bslfmt
Project-URL: Changelog, https://github.com/AzeevAN/bslfmt/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/AzeevAN/bslfmt/issues
Keywords: 1c,1c-enterprise,bsl,formatter,1с,форматтер
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Natural Language :: Russian
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Dynamic: license-file

# bslfmt

Детерминированный форматтер структурных отступов BSL. Проект работает как
Python-библиотека и CLI; интеграция с MCP 1C будет отдельным потребителем пакета.

## Границы

Форматтер приводит отступы и форматирование поддерживаемых операторов. Он
сохраняет значимые токены и порядок кода, строк, комментариев и директив. Он не
проверяет синтаксис BSL и не компилирует модули. Если структурное форматирование
небезопасно, команда завершает работу с диагностикой, не перезаписывая источник.

## Стиль форматирования

Стиль один, настроек нет. Он следует стандартам 1С «Тексты модулей» (std456) и
«Перенос выражений» (std444) и практике типовых конфигураций.

- **Отступы** — табуляцией, по вложенности блоков: процедуры и функции,
  `Если`/`ИначеЕсли`/`Иначе`, циклы, `Попытка`/`Исключение`. Английские и
  смешанные ключевые слова распознаются.
- **С колонки 0** — `Процедура`/`Функция` и их концы, аннотации
  (`&НаСервере`…), директивы препроцессора (`#Область`, `#Если`…, в том числе
  внутри процедур), переменные и код модуля вне процедур.
- **Строки продолжения** выражений и параметров — не меньше чем +1 отступ к
  инструкции; более глубокий отступ (выравнивание по скобке или первому
  операнду) сохраняется. На уровне инструкции остаются строка, начинающаяся
  с `)`, и текст запроса сразу после `=`. Строки `И`/`Или` многострочного
  условия — не меньше чем +1 к `Если`.
- **Многострочные строки**: строки `|` сдвигаются вместе со строкой, где
  начался литерал; пробелы перед `|` не входят в значение строки.
- **Комментарии** `//` встают на отступ следующей строки кода. Комментарий в
  колонке 0 (маркеры доработок `//!`, `//++`, закомментированный код)
  остаётся в колонке 0. Текст комментариев не меняется.
- **Пробелы**: вокруг бинарных операторов (`=`, `<>`, `+`, `%`…), после
  запятой; без пробелов перед `,` `;` `)` и после `(`. Лишние пробелы внутри
  строки схлопываются, хвостовые удаляются; выравнивание табами внутри строки
  заменяется одним пробелом.
- **Пустые строки**: не больше одной подряд. Строки из одних пробелов и табов
  (так их заполняет конфигуратор) не очищаются.
- **Методы расширений** с `&ИзменениеИКонтроль` форматируются как обычный
  код: платформа не сверяет пробелы и табы в контролируемых строках.
- **Не трогаются**: строки и даты, текст комментариев, области
  `#Вставка`/`#Удаление`, регистр букв, порядок и перенос кода (длинные
  строки не переносятся).

## Установка

Нужен Python 3.10+ или [uv](https://docs.astral.sh/uv/) — он сам скачает
Python. Пакет без зависимостей, одинаков для Windows, macOS и Linux.

```sh
uv tool install bslfmt        # команда bslfmt в терминале (рекомендуется)
pipx install bslfmt           # то же через pipx
uvx bslfmt Модуль.bsl         # разовый запуск без установки
```

Установить `uv`: Windows — `winget install astral-sh.uv` (или
`powershell -c "irm https://astral.sh/uv/install.ps1 | iex"`); macOS —
`brew install uv`; macOS и Linux — `curl -LsSf https://astral.sh/uv/install.sh | sh`.
Обновление: `uv tool upgrade bslfmt` (или `pipx upgrade bslfmt`).

### Для агентов и хуков

Форматировать файл на месте — одна команда, модуль через контекст агента не
передаётся:

```sh
uvx bslfmt -i Модуль.bsl            # отформатировать файл (uv сам поставит пакет)
uvx bslfmt --check Модуль.bsl       # код выхода 1 — файл нужно отформатировать
uvx bslfmt -i -sbc Модуль.bsl       # и удалить комментарии внутри методов
```

Если пакет установлен (`uv tool install bslfmt`), то же без `uvx`. Вывод —
UTF-8; сводка на файл: `ФАЙЛ: изменён (строк: N)` или `ФАЙЛ: без изменений`.

## Установка для разработки

```sh
python -m venv .venv
. .venv/bin/activate
python -m pip install -e .
python -m unittest discover -s tests -v
```

Команда `bslfmt` появляется в активном окружении.

CI (GitHub Actions) прогоняет тесты на Windows, macOS и Linux и проверяет
установленную команду: `python tests/cli_smoke.py` после `pip install .`.

## CLI

```sh
bslfmt Модуль.bsl                        # результат на экран, файл не меняется
bslfmt -i Модуль.bsl Форма.bsl           # отформатировать файлы на месте
bslfmt --check Модуль.bsl Форма.bsl      # только проверить (для CI и хуков)
bslfmt --check --diff Модуль.bsl         # проверить и показать различия
bslfmt Модуль.bsl --output Новый.bsl     # записать результат в новый файл
bslfmt - < Модуль.bsl                    # стандартный ввод
bslfmt -i -sbc Модуль.bsl                # и удалить комментарии внутри методов
bslfmt --help                            # справка по всем режимам
```

`-i` переписывает только файлы, которым нужна правка: запись атомарная
(временный файл рядом и замена), при отказе форматирования файл не меняется.
Сводка на каждый файл: `ФАЙЛ: изменён (строк: N)` или `ФАЙЛ: без изменений`.
Файл только для чтения не переписывается (ошибка, код 2). `--` завершает
флаги: `bslfmt --check -- -файл.bsl`.
`-sbc`, `--strip-body-comments` (с любым режимом) удаляет строки-комментарии внутри
процедур и функций — закомментированный код, маркеры доработок, пояснения.
Комментарии в конце строки кода, над методами, внутри строк (текстов
запросов) и областей `#Вставка`/`#Удаление` остаются. Без ключа комментарии
не удаляются.
`--check` ничего не записывает и перечисляет файлы, которые нужно
отформатировать. Несколько файлов — только с `-i`, `--check` или `--diff`;
каждый обрабатывается отдельно. `--output` создаёт новый файл и отказывается
перезаписывать существующий.

Ввод и вывод (текст, различия, сводка, ошибки) — UTF-8 на любой ОС; переводы
строк и BOM сохраняются как в исходнике.

Коды выхода (худший по всем файлам): `0` — успех (при `--check` — всё
отформатировано); `1` — `--check` нашёл файлы для форматирования; `2` —
ошибка аргументов, чтения или записи, неверная кодировка или отказ
форматирования (сообщение в stderr с именем файла и номером строки, если он
известен); `3` — внутренняя ошибка форматтера.

## Python API

```python
from bslfmt import format_code

formatted = format_code(source)
```

Для недоверенного ввода есть лимиты: `max_chars` — длина исходника
(по умолчанию 20 000 000 символов), `max_depth` — вложенность блоков
(по умолчанию 100). При превышении — `FormatError`; `None` отключает лимит.

```python
formatted = format_code(source, max_chars=1_000_000, max_depth=50)
cleaned = format_code(source, strip_body_comments=True)
```

Сервису, который принимает код извне, стоит также запускать форматирование в
отдельном процессе с ограничением памяти и времени.

Поддерживаемые функции и ограничения уточняются по синтетическим тестам в
`tests/`; локальные корпуса и конфигурации в репозиторий не входят.

## Лицензия

Apache License 2.0 — см. `LICENSE` и `NOTICE`. Проект не аффилирован с ООО «1С».
