mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 23:53:48 +01:00
text editor improvements
This commit is contained in:
parent
ed86577d6c
commit
0fc95e6215
@ -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
|
||||
|
@ -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 + "."));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<IStandaloneCodeEditor | null>(null);
|
||||
const monacoRef = useRef<Monaco | null>(null);
|
||||
const vimStatusRef = useRef<HTMLElement>(null);
|
||||
const [vimEditor, setVimEditor] = useState<any>(null);
|
||||
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
|
||||
|
||||
const [openScripts, setOpenScripts] = useState<OpenScript[]>(
|
||||
window.localStorage.getItem("scriptEditorOpenScripts") !== null
|
||||
? JSON.parse(window.localStorage.getItem("scriptEditorOpenScripts")!)
|
||||
: [],
|
||||
);
|
||||
|
||||
const [currentScript, setCurrentScript] = useState<OpenScript | null>(
|
||||
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<string[]>([]);
|
||||
@ -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,25 +395,27 @@ export function Root(props: IProps): React.ReactElement {
|
||||
function updateCode(newCode?: string): void {
|
||||
if (newCode === undefined) return;
|
||||
updateRAM(newCode);
|
||||
if (editorRef.current !== null) {
|
||||
if (editorRef.current === null) return;
|
||||
const newPos = editorRef.current.getPosition();
|
||||
if (newPos === null) return;
|
||||
setCurrentScript((oldScript) => ({ ...oldScript!, code: newCode, lastPosition: newPos! }));
|
||||
if (currentScript !== null) {
|
||||
currentScript = { ...currentScript, code: newCode, lastPosition: newPos };
|
||||
const curIndex = openScripts.findIndex(
|
||||
(script) => script.fileName === currentScript.fileName && script.hostname === currentScript.hostname,
|
||||
(script) =>
|
||||
currentScript !== null &&
|
||||
script.fileName === currentScript.fileName &&
|
||||
script.hostname === currentScript.hostname,
|
||||
);
|
||||
const newArr = [...openScripts];
|
||||
const tempScript = currentScript;
|
||||
tempScript.code = newCode;
|
||||
newArr[curIndex] = tempScript;
|
||||
setOpenScripts([...newArr]);
|
||||
openScripts = [...newArr];
|
||||
}
|
||||
try {
|
||||
infLoop(newCode);
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
|
||||
function saveScript(scriptToSave: OpenScript): void {
|
||||
const server = GetServer(scriptToSave.hostname);
|
||||
@ -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<OpenScript>, 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<void> {
|
||||
function onTabClose(index: number): void {
|
||||
// See if the script on the server is up to date
|
||||
const closingScript = openScripts[index];
|
||||
const savedOpenScripts: Array<OpenScript> = 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 {
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
id={"tabButton" + fileName + hostname}
|
||||
onClick={() => onTabClick(index)}
|
||||
style={{
|
||||
background:
|
||||
@ -727,10 +711,9 @@ export function Root(props: IProps): React.ReactElement {
|
||||
: "",
|
||||
}}
|
||||
>
|
||||
{hostname}:~/{fileName}
|
||||
{hostname}:~/{fileName} {dirty(index)}
|
||||
</Button>
|
||||
<Button
|
||||
id={"tabCloseButton" + fileName + hostname}
|
||||
onClick={() => onTabClose(index)}
|
||||
style={{
|
||||
maxWidth: "20px",
|
||||
@ -779,7 +762,8 @@ export function Root(props: IProps): React.ReactElement {
|
||||
<Typography color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }}>
|
||||
{ram}
|
||||
</Typography>
|
||||
<Button onClick={save}>Save & Close (Ctrl/Cmd + s)</Button>
|
||||
<Button onClick={save}>Save All (Ctrl/Cmd + s)</Button>
|
||||
<Button onClick={props.router.toTerminal}>Close (Ctrl/Cmd + b)</Button>
|
||||
<Typography sx={{ mx: 1 }}>
|
||||
{" "}
|
||||
Documentation:{" "}
|
||||
@ -825,10 +809,14 @@ export function Root(props: IProps): React.ReactElement {
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<p style={{ color: Settings.theme.primary, fontSize: "20px", textAlign: "center" }}>
|
||||
<h1>No open files</h1>
|
||||
<h5>Use "nano [File Name]" in the terminal to open files</h5>
|
||||
</p>
|
||||
<span style={{ color: Settings.theme.primary, fontSize: "20px", textAlign: "center" }}>
|
||||
<Typography variant="h4">No open files</Typography>
|
||||
<Typography variant="h5">
|
||||
Use `nano FILENAME` in
|
||||
<br />
|
||||
the terminal to open files
|
||||
</Typography>
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user