From 0fc95e62150267bcf539c37b8249d3445cfe5500 Mon Sep 17 00:00:00 2001
From: Olivier Gagnon
Date: Wed, 29 Dec 2021 02:04:24 -0500
Subject: [PATCH] text editor improvements
---
src/BitNode/BitNode.tsx | 2 +-
src/NetscriptFunctions.ts | 8 +-
src/Script/RamCalculations.ts | 1 -
src/ScriptEditor/ui/ScriptEditorRoot.tsx | 170 +++++++++++------------
4 files changed, 85 insertions(+), 96 deletions(-)
diff --git a/src/BitNode/BitNode.tsx b/src/BitNode/BitNode.tsx
index 48e2aa97f..c59a339de 100644
--- a/src/BitNode/BitNode.tsx
+++ b/src/BitNode/BitNode.tsx
@@ -745,7 +745,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
BitNodeMultipliers.StaneksGiftPowerMultiplier = 0.5;
BitNodeMultipliers.StaneksGiftExtraSize = 2;
BitNodeMultipliers.GangSoftcap = 0.8;
- BitNodeMultipliers.CorporationSoftCap = 0.9;
+ BitNodeMultipliers.CorporationSoftCap = 0.7;
BitNodeMultipliers.WorldDaemonDifficulty = 2;
break;
case 10: // Digital Carbon
diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts
index 83a4335ac..b70db75a0 100644
--- a/src/NetscriptFunctions.ts
+++ b/src/NetscriptFunctions.ts
@@ -64,7 +64,7 @@ import { NetscriptSleeve } from "./NetscriptFunctions/Sleeve";
import { NetscriptExtra } from "./NetscriptFunctions/Extra";
import { NetscriptHacknet } from "./NetscriptFunctions/Hacknet";
import { NetscriptStanek } from "./NetscriptFunctions/Stanek";
-import { NetscriptUserInterface } from './NetscriptFunctions/UserInterface';
+import { NetscriptUserInterface } from "./NetscriptFunctions/UserInterface";
import { NetscriptBladeburner } from "./NetscriptFunctions/Bladeburner";
import { NetscriptCodingContract } from "./NetscriptFunctions/CodingContract";
import { NetscriptCorporation } from "./NetscriptFunctions/Corporation";
@@ -2318,10 +2318,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
...base,
...extra,
};
- function getFunctionNames(obj: NS, prefix: string): string[] {
+ function getFunctionNames(obj: any, prefix: string): string[] {
const functionNames: string[] = [];
for (const [key, value] of Object.entries(obj)) {
- if (typeof value == "function") {
+ if (key === "args") {
+ continue;
+ } else if (typeof value == "function") {
functionNames.push(prefix + key);
} else if (typeof value == "object") {
functionNames.push(...getFunctionNames(value, key + "."));
diff --git a/src/Script/RamCalculations.ts b/src/Script/RamCalculations.ts
index bf0bfe855..05920baf9 100644
--- a/src/Script/RamCalculations.ts
+++ b/src/Script/RamCalculations.ts
@@ -109,7 +109,6 @@ async function parseOnlyRamCalculate(
for (const s of otherScripts) {
if (areImportsEquals(s.filename, fn)) {
script = s;
- console.log(`${s.filename} ${fn}`);
break;
}
}
diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx
index 1d4653dd4..b2cc86304 100644
--- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx
+++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx
@@ -93,26 +93,21 @@ class OpenScript {
}
}
+let openScripts: OpenScript[] = [];
+let currentScript: OpenScript | null = null;
+
// Called every time script editor is opened
export function Root(props: IProps): React.ReactElement {
+ const setRerender = useState(false)[1];
+ function rerender(): void {
+ setRerender((o) => !o);
+ }
const editorRef = useRef(null);
const monacoRef = useRef(null);
const vimStatusRef = useRef(null);
const [vimEditor, setVimEditor] = useState(null);
const [editor, setEditor] = useState(null);
- const [openScripts, setOpenScripts] = useState(
- window.localStorage.getItem("scriptEditorOpenScripts") !== null
- ? JSON.parse(window.localStorage.getItem("scriptEditorOpenScripts")!)
- : [],
- );
-
- const [currentScript, setCurrentScript] = useState(
- window.localStorage.getItem("scriptEditorCurrentScript") !== null
- ? JSON.parse(window.localStorage.getItem("scriptEditorCurrentScript")!)
- : null,
- );
-
const [ram, setRAM] = useState("RAM: ???");
const [updatingRam, setUpdatingRam] = useState(false);
const [decorations, setDecorations] = useState([]);
@@ -144,26 +139,6 @@ export function Root(props: IProps): React.ReactElement {
};
}, []);
- useEffect(() => {
- // Save currentScript
- window.localStorage.setItem(
- "scriptEditorCurrentScript",
- JSON.stringify(currentScript, (key, value) => {
- if (key == "model") return undefined;
- return value;
- }),
- );
-
- // Save openScripts
- window.localStorage.setItem(
- "scriptEditorOpenScripts",
- JSON.stringify(openScripts, (key, value) => {
- if (key == "model") return undefined;
- return value;
- }),
- );
- }, [currentScript, openScripts]);
-
useEffect(() => {
if (currentScript !== null) {
updateRAM(currentScript.code);
@@ -171,23 +146,23 @@ export function Root(props: IProps): React.ReactElement {
}, []);
useEffect(() => {
- function maybeSave(event: KeyboardEvent): void {
+ function keydown(event: KeyboardEvent): void {
if (Settings.DisableHotkeys) return;
//Ctrl + b
- if (event.keyCode == 66 && (event.ctrlKey || event.metaKey)) {
+ if (event.code == "KeyB" && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
- save();
+ props.router.toTerminal();
}
// CTRL/CMD + S
- if (event.code == `KeyS` && (event.ctrlKey || event.metaKey)) {
+ if (event.code == "KeyS" && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
event.stopPropagation();
save();
}
}
- document.addEventListener("keydown", maybeSave);
- return () => document.removeEventListener("keydown", maybeSave);
+ document.addEventListener("keydown", keydown);
+ return () => document.removeEventListener("keydown", keydown);
});
useEffect(() => {
@@ -362,7 +337,7 @@ export function Root(props: IProps): React.ReactElement {
regenerateModel(openScript);
}
- setCurrentScript(openScript);
+ currentScript = openScript;
editorRef.current.setModel(openScript.model);
editorRef.current.setPosition(openScript.lastPosition);
editorRef.current.revealLineInCenter(openScript.lastPosition.lineNumber);
@@ -376,14 +351,12 @@ export function Root(props: IProps): React.ReactElement {
new monacoRef.current.Position(0, 0),
monacoRef.current.editor.createModel(code, filename.endsWith(".txt") ? "plaintext" : "javascript"),
);
- setOpenScripts((oldArray) => [...oldArray, newScript]);
- setCurrentScript({ ...newScript });
+ openScripts.push(newScript);
+ currentScript = { ...newScript };
editorRef.current.setModel(newScript.model);
updateRAM(newScript.code);
}
}
- } else {
- console.log("here we need to load something if we can");
}
editorRef.current.focus();
@@ -422,24 +395,26 @@ export function Root(props: IProps): React.ReactElement {
function updateCode(newCode?: string): void {
if (newCode === undefined) return;
updateRAM(newCode);
- if (editorRef.current !== null) {
- const newPos = editorRef.current.getPosition();
- if (newPos === null) return;
- setCurrentScript((oldScript) => ({ ...oldScript!, code: newCode, lastPosition: newPos! }));
- if (currentScript !== null) {
- const curIndex = openScripts.findIndex(
- (script) => script.fileName === currentScript.fileName && script.hostname === currentScript.hostname,
- );
- const newArr = [...openScripts];
- const tempScript = currentScript;
- tempScript.code = newCode;
- newArr[curIndex] = tempScript;
- setOpenScripts([...newArr]);
- }
- try {
- infLoop(newCode);
- } catch (err) {}
+ if (editorRef.current === null) return;
+ const newPos = editorRef.current.getPosition();
+ if (newPos === null) return;
+ if (currentScript !== null) {
+ currentScript = { ...currentScript, code: newCode, lastPosition: newPos };
+ const curIndex = openScripts.findIndex(
+ (script) =>
+ currentScript !== null &&
+ script.fileName === currentScript.fileName &&
+ script.hostname === currentScript.hostname,
+ );
+ const newArr = [...openScripts];
+ const tempScript = currentScript;
+ tempScript.code = newCode;
+ newArr[curIndex] = tempScript;
+ openScripts = [...newArr];
}
+ try {
+ infLoop(newCode);
+ } catch (err) {}
}
function saveScript(scriptToSave: OpenScript): void {
@@ -487,7 +462,7 @@ export function Root(props: IProps): React.ReactElement {
function save(): void {
if (currentScript === null) {
- console.log("currentScript is null when it shouldn't be. Unabel to save script");
+ console.error("currentScript is null when it shouldn't be. Unable to save script");
return;
}
// this is duplicate code with saving later.
@@ -507,7 +482,6 @@ export function Root(props: IProps): React.ReactElement {
iTutorialNextStep();
- props.router.toTerminal();
return;
}
@@ -536,7 +510,6 @@ export function Root(props: IProps): React.ReactElement {
server.scripts,
);
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
- props.router.toTerminal();
return;
}
}
@@ -550,7 +523,6 @@ export function Root(props: IProps): React.ReactElement {
if (server.textFiles[i].fn === currentScript.fileName) {
server.textFiles[i].write(currentScript.code);
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
- props.router.toTerminal();
return;
}
}
@@ -562,7 +534,6 @@ export function Root(props: IProps): React.ReactElement {
}
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
- props.router.toTerminal();
}
function reorder(list: Array, startIndex: number, endIndex: number): OpenScript[] {
@@ -582,19 +553,22 @@ export function Root(props: IProps): React.ReactElement {
const items = reorder(openScripts, result.source.index, result.destination.index);
- setOpenScripts(items);
+ openScripts = items;
}
function onTabClick(index: number): void {
if (currentScript !== null) {
// Save currentScript to openScripts
const curIndex = openScripts.findIndex(
- (script) => script.fileName === currentScript.fileName && script.hostname === currentScript.hostname,
+ (script) =>
+ currentScript !== null &&
+ script.fileName === currentScript.fileName &&
+ script.hostname === currentScript.hostname,
);
openScripts[curIndex] = currentScript;
}
- setCurrentScript({ ...openScripts[index] });
+ currentScript = { ...openScripts[index] };
if (editorRef.current !== null && openScripts[index] !== null) {
if (openScripts[index].model === undefined || openScripts[index].model.isDisposed()) {
@@ -609,25 +583,21 @@ export function Root(props: IProps): React.ReactElement {
}
}
- async function onTabClose(index: number): Promise {
+ function onTabClose(index: number): void {
// See if the script on the server is up to date
const closingScript = openScripts[index];
- const savedOpenScripts: Array = JSON.parse(window.localStorage.getItem("scriptEditorOpenScripts")!);
- const savedScriptIndex = savedOpenScripts.findIndex(
+ const savedScriptIndex = openScripts.findIndex(
(script) => script.fileName === closingScript.fileName && script.hostname === closingScript.hostname,
);
let savedScriptCode = "";
if (savedScriptIndex !== -1) {
- savedScriptCode = savedOpenScripts[savedScriptIndex].code;
+ savedScriptCode = openScripts[savedScriptIndex].code;
}
+ const server = GetServer(closingScript.hostname);
+ if (server === null) throw new Error(`Server '${closingScript.hostname}' should not be null, but it is.`);
- const serverScriptIndex = GetServer(closingScript.hostname)?.scripts.findIndex(
- (script) => script.filename === closingScript.fileName,
- );
- if (
- serverScriptIndex === -1 ||
- savedScriptCode !== GetServer(closingScript.hostname)?.scripts[serverScriptIndex as number].code
- ) {
+ const serverScriptIndex = server.scripts.findIndex((script) => script.filename === closingScript.fileName);
+ if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex as number].code) {
PromptEvent.emit({
txt: "Do you want to save changes to " + closingScript.fileName + "?",
resolve: (result: boolean) => {
@@ -641,15 +611,18 @@ export function Root(props: IProps): React.ReactElement {
}
if (openScripts.length > 1) {
- setOpenScripts((oldScripts) => oldScripts.filter((value, i) => i !== index));
+ openScripts = openScripts.filter((value, i) => i !== index);
let indexOffset = -1;
if (openScripts[index + indexOffset] === undefined) {
indexOffset = 1;
+ if (openScripts[index + indexOffset] === undefined) {
+ indexOffset = 0;
+ }
}
// Change current script if we closed it
- setCurrentScript(openScripts[index + indexOffset]);
+ currentScript = openScripts[index + indexOffset];
if (editorRef.current !== null) {
if (
openScripts[index + indexOffset].model === undefined ||
@@ -664,14 +637,26 @@ export function Root(props: IProps): React.ReactElement {
editorRef.current.revealLineInCenter(openScripts[index + indexOffset].lastPosition.lineNumber);
editorRef.current.focus();
}
+ rerender();
} else {
// No more scripts are open
- setOpenScripts([]);
- setCurrentScript(null);
+ openScripts = [];
+ currentScript = null;
props.router.toTerminal();
}
}
+ function dirty(index: number): string {
+ const openScript = openScripts[index];
+ const server = GetServer(openScript.hostname);
+ if (server === null) throw new Error(`Server '${openScript.hostname}' should not be null, but it is.`);
+
+ const serverScript = server.scripts.find((s) => s.filename === openScript.fileName);
+ if (serverScript === undefined) return " *";
+
+ return serverScript.code !== openScript.code ? " *" : "";
+ }
+
// Toolbars are roughly 112px:
// 8px body margin top
// 38.5px filename tabs
@@ -718,7 +703,6 @@ export function Root(props: IProps): React.ReactElement {
}}
>
+
+ No open files
+
+ Use `nano FILENAME` in
+
+ the terminal to open files
+
+
>
);