mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
EDITOR: Add the ability to Beautify on Save (optionally) (#2287)
This commit is contained in:
@@ -16,4 +16,5 @@ export interface Options {
|
||||
wordWrap: WordWrapOptions;
|
||||
cursorStyle: CursorStyle;
|
||||
cursorBlinking: CursorBlinking;
|
||||
beautifyOnSave: boolean;
|
||||
}
|
||||
|
||||
@@ -142,6 +142,14 @@ export function OptionsModal(props: OptionsModalProps): ReactElement {
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<Typography marginRight={"auto"}>Run Beautify on Save: </Typography>
|
||||
<Switch
|
||||
onChange={(e) => props.onOptionChange("beautifyOnSave", e.target.checked)}
|
||||
checked={props.options.beautifyOnSave}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ export function ScriptEditorContextProvider({ children }: { children: React.Reac
|
||||
wordWrap: Settings.MonacoWordWrap,
|
||||
cursorStyle: Settings.MonacoCursorStyle,
|
||||
cursorBlinking: Settings.MonacoCursorBlinking,
|
||||
beautifyOnSave: Settings.MonacoBeautifyOnSave,
|
||||
});
|
||||
|
||||
function saveOptions(options: Options) {
|
||||
@@ -105,6 +106,7 @@ export function ScriptEditorContextProvider({ children }: { children: React.Reac
|
||||
Settings.MonacoCursorStyle = options.cursorStyle;
|
||||
Settings.MonacoCursorBlinking = options.cursorBlinking;
|
||||
Settings.MonacoWordWrap = options.wordWrap;
|
||||
Settings.MonacoBeautifyOnSave = options.beautifyOnSave;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -176,15 +176,26 @@ function Root(props: IProps): React.ReactElement {
|
||||
reloadModelOfCurrentScript();
|
||||
}
|
||||
|
||||
const { showRAMError, updateRAM, startUpdatingRAM, finishUpdatingRAM } = useScriptEditorContext();
|
||||
const { options, showRAMError, updateRAM, startUpdatingRAM, finishUpdatingRAM } = useScriptEditorContext();
|
||||
|
||||
let decorations: monaco.editor.IEditorDecorationsCollection | undefined;
|
||||
|
||||
const save = useCallback(() => {
|
||||
const beautify = useCallback(async (): Promise<void> => {
|
||||
const action = editorRef.current?.getAction("editor.action.formatDocument");
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
return action.run().catch((error) => console.error(error));
|
||||
}, []);
|
||||
|
||||
const save = useCallback(async () => {
|
||||
if (currentScript === null) {
|
||||
console.error("currentScript is null when it shouldn't be. Unable to save script");
|
||||
return;
|
||||
}
|
||||
|
||||
const preSave = options.beautifyOnSave ? beautify : () => Promise.resolve();
|
||||
|
||||
// this is duplicate code with saving later.
|
||||
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalEditScript) {
|
||||
//Make sure filename + code properly follow tutorial
|
||||
@@ -200,6 +211,7 @@ function Root(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
//Save the script
|
||||
await preSave();
|
||||
saveScript(currentScript);
|
||||
Router.toPage(Page.Terminal);
|
||||
|
||||
@@ -207,11 +219,12 @@ function Root(props: IProps): React.ReactElement {
|
||||
|
||||
return;
|
||||
}
|
||||
await preSave();
|
||||
saveScript(currentScript);
|
||||
rerender();
|
||||
}, [rerender]);
|
||||
}, [rerender, options.beautifyOnSave, beautify]);
|
||||
|
||||
const run = useCallback(() => {
|
||||
const run = useCallback(async () => {
|
||||
if (currentScript === null) {
|
||||
return;
|
||||
}
|
||||
@@ -227,7 +240,7 @@ function Root(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
// Always save before doing anything else.
|
||||
save();
|
||||
await save();
|
||||
|
||||
const result = createRunningScriptInstance(server, currentScript.path, null, 1, []);
|
||||
if (!result.success) {
|
||||
@@ -238,7 +251,7 @@ function Root(props: IProps): React.ReactElement {
|
||||
}, [save]);
|
||||
|
||||
useEffect(() => {
|
||||
function keydown(event: KeyboardEvent): void {
|
||||
async function keydown(event: KeyboardEvent) {
|
||||
if (Settings.DisableHotkeys) {
|
||||
return;
|
||||
}
|
||||
@@ -246,7 +259,7 @@ function Root(props: IProps): React.ReactElement {
|
||||
if (keyBindingTypes.has(ScriptEditorAction.Save)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
save();
|
||||
await save();
|
||||
}
|
||||
if (keyBindingTypes.has(ScriptEditorAction.GoToTerminal)) {
|
||||
event.preventDefault();
|
||||
@@ -254,11 +267,14 @@ function Root(props: IProps): React.ReactElement {
|
||||
}
|
||||
if (keyBindingTypes.has(ScriptEditorAction.Run)) {
|
||||
event.preventDefault();
|
||||
run();
|
||||
await run();
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", keydown);
|
||||
return () => document.removeEventListener("keydown", keydown);
|
||||
const listener = (event: KeyboardEvent) => {
|
||||
keydown(event).catch((error) => console.error(error));
|
||||
};
|
||||
document.addEventListener("keydown", listener);
|
||||
return () => document.removeEventListener("keydown", listener);
|
||||
}, [save, run]);
|
||||
|
||||
function infLoop(ast: AST, code: string): void {
|
||||
@@ -598,7 +614,7 @@ function Root(props: IProps): React.ReactElement {
|
||||
|
||||
{statusBarRef.current}
|
||||
|
||||
<Toolbar onSave={save} onRun={run} editor={editorRef.current} />
|
||||
<Toolbar onSave={save} onRun={run} editor={editorRef.current} onBeautify={beautify} />
|
||||
</div>
|
||||
{!currentScript && <NoOpenScripts />}
|
||||
</>
|
||||
|
||||
@@ -31,21 +31,15 @@ type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
||||
|
||||
interface IProps {
|
||||
editor: IStandaloneCodeEditor | null;
|
||||
onSave: () => void;
|
||||
onRun: () => void;
|
||||
onSave: () => Promise<void>;
|
||||
onRun: () => Promise<void>;
|
||||
onBeautify: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function Toolbar({ editor, onSave, onRun }: IProps) {
|
||||
export function Toolbar({ editor, onSave, onRun, onBeautify }: IProps) {
|
||||
const [ramInfoOpen, { on: openRAMInfo, off: closeRAMInfo }] = useBoolean(false);
|
||||
const [optionsOpen, { on: openOptions, off: closeOptions }] = useBoolean(false);
|
||||
|
||||
function beautify(): void {
|
||||
editor
|
||||
?.getAction("editor.action.formatDocument")
|
||||
?.run()
|
||||
.catch((error) => console.error(error));
|
||||
}
|
||||
|
||||
const { ram, ramEntries, isUpdatingRAM, options, saveOptions } = useScriptEditorContext();
|
||||
|
||||
const onOptionChange: OptionsModalProps["onOptionChange"] = (option, value) => {
|
||||
@@ -68,12 +62,24 @@ export function Toolbar({ editor, onSave, onRun }: IProps) {
|
||||
<Button startIcon={<SettingsIcon />} onClick={openOptions} sx={{ mr: 1 }}>
|
||||
Options
|
||||
</Button>
|
||||
<Button onClick={beautify}>Beautify</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
onBeautify().catch((error) => console.error(error));
|
||||
}}
|
||||
>
|
||||
Beautify
|
||||
</Button>
|
||||
<Button color={isUpdatingRAM ? "secondary" : "primary"} sx={{ mx: 1 }} onClick={openRAMInfo}>
|
||||
{ram}
|
||||
</Button>
|
||||
<Tooltip title={parseKeyCombinationsToString(CurrentKeyBindings[ScriptEditorAction.Save])}>
|
||||
<Button onClick={onSave}>Save</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
onSave().catch((error) => console.error(error));
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={parseKeyCombinationsToString(CurrentKeyBindings[ScriptEditorAction.GoToTerminal])}>
|
||||
<Button sx={{ mx: 1 }} onClick={() => Router.toPage(Page.Terminal)}>
|
||||
@@ -81,7 +87,12 @@ export function Toolbar({ editor, onSave, onRun }: IProps) {
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={parseKeyCombinationsToString(CurrentKeyBindings[ScriptEditorAction.Run])}>
|
||||
<Button sx={{ mr: 1 }} onClick={onRun}>
|
||||
<Button
|
||||
sx={{ mr: 1 }}
|
||||
onClick={() => {
|
||||
onRun().catch((error) => console.error(error));
|
||||
}}
|
||||
>
|
||||
Run
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
@@ -13,7 +13,7 @@ interface IProps {
|
||||
editor: IStandaloneCodeEditor | null;
|
||||
onOpenNextTab: (step: number) => void;
|
||||
onOpenPreviousTab: (step: number) => void;
|
||||
onSave: () => void;
|
||||
onSave: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function useVimEditor({ editor, vim, onOpenNextTab, onOpenPreviousTab, onSave }: IProps) {
|
||||
@@ -32,7 +32,7 @@ export function useVimEditor({ editor, vim, onOpenNextTab, onOpenPreviousTab, on
|
||||
setVimEditor(MonacoVim.initVimMode(editor, statusBarRef, StatusBar, rerender));
|
||||
MonacoVim.VimMode.Vim.defineEx("write", "w", function () {
|
||||
// your own implementation on what you want to do when :w is pressed
|
||||
actionsRef.current.save();
|
||||
actionsRef.current.save().catch((error) => console.error(error));
|
||||
});
|
||||
MonacoVim.VimMode.Vim.defineEx("quit", "q", function () {
|
||||
Router.toPage(Page.Terminal);
|
||||
@@ -43,8 +43,12 @@ export function useVimEditor({ editor, vim, onOpenNextTab, onOpenPreviousTab, on
|
||||
MonacoVim.VimMode.Vim.mapCommand("@", "", "", null, { context: "normal" });
|
||||
|
||||
const saveNQuit = (): void => {
|
||||
actionsRef.current.save();
|
||||
Router.toPage(Page.Terminal);
|
||||
actionsRef.current
|
||||
.save()
|
||||
.then(() => {
|
||||
Router.toPage(Page.Terminal);
|
||||
})
|
||||
.catch((error) => console.error(error));
|
||||
};
|
||||
// "wqriteandquit" & "xriteandquit" are not typos, prefix must be found in full string
|
||||
MonacoVim.VimMode.Vim.defineEx("wqriteandquit", "wq", saveNQuit);
|
||||
|
||||
@@ -176,6 +176,8 @@ export const Settings = {
|
||||
MonacoDefaultToVim: false,
|
||||
/** Word wrap setting for Script Editor. */
|
||||
MonacoWordWrap: "off" as WordWrapOptions,
|
||||
/** Whether to run Beautify code formatter on save */
|
||||
MonacoBeautifyOnSave: false,
|
||||
/** Control the cursor style*/
|
||||
MonacoCursorStyle: "line" as CursorStyle,
|
||||
/** Control the cursor animation style */
|
||||
|
||||
Reference in New Issue
Block a user