mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 24bba1305b |
@@ -194,11 +194,11 @@
|
||||
},
|
||||
{
|
||||
"command": "app:selectTabLeft",
|
||||
"keys": ["Cmd:[", "Shift:Cmd:["]
|
||||
"keys": ["Cmd:["]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTabRight",
|
||||
"keys": ["Cmd:]", "Shift:Cmd:]"]
|
||||
"keys": ["Cmd:]"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-1",
|
||||
|
||||
+2
-4
@@ -49,10 +49,8 @@
|
||||
"tsx-control-statements": "^5.1.1",
|
||||
"uuid": "^9.0.0",
|
||||
"winston": "^3.8.2",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-addon-web-links": "^0.9.0",
|
||||
"xterm-addon-serialize": "^0.11.0",
|
||||
"xterm-addon-webgl": "^0.16.0"
|
||||
"xterm": "^5.0.0",
|
||||
"xterm-addon-web-links": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.17.10",
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
--form-element-border-color: rgba(241, 246, 243, 0.15);
|
||||
--form-element-bg-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--form-element-text-color);
|
||||
--form-element-label-color: var(--app-text-secondary-color);
|
||||
--form-element-primary-color: var(--app-accent-color);
|
||||
--form-element-secondary-color: rgba(255, 255, 255, 0.2);
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
/* form colors */
|
||||
--form-element-border-color: rgba(0, 0, 0, 0.3);
|
||||
--form-element-bg-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--app-text-primary-color);
|
||||
--form-element-text-color: var(--app-text-color);
|
||||
--form-element-primary-text-color: var(--app-bg-color);
|
||||
--form-element-label-color: rgba(0, 0, 0, 0.6);
|
||||
--form-element-secondary-color: rgba(0, 0, 0, 0.09);
|
||||
--form-element-icon-color: rgb(0, 0, 0, 0.6);
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.danger {
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
|
||||
&.primary.outlined {
|
||||
background: none;
|
||||
border: 1px solid var(--form-element-primary-color);
|
||||
@@ -40,37 +36,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.greyoutlined {
|
||||
background: none;
|
||||
border: 1px solid var(--app-text-secondary-color);
|
||||
|
||||
i {
|
||||
fill: var(--app-text-secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.outlined,
|
||||
&.primary.greyoutlined {
|
||||
&.hover-danger:hover {
|
||||
color: var(--form-element-primary-text-color);
|
||||
border: 1px solid var(--app-error-color);
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.outlined.danger {
|
||||
background: none;
|
||||
border: 1px solid var(--app-error-color);
|
||||
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.greytext {
|
||||
color: var(--app-text-secondary-color);
|
||||
}
|
||||
|
||||
&.primary.ghost {
|
||||
background: none;
|
||||
i {
|
||||
@@ -78,13 +43,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.ghost.danger {
|
||||
background: none;
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-secondary-color);
|
||||
@@ -98,11 +56,6 @@
|
||||
border: 1px solid var(--form-element-text-color);
|
||||
}
|
||||
|
||||
&.secondary.outlined.danger {
|
||||
background: none;
|
||||
border: 1px solid var(--app-error-color);
|
||||
}
|
||||
|
||||
&.secondary.ghost {
|
||||
background: none;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
};
|
||||
this.wrapperRef = React.createRef();
|
||||
this.menuRef = React.createRef();
|
||||
this.curUuid = uuidv4();
|
||||
this.curUuid == uuidv4();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -100,9 +100,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
|
||||
@boundMethod
|
||||
handleClick() {
|
||||
if (!this.state.isOpen || !this.state.isTouched) {
|
||||
this.registerKeybindings();
|
||||
}
|
||||
this.toggleDropdown();
|
||||
}
|
||||
|
||||
@@ -112,7 +109,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
this.registerKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
registerKeybindings() {
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
let domain = "dropdown-" + this.curUuid;
|
||||
@@ -126,7 +122,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:cancel", (waveEvent) => {
|
||||
this.setState({ isOpen: false });
|
||||
this.unregisterKeybindings();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectAbove", (waveEvent) => {
|
||||
@@ -170,12 +165,10 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleBlur() {
|
||||
this.unregisterKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
unregisterKeybindings() {
|
||||
let domain = "dropdown-" + this.curUuid;
|
||||
GlobalModel.keybindManager.unregisterDomain(domain);
|
||||
@@ -196,7 +189,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
onChange(value);
|
||||
this.setState({ isOpen: false, isTouched: true });
|
||||
this.unregisterKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
|
||||
@@ -486,10 +486,10 @@ class HistoryView extends React.Component<{}, {}> {
|
||||
options={this.getRemoteItems(rnames, remoteIds)}
|
||||
onChange={this.clickLimitRemote}
|
||||
/>
|
||||
{/* <div className="fromts">
|
||||
<div className="fromts">
|
||||
<div className="fromts-text">From: </div>
|
||||
<DatePicker selectedDate={new Date()} onSelectDate={this.handleFromTsChange} />
|
||||
</div> */}
|
||||
</div>
|
||||
<div
|
||||
className="filter-cmds search-checkbox hoverEffect"
|
||||
title="Filter common commands like 'ls' and 'cd' from the results"
|
||||
|
||||
@@ -25,29 +25,4 @@
|
||||
&.collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.keybind-debug-pane {
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
.keybind-pane-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.keybind-level {
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.keybind-domain {
|
||||
font-size: 14px;
|
||||
margin-left: 20px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import dayjs from "dayjs";
|
||||
import { If, For } from "tsx-control-statements/components";
|
||||
|
||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import { GlobalModel } from "@/models";
|
||||
@@ -18,41 +17,6 @@ interface RightSideBarProps {
|
||||
parentRef: React.RefObject<HTMLElement>;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class KeybindDevPane extends React.Component<{}, {}> {
|
||||
render() {
|
||||
let curActiveKeybinds: Array<{ name: string; domains: Array<string> }> =
|
||||
GlobalModel.keybindManager.getActiveKeybindings();
|
||||
let keybindLevel: { name: string; domains: Array<string> } = null;
|
||||
let domain: string = null;
|
||||
let curVersion = GlobalModel.keybindManager.getActiveKeybindsVersion().get();
|
||||
let levelIdx: number = 0;
|
||||
let domainIdx: number = 0;
|
||||
let lastKeyData = GlobalModel.keybindManager.getLastKeyData();
|
||||
return (
|
||||
<div className="keybind-debug-pane">
|
||||
<div className="keybind-pane-title">Keybind Manager</div>
|
||||
<For index="levelIdx" each="keybindLevel" of={curActiveKeybinds}>
|
||||
<div className="keybind-level" key={"level-" + curVersion + levelIdx}>
|
||||
{keybindLevel.name}
|
||||
</div>
|
||||
<For index="domainIdx" each="domain" of={keybindLevel.domains}>
|
||||
<div className="keybind-domain" key={"domain-" + curVersion + domainIdx}>
|
||||
{domain}
|
||||
</div>
|
||||
</For>
|
||||
</For>
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
<h1>Last KeyPress Domain: {lastKeyData.domain}</h1>
|
||||
<h1>Last KeyPress key: {lastKeyData.keyPress}</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class RightSideBar extends React.Component<RightSideBarProps, {}> {
|
||||
render() {
|
||||
@@ -71,9 +35,6 @@ class RightSideBar extends React.Component<RightSideBarProps, {}> {
|
||||
<i className="fa-sharp fa-regular fa-xmark"></i>
|
||||
</Button>
|
||||
</div>
|
||||
<If condition={GlobalModel.isDev}>
|
||||
<KeybindDevPane></KeybindDevPane>
|
||||
</If>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</ResizableSidebar>
|
||||
|
||||
@@ -113,19 +113,21 @@ class AIChat extends React.Component<{}, {}> {
|
||||
mobx.action(() => {
|
||||
this.isFocused.set(true);
|
||||
})();
|
||||
GlobalModel.inputModel.codeSelectDeselectAndClear();
|
||||
}
|
||||
|
||||
onTextAreaBlur(e: any) {
|
||||
mobx.action(() => {
|
||||
this.isFocused.set(false);
|
||||
})();
|
||||
GlobalModel.inputModel.codeSelectDeselectAndClear();
|
||||
}
|
||||
|
||||
onTextAreaChange(e: any) {
|
||||
// set height of textarea based on number of newlines
|
||||
mobx.action(() => {
|
||||
this.textAreaNumLines.set(e.target.value.split(/\n/).length);
|
||||
GlobalModel.inputModel.codeSelectDeselectAll();
|
||||
GlobalModel.inputModel.codeSelectDeselectAndClear();
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -150,7 +152,7 @@ class AIChat extends React.Component<{}, {}> {
|
||||
return;
|
||||
}
|
||||
currentRef.setRangeText("\n", currentRef.selectionStart, currentRef.selectionEnd, "end");
|
||||
GlobalModel.inputModel.codeSelectDeselectAll();
|
||||
GlobalModel.inputModel.codeSelectDeselectAndClear();
|
||||
}
|
||||
|
||||
onArrowUpPressed(): boolean {
|
||||
@@ -160,7 +162,7 @@ class AIChat extends React.Component<{}, {}> {
|
||||
}
|
||||
if (this.getLinePos(currentRef).linePos > 1) {
|
||||
// normal up arrow
|
||||
GlobalModel.inputModel.codeSelectDeselectAll();
|
||||
GlobalModel.inputModel.codeSelectDeselectAndClear();
|
||||
return false;
|
||||
}
|
||||
GlobalModel.inputModel.codeSelectSelectNextOldestCodeBlock();
|
||||
|
||||
@@ -11,7 +11,7 @@ import cn from "classnames";
|
||||
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
||||
import { getMonoFontSize } from "@/util/textmeasure";
|
||||
import * as appconst from "@/app/appconst";
|
||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent, WaveKeyboardEvent } from "@/util/keyutil";
|
||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||
|
||||
type OV<T> = mobx.IObservableValue<T>;
|
||||
|
||||
@@ -41,11 +41,9 @@ function scrollDiv(div: any, amt: number) {
|
||||
|
||||
class HistoryKeybindings extends React.Component<{ inputObject: TextAreaInput }, {}> {
|
||||
componentDidMount(): void {
|
||||
if (GlobalModel.activeMainView != "session") {
|
||||
return;
|
||||
}
|
||||
let inputModel = GlobalModel.inputModel;
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
|
||||
keybindManager.registerKeybinding("pane", "history", "generic:cancel", (waveEvent) => {
|
||||
inputModel.resetHistory();
|
||||
return true;
|
||||
@@ -103,12 +101,8 @@ class HistoryKeybindings extends React.Component<{ inputObject: TextAreaInput },
|
||||
|
||||
class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }, {}> {
|
||||
lastTab: boolean;
|
||||
curPress: string;
|
||||
|
||||
componentDidMount() {
|
||||
if (GlobalModel.activeMainView != "session") {
|
||||
return;
|
||||
}
|
||||
let inputObject = this.props.inputObject;
|
||||
this.lastTab = false;
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
@@ -116,7 +110,6 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "cmdinput:autocomplete", (waveEvent) => {
|
||||
let lastTab = this.lastTab;
|
||||
this.lastTab = true;
|
||||
this.curPress = "tab";
|
||||
let curLine = inputModel.getCurLine();
|
||||
if (lastTab) {
|
||||
GlobalModel.submitCommand(
|
||||
@@ -185,12 +178,10 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "cmdinput:previousHistoryItem", (waveEvent) => {
|
||||
this.curPress = "historyupdown";
|
||||
inputObject.controlP();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "cmdinput:nextHistoryItem", (waveEvent) => {
|
||||
this.curPress = "historyupdown";
|
||||
inputObject.controlN();
|
||||
return true;
|
||||
});
|
||||
@@ -199,22 +190,18 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectAbove", (waveEvent) => {
|
||||
this.curPress = "historyupdown";
|
||||
let rtn = inputObject.arrowUpPressed();
|
||||
return rtn;
|
||||
inputObject.arrowUpPressed();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectBelow", (waveEvent) => {
|
||||
this.curPress = "historyupdown";
|
||||
let rtn = inputObject.arrowDownPressed();
|
||||
return rtn;
|
||||
inputObject.arrowDownPressed();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectPageAbove", (waveEvent) => {
|
||||
this.curPress = "historyupdown";
|
||||
inputObject.scrollPage(true);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectPageBelow", (waveEvent) => {
|
||||
this.curPress = "historyupdown";
|
||||
inputObject.scrollPage(false);
|
||||
return true;
|
||||
});
|
||||
@@ -222,16 +209,6 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
|
||||
inputObject.modEnter();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerDomainCallback("cmdinput", (waveEvent) => {
|
||||
if (this.curPress != "tab") {
|
||||
this.lastTab = false;
|
||||
}
|
||||
if (this.curPress != "historyupdown") {
|
||||
inputObject.lastHistoryUpDown = false;
|
||||
}
|
||||
this.curPress = "";
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@@ -161,11 +161,11 @@
|
||||
}
|
||||
|
||||
.newtab-container {
|
||||
margin: 8px 16px 0 16px;
|
||||
margin: 16px;
|
||||
|
||||
.newtab-section {
|
||||
display: flex;
|
||||
padding: 10px 16px;
|
||||
padding: 16px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
|
||||
@@ -558,6 +558,9 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
|
||||
return (
|
||||
<div className="window-view" ref={this.windowViewRef} style={{ width: this.props.width }}>
|
||||
<If condition={lines.length == 0}>
|
||||
<If condition={false && screen.nextLineNum.get() == 1}>
|
||||
<NewTabSettings screen={screen} />
|
||||
</If>
|
||||
<If condition={screen.nextLineNum.get() != 1}>
|
||||
<div className="window-empty" ref={this.windowViewRef} data-screenid={screen.screenId}>
|
||||
<div key="lines" className="lines"></div>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
position: absolute;
|
||||
top: var(--screentabs-height);
|
||||
width: 100%;
|
||||
height: 330px;
|
||||
transition: height 0.2s ease-in-out;
|
||||
overflow: hidden;
|
||||
z-index: 11;
|
||||
|
||||
@@ -8,7 +8,7 @@ import cn from "classnames";
|
||||
import dayjs from "dayjs";
|
||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { CmdInput } from "./cmdinput/cmdinput";
|
||||
import { ScreenView } from "./screen/screenview";
|
||||
import { ScreenTabs } from "./screen/tabs";
|
||||
@@ -17,17 +17,11 @@ import * as textmeasure from "@/util/textmeasure";
|
||||
import "./workspace.less";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import type { Screen } from "@/models";
|
||||
import { Button } from "@/elements";
|
||||
import { getRemoteStr, getRemoteStrWithAlias } from "@/common/prompt/prompt";
|
||||
import { TabColorSelector, TabIconSelector, TabNameTextField, TabRemoteSelector } from "./screen/newtabsettings";
|
||||
import * as util from "@/util/util";
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
|
||||
const ScreenDeleteMessage = `
|
||||
Are you sure you want to delete this tab?
|
||||
`.trim();
|
||||
|
||||
class SessionKeybindings extends React.Component<{}, {}> {
|
||||
componentDidMount() {
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
@@ -54,34 +48,33 @@ class SessionKeybindings extends React.Component<{}, {}> {
|
||||
GlobalModel.onBracketCmd(1);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "screen", "app:selectLineAbove", (waveEvent) => {
|
||||
keybindManager.registerKeybinding("pane", "session", "app:selectLineAbove", (waveEvent) => {
|
||||
GlobalModel.onMetaArrowUp();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "screen", "app:selectLineBelow", (waveEvent) => {
|
||||
keybindManager.registerKeybinding("pane", "session", "app:selectLineBelow", (waveEvent) => {
|
||||
GlobalModel.onMetaArrowDown();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "screen", "app:restartCommand", (waveEvent) => {
|
||||
keybindManager.registerKeybinding("pane", "session", "app:restartCommand", (waveEvent) => {
|
||||
GlobalModel.onRestartCommand();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "screen", "app:restartLastCommand", (waveEvent) => {
|
||||
keybindManager.registerKeybinding("pane", "session", "app:restartLastCommand", (waveEvent) => {
|
||||
GlobalModel.onRestartLastCommand();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "screen", "app:focusSelectedLine", (waveEvent) => {
|
||||
keybindManager.registerKeybinding("pane", "session", "app:focusSelectedLine", (waveEvent) => {
|
||||
GlobalModel.onFocusSelectedLine();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("pane", "screen", "app:deleteActiveLine", (waveEvent) => {
|
||||
keybindManager.registerKeybinding("pane", "session", "app:deleteActiveLine", (waveEvent) => {
|
||||
return GlobalModel.handleDeleteActiveLine();
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
GlobalModel.keybindManager.unregisterDomain("session");
|
||||
GlobalModel.keybindManager.unregisterDomain("screen");
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -112,29 +105,6 @@ class TabSettingsPulldownKeybindings extends React.Component<{}, {}> {
|
||||
class TabSettings extends React.Component<{ screen: Screen }, {}> {
|
||||
errorMessage: OV<string> = mobx.observable.box(null, { name: "TabSettings-errorMessage" });
|
||||
|
||||
@boundMethod
|
||||
handleDeleteScreen(): void {
|
||||
const { screen } = this.props;
|
||||
if (screen == null) {
|
||||
return;
|
||||
}
|
||||
if (screen.getScreenLines().lines.length == 0) {
|
||||
GlobalCommandRunner.screenDelete(screen.screenId, false);
|
||||
GlobalModel.modalsModel.popModal();
|
||||
return;
|
||||
}
|
||||
let message = ScreenDeleteMessage;
|
||||
let alertRtn = GlobalModel.showAlert({ message: message, confirm: true, markdown: true });
|
||||
alertRtn.then((result) => {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
let prtn = GlobalCommandRunner.screenDelete(screen.screenId, false);
|
||||
util.commandRtnHandler(prtn, this.errorMessage);
|
||||
GlobalModel.modalsModel.popModal();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let { screen } = this.props;
|
||||
let rptr = screen.curRemote.get();
|
||||
@@ -163,16 +133,6 @@ class TabSettings extends React.Component<{ screen: Screen }, {}> {
|
||||
<div className="newtab-section">
|
||||
<TabColorSelector screen={screen} errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
<div className="newtab-spacer" />
|
||||
<div className="newtab-section">
|
||||
<Button
|
||||
onClick={this.handleDeleteScreen}
|
||||
style={{ paddingTop: 4, paddingBottom: 4 }}
|
||||
className="primary greyoutlined greytext hover-danger"
|
||||
>
|
||||
Delete Tab
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -221,7 +181,7 @@ class WorkspaceView extends React.Component<{}, {}> {
|
||||
<i className="fa-solid fa-sharp fa-xmark-large" />
|
||||
</div>
|
||||
<TabSettings key={activeScreen.screenId} screen={activeScreen} />
|
||||
<If condition={showTabSettings && !isHidden}>
|
||||
<If condition={showTabSettings}>
|
||||
<TabSettingsPulldownKeybindings />
|
||||
</If>
|
||||
</div>
|
||||
|
||||
+9
-6
@@ -582,7 +582,7 @@ class InputModel {
|
||||
}
|
||||
let incBlockIndex = this.codeSelectSelectedIndex.get() + 1;
|
||||
if (this.codeSelectSelectedIndex.get() == this.codeSelectBlockRefArray.length - 1) {
|
||||
this.codeSelectDeselectAll();
|
||||
this.codeSelectDeselectAndClear();
|
||||
if (this.aiChatWindowRef?.current != null) {
|
||||
this.aiChatWindowRef.current.scrollTop = this.aiChatWindowRef.current.scrollHeight;
|
||||
}
|
||||
@@ -606,7 +606,7 @@ class InputModel {
|
||||
}
|
||||
let decBlockIndex = this.codeSelectSelectedIndex.get() - 1;
|
||||
if (decBlockIndex < 0) {
|
||||
this.codeSelectDeselectAll(this.codeSelectTop);
|
||||
this.codeSelectDeselectAndClear(this.codeSelectTop);
|
||||
if (this.aiChatWindowRef?.current != null) {
|
||||
this.aiChatWindowRef.current.scrollTop = 0;
|
||||
}
|
||||
@@ -629,16 +629,19 @@ class InputModel {
|
||||
return blockIndex == this.codeSelectSelectedIndex.get();
|
||||
}
|
||||
|
||||
codeSelectDeselectAll(direction: number = this.codeSelectBottom) {
|
||||
if (this.codeSelectSelectedIndex.get() == direction) {
|
||||
return;
|
||||
}
|
||||
codeSelectDeselectAndClear(direction: number = this.codeSelectBottom) {
|
||||
mobx.action(() => {
|
||||
this.codeSelectSelectedIndex.set(direction);
|
||||
this.codeSelectBlockRefArray = [];
|
||||
})();
|
||||
}
|
||||
|
||||
codeSelectDeselectAll(direction: number = this.codeSelectBottom) {
|
||||
mobx.action(() => {
|
||||
this.codeSelectSelectedIndex.set(direction);
|
||||
})();
|
||||
}
|
||||
|
||||
openAIAssistantChat(): void {
|
||||
mobx.action(() => {
|
||||
this.aIChatShow.set(true);
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
import * as mobx from "mobx";
|
||||
import { Terminal } from "xterm";
|
||||
import type { ITheme } from "xterm";
|
||||
//TODO: replace with `@xterm/addon-web-links` when it's available as stable
|
||||
import { WebLinksAddon } from "xterm-addon-web-links";
|
||||
import { sprintf } from "sprintf-js";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { windowWidthToCols, windowHeightToRows } from "@/util/textmeasure";
|
||||
import { boundInt } from "@/util/util";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { WebglAddon } from "xterm-addon-webgl";
|
||||
import { WebLinksAddon } from "xterm-addon-web-links";
|
||||
import { SerializeAddon } from "xterm-addon-serialize";
|
||||
|
||||
type DataUpdate = {
|
||||
data: Uint8Array;
|
||||
@@ -21,20 +20,6 @@ type DataUpdate = {
|
||||
const MinTermCols = 10;
|
||||
const MaxTermCols = 1024;
|
||||
|
||||
// detect webgl support
|
||||
function detectWebGLSupport(): boolean {
|
||||
try {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("webgl");
|
||||
return !!ctx;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const WebGLSupported = detectWebGLSupport();
|
||||
let loggedWebGL = false;
|
||||
|
||||
type TermWrapOpts = {
|
||||
termContext: TermContextUnion;
|
||||
usedRows?: number;
|
||||
@@ -102,7 +87,6 @@ class TermWrap {
|
||||
ptyDataSource: (termContext: TermContextUnion) => Promise<PtyDataType>;
|
||||
initializing: boolean;
|
||||
dataHandler?: (data: string, termWrap: TermWrap) => void;
|
||||
serializeAddon: SerializeAddon;
|
||||
|
||||
constructor(elem: Element, opts: TermWrapOpts) {
|
||||
opts = opts ?? ({} as any);
|
||||
@@ -158,19 +142,6 @@ class TermWrap {
|
||||
}
|
||||
})
|
||||
);
|
||||
if (WebGLSupported && GlobalModel.clientData.get().clientopts?.webgl) {
|
||||
const webglAddon = new WebglAddon();
|
||||
webglAddon.onContextLoss(() => {
|
||||
webglAddon.dispose();
|
||||
});
|
||||
this.terminal.loadAddon(webglAddon);
|
||||
if (!loggedWebGL) {
|
||||
console.log("loaded webgl!");
|
||||
loggedWebGL = true;
|
||||
}
|
||||
}
|
||||
this.serializeAddon = new SerializeAddon();
|
||||
this.terminal.loadAddon(this.serializeAddon);
|
||||
this.terminal._core._inputHandler._parser.setErrorHandler((state) => {
|
||||
this.numParseErrors++;
|
||||
return state;
|
||||
|
||||
Vendored
-1
@@ -588,7 +588,6 @@ declare global {
|
||||
};
|
||||
globalshortcut: string;
|
||||
globalshortcutenabled: boolean;
|
||||
webgl: boolean;
|
||||
};
|
||||
|
||||
type ReleaseInfoType = {
|
||||
|
||||
+11
-213
@@ -49,8 +49,6 @@ class KeybindManager {
|
||||
userKeybindings: KeybindConfigArray;
|
||||
userKeybindingError: OV<string>;
|
||||
globalModel: any;
|
||||
activeKeybindsVersion: OV<number>;
|
||||
lastKeyData: { domain: string; keyPress: string };
|
||||
|
||||
constructor(GlobalModel: any) {
|
||||
this.levelMap = new Map();
|
||||
@@ -61,14 +59,10 @@ class KeybindManager {
|
||||
this.levelMap.set(curLevel, new Array<Keybind>());
|
||||
}
|
||||
this.userKeybindingError = mobx.observable.box(null, {
|
||||
name: "keybindManager-userKeybindingError",
|
||||
});
|
||||
this.activeKeybindsVersion = mobx.observable.box(0, {
|
||||
name: "keybindManager-activeKeybindsVersion",
|
||||
name: "keyutil-userKeybindingError",
|
||||
});
|
||||
this.globalModel = GlobalModel;
|
||||
this.initKeyDescriptionsMap();
|
||||
this.lastKeyData = { domain: "none", keyPress: "none" };
|
||||
}
|
||||
|
||||
initKeyDescriptionsMap() {
|
||||
@@ -129,7 +123,8 @@ class KeybindManager {
|
||||
this.keyDescriptionsMap = newKeyDescriptions;
|
||||
}
|
||||
|
||||
prettyPrintKeyPress(keyPress: KeyPressDecl): string {
|
||||
prettyPrintKeybind(keyDescription: string): string {
|
||||
let keyPress = parseKeyDescription(keyDescription);
|
||||
let returnString = "";
|
||||
if (keyPress.mods.Cmd) {
|
||||
returnString += "⌘";
|
||||
@@ -153,11 +148,6 @@ class KeybindManager {
|
||||
return returnString;
|
||||
}
|
||||
|
||||
prettyPrintKeybind(keyDescription: string): string {
|
||||
let keyPress = parseKeyDescription(keyDescription);
|
||||
return this.prettyPrintKeyPress(keyPress);
|
||||
}
|
||||
|
||||
getUIDescription(keyDescription: string, prettyPrint: boolean = true): KeybindConfig {
|
||||
let keybinds = this.getKeybindsFromDescription(keyDescription, prettyPrint);
|
||||
if (!this.keyDescriptionsMap.has(keyDescription)) {
|
||||
@@ -238,26 +228,10 @@ class KeybindManager {
|
||||
});
|
||||
}
|
||||
|
||||
runDomainCallbacks(event: WaveKeyboardEvent, curDomainCallbacks: Map<string, KeybindCallback>) {
|
||||
for (let key of curDomainCallbacks.keys()) {
|
||||
let callback = curDomainCallbacks.get(key);
|
||||
if (callback != null) {
|
||||
callback(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processLevel(nativeEvent: any, event: WaveKeyboardEvent, keybindsArray: Array<Keybind>): boolean {
|
||||
// iterate through keybinds in backwards order
|
||||
let domainCallbacksToRun: Map<string, KeybindCallback> = new Map();
|
||||
for (let index = keybindsArray.length - 1; index >= 0; index--) {
|
||||
let curKeybind = keybindsArray[index];
|
||||
if (this.domainCallbacks.has(curKeybind.domain)) {
|
||||
let curDomainCallback = this.domainCallbacks.get(curKeybind.domain);
|
||||
if (curDomainCallback != null) {
|
||||
domainCallbacksToRun.set(curKeybind.domain, curDomainCallback);
|
||||
}
|
||||
}
|
||||
if (this.checkKeyPressed(event, curKeybind.keybinding)) {
|
||||
if (DumpLogs) {
|
||||
console.log("keybind found", curKeybind);
|
||||
@@ -268,60 +242,12 @@ class KeybindManager {
|
||||
shouldReturn = curKeybind.callback(event);
|
||||
shouldRunCommand = false;
|
||||
}
|
||||
if (shouldRunCommand) {
|
||||
shouldReturn = this.runSlashCommand(curKeybind);
|
||||
}
|
||||
if (shouldReturn) {
|
||||
nativeEvent.preventDefault();
|
||||
nativeEvent.stopPropagation();
|
||||
this.lastKeyData.domain = curKeybind.domain;
|
||||
this.lastKeyData.keyPress = this.prettyPrintKeyPress(
|
||||
getKeyPressDeclFromKeyboardEvent(event, KeyTypeKey)
|
||||
);
|
||||
mobx.action(() => {
|
||||
this.activeKeybindsVersion.set(this.activeKeybindsVersion.get() + 1);
|
||||
})();
|
||||
this.runDomainCallbacks(event, domainCallbacksToRun);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.lastKeyData.domain = "none";
|
||||
this.lastKeyData.keyPress = "none";
|
||||
mobx.action(() => {
|
||||
this.activeKeybindsVersion.set(this.activeKeybindsVersion.get() + 1);
|
||||
})();
|
||||
this.runDomainCallbacks(event, domainCallbacksToRun);
|
||||
return false;
|
||||
}
|
||||
|
||||
processModalLevel(nativeEvent: any, event: WaveKeyboardEvent, keybindsArray: Array<Keybind>): boolean {
|
||||
let curModalDomain: string = "";
|
||||
// iterate through keybinds in backwards order
|
||||
let domainCallbacksToRun: Map<string, KeybindCallback> = new Map();
|
||||
for (let index = keybindsArray.length - 1; index >= 0; index--) {
|
||||
let curKeybind = keybindsArray[index];
|
||||
if (curModalDomain == "") {
|
||||
curModalDomain = curKeybind.domain;
|
||||
}
|
||||
if (curKeybind.domain != curModalDomain) {
|
||||
continue;
|
||||
}
|
||||
if (this.domainCallbacks.has(curKeybind.domain)) {
|
||||
let curDomainCallback = this.domainCallbacks.get(curKeybind.domain);
|
||||
if (curDomainCallback != null) {
|
||||
domainCallbacksToRun.set(curKeybind.domain, curDomainCallback);
|
||||
}
|
||||
}
|
||||
if (this.checkKeyPressed(event, curKeybind.keybinding)) {
|
||||
if (DumpLogs) {
|
||||
console.log("keybind found", curKeybind);
|
||||
}
|
||||
let shouldReturn = false;
|
||||
let shouldRunCommand = true;
|
||||
if (curKeybind.callback != null) {
|
||||
shouldReturn = curKeybind.callback(event);
|
||||
if (!shouldReturn && this.domainCallbacks.has(curKeybind.domain)) {
|
||||
shouldRunCommand = false;
|
||||
let curDomainCallback = this.domainCallbacks.get(curKeybind.domain);
|
||||
if (curDomainCallback != null) {
|
||||
shouldReturn = curDomainCallback(event);
|
||||
}
|
||||
}
|
||||
if (shouldRunCommand) {
|
||||
shouldReturn = this.runSlashCommand(curKeybind);
|
||||
@@ -329,12 +255,10 @@ class KeybindManager {
|
||||
if (shouldReturn) {
|
||||
nativeEvent.preventDefault();
|
||||
nativeEvent.stopPropagation();
|
||||
this.runDomainCallbacks(event, domainCallbacksToRun);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.runDomainCallbacks(event, domainCallbacksToRun);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -348,7 +272,7 @@ class KeybindManager {
|
||||
if (shouldReturn) {
|
||||
return true;
|
||||
}
|
||||
shouldReturn = this.processModalLevel(nativeEvent, event, modalLevel);
|
||||
shouldReturn = this.processLevel(nativeEvent, event, modalLevel);
|
||||
if (shouldReturn) {
|
||||
return true;
|
||||
}
|
||||
@@ -390,104 +314,6 @@ class KeybindManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
getActiveKeybindsVersion() {
|
||||
return this.activeKeybindsVersion;
|
||||
}
|
||||
|
||||
checkKeyInKeybinding(key: string, keyDescription: string) {
|
||||
if (keyDescription == "any") {
|
||||
return true;
|
||||
}
|
||||
if (!this.keyDescriptionsMap.has(keyDescription)) {
|
||||
return false;
|
||||
}
|
||||
let keyPressArray = this.keyDescriptionsMap.get(keyDescription).keys;
|
||||
for (let index = 0; index < keyPressArray.length; index++) {
|
||||
let curKeyPress = keyPressArray[index];
|
||||
if (keybindingIsEqual(key, curKeyPress)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
lookupKeyInLevel(key: string, level: Array<Keybind>): Array<Keybind> {
|
||||
let toReturn: Array<Keybind> = [];
|
||||
for (let index = level.length - 1; index >= 0; index--) {
|
||||
let curKeybind = level[index];
|
||||
console.log("index", index, "curKeybind: ", curKeybind);
|
||||
if (this.checkKeyInKeybinding(key, curKeybind.keybinding)) {
|
||||
toReturn.push({ ...curKeybind }); // shallow copy
|
||||
}
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
lookupKey(key: string) {
|
||||
let modalLevel = this.levelMap.get("modal");
|
||||
let toReturn: Array<Keybind> = [];
|
||||
if (modalLevel.length != 0) {
|
||||
let controlLevel = this.levelMap.get("control");
|
||||
toReturn = toReturn.concat(this.lookupKeyInLevel(key, controlLevel));
|
||||
toReturn = toReturn.concat(this.lookupKeyInLevel(key, modalLevel));
|
||||
let systemLevel = this.levelMap.get("system");
|
||||
toReturn = toReturn.concat(this.lookupKeyInLevel(key, systemLevel));
|
||||
return toReturn;
|
||||
}
|
||||
for (let index = this.levelArray.length - 1; index >= 0; index--) {
|
||||
let curLevel = this.levelArray[index];
|
||||
let curKeybindsArray;
|
||||
if (this.levelMap.has(curLevel)) {
|
||||
curKeybindsArray = this.levelMap.get(curLevel);
|
||||
} else {
|
||||
console.error("error processing key event: couldn't find level: ", curLevel);
|
||||
continue;
|
||||
}
|
||||
toReturn = toReturn.concat(this.lookupKeyInLevel(key, curKeybindsArray));
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
getDomainListForLevel(level: Array<Keybind>): Array<string> {
|
||||
let toReturn: Array<string> = [];
|
||||
for (let index = 0; index < level.length; index++) {
|
||||
let curDomain = level[index].domain;
|
||||
if (!toReturn.includes(curDomain)) {
|
||||
toReturn.push(curDomain);
|
||||
}
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
getLastKeyData() {
|
||||
return this.lastKeyData;
|
||||
}
|
||||
|
||||
getActiveKeybindings(): Array<{ name: string; domains: Array<string> }> {
|
||||
let modalLevel = this.levelMap.get("modal");
|
||||
let toReturn: Array<{ name: string; domains: Array<string> }> = [];
|
||||
if (modalLevel.length != 0) {
|
||||
let controlLevel = this.levelMap.get("control");
|
||||
toReturn.push({ name: "control", domains: this.getDomainListForLevel(controlLevel) });
|
||||
toReturn.push({ name: "modal", domains: this.getDomainListForLevel(modalLevel) });
|
||||
let systemLevel = this.levelMap.get("system");
|
||||
toReturn.push({ name: "system", domains: this.getDomainListForLevel(systemLevel) });
|
||||
return toReturn;
|
||||
}
|
||||
for (let index = this.levelArray.length - 1; index >= 0; index--) {
|
||||
let curLevel = this.levelArray[index];
|
||||
let curKeybindsArray;
|
||||
if (this.levelMap.has(curLevel)) {
|
||||
curKeybindsArray = this.levelMap.get(curLevel);
|
||||
} else {
|
||||
console.error("error processing key event: couldn't find level: ", curLevel);
|
||||
continue;
|
||||
}
|
||||
toReturn.push({ name: curLevel, domains: this.getDomainListForLevel(curKeybindsArray) });
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
registerKeybinding(level: string, domain: string, keybinding: string, callback: KeybindCallback): boolean {
|
||||
if (domain == "" || this.keybindingAlreadyAdded(level, domain, keybinding)) {
|
||||
return false;
|
||||
@@ -500,9 +326,6 @@ class KeybindManager {
|
||||
let curKeybindArray = this.levelMap.get(level);
|
||||
curKeybindArray.push(newKeybind);
|
||||
this.levelMap.set(level, curKeybindArray);
|
||||
mobx.action(() => {
|
||||
this.activeKeybindsVersion.set(this.activeKeybindsVersion.get() + 1);
|
||||
})();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -548,11 +371,8 @@ class KeybindManager {
|
||||
keybindsArray.splice(index, 1);
|
||||
index--;
|
||||
this.levelMap.set(level, keybindsArray);
|
||||
return true;
|
||||
}
|
||||
mobx.action(() => {
|
||||
this.activeKeybindsVersion.set(this.activeKeybindsVersion.get() + 1);
|
||||
})();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -572,13 +392,10 @@ class KeybindManager {
|
||||
}
|
||||
}
|
||||
this.domainCallbacks.delete(domain);
|
||||
mobx.action(() => {
|
||||
this.activeKeybindsVersion.set(this.activeKeybindsVersion.get() + 1);
|
||||
})();
|
||||
return foundKeybind;
|
||||
}
|
||||
|
||||
registerDomainCallback(domain: string, callback: KeybindCallback) {
|
||||
getKeyPressEventForDomain(domain: string, callback: KeybindCallback) {
|
||||
if (callback == null) {
|
||||
console.log("domain callback can't be null");
|
||||
}
|
||||
@@ -666,25 +483,6 @@ function parseKeyDescription(keyDescription: string): KeyPressDecl {
|
||||
return rtn;
|
||||
}
|
||||
|
||||
function getKeyPressDeclFromKeyboardEvent(waveEvent: WaveKeyboardEvent, keyType: string): KeyPressDecl {
|
||||
let rtn = { key: "", mods: {} } as KeyPressDecl;
|
||||
rtn.mods.Cmd = waveEvent.cmd;
|
||||
rtn.mods.Ctrl = waveEvent.control;
|
||||
rtn.mods.Shift = waveEvent.shift;
|
||||
rtn.mods.Option = waveEvent.option;
|
||||
rtn.mods.Alt = waveEvent.alt && !waveEvent.option;
|
||||
rtn.mods.Meta = waveEvent.meta && !waveEvent.cmd;
|
||||
if (keyType == KeyTypeKey) {
|
||||
rtn.key = waveEvent.code;
|
||||
rtn.keyType = KeyTypeKey;
|
||||
}
|
||||
if (keyType == KeyTypeCode) {
|
||||
rtn.key = waveEvent.code;
|
||||
rtn.keyType = KeyTypeCode;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
function parseKey(key: string): { key: string; type: string } {
|
||||
let regexMatch = key.match(KeyTypeCodeRegex);
|
||||
if (regexMatch != null && regexMatch.length > 1) {
|
||||
|
||||
@@ -743,14 +743,13 @@ func MakeCmdFinalPacket(ck base.CommandKey) *CmdFinalPacketType {
|
||||
}
|
||||
|
||||
type CmdDonePacketType struct {
|
||||
Type string `json:"type"`
|
||||
Ts int64 `json:"ts"`
|
||||
CK base.CommandKey `json:"ck"`
|
||||
ExitCode int `json:"exitcode"`
|
||||
DurationMs int64 `json:"durationms"`
|
||||
FinalState *ShellState `json:"finalstate,omitempty"`
|
||||
FinalStateDiff *ShellStateDiff `json:"finalstatediff,omitempty"`
|
||||
FinalStateBasePtr *ShellStatePtr `json:"finalstatebaseptr,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Ts int64 `json:"ts"`
|
||||
CK base.CommandKey `json:"ck"`
|
||||
ExitCode int `json:"exitcode"`
|
||||
DurationMs int64 `json:"durationms"`
|
||||
FinalState *ShellState `json:"finalstate,omitempty"`
|
||||
FinalStateDiff *ShellStateDiff `json:"finalstatediff,omitempty"`
|
||||
}
|
||||
|
||||
func (*CmdDonePacketType) GetType() string {
|
||||
@@ -815,10 +814,10 @@ type RunPacketType struct {
|
||||
Type string `json:"type"`
|
||||
ReqId string `json:"reqid"`
|
||||
CK base.CommandKey `json:"ck"`
|
||||
ShellType string `json:"shelltype"` // added in Wave v0.6.0 (either "bash" or "zsh") (set by remote.go)
|
||||
ShellType string `json:"shelltype"` // new in v0.6.0 (either "bash" or "zsh") (set by remote.go)
|
||||
Command string `json:"command"`
|
||||
State *ShellState `json:"state,omitempty"`
|
||||
StatePtr *ShellStatePtr `json:"stateptr,omitempty"` // added in Wave v0.7.2
|
||||
StateDiff *ShellStateDiff `json:"statediff,omitempty"`
|
||||
StateComplete bool `json:"statecomplete,omitempty"` // set to true if state is complete (the default env should not be set)
|
||||
UsePty bool `json:"usepty,omitempty"`
|
||||
TermOpts *TermOpts `json:"termopts,omitempty"`
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user