show global/session history

This commit is contained in:
sawka
2022-08-31 13:29:59 -07:00
parent f2451329cd
commit 3ab2023423
5 changed files with 105 additions and 42 deletions
+37 -7
View File
@@ -467,7 +467,8 @@ class TextAreaInput extends React.Component<{}, {}> {
if (e.code == "ArrowUp" || e.code == "ArrowDown") {
if (!inputModel.isHistoryLoaded()) {
if (e.code == "ArrowUp") {
inputModel.loadHistory(false, 1);
this.lastHistoryUpDown = true;
inputModel.loadHistory(false, 1, "window");
}
return;
}
@@ -542,14 +543,14 @@ class TextAreaInput extends React.Component<{}, {}> {
inputModel.resetInput();
return;
}
if (e.code == "KeyM" && e.getModifierState("Meta")) {
if (e.code == "KeyM" && (e.getModifierState("Meta") || e.getModifierState("Control"))) {
e.preventDefault();
let opts = mobx.toJS(inputModel.historyQueryOpts.get());
opts.includeMeta = !opts.includeMeta;
inputModel.setHistoryQueryOpts(opts);
return;
}
if (e.code == "KeyR" && (e.getModifierState("Meta") && !e.getModifierState("Shift"))) {
if (e.code == "KeyR" && ((e.getModifierState("Meta") || e.getModifierState("Control")) && !e.getModifierState("Shift"))) {
console.log("meta-r");
e.preventDefault();
let opts = mobx.toJS(inputModel.historyQueryOpts.get());
@@ -564,6 +565,22 @@ class TextAreaInput extends React.Component<{}, {}> {
inputModel.setHistoryQueryOpts(opts);
return;
}
if (e.code == "KeyS" && (e.getModifierState("Meta") || e.getModifierState("Control"))) {
e.preventDefault();
let opts = mobx.toJS(inputModel.historyQueryOpts.get());
let htype = opts.queryType;
if (htype == "window") {
htype = "session";
}
else if (htype == "session") {
htype = "global";
}
else {
htype = "window";
}
inputModel.setHistoryType(htype);
return;
}
if (e.code == "Tab") {
e.preventDefault();
return;
@@ -695,10 +712,23 @@ class HistoryInfo extends React.Component<{}, {}> {
let line : string = "";
let idx = 0;
let limitRemote = opts.limitRemote;
let sessionStr = "";
if (opts.queryType == "global") {
if (!isBlank(hitem.sessionid)) {
let s = GlobalModel.getSessionById(hitem.sessionid);
if (s != null) {
sessionStr = s.name.get();
if (sessionStr.indexOf(" ") != -1) {
sessionStr = "[" + sessionStr + "]";
}
sessionStr = sprintf("#%-15s ", sessionStr);
}
}
}
return (
<div key={hitem.historynum} className={cn("history-item", {"is-selected": isSelected}, {"history-haderror": hitem.haderror}, "hnum-" + hitem.historynum)} onClick={() => this.handleItemClick(hitem)}>
<div className="history-line">{(isSelected ? "*" : " ")}{sprintf("%5s", hitem.historynum)} {!limitRemote ? this.renderRemote(hitem) : ""}{lines[0]}</div>
<For each="line" index="index" of={lines.slice(1)}>
<div className="history-line">{(isSelected ? "*" : " ")}{sprintf("%5s", hitem.historynum)} {opts.queryType == "global" ? sessionStr : ""}{!limitRemote ? this.renderRemote(hitem) : ""} {lines[0]}</div>
<For each="line" index="idx" of={lines.slice(1)}>
<div key={idx} className="history-line">{line}</div>
</For>
</div>
@@ -723,7 +753,7 @@ class HistoryInfo extends React.Component<{}, {}> {
<div className="history-title">
<div>history</div>
<div className="spacer"></div>
<div className="history-opt">[for window &#x2318;W]</div>
<div className="history-opt">[for {opts.queryType} &#x2318;S]</div>
<div className="spacer"></div>
<div className="history-opt">[containing '{opts.queryStr}']</div>
<div className="spacer"></div>
@@ -734,7 +764,7 @@ class HistoryInfo extends React.Component<{}, {}> {
<div className="history-clickable-opt" onClick={this.handleClose}>(ESC)</div>
<div className="spacer"></div>
</div>
<div className={cn("history-items", {"show-remotes": !opts.limitRemote})}>
<div className={cn("history-items", {"show-remotes": !opts.limitRemote}, {"show-sessions": opts.queryType == "global"})}>
<If condition={hitems.length == 0}>
[no history]
</If>
+62 -35
View File
@@ -577,6 +577,7 @@ class InputModel {
historyShow : OV<boolean> = mobx.observable.box(false);
infoShow : OV<boolean> = mobx.observable.box(false);
historyType : mobx.IObservableValue<string> = mobx.observable.box("window");
historyLoading : mobx.IObservableValue<boolean> = mobx.observable.box(false);
historyAfterLoadIndex : number = 0;
historyItems : mobx.IObservableValue<HistoryItem[]> = mobx.observable.box(null, {name: "history-items", deep: false}); // sorted in reverse (most recent is index 0)
@@ -629,33 +630,43 @@ class InputModel {
return false;
}
setHistoryType(htype : string) : void {
if (this.historyQueryOpts.get().queryType == htype) {
return;
}
this.loadHistory(true, -1, htype);
}
findBestNewIndex(oldItem : HistoryItem) : number {
if (oldItem == null) {
return 0;
}
let newItems = this.getFilteredHistoryItems();
if (newItems.length == 0) {
return 0;
}
let bestIdx = 0;
for (let i=0; i<newItems.length; i++) { // still start at i=0 to catch the historynum equality case
let item = newItems[i];
if (item.historynum == oldItem.historynum) {
bestIdx = i;
break;
}
let bestTsDiff = Math.abs(item.ts - newItems[bestIdx].ts);
let curTsDiff = Math.abs(item.ts - oldItem.ts);
if (curTsDiff < bestTsDiff) {
bestIdx = i;
}
}
return bestIdx + 1;
}
setHistoryQueryOpts(opts : HistoryQueryOpts) : void {
mobx.action(() => {
let oldItem = this.getHistorySelectedItem();
this.historyQueryOpts.set(opts);
if (oldItem == null) {
setTimeout(() => this.setHistoryIndex(0, true), 10);
return;
}
let newItems = this.getFilteredHistoryItems();
if (newItems.length == 0) {
setTimeout(() => this.setHistoryIndex(0, true), 10);
return;
}
let bestIdx = 0;
for (let i=0; i<newItems.length; i++) { // still start at i=0 to catch the historynum equality case
let item = newItems[i];
if (item.historynum == oldItem.historynum) {
bestIdx = i;
break;
}
let bestTsDiff = Math.abs(item.ts - newItems[bestIdx].ts);
let curTsDiff = Math.abs(item.ts - oldItem.ts);
if (curTsDiff < bestTsDiff) {
bestIdx = i;
}
}
setTimeout(() => this.setHistoryIndex(bestIdx+1, true), 10);
let bestIndex = this.findBestNewIndex(oldItem);
setTimeout(() => this.setHistoryIndex(bestIndex, true), 10);
return;
})();
}
@@ -680,18 +691,20 @@ class InputModel {
return (hitems != null);
}
loadHistory(show : boolean, afterLoadIndex : number) {
loadHistory(show : boolean, afterLoadIndex : number, htype : string) {
if (this.historyLoading.get()) {
return;
}
if (this.isHistoryLoaded()) {
return;
if (this.historyQueryOpts.get().queryType == htype) {
return;
}
}
this.historyAfterLoadIndex = afterLoadIndex;
mobx.action(() => {
this.historyLoading.set(true);
})();
GlobalCommandRunner.loadHistory(show);
GlobalCommandRunner.loadHistory(show, htype);
}
openHistory() : void {
@@ -699,7 +712,7 @@ class InputModel {
return;
}
if (!this.isHistoryLoaded()) {
this.loadHistory(true, 0);
this.loadHistory(true, 0, "window");
return;
}
if (!this.historyShow.get()) {
@@ -756,15 +769,25 @@ class InputModel {
setHistoryInfo(hinfo : HistoryInfoType) : void {
mobx.action(() => {
let oldItem = this.getHistorySelectedItem();
let hitems : HistoryItem[] = hinfo.items ?? [];
this.historyItems.set(hitems);
this.historyLoading.set(false);
if (this.historyAfterLoadIndex) {
this.historyQueryOpts.get().queryType = hinfo.historytype;
if (hinfo.historytype == "session" || hinfo.historytype == "global") {
this.historyQueryOpts.get().limitRemote = false;
this.historyQueryOpts.get().limitRemoteInstance = false;
}
if (this.historyAfterLoadIndex == -1) {
let bestIndex = this.findBestNewIndex(oldItem);
setTimeout(() => this.setHistoryIndex(bestIndex, true), 100);
}
else if (this.historyAfterLoadIndex) {
if (hitems.length >= this.historyAfterLoadIndex) {
this.setHistoryIndex(this.historyAfterLoadIndex);
}
this.historyAfterLoadIndex = 0;
}
this.historyAfterLoadIndex = 0;
if (hinfo.show) {
this.openHistory();
}
@@ -780,9 +803,9 @@ class InputModel {
let rtn : HistoryItem[] = [];
let opts = mobx.toJS(this.historyQueryOpts.get());
let ctx = GlobalModel.getUIContext();
let curRemote = ctx.remote;
let curRemote : RemotePtrType = ctx.remote;
if (curRemote == null) {
curRemote : RemotePtrType = {ownerid: "", name: "", remoteid: ""};
curRemote = {ownerid: "", name: "", remoteid: ""};
}
curRemote = mobx.toJS(curRemote);
for (let i=0; i<hitems.length; i++) {
@@ -797,7 +820,7 @@ class InputModel {
if (hitem.remote == null || isBlank(hitem.remote.remoteid)) {
continue;
}
if (((curRemote.ownerid ?? "") != (hitem.remote.owerid ?? ""))
if (((curRemote.ownerid ?? "") != (hitem.remote.ownerid ?? ""))
|| ((curRemote.remoteid ?? "") != (hitem.remote.remoteid ?? ""))
|| ((curRemote.name ?? "" ) != (hitem.remote.name ?? ""))) {
continue;
@@ -807,7 +830,7 @@ class InputModel {
if (hitem.remote == null || isBlank(hitem.remote.remoteid)) {
continue;
}
if (((curRemote.ownerid ?? "") != (hitem.remote.owerid ?? ""))
if (((curRemote.ownerid ?? "") != (hitem.remote.ownerid ?? ""))
|| ((curRemote.remoteid ?? "") != (hitem.remote.remoteid ?? ""))) {
continue;
}
@@ -839,7 +862,7 @@ class InputModel {
}
let buffer = 15;
let titleHeight = 24;
let titleDiv = document.querySelector(".cmd-history .history-title");
let titleDiv : HTMLElement = document.querySelector(".cmd-history .history-title");
if (titleDiv != null) {
titleHeight = titleDiv.offsetHeight + 2;
}
@@ -1058,6 +1081,7 @@ class InputModel {
mobx.action(() => {
this.setHistoryShow(false);
this.historyLoading.set(false);
this.historyType.set("window");
this.historyItems.set(null);
this.historyIndex.set(0);
this.historyQueryOpts.set(getDefaultHistoryQueryOpts());
@@ -1659,11 +1683,14 @@ class CommandRunner {
constructor() {
}
loadHistory(show : boolean) {
loadHistory(show : boolean, htype : string) {
let kwargs = {"nohist": "1"};
if (!show) {
kwargs["noshow"] = "1";
}
if (htype != null && htype != "window") {
kwargs["type"] = htype;
}
GlobalModel.submitCommand("history", null, null, kwargs, true);
}
+1
View File
@@ -5,6 +5,7 @@ contextBridge.exposeInMainWorld("api", {
onTCmd: (callback) => ipcRenderer.on("t-cmd", callback),
onICmd: (callback) => ipcRenderer.on("i-cmd", callback),
onHCmd: (callback) => ipcRenderer.on("h-cmd", callback),
onWCmd: (callback) => ipcRenderer.on("w-cmd", callback),
onMetaArrowUp: (callback) => ipcRenderer.on("meta-arrowup", callback),
onMetaArrowDown: (callback) => ipcRenderer.on("meta-arrowdown", callback),
onBracketCmd: (callback) => ipcRenderer.on("bracket-cmd", callback),
+4
View File
@@ -694,6 +694,10 @@ body .xterm .xterm-viewport {
margin-left: 174px;
}
&.show-remotes.show-sessions .history-line {
margin-left: 294px;
}
.history-item.history-haderror {
color: mix(@term-red, @term-white, 50%);
}
+1
View File
@@ -220,6 +220,7 @@ type ModelUpdateType = {
};
type HistoryInfoType = {
historytype : "global" | "session" | "window",
sessionid : string,
windowid : string,
items : HistoryItem[],