pub struct MotionResult {
pub target: Position,
pub linewise: bool,
pub exclusive: Option<bool>,
pub notice: Option<MotionNotice>,
pub curswant: Option<Curswant>,
}Expand description
What a motion’s evaluator returned.
Fields§
§target: PositionWhere the cursor lands.
linewise: booltrue if the motion is linewise (ranges expand to whole lines on
resolution).
exclusive: Option<bool>VM.3c: override MotionSpec::exclusive for THIS invocation.
None — the overwhelming default — means “use the spec’s flag”.
§Why the axis had to move
linewise has always travelled with the RESULT and exclusive with
the SPEC, and nothing needed the asymmetry resolved until a motion
existed whose exclusivity is not knowable until it runs. ; is that
motion: it repeats whatever f / F / t / T came last, and vim
gives it that motion’s exclusivity — f and t are inclusive, F
and T are not. A single flag on the ; spec has to be wrong half
the time, and it was: d, after an f deleted one character too
many, because , acts as F while the spec said inclusive.
Not on the WIT boundary. A plugin declares exclusivity on its
MotionSpec, which is the right place for every motion that knows its
own answer, so from_wit decodes this as None deliberately rather
than for want of a field to read.
notice: Option<MotionNotice>VM.3d-2: a notice for the user, which the dispatcher echoes alongside the motion’s effect — the search wrap. Not on the WIT boundary: a plugin motion reports none.
curswant: Option<Curswant>VM.3g-3: override the goal column for THIS invocation, the way
Self::exclusive overrides the spec’s flag. None — the
overwhelming default — means “apply the spec’s CurswantEffect”.
§Why a motion has to be able to say it
CurswantEffect can express “keep the goal”, “pin it to the line end”
and “take it from where I landed”, and for every motion in vim except
two that is the whole story. gj / gk are the exception: they aim at
a screen column that the reached display row may be too short to hold,
and vim records the aim, not the landing.
Measured in vim 9.2 (vimcheck_scroll_curswant.vim), wrap at 80 over a
240-char line then a 100-char line:
gj -> line 2 row 1 col=80 curswant=80
gj -> line 2 row 2 (CLAMPED) col=100 curswant=160160 is the column the motion wanted — next_start + goal, before the
clamp to the row’s 100 characters. Recording the landing instead loses
the aim permanently, so a following j onto a long line returns to 100
where vim returns to 160.
SetFromTarget cannot express this because the target IS the clamped
landing, and Keep cannot because the goal genuinely changes on every
gj (it tracks the screen column down the wrapped rows). Only the
motion knows the unclamped aim, so only the motion can report it.
Not on the WIT boundary, for the same reason exclusive is not: a
plugin motion declares its effect on the spec, which is the right place
for every motion that knows its own answer. from_wit decodes this as
None deliberately rather than for want of a field to read.
Trait Implementations§
Source§impl Clone for MotionResult
impl Clone for MotionResult
Source§fn clone(&self) -> MotionResult
fn clone(&self) -> MotionResult
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more