Patch 8.2.1588
Problem:    Cannot read back the prompt of a prompt buffer.
Solution:   Add prompt_getprompt(). (Ben Jackson, closes #6851)
Files:      runtime/doc/channel.txt, runtime/doc/eval.txt,
            runtime/doc/usr_41.txt, src/channel.c, src/edit.c, src/evalfunc.c,
            src/proto/channel.pro, src/proto/edit.pro,
            src/testdir/test_prompt_buffer.vim


*** ../vim-8.2.1587/runtime/doc/channel.txt     2020-04-12 17:52:49.421492420 
+0200
--- runtime/doc/channel.txt     2020-09-04 16:23:15.259384412 +0200
***************
*** 608,613 ****
--- 608,617 ----
                after every message, on Unix you can use "tail -f" to see what
                is going on in real time.
  
+               To enable the log very early, to see what is received from a
+               terminal during startup, use |--cmd|: >
+                       vim --cmd "call ch_logfile('logfile', 'w')"
+ <
                This function is not available in the |sandbox|.
                NOTE: the channel communication is stored in the file, be
                aware that this may contain confidential and privacy sensitive
***************
*** 1235,1242 ****
  - Use a terminal window.  This works well if what you type goes directly to
    the job and the job output is directly displayed in the window.
    See |terminal-window|.
! - Use a prompt window. This works well when entering a line for the job in Vim
!   while displaying (possibly filtered) output from the job.
  
  A prompt buffer is created by setting 'buftype' to "prompt". You would
  normally only do that in a newly created buffer.
--- 1239,1246 ----
  - Use a terminal window.  This works well if what you type goes directly to
    the job and the job output is directly displayed in the window.
    See |terminal-window|.
! - Use a window with a prompt buffer. This works well when entering a line for
!   the job in Vim while displaying (possibly filtered) output from the job.
  
  A prompt buffer is created by setting 'buftype' to "prompt". You would
  normally only do that in a newly created buffer.
***************
*** 1256,1265 ****
  mode, use `:startinsert` if you want to enter Insert mode, so that the user
  can start typing a line.
  
! The text of the prompt can be set with the |prompt_setprompt()| function.
  
  The user can go to Normal mode and navigate through the buffer.  This can be
! useful see older output or copy text.
  
  The CTRL-W key can be used to start a window command, such as CTRL-W w to
  switch to the next window.  This also works in Insert mode (use Shift-CTRL-W
--- 1260,1271 ----
  mode, use `:startinsert` if you want to enter Insert mode, so that the user
  can start typing a line.
  
! The text of the prompt can be set with the |prompt_setprompt()| function. If
! no prompt is set with |prompt_setprompt()|, "% " is used. You can get the
! effective prompt text for a buffer, with |prompt_getprompt()|.
  
  The user can go to Normal mode and navigate through the buffer.  This can be
! useful to see older output or copy text.
  
  The CTRL-W key can be used to start a window command, such as CTRL-W w to
  switch to the next window.  This also works in Insert mode (use Shift-CTRL-W
***************
*** 1270,1274 ****
--- 1276,1321 ----
  the cursor to the last line.  "A" will move to the end of the line, "I" to the
  start of the line.
  
+ Here is an example for Unix.  It starts a shell in the background and prompts
+ for the next shell command.  Output from the shell is displayed above the
+ prompt. >
+ 
+       " Create a channel log so we can see what happens.
+       call ch_logfile('logfile', 'w')
+ 
+       " Function handling a line of text has been typed.
+       func TextEntered(text)
+         " Send the text to a shell with Enter appended.
+         call ch_sendraw(g:shell_job, a:text .. "\n")
+       endfunc
+               
+       " Function handling output from the shell: Added above the prompt.
+       func GotOutput(channel, msg)
+         call append(line("$") - 1, "- " . a:msg)
+       endfunc
+ 
+       " Function handling the shell exist: close the window.
+       func JobExit(job, status)
+         quit!
+       endfunc
+ 
+       " Start a shell in the background.
+       let shell_job = job_start(["/bin/sh"], #{
+               \ out_cb: function('GotOutput'),
+               \ err_cb: function('GotOutput'),
+               \ exit_cb: function('JobExit'),
+               \ })
+       let shell_ch = job_getchannel(shell_job)
+ 
+       new
+       set buftype=prompt
+       let buf = bufnr('')
+       call prompt_setcallback(buf, function("TextEntered"))
+       eval prompt_setprompt(buf, "shell command: ")
+ 
+       " start accepting shell commands
+       startinsert
+ <
+ 
  
   vim:tw=78:ts=8:noet:ft=help:norl:
*** ../vim-8.2.1587/runtime/doc/eval.txt        2020-08-30 15:49:12.158736328 
+0200
--- runtime/doc/eval.txt        2020-09-04 16:23:15.259384412 +0200
***************
*** 2671,2676 ****
--- 2684,2690 ----
  pow({x}, {y})                 Float   {x} to the power of {y}
  prevnonblank({lnum})          Number  line nr of non-blank line <= {lnum}
  printf({fmt}, {expr1}...)     String  format text
+ prompt_getprompt({buf})               String  get prompt text
  prompt_setcallback({buf}, {expr}) none        set prompt callback function
  prompt_setinterrupt({buf}, {text}) none       set prompt interrupt function
  prompt_setprompt({buf}, {text}) none  set prompt text
***************
*** 7789,7794 ****
--- 7836,7852 ----
                arguments an error is given.  Up to 18 arguments can be used.
  
  
+ prompt_getprompt({buf})                                       
*prompt_getprompt()*
+               Returns the effective prompt text for buffer {buf}. {buf} can
+               be a buffer name or number. |prompt-buffer|.
+ 
+               If the buffer doesn't exist or isn't a prompt buffer, an empty
+               string is returned.
+ 
+               Can also be used as a |method|: >
+                       GetBuffer()->prompt_getprompt()
+ 
+ 
  prompt_setcallback({buf}, {expr})                     *prompt_setcallback()*
                Set prompt callback for buffer {buf} to {expr}.  When {expr}
                is an empty string the callback is removed.  This has only
***************
*** 7844,7850 ****
                Can also be used as a |method|: >
                        GetBuffer()->prompt_setprompt('command: ')
  
! prop_ functions are documented here: |text-prop-functions|.
  
  pum_getpos()                                          *pum_getpos()*
                If the popup menu (see |ins-completion-menu|) is not visible,
--- 7902,7908 ----
                Can also be used as a |method|: >
                        GetBuffer()->prompt_setprompt('command: ')
  
! prop_ functions are documented here: |text-prop-functions|
  
  pum_getpos()                                          *pum_getpos()*
                If the popup menu (see |ins-completion-menu|) is not visible,
*** ../vim-8.2.1587/runtime/doc/usr_41.txt      2020-08-30 15:49:12.158736328 
+0200
--- runtime/doc/usr_41.txt      2020-09-04 16:23:15.259384412 +0200
***************
*** 1110,1115 ****
--- 1118,1124 ----
        settagstack()           modify the tag stack of a window
  
  Prompt Buffer:                                        *promptbuffer-functions*
+       prompt_getprompt()      get the effective prompt text for a buffer
        prompt_setcallback()    set prompt callback for a buffer
        prompt_setinterrupt()   set interrupt callback for a buffer
        prompt_setprompt()      set the prompt text for a buffer
*** ../vim-8.2.1587/src/channel.c       2020-08-30 17:24:34.277662302 +0200
--- src/channel.c       2020-09-04 16:23:15.259384412 +0200
***************
*** 6368,6373 ****
--- 6368,6396 ----
      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
   */
*** ../vim-8.2.1587/src/edit.c  2020-06-06 22:36:20.464116743 +0200
--- src/edit.c  2020-09-04 16:23:15.259384412 +0200
***************
*** 1682,1697 ****
  
  #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
  /*
   * 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;
  }
  
  /*
   * Prepare for prompt mode: Make sure the last line has the prompt text.
   * Move the cursor to this line.
--- 1682,1707 ----
  
  #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)
  {
!     return buf_prompt_text(curbuf);
  }
  
+ 
  /*
   * Prepare for prompt mode: Make sure the last line has the prompt text.
   * Move the cursor to this line.
*** ../vim-8.2.1587/src/evalfunc.c      2020-09-02 22:25:31.717607993 +0200
--- src/evalfunc.c      2020-09-04 16:23:15.263384403 +0200
***************
*** 806,811 ****
--- 806,812 ----
      {"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)},
*** ../vim-8.2.1587/src/proto/channel.pro       2020-04-12 17:52:49.429492390 
+0200
--- src/proto/channel.pro       2020-09-04 16:23:15.263384403 +0200
***************
*** 56,61 ****
--- 56,62 ----
  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);
*** ../vim-8.2.1587/src/proto/edit.pro  2020-05-01 14:26:17.132949262 +0200
--- src/proto/edit.pro  2020-09-04 16:23:15.263384403 +0200
***************
*** 4,9 ****
--- 4,10 ----
  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);
*** ../vim-8.2.1587/src/testdir/test_prompt_buffer.vim  2020-08-12 
18:50:31.883655785 +0200
--- src/testdir/test_prompt_buffer.vim  2020-09-04 16:23:15.263384403 +0200
***************
*** 148,151 ****
--- 148,185 ----
    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
*** ../vim-8.2.1587/src/version.c       2020-09-04 15:37:27.865546317 +0200
--- src/version.c       2020-09-04 16:24:32.255203937 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     1588,
  /**/

-- 
Individualists unite!

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202009041436.084EaaMC346327%40masaka.moolenaar.net.

Raspunde prin e-mail lui