aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-16 11:29:09 +0200
committerDanilo M. <danix@danix.xyz>2026-10-16 11:29:09 +0200
commitf200f7007272129bf59fef3e0b0e0a19f5bd362c (patch)
tree1a9b46f694b3722e9c4c6da5d6df0c082d126d40 /desktop/modules
parente97d5dea1d2b36ee9882de8699b382cf4fef64ae (diff)
downloadquickshell-f200f7007272129bf59fef3e0b0e0a19f5bd362c.tar.gz
quickshell-f200f7007272129bf59fef3e0b0e0a19f5bd362c.zip
feat(git): add keys per section with a + beside each heading
The single Add line at the bottom took a full section.key and left the user to type the section right. Each heading now carries a + that opens a key and value row under it; git config --add writes the key into that existing section, among its neighbours, rather than at the end of the file. The typed text lives on the page, not in the fields, so a failed add keeps it across the reload that rebuilds every row. A new section is made in the editor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules')
-rw-r--r--desktop/modules/git/GitPage.qml229
-rw-r--r--desktop/modules/git/README.md4
2 files changed, 131 insertions, 102 deletions
diff --git a/desktop/modules/git/GitPage.qml b/desktop/modules/git/GitPage.qml
index c91f050..6edf085 100644
--- a/desktop/modules/git/GitPage.qml
+++ b/desktop/modules/git/GitPage.qml
@@ -36,6 +36,20 @@ Column {
// the page is closed. Not named `gm`, the module's id (it would bind to itself).
required property QtObject owner
+ // The section whose add row is open, and what is typed in it. The text
+ // lives here rather than in the fields because every reload rebuilds the
+ // rows, and a failed add should keep what was typed.
+ property string adding: ""
+ property string newKey: ""
+ property string newValue: ""
+ onAddingChanged: { newKey = ""; newValue = ""; errors = ({}); }
+
+ function add() {
+ if (page.newKey.trim() === "") return;
+ page.write(["add", page.adding + "." + page.newKey.trim(), page.newValue], "add",
+ () => page.adding = "");
+ }
+
function tag(e) { return e.name + "=" + e.value; }
// One Process per call, so reads and writes never share one (a running
@@ -98,6 +112,94 @@ Column {
font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
}
+ // The add row under a section's heading: key and value. Enter in the key
+ // moves to the value, Enter there adds, Escape closes the row.
+ Component {
+ id: addRow
+ Column {
+ spacing: 4
+
+ Item {
+ width: parent.width
+ height: 34
+
+ Rectangle {
+ id: keyBox
+ anchors.left: parent.left
+ width: parent.width * 0.32
+ height: parent.height
+ radius: 8
+ color: Theme.surface
+ TextInput {
+ id: keyIn
+ anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
+ verticalAlignment: TextInput.AlignVCenter
+ clip: true
+ selectByMouse: true
+ color: Theme.text
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
+ text: page.newKey
+ onTextEdited: page.newKey = text
+ onAccepted: valIn.forceActiveFocus()
+ Keys.onEscapePressed: page.adding = ""
+ Component.onCompleted: forceActiveFocus()
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ visible: parent.text === ""
+ text: "key"
+ color: Theme.subtext
+ font: parent.font
+ }
+ }
+ }
+
+ Rectangle {
+ anchors { left: keyBox.right; leftMargin: 8; right: addBtn.left; rightMargin: 8 }
+ height: parent.height
+ radius: 8
+ color: Theme.surface
+ TextInput {
+ id: valIn
+ anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
+ verticalAlignment: TextInput.AlignVCenter
+ clip: true
+ selectByMouse: true
+ color: Theme.text
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
+ text: page.newValue
+ onTextEdited: page.newValue = text
+ onAccepted: page.add()
+ Keys.onEscapePressed: page.adding = ""
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ visible: parent.text === ""
+ text: "value"
+ color: Theme.subtext
+ font: parent.font
+ }
+ }
+ }
+
+ Button {
+ id: addBtn
+ anchors { right: parent.right; verticalCenter: parent.verticalCenter }
+ text: "Add"
+ enabled: page.newKey.trim() !== ""
+ onClicked: page.add()
+ }
+ }
+
+ Text {
+ width: parent.width
+ visible: !!page.errors.add
+ text: page.errors.add ?? ""
+ wrapMode: Text.Wrap
+ color: Theme.red
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
+ }
+ }
+ }
+
Repeater {
model: page.entries
@@ -110,14 +212,33 @@ Column {
spacing: 4
enabled: !page.busy
- // A section's heading, above its first row.
- Text {
+ // A section's heading, above its first row, with + to add a key
+ // to it. git config --add writes into the existing section, so
+ // the new key lands with its neighbours in the file.
+ Item {
+ id: heading
visible: row.index === 0 || page.entries[row.index - 1].section !== row.modelData.section
- topPadding: 10
- bottomPadding: 2
- text: row.modelData.section
- font { family: Theme.fontFamily; pixelSize: Theme.fontSize; bold: true }
- color: Theme.text
+ width: parent.width
+ height: 40
+
+ Text {
+ anchors { left: parent.left; bottom: parent.bottom; bottomMargin: 6 }
+ text: row.modelData.section
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize; bold: true }
+ color: Theme.text
+ }
+ Button {
+ anchors { right: parent.right; bottom: parent.bottom; bottomMargin: 2 }
+ text: "+"
+ onClicked: page.adding = page.adding === row.modelData.section ? "" : row.modelData.section
+ }
+ }
+
+ Loader {
+ width: parent.width
+ active: heading.visible && page.adding === row.modelData.section
+ visible: active
+ sourceComponent: addRow
}
// An Item with anchors, not a Row: a Row sizes to its children
@@ -183,98 +304,4 @@ Column {
}
}
}
-
- // Add: section.key and a value. The fields clear only when git took it.
- Text {
- topPadding: 10
- bottomPadding: 2
- text: "Add"
- font { family: Theme.fontFamily; pixelSize: Theme.fontSize; bold: true }
- color: Theme.text
- }
-
- Item {
- width: parent.width
- height: 34
- enabled: !page.busy
-
- Rectangle {
- id: newKeyBox
- anchors { left: parent.left }
- width: parent.width * 0.32
- height: parent.height
- radius: 8
- color: Theme.surface
- TextInput {
- id: newKey
- anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
- verticalAlignment: TextInput.AlignVCenter
- clip: true
- 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 === ""
- text: "section.key"
- color: Theme.subtext
- font: parent.font
- }
- }
- }
-
- Rectangle {
- anchors { left: newKeyBox.right; leftMargin: 8; right: addBtn.left; rightMargin: 8 }
- height: parent.height
- radius: 8
- color: Theme.surface
- TextInput {
- id: newValue
- anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
- verticalAlignment: TextInput.AlignVCenter
- clip: true
- 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
- visible: parent.text === ""
- text: "value"
- color: Theme.subtext
- font: parent.font
- }
- }
- }
-
- Button {
- id: addBtn
- anchors { right: parent.right; verticalCenter: parent.verticalCenter }
- text: "Add"
- enabled: newKey.text.trim() !== ""
- onClicked: page.write(["add", newKey.text.trim(), newValue.text], "add",
- () => { newKey.text = ""; newValue.text = ""; })
- }
- }
-
- Text {
- width: parent.width
- visible: !!page.errors.add
- text: page.errors.add ?? ""
- wrapMode: Text.Wrap
- color: Theme.red
- font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
- }
}
diff --git a/desktop/modules/git/README.md b/desktop/modules/git/README.md
index e5a4370..65f2a8a 100644
--- a/desktop/modules/git/README.md
+++ b/desktop/modules/git/README.md
@@ -5,7 +5,9 @@ page's "More git settings" button. Back returns to the user page.
One row per value, grouped by section in file order, so a key set several
times shows several rows. Enter saves a row, Escape undoes an edit, Remove
-drops that one value, and the Add row takes `section.key` and a value.
+drops that one value, and `+` beside a section's heading adds a key to
+that section, where `git config --add` writes it among its neighbours. A
+new section is made in the editor.
"Edit in editor" opens the file in Sublime Text.
`gitcfg` does every read and write, through `git config`, so the file keeps