aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Hubrecht <github@mail.hubrecht.ovh>2024-05-28 11:19:08 +0200
committerTom Hubrecht <github@mail.hubrecht.ovh>2024-05-29 09:54:47 +0200
commit81bdf8d2d672e135e68745e6975ad5edafadf13a (patch)
tree3a571a94b17c0436ac586f01384308a687b86ee4 /src
parent6fd6795bc4faed644c5f3abafdcb21638a119342 (diff)
util.{hh,cc}: Split out terminal.{hh,cc}
Change-Id: I9de2296b4012d50f540124001d54d6ca3be4c6da
Diffstat (limited to 'src')
-rw-r--r--src/libcmd/markdown.cc1
-rw-r--r--src/libexpr/flake/flake.cc1
-rw-r--r--src/libexpr/print.cc1
-rw-r--r--src/libmain/progress-bar.cc1
-rw-r--r--src/libutil/error.cc1
-rw-r--r--src/libutil/logging.cc1
-rw-r--r--src/libutil/meson.build2
-rw-r--r--src/libutil/signals.cc1
-rw-r--r--src/libutil/suggestions.cc4
-rw-r--r--src/libutil/terminal.cc104
-rw-r--r--src/libutil/terminal.hh40
-rw-r--r--src/libutil/util.cc96
-rw-r--r--src/libutil/util.hh25
13 files changed, 156 insertions, 122 deletions
diff --git a/src/libcmd/markdown.cc b/src/libcmd/markdown.cc
index 668a07763..8b3bbc1b5 100644
--- a/src/libcmd/markdown.cc
+++ b/src/libcmd/markdown.cc
@@ -1,6 +1,7 @@
#include "markdown.hh"
#include "util.hh"
#include "finally.hh"
+#include "terminal.hh"
#include <sys/queue.h>
#include <lowdown.h>
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index e13d1cb93..ac50351ad 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -8,6 +8,7 @@
#include "fetchers.hh"
#include "finally.hh"
#include "fetch-settings.hh"
+#include "terminal.hh"
namespace nix {
diff --git a/src/libexpr/print.cc b/src/libexpr/print.cc
index 231bde0a0..c56b0e72e 100644
--- a/src/libexpr/print.cc
+++ b/src/libexpr/print.cc
@@ -9,6 +9,7 @@
#include "english.hh"
#include "signals.hh"
#include "eval.hh"
+#include "terminal.hh"
namespace nix {
diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc
index 1a68daca2..f3700f103 100644
--- a/src/libmain/progress-bar.cc
+++ b/src/libmain/progress-bar.cc
@@ -3,6 +3,7 @@
#include "sync.hh"
#include "store-api.hh"
#include "names.hh"
+#include "terminal.hh"
#include <atomic>
#include <map>
diff --git a/src/libutil/error.cc b/src/libutil/error.cc
index fe73ffc56..f780aabef 100644
--- a/src/libutil/error.cc
+++ b/src/libutil/error.cc
@@ -1,6 +1,7 @@
#include "environment-variables.hh"
#include "error.hh"
#include "position.hh"
+#include "terminal.hh"
#include <iostream>
#include <optional>
diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc
index 8e4828be4..731d1034d 100644
--- a/src/libutil/logging.cc
+++ b/src/libutil/logging.cc
@@ -4,6 +4,7 @@
#include "config.hh"
#include "source-path.hh"
#include "position.hh"
+#include "terminal.hh"
#include <atomic>
#include <nlohmann/json.hpp>
diff --git a/src/libutil/meson.build b/src/libutil/meson.build
index 01b3e24b7..c890911e9 100644
--- a/src/libutil/meson.build
+++ b/src/libutil/meson.build
@@ -30,6 +30,7 @@ libutil_sources = files(
'source-path.cc',
'suggestions.cc',
'tarfile.cc',
+ 'terminal.cc',
'thread-pool.cc',
'url.cc',
'url-name.cc',
@@ -90,6 +91,7 @@ libutil_headers = files(
'suggestions.hh',
'sync.hh',
'tarfile.hh',
+ 'terminal.hh',
'thread-pool.hh',
'topo-sort.hh',
'types.hh',
diff --git a/src/libutil/signals.cc b/src/libutil/signals.cc
index 41fdc9dc8..c0e66f6ed 100644
--- a/src/libutil/signals.cc
+++ b/src/libutil/signals.cc
@@ -2,6 +2,7 @@
#include "util.hh"
#include "error.hh"
#include "sync.hh"
+#include "terminal.hh"
#include <thread>
diff --git a/src/libutil/suggestions.cc b/src/libutil/suggestions.cc
index 9510a5f0c..63dcf84b5 100644
--- a/src/libutil/suggestions.cc
+++ b/src/libutil/suggestions.cc
@@ -1,7 +1,9 @@
#include "suggestions.hh"
#include "ansicolor.hh"
-#include "util.hh"
+#include "terminal.hh"
+
#include <algorithm>
+#include <ostream>
namespace nix {
diff --git a/src/libutil/terminal.cc b/src/libutil/terminal.cc
new file mode 100644
index 000000000..b58331d04
--- /dev/null
+++ b/src/libutil/terminal.cc
@@ -0,0 +1,104 @@
+#include "terminal.hh"
+#include "environment-variables.hh"
+#include "sync.hh"
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+namespace nix {
+
+bool shouldANSI()
+{
+ return isatty(STDERR_FILENO)
+ && getEnv("TERM").value_or("dumb") != "dumb"
+ && !(getEnv("NO_COLOR").has_value() || getEnv("NOCOLOR").has_value());
+}
+
+std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int width)
+{
+ std::string t, e;
+ size_t w = 0;
+ auto i = s.begin();
+
+ while (w < (size_t) width && i != s.end()) {
+
+ if (*i == '\e') {
+ std::string e;
+ e += *i++;
+ char last = 0;
+
+ if (i != s.end() && *i == '[') {
+ e += *i++;
+ // eat parameter bytes
+ while (i != s.end() && *i >= 0x30 && *i <= 0x3f) e += *i++;
+ // eat intermediate bytes
+ while (i != s.end() && *i >= 0x20 && *i <= 0x2f) e += *i++;
+ // eat final byte
+ if (i != s.end() && *i >= 0x40 && *i <= 0x7e) e += last = *i++;
+ } else {
+ if (i != s.end() && *i >= 0x40 && *i <= 0x5f) e += *i++;
+ }
+
+ if (!filterAll && last == 'm')
+ t += e;
+ }
+
+ else if (*i == '\t') {
+ i++; t += ' '; w++;
+ while (w < (size_t) width && w % 8) {
+ t += ' '; w++;
+ }
+ }
+
+ else if (*i == '\r' || *i == '\a')
+ // do nothing for now
+ i++;
+
+ else {
+ w++;
+ // Copy one UTF-8 character.
+ if ((*i & 0xe0) == 0xc0) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
+ } else if ((*i & 0xf0) == 0xe0) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
+ }
+ } else if ((*i & 0xf8) == 0xf0) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
+ }
+ }
+ } else
+ t += *i++;
+ }
+ }
+
+ return t;
+}
+
+static Sync<std::pair<unsigned short, unsigned short>> windowSize{{0, 0}};
+
+void updateWindowSize()
+{
+ struct winsize ws;
+ if (ioctl(2, TIOCGWINSZ, &ws) == 0) {
+ auto windowSize_(windowSize.lock());
+ windowSize_->first = ws.ws_row;
+ windowSize_->second = ws.ws_col;
+ }
+}
+
+
+std::pair<unsigned short, unsigned short> getWindowSize()
+{
+ return *windowSize.lock();
+}
+
+}
diff --git a/src/libutil/terminal.hh b/src/libutil/terminal.hh
new file mode 100644
index 000000000..43df5bd70
--- /dev/null
+++ b/src/libutil/terminal.hh
@@ -0,0 +1,40 @@
+#pragma once
+///@file
+
+#include <limits>
+#include <string>
+
+namespace nix {
+
+/**
+ * Determine whether ANSI escape sequences are appropriate for the
+ * present output.
+ */
+bool shouldANSI();
+
+/**
+ * Truncate a string to 'width' printable characters. If 'filterAll'
+ * is true, all ANSI escape sequences are filtered out. Otherwise,
+ * some escape sequences (such as colour setting) are copied but not
+ * included in the character count. Also, tabs are expanded to
+ * spaces.
+ */
+std::string filterANSIEscapes(std::string_view s,
+ bool filterAll = false,
+ unsigned int width = std::numeric_limits<unsigned int>::max());
+
+/**
+ * Recalculate the window size, updating a global variable. Used in the
+ * `SIGWINCH` signal handler.
+ */
+void updateWindowSize();
+
+/**
+ * @return the number of rows and columns of the terminal.
+ *
+ * The value is cached so this is quick. The cached result is computed
+ * by `updateWindowSize()`.
+ */
+std::pair<unsigned short, unsigned short> getWindowSize();
+
+}
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 97d53ca63..63d9e5248 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -1436,83 +1436,6 @@ void ignoreException(Verbosity lvl)
} catch (...) { }
}
-bool shouldANSI()
-{
- return isatty(STDERR_FILENO)
- && getEnv("TERM").value_or("dumb") != "dumb"
- && !(getEnv("NO_COLOR").has_value() || getEnv("NOCOLOR").has_value());
-}
-
-std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int width)
-{
- std::string t, e;
- size_t w = 0;
- auto i = s.begin();
-
- while (w < (size_t) width && i != s.end()) {
-
- if (*i == '\e') {
- std::string e;
- e += *i++;
- char last = 0;
-
- if (i != s.end() && *i == '[') {
- e += *i++;
- // eat parameter bytes
- while (i != s.end() && *i >= 0x30 && *i <= 0x3f) e += *i++;
- // eat intermediate bytes
- while (i != s.end() && *i >= 0x20 && *i <= 0x2f) e += *i++;
- // eat final byte
- if (i != s.end() && *i >= 0x40 && *i <= 0x7e) e += last = *i++;
- } else {
- if (i != s.end() && *i >= 0x40 && *i <= 0x5f) e += *i++;
- }
-
- if (!filterAll && last == 'm')
- t += e;
- }
-
- else if (*i == '\t') {
- i++; t += ' '; w++;
- while (w < (size_t) width && w % 8) {
- t += ' '; w++;
- }
- }
-
- else if (*i == '\r' || *i == '\a')
- // do nothing for now
- i++;
-
- else {
- w++;
- // Copy one UTF-8 character.
- if ((*i & 0xe0) == 0xc0) {
- t += *i++;
- if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
- } else if ((*i & 0xf0) == 0xe0) {
- t += *i++;
- if (i != s.end() && ((*i & 0xc0) == 0x80)) {
- t += *i++;
- if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
- }
- } else if ((*i & 0xf8) == 0xf0) {
- t += *i++;
- if (i != s.end() && ((*i & 0xc0) == 0x80)) {
- t += *i++;
- if (i != s.end() && ((*i & 0xc0) == 0x80)) {
- t += *i++;
- if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
- }
- }
- } else
- t += *i++;
- }
- }
-
- return t;
-}
-
-
constexpr char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string base64Encode(std::string_view s)
@@ -1630,25 +1553,6 @@ std::pair<std::string_view, std::string_view> getLine(std::string_view s)
//////////////////////////////////////////////////////////////////////
-static Sync<std::pair<unsigned short, unsigned short>> windowSize{{0, 0}};
-
-
-void updateWindowSize()
-{
- struct winsize ws;
- if (ioctl(2, TIOCGWINSZ, &ws) == 0) {
- auto windowSize_(windowSize.lock());
- windowSize_->first = ws.ws_row;
- windowSize_->second = ws.ws_col;
- }
-}
-
-
-std::pair<unsigned short, unsigned short> getWindowSize()
-{
- return *windowSize.lock();
-}
-
rlim_t savedStackSize = 0;
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 151da25b9..1ce7e8312 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -726,23 +726,6 @@ constexpr char treeLast[] = "└───";
constexpr char treeLine[] = "│ ";
constexpr char treeNull[] = " ";
-/**
- * Determine whether ANSI escape sequences are appropriate for the
- * present output.
- */
-bool shouldANSI();
-
-/**
- * Truncate a string to 'width' printable characters. If 'filterAll'
- * is true, all ANSI escape sequences are filtered out. Otherwise,
- * some escape sequences (such as colour setting) are copied but not
- * included in the character count. Also, tabs are expanded to
- * spaces.
- */
-std::string filterANSIEscapes(std::string_view s,
- bool filterAll = false,
- unsigned int width = std::numeric_limits<unsigned int>::max());
-
/**
* Base64 encoding/decoding.
@@ -841,14 +824,6 @@ struct MaintainCount
/**
- * @return the number of rows and columns of the terminal.
- */
-std::pair<unsigned short, unsigned short> getWindowSize();
-
-void updateWindowSize();
-
-
-/**
* Used in various places.
*/
typedef std::function<bool(const Path & path)> PathFilter;