[PR #653] feat(extmarks): add onEncounter and onDeletion hooks for virtual extmarks #689

Open
opened 2026-03-02 23:47:41 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/653
Author: @jorgeraad
Created: 2/9/2026
Status: 🔄 Open

Base: mainHead: feat/extmark-encounter-hooks


📝 Commits (7)

  • 3d38523 feat(extmarks): add encounter hook interfaces and callback storage
  • e8dd776 feat(extmarks): wire callback maps to extmark lifecycle
  • df0af4f feat(extmarks): add onEncounter hooks to cursor movement methods
  • 2cbec55 feat(extmarks): add onDeletion hooks to deletion methods
  • 8e02a45 test(extmarks): add tests for onEncounter and onDeletion hooks
  • 3ebfe22 feat(extmarks): add select-then-act interaction to extmarks demo
  • c2ef3e4 style: format extmarks files with prettier

📊 Changes

3 files changed (+732 additions, -41 deletions)

View changed files

📝 packages/core/src/examples/extmarks-demo.ts (+177 -41)
📝 packages/core/src/lib/extmarks.test.ts (+443 -0)
📝 packages/core/src/lib/extmarks.ts (+112 -0)

📄 Description

Closes #652

Summary

Adds per-extmark onEncounter and onDeletion callbacks to ExtmarkOptions, letting consumers
control what happens when the cursor hits a virtual extmark or the user tries to delete one.

Changes

Core hooks (packages/core/src/lib/extmarks.ts):

  • ExtmarkEncounter and ExtmarkDeletionEncounter interfaces with action methods (skip(), setCursor(), deleteExtmark(), prevent())
  • onEncounter and onDeletion optional fields on ExtmarkOptions
  • Callback maps stored alongside existing metadata map, cleaned up in delete() and clear()
  • onEncounter wired into all 5 wrapped cursor methods (left, right, up, down, setCursorByOffset)
  • onDeletion wired into deleteCharBackward and deleteChar
  • Fallback to default behavior when callback doesn't call any action method

Demo (packages/core/src/examples/extmarks-demo.ts):

  • Updated to use the new hooks — arrowing into an extmark stops and highlights it, then you can
    press Enter to expand it, Backspace to delete it, or arrow again to skip past

Demo

https://drive.google.com/file/d/1w83taLW36FnsmEeZGCj-49q9H00FuN12/view?usp=sharing

Backwards compatibility

Fully backwards compatible. Omitting onEncounter/onDeletion preserves existing skip and delete behavior unchanged.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/anomalyco/opentui/pull/653 **Author:** [@jorgeraad](https://github.com/jorgeraad) **Created:** 2/9/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/extmark-encounter-hooks` --- ### 📝 Commits (7) - [`3d38523`](https://github.com/anomalyco/opentui/commit/3d385233314702ec482442b0654e9c0124575c45) feat(extmarks): add encounter hook interfaces and callback storage - [`e8dd776`](https://github.com/anomalyco/opentui/commit/e8dd776277ec03369f94e76203c496de96d1e762) feat(extmarks): wire callback maps to extmark lifecycle - [`df0af4f`](https://github.com/anomalyco/opentui/commit/df0af4f15fd70f4031016be7e31feb47ef0dc34e) feat(extmarks): add onEncounter hooks to cursor movement methods - [`2cbec55`](https://github.com/anomalyco/opentui/commit/2cbec552e1faf668143d196339f1a7c014757254) feat(extmarks): add onDeletion hooks to deletion methods - [`8e02a45`](https://github.com/anomalyco/opentui/commit/8e02a4568a7aaa1c59d4d24cf15dba1d24a5c642) test(extmarks): add tests for onEncounter and onDeletion hooks - [`3ebfe22`](https://github.com/anomalyco/opentui/commit/3ebfe22b1c6d5190c4c0c40dbf8a902373d6ee36) feat(extmarks): add select-then-act interaction to extmarks demo - [`c2ef3e4`](https://github.com/anomalyco/opentui/commit/c2ef3e4163641669ca10c84a6d2d4250dd94812c) style: format extmarks files with prettier ### 📊 Changes **3 files changed** (+732 additions, -41 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/examples/extmarks-demo.ts` (+177 -41) 📝 `packages/core/src/lib/extmarks.test.ts` (+443 -0) 📝 `packages/core/src/lib/extmarks.ts` (+112 -0) </details> ### 📄 Description Closes #652 ## Summary Adds per-extmark `onEncounter` and `onDeletion` callbacks to `ExtmarkOptions`, letting consumers control what happens when the cursor hits a virtual extmark or the user tries to delete one. ## Changes **Core hooks** (`packages/core/src/lib/extmarks.ts`): - `ExtmarkEncounter` and `ExtmarkDeletionEncounter` interfaces with action methods (`skip()`, `setCursor()`, `deleteExtmark()`, `prevent()`) - `onEncounter` and `onDeletion` optional fields on `ExtmarkOptions` - Callback maps stored alongside existing `metadata` map, cleaned up in `delete()` and `clear()` - `onEncounter` wired into all 5 wrapped cursor methods (left, right, up, down, setCursorByOffset) - `onDeletion` wired into `deleteCharBackward` and `deleteChar` - Fallback to default behavior when callback doesn't call any action method **Demo** (`packages/core/src/examples/extmarks-demo.ts`): - Updated to use the new hooks — arrowing into an extmark stops and highlights it, then you can press Enter to expand it, Backspace to delete it, or arrow again to skip past ## Demo https://drive.google.com/file/d/1w83taLW36FnsmEeZGCj-49q9H00FuN12/view?usp=sharing ## Backwards compatibility Fully backwards compatible. Omitting `onEncounter`/`onDeletion` preserves existing skip and delete behavior unchanged. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#689
No description provided.