@@ -72,6 +72,21 @@ class DialogPluginTyped : public DialogPluginBase {
7272 return false ;
7373 }
7474
75+ // / Cursor-aware code change: `cursor` is the caret offset (bytes) in `code`,
76+ // / or negative when the host didn't report one. The dispatch always calls
77+ // / this; it defaults to onCodeChanged(name, code), so existing plugins keep
78+ // / working. Override this (instead of onCodeChanged) to drive caret-aware
79+ // / completion. A distinct name (rather than an overload) avoids the
80+ // / overloaded-virtual hiding hazard.
81+ // /
82+ // / The caret is only reported (and cursor-only moves only fire this at all)
83+ // / for editors that opted in via WidgetData::setCodeCaretTracking. Without
84+ // / opt-in this fires on text changes only, with cursor < 0 — so an editor
85+ // / that merely validates code is not re-run on every cursor move.
86+ virtual bool onCodeChangedWithCursor (std::string_view widget_name, std::string_view code, int /* cursor*/ ) {
87+ return onCodeChanged (widget_name, code);
88+ }
89+
7590 virtual bool onItemsDropped (std::string_view /* widget_name*/ , const std::vector<std::string>& /* items*/ ) {
7691 return false ;
7792 }
@@ -113,7 +128,7 @@ class DialogPluginTyped : public DialogPluginBase {
113128 return onItemsDropped (widget_name, *v);
114129 }
115130 if (auto v = event.codeChanged ()) {
116- return onCodeChanged (widget_name, *v);
131+ return onCodeChangedWithCursor (widget_name, *v, event. codeCursor (). value_or (- 1 ) );
117132 }
118133 if (auto v = event.text ()) {
119134 return onTextChanged (widget_name, *v);
0 commit comments