aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/patched/replxx/src/util.cxx
diff options
context:
space:
mode:
authorMaksim Kita <kitaetoya@gmail.com>2023-08-16 19:45:44 +0300
committermaksim-kita <maksim-kita@yandex-team.com>2023-08-16 21:20:29 +0300
commitb151ead5232fd8b20b940e6686c91b64c700db11 (patch)
treedd94250feffed4aabd4bc889e3db83445da59a99 /contrib/restricted/patched/replxx/src/util.cxx
parente4f09ec22e1897b1d7716cd23c5bab9069944cfb (diff)
downloadydb-b151ead5232fd8b20b940e6686c91b64c700db11.tar.gz
Added interactive CLI
Added Interactive CLI Pull Request resolved: #242
Diffstat (limited to 'contrib/restricted/patched/replxx/src/util.cxx')
-rw-r--r--contrib/restricted/patched/replxx/src/util.cxx179
1 files changed, 179 insertions, 0 deletions
diff --git a/contrib/restricted/patched/replxx/src/util.cxx b/contrib/restricted/patched/replxx/src/util.cxx
new file mode 100644
index 0000000000..730a7531f5
--- /dev/null
+++ b/contrib/restricted/patched/replxx/src/util.cxx
@@ -0,0 +1,179 @@
+#include <chrono>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <wctype.h>
+
+#include "util.hxx"
+#include "terminal.hxx"
+
+#undef min
+
+namespace replxx {
+
+int mk_wcwidth( char32_t );
+
+int virtual_render( char32_t const* display_, int size_, int& x_, int& y_, int screenColumns_, int promptLen_, char32_t* rendered_, int* renderedSize_ ) {
+ char32_t* out( rendered_ );
+ int visibleCount( 0 );
+ auto render = [&rendered_, &renderedSize_, &out, &visibleCount]( char32_t c_, bool visible_, bool renderAttributes_ = true ) {
+ if ( rendered_ && renderedSize_ && renderAttributes_ ) {
+ *out = c_;
+ ++ out;
+ if ( visible_ ) {
+ ++ visibleCount;
+ }
+ }
+ };
+ bool wrapped( false );
+ auto advance_cursor = [&x_, &y_, &screenColumns_, &wrapped]( int by_ = 1 ) {
+ wrapped = false;
+ x_ += by_;
+ if ( x_ >= screenColumns_ ) {
+ x_ = 0;
+ ++ y_;
+ wrapped = true;
+ }
+ };
+ bool const renderAttributes( !!tty::out );
+ int pos( 0 );
+ while ( pos < size_ ) {
+ char32_t c( display_[pos] );
+ if ( ( c == '\n' ) || ( c == '\r' ) ) {
+ render( c, true );
+ if ( ( c == '\n' ) && ! wrapped ) {
+ ++ y_;
+ }
+ x_ = promptLen_;
+ ++ pos;
+ continue;
+ }
+ if ( c == '\b' ) {
+ render( c, true );
+ -- x_;
+ if ( x_ < 0 ) {
+ x_ = screenColumns_ - 1;
+ -- y_;
+ }
+ ++ pos;
+ continue;
+ }
+ if ( c == '\033' ) {
+ render( c, false, renderAttributes );
+ ++ pos;
+ if ( pos >= size_ ) {
+ advance_cursor( 2 );
+ continue;
+ }
+ c = display_[pos];
+ if ( c != '[' ) {
+ advance_cursor( 2 );
+ continue;
+ }
+ render( c, false, renderAttributes );
+ ++ pos;
+ if ( pos >= size_ ) {
+ advance_cursor( 3 );
+ continue;
+ }
+ int codeLen( 0 );
+ while ( pos < size_ ) {
+ c = display_[pos];
+ if ( ( c != ';' ) && ( ( c < '0' ) || ( c > '9' ) ) ) {
+ break;
+ }
+ render( c, false, renderAttributes );
+ ++ codeLen;
+ ++ pos;
+ }
+ if ( pos >= size_ ) {
+ continue;
+ }
+ c = display_[pos];
+ if ( c != 'm' ) {
+ advance_cursor( 3 + codeLen );
+ continue;
+ }
+ render( c, false, renderAttributes );
+ ++ pos;
+ continue;
+ }
+ if ( is_control_code( c ) ) {
+ render( c, true );
+ advance_cursor( 2 );
+ ++ pos;
+ continue;
+ }
+ int wcw( mk_wcwidth( c ) );
+ if ( wcw < 0 ) {
+ break;
+ }
+ render( c, true );
+ advance_cursor( wcw );
+ ++ pos;
+ }
+ if ( rendered_ && renderedSize_ ) {
+ *renderedSize_ = out - rendered_;
+ }
+ return ( visibleCount );
+}
+
+char const* ansi_color( Replxx::Color color_ ) {
+ int unsigned code( static_cast<int unsigned>( color_ ) );
+ int unsigned fg( code & 0xFFu );
+ int unsigned bg( ( code >> 8 ) & 0xFFu );
+ char const* bold( ( code & color::BOLD ) != 0 ? ";1" : "" );
+ char const* underline = ( ( code & color::UNDERLINE ) != 0 ? ";4" : "" );
+ static int const MAX_COLOR_CODE_SIZE( 32 );
+ static char colorBuffer[MAX_COLOR_CODE_SIZE];
+ int pos( 0 );
+ if ( ( code & static_cast<int unsigned>( Replxx::Color::DEFAULT ) ) != 0 ) {
+ pos = snprintf( colorBuffer, MAX_COLOR_CODE_SIZE, "\033[0%s%sm", underline, bold );
+ } else if ( fg <= static_cast<int unsigned>( Replxx::Color::LIGHTGRAY ) ) {
+ pos = snprintf( colorBuffer, MAX_COLOR_CODE_SIZE, "\033[0;22;3%d%s%sm", fg, underline, bold );
+ } else if ( fg <= static_cast<int unsigned>( Replxx::Color::WHITE ) ) {
+#ifdef _WIN32
+ static bool const has256colorDefault( true );
+#else
+ static bool const has256colorDefault( false );
+#endif
+ static char const* TERM( getenv( "TERM" ) );
+ static bool const has256color( TERM ? ( strstr( TERM, "256" ) != nullptr ) : has256colorDefault );
+ static char const* ansiEscapeCodeTemplate = has256color ? "\033[0;9%d%s%sm" : "\033[0;1;3%d%s%sm";
+ pos = snprintf( colorBuffer, MAX_COLOR_CODE_SIZE, ansiEscapeCodeTemplate, fg - static_cast<int>( Replxx::Color::GRAY ), underline, bold );
+ } else {
+ pos = snprintf( colorBuffer, MAX_COLOR_CODE_SIZE, "\033[0;38;5;%d%s%sm", fg, underline, bold );
+ }
+ if ( ( code & color::BACKGROUND_COLOR_SET ) == 0 ) {
+ return colorBuffer;
+ }
+ if ( bg <= static_cast<int unsigned>( Replxx::Color::WHITE ) ) {
+ if ( bg <= static_cast<int unsigned>( Replxx::Color::LIGHTGRAY ) ) {
+ snprintf( colorBuffer + pos, MAX_COLOR_CODE_SIZE - pos, "\033[4%dm", bg );
+ } else {
+ snprintf( colorBuffer + pos, MAX_COLOR_CODE_SIZE - pos, "\033[10%dm", bg - static_cast<int>( Replxx::Color::GRAY ) );
+ }
+ } else {
+ snprintf( colorBuffer + pos, MAX_COLOR_CODE_SIZE - pos, "\033[48;5;%dm", bg );
+ }
+ return colorBuffer;
+}
+
+std::string now_ms_str( void ) {
+ std::chrono::milliseconds ms( std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch() ) );
+ time_t t( ms.count() / 1000 );
+ tm broken;
+#ifdef _WIN32
+#define localtime_r( t, b ) localtime_s( ( b ), ( t ) )
+#endif
+ localtime_r( &t, &broken );
+#undef localtime_r
+ static int const BUFF_SIZE( 32 );
+ char str[BUFF_SIZE];
+ strftime( str, BUFF_SIZE, "%Y-%m-%d %H:%M:%S.", &broken );
+ snprintf( str + sizeof ( "YYYY-mm-dd HH:MM:SS" ), 5, "%03d", static_cast<int>( ms.count() % 1000 ) );
+ return ( str );
+}
+
+}
+