Aufräumrunde zur Bugfix-Runde: Suche entzerrt, Flatten-Fix vervollständigt

- archive_search: match_expr in search() aufgelöst. sanitize_query lief zweimal
  pro Anfrage, und die Leer-Entscheidung stand an zwei Stellen mit leicht
  abweichender Bedingung.
- Der Tag-Filter geht jetzt durch dieselbe Quoting-Regel wie der Volltext. Ein
  leerer Tag ergab tags:"" und damit einen Syntaxfehler — erreichbar durch das
  angetippte #, den ersten Tastendruck jeder Tag-Suche.
- sanitize_query von 26 auf 12 Zeilen: split('"') und split_whitespace statt
  handgeschriebenem Tokenizer. Gleiches Ergebnis fuer alle Testeingaben.
- TerminalConfig bekommt ebenfalls serde flatten. Der Block wird als Ganzes
  mitgeschrieben, ein terminal.fontSize waere also weiterhin verloren gegangen;
  set_terminal_config_in traegt die unbekannten Keys jetzt herueber.
- markdown.test.ts enthielt ein literales NUL-Byte, wodurch git die Datei als
  binaer behandelte. Der Test erzeugt das Zeichen jetzt selbst.
- Kleineres: commands_delete-Bedingung als direkter Vergleich, eine
  Verschachtelungsebene in pool.rs, zwei redundante Kommentarbloecke.
  commands_delete benennt sich in der Doku als Provisorium.
This commit is contained in:
marcusH
2026-07-19 23:22:25 +02:00
parent b127269e89
commit e245600235
8 changed files with 119 additions and 80 deletions
+35 -3
View File
@@ -55,11 +55,15 @@ pub struct TerminalConfig {
pub icon: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
/// Unbekannte Keys, wie bei `ProjectConfig` — der verlustbehaftete
/// Round-Trip gilt hier genauso, weil dieser Block mitgeschrieben wird.
#[serde(flatten)]
pub rest: serde_json::Map<String, serde_json::Value>,
}
impl TerminalConfig {
pub(crate) fn is_empty(&self) -> bool {
self.theme.is_none() && self.icon.is_none() && self.title.is_none()
self.theme.is_none() && self.icon.is_none() && self.title.is_none() && self.rest.is_empty()
}
}
@@ -477,6 +481,9 @@ pub(crate) fn set_terminal_config_in(
terminal.icon = Some(name);
}
}
// Die Terminal-Config kommt aus der Oberfläche und kennt nur die drei Felder;
// unbekannte Keys der bestehenden Datei würden sonst hier verloren gehen.
terminal.rest = std::mem::take(&mut cfg.terminal.rest);
cfg.terminal = terminal;
write_project_config_in(paths, project, &cfg)?;
crate::platform::write_terminal_desktop(paths, project, &cfg.terminal);
@@ -510,7 +517,8 @@ mod tests {
let cfg_path = project_config_path(&p, "proj").unwrap();
fs::write(
&cfg_path,
r#"{"archiveHome":"~/archiv","zukunftsfeld":{"a":1},"terminal":{"theme":"monokai"}}"#,
r#"{"archiveHome":"~/archiv","zukunftsfeld":{"a":1},
"terminal":{"theme":"monokai","fontSize":13}}"#,
)
.unwrap();
@@ -521,9 +529,33 @@ mod tests {
assert_eq!(v["archiveHome"], "~/archiv");
assert_eq!(v["zukunftsfeld"]["a"], 1);
assert_eq!(v["terminal"]["theme"], "monokai");
// Auch im verschachtelten terminal-Block, der als Ganzes mitgeschrieben wird.
assert_eq!(v["terminal"]["fontSize"], 13);
assert_eq!(v["pool"], serde_json::Value::String(pool));
}
/// Das Setzen der Terminal-Config kommt aus der Oberfläche und kennt nur
/// theme/icon/title — unbekannte Keys müssen trotzdem stehen bleiben.
#[test]
fn terminal_config_setzen_erhaelt_fremde_keys() {
let p = tmp_paths();
create_project(&p, "proj").unwrap();
let cfg_path = project_config_path(&p, "proj").unwrap();
fs::write(&cfg_path, r#"{"terminal":{"theme":"monokai","fontSize":13}}"#).unwrap();
set_terminal_config_in(
&p,
"proj",
TerminalConfig { theme: Some("dracula".into()), ..Default::default() },
)
.unwrap();
let v: serde_json::Value =
serde_json::from_str(&fs::read_to_string(&cfg_path).unwrap()).unwrap();
assert_eq!(v["terminal"]["theme"], "dracula");
assert_eq!(v["terminal"]["fontSize"], 13);
}
#[test]
fn projekt_wizard_scaffold() {
let p = tmp_paths();
@@ -537,8 +569,8 @@ mod tests {
true,
TerminalConfig {
theme: Some("dracula".into()),
icon: None,
title: Some("Neu".into()),
..Default::default()
},
true,
)