feat: Add vim terminal command

This commit is contained in:
Billy Vong
2021-12-17 12:48:34 -05:00
parent 009bae5870
commit d30edc7f59
9 changed files with 107 additions and 48 deletions

View File

@ -44,7 +44,7 @@ interface IProps {
hostname: string;
player: IPlayer;
router: IRouter;
vim?: boolean;
vim: boolean;
}
// TODO: try to removve global symbols

View File

@ -40,6 +40,7 @@ export const TerminalHelpText: string[] = [
"tail [script] [args...] Displays dynamic logs for the specified script",
"top Displays all running scripts and their RAM usage",
"unalias [alias name] Deletes the specified alias",
"vim [file] Text editor - Open up and edit a script or text file in vim mode",
"weaken [server] Reduce the security of a server",
"wget [url] [target file] Retrieves code/text from a web server",
];
@ -402,6 +403,13 @@ export const HelpTexts: IMap<string[]> = {
" ",
"It is not necessary to differentiate between global and non-global aliases when using 'unalias'",
],
vim: [
"vim [file name]",
" ",
"Opens up the specified file in the Text Editor in vim mode. Only scripts (.script) or text files (.txt) can be ",
"edited using the Text Editor. If the file does not already exist, then a new, empty one ",
"will be created",
],
weaken: [
"weaken",
"",

View File

@ -67,6 +67,7 @@ import { sudov } from "./commands/sudov";
import { tail } from "./commands/tail";
import { top } from "./commands/top";
import { unalias } from "./commands/unalias";
import { vim } from "./commands/vim";
import { weaken } from "./commands/weaken";
import { wget } from "./commands/wget";
import { hash } from "../hash/hash";
@ -789,6 +790,7 @@ export class Terminal implements ITerminal {
tail: tail,
top: top,
unalias: unalias,
vim: vim,
weaken: weaken,
wget: wget,
};

View File

@ -0,0 +1,65 @@
import { ITerminal } from "../../ITerminal";
import { IRouter, ScriptEditorRouteOptions} from "../../../ui/Router";
import { IPlayer } from "../../../PersonObjects/IPlayer";
import { BaseServer } from "../../../Server/BaseServer";
import { isScriptFilename } from "../../../Script/isScriptFilename";
import { CursorPositions } from "../../../ScriptEditor/CursorPositions";
interface EditorParameters {
terminal: ITerminal;
router: IRouter;
player: IPlayer;
server: BaseServer;
args: (string | number | boolean)[];
}
export function commonEditor(command: string, {
terminal,
router,
player,
server,
args,
}: EditorParameters, scriptEditorRouteOptions?: ScriptEditorRouteOptions): void {
if (args.length !== 1) {
terminal.error(`Incorrect usage of ${command} command. Usage: ${command} [scriptname]`);
return;
}
try {
const filename = args[0] + "";
if (isScriptFilename(filename)) {
const filepath = terminal.getFilepath(filename);
const script = terminal.getScript(player, filename);
if (script == null) {
let code = "";
if (filename.endsWith(".ns") || filename.endsWith(".js")) {
code = `/** @param {NS} ns **/
export async function main(ns) {
}`;
}
CursorPositions.saveCursor(filename, {
row: 3,
column: 5,
});
router.toScriptEditor(filepath, code, scriptEditorRouteOptions);
} else {
router.toScriptEditor(filepath, script.code, scriptEditorRouteOptions);
}
} else if (filename.endsWith(".txt")) {
const filepath = terminal.getFilepath(filename);
const txt = terminal.getTextFile(player, filename);
if (txt == null) {
router.toScriptEditor(filepath, "", scriptEditorRouteOptions);
} else {
router.toScriptEditor(filepath, txt.text, scriptEditorRouteOptions);
}
} else {
terminal.error("Invalid file. Only scripts (.script, .ns, .js), or text files (.txt) can be edited with vim");
return;
}
} catch (e) {
terminal.error(e + "");
}
}

View File

@ -2,8 +2,8 @@ import { ITerminal } from "../ITerminal";
import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer";
import { isScriptFilename } from "../../Script/isScriptFilename";
import { CursorPositions } from "../../ScriptEditor/CursorPositions";
import {commonEditor} from './common/editor';
export function nano(
terminal: ITerminal,
@ -12,45 +12,5 @@ export function nano(
server: BaseServer,
args: (string | number | boolean)[],
): void {
if (args.length !== 1) {
terminal.error("Incorrect usage of nano command. Usage: nano [scriptname]");
return;
}
try {
const filename = args[0] + "";
if (isScriptFilename(filename)) {
const filepath = terminal.getFilepath(filename);
const script = terminal.getScript(player, filename);
if (script == null) {
let code = "";
if (filename.endsWith(".ns") || filename.endsWith(".js")) {
code = `/** @param {NS} ns **/
export async function main(ns) {
}`;
}
CursorPositions.saveCursor(filename, {
row: 3,
column: 5,
});
router.toScriptEditor(filepath, code);
} else {
router.toScriptEditor(filepath, script.code);
}
} else if (filename.endsWith(".txt")) {
const filepath = terminal.getFilepath(filename);
const txt = terminal.getTextFile(player, filename);
if (txt == null) {
router.toScriptEditor(filepath);
} else {
router.toScriptEditor(filepath, txt.text);
}
} else {
terminal.error("Invalid file. Only scripts (.script, .ns, .js), or text files (.txt) can be edited with nano");
return;
}
} catch (e) {
terminal.error(e + "");
}
return commonEditor('nano', {terminal, router, player, server, args});
}

View File

@ -0,0 +1,16 @@
import { ITerminal } from "../ITerminal";
import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer";
import {commonEditor} from './common/editor';
export function vim(
terminal: ITerminal,
router: IRouter,
player: IPlayer,
server: BaseServer,
args: (string | number | boolean)[],
): void {
return commonEditor('vim', {terminal, router, player, server, args}, {vim: true});
}

View File

@ -49,6 +49,7 @@ const commands = [
"tail",
"theme",
"top",
"vim",
"weaken",
];
@ -265,7 +266,7 @@ export async function determineAllPossibilitiesForTabCompletion(
return allPos;
}
if (isCommand("nano")) {
if (isCommand("nano") || isCommand("vim")) {
addAllScripts();
addAllTextFiles();
addAllDirectories();

View File

@ -33,7 +33,7 @@ import createStyles from "@mui/styles/createStyles";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { Page, IRouter } from "./Router";
import { Page, IRouter, ScriptEditorRouteOptions } from "./Router";
import { Overview } from "./React/Overview";
import { SidebarRoot } from "../Sidebar/ui/SidebarRoot";
import { AugmentationsRoot } from "../Augmentation/ui/AugmentationsRoot";
@ -97,6 +97,7 @@ const useStyles = makeStyles((theme: Theme) =>
let filename = "";
let code = "";
let vim = false;
export let Router: IRouter = {
page: () => {
@ -246,9 +247,10 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
toHacknetNodes: () => setPage(Page.Hacknet),
toMilestones: () => setPage(Page.Milestones),
toResleeves: () => setPage(Page.Resleeves),
toScriptEditor: (fn: string, c: string) => {
toScriptEditor: (fn: string, c: string, options?: ScriptEditorRouteOptions) => {
filename = fn;
code = c;
vim = !!options?.vim;
setPage(Page.ScriptEditor);
},
toSleeves: () => setPage(Page.Sleeves),
@ -335,6 +337,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
hostname={player.getCurrentServer().hostname}
player={player}
router={Router}
vim={vim}
/>
) : page === Page.ActiveScripts ? (
<ActiveScriptsRoot workerScripts={workerScripts} />

View File

@ -38,6 +38,10 @@ export enum Page {
Recovery,
}
export interface ScriptEditorRouteOptions {
vim: boolean;
}
/**
* This class keeps track of player navigation/routing within the game.
*/
@ -66,7 +70,7 @@ export interface IRouter {
toJob(): void;
toMilestones(): void;
toResleeves(): void;
toScriptEditor(filename?: string, code?: string): void;
toScriptEditor(filename?: string, code?: string, options?: ScriptEditorRouteOptions): void;
toSleeves(): void;
toStockMarket(): void;
toTerminal(): void;