patch 9.0.0656: cannot specify another character to use instead of '@'

Problem:    Cannot specify another character to use instead of '@' at the end
            of the window.
Solution:   Add "lastline" to 'fillchars'. (Martin Tournoij, closes #11264,
            closes #10963)
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index a0098a7..b3c4a40 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -2956,6 +2956,9 @@
 	When neither "lastline" nor "truncate" is included, a last line that
 	doesn't fit is replaced with "@" lines.
 
+	The "@" character can be changed by setting the "lastline" item in
+	'fillchars'.  The character is highlighted with |hl-NonText|.
+
 						*'eadirection'* *'ead'*
 'eadirection' 'ead'	string	(default "both")
 			global
@@ -3420,6 +3423,7 @@
 	  foldsep	'|'		open fold middle character
 	  diff		'-'		deleted lines of the 'diff' option
 	  eob		'~'		empty lines below the end of a buffer
+	  lastline	'@'		'display' contains lastline/truncate
 
 	Any one that is omitted will fall back to the default.  For "stl" and
 	"stlnc" the space will be used when there is highlighting, '^' or '='
@@ -3442,6 +3446,7 @@
 	  fold		Folded			|hl-Folded|
 	  diff		DiffDelete		|hl-DiffDelete|
 	  eob		EndOfBuffer		|hl-EndOfBuffer|
+	  lastline	NonText			|hl-NonText|
 
 		*'fixendofline'* *'fixeol'* *'nofixendofline'* *'nofixeol'*
 'fixendofline' 'fixeol'	boolean	(default on)
diff --git a/src/drawscreen.c b/src/drawscreen.c
index fa5d668..4735492 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -2643,33 +2643,42 @@
 #endif
 	else if (dy_flags & DY_TRUNCATE)	// 'display' has "truncate"
 	{
-	    int scr_row = W_WINROW(wp) + wp->w_height - 1;
+	    int		scr_row = W_WINROW(wp) + wp->w_height - 1;
+	    int		symbol  = wp->w_fill_chars.lastline;
+	    int		len;
+	    char_u	fillbuf[12];  // 2 characters of 6 bytes
+
+	    len =  mb_char2bytes(symbol, &fillbuf[0]);
+	    len += mb_char2bytes(symbol, &fillbuf[len]);
 
 	    // Last line isn't finished: Display "@@@" in the last screen line.
-	    screen_puts_len((char_u *)"@@", wp->w_width > 2 ? 2 : wp->w_width,
-				       scr_row, wp->w_wincol, HL_ATTR(HLF_AT));
+	    screen_puts_len(fillbuf,
+			    wp->w_width > 2 ? len : wp->w_width,
+			    scr_row, wp->w_wincol, HL_ATTR(HLF_AT));
 	    screen_fill(scr_row, scr_row + 1,
 		    (int)wp->w_wincol + 2, (int)W_ENDCOL(wp),
-		    '@', ' ', HL_ATTR(HLF_AT));
+		    symbol, ' ', HL_ATTR(HLF_AT));
 	    set_empty_rows(wp, srow);
 	    wp->w_botline = lnum;
 	}
 	else if (dy_flags & DY_LASTLINE)	// 'display' has "lastline"
 	{
 	    int start_col = (int)W_ENDCOL(wp) - 3;
+	    int symbol    = wp->w_fill_chars.lastline;
 
 	    // Last line isn't finished: Display "@@@" at the end.
 	    screen_fill(W_WINROW(wp) + wp->w_height - 1,
 		    W_WINROW(wp) + wp->w_height,
 		    start_col < wp->w_wincol ? wp->w_wincol : start_col,
 		    (int)W_ENDCOL(wp),
-		    '@', '@', HL_ATTR(HLF_AT));
+		    symbol, symbol, HL_ATTR(HLF_AT));
 	    set_empty_rows(wp, srow);
 	    wp->w_botline = lnum;
 	}
 	else
 	{
-	    win_draw_end(wp, '@', ' ', TRUE, srow, wp->w_height, HLF_AT);
+	    win_draw_end(wp, wp->w_fill_chars.lastline, ' ', TRUE,
+						   srow, wp->w_height, HLF_AT);
 	    wp->w_botline = lnum;
 	}
     }
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 2ce3ec3..8a122ba 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -936,7 +936,8 @@
 			    SCTX_INIT},
     {"fillchars",   "fcs",  P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP,
 			    (char_u *)&p_fcs, PV_FCS,
-			    {(char_u *)"vert:|,fold:-,eob:~", (char_u *)0L}
+			    {(char_u *)"vert:|,fold:-,eob:~,lastline:@",
+								  (char_u *)0L}
 			    SCTX_INIT},
     {"fixendofline",  "fixeol", P_BOOL|P_VI_DEF|P_RSTAT,
 			    (char_u *)&p_fixeol, PV_FIXEOL,
diff --git a/src/screen.c b/src/screen.c
index ebb5ffc..e5fd4bf 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2511,7 +2511,7 @@
 		    else
 			force_next = FALSE;
 		}
-#endif
+#endif // FEAT_GUI || defined(UNIX)
 		ScreenLines[off] = c;
 		if (enc_utf8)
 		{
@@ -4943,6 +4943,7 @@
 	{&fill_chars.foldsep,	"foldsep"},
 	{&fill_chars.diff,	"diff"},
 	{&fill_chars.eob,	"eob"},
+	{&fill_chars.lastline,	"lastline"},
     };
 
     static lcs_chars_T lcs_chars;
@@ -5022,6 +5023,7 @@
 		fill_chars.foldsep = '|';
 		fill_chars.diff = '-';
 		fill_chars.eob = '~';
+		fill_chars.lastline = '@';
 	    }
 	}
 	p = value;
diff --git a/src/structs.h b/src/structs.h
index d68468c..686aa8f 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3519,6 +3519,7 @@
     int	foldsep;
     int	diff;
     int	eob;
+    int	lastline;
 } fill_chars_T;
 
 /*
diff --git a/src/testdir/dumps/Test_display_lastline_1.dump b/src/testdir/dumps/Test_display_lastline_1.dump
index b0e34ea..d074773 100644
--- a/src/testdir/dumps/Test_display_lastline_1.dump
+++ b/src/testdir/dumps/Test_display_lastline_1.dump
@@ -1,10 +1,10 @@
 >a+0&#ffffff0||+1&&|a+0&&@2| @69
 |a||+1&&|b+0&&@72
-|a||+1&&|b+0&&@26| @45
+|a||+1&&|b+0&&@72
+@1||+1&&|b+0&&@53| @18
 |b||+1&&|~+0#4040ff13&| @71
 |b+0#0000000&||+1&&|~+0#4040ff13&| @71
 |b+0#0000000&||+1&&|~+0#4040ff13&| @71
-|b+0#0000000&||+1&&|~+0#4040ff13&| @71
 |@||+1#0000000&|~+0#4040ff13&| @71
 |<+3#0000000&| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @41|1|,|1| @11|A|l@1
 | +0&&@74
diff --git a/src/testdir/dumps/Test_display_lastline_2.dump b/src/testdir/dumps/Test_display_lastline_2.dump
index 2bd3309..065e5d8 100644
--- a/src/testdir/dumps/Test_display_lastline_2.dump
+++ b/src/testdir/dumps/Test_display_lastline_2.dump
@@ -1,10 +1,10 @@
 >a+0&#ffffff0||+1&&|a+0&&@2| @69
 |a||+1&&|b+0&&@72
-|a||+1&&|b+0&&@26| @45
+|a||+1&&|b+0&&@72
+@1||+1&&|b+0&&@53| @18
 |b||+1&&|~+0#4040ff13&| @71
 |b+0#0000000&||+1&&|~+0#4040ff13&| @71
 |b+0#0000000&||+1&&|~+0#4040ff13&| @71
-|b+0#0000000&||+1&&|~+0#4040ff13&| @71
 |@||+1#0000000&|~+0#4040ff13&| @71
 |<+3#0000000&| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @41|1|,|1| @11|A|l@1
 |:+0&&|s|e|t| |d|i|s|p|l|a|y|=|l|a|s|t|l|i|n|e| @53
diff --git a/src/testdir/dumps/Test_display_lastline_3.dump b/src/testdir/dumps/Test_display_lastline_3.dump
index a0b6e09..38673ab 100644
--- a/src/testdir/dumps/Test_display_lastline_3.dump
+++ b/src/testdir/dumps/Test_display_lastline_3.dump
@@ -1,7 +1,7 @@
 >a+0&#ffffff0@2| @69||+1&&|a+0&&
 |b@72||+1&&|a+0&&
-|b@26| @45||+1&&|a+0&&
-|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|b@72||+1&&|a+0&&
+|b@53| @18||+1&&|b+0&&
 |~+0#4040ff13&| @71||+1#0000000&|b+0&&
 |~+0#4040ff13&| @71||+1#0000000&|b+0&&
 |~+0#4040ff13&| @71||+1#0000000&|b+0&&
diff --git a/src/testdir/dumps/Test_display_lastline_4.dump b/src/testdir/dumps/Test_display_lastline_4.dump
index e34e7c7..2978631 100644
--- a/src/testdir/dumps/Test_display_lastline_4.dump
+++ b/src/testdir/dumps/Test_display_lastline_4.dump
@@ -1,7 +1,7 @@
 >a+0&#ffffff0@2| @69||+1&&|a+0&&
 |b@72||+1&&|a+0&&
-|b@26| @45||+1&&|a+0&&
-|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|b@72||+1&&|a+0&&
+|b@53| @18||+1&&|b+0&&
 |~+0#4040ff13&| @71||+1#0000000&|b+0&&
 |~+0#4040ff13&| @71||+1#0000000&|b+0&&
 |~+0#4040ff13&| @71||+1#0000000&|b+0&&
diff --git a/src/testdir/dumps/Test_display_lastline_5.dump b/src/testdir/dumps/Test_display_lastline_5.dump
new file mode 100644
index 0000000..7567da1
--- /dev/null
+++ b/src/testdir/dumps/Test_display_lastline_5.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0@2| @71
+|b@74
+|@+0#4040ff13&@2| @71
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1|,|1| @11|T|o|p
+|a+0&&@2| @71
+|b@74
+@75
+@50| @24
+|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|1|,|1| @11|A|l@1
+|:+0&&|3|s|p|l|i|t| @67
diff --git a/src/testdir/dumps/Test_display_lastline_euro_1.dump b/src/testdir/dumps/Test_display_lastline_euro_1.dump
new file mode 100644
index 0000000..2223d87
--- /dev/null
+++ b/src/testdir/dumps/Test_display_lastline_euro_1.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0||+1&&|a+0&&@2| @69
+|a||+1&&|b+0&&@72
+|a||+1&&|b+0&&@72
+@1||+1&&|b+0&&@53| @18
+|b||+1&&|~+0#4040ff13&| @71
+|b+0#0000000&||+1&&|~+0#4040ff13&| @71
+|b+0#0000000&||+1&&|~+0#4040ff13&| @71
+|€||+1#0000000&|~+0#4040ff13&| @71
+|<+3#0000000&| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @41|1|,|1| @11|A|l@1
+| +0&&@74
diff --git a/src/testdir/dumps/Test_display_lastline_euro_2.dump b/src/testdir/dumps/Test_display_lastline_euro_2.dump
new file mode 100644
index 0000000..e8da202
--- /dev/null
+++ b/src/testdir/dumps/Test_display_lastline_euro_2.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0||+1&&|a+0&&@2| @69
+|a||+1&&|b+0&&@72
+|a||+1&&|b+0&&@72
+@1||+1&&|b+0&&@53| @18
+|b||+1&&|~+0#4040ff13&| @71
+|b+0#0000000&||+1&&|~+0#4040ff13&| @71
+|b+0#0000000&||+1&&|~+0#4040ff13&| @71
+|€||+1#0000000&|~+0#4040ff13&| @71
+|<+3#0000000&| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @41|1|,|1| @11|A|l@1
+|:+0&&|s|e|t| |d|i|s|p|l|a|y|=|l|a|s|t|l|i|n|e| @53
diff --git a/src/testdir/dumps/Test_display_lastline_euro_3.dump b/src/testdir/dumps/Test_display_lastline_euro_3.dump
new file mode 100644
index 0000000..db414e7
--- /dev/null
+++ b/src/testdir/dumps/Test_display_lastline_euro_3.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0@2| @69||+1&&|a+0&&
+|b@72||+1&&|a+0&&
+|b@72||+1&&|a+0&&
+|b@53| @18||+1&&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|€+0#4040ff13&
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @41|1|,|1| @11|A|l@1| |<+1&&
+|:+0&&|1|0@1|w|i|n|c|m|d| |>| @62
diff --git a/src/testdir/dumps/Test_display_lastline_euro_4.dump b/src/testdir/dumps/Test_display_lastline_euro_4.dump
new file mode 100644
index 0000000..492438c
--- /dev/null
+++ b/src/testdir/dumps/Test_display_lastline_euro_4.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0@2| @69||+1&&|a+0&&
+|b@72||+1&&|a+0&&
+|b@72||+1&&|a+0&&
+|b@53| @18||+1&&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|b+0&&
+|~+0#4040ff13&| @71||+1#0000000&|€+0#4040ff13&
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @41|1|,|1| @11|A|l@1| |<+1&&
+|:+0&&|s|e|t| |d|i|s|p|l|a|y|=|t|r|u|n|c|a|t|e| @53
diff --git a/src/testdir/dumps/Test_display_lastline_euro_5.dump b/src/testdir/dumps/Test_display_lastline_euro_5.dump
new file mode 100644
index 0000000..75fc732
--- /dev/null
+++ b/src/testdir/dumps/Test_display_lastline_euro_5.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0@2| @71
+|b@74
+|€+0#4040ff13&@2| @71
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1|,|1| @11|T|o|p
+|a+0&&@2| @71
+|b@74
+@75
+@50| @24
+|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|1|,|1| @11|A|l@1
+|:+0&&|3|s|p|l|i|t| @67
diff --git a/src/testdir/test_display.vim b/src/testdir/test_display.vim
index 7237ed8..4d2ee9f 100644
--- a/src/testdir/test_display.vim
+++ b/src/testdir/test_display.vim
@@ -391,30 +391,46 @@
   let &breakat=_breakat
 endfunc
 
-func Test_display_lastline()
-  CheckScreendump
-
+func Run_Test_display_lastline(euro)
   let lines =<< trim END
-      call setline(1, ['aaa', 'b'->repeat(100)])
+      call setline(1, ['aaa', 'b'->repeat(200)])
       set display=truncate
+
       vsplit
       100wincmd <
   END
+  if a:euro != ''
+    let lines[2] = 'set fillchars=vert:\|,lastline:€'
+  endif
   call writefile(lines, 'XdispLastline', 'D')
   let buf = RunVimInTerminal('-S XdispLastline', #{rows: 10})
-  call VerifyScreenDump(buf, 'Test_display_lastline_1', {})
+  call VerifyScreenDump(buf, $'Test_display_lastline_{a:euro}1', {})
 
   call term_sendkeys(buf, ":set display=lastline\<CR>")
-  call VerifyScreenDump(buf, 'Test_display_lastline_2', {})
+  call VerifyScreenDump(buf, $'Test_display_lastline_{a:euro}2', {})
 
   call term_sendkeys(buf, ":100wincmd >\<CR>")
-  call VerifyScreenDump(buf, 'Test_display_lastline_3', {})
+  call VerifyScreenDump(buf, $'Test_display_lastline_{a:euro}3', {})
 
   call term_sendkeys(buf, ":set display=truncate\<CR>")
-  call VerifyScreenDump(buf, 'Test_display_lastline_4', {})
+  call VerifyScreenDump(buf, $'Test_display_lastline_{a:euro}4', {})
+
+  call term_sendkeys(buf, ":close\<CR>")
+  call term_sendkeys(buf, ":3split\<CR>")
+  call VerifyScreenDump(buf, $'Test_display_lastline_{a:euro}5', {})
 
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_display_lastline()
+  CheckScreendump
+
+  call Run_Test_display_lastline('')
+  call Run_Test_display_lastline('euro_')
+
+  call assert_fails(':set fillchars=lastline:', 'E474:')
+  call assert_fails(':set fillchars=lastline:〇', 'E474:')
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index dc9b6bd..a90ab47 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    656,
+/**/
     655,
 /**/
     654,