Repository: neovim/neovim
File: src/nvim/edit.c (C)

Code before:
{
  return buf_prompt_text(curbuf);
}

void buf_update_prompt_text(buf_T *buf, const char *new_prompt)
{
  if (buf->b_p_bt[0] != 'p') {
    // buftype not set as prompt. skip the special stuff cause we'll create
    // a new prompt anyway once bt=prompt is set
    goto theend;
  }

  if (buf->b_prompt_start.mark.lnum > buf->b_ml.ml_line_count) {
    // in case the where the mark is set the line doesn't exist
    buf->b_prompt_start.mark.lnum = buf->b_ml.ml_line_count;
  }

  linenr_T prompt_lno = buf->b_prompt_start.mark.lnum;
  char *old_prompt = buf->b_prompt_text != NULL ? buf->b_prompt_text : "";
  char *old_line = ml_get_buf(buf, prompt_lno);
  new_prompt = new_prompt != NULL ? new_prompt : "";
  old_line = old_line != NULL ? old_line : "";

  int old_prompt_len = (int)strlen(old_prompt);
  int new_prompt_len = (int)strlen(new_prompt);
  int old_line_len = (int)strlen(old_line);

  if (buf->b_prompt_start.mark.col < old_prompt_len
      || old_line_len < curbuf->b_prompt_start.mark.col
      || strncmp(old_line + curbuf->b_prompt_start.mark.col - old_prompt_len, old_prompt,
                 (size_t)old_prompt_len) != 0) {
    // in case if for some odd reason the old prompt is missing
    // replace the prompt line
    ml_replace_buf(buf, prompt_lno, (char *)new_prompt, true, false);
    if (curwin->w_buffer == buf) {
      coladvance(curwin, (colnr_T)new_prompt_len);
    }
  } else {
    char *new_line = concat_str(new_prompt, old_line + buf->b_prompt_start.mark.col);
    ml_replace_buf(buf, prompt_lno, new_line, false, false);
    if (curwin->w_buffer == buf) {
      coladvance(curwin, (colnr_T)((int)curwin->w_cursor.col + new_prompt_len - old_prompt_len));
    }
  }

  changed_lines_redraw_buf(buf, prompt_lno, prompt_lno + 1, 0);
  buf->b_prompt_start.mark.col = (colnr_T)new_prompt_len;

theend:
  // clear old prompt text and replace with the new one
  xfree(buf->b_prompt_text);

Review comment (suggestion):
to avoid analyzer warnings, should we assert after these casts?

```
assert(old_prompt_len > 0);
...
```

Code after:
{
  return buf_prompt_text(curbuf);
}

// Prepare for prompt mode: Make sure the last line has the prompt text.
// Move the cursor to this line.
static void init_prompt(int cmdchar_todo)
{
  char *prompt = prompt_text();
  int prompt_len = (int)strlen(prompt);

  if (curwin->w_cursor.lnum < curbuf->b_prompt_start.mark.lnum) {
    curwin->w_cursor.lnum = curbuf->b_prompt_start.mark.lnum;
  }
  char *text = ml_get(curbuf->b_prompt_start.mark.lnum);
  if ((curbuf->b_prompt_start.mark.lnum == curwin->w_cursor.lnum
       && (curbuf->b_prompt_start.mark.col < prompt_len
           || !strnequal(text + curbuf->b_prompt_start.mark.col - prompt_len, prompt,
                         (size_t)prompt_len)))) {
    // prompt is missing, insert it or append a line with it
    if (*text == NUL) {
      ml_replace(curbuf->b_prompt_start.mark.lnum, prompt, true);
    } else {
      ml_append(curbuf->b_ml.ml_line_count, prompt, 0, false);
      curbuf->b_prompt_start.mark.lnum = curbuf->b_ml.ml_line_count;
    }
    curbuf->b_prompt_start.mark.col = prompt_len;
    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
    coladvance(curwin, MAXCOL);
    inserted_bytes(curbuf->b_ml.ml_line_count, 0, 0, (colnr_T)prompt_len);
  }

  // Insert always starts after the prompt, allow editing text after it.
  if (Insstart_orig.lnum != curbuf->b_prompt_start.mark.lnum
      || Insstart_orig.col != curbuf->b_prompt_start.mark.col) {
    Insstart.lnum = curbuf->b_prompt_start.mark.lnum;
    Insstart.col = curbuf->b_prompt_start.mark.col;
    Insstart_orig = Insstart;
    Insstart_textlen = Insstart.col;
    Insstart_blank_vcol = MAXCOL;
    arrow_used = false;
  }

  if (cmdchar_todo == 'A') {
    coladvance(curwin, MAXCOL);
  }
  if (curbuf->b_prompt_start.mark.lnum == curwin->w_cursor.lnum) {
    curwin->w_cursor.col = MAX(curwin->w_cursor.col, curbuf->b_prompt_start.mark.col);
  }
  // Make sure the cursor is in a valid position.
  check_cursor(curwin);