Branch data Line data Source code
1 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
2 : : // SPDX-FileCopyrightText: 2021 Evan Welsh <contact@evanwelsh.com>
3 : :
4 : : #include <config.h>
5 : :
6 : : #include <stdio.h>
7 : :
8 : : #ifdef HAVE_UNISTD_H
9 : : # include <unistd.h>
10 : : #elif defined(_WIN32)
11 : : # include <io.h>
12 : : #endif
13 : :
14 : : #ifdef HAVE_READLINE_READLINE_H
15 : : # include <readline/history.h>
16 : : #endif
17 : :
18 : : #include <glib.h>
19 : :
20 : : #include "gjs/auto.h"
21 : : #include "util/console.h"
22 : :
23 : : /**
24 : : * ANSI escape code sequences to manipulate terminals.
25 : : *
26 : : * See
27 : : * https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences
28 : : */
29 : : namespace ANSICode {
30 : : /**
31 : : * ANSI escape code sequence to clear the terminal screen.
32 : : *
33 : : * Combination of 0x1B (Escape) and the sequence nJ where n=2,
34 : : * n=2 clears the entire display instead of only after the cursor.
35 : : */
36 : : constexpr const char CLEAR_SCREEN[] = "\x1b[2J";
37 : :
38 : : } // namespace ANSICode
39 : :
40 : : #ifdef HAVE_UNISTD_H
41 : : const int stdin_fd = STDIN_FILENO;
42 : : const int stdout_fd = STDOUT_FILENO;
43 : : const int stderr_fd = STDERR_FILENO;
44 : : #elif defined(_WIN32)
45 : : const int stdin_fd = _fileno(stdin);
46 : : const int stdout_fd = _fileno(stdout);
47 : : const int stderr_fd = _fileno(stderr);
48 : : #else
49 : : const int stdin_fd = 0;
50 : : const int stdout_fd = 1;
51 : : const int stderr_fd = 2;
52 : : #endif
53 : :
54 : 558 : bool gjs_console_is_tty(int fd) {
55 : : #ifdef HAVE_UNISTD_H
56 : 558 : return isatty(fd);
57 : : #elif defined(_WIN32)
58 : : return _isatty(fd);
59 : : #else
60 : : return false;
61 : : #endif
62 : : }
63 : :
64 : 0 : bool gjs_console_clear() {
65 [ # # ]: 0 : if (stdout_fd < 0 || !g_log_writer_supports_color(stdout_fd))
66 : 0 : return false;
67 : :
68 [ # # # # ]: 0 : return fputs(ANSICode::CLEAR_SCREEN, stdout) > 0 && fflush(stdout) > 0;
69 : : }
70 : :
71 : : #ifdef HAVE_READLINE_READLINE_H
72 : 62 : char* gjs_console_get_repl_history_path() {
73 : 62 : const char* user_history_path = g_getenv("GJS_REPL_HISTORY");
74 : : Gjs::AutoChar default_history_path =
75 : 62 : g_build_filename(g_get_user_cache_dir(), "gjs_repl_history", nullptr);
76 : 62 : bool is_write_history_disabled =
77 [ - + - - ]: 62 : user_history_path && user_history_path[0] == '\0';
78 [ - + ]: 62 : if (is_write_history_disabled)
79 : 0 : return nullptr;
80 : :
81 [ - + ]: 62 : if (user_history_path)
82 : 0 : return g_strdup(user_history_path);
83 : 62 : return default_history_path.release();
84 : 62 : }
85 : :
86 : 278 : void gjs_console_write_repl_history(const char* path) {
87 [ + - ]: 278 : if (path) {
88 : 278 : int err = write_history(path);
89 [ - + ]: 278 : if (err != 0)
90 : 0 : g_warning("Could not persist history to defined file %s: %s", path,
91 : : g_strerror(err));
92 : : }
93 : 278 : }
94 : : #endif
|