patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer

Problem:    Cannot handle pressing CTRL-C in a prompt buffer.
Solution:   Add prompt_setinterrupt().
diff --git a/src/channel.c b/src/channel.c
index d654dc0..1363ee9 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -5856,7 +5856,7 @@
     curwin->w_cursor.lnum = lnum + 1;
     curwin->w_cursor.col = 0;
 
-    if (curbuf->b_prompt_callback == NULL)
+    if (curbuf->b_prompt_callback == NULL || *curbuf->b_prompt_callback == NUL)
 	return;
     text = ml_get(lnum);
     prompt = prompt_text();
@@ -5874,4 +5874,28 @@
     clear_tv(&rettv);
 }
 
+/*
+ * Return TRUE when the interrupt callback was invoked.
+ */
+    int
+invoke_prompt_interrupt(void)
+{
+    typval_T	rettv;
+    int		dummy;
+    typval_T	argv[1];
+
+    if (curbuf->b_prompt_interrupt == NULL
+					|| *curbuf->b_prompt_interrupt == NUL)
+	return FALSE;
+    argv[0].v_type = VAR_UNKNOWN;
+
+    got_int = FALSE; // don't skip executing commands
+    call_func(curbuf->b_prompt_interrupt,
+	      (int)STRLEN(curbuf->b_prompt_interrupt),
+	      &rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE,
+	      curbuf->b_prompt_int_partial, NULL);
+    clear_tv(&rettv);
+    return TRUE;
+}
+
 #endif /* FEAT_JOB_CHANNEL */
diff --git a/src/edit.c b/src/edit.c
index 3204ec3..6a636b9 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1016,6 +1016,19 @@
 		goto doESCkey;
 	    }
 #endif
+#ifdef FEAT_JOB_CHANNEL
+	    if (c == Ctrl_C && bt_prompt(curbuf))
+	    {
+		if (invoke_prompt_interrupt())
+		{
+		    if (!bt_prompt(curbuf))
+			// buffer changed to a non-prompt buffer, get out of
+			// Insert mode
+			goto doESCkey;
+		    break;
+		}
+	    }
+#endif
 
 #ifdef UNIX
 do_intr:
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 4960203..3cb66f3 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -298,6 +298,7 @@
 static void f_printf(typval_T *argvars, typval_T *rettv);
 #ifdef FEAT_JOB_CHANNEL
 static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv);
+static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv);
 static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv);
 #endif
 static void f_pumvisible(typval_T *argvars, typval_T *rettv);
@@ -754,6 +755,7 @@
     {"printf",		1, 19, f_printf},
 #ifdef FEAT_JOB_CHANNEL
     {"prompt_setcallback", 2, 2, f_prompt_setcallback},
+    {"prompt_setinterrupt", 2, 2, f_prompt_setinterrupt},
     {"prompt_setprompt", 2, 2, f_prompt_setprompt},
 #endif
     {"pumvisible",	0, 0, f_pumvisible},
@@ -8622,6 +8624,35 @@
 }
 
 /*
+ * "prompt_setinterrupt({buffer}, {callback})" function
+ */
+    static void
+f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    buf_T	*buf;
+    char_u	*callback;
+    partial_T	*partial;
+
+    if (check_secure())
+	return;
+    buf = get_buf_tv(&argvars[0], FALSE);
+    if (buf == NULL)
+	return;
+
+    callback = get_callback(&argvars[1], &partial);
+    if (callback == NULL)
+	return;
+
+    free_callback(buf->b_prompt_interrupt, buf->b_prompt_int_partial);
+    if (partial == NULL)
+	buf->b_prompt_interrupt = vim_strsave(callback);
+    else
+	/* pointer into the partial */
+	buf->b_prompt_interrupt = callback;
+    buf->b_prompt_int_partial = partial;
+}
+
+/*
  * "prompt_setprompt({buffer}, {text})" function
  */
     static void
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 5326276..57b958a 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -72,4 +72,5 @@
 void job_info_all(list_T *l);
 int job_stop(job_T *job, typval_T *argvars, char *type);
 void invoke_prompt_callback(void);
+int invoke_prompt_interrupt(void);
 /* vim: set ft=c : */
diff --git a/src/version.c b/src/version.c
index e55be52..1f462b3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    69,
+/**/
     68,
 /**/
     67,