From e3a55b97fddf01755386e8850e49b18fafa4ad12 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Wed, 4 Nov 2026 01:30:31 -0800 Subject: [PATCH] Type: Text Tweaker leaves byte offsets to range_of Remove Text Tweaker's own start and end check: range_of already refuses a bad offset given with an id, and like the other type commands Text Tweaker now ignores start and end without one. The test's "2" case gets an id so it still reaches the check, and docs/mcp.md lists addon.type.textTweaker with the commands that refuse such offsets. --- crates/engine/src/cmd/addons/typetools.rs | 6 ------ crates/engine/src/cmd/addons/typetools/tests.rs | 2 +- docs/mcp.md | 4 ++-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/crates/engine/src/cmd/addons/typetools.rs b/crates/engine/src/cmd/addons/typetools.rs index 29ca6f6bf..320dce6b9 100644 --- a/crates/engine/src/cmd/addons/typetools.rs +++ b/crates/engine/src/cmd/addons/typetools.rs @@ -89,12 +89,6 @@ fn text_tweaker(s: &mut Session, p: &Value) -> Result { let mut rng = Rng::new(whole_or(p, "seed", 0, C)?); let skip = switch_or(p, "skipSpaces", true, C)?; let setup = s.doc()?.doc.setup.clone(); - // A range given as anything but whole bytes is refused, not read as all of the text. - for k in ["start", "end"] { - if p.get(k).is_some_and(|v| !v.is_null() && v.as_u64().is_none()) { - return Err(bad(C, format!("`{k}` must be a whole number of bytes"))); - } - } // At a caret, all of the object's text. let ranges = type_ranges(s, p, C, |text, _| Some((0, text.len())))?; // Each object's changed characters: (byte, its change), worked out before the edit. diff --git a/crates/engine/src/cmd/addons/typetools/tests.rs b/crates/engine/src/cmd/addons/typetools/tests.rs index fec04f9c6..6c56f6769 100644 --- a/crates/engine/src/cmd/addons/typetools/tests.rs +++ b/crates/engine/src/cmd/addons/typetools/tests.rs @@ -196,7 +196,7 @@ fn bad_params_are_refused_without_a_change() { json!({"ids": [999_999]}), json!({"id": id.0, "start": -1}), json!({"id": id.0, "start": 1, "end": 1.5}), - json!({"end": "2"}), + json!({"id": id.0, "end": "2"}), ] { assert!(s.execute(C, &p).is_err(), "{p}"); assert_eq!(s.doc().unwrap().doc, before, "{p}"); diff --git a/docs/mcp.md b/docs/mcp.md index e50412eb5..7c0499a06 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -1208,8 +1208,8 @@ and `amount` in `color.harmony`; `angle` in `paint.editGradient` and in the `gra swatch refuses a `tint` that is not a number with `` stop 0: `tint` must be a number ``. A byte offset must be a whole number of at least 0. `at` in `text.startList`, and `start` and `end` in -`text.editRange`, `text.getRange`, `text.setRangeStyle` and the `type.step`, `type.size.*`, `type.resetTracking` and -`type.resetHorizontalScale` commands given an `id`, refuse a negative or fractional number with +`text.editRange`, `text.getRange`, `text.setRangeStyle` and the `type.step`, `type.size.*`, `type.resetTracking`, +`type.resetHorizontalScale` and `addon.type.textTweaker` commands given an `id`, refuse a negative or fractional number with `` `at` must be a whole number ``, naming the key, and change nothing. `2.0` is read as `2`, and a null as the key left out. A step can use an earlier step's result, in `run` as in the `command_batch` tool. A parameter string that is exactly