Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/terminal/index.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Terminal server7*/89import { getLogger } from "@cocalc/backend/logger";10import type { Options, PrimusChannel, PrimusWithChannels } from "./lib/types";11export { PrimusChannel, PrimusWithChannels };12import { getChannelName, getRemotePtyChannelName } from "./lib/util";13import { Terminal } from "./lib/terminal";14export { RemoteTerminal } from "./lib/remote-terminal";15export { getRemotePtyChannelName };16import { EventEmitter } from "events";1718const logger = getLogger("terminal:index");1920const terminals: { [name: string]: Terminal } = {};2122class Terminals extends EventEmitter {23private paths: { [path: string]: true } = {};2425getOpenPaths = (): string[] => Object.keys(this.paths);2627isOpen = (path) => this.paths[path] != null;2829add = (path: string) => {30this.emit("open", path);31this.paths[path] = true;32};3334// not used YET:35close = (path: string) => {36this.emit("close", path);37delete this.paths[path];38};39}4041export const terminalTracker = new Terminals();4243// this is used to know which path belongs to which terminal44// (this is the overall tab, not the individual frame -- it's45// used for the processes page)46export function pidToPath(pid: number): string | undefined {47for (const terminal of Object.values(terminals)) {48if (terminal.getPid() == pid) {49return terminal.getPath();50}51}52}5354// INPUT: primus and description of a terminal session (the path)55// OUTPUT: the name of a websocket channel that serves that terminal session.56export async function terminal(57primus: PrimusWithChannels,58path: string,59options: Options,60): Promise<string> {61const name = getChannelName(path);62if (terminals[name] != null) {63if (64options.command != null &&65options.command != terminals[name].getCommand()66) {67logger.debug(68"changing command/args for existing terminal and restarting",69path,70);71terminals[name].setCommand(options.command, options.args);72}73return name;74}7576logger.debug("creating terminal for ", { path });77const terminal = new Terminal(primus, path, options);78terminals[name] = terminal;79await terminal.init();80terminalTracker.add(path);8182return name;83}848586