/// Set the pen color for the terminal. static void s_set_color(screen_t *s, data_buffer_t *b, highlight_spec_t c) { scoped_buffer_t scoped_buffer(b); //!OCLINT(has side effects) unsigned int uc = (unsigned int)c; set_color(highlight_get_color(uc & 0xffff, false), highlight_get_color((uc >> 16) & 0xffff, true)); }
/** Convert a wide string to a multibyte string and append it to the buffer. Returns the width. */ static int s_write_string( screen_t *s, data_buffer_t *b, const wcstring &str ) { scoped_buffer_t scoped_buffer(b); int width = fish_wcswidth(str.c_str(), str.size()); writestr(str.c_str()); s->actual.cursor.x += width; return width; }
/** Set the pen color for the terminal */ static void s_set_color( screen_t *s, data_buffer_t *b, int c ) { scoped_buffer_t scoped_buffer(b); unsigned int uc = (unsigned int)c; set_color( highlight_get_color( uc & 0xffff, false ), highlight_get_color( (uc>>16)&0xffff, true ) ); }
static bool test_stuff(screen_t *scr) { data_buffer_t output; scoped_buffer_t scoped_buffer(&output); s_move(scr, &output, 0, 0); int screen_width = common_get_width(); const wchar_t *left = L"left"; const wchar_t *right = L"right"; for (size_t idx = 0; idx < 80; idx++) { output.push_back('A'); } if (! output.empty()) { write_loop(STDOUT_FILENO, &output.at(0), output.size()); output.clear(); } sleep(5); for (size_t i=0; i < 1; i++) { writembs(cursor_left); } if (! output.empty()) { write_loop(1, &output.at(0), output.size()); output.clear(); } while (1) { int c = getchar(); if (c != EOF) break; } while (1) { int c = getchar(); if (c != EOF) break; } puts("Bye"); exit(0); while (1) sleep(10000); return true; }
/// Convert a wide character to a multibyte string and append it to the buffer. static void s_write_char(screen_t *s, data_buffer_t *b, wchar_t c) { scoped_buffer_t scoped_buffer(b); //!OCLINT(has side effects) s->actual.cursor.x += fish_wcwidth_min_0(c); writech(c); if (s->actual.cursor.x == s->actual_width && allow_soft_wrap()) { s->soft_wrap_location.x = 0; s->soft_wrap_location.y = s->actual.cursor.y + 1; // Note that our cursor position may be a lie: Apple Terminal makes the right cursor stick // to the margin, while Ubuntu makes it "go off the end" (but still doesn't wrap). We rely // on s_move to fix this up. } else { invalidate_soft_wrap(s); } }
/** Convert a wide string to a multibyte string and append it to the buffer. */ static void s_write_str( data_buffer_t *b, const wchar_t *s ) { scoped_buffer_t scoped_buffer(b); writestr( s ); }
/** Send the specified string through tputs and append the output to the specified buffer. */ static void s_write_mbs( data_buffer_t *b, char *s ) { scoped_buffer_t scoped_buffer(b); writembs( s ); }
/** Convert a wide character to a multibyte string and append it to the buffer. */ static void s_write_char( screen_t *s, data_buffer_t *b, wchar_t c ) { scoped_buffer_t scoped_buffer(b); s->actual.cursor.x+=fish_wcwidth( c ); writech( c ); }
/** Write the bytes needed to move screen cursor to the specified position to the specified buffer. The actual_cursor field of the specified screen_t will be updated. \param s the screen to operate on \param b the buffer to send the output escape codes to \param new_x the new x position \param new_y the new y position */ static void s_move( screen_t *s, data_buffer_t *b, int new_x, int new_y ) { int i; int x_steps, y_steps; char *str; /* debug( 0, L"move from %d %d to %d %d", s->screen_cursor[0], s->screen_cursor[1], new_x, new_y ); */ scoped_buffer_t scoped_buffer(b); y_steps = new_y - s->actual.cursor.y; if( y_steps > 0 && (strcmp( cursor_down, "\n")==0)) { /* This is very strange - it seems some (all?) consoles use a simple newline as the cursor down escape. This will of course move the cursor to the beginning of the line as well as moving it down one step. The cursor_up does not have this behaviour... */ s->actual.cursor.x=0; } if( y_steps < 0 ) { str = cursor_up; } else { str = cursor_down; } for( i=0; i<abs(y_steps); i++) { writembs(str); } x_steps = new_x - s->actual.cursor.x; if( x_steps && new_x == 0 ) { b->push_back('\r'); x_steps = 0; } if( x_steps < 0 ) { str = cursor_left; } else { str = cursor_right; } for( i=0; i<abs(x_steps); i++) { writembs(str); } s->actual.cursor.x = new_x; s->actual.cursor.y = new_y; }
/// Convert a wide string to a multibyte string and append it to the buffer. static void s_write_str(data_buffer_t *b, const wchar_t *s) { scoped_buffer_t scoped_buffer(b); //!OCLINT(has side effects) writestr(s); }
/// Send the specified string through tputs and append the output to the specified buffer. static void s_write_mbs(data_buffer_t *b, char *s) { scoped_buffer_t scoped_buffer(b); //!OCLINT(has side effects) writembs(s); }
/// Write the bytes needed to move screen cursor to the specified position to the specified buffer. /// The actual_cursor field of the specified screen_t will be updated. /// /// \param s the screen to operate on /// \param b the buffer to send the output escape codes to /// \param new_x the new x position /// \param new_y the new y position static void s_move(screen_t *s, data_buffer_t *b, int new_x, int new_y) { if (s->actual.cursor.x == new_x && s->actual.cursor.y == new_y) return; // If we are at the end of our window, then either the cursor stuck to the edge or it didn't. We // don't know! We can fix it up though. if (s->actual.cursor.x == common_get_width()) { // Either issue a cr to go back to the beginning of this line, or a nl to go to the // beginning of the next one, depending on what we think is more efficient. if (new_y <= s->actual.cursor.y) { b->push_back('\r'); } else { b->push_back('\n'); s->actual.cursor.y++; } // Either way we're not in the first column. s->actual.cursor.x = 0; } int i; int x_steps, y_steps; char *str; /* debug( 0, L"move from %d %d to %d %d", s->screen_cursor[0], s->screen_cursor[1], new_x, new_y ); */ scoped_buffer_t scoped_buffer(b); //!OCLINT(has side effects) y_steps = new_y - s->actual.cursor.y; if (y_steps > 0 && (strcmp(cursor_down, "\n") == 0)) { // This is very strange - it seems some (all?) consoles use a simple newline as the cursor // down escape. This will of course move the cursor to the beginning of the line as well as // moving it down one step. The cursor_up does not have this behaviour... s->actual.cursor.x = 0; } if (y_steps < 0) { str = cursor_up; } else { str = cursor_down; } for (i = 0; i < abs(y_steps); i++) { writembs(str); } x_steps = new_x - s->actual.cursor.x; if (x_steps && new_x == 0) { b->push_back('\r'); x_steps = 0; } char *multi_str = NULL; if (x_steps < 0) { str = cursor_left; multi_str = parm_left_cursor; } else { str = cursor_right; multi_str = parm_right_cursor; } // Use the bulk ('multi') output for cursor movement if it is supported and it would be shorter // Note that this is required to avoid some visual glitches in iTerm (issue #1448). bool use_multi = multi_str != NULL && multi_str[0] != '\0' && abs(x_steps) * strlen(str) > strlen(multi_str); if (use_multi) { char *multi_param = tparm(multi_str, abs(x_steps)); writembs(multi_param); } else { for (i = 0; i < abs(x_steps); i++) { writembs(str); } } s->actual.cursor.x = new_x; s->actual.cursor.y = new_y; }
/** Write the bytes needed to move screen cursor to the specified position to the specified buffer. The actual_cursor field of the specified screen_t will be updated. \param s the screen to operate on \param b the buffer to send the output escape codes to \param new_x the new x position \param new_y the new y position */ static void s_move(screen_t *s, data_buffer_t *b, int new_x, int new_y) { if (s->actual.cursor.x == new_x && s->actual.cursor.y == new_y) return; // If we are at the end of our window, then either the cursor stuck to the edge or it didn't. We don't know! We can fix it up though. if (s->actual.cursor.x == common_get_width()) { // Either issue a cr to go back to the beginning of this line, or a nl to go to the beginning of the next one, depending on what we think is more efficient if (new_y <= s->actual.cursor.y) { b->push_back('\r'); } else { b->push_back('\n'); s->actual.cursor.y++; } // Either way we're not in the first column s->actual.cursor.x = 0; } int i; int x_steps, y_steps; char *str; /* debug( 0, L"move from %d %d to %d %d", s->screen_cursor[0], s->screen_cursor[1], new_x, new_y ); */ scoped_buffer_t scoped_buffer(b); y_steps = new_y - s->actual.cursor.y; if (y_steps > 0 && (strcmp(cursor_down, "\n")==0)) { /* This is very strange - it seems some (all?) consoles use a simple newline as the cursor down escape. This will of course move the cursor to the beginning of the line as well as moving it down one step. The cursor_up does not have this behaviour... */ s->actual.cursor.x=0; } if (y_steps < 0) { str = cursor_up; } else { str = cursor_down; } for (i=0; i<abs(y_steps); i++) { writembs(str); } x_steps = new_x - s->actual.cursor.x; if (x_steps && new_x == 0) { b->push_back('\r'); x_steps = 0; } if (x_steps < 0) { str = cursor_left; } else { str = cursor_right; } for (i=0; i<abs(x_steps); i++) { writembs(str); } s->actual.cursor.x = new_x; s->actual.cursor.y = new_y; }