Utilities/js: Make it possible to exit via two consecutive ^C's

Apparently this is common in the js repl world.
Fixes #743.
This commit is contained in:
Ali Mohammad Pur 2024-07-26 00:36:15 +02:00 committed by Sam Atkins
parent a6ebd100ec
commit d3f089dc26
Notes: github-actions[bot] 2024-07-27 10:50:38 +00:00
5 changed files with 18 additions and 12 deletions

View file

@ -31,10 +31,6 @@
#include <sys/time.h>
#include <unistd.h>
namespace {
constexpr u32 ctrl(char c) { return c & 0x3f; }
}
namespace Line {
Configuration Configuration::from_config(StringView libname)

View file

@ -36,6 +36,8 @@
namespace Line {
static constexpr u32 ctrl(char c) { return c & 0x3f; }
struct KeyBinding {
Vector<Key> keys;
enum class Kind {

View file

@ -15,10 +15,6 @@
#include <sys/wait.h>
#include <unistd.h>
namespace {
constexpr u32 ctrl(char c) { return c & 0x3f; }
}
namespace Line {
Function<bool(Editor&)> Editor::find_internal_function(StringView name)

View file

@ -7,10 +7,6 @@
#include <AK/Debug.h>
#include <LibLine/Editor.h>
namespace {
constexpr u32 ctrl(char c) { return c & 0x3f; }
}
namespace Line {
void KeyCallbackMachine::register_key_input_callback(Vector<Key> keys, Function<bool(Editor&)> callback)

View file

@ -101,10 +101,13 @@ static ErrorOr<void> print(JS::Value value, PrintTarget target = PrintTarget::St
return print(value, *stream);
}
static size_t s_ctrl_c_hit_count = 0;
static ErrorOr<String> prompt_for_level(int level)
{
static StringBuilder prompt_builder;
prompt_builder.clear();
if (s_ctrl_c_hit_count > 0)
prompt_builder.append("(Use Ctrl+C again to exit)\n"sv);
prompt_builder.append("> "sv);
for (auto i = 0; i < level; ++i)
@ -122,6 +125,7 @@ static ErrorOr<String> read_next_piece()
do {
auto line_result = s_editor->get_line(TRY(prompt_for_level(s_repl_line_level)).to_byte_string());
s_ctrl_c_hit_count = 0;
line_level_delta_for_next_line = 0;
if (line_result.is_error()) {
@ -600,6 +604,18 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
s_editor->save_history(s_history_path.to_byte_string());
});
s_editor->register_key_input_callback(Line::ctrl('C'), [](Line::Editor& editor) -> bool {
if (editor.buffer_view().length() == 0 || s_ctrl_c_hit_count > 0) {
if (++s_ctrl_c_hit_count == 2) {
s_keep_running_repl = false;
editor.finish_edit();
return false;
}
}
return true;
});
s_editor->on_display_refresh = [syntax_highlight](Line::Editor& editor) {
auto stylize = [&](Line::Span span, Line::Style styles) {
if (syntax_highlight)