From e97d5dea1d2b36ee9882de8699b382cf4fef64ae Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 16 Oct 2026 11:22:41 +0200 Subject: fix(git): refuse duplicate values, show list errors, Escape on Add Review findings. With a key holding the same value twice, --fixed-value --replace-all rewrote both and merged two rows into one, and --unset failed on both; gitcfg now counts the matches and refuses anything but exactly one, pointing at the editor. A file git cannot parse made list print nothing, which the page drew as an empty config; list now prints git's error as an error= line and the page shows it. Escape in the Add fields clears the typed text before it leaves the page, as a row's edit is undone first. Co-Authored-By: Claude Opus 5.5 --- desktop/modules/git/GitPage.qml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'desktop/modules/git/GitPage.qml') diff --git a/desktop/modules/git/GitPage.qml b/desktop/modules/git/GitPage.qml index c1bffb5..c91f050 100644 --- a/desktop/modules/git/GitPage.qml +++ b/desktop/modules/git/GitPage.qml @@ -31,6 +31,7 @@ Column { // write because the value did not change. property var errors: ({}) property bool busy: false + property string loadError: "" // The module, which outlives the page: a write in flight finishes even if // the page is closed. Not named `gm`, the module's id (it would bind to itself). required property QtObject owner @@ -58,7 +59,10 @@ Column { function load() { page.run([page.ctl, "list"], out => { - page.entries = G.parse(out); + // gitcfg reports a file git cannot parse as one error= line; + // without it the page would draw an empty config. + page.loadError = out.startsWith("error=") ? out.slice(6).trim() : ""; + page.entries = page.loadError ? [] : G.parse(out); page.busy = false; }); } @@ -85,6 +89,15 @@ Column { onClicked: Quickshell.execDetached(["sublime_text", Quickshell.env("HOME") + "/.gitconfig"]) } + Text { + width: parent.width + visible: page.loadError !== "" + text: page.loadError + wrapMode: Text.Wrap + color: Theme.red + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + } + Repeater { model: page.entries @@ -200,6 +213,12 @@ Column { selectByMouse: true color: Theme.text font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + // Typed text is cleared first, as a row's edit is undone; + // an empty field lets Escape through, to leave the page. + Keys.onEscapePressed: event => { + if (text !== "") text = ""; + else event.accepted = false; + } Text { anchors.verticalCenter: parent.verticalCenter visible: parent.text === "" @@ -223,6 +242,12 @@ Column { selectByMouse: true color: Theme.text font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + // Typed text is cleared first, as a row's edit is undone; + // an empty field lets Escape through, to leave the page. + Keys.onEscapePressed: event => { + if (text !== "") text = ""; + else event.accepted = false; + } onAccepted: if (addBtn.enabled) addBtn.clicked() Text { anchors.verticalCenter: parent.verticalCenter -- cgit v1.2.3