[RFC] vim-patch: Multiple small patches (2)

These patches have nothing in common, but I thought that since they're so small, the PR/merge overhead would be smaller if they were reviewed together (*Edit:* I thought that merging other vim-patch PRs would trigger Github merge errors in version.c, but apparently that's not the case). I have these in separate branches, so it would be no problem to split this into multiple PRs, if you think that's better.

(version.c diffs removed from original patches below for brevity)

### 499

```diff
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -25076,6 +25076,7 @@ do_string_sub(str, pat, sub, flags)
     int		i;
     int		do_all;
     char_u	*tail;
+    char_u	*end;
     garray_T	ga;
     char_u	*ret;
     char_u	*save_cpo;
@@ -25094,6 +25095,7 @@ do_string_sub(str, pat, sub, flags)
     if (regmatch.regprog != NULL)
     {
 	tail = str;
+	end = str + STRLEN(str);
 	while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
 	{
 	    /* Skip empty match except for first match. */
@@ -25120,7 +25122,7 @@ do_string_sub(str, pat, sub, flags)
 	     * - The text after the match.
 	     */
 	    sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
-	    if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
+	    if (ga_grow(&ga, (int)((end - tail) + sublen -
 			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
 	    {
 		ga_clear(&ga);
```

### 494

```diff
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -9526,8 +9526,15 @@ ex_normal(eap)
     msg_didout |= save_msg_didout;	/* don't reset msg_didout now */
 
     /* Restore the state (needed when called from a function executed for
-     * 'indentexpr'). */
+     * 'indentexpr'). Update the mouse and cursor, they may have changed. */
     State = save_State;
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+
 #ifdef FEAT_MBYTE
     vim_free(arg);
 #endif
```

### 493

```diff
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -4877,6 +4877,13 @@ restore_backup:
 	    )
     {
 	unchanged(buf, TRUE);
+#ifdef FEAT_AUTOCMD
+	/* buf->b_changedtick is always incremented in unchanged() but that
+	 * should not trigger a TextChanged event. */
+	if (last_changedtick + 1 == buf->b_changedtick
+					       && last_changedtick_buf == buf)
+	    last_changedtick = buf->b_changedtick;
+#endif
 	u_unchanged(buf);
 	u_update_save_nr(buf);
     }
```

### 491

```diff
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -19576,7 +19576,7 @@ f_winrestview(argvars, rettv)
 # endif
 	changed_window_setting();
 
-	if (curwin->w_topline == 0)
+	if (curwin->w_topline <= 0)
 	    curwin->w_topline = 1;
 	if (curwin->w_topline > curbuf->b_ml.ml_line_count)
 	    curwin->w_topline = curbuf->b_ml.ml_line_count;
```

### 489

```diff
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1184,6 +1184,8 @@ win_lbr_chartabsize(wp, line, s, col, he
 	{
 	    col -= W_WIDTH(wp);
 	    numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
+	    if (numberextra > 0)
+		col %= numberextra;
 	    if (*p_sbr != NUL)
 	    {
 		colnr_T sbrlen = (colnr_T)MB_CHARLEN(p_sbr);
```

### 477

```diff
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -2325,7 +2325,7 @@ ex_diffgetput(eap)
 		    end_skip = 0;
 	    }
 
-	    buf_empty = FALSE;
+	    buf_empty = bufempty();
 	    added = 0;
 	    for (i = 0; i < count; ++i)
 	    {
```

### 474

```diff
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -4407,7 +4407,6 @@ skip_add:
     switch (state->c)
     {
 	case NFA_MATCH:
-//	    nfa_match = TRUE;
 	    break;
 
 	case NFA_SPLIT:
```
AFAIK we still need `setmouse()` calls in the same places as Vim.