[gjs/ewlsh/nova-repl] Support Ctrl+C guard in Repl
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/ewlsh/nova-repl] Support Ctrl+C guard in Repl
- Date: Fri, 3 Sep 2021 19:36:03 +0000 (UTC)
commit 42638c4267a1067f45a2ab19744eb6dec4d8e9fb
Author: Evan Welsh <contact evanwelsh com>
Date: Fri Sep 3 12:35:57 2021 -0700
Support Ctrl+C guard in Repl
modules/esm/repl.js | 31 +++++++++++++++++++++++++++++--
util/console.cpp | 3 ++-
2 files changed, 31 insertions(+), 3 deletions(-)
---
diff --git a/modules/esm/repl.js b/modules/esm/repl.js
index 648f0b66..698ec148 100644
--- a/modules/esm/repl.js
+++ b/modules/esm/repl.js
@@ -31,6 +31,8 @@ function toString(value) {
}
const sInputHandler = Symbol('input handler');
+const sExitHandler = Symbol('exit handler');
+const sExitWarning = Symbol('exit warning');
class ReplInput {
/**
* @param {object} _ _
@@ -81,6 +83,8 @@ class ReplInput {
* @param {string} _input the inputted line or lines (separated by \n)
*/
_input => { };
+
+ this[sExitWarning] = false;
}
[Symbol.toStringTag]() {
@@ -149,6 +153,17 @@ class ReplInput {
this.writeSync(Ansi.eraseDown(lines));
}
+ exit() {
+ if (this[sExitWarning]) {
+ this[sExitWarning] = false;
+ this[sExitHandler]?.();
+ } else {
+ this[sExitWarning] = true;
+ this.writeSync('\n(To exit, press Ctrl+C again or Ctrl+D)\n');
+ this.flush();
+ }
+ }
+
historyUp() {
if (this.historyIndex < this.history.length - 1) {
this.historyIndex++;
@@ -201,7 +216,7 @@ class ReplInput {
if (this.cursorColumn < editableValue.length - 1)
editableValue.splice(this.cursorColumn, 1);
else
- this.stop();
+ this.exit();
}
deleteToBeginning() {
@@ -310,6 +325,7 @@ class ReplInput {
if (this.validate(js)) {
// Reset lines before input is triggered
this.pendingInputLines = [];
+ this[sExitWarning] = false;
this[sInputHandler]?.(js);
} else {
// Buffer the input until a compilable unit is found...
@@ -320,6 +336,9 @@ class ReplInput {
handleEvent(key) {
if (key.ctrl && !key.meta && !key.shift) {
switch (key.name) {
+ case 'c':
+ this.exit();
+ return;
case 'h':
this.deleteChar();
return;
@@ -452,7 +471,7 @@ class ReplInput {
}
/**
- * @param {Uint8Array} buffer a string or Uint8Array to write to stdout
+ * @param {Uint8Array | string} buffer a string or Uint8Array to write to stdout
*/
writeSync(buffer) {
if (typeof buffer === 'string')
@@ -515,6 +534,10 @@ class ReplInput {
this._cancelled = false;
this.read();
}
+
+ onExit(exitHandler) {
+ this[sExitHandler] = exitHandler;
+ }
}
class FallbackReplInput extends ReplInput {
@@ -651,6 +674,10 @@ export class Repl {
enableColor: this[sSupportsColor],
});
+ this.input.onExit(() => {
+ this.exit();
+ });
+
this._registerInputHandler();
// Install our default mainloop...
diff --git a/util/console.cpp b/util/console.cpp
index 4498d165..3c0b7649 100644
--- a/util/console.cpp
+++ b/util/console.cpp
@@ -97,8 +97,9 @@ bool enable_raw_mode() {
// Disable echoing (terminal reprinting input)
// Disable canonical mode (output reflects input)
// Disable "extensions" that allow users to inject
+ // Disable C signal handling
// https://www.gnu.org/software/libc/manual/html_node/Other-Special.html
- raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);
+ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
// Set 0 characters required for a read
raw.c_cc[VMIN] = 0;
// Set the read timeout to 1 decisecond (0.1 seconds)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]