Skip to content
claudewheel.vertical_viewport
Edit
On this page

Places a window over a column of variable-height blocks: centred on the focused row, clamped at both ends, reporting what each edge cuts off.

#claudewheel.vertical_viewport

#claudewheel.vertical_viewport

Scroll a column of variable-height row blocks, as arithmetic over dimensions.

This is the vertical mirror of the renderer's horizontal viewport (:meth:claudewheel.renderer.Renderer._compute_viewport), and it keeps that one's rule: when the content does not fit, the window is centered on the focused item and then clamped to the content, so scrolling is a function of the focus alone and nothing has to be remembered between frames.

Two deliberate differences from the horizontal original:

  • It is pure. The horizontal version reads self.term.cols in the middle

of its arithmetic, so it cannot be exercised without a terminal object. Here every dimension -- the row heights and the window height -- is a parameter, and the result is a plain value.

  • Rows have heights. A horizontal segment occupies one screen row; a

session block occupies two or three lines collapsed and five when highlighted, so the arithmetic runs over cumulative line offsets rather than a single row index, and the focused row may itself be taller than the whole window. When it is, its top is pinned to the top of the window: centering a block that cannot fit would cut off the line carrying its name.

The result reports one :class:RowSlice per row with any visible line, including the partially visible rows at each edge, and says how many lines of each were cut. It never decides what to do about a partial row -- drawing it clipped or dropping it is the screen's choice, and both are expressible from the same result.

#RowSlice

The visible part of one row block.

screen_top is window-relative (0 is the window's first line); skip_top counts the row's own leading lines that fall above the window, and lines how many of its lines are visible.

#skip_bottom

python
def skip_bottom(self) -> int

The row's own trailing lines that fall below the window.

#clipped

python
def clipped(self) -> bool

True when some of the row's lines are outside the window.

#Viewport

Where the window sits over the content, and what it shows.

start is the first visible content line, height the window as the caller declared it, and total the summed height of every row.

#scrolling

python
def scrolling(self) -> bool

True when the content is taller than the window.

#row_tops

python
def row_tops(row_heights: Sequence[int]) -> tuple[int, ...]

The content line each row starts at, one entry per row.

#_start_line

python
def _start_line(row_heights: Sequence[int], tops: Sequence[int], focus_idx: int, window_height: int) -> int

The first visible content line, by the centering rule described above.

#compute_viewport

python
def compute_viewport(row_heights: Sequence[int], focus_idx: int, window_height: int) -> Viewport

Place a window_height-line window over rows of the given heights.

The window is centered on the row at focus_idx and clamped to the content; a focused row taller than the window has its top pinned instead. A focus_idx naming no row, and a window with no lines, both leave the window at the top. Negative heights are a caller bug and raise.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • selfdoc Static Site Generator that builds a project's documentation site directly from its source code, so the docs can never drift from the code they describe, with SEO/AEO, first-class blog, search, and cross-project linking built in
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search