set(), end() and move_cursor() used the byte length of the input as the
cursor bound while append/backspace/delete/clear_* index a grapheme table.
Any non-ASCII input (æøå, emoji) followed by End or typing past the end
indexed out of bounds and, with panic = "abort" in release, killed wldash.
While here:
- clamp Up so the selection can't run past the last row (every widget now
reports its row count), and make mouse selection underflow-safe
- strip all desktop-entry field codes from Exec (%i %c %k ... and %% -> %),
not just %f/%F/%u/%U
- report a failed spawn instead of panicking
- size the highlight colour table by chars, matching the drawing code
Adds unit tests for the prompt and the field-code stripping.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
On a shared (NFS-roamed) home, ~/.config/wldash/config.yml is identical on
every machine. Prefer a host-specific /etc/wldash/config.yml when it exists so
each machine can keep its own layout without conflicting; --config still
overrides both. Enables the 'factor host-specific config to /etc' pattern for
shared-home fleets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ensure ~/.config/wldash and ~/.cache/wldash exist.
Provide hints when no configuration exists.
Signed-off-by: Alejandro Visiedo <alejandro.visiedo@gmail.com>
This implementation is a rewrite of wldash, implemented from scratch.
This also means that it is an unrelated history, hence the history now
having two initial commits.
wldash was originally written to expect server-side shm buffer
optimizations, which make it so only a single buffer has to be in use.
This simplifies damage tracking and repaint needs.
Support for using multiple buffers was added to support e.g., jay, but
the damage handling was not in place for this to work. Fix that by
tracking damage per buffer.
The calloop timer is only responsible for ensuring wakeup at the right
time, but we can also be woken up before time so we need to check the
deadline.
At the same time, We may end up being significantly delayed past the
deadline if something else was slow. If we are too far behind, reset the
base of the repeat timer by just offsetting from the current time.