static void refreshLine(const char *prompt, struct current *current) { int plen; int pchars; int backup = 0; int i; const char *buf = current->buf; int chars = current->chars; int pos = current->pos; int b; int ch; int n; int width; int bufwidth; /* Should intercept SIGWINCH. For now, just get the size every time */ getWindowSize(current); plen = strlen(prompt); pchars = utf8_strwidth(prompt, utf8_strlen(prompt, plen)); /* Scan the prompt for embedded ansi color control sequences and * discount them as characters/columns. */ pchars -= countColorControlChars(prompt); /* Account for a line which is too long to fit in the window. * Note that control chars require an extra column */ /* How many cols are required to the left of 'pos'? * The prompt, plus one extra for each control char */ n = pchars + utf8_strwidth(buf, utf8_strlen(buf, current->len)); b = 0; for (i = 0; i < pos; i++) { b += utf8_tounicode(buf + b, &ch); if (ch < ' ') { n++; } } /* Pluse one if the current char is a control character */ if (current->pos < current->chars && get_char(current, current->pos) < ' ') { n++; } /* If too many are needed, strip chars off the front of 'buf' * until it fits. Note that if the current char is a control character, * we need one extra col. */ while (n >= current->cols && pos > 0) { b = utf8_tounicode(buf, &ch); if (ch < ' ') { n--; } n -= utf8_width(ch); buf += b; pos--; chars--; } /* Cursor to left edge, then the prompt */ cursorToLeft(current); outputChars(current, prompt, plen); /* Now the current buffer content */ /* Need special handling for control characters. * If we hit 'cols', stop. */ b = 0; /* unwritted bytes */ n = 0; /* How many control chars were written */ width = 0; /* current display width */ bufwidth = utf8_strwidth(buf, pos); for (i = 0; i < chars; i++) { int ch; int w = utf8_tounicode(buf + b, &ch); if (ch < ' ') { n++; } width += utf8_width(ch); if (pchars + width + n >= current->cols) { break; } if (ch < ' ') { /* A control character, so write the buffer so far */ outputChars(current, buf, b); buf += b + w; b = 0; outputControlChar(current, ch + '@'); if (i < pos) { backup++; } } else { b += w; } } outputChars(current, buf, b); /* Erase to right, move cursor to original position */ eraseEol(current); setCursorPos(current, bufwidth + pchars + backup); }
static void refreshLine(const char *prompt, struct current *current) { int plen; int pchars; int backup = 0; int i; const char *buf = current->buf; int chars = current->chars; int pos = current->pos; int b; int ch; int n; /* Should intercept SIGWINCH. For now, just get the size every time */ getWindowSize(current); plen = strlen(prompt); pchars = utf8_strlen(prompt, plen); /* Scan the prompt for embedded ansi color control sequences and * discount them as characters/columns. */ pchars -= countColorControlChars(prompt); /* Account for a line which is too long to fit in the window. * Note that control chars require an extra column */ /* How many cols are required to the left of 'pos'? * The prompt, plus one extra for each control char */ n = pchars + utf8_strlen(buf, current->len); b = 0; for (i = 0; i < pos; i++) { b += utf8_tounicode(buf + b, &ch); if (ch < ' ') { n++; } } /* If too many are needed, strip chars off the front of 'buf' * until it fits. Note that if the current char is a control character, * we need one extra col. */ if (current->pos < current->chars && get_char(current, current->pos) < ' ') { n++; } while (n >= current->cols && pos > 0) { b = utf8_tounicode(buf, &ch); if (ch < ' ') { n--; } n--; buf += b; pos--; chars--; } /* Cursor to left edge, then the prompt */ cursorToLeft(current); outputChars(current, prompt, plen); /* Now the current buffer content, but only if not fully hidden */ if (is_hidden != LN_HIDDEN_ALL) { /* Need special handling for control characters. * If we hit 'cols', stop. */ b = 0; /* unwritted bytes */ n = 0; /* How many control chars were written */ for (i = 0; i < chars; i++) { int ch; int w = utf8_tounicode(buf + b, &ch); if (!is_hidden && ch < ' ') { n++; } if (pchars + i + n >= current->cols) { break; } if (is_hidden == LN_HIDDEN_STAR) { /* In hidden/star mode all user-entered characters are * shown as astericks ('*'). This is like control chars, * except for a different translation. */ /* assert (b == 0) */ outputChars(current, "*", 1); buf += w; /* keep b = 0; */ } else if (ch < ' ') { /* A control character, so write the buffer so far */ outputChars(current, buf, b); buf += b + w; b = 0; outputControlChar(current, ch + '@'); if (i < pos) { backup++; } } else { b += w; } } /* if (is_hidden) assert (b==0) */ outputChars(current, buf, b); /* Erase to right, move cursor to original position */ eraseEol(current); setCursorPos(current, pos + pchars + backup); } }