[gjs/ewlsh/whatwg-console: 3/3] modules: Implement console.clear()




commit e24c054839170a1c08d130120ca2a5ea3c913198
Author: Evan Welsh <contact evanwelsh com>
Date:   Tue Jun 29 01:07:13 2021 -0700

    modules: Implement console.clear()

 libgjs-private/gjs-util.c | 13 +++++++++++++
 libgjs-private/gjs-util.h |  3 +++
 modules/esm/console.js    |  2 ++
 util/console.cpp          | 28 ++++++++++++++++++++++++++++
 util/console.h            |  2 ++
 5 files changed, 48 insertions(+)
---
diff --git a/libgjs-private/gjs-util.c b/libgjs-private/gjs-util.c
index 1edbdd7d..5ca54a3e 100644
--- a/libgjs-private/gjs-util.c
+++ b/libgjs-private/gjs-util.c
@@ -17,6 +17,7 @@
 #include <glib/gi18n.h> /* for bindtextdomain, bind_textdomain_codeset, textdomain */
 
 #include "libgjs-private/gjs-util.h"
+#include "util/console.h"
 
 char *
 gjs_format_int_alternative_output(int n)
@@ -329,3 +330,15 @@ void gjs_log_set_writer_func(GjsGLogWriterFunc func, void* user_data,
 
     g_log_set_writer_func(gjs_log_writer_func_wrapper, func, NULL);
 }
+
+/**
+ * gjs_clear_terminal:
+ *
+ * Clears the terminal, if possible.
+ */
+void gjs_clear_terminal(void) {
+    if (!gjs_console_is_tty(stdout_fd))
+        return;
+
+    gjs_console_clear();
+}
diff --git a/libgjs-private/gjs-util.h b/libgjs-private/gjs-util.h
index 06114751..e1213600 100644
--- a/libgjs-private/gjs-util.h
+++ b/libgjs-private/gjs-util.h
@@ -137,6 +137,9 @@ void gjs_gtk_container_child_set_property(GObject* container, GObject* child,
                                           const char* property,
                                           const GValue* value);
 
+GJS_EXPORT
+void gjs_clear_terminal(void);
+
 G_END_DECLS
 
 #endif /* LIBGJS_PRIVATE_GJS_UTIL_H_ */
diff --git a/modules/esm/console.js b/modules/esm/console.js
index 152df43c..bdbfc69d 100644
--- a/modules/esm/console.js
+++ b/modules/esm/console.js
@@ -2,6 +2,7 @@
 // SPDX-FileCopyrightText: 2021 Evan Welsh <contact evanwelsh com>
 
 import GLib from 'gi://GLib';
+import GjsPrivate from 'gi://GjsPrivate';
 
 const sLogger = Symbol('Logger');
 const sPrinter = Symbol('Printer');
@@ -150,6 +151,7 @@ class Console {
      */
     clear() {
         this[sGroupIndentation] = '';
+        GjsPrivate.clear_terminal();
     }
 
     /**
diff --git a/util/console.cpp b/util/console.cpp
index 49bf77e1..5489ab6b 100644
--- a/util/console.cpp
+++ b/util/console.cpp
@@ -3,14 +3,35 @@
 
 #include <config.h>
 
+#include <stdio.h>
+
 #ifdef HAVE_UNISTD_H
 #    include <unistd.h>
 #elif defined(_WIN32)
 #    include <io.h>
 #endif
 
+#include <glib.h>
+
 #include "util/console.h"
 
+/**
+ * ANSI escape code sequences to manipulate terminals.
+ *
+ * See
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences
+ */
+namespace ANSICode {
+/**
+ * ANSI escape code sequence to clear the terminal screen.
+ *
+ * Combination of 0x1B (Escape) and the sequence nJ where n=2,
+ * n=2 clears the entire display instead of only after the cursor.
+ */
+constexpr const char CLEAR_SCREEN[] = "\x1b[2J";
+
+}  // namespace ANSICode
+
 #ifdef HAVE_UNISTD_H
 const int stdin_fd = STDIN_FILENO;
 const int stdout_fd = STDOUT_FILENO;
@@ -34,3 +55,10 @@ bool gjs_console_is_tty(int fd) {
     return false;
 #endif
 }
+
+bool gjs_console_clear() {
+    if (stdout_fd < 0 || !g_log_writer_supports_color(stdout_fd))
+        return false;
+
+    return fputs(ANSICode::CLEAR_SCREEN, stdout) > 0 && fflush(stdout) > 0;
+}
diff --git a/util/console.h b/util/console.h
index d8acd5ed..df27f305 100644
--- a/util/console.h
+++ b/util/console.h
@@ -24,6 +24,8 @@ extern const int stderr_fd;
 GJS_USE
 bool gjs_console_is_tty(int fd);
 
+bool gjs_console_clear(void);
+
 G_END_DECLS
 
 #endif  // UTIL_CONSOLE_H_


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]