mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-23 21:51:30 +01:00
implement command history
This commit is contained in:
parent
034995ef2a
commit
b70d42bca4
@ -249,12 +249,12 @@ class CmdInput extends React.Component<{}, {}> {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let lastTab = (ltCurLine != null && curLine == ltCurLine);
|
let lastTab = (ltCurLine != null && curLine == ltCurLine);
|
||||||
if (lastTab) {
|
if (lastTab) {
|
||||||
GlobalModel.submitCommand("compgen", null, [curLine], {"comppos": String(curLine.length), "compshow": "1"});
|
GlobalModel.submitCommand("compgen", null, [curLine], {"comppos": String(curLine.length), "compshow": "1", "nohist": "1"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.lastTabCurLine.set(curLine);
|
this.lastTabCurLine.set(curLine);
|
||||||
GlobalModel.submitCommand("compgen", null, [curLine], {"comppos": String(curLine.length)});
|
GlobalModel.submitCommand("compgen", null, [curLine], {"comppos": String(curLine.length), "nohist": "1"});
|
||||||
GlobalModel.clearInfoMsg(true);
|
GlobalModel.clearInfoMsg(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ class CmdInput extends React.Component<{}, {}> {
|
|||||||
let hitem = {cmdtext: commandStr};
|
let hitem = {cmdtext: commandStr};
|
||||||
inputModel.clearCurLine();
|
inputModel.clearCurLine();
|
||||||
GlobalModel.clearInfoMsg(true);
|
GlobalModel.clearInfoMsg(true);
|
||||||
model.submitRawCommand(commandStr);
|
model.submitRawCommand(commandStr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAfterSlash(s : string) : string {
|
getAfterSlash(s : string) : string {
|
||||||
|
131
src/model.ts
131
src/model.ts
@ -263,7 +263,6 @@ class Window {
|
|||||||
loaded : OV<boolean> = mobx.observable.box(false);
|
loaded : OV<boolean> = mobx.observable.box(false);
|
||||||
loadError : OV<string> = mobx.observable.box(null);
|
loadError : OV<string> = mobx.observable.box(null);
|
||||||
lines : OArr<LineType> = mobx.observable.array([], {deep: false});
|
lines : OArr<LineType> = mobx.observable.array([], {deep: false});
|
||||||
history : any[] = [];
|
|
||||||
cmds : Record<string, Cmd> = {};
|
cmds : Record<string, Cmd> = {};
|
||||||
remoteInstances : OArr<RemoteInstanceType> = mobx.observable.array([]);
|
remoteInstances : OArr<RemoteInstanceType> = mobx.observable.array([]);
|
||||||
|
|
||||||
@ -272,14 +271,6 @@ class Window {
|
|||||||
this.windowId = windowId;
|
this.windowId = windowId;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNumHistoryItems() : number {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getHistoryItem(hnum : number) : any {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePtyData(ptyMsg : PtyDataUpdateType) {
|
updatePtyData(ptyMsg : PtyDataUpdateType) {
|
||||||
let cmd = this.cmds[ptyMsg.cmdid];
|
let cmd = this.cmds[ptyMsg.cmdid];
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
@ -297,7 +288,6 @@ class Window {
|
|||||||
this.loaded.set(true);
|
this.loaded.set(true);
|
||||||
}
|
}
|
||||||
genMergeSimpleData(this.lines, win.lines, (l : LineType) => String(l.lineid), (l : LineType) => l.lineid);
|
genMergeSimpleData(this.lines, win.lines, (l : LineType) => String(l.lineid), (l : LineType) => l.lineid);
|
||||||
this.history = win.history || [];
|
|
||||||
let cmds = win.cmds || [];
|
let cmds = win.cmds || [];
|
||||||
for (let i=0; i<cmds.length; i++) {
|
for (let i=0; i<cmds.length; i++) {
|
||||||
this.cmds[cmds[i].cmdid] = new Cmd(cmds[i]);
|
this.cmds[cmds[i].cmdid] = new Cmd(cmds[i]);
|
||||||
@ -499,8 +489,12 @@ class Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InputModel {
|
class InputModel {
|
||||||
historyIndex : mobx.IObservableValue<number> = mobx.observable.box(0, {name: "history-index"});
|
historyLoading : mobx.IObservableValue<boolean> = mobx.observable.box(false);
|
||||||
|
historySessionId : string = null;
|
||||||
|
historyItems : mobx.IObservableValue<HistoryItem[]> = mobx.observable.box(null, {name: "history-items", deep: false});
|
||||||
|
historyIndex : mobx.IObservableValue<number> = mobx.observable.box(0, {name: "history-index"}); // 1-indexed (because 0 is current)
|
||||||
modHistory : mobx.IObservableArray<string> = mobx.observable.array([""], {name: "mod-history"});
|
modHistory : mobx.IObservableArray<string> = mobx.observable.array([""], {name: "mod-history"});
|
||||||
|
setHIdx : number = 0;
|
||||||
|
|
||||||
updateCmdLine(cmdLine : CmdLineUpdateType) {
|
updateCmdLine(cmdLine : CmdLineUpdateType) {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
@ -516,14 +510,66 @@ class InputModel {
|
|||||||
|
|
||||||
setCurLine(val : string) {
|
setCurLine(val : string) {
|
||||||
let hidx = this.historyIndex.get();
|
let hidx = this.historyIndex.get();
|
||||||
|
mobx.action(() => {
|
||||||
|
if (this.modHistory.length <= hidx) {
|
||||||
|
this.modHistory.length = hidx + 1;
|
||||||
|
}
|
||||||
this.modHistory[hidx] = val;
|
this.modHistory[hidx] = val;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadHistory() {
|
||||||
|
if (this.historyLoading.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let sessionId = GlobalModel.activeSessionId.get();
|
||||||
|
if (sessionId == null) {
|
||||||
|
this.setHIdx = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mobx.action(() => {
|
||||||
|
this.historySessionId = sessionId;
|
||||||
|
this.historyItems.set(null);
|
||||||
|
this.historyLoading.set(true);
|
||||||
|
})();
|
||||||
|
let usp = new URLSearchParams({sessionid: sessionId});
|
||||||
|
let url = new URL("http://localhost:8080/api/get-history?" + usp.toString());
|
||||||
|
fetch(url).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
|
||||||
|
mobx.action(() => {
|
||||||
|
if (!this.historyLoading.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sessionId != GlobalModel.activeSessionId.get()) {
|
||||||
|
this.resetHistory();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.data && data.data.history) {
|
||||||
|
let hitems : HistoryItem[] = data.data.history || [];
|
||||||
|
this.historySessionId = sessionId;
|
||||||
|
this.historyItems.set(hitems);
|
||||||
|
this.historyLoading.set(false);
|
||||||
|
let hlen = hitems.length;
|
||||||
|
let setHIdx = this.setHIdx;
|
||||||
|
if (setHIdx > hlen) {
|
||||||
|
setHIdx = hlen;
|
||||||
|
}
|
||||||
|
this.historyIndex.set(setHIdx);
|
||||||
|
this.setHIdx = 0;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}).catch((err) => {
|
||||||
|
GlobalModel.errorHandler("getting history items", err, false);
|
||||||
|
mobx.action(() => {
|
||||||
|
this.historyLoading.set(false);
|
||||||
|
this.historyIndex.set(0);
|
||||||
|
})();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCurLine() {
|
clearCurLine() {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
this.historyIndex.set(0);
|
this.resetHistory();
|
||||||
this.modHistory.clear();
|
this.modHistory.replace([""]);
|
||||||
this.modHistory[0] = "";
|
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,24 +579,43 @@ class InputModel {
|
|||||||
if (hidx < this.modHistory.length && this.modHistory[hidx] != null) {
|
if (hidx < this.modHistory.length && this.modHistory[hidx] != null) {
|
||||||
return this.modHistory[hidx];
|
return this.modHistory[hidx];
|
||||||
}
|
}
|
||||||
let win = model.getActiveWindow();
|
let hitems = this.historyItems.get();
|
||||||
if (win == null) {
|
if (hidx == 0 || hitems == null || hidx > hitems.length) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
let hitem = win.getHistoryItem(-hidx);
|
let hitem = hitems[hidx-1];
|
||||||
if (hitem == null) {
|
if (hitem == null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return hitem.cmdtext;
|
return hitem.cmdstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetHistory() : void {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.historyLoading.set(false);
|
||||||
|
this.historyItems.set(null);
|
||||||
|
this.historyIndex.set(0);
|
||||||
|
if (this.modHistory.length > 1) {
|
||||||
|
this.modHistory.splice(1, this.modHistory.length-1);
|
||||||
|
}
|
||||||
|
this.setHIdx = 0;
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
prevHistoryItem() : void {
|
prevHistoryItem() : void {
|
||||||
let model = GlobalModel;
|
let loading = this.historyLoading.get();
|
||||||
let win = model.getActiveWindow();
|
let hitems = this.historyItems.get();
|
||||||
|
if (loading || hitems == null) {
|
||||||
|
this.setHIdx += 1;
|
||||||
|
if (!loading) {
|
||||||
|
this.loadHistory();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
let hidx = this.historyIndex.get();
|
let hidx = this.historyIndex.get();
|
||||||
hidx += 1;
|
hidx += 1;
|
||||||
if (hidx > win.getNumHistoryItems()) {
|
if (hidx > hitems.length) {
|
||||||
hidx = win.getNumHistoryItems();
|
hidx = hitems.length;
|
||||||
}
|
}
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
this.historyIndex.set(hidx);
|
this.historyIndex.set(hidx);
|
||||||
@ -560,6 +625,9 @@ class InputModel {
|
|||||||
|
|
||||||
nextHistoryItem() : void {
|
nextHistoryItem() : void {
|
||||||
let hidx = this.historyIndex.get();
|
let hidx = this.historyIndex.get();
|
||||||
|
if (hidx == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
hidx -= 1;
|
hidx -= 1;
|
||||||
if (hidx < 0) {
|
if (hidx < 0) {
|
||||||
hidx = 0;
|
hidx = 0;
|
||||||
@ -854,13 +922,16 @@ class Model {
|
|||||||
this.submitCommandPacket(pk);
|
this.submitCommandPacket(pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
submitRawCommand(cmdStr : string) {
|
submitRawCommand(cmdStr : string, addToHistory : boolean) {
|
||||||
let pk : FeCmdPacketType = {
|
let pk : FeCmdPacketType = {
|
||||||
type: "fecmd",
|
type: "fecmd",
|
||||||
metacmd: "eval",
|
metacmd: "eval",
|
||||||
args: [cmdStr],
|
args: [cmdStr],
|
||||||
kwargs: this.getClientKwargs(),
|
kwargs: this.getClientKwargs(),
|
||||||
};
|
};
|
||||||
|
if (!addToHistory) {
|
||||||
|
pk.kwargs["nohist"] = "1";
|
||||||
|
}
|
||||||
this.submitCommandPacket(pk)
|
this.submitCommandPacket(pk)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,7 +984,11 @@ class Model {
|
|||||||
}
|
}
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
this.deactivateWindows();
|
this.deactivateWindows();
|
||||||
|
let curSessionId = this.activeSessionId.get();
|
||||||
|
if (curSessionId != sessionId) {
|
||||||
this.activeSessionId.set(sessionId);
|
this.activeSessionId.set(sessionId);
|
||||||
|
this.inputModel.resetHistory();
|
||||||
|
}
|
||||||
this.getActiveSession().activeScreenId.set(screenId);
|
this.getActiveSession().activeScreenId.set(screenId);
|
||||||
})();
|
})();
|
||||||
let curScreen = this.getActiveScreen();
|
let curScreen = this.getActiveScreen();
|
||||||
@ -1005,23 +1080,23 @@ class InputClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switchSession(session : string) {
|
switchSession(session : string) {
|
||||||
GlobalModel.submitCommand("session", null, [session], null);
|
GlobalModel.submitCommand("session", null, [session], {"nohist": "1"});
|
||||||
}
|
}
|
||||||
|
|
||||||
switchScreen(screen : string) {
|
switchScreen(screen : string) {
|
||||||
GlobalModel.submitCommand("screen", null, [screen], null);
|
GlobalModel.submitCommand("screen", null, [screen], {"nohist": "1"});
|
||||||
}
|
}
|
||||||
|
|
||||||
createNewSession() {
|
createNewSession() {
|
||||||
GlobalModel.submitCommand("session", "open", null, null);
|
GlobalModel.submitCommand("session", "open", null, {"nohist": "1"});
|
||||||
}
|
}
|
||||||
|
|
||||||
createNewScreen() {
|
createNewScreen() {
|
||||||
GlobalModel.submitCommand("screen", "open", null, null);
|
GlobalModel.submitCommand("screen", "open", null, {"nohist": "1"});
|
||||||
}
|
}
|
||||||
|
|
||||||
closeScreen(screen : string) {
|
closeScreen(screen : string) {
|
||||||
GlobalModel.submitCommand("screen", "close", [screen], null);
|
GlobalModel.submitCommand("screen", "close", [screen], {"nohist": "1"});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
11
src/types.ts
11
src/types.ts
@ -98,7 +98,6 @@ type WindowDataType = {
|
|||||||
windowid : string,
|
windowid : string,
|
||||||
curremote : string,
|
curremote : string,
|
||||||
lines : LineType[],
|
lines : LineType[],
|
||||||
history : HistoryItem[],
|
|
||||||
cmds : CmdDataType[],
|
cmds : CmdDataType[],
|
||||||
remotes : RemoteInstanceType[],
|
remotes : RemoteInstanceType[],
|
||||||
|
|
||||||
@ -107,7 +106,17 @@ type WindowDataType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type HistoryItem = {
|
type HistoryItem = {
|
||||||
|
historyid : string,
|
||||||
|
ts : number,
|
||||||
|
userid : string,
|
||||||
|
sessionid : string,
|
||||||
|
screenid : string,
|
||||||
|
windowid : string,
|
||||||
|
lineid : number,
|
||||||
|
haderror : boolean,
|
||||||
|
cmdid : string,
|
||||||
cmdstr : string,
|
cmdstr : string,
|
||||||
|
remove : boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
type CmdRemoteStateType = {
|
type CmdRemoteStateType = {
|
||||||
|
Loading…
Reference in New Issue
Block a user