Example #1
0
/* After a resize, clear all the lines that were occupied by prompt + line buffer before the resize */
static
void wipe_textarea(struct winsize *old_winsize)
{
    int point, lineheight, linelength, cursor_height, i, promptlength;
    if (!prompt_is_single_line()) {       /* Don't need to do anything in horizontal_scroll_mode  */
        promptlength = colourless_strlen((saved_rl_state.cooked_prompt ? saved_rl_state.cooked_prompt:  saved_rl_state.raw_prompt), NULL, old_winsize -> ws_col);
        linelength = (within_line_edit ? strlen(rl_line_buffer) : 0) + promptlength;
        point = (within_line_edit ? rl_point : 0) + promptlength;
        assert(old_winsize -> ws_col > 0);
        lineheight = (linelength == 0 ? 0 : (1 + (max(point, (linelength - 1)) / old_winsize -> ws_col)));
        if (lineheight > 1 && term_cursor_up != NULL && term_cursor_down != NULL) {
            /* i.e. if we have multiple rows displayed, and we can clean them up first */
            cr();
            cursor_height = point / old_winsize -> ws_col;    /* cursor is still on old line */
            DPRINTF2(DEBUG_SIGNALS, "lineheight: %d, cursor_height: %d", lineheight, cursor_height);
            for (i = 1 + cursor_height; i < lineheight; i++)
                curs_down();    /* ...move it down to last line */
            for (i = lineheight; i > 1; i--) {        /* go up again, erasing every line */
                clear_line();
                curs_up();
            }
        }
        clear_line();
        cr();
    }
}
Example #2
0
int
colourless_strlen_unmarked (const char *str, int termwidth)
{
  char *marked_str = mark_invisible(str);
  int colourless_length = colourless_strlen(marked_str, NULL, termwidth);
  free(marked_str);
  return colourless_length;
}
Example #3
0
static void
my_homegrown_redisplay(int hide_passwords)
{
  static int line_start = 0;    /* at which position of prompt_plus_line does the printed line start? */
  static int line_extends_right = 0;
  static int line_extends_left = 0;
  static char *previous_line = NULL;
  
  
  int width = winsize.ws_col;
  int skip = max(1, min(width / 5, 10));        /* jumpscroll this many positions when cursor reaches edge of terminal */
  
  char *prompt_without_ignore_markers;
  int colourless_promptlen = colourless_strlen(rl_prompt, &prompt_without_ignore_markers,0);
  int promptlen = strlen(prompt_without_ignore_markers);
  int invisible_chars_in_prompt = promptlen - colourless_promptlen;
  char *prompt_plus_line = add2strings(prompt_without_ignore_markers, rl_line_buffer);
  char *new_line;
  int total_length = strlen(prompt_plus_line);
  int curpos = promptlen + rl_point; /* cursor position within prompt_plus_line */
  int i, printed_length,
    new_curpos,                    /* cursor position on screen */
    keep_old_line, vlinestart, printwidth, last_column;
  DPRINTF3(DEBUG_AD_HOC,"rl_prompt: <%s>, prompt_without_ignore_markers: <%s>,  prompt_plus_line: <%s>", rl_prompt, prompt_without_ignore_markers, prompt_plus_line);   

  /* In order to handle prompt with colour we either print the whole prompt, or start past it:
     starting in the middle is too difficult (i.e. I am too lazy) to get it right.
     We use a "virtual line start" vlinestart, which is the number of invisible chars in prompt in the former case, or
     linestart in the latter (which then must be >= strlen(prompt))

     At all times (before redisplay and after) the following is true:
     - the cursor is at column (curpos - vlinestart) (may be < 0 or > width)
     - the character under the cursor is prompt_plus_line[curpos]
     - the character at column 0 is prompt_plus_line[linestart]
     - the last column is at <number of printed visible or invisible chars> - vlinestart
     
     the goal of this function is to display (part of) prompt_plus_line such
     that the cursor is visible again */
     
  
  if (hide_passwords)
    for (i = promptlen; i < total_length; i++)
      prompt_plus_line[i] = '*';        /* hide a pasword by making user input unreadable  */


  if (rl_point == 0)            /* (re)set  at program start and after accept_line (where rl_point is zeroed) */
    line_start = 0;
  assert(line_start == 0 || line_start >= promptlen); /* the line *never* starts in the middle of the prompt (too complicated to handle)*/
  vlinestart = (line_start > promptlen ? line_start : invisible_chars_in_prompt); 
  

  if (curpos - vlinestart > width - line_extends_right) /* cursor falls off right edge ?   */
    vlinestart = (curpos - width + line_extends_right) + skip;  /* jumpscroll left                 */

  else if (curpos < vlinestart + line_extends_left) {   /* cursor falls off left edge ?    */
    if (curpos == total_length) /* .. but still at end of line?    */
      vlinestart = max(0, total_length - width);        /* .. try to display entire line   */
    else                        /* in not at end of line ..        */
      vlinestart = curpos - line_extends_left - skip; /* ... jumpscroll right ..         */
  }     
  if (vlinestart <= invisible_chars_in_prompt) {
    line_start = 0;             /* ... but not past start of line! */
    vlinestart = invisible_chars_in_prompt;
  } else if (vlinestart > invisible_chars_in_prompt && vlinestart <= promptlen) {
    line_start = vlinestart = promptlen;
  } else {
    line_start = vlinestart;
  }

  printwidth = (line_start > 0 ? width : width + invisible_chars_in_prompt);
  printed_length = min(printwidth, total_length - line_start);  /* never print more than width     */
  last_column = printed_length - vlinestart;


  /* some invariants :     0 <= line_start <= curpos <= line_start + printed_length <= total_length */
  /* these are interesting:   ^                                                      ^              */

  assert(0 <= line_start);
  assert(line_start <= curpos);
  assert(curpos <= line_start + printed_length);        /* <=, rather than <, as cursor may be past eol   */
  assert(line_start + printed_length <= total_length);


  new_line = prompt_plus_line + line_start;
  new_line[printed_length] = '\0';
  new_curpos = curpos - vlinestart;

  /* indicate whether line extends past right or left edge  (i.e. whether the "interesting
     inequalities marked ^ above are really unequal) */

  line_extends_left = (line_start > 0 ? 1 : 0);
  line_extends_right = (total_length - vlinestart > width ? 1 : 0);
  if (line_extends_left)
    new_line[0] = '<';
  if (line_extends_right)
    new_line[printwidth - 1] = '>';

  

  keep_old_line = FALSE;
  if (term_cursor_hpos) {
    if (previous_line && strcmp(new_line, previous_line) == 0) {
      keep_old_line = TRUE;
    } else {
      if (previous_line)
        free(previous_line);
      previous_line = mysavestring(new_line);
    }
  }
  /* DPRINTF2(DEBUG_AD_HOC, "keep_old_line=%d, new_line=<%s>", keep_old_line, new_line); */
  /* keep_old_line = TRUE; */
  if (!keep_old_line) {
    clear_line();
    cr();
    write_patiently(STDOUT_FILENO, new_line, printed_length, "to stdout");
  }
  
  assert(term_cursor_hpos || !keep_old_line);   /* if we cannot position cursor, we must have reprinted ... */

  if (term_cursor_hpos)
    cursor_hpos(new_curpos);
  else                          /* ... so we know we're 1 past last position on line */
    backspace(last_column - new_curpos);
  free(prompt_plus_line);
  free(prompt_without_ignore_markers);
}