patch 8.0.0716: not easy to start Vim cleanly

Problem:    Not easy to start Vim cleanly without changing the viminfo file.
            Not possible to know whether the -i command line flag was used.
Solution:   Add the --clean command line argument.  Add the 'viminfofile'
            option.  Add "-u DEFAULTS".
diff --git a/src/channel.c b/src/channel.c
index ffee334..c9e5e14 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1438,6 +1438,7 @@
     if (!bufref_valid(&in_part->ch_bufref) || buf->b_ml.ml_mfp == NULL)
     {
 	/* buffer was wiped out or unloaded */
+	ch_log(channel, "input buffer has been wiped out");
 	in_part->ch_bufref.br_buf = NULL;
 	return;
     }
@@ -2338,7 +2339,7 @@
     int		save_write_to = buffer->b_write_to_channel;
     chanpart_T  *ch_part = &channel->ch_part[part];
     int		save_p_ma = buffer->b_p_ma;
-    int		empty = (buffer->b_ml.ml_flags & ML_EMPTY);
+    int		empty = (buffer->b_ml.ml_flags & ML_EMPTY) ? 1 : 0;
 
     if (!buffer->b_p_ma && !ch_part->ch_nomodifiable)
     {
@@ -2359,13 +2360,14 @@
     }
 
     /* Append to the buffer */
-    ch_logn(channel, "appending line %d to buffer", (int)lnum + 1);
+    ch_logn(channel, "appending line %d to buffer", (int)lnum + 1 - empty);
 
     buffer->b_p_ma = TRUE;
     curbuf = buffer;
+    curwin->w_buffer = curbuf;
     u_sync(TRUE);
     /* ignore undo failure, undo is not very useful here */
-    ignored = u_save(lnum, lnum + 1 + (empty ? 1 : 0));
+    ignored = u_save(lnum - empty, lnum + 1);
 
     if (empty)
     {
@@ -2377,6 +2379,7 @@
 	ml_append(lnum, msg, 0, FALSE);
     appended_lines_mark(lnum, 1L);
     curbuf = save_curbuf;
+    curwin->w_buffer = curbuf;
     if (ch_part->ch_nomodifiable)
 	buffer->b_p_ma = FALSE;
     else
@@ -2483,9 +2486,11 @@
     }
 
     buffer = ch_part->ch_bufref.br_buf;
-    if (buffer != NULL && !bufref_valid(&ch_part->ch_bufref))
+    if (buffer != NULL && (!bufref_valid(&ch_part->ch_bufref)
+					       || buffer->b_ml.ml_mfp == NULL))
     {
-	/* buffer was wiped out */
+	/* buffer was wiped out or unloaded */
+	ch_logs(channel, "%s buffer has been wiped out", part_names[part]);
 	ch_part->ch_bufref.br_buf = NULL;
 	buffer = NULL;
     }
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index a69a052..9c84e24 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -1743,7 +1743,7 @@
 no_viminfo(void)
 {
     /* "vim -i NONE" does not read or write a viminfo file */
-    return (use_viminfo != NULL && STRCMP(use_viminfo, "NONE") == 0);
+    return STRCMP(p_viminfofile, "NONE") == 0;
 }
 
 /*
@@ -2093,8 +2093,8 @@
 {
     if (file == NULL || *file == NUL)
     {
-	if (use_viminfo != NULL)
-	    file = use_viminfo;
+	if (*p_viminfofile != NUL)
+	    file = p_viminfofile;
 	else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL)
 	{
 #ifdef VIMINFO_FILE2
diff --git a/src/globals.h b/src/globals.h
index 7cf928c..d0938fd 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1036,7 +1036,6 @@
 EXTERN int	do_redraw INIT(= FALSE);    /* extra redraw once */
 
 EXTERN int	need_highlight_changed INIT(= TRUE);
-EXTERN char_u	*use_viminfo INIT(= NULL);  /* name of viminfo file to use */
 
 #define NSCRIPT 15
 EXTERN FILE	*scriptin[NSCRIPT];	    /* streams to read script from */
diff --git a/src/main.c b/src/main.c
index 67c0a30..6e21f73 100644
--- a/src/main.c
+++ b/src/main.c
@@ -433,7 +433,9 @@
 #ifndef NO_VIM_MAIN
     /* Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
      * Allows for setting 'loadplugins' there. */
-    if (params.use_vimrc != NULL && STRCMP(params.use_vimrc, "NONE") == 0)
+    if (params.use_vimrc != NULL
+	    && (STRCMP(params.use_vimrc, "NONE") == 0
+		|| STRCMP(params.use_vimrc, "DEFAULTS") == 0))
 	p_lpl = FALSE;
 
     /* Execute --cmd arguments. */
@@ -1869,6 +1871,7 @@
 	    case '-':		/* "--" don't take any more option arguments */
 				/* "--help" give help message */
 				/* "--version" give version message */
+				/* "--clean" clean context */
 				/* "--literal" take files literally */
 				/* "--nofork" don't fork */
 				/* "--not-a-term" don't warn for not a term */
@@ -1886,6 +1889,11 @@
 		    msg_didout = FALSE;
 		    mch_exit(0);
 		}
+		else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0)
+		{
+		    parmp->use_vimrc = (char_u *)"DEFAULTS";
+		    set_option_value((char_u *)"vif", 0L, (char_u *)"NONE", 0);
+		}
 		else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0)
 		{
 #ifdef EXPAND_FILENAMES
@@ -2318,7 +2326,7 @@
 #endif
 
 		case 'i':	/* "-i {viminfo}" use for viminfo */
-		    use_viminfo = (char_u *)argv[0];
+		    set_option_value((char_u *)"vif", 0L, (char_u *)argv[0], 0);
 		    break;
 
 		case 's':	/* "-s {scriptin}" read from script file */
@@ -2988,7 +2996,9 @@
      */
     if (parmp->use_vimrc != NULL)
     {
-	if (STRCMP(parmp->use_vimrc, "NONE") == 0
+	if (STRCMP(parmp->use_vimrc, "DEFAULTS") == 0)
+	    do_source((char_u *)VIM_DEFAULTS_FILE, FALSE, DOSO_NONE);
+	else if (STRCMP(parmp->use_vimrc, "NONE") == 0
 				     || STRCMP(parmp->use_vimrc, "NORC") == 0)
 	{
 #ifdef FEAT_GUI
@@ -3383,6 +3393,7 @@
 #ifdef FEAT_VIMINFO
     main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
 #endif
+    main_msg(_("--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"));
     main_msg(_("-h  or  --help\tPrint Help (this message) and exit"));
     main_msg(_("--version\t\tPrint version information and exit"));
 
diff --git a/src/option.c b/src/option.c
index 39aef6e..8e91fae 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2986,6 +2986,15 @@
 			    {(char_u *)0L, (char_u *)0L}
 #endif
 			    SCRIPTID_INIT},
+    {"viminfofile", "vif",  P_STRING|P_ONECOMMA|P_NODUP|P_SECURE|P_VI_DEF,
+#ifdef FEAT_VIMINFO
+			    (char_u *)&p_viminfofile, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    SCRIPTID_INIT},
     {"virtualedit", "ve",   P_STRING|P_ONECOMMA|P_NODUP|P_VI_DEF
 							    |P_VIM|P_CURSWANT,
 #ifdef FEAT_VIRTUALEDIT
diff --git a/src/option.h b/src/option.h
index c74a89b..7394c7f 100644
--- a/src/option.h
+++ b/src/option.h
@@ -920,6 +920,7 @@
 #endif
 #ifdef FEAT_VIMINFO
 EXTERN char_u	*p_viminfo;	/* 'viminfo' */
+EXTERN char_u	*p_viminfofile;	/* 'viminfofile' */
 #endif
 #ifdef FEAT_SESSION
 EXTERN char_u	*p_vdir;	/* 'viewdir' */
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index 3694fc2..c988968 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -739,6 +739,38 @@
   call Run_test_pipe_to_buffer(1, 0, 1)
 endfunc
 
+func Test_close_output_buffer()
+  if !has('job')
+    return
+  endif
+  enew!
+  let test_lines = ['one', 'two']
+  call setline(1, test_lines)
+  call ch_log('Test_close_output_buffer()')
+  let options = {'out_io': 'buffer'}
+  let options['out_name'] = 'buffer-output'
+  let options['out_msg'] = 0
+  split buffer-output
+  let job = job_start(s:python . " test_channel_write.py", options)
+  call assert_equal("run", job_status(job))
+  try
+    call WaitFor('line("$") == 3')
+    call assert_equal(3, line('$'))
+    quit!
+    sleep 100m
+    " Make sure the write didn't happen to the wrong buffer.
+    call assert_equal(test_lines, getline(1, line('$')))
+    call assert_equal(-1, bufwinnr('buffer-output'))
+    sbuf buffer-output
+    call assert_notequal(-1, bufwinnr('buffer-output'))
+    sleep 100m
+    close  " no more writes
+    bwipe!
+  finally
+    call job_stop(job)
+  endtry
+endfunc
+
 func Run_test_pipe_err_to_buffer(use_name, nomod, do_msg)
   if !has('job')
     return
diff --git a/src/testdir/test_channel_write.py b/src/testdir/test_channel_write.py
new file mode 100644
index 0000000..9c8813b
--- /dev/null
+++ b/src/testdir/test_channel_write.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+#
+# Program that writes a number to stdout repeatedly
+#
+# This requires Python 2.6 or later.
+
+from __future__ import print_function
+import sys
+import time
+
+if __name__ == "__main__":
+
+    done = 0
+    while done < 10:
+        done = done + 1
+        print(done)
+        sys.stdout.flush()
+        time.sleep(0.05)  # sleep 50 msec
diff --git a/src/version.c b/src/version.c
index c8322cd..09b3b85 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,10 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    716,
+/**/
+    715,
+/**/
     714,
 /**/
     713,