history query opts

This commit is contained in:
sawka 2022-08-31 00:02:16 -07:00
parent 9ed993078d
commit e2212ad661
3 changed files with 102 additions and 7 deletions

View File

@ -542,6 +542,12 @@ class TextAreaInput extends React.Component<{}, {}> {
inputModel.resetInput();
return;
}
if (e.code == "KeyM" && e.getModifierState("Meta")) {
e.preventDefault();
let opts = mobx.toJS(inputModel.historyQueryOpts.get());
opts.includeMeta = !opts.includeMeta;
inputModel.setHistoryQueryOpts(opts);
}
if (e.code == "Tab") {
e.preventDefault();
return;
@ -562,7 +568,9 @@ class TextAreaInput extends React.Component<{}, {}> {
handleHistoryInput(e : any) {
let inputModel = GlobalModel.inputModel;
mobx.action(() => {
inputModel.historyQueryOpts.get().queryStr = e.target.value;
let opts = mobx.toJS(inputModel.historyQueryOpts.get());
opts.queryStr = e.target.value;
inputModel.setHistoryQueryOpts(opts);
})();
}
@ -646,7 +654,7 @@ class HistoryInfo extends React.Component<{}, {}> {
let line : string = "";
let idx = 0;
return (
<div key={hitem.historynum} className={cn("history-item", {"is-selected": isSelected}, "hnum-" + hitem.historynum)} onClick={() => this.handleItemClick(hitem)}>
<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)} {lines[0]}</div>
<For each="line" index="index" of={lines.slice(1)}>
<div key={idx} className="history-line">{line}</div>
@ -667,12 +675,13 @@ class HistoryInfo extends React.Component<{}, {}> {
let hitems = inputModel.getFilteredHistoryItems();
hitems = hitems.slice().reverse();
let hitem : HistoryItem = null;
let opts = inputModel.historyQueryOpts.get();
return (
<div className="cmd-history">
<div className="history-title">
history
{" "}
<span className="history-opt">[containing '']</span>
<span className="history-opt">[containing '{opts.queryStr}']</span>
{" "}
<span className="history-opt">[this session &#x2318;S]</span>
{" "}
@ -680,7 +689,7 @@ class HistoryInfo extends React.Component<{}, {}> {
{" "}
<span className="history-opt">[this remote &#x2318;R]</span>
{" "}
<span className="history-opt">[including metacmds &#x2318;M]</span>
<span className="history-opt">[{opts.includeMeta ? "including" : "excluding"} metacmds &#x2318;M]</span>
{" "} <span className="history-clickable-opt" onClick={this.handleClose}>(close ESC)</span>
</div>
<div className="history-items">

View File

@ -633,6 +633,37 @@ class InputModel {
return false;
}
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);
return;
})();
}
setHistoryShow(show : boolean) : void {
if (this.historyShow.get() == show) {
return;
@ -746,7 +777,54 @@ class InputModel {
getFilteredHistoryItems() : HistoryItem[] {
let hitems : HistoryItem[] = this.historyItems.get() ?? [];
return hitems;
let rtn : HistoryItem[] = [];
let opts = mobx.toJS(this.historyQueryOpts.get());
let ctx = GlobalModel.getUIContext();
let curRemote = ctx.remote;
if (curRemote == null) {
curRemote : RemotePtrType = {ownerid: "", name: "", remoteid: ""};
}
for (let i=0; i<hitems.length; i++) {
let hitem = hitems[i];
if (hitem.ismetacmd) {
if (!opts.includeMeta) {
continue;
}
}
else {
if (opts.limitRemoteInstance) {
if (hitem.remote == null || isBlank(hitem.remote.remoteid)) {
continue;
}
if (((curRemote.ownerid ?? "") != (hitem.remote.owerid ?? ""))
|| ((curRemote.remoteid ?? "") != (hitem.remote.remoteid ?? ""))
|| ((curRemote.name ?? "" ) != (hitem.remote.name ?? ""))) {
continue;
}
}
else if (opts.limitRemote) {
if (hitem.remote == null || isBlank(hitem.remote.remoteid)) {
continue;
}
if (((curRemote.ownerid ?? "") != (hitem.remote.owerid ?? ""))
|| ((curRemote.remoteid ?? "") != (hitem.remote.remoteid ?? ""))) {
continue;
}
}
}
if (!isBlank(opts.queryStr)) {
if (isBlank(hitem.cmdstr)) {
continue;
}
let idx = hitem.cmdstr.indexOf(opts.queryStr);
if (idx == -1) {
continue;
}
}
rtn.push(hitem);
}
return rtn;
}
scrollHistoryItemIntoView(hnum : string) : void {
@ -794,11 +872,11 @@ class InputModel {
})();
}
setHistoryIndex(hidx : number) : void {
setHistoryIndex(hidx : number, force? : boolean) : void {
if (hidx < 0) {
return;
}
if (this.historyIndex.get() == hidx) {
if (!force && this.historyIndex.get() == hidx) {
return;
}
mobx.action(() => {

View File

@ -667,6 +667,10 @@ body .xterm .xterm-viewport {
margin-left: 58px;
}
.history-item.history-haderror {
color: mix(@term-red, @term-white, 50%);
}
.history-line:first-child {
margin-left: 0;
}
@ -685,6 +689,10 @@ body .xterm .xterm-viewport {
color: @term-bright-white;
background-color: #444;
}
.history-item.is-selected.history-haderror {
color: mix(@term-bright-red, @term-bright-white, 50%);
}
}
}