Merge pull request #1635 from Hamza0101/entsel-pickbox

AutoLISP: an entsel prompt shows the pick box whatever its message says
This commit is contained in:
skylar taylor-barrick
2026-10-22 07:50:47 -06:00
committed by GitHub
3 changed files with 48 additions and 4 deletions
+6
View File
@@ -67,6 +67,12 @@ impl GetRequest {
let mut p = Prompt::new(message, accept).base_opt(base);
p.keywords = self.initget.keywords.clone();
p.raw = true;
// `entsel`/`nentsel` pick one object. The routine writes the message, so the prompt says
// so itself rather than being read for the word "Select" -- with a message of its own
// ("\nSelect the second line: ", or no mention of selecting at all) the pick box went
// missing, while the same call without one got it from the default "Select object: "
// (#1598).
p.picks_one = matches!(self.kind, GetKind::EntSel);
p
}
+31
View File
@@ -485,6 +485,37 @@ fn hostile_lisp_never_panics() {
assert!(!s.lisp_running());
}
/// `entsel` and `nentsel` pick one object, so the cursor shows the pick box at their prompt. It
/// was read off the message's first word, and a routine's own message begins with a newline -- so
/// the same call showed the pick box without a message and lost it with one (#1598).
#[test]
fn an_entsel_prompt_picks_objects_whatever_its_message_says() {
let mut s = session();
// No message: the default "Select object: ".
s.cmdline("(nentsel)").unwrap();
assert!(s.current_prompt().unwrap().picks_objects(), "{}", s.prompt_text());
s.cancel();
// The reported case: the routine's own message, starting with a newline.
s.cmdline("(nentsel \"\nSelect second line or polyline: \")").unwrap();
assert!(s.current_prompt().unwrap().picks_objects(), "{}", s.prompt_text());
s.cancel();
// Wording that never says "select" picks an object just the same.
s.cmdline("(entsel \"\nPick a line: \")").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]
fn a_waiting_routine_is_a_prompt_with_a_rubber_band() {
let mut s = session();
+11 -4
View File
@@ -62,6 +62,10 @@ pub struct Prompt {
/// pointer boxes.
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub distance: bool,
/// The prompt picks one object whatever it says: an AutoLISP `entsel`/`nentsel`, whose message
/// the routine writes, so it cannot be read for the word "Select" (#1598).
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub picks_one: bool,
}
/// Parse `@distance<angle` (relative polar), returning `(distance, angle in radians)`.
@@ -128,11 +132,14 @@ impl Prompt {
self.default = Some(d.into());
self
}
/// The prompt picks objects: a "Select objects" prompt, or a point prompt whose click selects
/// one object ("Select object to offset", "Select first line"…, the commands that pick a
/// single object themselves). The UI shows the pick box there.
/// 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. 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.accept.select || (self.accept.point && self.message.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 {