fix(command_line): preserve argument casing

This commit is contained in:
Karim Jerbi committed 2026-10-18 10:54:24 +01:00
1 parent 43bdd18061
commit ddbfb8f72b
4 files changed
+40 -16

No files matched your search

+9 -4
View File
@@ -369,10 +369,15 @@ impl OpenCADStudio {
self.command_line.input.push_str(&s); self.command_line.input.push_str(&s);
} }
} else { } else {
// Command-line entry is shown uppercase — except in // Preserve case while entering a command or literal/free-text
// free-form text prompts, where the typed case is the // value. Active single-token prompt keywords keep their
// content (matches the CommandInput route). // established uppercase normalization.
if self.is_free_text_active() { let preserve_case = self.tabs[i].active_cmd.is_none()
|| self.is_free_text_active()
|| self.command_line.literal_spaces
|| self.command_line.input.starts_with('>')
|| s.starts_with('>');
if preserve_case {
self.command_line.input.push_str(&s); self.command_line.input.push_str(&s);
} else { } else {
self.command_line.input.push_str(&s.to_uppercase()); self.command_line.input.push_str(&s.to_uppercase());
+19 -11
View File
@@ -2796,16 +2796,16 @@ impl OpenCADStudio {
// string, a path, `UCS Z 90` as one line) can be typed; the `>` // string, a path, `UCS Z 90` as one line) can be typed; the `>`
// is stripped on submit. (Unfocused Space repeats the last // is stripped on submit. (Unfocused Space repeats the last
// command via CommandSpace.) // command via CommandSpace.)
// Command-line entry is shown uppercase — except while the // Preserve command-entry input exactly. Active single-token
// active command collects free-form text (cell text, TEXT / // prompt keywords keep their established uppercase behavior;
// MTEXT bodies), where the typed case is the content and // `CommandLine::submit` uppercases only the command verb.
// Space must stay in the buffer.
let text_with_spaces = self.is_free_text_active(); let text_with_spaces = self.is_free_text_active();
let active_prompt = self.tabs[self.active_tab].active_cmd.is_some();
let literal = self.command_line.literal_spaces || s.starts_with('>'); let literal = self.command_line.literal_spaces || s.starts_with('>');
let s = if text_with_spaces || literal { let s = if active_prompt && !text_with_spaces && !literal {
s
} else {
s.to_uppercase() s.to_uppercase()
} else {
s
}; };
// A space submits (acts like Enter). The whole value is handed to // A space submits (acts like Enter). The whole value is handed to
// the submit path, which tokenises multi-token lines — so a typed // the submit path, which tokenises multi-token lines — so a typed
@@ -12849,13 +12849,13 @@ mod free_text_entry_tests {
} }
#[test] #[test]
fn normal_commands_still_uppercase_and_submit_on_space() { fn command_input_preserves_case_and_submits_multi_token_lines() {
let mut app = OpenCADStudio::new_for_test(); let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#); app.automation_op(r#"{"op":"new"}"#);
// No free-text command active: entry is uppercased… // Ordinary command entry now retains its typed case…
let _ = app.update(Message::CommandInput("lin".into())); let _ = app.update(Message::CommandInput("lin".into()));
assert_eq!(app.command_line.input, "LIN"); assert_eq!(app.command_line.input, "lin");
// …and a pasted multi-token line runs as a command, not as text. // …and a pasted multi-token line still submits as a command.
let _ = app.update(Message::CommandInput("LINE 0,0 10,10".into())); let _ = app.update(Message::CommandInput("LINE 0,0 10,10".into()));
assert!( assert!(
app.command_line.input.is_empty(), app.command_line.input.is_empty(),
@@ -12864,6 +12864,14 @@ mod free_text_entry_tests {
assert_eq!(app.text_entry_mode(), TextEntryMode::Command); assert_eq!(app.text_entry_mode(), TextEntryMode::Command);
} }
#[test]
fn typed_command_characters_preserve_case() {
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
let _ = app.update(Message::CommandAppendChar("MyPath".into()));
assert_eq!(app.command_line.input, "MyPath");
}
#[test] #[test]
fn literal_command_input_preserves_case() { fn literal_command_input_preserves_case() {
let mut app = OpenCADStudio::new_for_test(); let mut app = OpenCADStudio::new_for_test();
+2 -1
View File
@@ -1450,6 +1450,7 @@ mod ds_set_handle_tests {
.get(&old_name) .get(&old_name)
.unwrap() .unwrap()
.clone(); .clone();
style.dimdle = 7.0;
let before = style.dimdle; let before = style.dimdle;
app.tabs[i].scene.document.dim_styles.remove(&old_name); app.tabs[i].scene.document.dim_styles.remove(&old_name);
style.name = "ARCH|Imported".to_string(); style.name = "ARCH|Imported".to_string();
@@ -1459,7 +1460,7 @@ mod ds_set_handle_tests {
assert!(app.selected_dimstyle_is_read_only()); assert!(app.selected_dimstyle_is_read_only());
app.ds_dimdle = "456".to_string(); app.ds_dimdle = "456".to_string();
app.apply_dimstyle_bufs(i); app.apply_dimstyle_bufs(i);
assert_ne!( assert_eq!(
app.tabs[i] app.tabs[i]
.scene .scene
.document .document
+10
View File
@@ -1429,6 +1429,16 @@ mod tests {
assert!(m.iter().any(|c| c == "LINE"), "got {m:?}"); assert!(m.iter().any(|c| c == "LINE"), "got {m:?}");
} }
#[test]
fn submit_uppercases_only_the_command_verb() {
let mut line = CommandLine::new();
line.input = "open /home/u/My.dwg --PluginArg".to_string();
assert_eq!(
line.submit().as_deref(),
Some("OPEN /home/u/My.dwg --PluginArg")
);
}
#[test] #[test]
fn aliases_are_hidden_but_their_command_survives() { fn aliases_are_hidden_but_their_command_survives() {
// The alias `L` is dropped from suggestions while `LINE` (its target) // The alias `L` is dropped from suggestions while `LINE` (its target)