Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #761 +/- ##
=======================================
Coverage 52.37% 52.37%
=======================================
Files 26 26
Lines 3729 3729
Branches 747 747
=======================================
Hits 1953 1953
Misses 1472 1472
Partials 304 304 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
tony
force-pushed
the
example-style
branch
7 times, most recently
from
October 4, 2026 20:07
252dc6e to
b00f03f
Compare
why: The capture-pane example carried `# doctest: +SKIP`, which WRITING.md bans: it rendered a prompt and output that nothing ever checked. Waiting for the echoed line and asserting it makes the quickstart's capture step a real test. A planted absent string fails with WaitTimeout. what: - Replace the skipped capture with retry_until on capture_pane() - Keep the sample capture beside it as a text fence, so a reader still sees what capture_pane() returns
why: The install commands and the two from_*_id examples ran past 80 columns. what: - Split the pip and uv trunk-install commands with `\`, one option per continuation line, and quote the pip URL - Name the new window and pane ids before passing them to Window.from_window_id and Pane.from_pane_id
why: Two new_window calls and the retry_until_success signature ran past 80 columns in the rendered block. what: - Pass the window name to new_window by position in the timeout and cleanup demos - Shorten the retry_until_success parameter `success_marker` to `marker` so its signature fits on a line
why: The comment under the innermost `with` ran past 80 columns. It said "Everything is cleaned up automatically when exiting contexts", which the prose below the block already states. what: - Reword to "Exiting the contexts cleans everything up"
why: Four link-window setups repeated a 78-column call split across
three lines, and several expected reprs listed the full Session(...)
tail. The repeated target and the long reprs hid the lookup being
taught.
what:
- Bind `target = f"{guest.session_id}:"` once per example and call
link-window on one line
- Bind `name` for the exact-lookup equivalence example and drop the
doctest directive the global flags already cover
- Bind `same` before comparing window ids in the from_window_id example
- Bind the istartswith and `in` results and list their window names
instead of printing full reprs, which asserts the exact windows and
fits on a line
why: The set_hook calls carried a trailing `# doctest: +ELLIPSIS` that pushed them past 80 columns, though Session(...) already matches under the global ELLIPSIS flag. what: - Name hook_command before the session-renamed set_hook call - Drop the per-line ELLIPSIS directives, which lets the two after-split-window set_hook calls fit on one line
why: The two Pane.resize calls were 102 and 105 columns wide with a trailing directive the global ELLIPSIS flag makes redundant. what: - Bind the Up and Left directions before the Pane.resize calls - Drop the per-line ELLIPSIS directives
why: The holders set comprehension ran past 80 columns. what: - Bind worker_panes, then build holders from it
why: The window-name results printed every Session($... ...) tail, which ran the lines to 100 columns and buried the window names the example shows. One comment trailed the new_session call. what: - Bind the startswith, contains, istartswith and regex results and list their window names instead of printing full reprs, which asserts the exact windows and fits on a line - Drop the trailing comment on new_session; the lead-in sentence "First, create a test session" already says it - Drop per-line ELLIPSIS directives where the global flag applies
why: The v-split new_window call, the pane-grid split and the create_pane_grid call each passed 80 columns. what: - Pass the window name to new_window and the arguments to create_pane_grid by position - Bind `source` for the grid split so the split call fits on a line
why: parse_lookup, the QueryList example data and QueryList.get had doctest lines over 80 columns. what: - Bind `obj` for the parse_lookup call and break the dict argument of the QueryList example - Expand the two nested `foods` dicts in the QueryList data, one key per line - Bind `rows` before building the QueryList in the get example
why: The tmux_cmd new-session example was 85 columns wide. what: - Bind the socket flag as `socket_flag` before the tmux_cmd call
why: Two doctests in _is_target_not_found_error and _best_winlink ran past 80 columns. what: - Bind `stderr` (and `missing` for the connection error) before each _is_target_not_found_error call - Bind `rows` before calling _best_winlink
why: The Pane.split full-window example was 88 columns wide, and the 83-column capture_pane example carried a `+NORMALIZE_WHITESPACE` directive the global doctest flags already provide. what: - Bind `above` for PaneDirection.Above so the top_pane split fits on a line - Drop the redundant directive from the print(capture_pane()) example
why: The fixture docstrings re-read the doctest examples with a 88-column line in three places, and the server example shadowed `session` inside a comprehension. what: - Bind `examples` from the pytest item before slicing it into source in the server, session_params and session fixtures - Rename the comprehension variable to `s` in the server fixture's sample test so it no longer shadows `session`
why: The from_window_id and from_pane_id examples, the control-mode send-keys examples and the search_sessions example ran past 80 columns, two of them by splitting a call mid-argument. what: - Bind `new_id` and pass it to Window.from_window_id and Pane.from_pane_id - In the control-mode examples bind `client`, then `show`, so the send-keys and show-options calls fit - Bind `pattern` for the search_sessions filter
why: The search_windows filter and the from_window_id example ran past 80 columns. what: - Bind `pattern` for the search_windows filter - Bind `new_id` and pass it to Window.from_window_id
why: Five doctests in Window ran past 80 columns. what: - Pass the server and window id to Window.from_window_id by position - Bind `source` for the link-window call - Bind `names` for the linked_sessions comparison - Bind `new_id` and pass it to Pane.from_pane_id - Bind `windows` before filtering for the active window
tony
force-pushed
the
example-style
branch
4 times, most recently
from
October 4, 2026 22:58
4caecb3 to
7bedca6
Compare
tony
force-pushed
the
example-style
branch
11 times, most recently
from
October 11, 2026 16:26
0fcfa2c to
192f1e2
Compare
why: The explode_complex doctests carried a status-format literal of
over 1,500 characters, written out twice (input and expected value),
plus terminal-features expectations broken mid-dict. A reader could not
see what the example demonstrates: an array option parsed into indexed
entries.
what:
- Rebuild the status-format example from two short named fragments,
`left` and `centre`, joined into option text with an f-string and
compared against the same fragments, so the expected value cannot
drift from the input. It keeps indexes 0 and 1 and the #[...] and
#{...} syntax, but no longer round-trips tmux's full default
status-format string
- Break the terminal-features expected dict one key per line, and bind
`features` and `sparse` for the two array inputs; the sparse result is
still compared with a SparseArray literal
- Bind `raw` once for the two _show_option_raw assertions
why: Three fenced Python examples ran 81 to 90 columns. A trailing comment, a three-name import, and a call with a long keyword argument caused it. what: - Shorten the "Live" comment in the client snapshot example - Parenthesize the libtmux.test.random import, one name per line - Break the resize_pane call after its opening parenthesis
why: Example width, placement of comments and what may not be wrapped were unwritten, so each page drifted its own way. what: - Add the shared example rules to "Documented examples that run" - Add "In this repository" in the shared four-bullet shape: the hard limit and the width check command, the surfaces no formatter touches, the markers that decide what runs or is exempt, and the output and copied blocks that never break - Add a Bad and Good pair from a doctest line the example commits fitted
why: An agent editing a doctest or Markdown code block was not sent to the example rules. what: - Add code examples to the WRITING.md routing line - Link the "Documented examples that run" section
tony
force-pushed
the
example-style
branch
14 times, most recently
from
October 11, 2026 23:54
694b241 to
11609c0
Compare
why: Examples render in fixed-width boxes that scroll sideways, and nothing enforced a limit. Doctest lines and fenced blocks accumulated past 80 columns. A libtmux.org code block holds 78 columns at 1024 px (Firefox, WebKit, CI's Chrome) and 99 at 1440 px (Firefox, WebKit); libtmux/docs#101 sizes the code font so 80 columns fit from 1024 px up. ruff cannot enforce this. ruff 0.16.9 formats docstring code only when `docstring-code-format` is on, and the option was rejected after a probe: it parsed a `::` literal block in src/libtmux/options.py as Python and rewrote the tmux option text `visual-activity* on` to `visual - activity * on`. The formatter cannot tell a literal block from code, so it corrupts documented output. Markdown fences are outside ruff's Python formatting entirely. https://github.com/astral-sh/ruff/blob/0.16.9/docs/formatter.md#docstring-formatting Alternatives considered: - ruff E501: already on (`extend-select` includes `"E"`), but it measures 88 columns and reads only .py files, never Markdown fences - hand review: the limit drifted before this commit, so it needs a gate what: - Add scripts/check_example_width.py and .github/example-width.toml, which reads every `**/*.md` page plus MIGRATION and CHANGES, and the doc comments under src/ - No `examples/` directory and no exclusions; the one [[allow]] entry is the deliberately wide Bad line in the WRITING.md port block - Record checker_digest from `--digest`, and shared_digest, the --digest of WRITING.md's shared section, so a local edit to it fails the check - Run its self-test and the check in tests.yml beside the ruff steps, add a check-example-width just recipe, and list it in CONTRIBUTING - Exclude scripts/ from mypy, which targets 3.10 while the script needs tomllib (3.11+)
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Doctests and README fences in this repository now follow the shared libtmux example rules, which hold examples to 80 columns. ruff cannot hold that limit, so a stdlib Python check holds it in CI; the commits before it fix every line it reported. Merge after libtmux/docs#101 deploys: it makes 80 columns fit a libtmux.org code block from 1024 px up. Run against origin/master, the checker reports 68 lines over 80 in 19 files. The README capture example also loses its
# doctest: +SKIP, which WRITING.md bans, and becomes a real test.What changed
Policy
.github/WRITING.mdgains the shared example rules as subsections inside## Documented examples that run(CONTRIBUTING links its anchor), plus an "In this repository" block:ruff formatand E501 at ruff's default 88, reading.pyonly, docstring code anddocs/*.mddoctests unformatted,+HIDElines skipped by the width check, and expected doctest output never wrapped (ELLIPSISis global, so a long repr is trimmed with...).AGENTS.mdroutes code examples to that section.Tooling
scripts/check_example_width.pyand.github/example-width.tomlread every**/*.mdpage plusMIGRATIONandCHANGES, and the doc comments undersrc/. No excludes. One[[allow]]entry: the deliberately wide Bad line in WRITING.md's port block.tests.ymlbeside the ruff steps; acheck-example-widthjust recipe and a CONTRIBUTING entry document it.scripts/is excluded from mypy, which targets 3.10 while the script needstomllib(3.11+).Examples
Test the capture examplereplaces the skipped README capture withretry_untiloncapture_pane()and keeps the sample capture beside it as atextfence.Evidence
docstring-code-formatis on (formatter docs). A probe rejected turning it on: it parsed a::literal block insrc/libtmux/options.pyas Python and rewrote the tmux option textvisual-activity* ontovisual - activity * on, and it lengthened doctest lines past 80. Markdown fences are outside ruff's Python formatting entirely..pyonly).WaitTimeout.How to verify
$ python3 scripts/check_example_width.py --self-test$ python3 scripts/check_example_width.py$ uv run ruff check .$ uv run pytest README.md docs src/libtmux