Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ The pattern syntax is a small subset of gitignore's:
| `*` | Any run of characters within one path component, including none. |
| `?` | Exactly one character within one path component. |
| `**` | Zero or more whole path components — the only wildcard crossing a `/`. |
| `/` leading | Anchors the pattern to the directory the ignore file sits in. |
| `/` leading | Anchors the pattern to the top level of the path as given, wherever the ignore file itself sits. |
| `/` trailing | Restricts the pattern to directories, so `build/` covers `build/x.md`. |
| `!` leading | Negates. The last matching pattern wins. |
| `\` | Escapes a leading `#` or `!`, or a trailing space. |
Expand Down Expand Up @@ -301,11 +301,11 @@ The conservative boundary is the feature. Every one of these is left exactly as
- The file's original line endings: `\r\n` and `\r` survive a rewrite
- Any paragraph an `<!-- unwrap-ignore -->` comment claims, covered in [One paragraph, by comment](#one-paragraph-by-comment), and any run of paragraphs inside a [marker pair](#a-run-of-paragraphs-by-comment-pair)

Two of those are about shape rather than about every line. Prose wrapped inside a `-` or `1.` item joins at the indentation its marker implies, and prose inside a blockquote joins behind its marker: what the tool preserves there is the container, not the line breaks within it. A single-letter enumerator is structural, so those lines do stay as written.
Four of those are about shape rather than about every line. Prose wrapped inside a `-` or `1.` item joins at the indentation its marker implies, and prose inside a blockquote joins behind its marker: what the tool preserves there is the container, not the line breaks within it. A label row and an inline speaker turn keep their own line while a value wrapped underneath joins onto it, so what survives there is the row rather than the breaks inside it -- a whole file that reads as a transcript is a different matter and is skipped untouched. A single-letter enumerator is structural, so those lines do stay as written.

### Known limitations

A **bare** pipe in running prose is treated as table syntax and blocks unwrapping for that paragraph. This is deliberate. Every row of a GFM table contains a pipe, so the pipe test is what protects tables; narrowing it to real tables needs full table state rather than a delimiter-row lookahead, because body rows do not follow a delimiter row. Corrupting a table is a worse outcome than declining to unwrap a paragraph. A pipe inside an inline code span does **not** block unwrapping — code spans are masked before the test.
A **bare** pipe in running prose is treated as table syntax, so the line carrying it is left as written and the prose on either side of it joins separately. This is deliberate. Every row of a GFM table contains a pipe, so the pipe test is what protects tables; narrowing it to real tables needs full table state rather than a delimiter-row lookahead, because body rows do not follow a delimiter row. Corrupting a table is a worse outcome than declining to join a line. A pipe inside an inline code span does **not** block unwrapping — code spans are masked before the test.

An inline code span opened on one line and closed on the next is not recognized, since the matcher works a line at a time.

Expand Down
2 changes: 1 addition & 1 deletion docs/rust-port-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Two mechanisms, both language-neutral:

Exclusion filters the file list however that list was produced — explicit arguments, `--files-from`, or directory discovery. This is what makes it invocation-independent: `pre-commit` passes filenames explicitly, so a tool that only honored exclusions during its own discovery would ignore them precisely where they are most used. An excluded file is skipped silently and does not trip `--fail-on-change`; exclusion is a statement about scope, not an error.

The format is a deliberately small subset of gitignore, because full fidelity across two hand-written implementations is a parity liability rather than a feature. Blank lines and `#` comments are skipped. `*` matches a run of non-separator characters, `**` matches across separators, `?` matches one non-separator character. A leading `/` anchors to the ignore file's directory; without it a pattern matches at any depth. A trailing `/` restricts to directories. A leading `!` negates, and the last matching pattern wins. Character classes are excluded from the subset.
The format is a deliberately small subset of gitignore, because full fidelity across two hand-written implementations is a parity liability rather than a feature. Blank lines and `#` comments are skipped. `*` matches a run of non-separator characters, `**` matches across separators, `?` matches one non-separator character. A leading `/` anchors to the top level of the candidate path as it was given, not to the ignore file's own directory, which is what keeps the rule the same for an `--exclude` glob that has no ignore file behind it; without it a pattern matches at any depth. A trailing `/` restricts to directories. A leading `!` negates, and the last matching pattern wins. Character classes are excluded from the subset.

Nested per-directory ignore files are deferred. Git supports them, and supporting them means specifying precedence between levels in a way both implementations must agree on — worth doing deliberately later, not smuggled in now.

Expand Down
Loading