您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include <chrono>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <ctime>
  5. #include <wctype.h>
  6. #include "util.hxx"
  7. namespace replxx {
  8. int mk_wcwidth( char32_t );
  9. /**
  10. * Calculate a new screen position given a starting position, screen width and
  11. * character count
  12. * @param x - initial x position (zero-based)
  13. * @param y - initial y position (zero-based)
  14. * @param screenColumns - screen column count
  15. * @param charCount - character positions to advance
  16. * @param xOut - returned x position (zero-based)
  17. * @param yOut - returned y position (zero-based)
  18. */
  19. void calculate_screen_position(
  20. int x, int y, int screenColumns,
  21. int charCount, int& xOut, int& yOut
  22. ) {
  23. xOut = x;
  24. yOut = y;
  25. int charsRemaining = charCount;
  26. while ( charsRemaining > 0 ) {
  27. int charsThisRow = ( ( x + charsRemaining ) < screenColumns )
  28. ? charsRemaining
  29. : screenColumns - x;
  30. xOut = x + charsThisRow;
  31. yOut = y;
  32. charsRemaining -= charsThisRow;
  33. x = 0;
  34. ++ y;
  35. }
  36. if ( xOut == screenColumns ) { // we have to special-case line wrap
  37. xOut = 0;
  38. ++ yOut;
  39. }
  40. }
  41. /**
  42. * Calculate a column width using mk_wcswidth()
  43. * @param buf32 - text to calculate
  44. * @param len - length of text to calculate
  45. */
  46. int calculate_displayed_length( char32_t const* buf32_, int size_ ) {
  47. int len( 0 );
  48. for ( int i( 0 ); i < size_; ++ i ) {
  49. char32_t c( buf32_[i] );
  50. if ( c == '\033' ) {
  51. int escStart( i );
  52. ++ i;
  53. if ( ( i < size_ ) && ( buf32_[i] != '[' ) ) {
  54. i = escStart;
  55. ++ len;
  56. continue;
  57. }
  58. ++ i;
  59. for ( ; i < size_; ++ i ) {
  60. c = buf32_[i];
  61. if ( ( c != ';' ) && ( ( c < '0' ) || ( c > '9' ) ) ) {
  62. break;
  63. }
  64. }
  65. if ( ( i < size_ ) && ( buf32_[i] == 'm' ) ) {
  66. continue;
  67. }
  68. i = escStart;
  69. len += 2;
  70. } else if ( is_control_code( c ) ) {
  71. len += 2;
  72. } else {
  73. int wcw( mk_wcwidth( c ) );
  74. if ( wcw < 0 ) {
  75. len = -1;
  76. break;
  77. }
  78. len += wcw;
  79. }
  80. }
  81. return ( len );
  82. }
  83. char const* ansi_color( Replxx::Color color_ ) {
  84. static char const reset[] = "\033[0m";
  85. static char const black[] = "\033[0;22;30m";
  86. static char const red[] = "\033[0;22;31m";
  87. static char const green[] = "\033[0;22;32m";
  88. static char const brown[] = "\033[0;22;33m";
  89. static char const blue[] = "\033[0;22;34m";
  90. static char const magenta[] = "\033[0;22;35m";
  91. static char const cyan[] = "\033[0;22;36m";
  92. static char const lightgray[] = "\033[0;22;37m";
  93. #ifdef _WIN32
  94. static bool const has256colorDefault( true );
  95. #else
  96. static bool const has256colorDefault( false );
  97. #endif
  98. static char const* TERM( getenv( "TERM" ) );
  99. static bool const has256color( TERM ? ( strstr( TERM, "256" ) != nullptr ) : has256colorDefault );
  100. static char const* gray = has256color ? "\033[0;1;90m" : "\033[0;1;30m";
  101. static char const* brightred = has256color ? "\033[0;1;91m" : "\033[0;1;31m";
  102. static char const* brightgreen = has256color ? "\033[0;1;92m" : "\033[0;1;32m";
  103. static char const* yellow = has256color ? "\033[0;1;93m" : "\033[0;1;33m";
  104. static char const* brightblue = has256color ? "\033[0;1;94m" : "\033[0;1;34m";
  105. static char const* brightmagenta = has256color ? "\033[0;1;95m" : "\033[0;1;35m";
  106. static char const* brightcyan = has256color ? "\033[0;1;96m" : "\033[0;1;36m";
  107. static char const* white = has256color ? "\033[0;1;97m" : "\033[0;1;37m";
  108. static char const error[] = "\033[101;1;33m";
  109. char const* code( reset );
  110. switch ( color_ ) {
  111. case Replxx::Color::BLACK: code = black; break;
  112. case Replxx::Color::RED: code = red; break;
  113. case Replxx::Color::GREEN: code = green; break;
  114. case Replxx::Color::BROWN: code = brown; break;
  115. case Replxx::Color::BLUE: code = blue; break;
  116. case Replxx::Color::MAGENTA: code = magenta; break;
  117. case Replxx::Color::CYAN: code = cyan; break;
  118. case Replxx::Color::LIGHTGRAY: code = lightgray; break;
  119. case Replxx::Color::GRAY: code = gray; break;
  120. case Replxx::Color::BRIGHTRED: code = brightred; break;
  121. case Replxx::Color::BRIGHTGREEN: code = brightgreen; break;
  122. case Replxx::Color::YELLOW: code = yellow; break;
  123. case Replxx::Color::BRIGHTBLUE: code = brightblue; break;
  124. case Replxx::Color::BRIGHTMAGENTA: code = brightmagenta; break;
  125. case Replxx::Color::BRIGHTCYAN: code = brightcyan; break;
  126. case Replxx::Color::WHITE: code = white; break;
  127. case Replxx::Color::ERROR: code = error; break;
  128. case Replxx::Color::DEFAULT: code = reset; break;
  129. }
  130. return ( code );
  131. }
  132. std::string now_ms_str( void ) {
  133. std::chrono::milliseconds ms( std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch() ) );
  134. time_t t( ms.count() / 1000 );
  135. tm broken;
  136. #ifdef _WIN32
  137. #define localtime_r( t, b ) localtime_s( ( b ), ( t ) )
  138. #endif
  139. localtime_r( &t, &broken );
  140. #undef localtime_r
  141. static int const BUFF_SIZE( 32 );
  142. char str[BUFF_SIZE];
  143. strftime( str, BUFF_SIZE, "%Y-%m-%d %H:%M:%S.", &broken );
  144. snprintf( str + sizeof ( "YYYY-mm-dd HH:MM:SS" ), 5, "%03d", static_cast<int>( ms.count() % 1000 ) );
  145. return ( str );
  146. }
  147. }