patch 8.2.1588: cannot read back the prompt of a prompt buffer

Problem:    Cannot read back the prompt of a prompt buffer.
Solution:   Add prompt_getprompt(). (Ben Jackson, closes #6851)
diff --git a/src/channel.c b/src/channel.c
index 1a899e8..5bf561e 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -6368,6 +6368,29 @@
     set_callback(&buf->b_prompt_interrupt, &callback);
 }
 
+
+/*
+ * "prompt_getprompt({buffer})" function
+ */
+    void
+f_prompt_getprompt(typval_T *argvars, typval_T *rettv)
+{
+    buf_T	*buf;
+
+    // return an empty string by default, e.g. it's not a prompt buffer
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+
+    buf = tv_get_buf_from_arg(&argvars[0]);
+    if (buf == NULL)
+	return;
+
+    if (!bt_prompt(buf))
+	return;
+
+    rettv->vval.v_string = vim_strsave(buf_prompt_text(buf));
+}
+
 /*
  * "prompt_setprompt({buffer}, {text})" function
  */
diff --git a/src/edit.c b/src/edit.c
index dc0b450..bc74f44 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1682,16 +1682,26 @@
 
 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
 /*
+ * Return the effective prompt for the specified buffer.
+ */
+    char_u *
+buf_prompt_text(buf_T* buf)
+{
+    if (buf->b_prompt_text == NULL)
+	return (char_u *)"% ";
+    return buf->b_prompt_text;
+}
+
+/*
  * Return the effective prompt for the current buffer.
  */
     char_u *
 prompt_text(void)
 {
-    if (curbuf->b_prompt_text == NULL)
-	return (char_u *)"% ";
-    return curbuf->b_prompt_text;
+    return buf_prompt_text(curbuf);
 }
 
+
 /*
  * Prepare for prompt mode: Make sure the last line has the prompt text.
  * Move the cursor to this line.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 91fbc67..ac75a7d 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -806,6 +806,7 @@
     {"pow",		2, 2, FEARG_1,	  ret_float,	FLOAT_FUNC(f_pow)},
     {"prevnonblank",	1, 1, FEARG_1,	  ret_number,	f_prevnonblank},
     {"printf",		1, 19, FEARG_2,	  ret_string,	f_printf},
+    {"prompt_getprompt", 1, 1, FEARG_1,	  ret_string,	JOB_FUNC(f_prompt_getprompt)},
     {"prompt_setcallback", 2, 2, FEARG_1, ret_void,	JOB_FUNC(f_prompt_setcallback)},
     {"prompt_setinterrupt", 2, 2, FEARG_1,ret_void,	JOB_FUNC(f_prompt_setinterrupt)},
     {"prompt_setprompt", 2, 2, FEARG_1,	  ret_void,	JOB_FUNC(f_prompt_setprompt)},
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 56a0167..a402177 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -56,6 +56,7 @@
 int job_stop(job_T *job, typval_T *argvars, char *type);
 void invoke_prompt_callback(void);
 int invoke_prompt_interrupt(void);
+void f_prompt_getprompt(typval_T *argvars, typval_T *rettv);
 void f_prompt_setcallback(typval_T *argvars, typval_T *rettv);
 void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv);
 void f_prompt_setprompt(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/edit.pro b/src/proto/edit.pro
index 6efe537..e2ec8dc 100644
--- a/src/proto/edit.pro
+++ b/src/proto/edit.pro
@@ -4,6 +4,7 @@
 void ins_redraw(int ready);
 int decodeModifyOtherKeys(int c);
 void edit_putchar(int c, int highlight);
+char_u *buf_prompt_text(buf_T* buf);
 char_u *prompt_text(void);
 int prompt_curpos_editable(void);
 void edit_unputchar(void);
diff --git a/src/testdir/test_prompt_buffer.vim b/src/testdir/test_prompt_buffer.vim
index 45eb1c9..3656875 100644
--- a/src/testdir/test_prompt_buffer.vim
+++ b/src/testdir/test_prompt_buffer.vim
@@ -148,4 +148,38 @@
   call assert_equal(0, prompt_setprompt([], ''))
 endfunc
 
+func Test_prompt_buffer_getbufinfo()
+  new
+  call assert_equal('', prompt_getprompt('%'))
+  call assert_equal('', prompt_getprompt(bufnr('%')))
+  let another_buffer = bufnr('%')
+
+  set buftype=prompt
+  call assert_equal('% ', prompt_getprompt('%'))
+  call prompt_setprompt( bufnr( '%' ), 'This is a test: ' )
+  call assert_equal('This is a test: ', prompt_getprompt('%'))
+
+  call prompt_setprompt( bufnr( '%' ), '' )
+  call assert_equal('', '%'->prompt_getprompt())
+
+  call prompt_setprompt( bufnr( '%' ), 'Another: ' )
+  call assert_equal('Another: ', prompt_getprompt('%'))
+  let another = bufnr('%')
+
+  new
+
+  call assert_equal('', prompt_getprompt('%'))
+  call assert_equal('Another: ', prompt_getprompt(another))
+
+  " Doesn't exist
+  let buffers_before = len( getbufinfo() )
+  call assert_equal('', prompt_getprompt( bufnr('$') + 1))
+  call assert_equal(buffers_before, len( getbufinfo()))
+
+  " invalid type
+  call assert_fails('call prompt_getprompt({})', 'E728:')
+
+  %bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 92ff1e9..2c6e47e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1588,
+/**/
     1587,
 /**/
     1586,