diff --git a/.vale.ini b/.vale.ini index 729a5e88..c60c5e1f 100644 --- a/.vale.ini +++ b/.vale.ini @@ -4,7 +4,8 @@ MinAlertLevel = error Packages = https://github.com/tbhb/vale-ai-tells/releases/download/v1.29.0/ai-tells.zip [*.{rst,md}] -BasedOnStyles = ai-tells +BasedOnStyles = ai-tells, snapper +snapper.SemanticLineBreaks = error # These rules misclassify established technical, example, or release-note prose # in this repository. All other ai-tells rules remain enforced. diff --git a/docs/source/index.rst b/docs/source/index.rst index c9bca548..b3ac5445 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -14,8 +14,8 @@ Usage ----- .. click:: vws_web_tools:vws_web_tools_group - :prog: vws-web-tools - :show-nested: + :prog: vws-web-tools + :show-nested: Reference diff --git a/docs/source/unreleased.rst b/docs/source/unreleased.rst index 22ac7472..d297d197 100644 --- a/docs/source/unreleased.rst +++ b/docs/source/unreleased.rst @@ -1,8 +1,8 @@ Unreleased changes ================== -Changes that have landed on the main branch but are not yet part of a -tagged release. These entries are assembled into the +Changes that have landed on the main branch but are not yet part of a tagged release. +These entries are assembled into the :doc:`changelog` when the next release is published. .. towncrier-draft-entries:: diff --git a/prek.toml b/prek.toml index 6cbe2ca9..5a350c3c 100644 --- a/prek.toml +++ b/prek.toml @@ -388,6 +388,19 @@ hooks = [ additional_dependencies = ["uv==0.11.7"], stages = ["pre-commit"] }, + { + id = "snapper", + name = "snapper", + entry = "uv run --group=dev snapper --max-width 0 --in-place", + language = "python", + types_or = [ + "rst", + "markdown" + ], + require_serial = true, + additional_dependencies = ["uv==0.11.7"], + stages = ["pre-commit"] + }, { id = "vale", name = "vale", diff --git a/pyproject.toml b/pyproject.toml index 20932416..4b29ad76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,7 @@ dev = [ # use it to lint shell commands in GitHub workflow files. "shellcheck-py==0.11.0.1", "shfmt-py==4.1.0", + "snapper-fmt==0.11.0", "sphinx==9.1.0", "sphinx-click==6.2.0", "sphinx-copybutton==0.5.2", @@ -273,6 +274,7 @@ ignore = [ ".checkmake-config.ini", ".git_archival.txt", ".prettierrc", + ".snapperrc.toml", ".vale.ini", ".vscode/**", ".yamlfmt", @@ -292,6 +294,7 @@ ignore = [ "newsfragments/**", "prek.toml", "spelling_private_dict.txt", + "styles/snapper/**", "tests", "tests-pylintrc", "tests/**", diff --git a/styles/snapper/LongProseLine.yml b/styles/snapper/LongProseLine.yml new file mode 100644 index 00000000..1f5029f7 --- /dev/null +++ b/styles/snapper/LongProseLine.yml @@ -0,0 +1,11 @@ +--- +# Vale style rule: flag prose lines that are suspiciously long. +# Likely indicates wrapped text that should use semantic line breaks. +extends: existence +message: Prose line exceeds 120 characters. Consider running 'snapper' to break at + sentence boundaries. +level: suggestion +scope: paragraph +# This catches lines > 120 chars that contain a period followed by a space. +# Pure code or URLs are less likely to match. +tokens: ['.{120,}'] diff --git a/styles/snapper/SemanticLineBreaks.yml b/styles/snapper/SemanticLineBreaks.yml new file mode 100644 index 00000000..3f4edaf5 --- /dev/null +++ b/styles/snapper/SemanticLineBreaks.yml @@ -0,0 +1,11 @@ +--- +# Vale style rule: flag lines containing multiple sentences. +# These should be broken at sentence boundaries. +extends: existence +message: Line contains multiple sentences. Run 'snapper --check' or reformat with + 'snapper --in-place'. +level: warning +scope: paragraph +# Match a sentence-ending punctuation followed by a space and a capital letter +# on the same line (indicating two sentences on one line). +tokens: ['[.!?]\\s+[A-Z]']