bitburner-src/src/Terminal.jsx

407 lines
12 KiB
React
Raw Normal View History

import { determineAllPossibilitiesForTabCompletion } from "./Terminal/determineAllPossibilitiesForTabCompletion";
import { tabCompletion } from "./Terminal/tabCompletion";
import { CONSTANTS } from "./Constants";
import { Engine } from "./engine";
import { FconfSettings } from "./Fconf/FconfSettings";
import { Player } from "./Player";
import { setTimeoutRef } from "./utils/SetTimeoutRef";
import { Page, routing } from "./ui/navigationTracking";
import { KEY } from "../utils/helpers/keyCodes";
import { getTimestamp } from "../utils/helpers/getTimestamp";
2021-09-16 01:50:44 +02:00
import { post } from "./ui/postToTerminal";
import { Terminal as TTerminal } from "./Terminal/Terminal";
2021-09-16 02:06:48 +02:00
const NewTerminal = new TTerminal();
import autosize from "autosize";
2018-03-12 20:39:04 +01:00
2021-09-10 22:08:58 +02:00
function postVersion() {
2021-09-05 01:09:30 +02:00
post("Bitburner v" + CONSTANTS.Version);
2016-10-20 23:11:01 +02:00
}
function getTerminalInput() {
2021-09-05 01:09:30 +02:00
return document.getElementById("terminal-input-text-box").value;
}
// Defines key commands in terminal
2021-09-05 01:09:30 +02:00
$(document).keydown(function (event) {
// Terminal
if (routing.isOn(Page.Terminal)) {
var terminalInput = document.getElementById("terminal-input-text-box");
2021-09-16 02:06:48 +02:00
if (terminalInput != null && !event.ctrlKey && !event.shiftKey && !NewTerminal.contractOpen) {
2021-09-05 01:09:30 +02:00
terminalInput.focus();
}
2021-09-05 01:09:30 +02:00
if (event.keyCode === KEY.ENTER) {
event.preventDefault(); // Prevent newline from being entered in Script Editor
const command = getTerminalInput();
2021-09-16 02:06:48 +02:00
const dir = NewTerminal.currDir;
2021-09-05 01:09:30 +02:00
post(
"<span class='prompt'>[" +
(FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") +
Player.getCurrentServer().hostname +
` ~${dir}]&gt;</span> ${command}`,
);
if (command.length > 0) {
Terminal.resetTerminalInput(); // Clear input first
2021-09-16 02:06:48 +02:00
NewTerminal.executeCommands(Engine, Player, command);
2021-09-05 01:09:30 +02:00
}
}
2021-09-05 01:09:30 +02:00
if (event.keyCode === KEY.C && event.ctrlKey) {
if (Engine._actionInProgress) {
// Cancel action
post("Cancelling...");
Engine._actionInProgress = false;
2021-09-16 02:06:48 +02:00
NewTerminal.finishAction(true);
2021-09-05 01:09:30 +02:00
} else if (FconfSettings.ENABLE_BASH_HOTKEYS) {
// Dont prevent default so it still copies
Terminal.resetTerminalInput(); // Clear Terminal
}
}
2021-09-05 01:09:30 +02:00
if (event.keyCode === KEY.L && event.ctrlKey) {
event.preventDefault();
2021-09-16 02:06:48 +02:00
NewTerminal.executeCommands(Engine, Player, "clear"); // Clear screen
2021-09-05 01:09:30 +02:00
}
2018-03-12 20:39:04 +01:00
2021-09-05 01:09:30 +02:00
// Ctrl p same as up arrow
// Ctrl n same as down arrow
if (
event.keyCode === KEY.UPARROW ||
2021-09-09 05:47:34 +02:00
(FconfSettings.ENABLE_BASH_HOTKEYS && event.keyCode === KEY.P && event.ctrlKey)
2021-09-05 01:09:30 +02:00
) {
if (FconfSettings.ENABLE_BASH_HOTKEYS) {
event.preventDefault();
}
// Cycle through past commands
if (terminalInput == null) {
return;
}
2021-09-16 02:06:48 +02:00
var i = NewTerminal.commandHistoryIndex;
var len = NewTerminal.commandHistory.length;
2021-09-05 01:09:30 +02:00
if (len == 0) {
return;
}
if (i < 0 || i > len) {
2021-09-16 02:06:48 +02:00
NewTerminal.commandHistoryIndex = len;
2021-09-05 01:09:30 +02:00
}
if (i != 0) {
2021-09-16 02:06:48 +02:00
--NewTerminal.commandHistoryIndex;
2021-09-05 01:09:30 +02:00
}
2021-09-16 02:06:48 +02:00
var prevCommand = NewTerminal.commandHistory[NewTerminal.commandHistoryIndex];
2021-09-05 01:09:30 +02:00
terminalInput.value = prevCommand;
setTimeoutRef(function () {
terminalInput.selectionStart = terminalInput.selectionEnd = 10000;
}, 10);
}
2018-03-12 20:39:04 +01:00
2021-09-05 01:09:30 +02:00
if (
event.keyCode === KEY.DOWNARROW ||
2021-09-09 05:47:34 +02:00
(FconfSettings.ENABLE_BASH_HOTKEYS && event.keyCode === KEY.M && event.ctrlKey)
2021-09-05 01:09:30 +02:00
) {
if (FconfSettings.ENABLE_BASH_HOTKEYS) {
event.preventDefault();
}
// Cycle through past commands
if (terminalInput == null) {
return;
}
2021-09-16 02:06:48 +02:00
var i = NewTerminal.commandHistoryIndex;
var len = NewTerminal.commandHistory.length;
2021-09-05 01:09:30 +02:00
if (len == 0) {
return;
}
if (i < 0 || i > len) {
2021-09-16 02:06:48 +02:00
NewTerminal.commandHistoryIndex = len;
2021-09-05 01:09:30 +02:00
}
// Latest command, put nothing
if (i == len || i == len - 1) {
2021-09-16 02:06:48 +02:00
NewTerminal.commandHistoryIndex = len;
2021-09-05 01:09:30 +02:00
terminalInput.value = "";
} else {
2021-09-16 02:06:48 +02:00
++NewTerminal.commandHistoryIndex;
var prevCommand = NewTerminal.commandHistory[NewTerminal.commandHistoryIndex];
2021-09-05 01:09:30 +02:00
terminalInput.value = prevCommand;
}
}
2021-09-05 01:09:30 +02:00
if (event.keyCode === KEY.TAB) {
event.preventDefault();
// Autocomplete
if (terminalInput == null) {
return;
}
let input = terminalInput.value;
if (input == "") {
return;
}
const semiColonIndex = input.lastIndexOf(";");
if (semiColonIndex !== -1) {
input = input.slice(semiColonIndex + 1);
}
input = input.trim();
input = input.replace(/\s\s+/g, " ");
const commandArray = input.split(" ");
let index = commandArray.length - 2;
if (index < -1) {
index = 0;
}
2021-09-16 02:06:48 +02:00
const allPos = determineAllPossibilitiesForTabCompletion(Player, input, index, NewTerminal.currDir);
2021-09-05 01:09:30 +02:00
if (allPos.length == 0) {
return;
}
let arg = "";
let command = "";
if (commandArray.length == 0) {
return;
}
if (commandArray.length == 1) {
command = commandArray[0];
} else if (commandArray.length == 2) {
command = commandArray[0];
arg = commandArray[1];
} else if (commandArray.length == 3) {
command = commandArray[0] + " " + commandArray[1];
arg = commandArray[2];
} else {
arg = commandArray.pop();
command = commandArray.join(" ");
}
tabCompletion(command, arg, allPos);
terminalInput.focus();
}
2021-09-05 01:09:30 +02:00
// Extra Bash Emulation Hotkeys, must be enabled through .fconf
if (FconfSettings.ENABLE_BASH_HOTKEYS) {
if (event.keyCode === KEY.A && event.ctrlKey) {
event.preventDefault();
Terminal.moveTextCursor("home");
}
if (event.keyCode === KEY.E && event.ctrlKey) {
event.preventDefault();
Terminal.moveTextCursor("end");
}
if (event.keyCode === KEY.B && event.ctrlKey) {
event.preventDefault();
Terminal.moveTextCursor("prevchar");
}
if (event.keyCode === KEY.B && event.altKey) {
event.preventDefault();
Terminal.moveTextCursor("prevword");
}
if (event.keyCode === KEY.F && event.ctrlKey) {
event.preventDefault();
Terminal.moveTextCursor("nextchar");
}
if (event.keyCode === KEY.F && event.altKey) {
event.preventDefault();
Terminal.moveTextCursor("nextword");
}
2021-09-09 05:47:34 +02:00
if ((event.keyCode === KEY.H || event.keyCode === KEY.D) && event.ctrlKey) {
2021-09-05 01:09:30 +02:00
Terminal.modifyInput("backspace");
event.preventDefault();
}
// TODO AFTER THIS:
// alt + d deletes word after cursor
// ^w deletes word before cursor
// ^k clears line after cursor
// ^u clears line before cursor
}
}
});
2021-09-05 01:09:30 +02:00
// Keep terminal in focus
let terminalCtrlPressed = false,
shiftKeyPressed = false;
$(document).ready(function () {
if (routing.isOn(Page.Terminal)) {
$(".terminal-input").focus();
}
});
$(document).keydown(function (e) {
if (routing.isOn(Page.Terminal)) {
if (e.which == KEY.CTRL) {
terminalCtrlPressed = true;
} else if (e.shiftKey) {
shiftKeyPressed = true;
2021-09-16 02:06:48 +02:00
} else if (terminalCtrlPressed || shiftKeyPressed || NewTerminal.contractOpen) {
2021-09-05 01:09:30 +02:00
// Don't focus
} else {
var inputTextBox = document.getElementById("terminal-input-text-box");
if (inputTextBox != null) {
inputTextBox.focus();
}
terminalCtrlPressed = false;
shiftKeyPressed = false;
}
}
});
2021-09-05 01:09:30 +02:00
$(document).keyup(function (e) {
if (routing.isOn(Page.Terminal)) {
if (e.which == KEY.CTRL) {
terminalCtrlPressed = false;
}
if (e.shiftKey) {
shiftKeyPressed = false;
}
}
});
2021-09-05 01:09:30 +02:00
let Terminal = {
resetTerminalInput: function (keepInput = false) {
let input = "";
if (keepInput) {
input = getTerminalInput();
}
2021-09-16 02:06:48 +02:00
const dir = NewTerminal.currDir;
2021-09-05 01:09:30 +02:00
if (FconfSettings.WRAP_INPUT) {
document.getElementById("terminal-input-td").innerHTML =
2021-09-09 05:47:34 +02:00
`<div id='terminal-input-header' class='prompt'>[${Player.getCurrentServer().hostname} ~${dir}]$ </div>` +
2021-09-05 01:09:30 +02:00
`<textarea type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" value=\"${input}\" autocomplete="off" />`;
// Auto re-size the line element as it wraps
autosize(document.getElementById("terminal-input-text-box"));
} else {
document.getElementById("terminal-input-td").innerHTML =
2021-09-09 05:47:34 +02:00
`<div id='terminal-input-header' class='prompt'>[${Player.getCurrentServer().hostname} ~${dir}]$ </div>` +
2021-09-05 01:09:30 +02:00
`<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" value=\"${input}\" autocomplete="off" />`;
}
const hdr = document.getElementById("terminal-input-header");
hdr.style.display = "inline";
const terminalInput = document.getElementById("terminal-input-text-box");
if (typeof terminalInput.selectionStart == "number") {
2021-09-09 05:47:34 +02:00
terminalInput.selectionStart = terminalInput.selectionEnd = terminalInput.value.length;
2021-09-05 01:09:30 +02:00
} else if (typeof terminalInput.createTextRange != "undefined") {
terminalInput.focus();
var range = el.createTextRange();
range.collapse(false);
range.select();
}
},
modifyInput: function (mod) {
try {
var terminalInput = document.getElementById("terminal-input-text-box");
if (terminalInput == null) {
return;
}
terminalInput.focus();
var inputLength = terminalInput.value.length;
var start = terminalInput.selectionStart;
var inputText = terminalInput.value;
switch (mod.toLowerCase()) {
case "backspace":
if (start > 0 && start <= inputLength + 1) {
2021-09-09 05:47:34 +02:00
terminalInput.value = inputText.substr(0, start - 1) + inputText.substr(start);
2021-09-05 01:09:30 +02:00
}
break;
case "deletewordbefore": // Delete rest of word before the cursor
for (var delStart = start - 1; delStart > 0; --delStart) {
if (inputText.charAt(delStart) === " ") {
2021-09-09 05:47:34 +02:00
terminalInput.value = inputText.substr(0, delStart) + inputText.substr(start);
2021-09-05 01:09:30 +02:00
return;
}
}
break;
case "deletewordafter": // Delete rest of word after the cursor
2021-09-09 05:47:34 +02:00
for (var delStart = start + 1; delStart <= text.length + 1; ++delStart) {
2021-09-05 01:09:30 +02:00
if (inputText.charAt(delStart) === " ") {
2021-09-09 05:47:34 +02:00
terminalInput.value = inputText.substr(0, start) + inputText.substr(delStart);
2021-09-05 01:09:30 +02:00
return;
}
}
break;
case "clearafter": // Deletes everything after cursor
break;
case "clearbefore:": // Deleetes everything before cursor
break;
}
} catch (e) {
console.error("Exception in Terminal.modifyInput: " + e);
}
},
moveTextCursor: function (loc) {
try {
var terminalInput = document.getElementById("terminal-input-text-box");
if (terminalInput == null) {
return;
}
terminalInput.focus();
var inputLength = terminalInput.value.length;
var start = terminalInput.selectionStart;
switch (loc.toLowerCase()) {
case "home":
terminalInput.setSelectionRange(0, 0);
break;
case "end":
terminalInput.setSelectionRange(inputLength, inputLength);
break;
case "prevchar":
if (start > 0) {
terminalInput.setSelectionRange(start - 1, start - 1);
}
break;
case "prevword":
for (var i = start - 2; i >= 0; --i) {
if (terminalInput.value.charAt(i) === " ") {
terminalInput.setSelectionRange(i + 1, i + 1);
return;
}
}
terminalInput.setSelectionRange(0, 0);
break;
case "nextchar":
terminalInput.setSelectionRange(start + 1, start + 1);
break;
case "nextword":
for (var i = start + 1; i <= inputLength; ++i) {
if (terminalInput.value.charAt(i) === " ") {
terminalInput.setSelectionRange(i, i);
return;
}
}
terminalInput.setSelectionRange(inputLength, inputLength);
break;
default:
console.warn("Invalid loc argument in Terminal.moveTextCursor()");
break;
}
} catch (e) {
console.error("Exception in Terminal.moveTextCursor: " + e);
}
},
};
2021-09-10 22:08:58 +02:00
export { postVersion, Terminal };