In a chat, the point of our chip alone marks a message that names us
The notch and the point together were too heavy. The mark is now one cell, the point of our chip in its fill, then a space before the time. Without chips, it is ">" in our hue. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
68d5d03324
commit
691170d342
7 files changed
+52
-55
No files matched your search
@@ -488,15 +488,16 @@ as a grouped list does. Filling a page in is editing its `.md`; no Python follow
|
||||
the star in the chip's dark ink: a yellow star measured under 3:1 on the light fill for
|
||||
238 of 256 hues, and the star on the page right of the chip was tried and put back (JP,
|
||||
2026-10-13). A **mention** of us is the turned-over chip with no star
|
||||
(`mention_chip(you=True)`); the message carrying it gets **the two ends of our chip**
|
||||
in the two cells left of its time instead — notch then point, no label, in our chip's
|
||||
fill (`widgets.mention_mark` → `pathline.chip_ends`; `>>` in our hue in arrow mode;
|
||||
it replaced a `★`, JP 2026-10-13). Every time sits two cells right to keep the column
|
||||
(`❯`, a space, the mark, then `12:34 body`), and the Messages list puts the mark left
|
||||
of the row's age. Arrow mode draws the chip as
|
||||
a padded reverse-video block. The PicoCalc can't put a bright slot behind text, so
|
||||
there the chip keeps the normal colours and the `★` alone marks us. With no name or key from the device, the bare `★` chip stays. Path lines
|
||||
(delivery paths, the packet viewer, routes) keep `★`.
|
||||
(`mention_chip(you=True)`); the message carrying it gets **the point of our chip**
|
||||
alone, one cell in our chip's fill, left of its time instead (`widgets.mention_mark` →
|
||||
`pathline.chip_point`; `>` in our hue in arrow mode). It replaced a `★`, and then the
|
||||
notch-and-point pair, which read as ugly (JP, 2026-10-13). Every time sits two cells
|
||||
right to keep the column (`❯`, a space, the mark, a space, then `12:34 body`), and the
|
||||
Messages list puts the mark left of the row's age. Arrow mode draws the chip as a
|
||||
padded reverse-video block. The PicoCalc can't put a bright slot behind text, so there
|
||||
the chip keeps the normal colours and the `★` alone marks us. With no name or key from
|
||||
the device, the bare `★` chip stays. Path lines (delivery paths, the packet viewer,
|
||||
routes) keep `★`.
|
||||
- **The compose line draws a mention as its chip** (`ui/compose.py`, `MentionEditor`): the
|
||||
moment `]` completes an `@[Name]` token it renders as the same chip the transcript will
|
||||
show, and from then on it is an **atom** — ←/→ step over it, ^←/^→ never stop inside
|
||||
|
||||
@@ -986,15 +986,15 @@ def _title(
|
||||
text.append(" " * _BADGE_WIDTH)
|
||||
# The relative age lane (right-aligned) is between the badge and the message text. Thus
|
||||
# the ages are in one neat column, and all the previews start at the same position. A
|
||||
# last message that names us has the ends of our chip at the left of its age, the same
|
||||
# as the transcript has them at the left of the time (refer to ChatScreen._body_lines).
|
||||
# last message that names us has the point of our chip at the left of its age, the same
|
||||
# as the transcript has it at the left of the time (refer to ChatScreen._body_lines).
|
||||
age = _ago(last.created_at) if last is not None else ""
|
||||
lane = f" {age:>{_AGE_WIDTH}}"
|
||||
if age and last is not None and _names_us(last, us):
|
||||
mark = len(lane) - len(age) - 2 # the two cells of the mark, then the age
|
||||
mark = len(lane) - len(age) - 2 # the mark, a space, then the age
|
||||
text.append(lane[:mark])
|
||||
text.append_text(mention_mark(us[1]))
|
||||
text.append(age, style="muted")
|
||||
text.append(lane[mark + 1 :], style="muted")
|
||||
else:
|
||||
text.append(lane, style="muted")
|
||||
text.append(" ")
|
||||
@@ -1057,7 +1057,7 @@ def _preview_text(
|
||||
|
||||
- Our own messages start with our chip, ``★ Name`` turned over (refer to
|
||||
:func:`~meshterm.ui.widgets.self_chip`). A mention of our name has the chip that is
|
||||
turned over, with no star. A message that names us has the ends of our chip at the
|
||||
turned over, with no star. A message that names us has the point of our chip at the
|
||||
left of the age of the row (refer to :func:`_title`).
|
||||
- In a received channel message, the inline ``Name:`` sender is the author, in the hue
|
||||
that comes from its key (the node grey when no known node has the name).
|
||||
|
||||
+5
-4
@@ -775,9 +775,9 @@ class ChatScreen(Screen):
|
||||
is marked as the reply target (the same as the ``❯`` pointer and the highlight of
|
||||
the select screen).
|
||||
|
||||
A message that mentions our name has a mark at the left of its time: the two ends
|
||||
of our chip, in its colour, with no label (refer to
|
||||
:func:`~meshterm.ui.widgets.mention_mark`, JP, 2026-10-13). The chip of the mention
|
||||
A message that mentions our name has a mark at the left of its time: the point of
|
||||
our chip, in its colour (refer to :func:`~meshterm.ui.widgets.mention_mark`, JP,
|
||||
2026-10-13). The chip of the mention
|
||||
in the body is turned over, but it has no star (refer to
|
||||
:func:`~meshterm.ui.widgets.mention_hop`). Thus the mark of a message that names us
|
||||
is in one column, where the eye finds it when it goes down the transcript. Each time
|
||||
@@ -799,6 +799,7 @@ class ChatScreen(Screen):
|
||||
prefix.append("❯ " if selected else " ", style="cursor" if selected else None)
|
||||
if self._names_us(body):
|
||||
prefix.append_text(mention_mark(self._self_key))
|
||||
prefix.append(" ")
|
||||
else:
|
||||
prefix.append(" ")
|
||||
prefix.append(f"{stamp:%H:%M} ", style="cursor" if selected else "muted")
|
||||
@@ -855,7 +856,7 @@ class ChatScreen(Screen):
|
||||
Thus the user sees that a mention belongs to the node that it names. The text
|
||||
around the mentions keeps the base style of the line (``cursor`` when the message
|
||||
is the selected reply target, or else no style). A mention of our own name has our
|
||||
chip, turned over, and the line has the ends of our chip at the left of its time
|
||||
chip, turned over, and the line has the point of our chip at the left of its time
|
||||
(refer to :meth:`_body_lines`). Thus a message that names us is easy to see.
|
||||
|
||||
The chip opens on the notch, because the node that a mention names is the
|
||||
|
||||
+6
-10
@@ -1294,12 +1294,11 @@ def _bind_chips(platform: Platform) -> None:
|
||||
_colours_of, _WEIGHT, _FLAT = _slot_colours, "not bold ", "not bold "
|
||||
|
||||
|
||||
def chip_ends(hop: PathHop) -> Text:
|
||||
"""The two ends of the chip of ``hop`` with no label between them: the notch, then the point.
|
||||
def chip_point(hop: PathHop) -> Text:
|
||||
"""The point of the chip of ``hop`` alone: one cell in the fill of the chip.
|
||||
|
||||
It is two cells in the fill of the chip, the same two cells that open and close a chip
|
||||
of a destination (refer to :meth:`PathLine._notch`). A chat puts it at the left of the
|
||||
time of a message that names us, in the fill of our chip (refer to
|
||||
It is the same cell that closes a chip whose route goes on. A chat puts it at the left
|
||||
of the time of a message that names us, in the fill of our chip (refer to
|
||||
:func:`~meshterm.ui.widgets.mention_mark`). The colours come from the palette of the
|
||||
platform, so the PicoCalc draws it in the fill that the chip has there.
|
||||
|
||||
@@ -1307,12 +1306,9 @@ def chip_ends(hop: PathHop) -> Text:
|
||||
hop: The hop whose chip gives the fill.
|
||||
|
||||
Returns:
|
||||
The two styled cells.
|
||||
The one styled cell.
|
||||
"""
|
||||
fill = _colours_of(hop).fill
|
||||
text = PathLine._notch(fill)
|
||||
text.append(POWERLINE_SEP, style=f"{_FLAT}{fill}")
|
||||
return text
|
||||
return Text(POWERLINE_SEP, style=f"{_FLAT}{_colours_of(hop).fill}")
|
||||
|
||||
|
||||
def _shorten(value: str, hash_bytes: int | None) -> str:
|
||||
|
||||
+14
-14
@@ -57,7 +57,7 @@ from .marks import (
|
||||
LabelRgbOf,
|
||||
parse_hex,
|
||||
)
|
||||
from .pathline import SELF_GLYPH, PathHop, PathLine, chip_ends, path_line
|
||||
from .pathline import SELF_GLYPH, PathHop, PathLine, chip_point, path_line
|
||||
from .termfont import powerline_enabled
|
||||
from .theme import glyph, mark_rgb, name_style, node_style, snr_style
|
||||
|
||||
@@ -698,8 +698,8 @@ def self_chip(name: str | None, key: str | None, *, role: str | None = None) ->
|
||||
:attr:`~meshterm.ui.pathline.PathHop.inverse`).
|
||||
|
||||
A mention of our name is a different mark (refer to :func:`mention_chip`). The chip is
|
||||
turned over, but it has no star. The message that names us has the ends of our chip at
|
||||
the left of its time (refer to :func:`mention_mark`).
|
||||
turned over, but it has no star. The message that names us has the point of our chip
|
||||
at the left of its time (refer to :func:`mention_mark`).
|
||||
|
||||
Our node with no name or no key (the device did not report them) keeps the bare ``★``
|
||||
chip of a route.
|
||||
@@ -718,26 +718,26 @@ def self_chip(name: str | None, key: str | None, *, role: str | None = None) ->
|
||||
|
||||
|
||||
def mention_mark(key: str | None) -> Text:
|
||||
"""The mark of a message that names us: the two ends of our chip, with no label.
|
||||
"""The mark of a message that names us: the point of our chip, alone.
|
||||
|
||||
The notch, then the point, in the fill of our chip (refer to
|
||||
:func:`~meshterm.ui.pathline.chip_ends`). The chat puts it in the two cells at the left
|
||||
of the time of each message that mentions our name, and the Messages list puts it at
|
||||
the left of the age of a row whose last message does (JP, 2026-10-13). It replaced a
|
||||
``★``. The mark has the colour of the chip that the mention has in the body, so the eye
|
||||
joins the two. Where the terminal draws no chips, it is ``>>`` in our hue, the colour
|
||||
that our chip has there.
|
||||
One cell in the fill of our chip (refer to :func:`~meshterm.ui.pathline.chip_point`).
|
||||
The chat puts it at the left of the time of each message that mentions our name, and
|
||||
the Messages list puts it at the left of the age of a row whose last message does (JP,
|
||||
2026-10-13). It replaced a ``★``, and then the notch and the point together, which JP
|
||||
found too heavy. The mark has the colour of the chip that the mention has in the body,
|
||||
so the eye joins the two. Where the terminal draws no chips, it is ``>`` in our hue,
|
||||
the colour that our chip has there.
|
||||
|
||||
Args:
|
||||
key: Our public key, which gives the hue. With ``None``, the mark has the keyless
|
||||
grey, the same as the chip of the mention.
|
||||
|
||||
Returns:
|
||||
The mark, two cells wide.
|
||||
The mark, one cell wide. The caller puts a space after it.
|
||||
"""
|
||||
if powerline_enabled():
|
||||
return chip_ends(PathHop("", key=key or None, inverse=bool(key)))
|
||||
return Text(">>", style=node_style(key) if key else "node.unknown")
|
||||
return chip_point(PathHop("", key=key or None, inverse=bool(key)))
|
||||
return Text(">", style=node_style(key) if key else "node.unknown")
|
||||
|
||||
|
||||
def mention_hop(name: str, key: str | None, *, you: bool = False) -> PathHop:
|
||||
|
||||
+4
-4
@@ -1624,7 +1624,7 @@ def test_a_mention_of_our_name_takes_our_chip_with_no_star(powerline) -> None:
|
||||
def test_a_message_that_names_us_has_the_mark_left_of_its_time() -> None:
|
||||
"""The mark goes in the two cells before the time, and each time moves two cells right.
|
||||
|
||||
The suite draws no chips, so the mark is ``>>`` in our hue (refer to the widget tests
|
||||
The suite draws no chips, so the mark is ``>`` in our hue (refer to the widget tests
|
||||
for the two ends of the chip).
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
@@ -1637,12 +1637,12 @@ def test_a_message_that_names_us_has_the_mark_left_of_its_time() -> None:
|
||||
]
|
||||
screen = _channel_screen(messages, self_name="Me", self_key=_OUR_KEY)
|
||||
rows = _strip_ansi("\n".join(screen._render_grouped(72))).splitlines()
|
||||
assert any(row.startswith(f" >>{stamp} hi") for row in rows)
|
||||
assert any(row.startswith(f" > {stamp} hi") for row in rows)
|
||||
assert any(row.startswith(f" {stamp} hi") for row in rows) # the other message
|
||||
screen.handle("up")
|
||||
screen.handle("up") # the first message: the pointer, then the mark
|
||||
rows = _strip_ansi("\n".join(screen._render_grouped(72))).splitlines()
|
||||
assert any(row.startswith(f"❯ >>{stamp} hi") for row in rows)
|
||||
assert any(row.startswith(f"❯ > {stamp} hi") for row in rows)
|
||||
|
||||
|
||||
def _channel_screen(
|
||||
@@ -1766,7 +1766,7 @@ def test_a_row_whose_last_message_names_us_has_the_mark_left_of_its_age(
|
||||
lanes = _lanes([conv])
|
||||
marked = _title(ctx, conv, {"chan:c0": named}, _NO_KEYS, lanes, us=us).plain
|
||||
plain = _title(ctx, conv, {"chan:c0": other}, _NO_KEYS, lanes, us=us).plain
|
||||
assert ">>now " in marked and ">>" not in plain
|
||||
assert "> now " in marked and ">" not in plain
|
||||
assert marked.index("now") == plain.index("now") # the mark takes the cells of the gap
|
||||
|
||||
|
||||
|
||||
@@ -399,23 +399,22 @@ def test_a_mention_of_us_is_turned_over_with_no_star(powerline) -> None:
|
||||
assert not mention_hop("Me", None, you=True).inverse # no key: no hue to turn over
|
||||
|
||||
|
||||
def test_the_mark_of_a_message_that_names_us_is_the_ends_of_our_chip(powerline) -> None:
|
||||
"""The notch, then the point, in the fill of our chip, and no label between them."""
|
||||
def test_the_mark_of_a_message_that_names_us_is_the_point_of_our_chip(powerline) -> None:
|
||||
"""One cell: the point, in the fill of our chip."""
|
||||
powerline(True)
|
||||
mark = mention_mark("5e7f")
|
||||
fill = _span_style(mention_chip("Me", "5e7f", you=True), "Me").bgcolor.name
|
||||
|
||||
assert mark.plain == POWERLINE_SEP * 2
|
||||
notch, point = (Style.parse(str(span.style)) for span in mark.spans)
|
||||
assert notch.reverse and notch.color.name == fill # cut out of the fill
|
||||
assert not point.reverse and point.color.name == fill # the point of the fill
|
||||
assert mark.plain == POWERLINE_SEP
|
||||
point = Style.parse(str(mark.style))
|
||||
assert not point.reverse and point.color.name == fill
|
||||
|
||||
|
||||
def test_the_mark_without_chips_is_two_arrows_in_our_hue(powerline) -> None:
|
||||
"""With no chips, the mark is ``>>``, in the hue that our chip has in arrow mode."""
|
||||
def test_the_mark_without_chips_is_an_arrow_in_our_hue(powerline) -> None:
|
||||
"""With no chips, the mark is ``>``, in the hue that our chip has in arrow mode."""
|
||||
powerline(False)
|
||||
mark = mention_mark("5e7f")
|
||||
assert mark.plain == ">>" and str(mark.style) == node_style("5e7f")
|
||||
assert mark.plain == ">" and str(mark.style) == node_style("5e7f")
|
||||
assert str(mention_mark(None).style) == "node.unknown"
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user