patch 8.1.2195: Vim does not exit when the terminal window is last window

Problem:    Vim does not exit when closing a terminal window and it is the
            last window.
Solution:   Exit Vim if the closed terminal window is the last one.
            (closes #4539)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 1d04769..d9fe7de 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -87,7 +87,6 @@
 static char_u	*repl_cmdline(exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep);
 static void	ex_highlight(exarg_T *eap);
 static void	ex_colorscheme(exarg_T *eap);
-static void	ex_quit(exarg_T *eap);
 static void	ex_cquit(exarg_T *eap);
 static void	ex_quit_all(exarg_T *eap);
 static void	ex_close(exarg_T *eap);
@@ -4842,8 +4841,9 @@
 /*
  * ":quit": quit current window, quit Vim if the last window is closed.
  * ":{nr}quit": quit window {nr}
+ * Also used when closing a terminal window that's the last one.
  */
-    static void
+    void
 ex_quit(exarg_T *eap)
 {
     win_T	*wp;
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index cc64ac8..f5942f5 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -15,13 +15,14 @@
 void ex_ni(exarg_T *eap);
 int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp);
 void separate_nextcmd(exarg_T *eap);
-char_u *skip_cmd_arg( char_u *p, int rembs);
+char_u *skip_cmd_arg(char_u *p, int rembs);
 int get_bad_opt(char_u *p, exarg_T *eap);
 int ends_excmd(int c);
 char_u *find_nextcmd(char_u *p);
 char_u *check_nextcmd(char_u *p);
 char_u *get_command_name(expand_T *xp, int idx);
 void not_exiting(void);
+void ex_quit(exarg_T *eap);
 void tabpage_close(int forceit);
 void tabpage_close_other(tabpage_T *tp, int forceit);
 void handle_drop(int filec, char_u **filev, int split, void (*callback)(void *), void *cookie);
@@ -30,8 +31,8 @@
 void tabpage_new(void);
 void do_exedit(exarg_T *eap, win_T *old_curwin);
 void free_cd_dir(void);
-void post_chdir(cdscope_T cdscope);
-int changedir_func(char_u *new_dir, int forceit, cdscope_T cdscope);
+void post_chdir(cdscope_T scope);
+int changedir_func(char_u *new_dir, int forceit, cdscope_T scope);
 void ex_cd(exarg_T *eap);
 void do_sleep(long msec);
 void ex_may_print(exarg_T *eap);
@@ -47,8 +48,6 @@
 int find_cmdline_var(char_u *src, int *usedlen);
 char_u *eval_vars(char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char **errormsg, int *escaped);
 char_u *expand_sfile(char_u *arg);
-int put_eol(FILE *fd);
-int put_line(FILE *fd, char *s);
 void dialog_msg(char_u *buff, char *format, char_u *fname);
 void set_no_hlsearch(int flag);
 int is_loclist_cmd(int cmdidx);
diff --git a/src/terminal.c b/src/terminal.c
index 7b2d43b..07b2e97 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3073,6 +3073,16 @@
 	    aco_save_T	aco;
 	    int		do_set_w_closing = term->tl_buffer->b_nwindows == 0;
 
+	    // If this is the last normal window: exit Vim.
+	    if (term->tl_buffer->b_nwindows > 0 && only_one_window())
+	    {
+		exarg_T ea;
+
+		vim_memset(&ea, 0, sizeof(ea));
+		ex_quit(&ea);
+		return TRUE;
+	    }
+
 	    // ++close or term_finish == "close"
 	    ch_log(NULL, "terminal job finished, closing window");
 	    aucmd_prepbuf(&aco, term->tl_buffer);
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index c4d3e52..f506a39 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -1051,6 +1051,32 @@
   quit
 endfunc
 
+" Run Vim in a terminal, then start a terminal window with a shell and check
+" that Vim exits if it is closed.
+func Test_terminal_exit()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+     let winid = win_getid()
+     help
+     term
+     let termid = win_getid()
+     call win_gotoid(winid)
+     close
+     call win_gotoid(termid)
+  END
+  call writefile(lines, 'XtermExit')
+  let buf = RunVimInTerminal('-S XtermExit', #{rows: 10})
+  let job = term_getjob(buf)
+  call WaitForAssert({-> assert_equal("run", job_status(job))})
+
+  " quit the shell, it will make Vim exit
+  call term_sendkeys(buf, "exit\<CR>")
+  call WaitForAssert({-> assert_equal("dead", job_status(job))})
+
+  call delete('XtermExit')
+endfunc
+
 func Test_terminal_open_autocmd()
   augroup repro
     au!
diff --git a/src/version.c b/src/version.c
index 38696fa..c378c1b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2195,
+/**/
     2194,
 /**/
     2193,