numux 2.13.1 → 2.14.0
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/README.md +8 -3
- package/dist/man/numux.1 +38 -8
- package/dist/numux.js +214 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -477,14 +477,19 @@ Keybindings are shown in the status bar at the bottom of the app. Panes are read
|
|
|
477
477
|
<!-- generated:keybindings -->
|
|
478
478
|
| Key | Action |
|
|
479
479
|
|-----|--------|
|
|
480
|
-
| `←`/`→` or `1`-`9` |
|
|
481
|
-
| `
|
|
480
|
+
| `←`/`→` or `1`-`9` | Switch tabs |
|
|
481
|
+
| `Enter` | Input mode |
|
|
482
|
+
| `F` | Search |
|
|
482
483
|
| `R` | Restart |
|
|
484
|
+
| `Shift+R` | Restart all |
|
|
483
485
|
| `S` | Stop/start |
|
|
484
|
-
| `F` | Search |
|
|
485
486
|
| `Y` | Copy all |
|
|
486
487
|
| `L` | Clear |
|
|
487
488
|
| `T` | Timestamps |
|
|
489
|
+
| `↑↓` | Scroll line |
|
|
490
|
+
| `Shift+↑↓` | Top/bottom |
|
|
491
|
+
| `G/Shift+G` | Top/bottom |
|
|
492
|
+
| `PgUp/PgDn` | Scroll page |
|
|
488
493
|
| `O` | Open logs |
|
|
489
494
|
| `Ctrl+Click` | Open link |
|
|
490
495
|
| `Ctrl+C` | Quit |
|
package/dist/man/numux.1
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.TH "NUMUX" "1" "April 2026" "2.
|
|
1
|
+
.TH "NUMUX" "1" "April 2026" "2.14.0" "numux manual"
|
|
2
2
|
.SH "NAME"
|
|
3
3
|
\fBnumux\fR
|
|
4
4
|
.P
|
|
@@ -949,13 +949,19 @@ T}
|
|
|
949
949
|
T{
|
|
950
950
|
\fB←\fP/\fB→\fP or \fB1\fP\-\fB9\fP
|
|
951
951
|
T}|T{
|
|
952
|
-
|
|
952
|
+
Switch tabs
|
|
953
953
|
T}
|
|
954
954
|
_
|
|
955
955
|
T{
|
|
956
|
-
\
|
|
956
|
+
\fBEnter\fP
|
|
957
957
|
T}|T{
|
|
958
|
-
|
|
958
|
+
Input mode
|
|
959
|
+
T}
|
|
960
|
+
_
|
|
961
|
+
T{
|
|
962
|
+
\fBF\fP
|
|
963
|
+
T}|T{
|
|
964
|
+
Search
|
|
959
965
|
T}
|
|
960
966
|
_
|
|
961
967
|
T{
|
|
@@ -965,15 +971,15 @@ Restart
|
|
|
965
971
|
T}
|
|
966
972
|
_
|
|
967
973
|
T{
|
|
968
|
-
\
|
|
974
|
+
\fBShift+R\fP
|
|
969
975
|
T}|T{
|
|
970
|
-
|
|
976
|
+
Restart all
|
|
971
977
|
T}
|
|
972
978
|
_
|
|
973
979
|
T{
|
|
974
|
-
\
|
|
980
|
+
\fBS\fP
|
|
975
981
|
T}|T{
|
|
976
|
-
|
|
982
|
+
Stop/start
|
|
977
983
|
T}
|
|
978
984
|
_
|
|
979
985
|
T{
|
|
@@ -995,6 +1001,30 @@ Timestamps
|
|
|
995
1001
|
T}
|
|
996
1002
|
_
|
|
997
1003
|
T{
|
|
1004
|
+
\fB↑↓\fP
|
|
1005
|
+
T}|T{
|
|
1006
|
+
Scroll line
|
|
1007
|
+
T}
|
|
1008
|
+
_
|
|
1009
|
+
T{
|
|
1010
|
+
\fBShift+↑↓\fP
|
|
1011
|
+
T}|T{
|
|
1012
|
+
Top/bottom
|
|
1013
|
+
T}
|
|
1014
|
+
_
|
|
1015
|
+
T{
|
|
1016
|
+
\fBG/Shift+G\fP
|
|
1017
|
+
T}|T{
|
|
1018
|
+
Top/bottom
|
|
1019
|
+
T}
|
|
1020
|
+
_
|
|
1021
|
+
T{
|
|
1022
|
+
\fBPgUp/PgDn\fP
|
|
1023
|
+
T}|T{
|
|
1024
|
+
Scroll page
|
|
1025
|
+
T}
|
|
1026
|
+
_
|
|
1027
|
+
T{
|
|
998
1028
|
\fBO\fP
|
|
999
1029
|
T}|T{
|
|
1000
1030
|
Open logs
|
package/dist/numux.js
CHANGED
|
@@ -456,14 +456,19 @@ Unmatched references are left as-is (the shell will expand \`$db\` as empty + \`
|
|
|
456
456
|
<!-- generated:keybindings -->
|
|
457
457
|
| Key | Action |
|
|
458
458
|
|-----|--------|
|
|
459
|
-
| \`\u2190\`/\`\u2192\` or \`1\`-\`9\` |
|
|
460
|
-
| \`
|
|
459
|
+
| \`\u2190\`/\`\u2192\` or \`1\`-\`9\` | Switch tabs |
|
|
460
|
+
| \`Enter\` | Input mode |
|
|
461
|
+
| \`F\` | Search |
|
|
461
462
|
| \`R\` | Restart |
|
|
463
|
+
| \`Shift+R\` | Restart all |
|
|
462
464
|
| \`S\` | Stop/start |
|
|
463
|
-
| \`F\` | Search |
|
|
464
465
|
| \`Y\` | Copy all |
|
|
465
466
|
| \`L\` | Clear |
|
|
466
467
|
| \`T\` | Timestamps |
|
|
468
|
+
| \`\u2191\u2193\` | Scroll line |
|
|
469
|
+
| \`Shift+\u2191\u2193\` | Top/bottom |
|
|
470
|
+
| \`G/Shift+G\` | Top/bottom |
|
|
471
|
+
| \`PgUp/PgDn\` | Scroll page |
|
|
467
472
|
| \`O\` | Open logs |
|
|
468
473
|
| \`Ctrl+Click\` | Open link |
|
|
469
474
|
| \`Ctrl+C\` | Quit |
|
|
@@ -541,7 +546,7 @@ var init_help = __esm(() => {
|
|
|
541
546
|
var require_package = __commonJS((exports, module) => {
|
|
542
547
|
module.exports = {
|
|
543
548
|
name: "numux",
|
|
544
|
-
version: "2.
|
|
549
|
+
version: "2.14.0",
|
|
545
550
|
description: "Terminal multiplexer with dependency orchestration",
|
|
546
551
|
type: "module",
|
|
547
552
|
license: "MIT",
|
|
@@ -2500,9 +2505,7 @@ class ProcessRunner {
|
|
|
2500
2505
|
}
|
|
2501
2506
|
}
|
|
2502
2507
|
write(data) {
|
|
2503
|
-
|
|
2504
|
-
this.proc.terminal.write(data);
|
|
2505
|
-
}
|
|
2508
|
+
this.proc?.terminal?.write(data);
|
|
2506
2509
|
}
|
|
2507
2510
|
}
|
|
2508
2511
|
|
|
@@ -2895,7 +2898,10 @@ function evaluateCondition(condition) {
|
|
|
2895
2898
|
}
|
|
2896
2899
|
|
|
2897
2900
|
// src/ui/app.ts
|
|
2898
|
-
import { BoxRenderable, createCliRenderer } from "@opentui/core";
|
|
2901
|
+
import { BoxRenderable as BoxRenderable3, createCliRenderer } from "@opentui/core";
|
|
2902
|
+
|
|
2903
|
+
// src/ui/help-overlay.ts
|
|
2904
|
+
import { BoxRenderable, TextRenderable } from "@opentui/core";
|
|
2899
2905
|
|
|
2900
2906
|
// src/ui/keybindings.ts
|
|
2901
2907
|
var SHORTCUTS = {
|
|
@@ -2910,20 +2916,105 @@ var SHORTCUTS = {
|
|
|
2910
2916
|
scrollToBottom: { key: "g", label: "Shift+G", description: "bottom", shift: true },
|
|
2911
2917
|
openLogs: { key: "o", label: "O", description: "open logs" }
|
|
2912
2918
|
};
|
|
2913
|
-
|
|
2914
|
-
[
|
|
2919
|
+
function toHintPair(hint) {
|
|
2920
|
+
return Array.isArray(hint) ? hint : [hint.label, hint.description];
|
|
2921
|
+
}
|
|
2922
|
+
var STATUS_HINTS_COMPACT = [
|
|
2923
|
+
["\u2190\u2192", "tabs"],
|
|
2924
|
+
SHORTCUTS.search,
|
|
2925
|
+
SHORTCUTS.copy,
|
|
2926
|
+
["Enter", "input"],
|
|
2927
|
+
["H", "help"]
|
|
2928
|
+
];
|
|
2929
|
+
var STATUS_HINTS_FULL = [
|
|
2930
|
+
["\u2190\u2192/1-9", "switch tabs"],
|
|
2931
|
+
["Enter", "input mode"],
|
|
2932
|
+
SHORTCUTS.search,
|
|
2933
|
+
SHORTCUTS.restart,
|
|
2934
|
+
SHORTCUTS.restartAll,
|
|
2935
|
+
SHORTCUTS.stopStart,
|
|
2936
|
+
SHORTCUTS.copy,
|
|
2937
|
+
SHORTCUTS.clear,
|
|
2938
|
+
SHORTCUTS.timestamps,
|
|
2939
|
+
["\u2191\u2193", "scroll line"],
|
|
2940
|
+
["Shift+\u2191\u2193", "top/bottom"],
|
|
2915
2941
|
["G/Shift+G", "top/bottom"],
|
|
2916
|
-
[
|
|
2917
|
-
|
|
2918
|
-
[SHORTCUTS.search.label, SHORTCUTS.search.description],
|
|
2919
|
-
[SHORTCUTS.copy.label, SHORTCUTS.copy.description],
|
|
2920
|
-
[SHORTCUTS.clear.label, SHORTCUTS.clear.description],
|
|
2921
|
-
[SHORTCUTS.timestamps.label, SHORTCUTS.timestamps.description],
|
|
2922
|
-
[SHORTCUTS.openLogs.label, SHORTCUTS.openLogs.description],
|
|
2942
|
+
["PgUp/PgDn", "scroll page"],
|
|
2943
|
+
SHORTCUTS.openLogs,
|
|
2923
2944
|
["Ctrl+Click", "open link"],
|
|
2924
2945
|
["Ctrl+C", "quit"]
|
|
2925
2946
|
];
|
|
2926
|
-
var STATUS_BAR_TEXT =
|
|
2947
|
+
var STATUS_BAR_TEXT = STATUS_HINTS_COMPACT.map((h) => {
|
|
2948
|
+
const [l, d] = toHintPair(h);
|
|
2949
|
+
return `${l}: ${d}`;
|
|
2950
|
+
}).join(" ");
|
|
2951
|
+
|
|
2952
|
+
// src/ui/help-overlay.ts
|
|
2953
|
+
class HelpOverlay {
|
|
2954
|
+
renderable;
|
|
2955
|
+
textRenderable;
|
|
2956
|
+
constructor(renderer) {
|
|
2957
|
+
this.renderable = new BoxRenderable(renderer, {
|
|
2958
|
+
id: "help-overlay",
|
|
2959
|
+
position: "absolute",
|
|
2960
|
+
width: "100%",
|
|
2961
|
+
height: "100%",
|
|
2962
|
+
zIndex: 100,
|
|
2963
|
+
visible: false,
|
|
2964
|
+
justifyContent: "center",
|
|
2965
|
+
alignItems: "center"
|
|
2966
|
+
});
|
|
2967
|
+
const backdrop = new BoxRenderable(renderer, {
|
|
2968
|
+
id: "help-backdrop",
|
|
2969
|
+
position: "absolute",
|
|
2970
|
+
width: "100%",
|
|
2971
|
+
height: "100%",
|
|
2972
|
+
backgroundColor: "#000000",
|
|
2973
|
+
opacity: 0.7
|
|
2974
|
+
});
|
|
2975
|
+
const box = new BoxRenderable(renderer, {
|
|
2976
|
+
id: "help-box",
|
|
2977
|
+
flexDirection: "column",
|
|
2978
|
+
padding: 1,
|
|
2979
|
+
paddingX: 5,
|
|
2980
|
+
backgroundColor: "#1a1a2e",
|
|
2981
|
+
border: true,
|
|
2982
|
+
borderColor: "#444",
|
|
2983
|
+
zIndex: 101
|
|
2984
|
+
});
|
|
2985
|
+
const lines = [
|
|
2986
|
+
"Keyboard Shortcuts",
|
|
2987
|
+
"",
|
|
2988
|
+
...STATUS_HINTS_FULL.map((h) => {
|
|
2989
|
+
const [label, desc] = toHintPair(h);
|
|
2990
|
+
return ` ${label.padEnd(14)} ${desc}`;
|
|
2991
|
+
}),
|
|
2992
|
+
"",
|
|
2993
|
+
"Press H or Esc to close"
|
|
2994
|
+
];
|
|
2995
|
+
this.textRenderable = new TextRenderable(renderer, {
|
|
2996
|
+
id: "help-text",
|
|
2997
|
+
content: lines.join(`
|
|
2998
|
+
`),
|
|
2999
|
+
fg: "#cccccc"
|
|
3000
|
+
});
|
|
3001
|
+
box.add(this.textRenderable);
|
|
3002
|
+
this.renderable.add(backdrop);
|
|
3003
|
+
this.renderable.add(box);
|
|
3004
|
+
}
|
|
3005
|
+
get isVisible() {
|
|
3006
|
+
return this.renderable.visible;
|
|
3007
|
+
}
|
|
3008
|
+
toggle() {
|
|
3009
|
+
this.renderable.visible = !this.renderable.visible;
|
|
3010
|
+
}
|
|
3011
|
+
hide() {
|
|
3012
|
+
this.renderable.visible = false;
|
|
3013
|
+
}
|
|
3014
|
+
show() {
|
|
3015
|
+
this.renderable.visible = true;
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
2927
3018
|
|
|
2928
3019
|
// src/ui/pane.ts
|
|
2929
3020
|
import {
|
|
@@ -3811,13 +3902,22 @@ class SearchController {
|
|
|
3811
3902
|
}
|
|
3812
3903
|
|
|
3813
3904
|
// src/ui/status-bar.ts
|
|
3814
|
-
import {
|
|
3905
|
+
import {
|
|
3906
|
+
BoxRenderable as BoxRenderable2,
|
|
3907
|
+
cyan,
|
|
3908
|
+
red,
|
|
3909
|
+
reverse,
|
|
3910
|
+
StyledText as StyledText2,
|
|
3911
|
+
TextRenderable as TextRenderable2,
|
|
3912
|
+
yellow
|
|
3913
|
+
} from "@opentui/core";
|
|
3815
3914
|
function plain(text) {
|
|
3816
3915
|
return { __isChunk: true, text };
|
|
3817
3916
|
}
|
|
3818
3917
|
|
|
3819
3918
|
class StatusBar {
|
|
3820
3919
|
renderable;
|
|
3920
|
+
text;
|
|
3821
3921
|
_searchMode = false;
|
|
3822
3922
|
_searchQuery = "";
|
|
3823
3923
|
_searchMatchCount = 0;
|
|
@@ -3825,16 +3925,23 @@ class StatusBar {
|
|
|
3825
3925
|
_crossProcessInfo;
|
|
3826
3926
|
_tempMessage = null;
|
|
3827
3927
|
_tempTimer = null;
|
|
3928
|
+
_inputMode = false;
|
|
3828
3929
|
constructor(renderer) {
|
|
3829
|
-
this.renderable = new
|
|
3930
|
+
this.renderable = new BoxRenderable2(renderer, {
|
|
3830
3931
|
id: "status-bar",
|
|
3831
3932
|
width: "100%",
|
|
3933
|
+
backgroundColor: "#1a1a1a",
|
|
3934
|
+
paddingX: 1,
|
|
3935
|
+
minHeight: 1
|
|
3936
|
+
});
|
|
3937
|
+
this.text = new TextRenderable2(renderer, {
|
|
3938
|
+
id: "status-bar-text",
|
|
3939
|
+
width: "100%",
|
|
3832
3940
|
wrapMode: "word",
|
|
3833
|
-
content: this.buildContent()
|
|
3834
|
-
bg: "#1a1a1a",
|
|
3835
|
-
paddingX: 1
|
|
3941
|
+
content: this.buildContent()
|
|
3836
3942
|
});
|
|
3837
|
-
this.
|
|
3943
|
+
this.text.selectable = false;
|
|
3944
|
+
this.renderable.add(this.text);
|
|
3838
3945
|
}
|
|
3839
3946
|
setSearchMode(active, query = "", matchCount = 0, currentIndex = -1, crossProcessInfo) {
|
|
3840
3947
|
this._searchMode = active;
|
|
@@ -3842,19 +3949,23 @@ class StatusBar {
|
|
|
3842
3949
|
this._searchMatchCount = matchCount;
|
|
3843
3950
|
this._searchCurrentIndex = currentIndex;
|
|
3844
3951
|
this._crossProcessInfo = crossProcessInfo;
|
|
3845
|
-
this.
|
|
3952
|
+
this.text.content = this.buildContent();
|
|
3846
3953
|
}
|
|
3847
3954
|
showTemporaryMessage(message, duration = 2000) {
|
|
3848
3955
|
if (this._tempTimer)
|
|
3849
3956
|
clearTimeout(this._tempTimer);
|
|
3850
3957
|
this._tempMessage = message;
|
|
3851
|
-
this.
|
|
3958
|
+
this.text.content = this.buildContent();
|
|
3852
3959
|
this._tempTimer = setTimeout(() => {
|
|
3853
3960
|
this._tempMessage = null;
|
|
3854
3961
|
this._tempTimer = null;
|
|
3855
|
-
this.
|
|
3962
|
+
this.text.content = this.buildContent();
|
|
3856
3963
|
}, duration);
|
|
3857
3964
|
}
|
|
3965
|
+
setInputMode(active) {
|
|
3966
|
+
this._inputMode = active;
|
|
3967
|
+
this.text.content = this.buildContent();
|
|
3968
|
+
}
|
|
3858
3969
|
buildContent() {
|
|
3859
3970
|
if (this._tempMessage) {
|
|
3860
3971
|
return new StyledText2([cyan(this._tempMessage)]);
|
|
@@ -3862,6 +3973,9 @@ class StatusBar {
|
|
|
3862
3973
|
if (this._searchMode) {
|
|
3863
3974
|
return this.buildSearchContent();
|
|
3864
3975
|
}
|
|
3976
|
+
if (this._inputMode) {
|
|
3977
|
+
return new StyledText2([yellow("INPUT"), plain(" Type to send input to process. "), plain("Esc: exit")]);
|
|
3978
|
+
}
|
|
3865
3979
|
return new StyledText2([plain(STATUS_BAR_TEXT)]);
|
|
3866
3980
|
}
|
|
3867
3981
|
buildSearchContent() {
|
|
@@ -4150,8 +4264,10 @@ class App {
|
|
|
4150
4264
|
panes = new Map;
|
|
4151
4265
|
tabBar;
|
|
4152
4266
|
statusBar;
|
|
4267
|
+
helpOverlay;
|
|
4153
4268
|
search;
|
|
4154
4269
|
activePane = null;
|
|
4270
|
+
inputMode = false;
|
|
4155
4271
|
destroyed = false;
|
|
4156
4272
|
names;
|
|
4157
4273
|
termCols = 80;
|
|
@@ -4180,7 +4296,7 @@ class App {
|
|
|
4180
4296
|
this.termCols = Math.max(40, width - this.sidebarWidth - 2);
|
|
4181
4297
|
this.termRows = Math.max(5, height - 2);
|
|
4182
4298
|
const { termCols, termRows } = this;
|
|
4183
|
-
const layout = new
|
|
4299
|
+
const layout = new BoxRenderable3(this.renderer, {
|
|
4184
4300
|
id: "root",
|
|
4185
4301
|
flexDirection: "column",
|
|
4186
4302
|
width: "100%",
|
|
@@ -4189,14 +4305,14 @@ class App {
|
|
|
4189
4305
|
});
|
|
4190
4306
|
const processHexColors = buildProcessHexColorMap(this.names, this.config);
|
|
4191
4307
|
this.tabBar = new TabBar(this.renderer, this.names, processHexColors);
|
|
4192
|
-
const contentRow = new
|
|
4308
|
+
const contentRow = new BoxRenderable3(this.renderer, {
|
|
4193
4309
|
id: "content-row",
|
|
4194
4310
|
flexDirection: "row",
|
|
4195
4311
|
flexGrow: 1,
|
|
4196
4312
|
width: "100%",
|
|
4197
4313
|
border: false
|
|
4198
4314
|
});
|
|
4199
|
-
const sidebar = new
|
|
4315
|
+
const sidebar = new BoxRenderable3(this.renderer, {
|
|
4200
4316
|
id: "sidebar",
|
|
4201
4317
|
width: this.sidebarWidth,
|
|
4202
4318
|
height: "100%",
|
|
@@ -4204,12 +4320,13 @@ class App {
|
|
|
4204
4320
|
borderColor: "#444"
|
|
4205
4321
|
});
|
|
4206
4322
|
sidebar.add(this.tabBar.renderable);
|
|
4207
|
-
const paneContainer = new
|
|
4323
|
+
const paneContainer = new BoxRenderable3(this.renderer, {
|
|
4208
4324
|
id: "pane-container",
|
|
4209
4325
|
flexGrow: 1,
|
|
4210
4326
|
border: false
|
|
4211
4327
|
});
|
|
4212
4328
|
this.statusBar = new StatusBar(this.renderer);
|
|
4329
|
+
this.helpOverlay = new HelpOverlay(this.renderer);
|
|
4213
4330
|
this.search = new SearchController({
|
|
4214
4331
|
logWriter: this.logWriter,
|
|
4215
4332
|
statusBar: this.statusBar,
|
|
@@ -4244,6 +4361,7 @@ class App {
|
|
|
4244
4361
|
layout.add(contentRow);
|
|
4245
4362
|
layout.add(this.statusBar.renderable);
|
|
4246
4363
|
this.renderer.root.add(layout);
|
|
4364
|
+
this.renderer.root.add(this.helpOverlay.renderable);
|
|
4247
4365
|
this.tabBar.onSelect((_index, name) => this.switchPane(name));
|
|
4248
4366
|
this.tabBar.onSelectionChanged((_index, name) => this.switchPane(name));
|
|
4249
4367
|
this.manager.on((event) => {
|
|
@@ -4280,6 +4398,14 @@ class App {
|
|
|
4280
4398
|
this.renderer.keyInput.on("keypress", (key) => {
|
|
4281
4399
|
log(key);
|
|
4282
4400
|
if (key.ctrl && key.name === "c") {
|
|
4401
|
+
if (this.helpOverlay.isVisible) {
|
|
4402
|
+
this.helpOverlay.hide();
|
|
4403
|
+
return;
|
|
4404
|
+
}
|
|
4405
|
+
if (this.inputMode) {
|
|
4406
|
+
this.exitInputMode();
|
|
4407
|
+
return;
|
|
4408
|
+
}
|
|
4283
4409
|
if (this.search.isActive) {
|
|
4284
4410
|
this.search.exit();
|
|
4285
4411
|
return;
|
|
@@ -4289,15 +4415,39 @@ class App {
|
|
|
4289
4415
|
});
|
|
4290
4416
|
return;
|
|
4291
4417
|
}
|
|
4418
|
+
if (this.helpOverlay.isVisible) {
|
|
4419
|
+
if (key.name === "escape" || key.sequence === "?" || key.name === "h") {
|
|
4420
|
+
this.helpOverlay.hide();
|
|
4421
|
+
}
|
|
4422
|
+
return;
|
|
4423
|
+
}
|
|
4292
4424
|
if (this.search.isActive) {
|
|
4293
4425
|
this.search.handleInput(key);
|
|
4294
4426
|
return;
|
|
4295
4427
|
}
|
|
4428
|
+
if (this.inputMode && this.activePane) {
|
|
4429
|
+
if (key.name === "escape") {
|
|
4430
|
+
this.exitInputMode();
|
|
4431
|
+
return;
|
|
4432
|
+
}
|
|
4433
|
+
if (key.sequence) {
|
|
4434
|
+
this.manager.write(this.activePane, key.sequence);
|
|
4435
|
+
}
|
|
4436
|
+
return;
|
|
4437
|
+
}
|
|
4296
4438
|
if (!this.activePane)
|
|
4297
4439
|
return;
|
|
4298
4440
|
const isInteractive = this.config.processes[this.activePane]?.interactive === true;
|
|
4299
4441
|
if (!isInteractive) {
|
|
4300
4442
|
const name = key.name.toLowerCase();
|
|
4443
|
+
if (key.sequence === "?" || name === "h") {
|
|
4444
|
+
this.helpOverlay.toggle();
|
|
4445
|
+
return;
|
|
4446
|
+
}
|
|
4447
|
+
if (name === "return") {
|
|
4448
|
+
this.enterInputMode();
|
|
4449
|
+
return;
|
|
4450
|
+
}
|
|
4301
4451
|
if (key.shift && name === SHORTCUTS.scrollToBottom.key) {
|
|
4302
4452
|
this.panes.get(this.activePane)?.scrollToBottom();
|
|
4303
4453
|
return;
|
|
@@ -4366,6 +4516,15 @@ class App {
|
|
|
4366
4516
|
this.switchPane(this.tabBar.getNameAtIndex(next));
|
|
4367
4517
|
return;
|
|
4368
4518
|
}
|
|
4519
|
+
if (name === "up" || name === "down") {
|
|
4520
|
+
const pane = this.panes.get(this.activePane);
|
|
4521
|
+
if (key.shift) {
|
|
4522
|
+
name === "up" ? pane?.scrollToTop() : pane?.scrollToBottom();
|
|
4523
|
+
} else {
|
|
4524
|
+
pane?.scrollBy(name === "up" ? -1 : 1);
|
|
4525
|
+
}
|
|
4526
|
+
return;
|
|
4527
|
+
}
|
|
4369
4528
|
if (name === "pageup" || name === "pagedown") {
|
|
4370
4529
|
const pane = this.panes.get(this.activePane);
|
|
4371
4530
|
const delta = this.termRows - 2;
|
|
@@ -4392,9 +4551,33 @@ class App {
|
|
|
4392
4551
|
}
|
|
4393
4552
|
await this.manager.startAll(termCols, termRows);
|
|
4394
4553
|
}
|
|
4554
|
+
enterInputMode() {
|
|
4555
|
+
this.inputMode = true;
|
|
4556
|
+
this.statusBar.setInputMode(true);
|
|
4557
|
+
if (this.activePane) {
|
|
4558
|
+
const pane = this.panes.get(this.activePane);
|
|
4559
|
+
if (pane)
|
|
4560
|
+
pane.terminal.showCursor = true;
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
exitInputMode() {
|
|
4564
|
+
this.inputMode = false;
|
|
4565
|
+
this.statusBar.setInputMode(false);
|
|
4566
|
+
if (this.activePane) {
|
|
4567
|
+
const isInteractive = this.config.processes[this.activePane]?.interactive === true;
|
|
4568
|
+
if (!isInteractive) {
|
|
4569
|
+
const pane = this.panes.get(this.activePane);
|
|
4570
|
+
if (pane)
|
|
4571
|
+
pane.terminal.showCursor = false;
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
}
|
|
4395
4575
|
switchPane(name) {
|
|
4396
4576
|
if (this.activePane === name)
|
|
4397
4577
|
return;
|
|
4578
|
+
if (this.inputMode) {
|
|
4579
|
+
this.exitInputMode();
|
|
4580
|
+
}
|
|
4398
4581
|
if (this.search.isActive && !this.search.isAllMode) {
|
|
4399
4582
|
this.search.exit();
|
|
4400
4583
|
}
|