The code text uses the glossary words in more places
A final pass over the docstrings and comments: "the own X of Y" is now "Y's own X" (84 places), a navigation entry is a screen on the stack, our node is our node, a paint is a paint, the quoted UX labels are in code font, and a list of punctuation glyphs is in code font. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
bc51115d24
commit
efc02ddced
51 files changed
+116
-116
No files matched your search
+2
-2
@@ -74,7 +74,7 @@ class _GlobalOptionsAnywhere(TyperGroup):
|
||||
|
||||
|
||||
def _globals_first(group: TyperGroup, args: list[str]) -> list[str]:
|
||||
"""``args`` with the own options of ``group`` moved ahead of the subcommand.
|
||||
"""``args`` with the options of ``group`` itself moved ahead of the subcommand.
|
||||
|
||||
The function finds an option, and tells it from an argument, because the option has
|
||||
``is_flag``. Typer includes its own copy of Click, so there is no ``click.Option`` that
|
||||
@@ -219,7 +219,7 @@ def main_callback(
|
||||
spi: Select the radio on the SPI bus of this machine. MeshTerm itself runs the node.
|
||||
mock: Whether to use the simulator instead of real hardware.
|
||||
db_path: Override the location of the database. If it is not set, a ``--mock`` run
|
||||
stores to the own database of the simulator and not to the real history.
|
||||
stores to the simulator's own database and not to the real history.
|
||||
json_output: Print the answer as JSON instead of aligned text.
|
||||
absolute: Print times as ISO-8601 instants instead of relative ages, for this run.
|
||||
quiet: Suppress console logging (logging to the file continues).
|
||||
|
||||
@@ -3789,7 +3789,7 @@ class MeshCoreDevice(Device):
|
||||
path_bytes = bytes.fromhex("".join(hops))
|
||||
flags = path_hash_flags(len(bytes.fromhex(hops[0]))) or 0
|
||||
else:
|
||||
# No forced path: build a path that ends at the own hash of the target (with
|
||||
# No forced path: build a path that ends at the target's own hash (with
|
||||
# any learned ``out_path`` repeaters before it), because a trace replies only
|
||||
# when its destination is the last hop. It is ``None`` only when the contact
|
||||
# is unknown, and then the trace runs without a path.
|
||||
@@ -3888,7 +3888,7 @@ class MeshCoreDevice(Device):
|
||||
repeaters to mirror, so the outbound leg is the full path).
|
||||
* learned multi-hop route → ``[repeater…, destination, repeater… (reversed)]``.
|
||||
|
||||
Each hash is encoded again at the own width of the trace (``1 << flags``, only
|
||||
Each hash is encoded again at the trace's own width (``1 << flags``, only
|
||||
1/2/4/8 bytes). This changes the routing width of a region (for example 3) to the
|
||||
widest value that the trace can represent (2). The firmware matches by hash
|
||||
prefix, so a narrower prefix still addresses the same node.
|
||||
@@ -3931,7 +3931,7 @@ class MeshCoreDevice(Device):
|
||||
route = bytes.fromhex(out_path)[: out_path_len * size]
|
||||
repeaters = [route[i * size : i * size + trace_size] for i in range(out_path_len)]
|
||||
dest = bytes.fromhex(pub)[:trace_size]
|
||||
# The outbound leg always ends at the own hash of the destination, so the
|
||||
# The outbound leg always ends at the destination's own hash, so the
|
||||
# destination recognizes the trace and replies. The return leg mirrors the same
|
||||
# repeaters back to us, because nothing sends the packet back automatically.
|
||||
path_bytes = b"".join(repeaters) + dest + b"".join(reversed(repeaters))
|
||||
|
||||
@@ -441,7 +441,7 @@ def _lookup(name: str, *, source: str) -> Platform:
|
||||
return _BY_NAME[name.strip().lower()]
|
||||
except KeyError:
|
||||
choices = ", ".join(sorted(_BY_NAME))
|
||||
# Plain ASCII. This error can come through the own error path of Typer and Click.
|
||||
# Plain ASCII. This error can come through the error path of Typer and Click themselves.
|
||||
# They raise it before make_console() sets stdout and stderr to UTF-8. On a legacy
|
||||
# Windows console, this damages non-ASCII text, as the docstring of make_console
|
||||
# warns.
|
||||
|
||||
@@ -98,7 +98,7 @@ def report_shift(down: bool) -> None:
|
||||
if callback is not None:
|
||||
try:
|
||||
callback()
|
||||
except Exception: # noqa: BLE001 - a repaint hiccup must not break the host's input
|
||||
except Exception: # noqa: BLE001 - a paint problem must not break the input of the host
|
||||
pass
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ def start(on_change: Callable[[], None], keyboard: str) -> bool:
|
||||
_shift_down = now
|
||||
try:
|
||||
on_change()
|
||||
except Exception: # noqa: BLE001 - a repaint hiccup must not kill the watch
|
||||
except Exception: # noqa: BLE001 - a paint problem must not stop the watch
|
||||
pass
|
||||
|
||||
_thread = threading.Thread(target=_watch, name="modifier-watch", daemon=True)
|
||||
|
||||
@@ -9,7 +9,7 @@ touches the radio or the database. Thus a page reads the same when no device is
|
||||
|
||||
Unlike each other screen in the app, these pages are **written** and not composed. Their
|
||||
content is markdown. It is in ``meshterm/assets/pages``, beside the wordmark.
|
||||
:mod:`meshterm.ui.markdown` draws it in the own visual language of the app (refer to that
|
||||
:mod:`meshterm.ui.markdown` draws it in the app's own visual language (refer to that
|
||||
module for what each construct becomes). To fill in a page, edit its ``.md`` file. No
|
||||
screen, menu row, or CLI face must follow. Everything that markdown offers is available:
|
||||
sections, sub-headings, lists, quotes, links, and tables.
|
||||
|
||||
@@ -187,7 +187,7 @@ def rule_caption(*, full: bool) -> str:
|
||||
A bordered frame already has a rule under the body, and the rule only closes the box. A
|
||||
caption in it is the cheapest place for the credit. It uses no cell of the drawing and
|
||||
no cell of a line that the app used for other content. The frame renders the caption
|
||||
right-justified through the own subtitle machinery of Rich
|
||||
right-justified through Rich's own subtitle machinery
|
||||
(:func:`~meshterm.ui.tui.frame._panel_box`). Thus it lands as
|
||||
``──── © OpenStreetMap ─╯``: one rule cell before the corner, as a title sits in the top
|
||||
rule.
|
||||
|
||||
@@ -338,7 +338,7 @@ async def write_channel(
|
||||
edit, reorder, and clear all come here. Thus the channel store is a true record of what
|
||||
MeshTerm wrote (refer to :mod:`meshterm.core.channel_store`). If the user clears a slot
|
||||
(an empty ``name``), the store forgets it. Any other write makes the store remember the
|
||||
channel under the own public key of the device. For a channel whose key comes from its
|
||||
channel under the device's own public key. For a channel whose key comes from its
|
||||
name, the store keeps that derived key, so that it can be sent again as it is. The
|
||||
remembering is a best effort. It never blocks the real write to the device, and it never
|
||||
makes the write fail.
|
||||
@@ -449,8 +449,8 @@ class _LiveStats:
|
||||
arrives while the manager is open, the counts, the age, and the sparkline of that
|
||||
channel update in place. But the code queries the repository at most one time for each
|
||||
``ttl`` seconds, and not one time for each row at each paint. Thus a full slot table
|
||||
stays cheap at the repaint of the session, which is approximately 1 Hz. The TTL is
|
||||
*higher* than that repaint period on purpose. If the TTL was exactly the tick rate,
|
||||
stays cheap at the paint rate of the session, which is approximately 1 Hz. The TTL is
|
||||
*higher* than that paint period on purpose. If the TTL was exactly the tick rate,
|
||||
each idle frame would still cause one repository query, and the throttle would limit
|
||||
nothing.
|
||||
"""
|
||||
|
||||
@@ -31,7 +31,7 @@ count that is worth a lane. What it does have, the time that it left, has no col
|
||||
To remove *one* named contact for good belongs to that contact and not to the list. It is
|
||||
the last action on the Node detail page of the contact, where the user already looks at
|
||||
the node that the user wants to remove. That action is a real deletion. It goes to both
|
||||
halves of what the list shows: the own table of the device and the store that lasts
|
||||
halves of what the list shows: the device's own table and the store that lasts
|
||||
between sessions (refer to :mod:`~meshterm.core.contact_store`). Thus a bridge with no
|
||||
firmware does not merge the contact back. In both cases, only the *contact* goes. MeshTerm
|
||||
does not change the reception history and the overheard traffic of each node.
|
||||
|
||||
@@ -506,7 +506,7 @@ async def _pick_schedule(ctx: AppContext, name: str):
|
||||
"""Float the picker for when to send. Return an aware UTC time, ``None``, or a cancel.
|
||||
|
||||
``None`` means "no schedule, send on the next sign of life" (the explicit
|
||||
*When it's next heard* row). An aware UTC datetime means that the message waits until
|
||||
``When it's next heard`` row). An aware UTC datetime means that the message waits until
|
||||
that time. :data:`CANCEL_SCHEDULE` means that the user went back, and the code must not
|
||||
queue anything.
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class DeviceInfoScreen(ScrollScreen):
|
||||
|
||||
@property
|
||||
def picocalc_lyra_lane(self):
|
||||
"""The shared pager, and the reveal on F3, which is the own verb slot of this screen.
|
||||
"""The shared pager, and the reveal on F3, which is this screen's own verb slot.
|
||||
|
||||
The chip is the only place where the user of a PicoCalc can learn that the key
|
||||
exists. It names the action and not its object: ``Reveal`` while the PIN is masked,
|
||||
|
||||
+1
-1
@@ -216,7 +216,7 @@ def _state_intensity(row: str) -> str:
|
||||
fg = next((p for p in parts if _DIM_FG.fullmatch(p)), None)
|
||||
if fg is None:
|
||||
# A bare "1" has nothing more to say when brightness travels as a colour. If
|
||||
# the code removes it, bold stays off the glyphs that a terminal can redraw at
|
||||
# the code removes it, bold stays off the glyphs that a terminal can draw again at
|
||||
# another weight.
|
||||
kept = [p for p in parts if p != "1"]
|
||||
# But the brightness that it announced applies to the colour that is in force
|
||||
|
||||
+3
-3
@@ -803,7 +803,7 @@ async def _menu_loop(ctx: AppContext, session: TuiSession) -> None:
|
||||
it for all of the session. Thus the highlight, a typed filter, and the scroll offset
|
||||
are still there when a tool closes. No ``default=`` restore is necessary, and such a
|
||||
restore could only recover the highlight. The menu is also where the pop-all key goes:
|
||||
^W raises :class:`~meshterm.ui.tui.screen.PopToMenu` through each stack frame that the
|
||||
^W raises :class:`~meshterm.ui.tui.screen.PopToMenu` through each screen on the stack that the
|
||||
user opened, and this is the one place that catches it.
|
||||
|
||||
The menu is still popped while a full-screen tool runs (only a ``popup`` tool shows
|
||||
@@ -811,7 +811,7 @@ async def _menu_loop(ctx: AppContext, session: TuiSession) -> None:
|
||||
all cases. The screen object stays after the pop, and that is why a return feels like
|
||||
a pop and not like a rebuild. The screen object is also what the lead-in question of
|
||||
a tool shows over. The menu is declared as the root of the session, so it is the base
|
||||
that is pushed under a dialog that is otherwise the only stack frame
|
||||
that is pushed under a dialog that is otherwise the only screen on the stack
|
||||
(``TuiSession._floated``). Thus a dialog always shows around it the page from which
|
||||
the user opened it. For the same reason, the root stays declared while the loop
|
||||
exits, because the reconnect dialog draws over it. The next menu declares itself.
|
||||
@@ -843,7 +843,7 @@ async def _menu_loop(ctx: AppContext, session: TuiSession) -> None:
|
||||
except _Quit:
|
||||
return
|
||||
except PopToMenu:
|
||||
# ^W from a deep screen. Each stack frame between there and here has already
|
||||
# ^W from a deep screen. Each screen on the stack between there and here has already
|
||||
# popped itself. The only remaining step is to disarm and paint the menu that
|
||||
# the user asked for.
|
||||
session.unwound()
|
||||
|
||||
@@ -1245,7 +1245,7 @@ def _located(lat: float | None, lon: float | None) -> bool:
|
||||
async def open_node_detail(
|
||||
ctx: AppContext, contact: Contact | None, *, manage: bool = True
|
||||
) -> bool:
|
||||
"""Open the Node detail page for a contact (or our own node) and run its action loop.
|
||||
"""Open the Node detail page for a contact (or our node) and run its action loop.
|
||||
|
||||
The function assembles the page from the stored history, the contacts of the device,
|
||||
and the observed topology: the identity, the reception statistics, a location preview,
|
||||
@@ -1277,7 +1277,7 @@ async def open_node_detail(
|
||||
|
||||
Args:
|
||||
ctx: The shared application context (the interactive TUI must be running).
|
||||
contact: The contact to show, or ``None`` for our own node (a page of identity and
|
||||
contact: The contact to show, or ``None`` for our node (a page of identity and
|
||||
ledger only, because our node never overhears itself, so there is no reception
|
||||
history to show).
|
||||
manage: Whether to show the contact-management actions (lock, archive, restore,
|
||||
@@ -1313,7 +1313,7 @@ async def open_node_detail(
|
||||
|
||||
you = contact is None
|
||||
|
||||
# -- our own node, for the "us" label, the centre of the location preview, and the range
|
||||
# -- our node, for the "us" label, the centre of the location preview, and the range
|
||||
# and bearing.
|
||||
try:
|
||||
info = await ctx.devstate.self_info()
|
||||
@@ -1526,7 +1526,7 @@ async def open_node_detail(
|
||||
info_actions.append(_Action("regions", "🔖", "", "Ask which regions it carries"))
|
||||
# -- contact management: the last group of the page, and the only actions that end the
|
||||
# visit. None of them shows when the caller opened the page to look, not to act (refer
|
||||
# to ``manage``). They never show for our own node, or for a contact with no key at
|
||||
# to ``manage``). They never show for our node, or for a contact with no key at
|
||||
# all, because the write has nothing to use as its address.
|
||||
archived = manage and _is_archived(ctx, contact, self_key)
|
||||
manageable = (
|
||||
|
||||
@@ -582,7 +582,7 @@ def render_path_graph(
|
||||
|
||||
# When one path has more emphasis than the rest, all that is not on it is dim. The nodes
|
||||
# of the emphasized path keep their hue, and each other marker and label draws in the
|
||||
# :data:`_OFF_ROUTE` grey. The membership test uses the own id space of the graph (after
|
||||
# :data:`_OFF_ROUTE` grey. The membership test uses the graph's own id space (after
|
||||
# the prefix coalesce, the identical-path collapse, and the revisit split). Thus a relay
|
||||
# that the selected route reaches by a short hash still counts as on the route, after it
|
||||
# is folded into the wide marker that is drawn for it.
|
||||
|
||||
+15
-15
@@ -124,7 +124,7 @@ from .theme import DIM_TWIN, active_theme, node_style, slot_hex
|
||||
POWERLINE_SEP = "\ue0b0"
|
||||
|
||||
#: The thin right-pointing chevron (U+E0B1). It is the outline sibling of the solid point,
|
||||
#: in the same core set. It is the own mark of powerline for a join *inside* one colour. It
|
||||
#: in the same core set. It is powerline's own mark for a join *inside* one colour. It
|
||||
#: draws the seam between two chips whose fills the eye cannot tell apart
|
||||
#: (:meth:`PathLine._seam`). It is the previous fill, shaded, and drawn on the next chip,
|
||||
#: where a solid point disappears.
|
||||
@@ -138,7 +138,7 @@ POWERLINE_ROUND_OPEN = ""
|
||||
POWERLINE_ROUND_CLOSE = ""
|
||||
|
||||
#: Our node, where a surface asks for it without its name and hash (``bare_self``): the
|
||||
#: ``★`` of the app. It is the own marker of the map, taken from
|
||||
#: ``★`` of the app. It is the map's own marker, taken from
|
||||
#: :data:`~meshterm.ui.marks.SELF_MARK`. Thus the star in a route and the star on the map
|
||||
#: can never be different, in glyph or in hue.
|
||||
SELF_GLYPH, _SELF_INK = SELF_MARK
|
||||
@@ -249,7 +249,7 @@ _ELLIPSIS = "…"
|
||||
ACTION_MARK = " …"
|
||||
|
||||
#: What a *chip* line uses to cut instead (JP, 2026-08-09): the half block. It is drawn in
|
||||
#: the own fill of the cut chip, with no background. Thus the cell is half segment and
|
||||
#: the cut chip's own fill, with no background. Thus the cell is half segment and
|
||||
#: half bare page. The chip breaks off in the middle of its body, and the crack says that
|
||||
#: it is incomplete. An ellipsis says the opposite: that a *word* was made shorter, when
|
||||
#: what ran out is the lane. :data:`CRACK_TAIL` closes a line past which the path runs on
|
||||
@@ -358,7 +358,7 @@ def _style_hex(style: str) -> str | None:
|
||||
#: across the greens and ``0.165`` across the cyans. The wheel is not uniform to the eye.
|
||||
#: Thus a gap of hue blurred too little there and too much here. An sRGB distance only
|
||||
#: restates the hue gap (a fixed step of one byte is a near-constant ``55`` to ``60`` of 8-bit
|
||||
#: RGB all the way round). Then JP set the value by eye, on a ladder of the own pairs of the
|
||||
#: RGB all the way round). Then JP set the value by eye, on a ladder of pairs from the
|
||||
#: spectrum, drawn in both ways (JP, 2026-09-16). The value is where the solid point is not
|
||||
#: only visible at one cell, but the user *finds* it without a search: ``0.06``, which is
|
||||
#: three differences that the user can see. A tighter value (``0.035``) left wedges that
|
||||
@@ -510,7 +510,7 @@ def hops_atom(count: int) -> Text:
|
||||
2026-08-10). The picture above encodes this number but never states it. Users often
|
||||
compare two routes by this number, and without it the user must count the chips. The
|
||||
text is ``direct`` where there are no hops. A path with no relays is not "0 hops". It
|
||||
is the own word of the app for a packet that went straight there (the ``empty`` note
|
||||
is the app's own word for a packet that went straight there (the ``empty`` note
|
||||
of :class:`PathLine` says the same).
|
||||
|
||||
Args:
|
||||
@@ -641,7 +641,7 @@ class PathLine:
|
||||
Each continuation starts with ``indent`` spaces, plus :data:`WRAP_OFFSET`. This step
|
||||
makes a fold clear as a fold. Each line fits in ``width``.
|
||||
|
||||
Plain-mode lines that continue end with the own mark of the separator: a trailing
|
||||
Plain-mode lines that continue end with the separator's own mark: a trailing
|
||||
``→`` for a path that arrows join, or the bare ``,`` for a wire spec that commas
|
||||
join. This is the cue "the path goes on". Chip lines always close with their pointed
|
||||
edge. From the second line down, they open when they draw again the seam that the
|
||||
@@ -667,7 +667,7 @@ class PathLine:
|
||||
return [Text(self._empty, style="muted")]
|
||||
budget = max(1, width - indent)
|
||||
plain = self._resolved_mode() != "powerline"
|
||||
# The continuation cue is the own mark of the separator, without the space where the
|
||||
# The continuation cue is the separator's own mark, without the space where the
|
||||
# next hop sat: " → " reads " →", and the "," of a wire spec stays ",".
|
||||
cue = self._separator.rstrip() if plain else ""
|
||||
groups = self._flow(self._hops, budget, plain, len(cue), 0)
|
||||
@@ -912,8 +912,8 @@ class PathLine:
|
||||
answered it fold in the same place, the two readings of one route look like one
|
||||
route. In both cases, the fold needs real legs on both sides, with at least two hops
|
||||
each. Thus a path whose only faded tail is the automatic return to us never leaves
|
||||
that hop as a widow on a line of its own. That single hop marks no turn, and the own
|
||||
mirror of the walk can still name one.
|
||||
that hop as a widow on a line of its own. That single hop marks no turn, and the walk's
|
||||
own mirror can still name one.
|
||||
"""
|
||||
seam: int | None = len(self._hops)
|
||||
while seam and self._hops[seam - 1].dim:
|
||||
@@ -1039,8 +1039,8 @@ class PathLine:
|
||||
closes on the point. This is the same cue "goes on" that arrow mode spells with a
|
||||
trailing ``→``.
|
||||
|
||||
An end that really is the own end of the route opens or closes **rounded**. Where the
|
||||
font has no rounded caps, it is **square**: the own pad of the chip is the edge, and
|
||||
An end that really is the route's own end opens or closes **rounded**. Where the
|
||||
font has no rounded caps, it is **square**: the chip's own pad is the edge, and
|
||||
the function appends nothing. A square end is not a degraded cap. It is the one shape
|
||||
that is left that says *stop*. The point is the continuation cue. Thus, when a
|
||||
finished path closed on a point, it claimed that a hop was cut off (JP, 2026-09-09).
|
||||
@@ -1113,8 +1113,8 @@ class PathLine:
|
||||
equality, and it is not a gap of hue.
|
||||
|
||||
There the seam is the **thin** chevron, :data:`POWERLINE_THIN`. It is drawn on the
|
||||
fill ahead, in the colour of the label of the previous chip. It is the own mark of
|
||||
powerline for a join inside one colour, and the chip to which it belongs draws a line
|
||||
fill ahead, in the colour of the label of the previous chip. It is powerline's
|
||||
own mark for a join inside one colour, and the chip to which it belongs draws a line
|
||||
on itself. Thus the ribbon continues without a break, and nothing on it is a colour
|
||||
that is not a colour of a chip. Before, the solid point that was drawn bare cut a
|
||||
wedge of page out of the route here. (A run of near hues read as dashes, and on a
|
||||
@@ -1139,7 +1139,7 @@ class PathLine:
|
||||
def _notch(fill: str) -> Text:
|
||||
"""The left edge of a chip: the point, cut inward out of its own fill.
|
||||
|
||||
Reverse video paints the notch in the own background of the terminal. This is the
|
||||
Reverse video paints the notch in the terminal's own background. This is the
|
||||
only way to name the colour of the page without knowing it. Thus nothing that is on
|
||||
the left of the chip (the taper of the previous chip, the line above a wrapped break)
|
||||
bleeds into it, and the point still faces the direction in which the path flows.
|
||||
@@ -1159,7 +1159,7 @@ class PathLine:
|
||||
"""One chip: the same words as in arrow mode, in the ink of the chip on its fill.
|
||||
|
||||
Each chip has padding on both sides, also the ``★`` (JP, 2026-08-09). The pads are
|
||||
not there to make room for a long *word*. They are the own shape of the chip. A star
|
||||
not there to make room for a long *word*. They are the chip's own shape. A star
|
||||
that is squeezed between two chevrons reads as a glyph that is wedged into the seam,
|
||||
and not as a segment of the route. The ink of our chip is the yellow of the map on
|
||||
the neutral dark grey :data:`_YOU_BG`. Thus the star in the line and the star on the
|
||||
|
||||
@@ -23,8 +23,8 @@ have to repeat the rules of the firmware to know that it works. For these reason
|
||||
action sends its one command, and the tree is drawn again from the reply
|
||||
(:meth:`~meshterm.core.region_admin.RegionTable.after`). The title counts the edits that are
|
||||
not yet saved. The page ends with the same Apply/discard pair that the editors use
|
||||
(:func:`~meshterm.ui.menus.exit_rows`), with words that fit this case: *Save n changes to
|
||||
the repeater* over *Back — a reboot undoes them*. If the user leaves with unsaved edits, the
|
||||
(:func:`~meshterm.ui.menus.exit_rows`), with words that fit this case: ``Save n changes to
|
||||
the repeater`` over ``Back — a reboot undoes them``. If the user leaves with unsaved edits, the
|
||||
page asks first. On firmware that has it, ``region default`` saves the whole table itself
|
||||
(:func:`~meshterm.core.region_admin.saves_table`), so the count also goes to zero there.
|
||||
|
||||
@@ -125,7 +125,7 @@ class RegionMenu(SelectScreen):
|
||||
"""The list of the region editor, with ``^R`` to read the table again.
|
||||
|
||||
This is a full-screen page and not a dialog. The user works in it for some time, and it
|
||||
is the own view of the tool for one repeater. Each question that it asks (the actions of
|
||||
is the tool's own view for one repeater. Each question that it asks (the actions of
|
||||
a region, a new name, a confirm) floats over it. ``^R`` is the *read again* chord of
|
||||
the admin page, and it is here for the same reason: the mesh gets the same question
|
||||
again. Here it reads the whole table again, which is the only read that exists.
|
||||
|
||||
@@ -257,7 +257,7 @@ class PlainRenderer(Renderer):
|
||||
# output where the exit status is the whole report.
|
||||
return None
|
||||
# Use a Text and not a markup string. The value can be a private key, a share
|
||||
# URL, or the own reply of a remote node. Rich would read a bracket in these
|
||||
# URL, or the reply of a remote node itself. Rich would read a bracket in these
|
||||
# values as a style tag.
|
||||
return Text(column.lanes[0].render(value))
|
||||
return script.pairs(facts_pairs(block))
|
||||
|
||||
@@ -320,7 +320,7 @@ async def _outcome(ctx: AppContext, room: Contact, login: RoomLogin, password: s
|
||||
async def _restore(ctx: AppContext, room: Contact, *, asked: bool = False) -> bool:
|
||||
"""Put a room that the radio forgot back in its contacts. Return ``True`` when it is there.
|
||||
|
||||
MeshTerm addresses a login through the own contact entry of the radio. Thus if MeshTerm
|
||||
MeshTerm addresses a login through the radio's own contact entry. Thus if MeshTerm
|
||||
still lists a room but the radio dropped it, the user cannot log in to the room until
|
||||
MeshTerm writes it back. This is the same one write that "add it back" makes for a
|
||||
direct message.
|
||||
|
||||
@@ -409,7 +409,7 @@ class PlainUi(Ui):
|
||||
(:func:`meshterm.ui.script.console`). Everything that a tool gives to it passes through
|
||||
:func:`~meshterm.ui.script.flatten` on the way out. Thus no border, no box, and no
|
||||
hoisted title reaches stdout. That fold is a safety net and not the design. The output
|
||||
that a script must read is *written* in the own vocabulary of the CLI (refer to
|
||||
that a script must read is *written* in the CLI's own vocabulary (refer to
|
||||
:mod:`meshterm.ui.script`).
|
||||
"""
|
||||
|
||||
|
||||
@@ -475,8 +475,8 @@ def _vscode_default_face() -> str:
|
||||
def _vscode_face(environ: Mapping[str, str], start: Path | None = None) -> str:
|
||||
"""The face that the integrated terminal of VS Code uses to render.
|
||||
|
||||
``terminal.integrated.fontFamily`` wins over ``editor.fontFamily`` (the own fallback
|
||||
of VS Code). For each key, the workspace file wins over the user file. The stored
|
||||
``terminal.integrated.fontFamily`` wins over ``editor.fontFamily`` (VS Code's own
|
||||
fallback). For each key, the workspace file wins over the user file. The stored
|
||||
value is a comma list in the CSS style, and MeshTerm judges the first family.
|
||||
"""
|
||||
paths = _vscode_settings_paths(environ, start)
|
||||
@@ -636,8 +636,8 @@ def _powerline_support(
|
||||
the process).
|
||||
conhost_probe: The function that reads the face of the classic console (a
|
||||
parameter, so that tests can replace it).
|
||||
handheld: The name and the glyph inventory of the platform, where the own font of
|
||||
a handheld draws the screen. ``None`` on a terminal.
|
||||
handheld: The name and the glyph inventory of the platform, where the font of
|
||||
a handheld itself draws the screen. ``None`` on a terminal.
|
||||
"""
|
||||
env = os.environ if environ is None else environ
|
||||
override = (env.get("MESHTERM_POWERLINE") or "").strip().lower()
|
||||
|
||||
@@ -451,7 +451,7 @@ MESH_THEME_16 = Theme(
|
||||
# partner of slot 6 is the brand). Links use the bright blue. The chrome (bullets,
|
||||
# rails, a struck-out run) uses the two greys. Thus a page reads as text with
|
||||
# landmarks and not as a colour chart. There is no underline anywhere. The VT
|
||||
# renders it with the own underline colour of the console, and this removes the hue
|
||||
# renders it with the console's own underline colour, and this removes the hue
|
||||
# of the link.
|
||||
"md.strong": "bold color(7)",
|
||||
"md.em": "not bold color(7)",
|
||||
@@ -480,7 +480,7 @@ def mark_rgb(colour: str) -> tuple[int, int, int]:
|
||||
is a theme style name (the node-type marks, which have names so that each platform
|
||||
chooses its own colour, refer to ``type.*`` of the theme).
|
||||
|
||||
On the 16-slot theme, a ``color(N)`` entry gives the own :data:`_VT_SLOTS` RGB of that
|
||||
On the 16-slot theme, a ``color(N)`` entry gives the :data:`_VT_SLOTS` RGB of that
|
||||
slot, and not the stock triple of Rich. The palette of Rich is a shade different from
|
||||
ours, and the quantizer of the fold matches against ours. If the function used the
|
||||
stock triple, the round trip would put the marker on a neighbouring slot. The
|
||||
@@ -586,7 +586,7 @@ _NODE_HUE_VAL = 0.95
|
||||
#: The same wheel at the resolution of the PicoCalc console: the six *chromatic bright*
|
||||
#: palette slots. They are in hue order, from red. Thus the index ``round(byte / 256 * 6)
|
||||
#: % 6`` is the sector in which the hue of the byte is. The sectors are 60° apart, and
|
||||
#: each is an equal sixth of the wheel. They are written as the own :data:`_VT_SLOTS` RGB
|
||||
#: each is an equal sixth of the wheel. They are written as the :data:`_VT_SLOTS` RGB
|
||||
#: values of the slots and not as ``color(N)``. Thus the value is still a hex that a
|
||||
#: caller can parse into an RGB (the map canvas and the mesh walk read the hue from the
|
||||
#: style string). Also, each downsample on the way out (the downsample of Rich, and
|
||||
|
||||
@@ -115,7 +115,7 @@ from .emoji_width import clusters
|
||||
_TEXT_GLYPHS: tuple[tuple[str, str], ...] = (
|
||||
("\x00", "\x7f"), # ASCII: each letter, digit, and escape byte in a composed row
|
||||
(" ", "ſ"), # Latin-1 + Latin Extended-A: an accented name, °, ·, ±
|
||||
("‐", "‧"), # General Punctuation: – — ‘ ’ “ ” • …
|
||||
("‐", "‧"), # General Punctuation: `– — ‘ ’ “ ” • …`
|
||||
("←", "↓"), # ← ↑ → ↓: the arrow atoms at the start of each footer hint
|
||||
("─", "╿"), # Box Drawing: each panel border and each rule
|
||||
("▀", "▟"), # Block Elements: the half blocks of the path line, and the splash art
|
||||
|
||||
@@ -643,8 +643,8 @@ async def open_tx_optimize(
|
||||
session = ctx.ui.session
|
||||
device = await ctx.device()
|
||||
# The contacts, the self-info, and the routing width come from the session cache (refer
|
||||
# to DeviceState). The code still keeps the live ``device`` for the own transmissions of
|
||||
# the sweep below.
|
||||
# to DeviceState). The code still keeps the live ``device`` for the transmissions of
|
||||
# the sweep itself below.
|
||||
contacts = await ctx.devstate.contacts()
|
||||
resolve = trace_runner.make_node_resolver(contacts)
|
||||
self_info = await ctx.devstate.self_info()
|
||||
|
||||
@@ -432,7 +432,7 @@ def revisit_note(
|
||||
The function takes the repeated hops and not the path itself. Thus the caller decides
|
||||
what "repeated" means for its surface. One path asks
|
||||
:func:`~meshterm.ui.pathgraph.revisited_hops`. A surface that draws a *fan* of paths
|
||||
must join the own revisits of each path. A hop that two different routes share is not
|
||||
must join each path's own revisits. A hop that two different routes share is not
|
||||
a revisit. If the surface pools their hops, it wrongly calls that hop a revisit.
|
||||
|
||||
Args:
|
||||
@@ -953,7 +953,7 @@ def node_marker(node_type: int | None) -> tuple[str, RGB]:
|
||||
"""The glyph and colour from the map palette for a node type, as a ``(glyph, rgb)`` pair.
|
||||
|
||||
These are the shared node-type marks (``▲`` repeater, ``■`` room, ``◉`` sensor, ``●``
|
||||
plain node) in the own colours of the map. This function makes them for a braille
|
||||
plain node) in the map's own colours. This function makes them for a braille
|
||||
raster, as :data:`NODE_GLYPHS` makes them for a Rich row. Thus a spatial drawing pins
|
||||
its nodes with the same glyphs and hues that the map and the list of nodes use. Both
|
||||
read the same ``type.*`` entry of the theme (here through
|
||||
|
||||
@@ -196,7 +196,7 @@ def _license_summary(dist: Distribution) -> str:
|
||||
|
||||
|
||||
def _dist_info_files(dist: Distribution) -> list[PackagePath]:
|
||||
"""Each file that RECORD lists under the own ``.dist-info`` directory of this distribution.
|
||||
"""Each file that RECORD lists under this distribution's own ``.dist-info`` directory.
|
||||
|
||||
The function uses :attr:`Distribution.files`. It does not use the private
|
||||
``Distribution._path`` that some tools use. Thus the function stays correct if a future
|
||||
|
||||
@@ -13,7 +13,7 @@ This script gives that explanation. It is standalone and uses only the standard
|
||||
the user can paste it onto any machine that runs any version of MeshTerm. It prints one
|
||||
verdict with the fix.
|
||||
|
||||
The script must run under the own interpreter of MeshTerm. This is the important point. A
|
||||
The script must run under MeshTerm's own interpreter. This is the important point. A
|
||||
Mac usually has three Pythons, and only one of them is the Python of the app. Only the
|
||||
certificate store of that Python is the store that the map uses. If another Python starts
|
||||
the script, the script finds the installed ``meshterm`` command and reads the interpreter
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# calculinux-console-font-6x8.sh -- build and install meshterm8.psf.gz, the 6x8 (53x40)
|
||||
# console font for the PicoCalc display.
|
||||
#
|
||||
# LICENCE -- READ THIS FIRST. The base bitmap that is embedded below is the own font_6x8
|
||||
# of the Linux kernel (lib/fonts/font_6x8.c), which is GPL-2.0. Thus this script is
|
||||
# LICENCE -- READ THIS FIRST. The base bitmap that is embedded below is the font_6x8
|
||||
# of the Linux kernel itself (lib/fonts/font_6x8.c), which is GPL-2.0. Thus this script is
|
||||
# GPL-2.0-only, and the PSF that it produces is GPL-2.0-only too. The full licence text is
|
||||
# beside this script, as scripts/picocalc-lyra/LICENSE.GPL-2.0. The rest of MeshTerm is
|
||||
# Apache-2.0, and it stays Apache-2.0. The file meshterm8.psf.gz that this script produces
|
||||
|
||||
@@ -1034,7 +1034,7 @@ def run_bridge(host: str, port: int, node_name: str) -> int:
|
||||
|
||||
# Prefer the hackergadgets meshcore_console helpers. They have the correct board pins and
|
||||
# the same node identity that the GUI uses. Fall back to a direct setup for a generic
|
||||
# install (a Waveshare HAT with a runtime from pip), or for the own venv of the bridge on
|
||||
# install (a Waveshare HAT with a runtime from pip), or for the bridge's own venv on
|
||||
# a host where the GUI package is older than the runtime.
|
||||
identity = None
|
||||
radio = None
|
||||
@@ -1135,7 +1135,7 @@ def run_bridge(host: str, port: int, node_name: str) -> int:
|
||||
}
|
||||
# Use the identity of the GUI first, in the place where the meshcore-uconsole stack
|
||||
# keeps it. Thus a bridge that runs from its own venv is the same node as the GUI.
|
||||
# Then use the own identity of the bridge.
|
||||
# Then use the bridge's own identity.
|
||||
xdg = Path(env("XDG_DATA_HOME") or (HOME / ".local" / "share"))
|
||||
for key_path in (
|
||||
xdg / "meshcore-uconsole" / "identity.key",
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ Windows Terminal (both can draw chips) or in a bare CI shell (which cannot). The
|
||||
assertions must not change with the terminal of the developer. ``MESHTERM_POWERLINE=0``
|
||||
is the supported way to fix the verdict. The suite clears the cached verdict around each
|
||||
test, so that the order of the tests has no effect. The tests that are specific to
|
||||
powerline pass explicit modes, or they patch the own switch of the widget with
|
||||
powerline pass explicit modes, or they patch the widget's own switch with
|
||||
``monkeypatch``.
|
||||
|
||||
``NO_COLOR`` depends on the environment in the same way. Rich obeys it: it removes colour
|
||||
@@ -94,7 +94,7 @@ def _reset_transmit_gate() -> Iterator[None]:
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _isolate_config_dir(tmp_path_factory: pytest.TempPathFactory) -> Iterator[None]:
|
||||
"""No test can reach the own ``~/.meshterm`` of the developer.
|
||||
"""No test can reach the developer's own ``~/.meshterm``.
|
||||
|
||||
``$MESHTERM_HOME`` moves the whole directory: the history, the caches of contacts and
|
||||
channels, the outbox, the stored admin passwords, the device profiles, the preferences,
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
"""Tests for the own BlueZ pairing of MeshTerm (PIN pairing on Linux through a D-Bus agent).
|
||||
"""Tests for MeshTerm's own BlueZ pairing (PIN pairing on Linux through a D-Bus agent).
|
||||
|
||||
The ``pair()`` of bleak for BlueZ never gives a PIN. BlueZ asks a pairing agent for the
|
||||
PIN, and bleak registers no agent. Thus a companion that has a PIN could not bond on Linux
|
||||
@@ -52,7 +52,7 @@ def test_status_names_read_as_words() -> None:
|
||||
assert bluez.status_name("org.bluez.Error.ConnectionAttemptFailed") == (
|
||||
"connection attempt failed"
|
||||
)
|
||||
# The bare Failed gives no information, so the own detail of BlueZ is added.
|
||||
# The bare Failed gives no information, so the detail of BlueZ itself is added.
|
||||
assert bluez.status_name("org.bluez.Error.Failed", ["le-connection-abort-by-local"]) == (
|
||||
"failed: le-connection-abort-by-local"
|
||||
)
|
||||
|
||||
@@ -109,7 +109,7 @@ def run(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): # noqa: ANN201 - a cl
|
||||
|
||||
``--db`` moves only the history. The contact cache, the outbox, the channel cache, the
|
||||
stored admin passwords, and the device profiles stay in the config directory. Thus a
|
||||
suite that set only ``--db`` read the files in the own ``~/.meshterm`` of the developer.
|
||||
suite that set only ``--db`` read the files in the developer's own ``~/.meshterm``.
|
||||
For this reason, a contact named ``[/]Bob``, which a person added by hand on one
|
||||
machine, could make this suite crash on that machine and pass on all other machines.
|
||||
``$MESHTERM_HOME`` moves the whole directory, and a test must use it.
|
||||
|
||||
@@ -270,7 +270,7 @@ class _Tty:
|
||||
It obeys what the differential renderer of prompt_toolkit and :class:`colsnap.PinnedOutput`
|
||||
send: carriage return, newline, backspace, cursor save and restore, and the CSI cursor
|
||||
moves. It ignores colour and mode sequences. For column arithmetic, a real terminal does
|
||||
the same. Glyph widths come from the own measurement of prompt_toolkit, unless ``draws``
|
||||
the same. Glyph widths come from prompt_toolkit's own measurement, unless ``draws``
|
||||
names a glyph that this terminal disagrees about.
|
||||
"""
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ def test_reading_the_console_font_never_raises() -> None:
|
||||
|
||||
|
||||
def test_the_user_font_directory_is_under_the_users_own_profile() -> None:
|
||||
"""The font directory of the user is in the own profile of the user.
|
||||
"""The font directory of the user is in the user's own profile.
|
||||
|
||||
This is the purpose of the location for each user: no administrator rights are
|
||||
necessary.
|
||||
|
||||
@@ -244,7 +244,7 @@ def _archive_ranked(): # noqa: ANN201
|
||||
"""A ranked contact table for the screens of the sweep. The real function scores it.
|
||||
|
||||
The percentiles are not written by hand, on purpose. The purpose of the gallery is that
|
||||
a specimen comes from the own funnels of the app. A percentile is the one number on
|
||||
a specimen comes from the app's own funnels. A percentile is the one number on
|
||||
these screens that cannot be written by hand and still be true. It is the rank of a
|
||||
contact against the other contacts in the same list. If the test makes it up, the
|
||||
screen is not consistent in itself: three contacts show 2, 7, and 11 out of a field of
|
||||
@@ -338,7 +338,7 @@ def _archived(cols: int, rows: int) -> Screen:
|
||||
|
||||
|
||||
def _node_detail_mark() -> Text:
|
||||
# The code uses the own marker and name styles of the app, not a hex colour that is
|
||||
# The code uses the app's own marker and name styles, not a hex colour that is
|
||||
# written by hand. The gallery is a specimen of what the platform draws, so a colour in a
|
||||
# stub can hide a bug in the palette.
|
||||
glyph, glyph_style = NODE_GLYPHS[NODE_TYPE_REPEATER]
|
||||
@@ -797,7 +797,7 @@ class _PickerRepo:
|
||||
|
||||
|
||||
def _chat_picker(cols: int, rows: int) -> Screen:
|
||||
"""The conversation picker, built through the own row funnel of the tool.
|
||||
"""The conversation picker, built through the tool's own row funnel.
|
||||
|
||||
This is its widest case. It has a name at the maximum of the lane, an unread badge that
|
||||
can have three digits, and a last message that is much longer than any terminal. The
|
||||
@@ -851,7 +851,7 @@ def _chat_picker(cols: int, rows: int) -> Screen:
|
||||
def _channels_manager(cols: int, rows: int) -> Screen:
|
||||
"""The channel manager when it is widest: each lane has data, and each action row is drawn.
|
||||
|
||||
The test builds it through the own row funnel of the feature. Thus the code that the app
|
||||
The test builds it through the feature's own row funnel. Thus the code that the app
|
||||
runs lays out the header line, the glyph lane, the unread badge, the counts, the ages,
|
||||
and the sparkline. The cases that matter are here. There is a name at the maximum of the
|
||||
lane. There is a send scope at the maximum of its lane (cut with an ellipsis), next to a
|
||||
@@ -1579,7 +1579,7 @@ def _join_discord(cols: int, rows: int) -> Screen:
|
||||
def _diagnostics(cols: int, rows: int) -> Screen:
|
||||
"""The Diagnostics page, with the widest values that a real page can have.
|
||||
|
||||
A deep Windows config directory and a connection error in the own words of the radio
|
||||
A deep Windows config directory and a connection error in the radio's own words
|
||||
are the two fields that have no natural limit. Both are here on purpose. A markdown list
|
||||
item hangs its wrapped text under itself at any width, and this must work in 53
|
||||
columns.
|
||||
@@ -1936,7 +1936,7 @@ def test_gallery_map_shows_the_basemap_credit_where_its_frame_puts_it(
|
||||
if platform.frame_border:
|
||||
assert "OpenStreetMap" not in body, "the credit reached the drawing on a bordered frame"
|
||||
# The corners are rounded, or square where Rich decides that the console is legacy
|
||||
# Windows (a pytest run with captured output there). Both are the own bottom rule of
|
||||
# Windows (a pytest run with captured output there). Both are the bottom rule of
|
||||
# the frame.
|
||||
rule = next(ln for ln in reversed(lines) if "╰" in ln or "└" in ln)
|
||||
assert rule[-1] in "╯┘" and rule[:-1].endswith(f" {expected} ─"), rule
|
||||
|
||||
@@ -648,7 +648,7 @@ def test_every_action_row_starts_its_words_in_one_cell_in_both_modes(platform_na
|
||||
async def test_trace_screen_action_cursor_commits_the_selected_row() -> None:
|
||||
"""↑↓ move over the action rows. Enter commits the row that has the highlight.
|
||||
|
||||
The rows are only the own verbs of the screen. No exit row ends them, so Trace is the
|
||||
The rows are only the screen's own verbs. No exit row ends them, so Trace is the
|
||||
last stop.
|
||||
"""
|
||||
opened: list[str] = []
|
||||
|
||||
@@ -144,8 +144,8 @@ def test_livefeed_class_lane_names_the_payload_class_once() -> None:
|
||||
|
||||
``packet`` is only the name of the event family that the frame arrived in. Thus the
|
||||
class lane shows the parsed payload class. This is the same label as the heading of
|
||||
the card in the viewer. The subject lane is then free for the own subject of the
|
||||
packet. If the class has no subject, the lane shows a dash. It does not show the class
|
||||
the card in the viewer. The subject lane is then free for the packet's own
|
||||
subject. If the class has no subject, the lane shows a dash. It does not show the class
|
||||
a second time.
|
||||
"""
|
||||
screen = _screen()
|
||||
@@ -156,7 +156,7 @@ def test_livefeed_class_lane_names_the_payload_class_once() -> None:
|
||||
)
|
||||
)
|
||||
row = _rows(screen, 100)[0]
|
||||
assert "🧩 multipart" in row # the class lane, with the own icon of the payload class
|
||||
assert "🧩 multipart" in row # the class lane, with the payload class's own icon
|
||||
assert row.count("multipart") == 1 # one time, not one time for each lane
|
||||
assert "packet" not in row # and never as the generic event family
|
||||
assert "—" in row # the subject lane: the class has no subject
|
||||
@@ -321,7 +321,7 @@ def test_livefeed_opens_pinned_and_the_pin_rides_the_newest_packet() -> None:
|
||||
"""
|
||||
screen = _screen(seed=[_obs(node="n0", age_s=1)])
|
||||
assert screen._pinned and screen._selected == 0
|
||||
assert _rows(screen, 100)[0].startswith("^ ") # the own mark of the pin
|
||||
assert _rows(screen, 100)[0].startswith("^ ") # the pin's own mark
|
||||
|
||||
screen.on_event(MeshEvent.observation_event(_obs(node="a1b2")))
|
||||
assert screen._selected == 0, "the pin let go of the top"
|
||||
|
||||
+2
-2
@@ -80,8 +80,8 @@ def test_bright_after_a_reset_is_white() -> None:
|
||||
|
||||
After `0m`, the colour in force is the default grey of the console, so `1m` means
|
||||
white. The letters of the splash say white in exactly this way (`0m` then `1m`). When
|
||||
the code read this as "no colour to state again", the run used the own default of the
|
||||
terminal, and a white row was drawn grey.
|
||||
the code read this as "no colour to state again", the run used the terminal's own
|
||||
default, and a white row was drawn grey.
|
||||
"""
|
||||
out = _state_intensity("\x1b[0;36mcyan\x1b[0m\x1b[1mwhite")
|
||||
tail = out.split("white")[0].split("\x1b[0m")[-1]
|
||||
|
||||
@@ -51,7 +51,7 @@ def test_every_palette_slot_comes_from_the_theme() -> None:
|
||||
"""Each palette slot comes from the theme.
|
||||
|
||||
The window cannot differ from the screen that it holds. The profile has sixteen keys,
|
||||
in the order that Terminal needs (dim, then bright). Each key has the own hex value of
|
||||
in the order that Terminal needs (dim, then bright). Each key has its own hex value in
|
||||
the theme. A change to a slot in :data:`~meshterm.ui.theme._VT_SLOTS` appears here at
|
||||
the next write. This is the reason that the code generates the profile, and does not
|
||||
ship it.
|
||||
@@ -228,7 +228,7 @@ def test_nothing_happens_off_macos(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
def test_the_profile_is_written_under_meshterm_home(
|
||||
tmp_path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""The profile is in the own directory of MeshTerm.
|
||||
"""The profile is in MeshTerm's own directory.
|
||||
|
||||
It follows ``MESHTERM_HOME`` when that is set.
|
||||
"""
|
||||
@@ -258,7 +258,7 @@ def test_the_readers_preferences_are_never_named(tmp_path, monkeypatch) -> None:
|
||||
|
||||
|
||||
def test_the_font_goes_to_the_users_own_library() -> None:
|
||||
"""The font goes to the own library of the user.
|
||||
"""The font goes to the user's own library.
|
||||
|
||||
No administrator rights are necessary, and the user can undo it from Font Book.
|
||||
"""
|
||||
|
||||
@@ -450,7 +450,7 @@ async def test_a_popup_with_nothing_under_it_floats_over_the_menu() -> None:
|
||||
screen on the stack, and the app drew it full-frame. The blank base that corrected this
|
||||
showed nothing behind the box. A dialog is smaller than the frame, so the page that the
|
||||
user came from must show around it. The root that the menu declared is the base that is
|
||||
pushed under the dialog and popped with it. Thus the own page of the tool opens over
|
||||
pushed under the dialog and popped with it. Thus the tool's own page opens over
|
||||
nothing.
|
||||
"""
|
||||
menu = SelectScreen("What would you like to do?", [Choice("TX optimize", "tx")])
|
||||
|
||||
@@ -431,7 +431,7 @@ def test_routes_view_tags_every_relay_with_its_hash_byte_alone() -> None:
|
||||
|
||||
|
||||
def test_routes_view_target_wears_its_node_type_glyph() -> None:
|
||||
"""The left end shows the own map mark of the target (a repeater ▲), not a plain dot."""
|
||||
"""The left end shows the target's own map mark (a repeater ▲), not a plain dot."""
|
||||
from meshterm.persistence.repository import TracedPath
|
||||
|
||||
leaf = Contact(name="Leaf", public_key="27d4396a2967" + "0" * 52, key_prefix="27d4396a2967")
|
||||
@@ -658,7 +658,7 @@ def test_node_detail_screen_renders_its_sections() -> None:
|
||||
body = _plain(screen.render_body(72))
|
||||
assert "Hub" in body and "repeater" in body # the pinned identity header
|
||||
assert "│ Info │" in body and "42" in body # the vitals are in the Info tab, which has a box
|
||||
assert "Time machine" in body # the own action of the Info tab
|
||||
assert "Time machine" in body # the Info tab's own action
|
||||
assert "Back" not in body # no exit row anywhere: Esc leaves
|
||||
assert "────────" in body # the faint rule that closes the stage
|
||||
assert "no route observed yet" not in body # the Routes stage is only on its own tab
|
||||
|
||||
@@ -243,7 +243,7 @@ def test_self_info_wins_where_the_two_frames_overlap() -> None:
|
||||
|
||||
|
||||
def test_the_device_pin_row_reads_the_firmware_s_own_name() -> None:
|
||||
"""The Device PIN row reads the own name of the firmware.
|
||||
"""The Device PIN row reads the firmware's own name.
|
||||
|
||||
The row showed "?" on each real companion. The code wrote the key as ``device_pin``,
|
||||
but the firmware reports it as ``ble_pin``.
|
||||
|
||||
+11
-11
@@ -100,7 +100,7 @@ def test_plain_mode_matches_the_app_wide_arrow_presentation() -> None:
|
||||
|
||||
|
||||
def test_plain_mode_annotation_dim_and_custom_separator() -> None:
|
||||
"""Annotations, dimming, and the own separator of a caller all stay in plain mode.
|
||||
"""Annotations, dimming, and a caller's own separator all stay in plain mode.
|
||||
|
||||
The ``(3d)`` note of a trace is muted. A dim hop (and the arrow into it) fades. The own
|
||||
separator of a surface passes through without a change. An example is the ``›`` of the
|
||||
@@ -131,12 +131,12 @@ def test_empty_path_reads_as_the_callers_word() -> None:
|
||||
|
||||
|
||||
def test_chips_are_joined_by_one_interlocked_chevron() -> None:
|
||||
"""A seam is one cell and not two, and the own end of the path is not a seam at all.
|
||||
"""A seam is one cell and not two, and the path's own end is not a seam at all.
|
||||
|
||||
The point of the previous chip is laid *on* the fill of the next chip. Thus the route
|
||||
reads as a ribbon whose segments meet on a chevron. The point has a meaning: it says
|
||||
that the route continues, so a finished path never has one. It ends square on the own
|
||||
pad of the last chip, and the only chevrons in the line are the joins.
|
||||
that the route continues, so a finished path never has one. It ends square on the last
|
||||
chip's own pad, and the only chevrons in the line are the joins.
|
||||
"""
|
||||
alice_fill = _fill("aa")
|
||||
line = PathLine([PathHop("Alice", key="aa"), PathHop("you", you=True)], mode="powerline")
|
||||
@@ -590,7 +590,7 @@ def test_wrapped_lines_always_fit_their_width() -> None:
|
||||
|
||||
|
||||
def test_wrapped_continuation_cue_follows_the_separator() -> None:
|
||||
"""The continuation cue is the own mark of the separator, and it is not always an arrow.
|
||||
"""The continuation cue is the separator's own mark, and it is not always an arrow.
|
||||
|
||||
A line that commas join (the wire spec of the trace screen) continues on a comma. Thus
|
||||
the spec stays exactly as it is.
|
||||
@@ -691,7 +691,7 @@ def test_wrapped_chip_lines_open_on_the_break_they_continue() -> None:
|
||||
assert lines[0].plain.startswith(" AAAA") # the square edge: this is the start
|
||||
step = 2 + WRAP_OFFSET
|
||||
assert lines[1].plain[:step].isspace() and lines[1].plain[step] == POWERLINE_SEP
|
||||
# …past the own PATH_INK stamp of the line, which covers the whole body from the same
|
||||
# …past the line's own PATH_INK stamp, which covers the whole body from the same
|
||||
# cell (it marks the run as a path line for the cursor fold, and it draws nothing).
|
||||
carried = next(s for s in lines[1].spans if s.start == step and str(s.style) != PATH_INK)
|
||||
assert str(carried.style) == f"{_fill('3d')} reverse"
|
||||
@@ -704,8 +704,8 @@ def test_rounded_caps_finish_a_path_only_where_the_font_has_them(monkeypatch) ->
|
||||
"""Rounded caps finish a path only where the font really has them.
|
||||
|
||||
A full Nerd Font rounds the two *outer* ends of the path into a lozenge. A terminal that
|
||||
has only the core glyphs makes *both* of them square. It appends nothing, and the own
|
||||
pads of the outer chips are the edges. It never draws tofu. Interior breaks stay angled
|
||||
has only the core glyphs makes *both* of them square. It appends nothing, and the
|
||||
own pads of the outer chips are the edges. It never draws tofu. Interior breaks stay angled
|
||||
in both cases. A rounded end reads as the path that stops. A pointed end at the finish
|
||||
reads as the opposite: a route that is cut off in the middle of a walk.
|
||||
"""
|
||||
@@ -828,9 +828,9 @@ def test_a_seam_between_two_of_one_colour_is_the_thin_chevron_in_its_label() ->
|
||||
"""Where two chips have the same fill, the seam is the thin chevron in the label colour.
|
||||
|
||||
The interlock cannot draw a solid point in its own background. Thus MeshTerm draws the
|
||||
join *on* the shared fill instead (the own mark of powerline for a join inside one
|
||||
join *on* the shared fill instead (powerline's own mark for a join inside one
|
||||
colour), and the ribbon continues without a break. Its colour is the label of the
|
||||
previous chip. It is the light half of the own pair of the chip, so it is visible on the
|
||||
previous chip. It is the light half of the chip's own pair, so it is visible on the
|
||||
fill, and nothing on the line has a colour that is not a colour of a chip. The faded
|
||||
slate draws it in its muted text.
|
||||
|
||||
@@ -1005,7 +1005,7 @@ def test_action_mark_leaves_a_chip_path_closed_rather_than_cracked() -> None:
|
||||
def test_hops_atom_counts_relays_and_says_direct_for_none() -> None:
|
||||
"""The atom of the statistics line: ``direct`` for a route with no hops, else ``n hop(s)``.
|
||||
|
||||
A path with no relays is not "0 hops". ``direct`` is the own word of the app for a
|
||||
A path with no relays is not "0 hops". ``direct`` is the app's own word for a
|
||||
packet that went straight there, and :class:`PathLine` says it for an empty path also.
|
||||
"""
|
||||
assert hops_atom(0).plain == "direct"
|
||||
|
||||
@@ -225,7 +225,7 @@ def test_fkey_lane_resolution_and_banks() -> None:
|
||||
"""The shared lane has some slots, and it leaves the other slots free.
|
||||
|
||||
The pager takes F4 and F5. Each jump is on the Shift half of the pager that goes toward
|
||||
it. F1 to F3 stay free for the own verbs of the screen. Neither Enter nor Esc takes a
|
||||
it. F1 to F3 stay free for the screen's own verbs. Neither Enter nor Esc takes a
|
||||
slot.
|
||||
"""
|
||||
lane = DEFAULT_LANE
|
||||
|
||||
+1
-1
@@ -755,7 +755,7 @@ def test_an_author_is_named_by_key_or_stands_as_a_grey_hash() -> None:
|
||||
|
||||
|
||||
def test_the_board_draws_each_post_under_its_author() -> None:
|
||||
"""A contact, a stranger, the own notice of the room, and us: each has its own chip."""
|
||||
"""A contact, a stranger, the room's own notice, and us: each has its own chip."""
|
||||
screen, _ = _view(_board())
|
||||
text = plain("\n".join(screen.render_body(72)))
|
||||
for expected in ("Alice", STRANGER_KEY, ROOM.name, "Anyone driving Saturday?", "I'll check it"):
|
||||
|
||||
@@ -141,8 +141,8 @@ def test_a_time_is_an_age_unless_the_instant_is_itself_the_fact() -> None:
|
||||
A person at a prompt who reads ``2026-09-07T19:58:53-04:00`` does arithmetic to answer
|
||||
"recently?". This is the question that the person typed the command to ask. Thus an age
|
||||
is now the default. :func:`~meshterm.ui.script.stamp` stays for three places where the
|
||||
instant is the answer: the device clock, an appointment that ``--at`` sets, and the own
|
||||
``TIME`` column of a live capture (an age shows ``now`` in each row). It
|
||||
instant is the answer: the device clock, an appointment that ``--at`` sets, and the
|
||||
``TIME`` column of a live capture itself (an age shows ``now`` in each row). It
|
||||
also stays for each column under ``--absolute``.
|
||||
"""
|
||||
fresh = datetime.now(timezone.utc) - timedelta(seconds=5)
|
||||
|
||||
@@ -764,7 +764,7 @@ async def test_three_byte_route_appends_destination_hash() -> None:
|
||||
|
||||
Two things are important for a region that is not a power of two (hashes of 3 bytes).
|
||||
First, each routing hash of 3 bytes becomes its first 2 bytes (the widest trace width
|
||||
that the protocol can represent). Second, the own hash of the destination is added as
|
||||
that the protocol can represent). Second, the destination's own hash is added as
|
||||
the last outbound hop, because a trace replies only when its destination is the last
|
||||
outbound hop. The trace protocol has no separate return-path field, so the code
|
||||
mirrors the same repeaters back afterwards. If it does not, no node relays the reply
|
||||
@@ -789,7 +789,7 @@ async def test_three_byte_route_appends_destination_hash() -> None:
|
||||
resolved = await device._trace_path_to_contact(mc, "Repeater")
|
||||
assert resolved is not None
|
||||
path_bytes, flags = resolved
|
||||
# Two repeater hops cut to 2 bytes, the own hash of the target (2 bytes), then the same
|
||||
# Two repeater hops cut to 2 bytes, the target's own hash (2 bytes), then the same
|
||||
# two repeaters mirrored back to us.
|
||||
assert path_bytes == bytes.fromhex("11224455aabb44551122")
|
||||
assert flags == trace_runner.path_hash_flags(2) # a width of 2 bytes
|
||||
@@ -823,7 +823,7 @@ async def test_direct_neighbor_resolves_to_destination_hash() -> None:
|
||||
resolved = await device._trace_path_to_contact(mc, "Neighbor")
|
||||
assert resolved is not None
|
||||
path_bytes, flags = resolved
|
||||
# Only the own hash of the target. The region width of 3 is cut to a trace hop of 2 bytes.
|
||||
# Only the target's own hash. The region width of 3 is cut to a trace hop of 2 bytes.
|
||||
assert path_bytes == bytes.fromhex("3d63")
|
||||
assert flags == trace_runner.path_hash_flags(2)
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ def test_every_glyph_map_target_stays_inside_the_bmp() -> None:
|
||||
a character above U+FFFF with U+FFFD before it uses the font. This is the reason that
|
||||
MeshTerm sends icons through this table there too (refer to
|
||||
:func:`meshterm.ui.termfont.emoji_support`). Someone can change a substitute to an
|
||||
emoji. The emoji draws correctly in the own font of the PicoCalc, but it breaks each
|
||||
emoji. The emoji draws correctly in the PicoCalc's own font, but it breaks each
|
||||
Windows console without a warning. Thus this test asserts the plane. It does not
|
||||
depend on the font whitelist for the same result.
|
||||
"""
|
||||
@@ -274,7 +274,7 @@ def test_fold_quantizes_a_colour_that_shares_its_sequence_with_another() -> None
|
||||
|
||||
|
||||
def test_the_qr_style_is_white_on_black_on_both_themes() -> None:
|
||||
"""A code is white ink on a black field on each platform, with the own slots of the PicoCalc."""
|
||||
"""A code is white ink on a black field on each platform, with the PicoCalc's own slots."""
|
||||
from rich.style import Style
|
||||
|
||||
regular = (
|
||||
@@ -316,7 +316,7 @@ def test_names_colour_by_key_on_both_platforms() -> None:
|
||||
def test_picocalc_node_hues_land_on_their_own_palette_slots() -> None:
|
||||
"""The quantized wheel uses only the six chromatic bright slots, in equal parts.
|
||||
|
||||
Each hex that the code returns is the own RGB of a slot. Thus each later downsample (the
|
||||
Each hex that the code returns is the RGB of a slot itself. Thus each later downsample (the
|
||||
downsample of Rich and the downsample of the fold) gives that exact slot. It does not
|
||||
guess a neighbour slot.
|
||||
"""
|
||||
|
||||
+1
-1
@@ -3872,7 +3872,7 @@ def test_the_splash_hint_stays_inside_the_box_it_is_drawn_in() -> None:
|
||||
from meshterm.ui.device_picker import _shortcut_hint
|
||||
from meshterm.ui.tui.select import splice_hint
|
||||
|
||||
base = "↑↓ move · Enter select · Esc bye" # This is the own farewell of the splash.
|
||||
base = "↑↓ move · Enter select · Esc bye" # This is the splash's own farewell.
|
||||
radio = serial_device("COM7", name="A Radio")
|
||||
common = splice_hint(base, _shortcut_hint(0)(radio))
|
||||
for platform in (REGULAR, PICOCALC_LYRA):
|
||||
|
||||
@@ -58,7 +58,7 @@ class _Recorder:
|
||||
|
||||
@pytest.fixture
|
||||
def device(monkeypatch: pytest.MonkeyPatch) -> _Recorder:
|
||||
"""Make the process look like MeshTerm that runs on the own VT of the handheld."""
|
||||
"""Make the process look like MeshTerm that runs on the handheld's own VT."""
|
||||
set_platform(PICOCALC_LYRA)
|
||||
monkeypatch.setattr(os, "ttyname", lambda fd: "/dev/tty1", raising=False)
|
||||
monkeypatch.setattr(consolefont.shutil, "which", lambda name: "/usr/bin/setfont")
|
||||
|
||||
@@ -256,7 +256,7 @@ def test_name_chip_wears_the_hue_as_its_label_padded_like_every_chip(powerline)
|
||||
|
||||
|
||||
def test_name_chip_draws_us_as_the_star_never_as_our_name(powerline) -> None:
|
||||
"""Our end of a route is the own marker of the map, and a sender label is the same."""
|
||||
"""Our end of a route is the map's own marker, and a sender label is the same."""
|
||||
powerline(True)
|
||||
chip = name_chip("you", you=True)
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ def test_the_bundles_own_bookkeeping_never_reaches_the_new_process(
|
||||
|
||||
assert not [key for key in environment if key.startswith("_PYI")]
|
||||
assert "_MEIPASS2" not in environment
|
||||
assert environment["MESHTERM_HOME"] == r"C:\mine" # the own settings of the user stay
|
||||
assert environment["MESHTERM_HOME"] == r"C:\mine" # the user's own settings stay
|
||||
assert environment[winterminal.REOPENED_ENV] == "1"
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user