Skip to content

Commit 2942e01

Browse files
committed
feat(ssh-sessions): add panel search and keyboard navigation
1 parent 2415d74 commit 2942e01

4 files changed

Lines changed: 75 additions & 4 deletions

File tree

ssh-sessions/Panel.qml

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,40 @@ Item {
1717
readonly property var mainInstance: pluginApi?.mainInstance
1818
readonly property int activeCount: mainInstance?.activeCount ?? 0
1919

20+
// Search state
21+
property string searchQuery: ""
22+
property int selectedIndex: -1
23+
24+
function getFilteredHosts() {
25+
var hosts = root.mainInstance?.sortedHosts ?? []
26+
if (!root.searchQuery || root.searchQuery.trim() === "") return hosts
27+
28+
var results = FuzzySort.go(root.searchQuery, hosts, {
29+
keys: ["host.name", "host.hostname", "host.user"],
30+
limit: 50
31+
})
32+
return results.map(function(r) { return r.obj })
33+
}
34+
35+
function connectSelected() {
36+
var filtered = getFilteredHosts()
37+
if (root.selectedIndex >= 0 && root.selectedIndex < filtered.length) {
38+
root.mainInstance?.connectToHost(filtered[root.selectedIndex].host.name)
39+
}
40+
}
41+
42+
onVisibleChanged: {
43+
if (visible) {
44+
root.searchQuery = ""
45+
root.selectedIndex = -1
46+
Qt.callLater(function() {
47+
if (searchInput && searchInput.inputItem) {
48+
searchInput.inputItem.forceActiveFocus()
49+
}
50+
})
51+
}
52+
}
53+
2054
anchors.fill: parent
2155

2256
Rectangle {
@@ -45,6 +79,40 @@ Item {
4579
color: root.activeCount > 0 ? Color.mPrimary : Color.mOnSurfaceVariant
4680
}
4781

82+
// ======== Search input ========
83+
NTextInput {
84+
id: searchInput
85+
Layout.fillWidth: true
86+
placeholderText: pluginApi?.tr("panel.search")
87+
text: root.searchQuery
88+
onTextChanged: {
89+
root.searchQuery = text
90+
root.selectedIndex = text.length > 0 ? 0 : -1
91+
}
92+
93+
Keys.onDownPressed: {
94+
var filtered = root.getFilteredHosts()
95+
if (filtered.length > 0) {
96+
root.selectedIndex = Math.min(root.selectedIndex + 1, filtered.length - 1)
97+
}
98+
}
99+
Keys.onUpPressed: {
100+
if (root.selectedIndex > 0) {
101+
root.selectedIndex = root.selectedIndex - 1
102+
}
103+
}
104+
Keys.onReturnPressed: root.connectSelected()
105+
Keys.onEscapePressed: {
106+
if (root.searchQuery !== "") {
107+
root.searchQuery = ""
108+
searchInput.text = ""
109+
root.selectedIndex = -1
110+
} else {
111+
if (pluginApi) pluginApi.closePanel(pluginApi.panelOpenScreen)
112+
}
113+
}
114+
}
115+
48116
// ======== Scrollable host list ========
49117
NScrollView {
50118
id: hostScrollView
@@ -58,12 +126,14 @@ Item {
58126
spacing: Style.marginS
59127

60128
Repeater {
61-
model: root.mainInstance?.sortedHosts ?? []
129+
model: root.getFilteredHosts()
62130

63131
delegate: NBox {
64132
required property var modelData
133+
required property int index
65134
Layout.fillWidth: true
66135
Layout.preferredHeight: hostRow.implicitHeight + Style.marginM * 2
136+
color: index === root.selectedIndex ? Qt.alpha(Color.mPrimary, 0.15) : Color.mSurfaceVariant
67137

68138
RowLayout {
69139
id: hostRow

ssh-sessions/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Manage SSH connections from `~/.ssh/config` with active session detection and la
55
## Features
66

77
- **Bar Widget**: Shows active SSH session count with tooltip listing connected hosts
8-
- **Panel**: Host list with active/inactive status indicators and connect buttons
8+
- **Panel**: Host list with active/inactive status indicators, connect buttons, and fuzzy search with keyboard navigation
99
- **Launcher**: Type `>ssh` to search and connect to hosts
1010
- **Auto-detection**: Parses `~/.ssh/config` automatically and watches for changes
1111
- **Session Monitoring**: Polls active SSH connections via `pgrep`, filters ProxyJump sub-processes
@@ -20,7 +20,7 @@ Active sessions are detected by polling `pgrep -af "ssh "` at a configurable int
2020
## Usage
2121

2222
- **Bar widget**: Left click to open panel, right click for context menu, middle click to refresh
23-
- **Panel**: Click the terminal icon next to any host to connect
23+
- **Panel**: Type to search hosts with fuzzy matching. Arrow keys to navigate, Enter to connect, Escape to clear search or close panel. Click the terminal icon to connect directly
2424
- **Launcher**: Open launcher, type `>ssh`, select a host to connect
2525

2626
## Settings

ssh-sessions/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"panel": {
1111
"activeSessions": "Active sessions",
1212
"hosts": "Hosts",
13+
"search": "Search hosts...",
1314
"noActive": "No active sessions",
1415
"noHosts": "No hosts in ~/.ssh/config",
1516
"refresh": "Refresh",

ssh-sessions/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "ssh-sessions",
33
"name": "SSH Sessions",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"minNoctaliaVersion": "3.6.0",
66
"author": "adriamartin91",
77
"license": "MIT",

0 commit comments

Comments
 (0)