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.