@jx0/jmux 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/main.ts +27 -13
- package/src/sidebar.ts +9 -0
package/package.json
CHANGED
package/src/main.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { homedir } from "os";
|
|
|
12
12
|
|
|
13
13
|
// --- CLI commands (run and exit before TUI) ---
|
|
14
14
|
|
|
15
|
-
const VERSION = "0.3.
|
|
15
|
+
const VERSION = "0.3.7";
|
|
16
16
|
|
|
17
17
|
const HELP = `jmux — a persistent session sidebar for tmux
|
|
18
18
|
|
|
@@ -145,6 +145,7 @@ process.stdout.write("\x1b[?1049h");
|
|
|
145
145
|
process.stdout.write("\x1b[?1000h"); // mouse button tracking
|
|
146
146
|
process.stdout.write("\x1b[?1002h"); // mouse drag tracking
|
|
147
147
|
process.stdout.write("\x1b[?1006h"); // SGR extended mouse mode
|
|
148
|
+
process.stdout.write("\x1b[?2004h"); // bracketed paste mode
|
|
148
149
|
if (process.stdin.setRawMode) {
|
|
149
150
|
process.stdin.setRawMode(true);
|
|
150
151
|
}
|
|
@@ -251,21 +252,10 @@ async function switchSession(sessionId: string): Promise<void> {
|
|
|
251
252
|
await control.sendCommand(
|
|
252
253
|
`switch-client -c ${ptyClientName} -t '${sessionId}'`,
|
|
253
254
|
);
|
|
254
|
-
lastViewedTimestamps.set(sessionId, Math.floor(Date.now() / 1000));
|
|
255
|
-
sidebar.setActivity(sessionId, false);
|
|
256
255
|
currentSessionId = sessionId;
|
|
257
256
|
sidebar.setActiveSession(sessionId);
|
|
258
257
|
sidebar.scrollToActive();
|
|
259
258
|
renderFrame();
|
|
260
|
-
|
|
261
|
-
// Clear attention flag if set
|
|
262
|
-
try {
|
|
263
|
-
await control.sendCommand(
|
|
264
|
-
`set-option -t '${sessionId}' -u @jmux-attention`,
|
|
265
|
-
);
|
|
266
|
-
} catch {
|
|
267
|
-
// Option may not be set
|
|
268
|
-
}
|
|
269
259
|
} catch {
|
|
270
260
|
// Session may have been killed
|
|
271
261
|
}
|
|
@@ -289,12 +279,35 @@ function scheduleRender(): void {
|
|
|
289
279
|
}, 16); // ~60fps cap
|
|
290
280
|
}
|
|
291
281
|
|
|
282
|
+
// --- Indicator clearing on interaction ---
|
|
283
|
+
|
|
284
|
+
function clearSessionIndicators(): void {
|
|
285
|
+
if (!currentSessionId) return;
|
|
286
|
+
const id = currentSessionId;
|
|
287
|
+
|
|
288
|
+
// Only clear if there's something to clear
|
|
289
|
+
const needsActivityClear = sidebar.hasActivity(id);
|
|
290
|
+
const needsAttentionClear = sidebar.hasAttention(id);
|
|
291
|
+
if (!needsActivityClear && !needsAttentionClear) return;
|
|
292
|
+
|
|
293
|
+
lastViewedTimestamps.set(id, Math.floor(Date.now() / 1000));
|
|
294
|
+
sidebar.setActivity(id, false);
|
|
295
|
+
scheduleRender();
|
|
296
|
+
|
|
297
|
+
if (needsAttentionClear) {
|
|
298
|
+
control.sendCommand(`set-option -t '${id}' -u @jmux-attention`).catch(() => {});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
292
302
|
// --- Input Router ---
|
|
293
303
|
|
|
294
304
|
const inputRouter = new InputRouter(
|
|
295
305
|
{
|
|
296
306
|
sidebarCols: SIDEBAR_WIDTH,
|
|
297
|
-
onPtyData: (data) =>
|
|
307
|
+
onPtyData: (data) => {
|
|
308
|
+
pty.write(data);
|
|
309
|
+
clearSessionIndicators();
|
|
310
|
+
},
|
|
298
311
|
onSidebarClick: (row) => {
|
|
299
312
|
const session = sidebar.getSessionByRow(row);
|
|
300
313
|
if (session) switchSession(session.id);
|
|
@@ -500,6 +513,7 @@ async function start(): Promise<void> {
|
|
|
500
513
|
|
|
501
514
|
function cleanup(): void {
|
|
502
515
|
control.close().catch(() => {});
|
|
516
|
+
process.stdout.write("\x1b[?2004l"); // disable bracketed paste mode
|
|
503
517
|
process.stdout.write("\x1b[?1000l"); // disable mouse button tracking
|
|
504
518
|
process.stdout.write("\x1b[?1002l"); // disable mouse drag tracking
|
|
505
519
|
process.stdout.write("\x1b[?1006l"); // disable SGR mouse mode
|
package/src/sidebar.ts
CHANGED
|
@@ -198,6 +198,15 @@ export class Sidebar {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
hasActivity(sessionId: string): boolean {
|
|
202
|
+
return this.activitySet.has(sessionId);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
hasAttention(sessionId: string): boolean {
|
|
206
|
+
const session = this.sessions.find((s) => s.id === sessionId);
|
|
207
|
+
return session?.attention === true;
|
|
208
|
+
}
|
|
209
|
+
|
|
201
210
|
getDisplayOrderIds(): string[] {
|
|
202
211
|
return this.displayOrder
|
|
203
212
|
.map((idx) => this.sessions[idx]?.id)
|