Skip to content
This repository has been archived by the owner on Apr 13, 2024. It is now read-only.

Commit

Permalink
Merge pull request #71 from AtkinsSJ/ctrl-c-interception
Browse files Browse the repository at this point in the history
Only exit the shell if Ctrl-C is pressed with an empty input
  • Loading branch information
KernelDeimos authored Mar 29, 2024
2 parents 0b378bd + a3a3409 commit ae2b11b
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 71 deletions.
80 changes: 80 additions & 0 deletions src/ansi-shell/readline/history.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Phoenix Shell.
*
* Phoenix Shell is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export class HistoryManager {
constructor({ enableLogging = false } = {}) {
this.items = [];
this.index_ = 0;
this.listeners_ = {};
this.enableLogging_ = enableLogging;
}

log(...a) {
// TODO: Command line option for configuring logging
if ( this.enableLogging_ ) {
console.log('[HistoryManager]', ...a);
}
}

get index() {
return this.index_;
}

set index(v) {
this.log('setting index', v);
this.index_ = v;
}

get() {
return this.items[this.index];
}

// Save, overwriting the current history item
save(data, { opt_debug } = {}) {
this.log('saving', data, 'at', this.index,
...(opt_debug ? [ 'from', opt_debug ] : []));
this.items[this.index] = data;

if (this.listeners_.hasOwnProperty('add')) {
for (const listener of this.listeners_.add) {
listener(data);
}
}
}

append(data) {
if (
this.items.length !== 0 &&
this.index !== this.items.length
) {
this.log('POP');
// remove last item
this.items.pop();
}
this.index = this.items.length;
this.save(data, { opt_debug: 'append' });
this.index++;
}

on(topic, listener) {
if (!this.listeners_.hasOwnProperty(topic)) {
this.listeners_[topic] = [];
}
this.listeners_[topic].push(listener);
}
}
84 changes: 17 additions & 67 deletions src/ansi-shell/readline/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Context } from "../../context/context.js";
import { CommandCompleter } from "../../puter-shell/completers/command_completer.js";
import { FileCompleter } from "../../puter-shell/completers/file_completer.js";
import { Context } from '../../context/context.js';
import { CommandCompleter } from '../../puter-shell/completers/command_completer.js';
import { FileCompleter } from '../../puter-shell/completers/file_completer.js';
import { OptionCompleter } from '../../puter-shell/completers/option_completer.js';
import { Uint8List } from "../../util/bytes.js";
import { StatefulProcessorBuilder } from "../../util/statemachine.js";
import { ANSIContext } from "../ANSIContext.js";
import { readline_comprehend } from "./rl_comprehend.js";
import { CSI_HANDLERS } from "./rl_csi_handlers.js";
import { Uint8List } from '../../util/bytes.js';
import { StatefulProcessorBuilder } from '../../util/statemachine.js';
import { ANSIContext } from '../ANSIContext.js';
import { readline_comprehend } from './rl_comprehend.js';
import { CSI_HANDLERS } from './rl_csi_handlers.js';
import { HistoryManager } from './history.js';

const decoder = new TextDecoder();

Expand Down Expand Up @@ -71,6 +72,13 @@ const ReadlineProcessorBuilder = builder => builder

if ( locals.byte === consts.CHAR_ETX ) {
externs.out.write('^C\n');
// Exit if input line is empty
// FIXME: Check for 'process' is so we only do this on Node. How should we handle exiting in Puter terminal?
if ( process && ctx.vars.result.length === 0 ) {
process.exit(1);
return;
}
// Otherwise clear it
ctx.vars.result = '';
ctx.setState('end');
return;
Expand Down Expand Up @@ -315,51 +323,6 @@ const ReadlineProcessor = ReadlineProcessorBuilder(
new StatefulProcessorBuilder()
);

class HistoryManager {
constructor () {
this.items = [];
this.index_ = 0;
this.listeners_ = {};
}

log (...a) {
// TODO: proper logging and verbosity config
// console.log('[HistoryManager]', ...a);
}

get index () {
return this.index_;
}

set index (v) {
this.log('setting index', v);
this.index_ = v;
}

get () {
return this.items[this.index];
}

save (data, { opt_debug } = {}) {
this.log('saving', data, 'at', this.index,
...(opt_debug ? ['from', opt_debug] : []));
this.items[this.index] = data;

if ( this.listeners_.hasOwnProperty('add') ) {
for ( const listener of this.listeners_.add ) {
listener(data);
}
}
}

on (topic, listener) {
if ( ! this.listeners_.hasOwnProperty(topic) ) {
this.listeners_[topic] = [];
}
this.listeners_[topic].push(listener);
}
}

class Readline {
constructor (params) {
this.internal_ = {};
Expand All @@ -383,21 +346,8 @@ class Readline {
commandCtx,
});

// TODO: this condition, redundant to the one in ANSIShell,
// is an indication that HistoryManager
if ( result.trim() !== '' ) {
// console.log('[HistoryManager] len?', this.history.items.length);
if (
this.history.items.length !== 0 &&
this.history.index !== this.history.items.length
) {
// console.log('[HistoryManager] POP');
// remove last item
this.history.items.pop();
}
this.history.index = this.history.items.length;
this.history.save(result, { opt_debug: 'post-readline' });
this.history.index++;
this.history.append(result);
}

return result;
Expand Down
4 changes: 0 additions & 4 deletions src/pty/NodeStdioPTT.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ export class NodeStdioPTT {
process.stdin.on('data', chunk => {
const input = new Uint8Array(chunk);
readController.enqueue(input);
if (input.length === 1 && (input[0] === signals.SIGINT || input[0] === signals.SIGQUIT)) {
process.exit(1);
return;
}
});

this.out = writestream_node_to_web(process.stdout);
Expand Down

0 comments on commit ae2b11b

Please sign in to comment.