This commit is contained in:
Olivier Gagnon 2022-03-10 22:34:54 -05:00
parent 9b12da4eb7
commit 9c3c83dcd5

@ -32,8 +32,8 @@ import Typography from "@mui/material/Typography";
import Link from "@mui/material/Link";
import Box from "@mui/material/Box";
import SettingsIcon from "@mui/icons-material/Settings";
import SyncIcon from '@mui/icons-material/Sync';
import CloseIcon from '@mui/icons-material/Close';
import SyncIcon from "@mui/icons-material/Sync";
import CloseIcon from "@mui/icons-material/Close";
import Table from "@mui/material/Table";
import TableCell from "@mui/material/TableCell";
import TableRow from "@mui/material/TableRow";
@ -133,13 +133,12 @@ export function Root(props: IProps): React.ReactElement {
// Prevent Crash if script is open on deleted server
openScripts = openScripts.filter((script) => {
return GetServer(script.hostname) !== null;
})
if (currentScript && (GetServer(currentScript.hostname) === null)) {
});
if (currentScript && GetServer(currentScript.hostname) === null) {
currentScript = openScripts[0];
if (currentScript === undefined) currentScript = null;
}
const [dimensions, setDimensions] = useState({
height: window.innerHeight,
width: window.innerWidth,
@ -208,7 +207,7 @@ export function Root(props: IProps): React.ReactElement {
// Setup "go to next tab" and "go to previous tab". This is a little more involved
// since these aren't Ex commands (they run in normal mode, not after typing `:`)
MonacoVim.VimMode.Vim.defineAction("nextTabs", function (_cm: any, args: {repeat?: number}, _vim: any) {
MonacoVim.VimMode.Vim.defineAction("nextTabs", function (_cm: any, args: { repeat?: number }) {
const nTabs = args.repeat ?? 1;
// Go to the next tab (to the right). Wraps around when at the rightmost tab
const currIndex = currentTabIndex();
@ -217,23 +216,23 @@ export function Root(props: IProps): React.ReactElement {
onTabClick(nextIndex);
}
});
MonacoVim.VimMode.Vim.defineAction("prevTabs", function (_cm: any, args: {repeat?: number}, _vim: any) {
MonacoVim.VimMode.Vim.defineAction("prevTabs", function (_cm: any, args: { repeat?: number }) {
const nTabs = args.repeat ?? 1;
// Go to the previous tab (to the left). Wraps around when at the leftmost tab
const currIndex = currentTabIndex();
if (currIndex !== undefined) {
let nextIndex = (currIndex - nTabs);
let nextIndex = currIndex - nTabs;
while (nextIndex < 0) {
nextIndex += openScripts.length;
}
onTabClick(nextIndex);
}
});
MonacoVim.VimMode.Vim.mapCommand("gt", "action", "nextTabs", {}, {context: "normal"});
MonacoVim.VimMode.Vim.mapCommand("gT", "action", "prevTabs", {}, {context: "normal"});
MonacoVim.VimMode.Vim.mapCommand("gt", "action", "nextTabs", {}, { context: "normal" });
MonacoVim.VimMode.Vim.mapCommand("gT", "action", "prevTabs", {}, { context: "normal" });
editor.focus();
});
} catch { }
} catch {}
} else if (!options.vim) {
// Whem vim mode is disabled
vimEditor?.dispose();
@ -342,13 +341,18 @@ export function Root(props: IProps): React.ReactElement {
.loader();
// replaced the bare tokens with regexes surrounded by \b, e.g. \b{token}\b which matches a word-break on either side
// this prevents the highlighter from highlighting pieces of variables that start with a reserved token name
l.language.tokenizer.root.unshift([new RegExp('\\bns\\b'), { token: "ns" }]);
for (const symbol of symbols) l.language.tokenizer.root.unshift([new RegExp(`\\b${symbol}\\b`), { token: "netscriptfunction" }]);
l.language.tokenizer.root.unshift([new RegExp("\\bns\\b"), { token: "ns" }]);
for (const symbol of symbols)
l.language.tokenizer.root.unshift([new RegExp(`\\b${symbol}\\b`), { token: "netscriptfunction" }]);
const otherKeywords = ["let", "const", "var", "function"];
const otherKeyvars = ["true", "false", "null", "undefined"];
otherKeywords.forEach((k) => l.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeywords" }]));
otherKeyvars.forEach((k) => l.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeyvars" }]));
l.language.tokenizer.root.unshift([new RegExp('\\bthis\\b'), { token: "this" }]);
otherKeywords.forEach((k) =>
l.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeywords" }]),
);
otherKeyvars.forEach((k) =>
l.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeyvars" }]),
);
l.language.tokenizer.root.unshift([new RegExp("\\bthis\\b"), { token: "this" }]);
})();
const source = (libSource + "").replace(/export /g, "");
@ -474,7 +478,7 @@ export function Root(props: IProps): React.ReactElement {
}
try {
infLoop(newCode);
} catch (err) { }
} catch (err) {}
}
function saveScript(scriptToSave: OpenScript): void {
@ -633,12 +637,12 @@ export function Root(props: IProps): React.ReactElement {
function currentTabIndex(): number | undefined {
if (currentScript !== null) {
return openScripts.findIndex(
(script) =>
currentScript !== null &&
script.fileName === currentScript.fileName &&
script.hostname === currentScript.hostname,
);
}
(script) =>
currentScript !== null &&
script.fileName === currentScript.fileName &&
script.hostname === currentScript.hostname,
);
}
return undefined;
}
@ -737,15 +741,17 @@ export function Root(props: IProps): React.ReactElement {
if (openScript.code !== serverScriptCode) {
PromptEvent.emit({
txt: "Do you want to overwrite the current editor content with the contents of " +
openScript.fileName + " on the server? This cannot be undone.",
txt:
"Do you want to overwrite the current editor content with the contents of " +
openScript.fileName +
" on the server? This cannot be undone.",
resolve: (result: boolean) => {
if (result) {
// Save changes
openScript.code = serverScriptCode;
// Switch to target tab
onTabClick(index)
onTabClick(index);
if (editorRef.current !== null && openScript !== null) {
if (openScript.model === undefined || openScript.model.isDisposed()) {
@ -789,11 +795,11 @@ export function Root(props: IProps): React.ReactElement {
// 44px bottom tool bar + 16px margin
// + vim bar 34px
const editorHeight = dimensions.height - (130 + (options.vim ? 34 : 0));
const tabsMaxWidth = 1640
const tabMargin = 5
const tabMaxWidth = openScripts.length ? (tabsMaxWidth / openScripts.length) - tabMargin : 0
const tabIconWidth = 25
const tabTextWidth = tabMaxWidth - (tabIconWidth * 2)
const tabsMaxWidth = 1640;
const tabMargin = 5;
const tabMaxWidth = openScripts.length ? tabsMaxWidth / openScripts.length - tabMargin : 0;
const tabIconWidth = 25;
const tabTextWidth = tabMaxWidth - tabIconWidth * 2;
return (
<>
<div style={{ display: currentScript !== null ? "block" : "none", height: "100%", width: "100%" }}>
@ -819,20 +825,22 @@ export function Root(props: IProps): React.ReactElement {
const iconButtonStyle = {
maxWidth: `${tabIconWidth}px`,
minWidth: `${tabIconWidth}px`,
minHeight: '38.5px',
maxHeight: '38.5px',
...(currentScript?.fileName === openScripts[index].fileName ? {
background: Settings.theme.button,
borderColor: Settings.theme.button,
color: Settings.theme.primary
} : {
background: Settings.theme.backgroundsecondary,
borderColor: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary
})
minHeight: "38.5px",
maxHeight: "38.5px",
...(currentScript?.fileName === openScripts[index].fileName
? {
background: Settings.theme.button,
borderColor: Settings.theme.button,
color: Settings.theme.primary,
}
: {
background: Settings.theme.backgroundsecondary,
borderColor: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary,
}),
};
const scriptTabText = `${hostname}:~/${fileName} ${dirty(index)}`
const scriptTabText = `${hostname}:~/${fileName} ${dirty(index)}`;
return (
<Draggable
key={fileName + hostname}
@ -850,47 +858,49 @@ export function Root(props: IProps): React.ReactElement {
maxWidth: `${tabMaxWidth}px`,
marginRight: `${tabMargin}px`,
flexShrink: 0,
border: '1px solid ' + Settings.theme.well,
border: "1px solid " + Settings.theme.well,
}}
>
<Tooltip title={scriptTabText}>
<Button
onClick={() => onTabClick(index)}
onMouseDown={e => {
onMouseDown={(e) => {
e.preventDefault();
if (e.button === 1) onTabClose(index);
}}
style={{
maxWidth: `${tabTextWidth}px`,
overflow: "hidden",
...(currentScript?.fileName === openScripts[index].fileName ? {
background: Settings.theme.button,
borderColor: Settings.theme.button,
color: Settings.theme.primary
} : {
background: Settings.theme.backgroundsecondary,
borderColor: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary
})
...(currentScript?.fileName === openScripts[index].fileName
? {
background: Settings.theme.button,
borderColor: Settings.theme.button,
color: Settings.theme.primary,
}
: {
background: Settings.theme.backgroundsecondary,
borderColor: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary,
}),
}}
>
<span style={{ overflow: 'hidden', direction: 'rtl', textOverflow: "ellipsis" }}>
<span style={{ overflow: "hidden", direction: "rtl", textOverflow: "ellipsis" }}>
{scriptTabText}
</span>
</Button>
</Tooltip>
<Tooltip title="Overwrite editor content with saved file content">
<Button onClick={() => onTabUpdate(index)} style={iconButtonStyle} >
<SyncIcon fontSize='small' />
<Button onClick={() => onTabUpdate(index)} style={iconButtonStyle}>
<SyncIcon fontSize="small" />
</Button>
</Tooltip>
<Button onClick={() => onTabClose(index)} style={iconButtonStyle}>
<CloseIcon fontSize='small' />
<CloseIcon fontSize="small" />
</Button>
</div>
)}
</Draggable>
)
);
})}
{provided.placeholder}
</Box>
@ -920,13 +930,23 @@ export function Root(props: IProps): React.ReactElement {
></Box>
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
<Button startIcon={<SettingsIcon />} onClick={() => setOptionsOpen(true)} sx={{ mr: 1 }}>Options</Button>
<Button startIcon={<SettingsIcon />} onClick={() => setOptionsOpen(true)} sx={{ mr: 1 }}>
Options
</Button>
<Button onClick={beautify}>Beautify</Button>
<Button color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }} onClick={() => { setRamInfoOpen(true) }}>
<Button
color={updatingRam ? "secondary" : "primary"}
sx={{ mx: 1 }}
onClick={() => {
setRamInfoOpen(true);
}}
>
{ram}
</Button>
<Button onClick={save}>Save (Ctrl/Cmd + s)</Button>
<Button sx={{ mx: 1 }} onClick={props.router.toTerminal}>Terminal (Ctrl/Cmd + b)</Button>
<Button sx={{ mx: 1 }} onClick={props.router.toTerminal}>
Terminal (Ctrl/Cmd + b)
</Button>
<Typography>
{" "}
Documentation:{" "}
@ -965,7 +985,9 @@ export function Root(props: IProps): React.ReactElement {
<React.Fragment key={n + r}>
<TableRow>
<TableCell sx={{ color: Settings.theme.primary }}>{n}</TableCell>
<TableCell align="right" sx={{ color: Settings.theme.primary }}>{r}</TableCell>
<TableCell align="right" sx={{ color: Settings.theme.primary }}>
{r}
</TableCell>
</TableRow>
</React.Fragment>
))}