Read a prompt's wording only where the engine wrote it

The pick-box heuristic read the message for a leading "Select", and
this branch had widened it past leading whitespace so that a routine's
own message would be read the same way. That makes a plain point prompt
look like a pick: (getpoint "\nSelect a point: ") showed the pick box
and lost its point modifiers, since pointmod refuses them wherever
picks_objects holds.

A routine writes all of its own message (raw), and says through
picks_one when it picks an object, so the wording needs reading only
where the engine wrote it. Covered for both spellings a routine might
use, with and without the leading newline.
This commit is contained in:
Hamza
2026-10-20 00:31:05 +05:00
parent b72680cfb7
commit 27861ad0ed
2 changed files with 12 additions and 7 deletions
+8 -4
View File
@@ -473,10 +473,14 @@ fn an_entsel_prompt_picks_objects_whatever_its_message_says() {
assert!(s.current_prompt().unwrap().picks_objects(), "{}", s.prompt_text());
s.cancel();
// A point prompt is not a pick, and keeps its point modifiers.
s.cmdline("(getpoint \"\nSpecify a point: \")").unwrap();
assert!(!s.current_prompt().unwrap().picks_objects(), "{}", s.prompt_text());
s.cancel();
// A point prompt is not a pick, and keeps its point modifiers -- including one whose own
// message happens to begin with the word the built-in commands are read by. `picks_one` says
// which calls pick, so the wording is only ever read where the engine wrote it (#1635 review).
for point in ["(getpoint \"\nSpecify a point: \")", "(getpoint \"\nSelect a point: \")", "(getpoint \"Select a point: \")"] {
s.cmdline(point).unwrap();
assert!(!s.current_prompt().unwrap().picks_objects(), "{point}: {}", s.prompt_text());
s.cancel();
}
}
#[test]
+4 -3
View File
@@ -135,10 +135,11 @@ impl Prompt {
/// The prompt picks objects: a "Select objects" prompt, one that says it picks a single object
/// ([`Prompt::picks_one`]), or a point prompt whose click selects one ("Select object to
/// offset", "Select first line"…, the commands that pick a single object themselves). The UI
/// shows the pick box there. A routine's own prompt usually begins with a newline, so the
/// wording is read past the leading whitespace.
/// shows the pick box there. The wording is only read where the engine wrote it: a routine
/// writes its own message (`raw`), which may open with "Select" and still ask for a point,
/// and says through `picks_one` when it picks instead (#1635 review).
pub fn picks_objects(&self) -> bool {
self.picks_one || self.accept.select || (self.accept.point && self.message.trim_start().starts_with("Select"))
self.picks_one || self.accept.select || (self.accept.point && !self.raw && self.message.starts_with("Select"))
}
/// "Specify next point or [Undo/Close] <default>:".
pub fn display(&self) -> String {