launcher: python execution like calculator functionality
This commit is contained in:
parent
4897b37882
commit
47dfcf4baf
4 changed files with 150 additions and 2 deletions
|
|
@ -38,6 +38,14 @@ JsonObject {
|
|||
enabled: true,
|
||||
dangerous: false
|
||||
},
|
||||
{
|
||||
name: "Python",
|
||||
icon: "code",
|
||||
description: "Execute Python one-liners",
|
||||
command: ["autocomplete", "python"],
|
||||
enabled: true,
|
||||
dangerous: false
|
||||
},
|
||||
{
|
||||
name: "Scheme",
|
||||
icon: "palette",
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ StyledListView {
|
|||
const text = search.text;
|
||||
const prefix = Config.launcher.actionPrefix;
|
||||
if (text.startsWith(prefix)) {
|
||||
for (const action of ["calc", "scheme", "variant"])
|
||||
for (const action of ["calc", "python", "scheme", "variant"])
|
||||
if (text.startsWith(`${prefix}${action} `))
|
||||
return action;
|
||||
|
||||
|
|
@ -92,6 +92,14 @@ StyledListView {
|
|||
root.delegate: calcItem
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "python"
|
||||
|
||||
PropertyChanges {
|
||||
model.values: [0]
|
||||
root.delegate: pythonItem
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "scheme"
|
||||
|
||||
|
|
@ -239,6 +247,14 @@ StyledListView {
|
|||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: pythonItem
|
||||
|
||||
PythonItem {
|
||||
list: root
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: schemeItem
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ Item {
|
|||
Wallpapers.setWallpaper(currentItem.modelData.path);
|
||||
root.visibilities.launcher = false;
|
||||
} else if (text.startsWith(Config.launcher.actionPrefix)) {
|
||||
if (text.startsWith(`${Config.launcher.actionPrefix}calc `))
|
||||
if (text.startsWith(`${Config.launcher.actionPrefix}calc `) || text.startsWith(`${Config.launcher.actionPrefix}python `))
|
||||
currentItem.onClicked();
|
||||
else
|
||||
currentItem.modelData.onClicked(list.currentList);
|
||||
|
|
|
|||
124
modules/launcher/items/PythonItem.qml
Normal file
124
modules/launcher/items/PythonItem.qml
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import qs.components
|
||||
import qs.services
|
||||
import qs.config
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property var list
|
||||
readonly property string code: list.search.text.slice(`${Config.launcher.actionPrefix}python `.length)
|
||||
|
||||
function onClicked(): void {
|
||||
// Execute Python code and copy result to clipboard
|
||||
// Escape single quotes in code for shell safety
|
||||
const escapedCode = root.code.replace(/'/g, "'\\''");
|
||||
Quickshell.execDetached(["sh", "-c", `python3 -c '${escapedCode}' 2>&1 | wl-copy`]);
|
||||
root.list.visibilities.launcher = false;
|
||||
}
|
||||
|
||||
implicitHeight: Config.launcher.sizes.itemHeight
|
||||
|
||||
anchors.left: parent?.left
|
||||
anchors.right: parent?.right
|
||||
|
||||
StateLayer {
|
||||
radius: Appearance.rounding.normal
|
||||
|
||||
function onClicked(): void {
|
||||
root.onClicked();
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Appearance.padding.larger
|
||||
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
MaterialIcon {
|
||||
text: "code"
|
||||
font.pointSize: Appearance.font.size.extraLarge
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: result
|
||||
|
||||
color: {
|
||||
if (!root.code)
|
||||
return Colours.palette.m3onSurfaceVariant;
|
||||
return Colours.palette.m3onSurface;
|
||||
}
|
||||
|
||||
text: root.code.length > 0 ? qsTr("Press Enter to execute: %1").arg(root.code) : qsTr("Type Python code to execute")
|
||||
elide: Text.ElideLeft
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
color: Colours.palette.m3tertiary
|
||||
radius: Appearance.rounding.normal
|
||||
clip: true
|
||||
|
||||
implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Appearance.padding.normal * 2
|
||||
implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Appearance.padding.small * 2
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
StateLayer {
|
||||
id: stateLayer
|
||||
|
||||
color: Colours.palette.m3onTertiary
|
||||
|
||||
function onClicked(): void {
|
||||
const escapedCode = root.code.replace(/'/g, "'\\''");
|
||||
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `python3 -i -c '${escapedCode}'`]);
|
||||
root.list.visibilities.launcher = false;
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: label
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: icon.left
|
||||
anchors.rightMargin: Appearance.spacing.small
|
||||
|
||||
text: qsTr("Open in terminal")
|
||||
color: Colours.palette.m3onTertiary
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
|
||||
opacity: stateLayer.containsMouse ? 1 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
id: icon
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Appearance.padding.normal
|
||||
|
||||
text: "open_in_new"
|
||||
color: Colours.palette.m3onTertiary
|
||||
font.pointSize: Appearance.font.size.large
|
||||
}
|
||||
|
||||
Behavior on implicitWidth {
|
||||
Anim {
|
||||
easing.bezierCurve: Appearance.anim.curves.emphasized
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue