Skip to content

Commit

Permalink
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Browse files Browse the repository at this point in the history
Problem:    Difficult to make a plugin that feeds a line to a job.
Solution:   Add the nitial code for the "prompt" buftype.
  • Loading branch information
brammool committed Jun 3, 2018
1 parent 33c5e9f commit f273245
Show file tree
Hide file tree
Showing 22 changed files with 532 additions and 58 deletions.
39 changes: 39 additions & 0 deletions runtime/doc/channel.txt
Expand Up @@ -22,6 +22,7 @@ The Netbeans interface also uses a channel. |netbeans|
9. Starting a job without a channel |job-start-nochannel|
10. Job options |job-options|
11. Controlling a job |job-control|
12. Using a prompt buffer |prompt-buffer|

{Vi does not have any of these features}
{only when compiled with the |+channel| feature for channel stuff}
Expand Down Expand Up @@ -770,5 +771,43 @@ signals. E.g. to force a job to stop, "kill it": >
For more options see |job_stop()|.

==============================================================================
12. Using a prompt buffer *prompt-buffer*

If you want to type input for the job in a Vim window you have a few options:
- Use a normal buffer and handle all possible commands yourself.
This will be complicated, since there are so many possible commands.
- 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.

The user can edit and enter one line of text at the very last line of the
buffer. When pressing Enter in the prompt line the callback set with
|prompt_setcallback()| is invoked. It would normally send the line to a job.
Another callback would receive the output from the job and display it in the
buffer, below the prompt (and above the next prompt).

Only the text in the last line, after the prompt, is editable. The rest of the
buffer is not modifiable with Normal mode commands. It can be modified by
calling functions, such as |append()|. Using other commands may mess up the
buffer.

After setting 'buftype' to "prompt" Vim does not automatically start Insert
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.

Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
the cursor to the last line, after the prompt.


vim:tw=78:ts=8:ft=help:norl:
43 changes: 41 additions & 2 deletions runtime/doc/eval.txt
Expand Up @@ -2294,6 +2294,9 @@ perleval({expr}) any evaluate |Perl| expression
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_addtext({buf}, {expr}) none add text to a prompt buffer
prompt_setprompt({buf}, {text}) none set prompt text
prompt_setcallback({buf}, {expr}) none set prompt callback function
pumvisible() Number whether popup menu is visible
pyeval({expr}) any evaluate |Python| expression
py3eval({expr}) any evaluate |python3| expression
Expand All @@ -2302,7 +2305,7 @@ range({expr} [, {max} [, {stride}]])
List items from {expr} to {max}
readfile({fname} [, {binary} [, {max}]])
List get list of lines from file {fname}
reg_executing() Number get the executing register name
reg_executing() String get the executing register name
reg_recording() String get the recording register name
reltime([{start} [, {end}]]) List get time value
reltimefloat({time}) Float turn the time value into a Float
Expand Down Expand Up @@ -4650,7 +4653,7 @@ getline({lnum} [, {end}])
from the current buffer. Example: >
getline(1)
< When {lnum} is a String that doesn't start with a
digit, line() is called to translate the String into a Number.
digit, |line()| is called to translate the String into a Number.
To get the line under the cursor: >
getline(".")
< When {lnum} is smaller than 1 or bigger than the number of
Expand Down Expand Up @@ -6475,6 +6478,42 @@ printf({fmt}, {expr1} ...) *printf()*
arguments an error is given. Up to 18 arguments can be used.


prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Set prompt for buffer {buf} to {text}. You most likely want
{text} to end in a space.
The result is only visible if {buf} has 'buftype' set to
"prompt". Example: >
call prompt_setprompt(bufnr(''), 'command: ')
prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
Set prompt callback for buffer {buf} to {expr}. This has only
effect if {buf} has 'buftype' set to "prompt".
The callback is invoked when pressing Enter. The current
buffer will always be the prompt buffer. A new line for a
prompt is added before invoking the callback, thus the prompt
for which the callback was invoked will be in the last but one
line.
If the callback wants to add text to the buffer, it must
insert it above the last line, since that is where the current
prompt is. This can also be done asynchronously.
The callback is invoked with one argument, which is the text
that was entered at the prompt. This can be an empty string
if the user only typed Enter.
Example: >
call prompt_setcallback(bufnr(''), function('s:TextEntered'))
func s:TextEntered(text)
if a:text == 'exit' || a:text == 'quit'
stopinsert
close
else
call append(line('$') - 1, 'Entered: "' . a:text . '"')
" Reset 'modified' to allow the buffer to be closed.
set nomodified
endif
endfunc
pumvisible() *pumvisible()*
Returns non-zero when the popup menu is visible, zero
otherwise. See |ins-completion-menu|.
Expand Down
15 changes: 11 additions & 4 deletions runtime/doc/options.txt
Expand Up @@ -1394,6 +1394,9 @@ A jump table for the options with a short description can be found at |Q_op|.
manually)
terminal buffer for a |terminal| (you are not supposed to set
this manually)
prompt buffer where only the last line can be edited, meant
to be used by a plugin, see |prompt-buffer|
{only when compiled with the |+channel| feature}

This option is used together with 'bufhidden' and 'swapfile' to
specify special kinds of buffers. See |special-buffers|.
Expand Down Expand Up @@ -4264,7 +4267,8 @@ A jump table for the options with a short description can be found at |Q_op|.
'imactivatefunc' 'imaf' string (default "")
global
{not in Vi}
{only available when compiled with |+mbyte|}
{only available when compiled with the |+multi_byte|
feature}
This option specifies a function that will be called to
activate or deactivate the Input Method.
It is not used in the GUI.
Expand Down Expand Up @@ -4316,7 +4320,8 @@ A jump table for the options with a short description can be found at |Q_op|.
'imcmdline' 'imc' boolean (default off)
global
{not in Vi}
{only available when compiled with |+mbyte|}
{only available when compiled with the |+multi_byte|
feature}
When set the Input Method is always on when starting to edit a command
line, unless entering a search pattern (see 'imsearch' for that).
Setting this option is useful when your input method allows entering
Expand All @@ -4327,7 +4332,8 @@ A jump table for the options with a short description can be found at |Q_op|.
'imdisable' 'imd' boolean (default off, on for some systems (SGI))
global
{not in Vi}
{only available when compiled with |+mbyte|}
{only available when compiled with the |+multi_byte|
feature}
When set the Input Method is never used. This is useful to disable
the IM when it doesn't work properly.
Currently this option is on by default for SGI/IRIX machines. This
Expand Down Expand Up @@ -4380,7 +4386,8 @@ A jump table for the options with a short description can be found at |Q_op|.
'imstatusfunc' 'imsf' string (default "")
global
{not in Vi}
{only available when compiled with |+mbyte|}
{only available when compiled with the |+multi_byte|
feature}
This option specifies a function that is called to obtain the status
of Input Method. It must return a positive number when IME is active.
It is not used in the GUI.
Expand Down
48 changes: 45 additions & 3 deletions runtime/doc/todo.txt
Expand Up @@ -38,6 +38,10 @@ browser use: https://github.com/vim/vim/issues/1234
*known-bugs*
-------------------- Known bugs and current work -----------------------

Prompt buffer:
- Add a command line history.
- delay next prompt until plugin gives OK?

Terminal emulator window:
- Win32: Termdebug doesn't work, because gdb does not support mi2 on a tty.
This plugin: https://github.com/cpiger/NeoDebug runs gdb as a job,
Expand Down Expand Up @@ -71,33 +75,66 @@ Crash when mixing matchadd and substitute()? (Max Christian Pohle, 2018 May
On Win32 when not in the console and t_Co >= 256, allow using 'tgc'.
(Nobuhiro Takasaki, #2833) Also check t_Co.

balloon_show() does not work properly in the terminal. (Ben Jackson, 2017 Dec
20, #2481)
Also see #2352, want better control over balloon, perhaps set the position.
Patch to fix arguments of :edit. (Dominique Pelle, 2018 May 28 #2966)

Ptch to update html syntax. (Jorge Maldonado Ventura, #2974)

Patch to fix that restoring window doesn't work when 'winheight' is large.
(Darrell Nash, 2018 May 30, #2971) Doesn't work? Issue #2970

Patch to add completion to :unlet for environment vars. (Jason Franklin, 2018
May 30) Last update.

Errors found with random data:
heap-buffer-overflow in alist_add (#2472)

More warnings from static analysis:
https://lgtm.com/projects/g/vim/vim/alerts/?mode=list

Patch to make "is" and "as" work bettter. (Jason Franklin, 2018 May 19)

Patch to add tests for user and language completion. (Dominique Pelle, 2018
Jun 2, #2978)

Using ":file" in quickfix window during an autocommand doesn't work.
(Jason Franklin, 2018 May 23) Allow for using it when there is no argument.

Pull request #2967: Allow white space in sign text. (Ben Jackson)

Patch for xterm and vt320 builtin termcap. (Kouichi Iwamoto, 2018 May 31,
#2973)

Patch to add more testing for :cd command. (Dominique Pelle, 2018 May 30,
#2972)

Script generated by :mksession does not work well if there are windows with
modified buffers
change "silent only" into "silent only!"
change "edit fname" of first buffer to "hide edit fname"
skip "badd fname" if "fname" is already in the buffer list
remove remark about unloading buffers from documentation

Patch to make :help work for tags with a ?. (Hirohito Higashi, 2018 May 28)

Compiler warnings (geeknik, 2017 Oct 26):
- signed integer overflow in do_sub() (#2249)
- signed integer overflow in get_address() (#2248)
- signed integer overflow in getdecchrs() (#2254)
- undefined left shift in get_string_tv() (#2250)

Patch for more quickfix refactoring. (Yegappan Lakshmanan, #2950)

Tests failing for "make testgui" with GTK:
- Test_setbufvar_options()
- Test_exit_callback_interval()

Make balloon_show() work outside of 'balloonexpr'? Users expect it to work:
#2948. (related to #1512?)
On Win32 it stops showing, because showState is already ShS_SHOWING.
balloon_show() does not work properly in the terminal. (Ben Jackson, 2017 Dec
20, #2481)
Also see #2352, want better control over balloon, perhaps set the position.

Try out background make plugin:
https://github.com/AndrewVos/vim-make-background
or asyncmake:
Expand All @@ -112,6 +149,8 @@ used for git temp files.

Cursor in wrong position when line wraps. (#2540)

Patch for Lua support. (Kazunobu Kuriyama, 2018 May 26)

Add an option similar to 'lazyredraw' to skip redrawing while executing a
script or function.

Expand Down Expand Up @@ -141,6 +180,9 @@ How to test that it works well for all Vim users?

Alternative manpager.vim. (Enno, 2018 Jan 5, #2529)

Patch to use NGETTEXT() in many more places. (Sergey Alyoshin, 2018 May 25)
Updated ptach May 27.

Does setting 'cursorline' cause syntax highlighting to slow down? Perhaps is
mess up the cache? (Mike Lee Williams, 2018 Jan 27, #2539)
Also: 'foldtext' is evaluated too often. (Daniel Hahler, #2773)
Expand Down
1 change: 1 addition & 0 deletions src/Makefile
Expand Up @@ -2252,6 +2252,7 @@ test_arglist \
test_popup \
test_preview \
test_profile \
test_prompt_buffer \
test_put \
test_python2 \
test_python3 \
Expand Down
20 changes: 18 additions & 2 deletions src/buffer.c
Expand Up @@ -851,6 +851,10 @@ free_buffer(buf_T *buf)
#ifdef FEAT_TERMINAL
free_terminal(buf);
#endif
#ifdef FEAT_JOB_CHANNEL
vim_free(buf->b_prompt_text);
free_callback(buf->b_prompt_callback, buf->b_prompt_partial);
#endif

buf_hashtab_remove(buf);

Expand Down Expand Up @@ -5633,6 +5637,15 @@ bt_help(buf_T *buf)
return buf != NULL && buf->b_help;
}

/*
* Return TRUE if "buf" is a prompt buffer.
*/
int
bt_prompt(buf_T *buf)
{
return buf != NULL && buf->b_p_bt[0] == 'p';
}

/*
* Return TRUE if "buf" is a "nofile", "acwrite" or "terminal" buffer.
* This means the buffer name is not a file name.
Expand All @@ -5642,7 +5655,8 @@ bt_nofile(buf_T *buf)
{
return buf != NULL && ((buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f')
|| buf->b_p_bt[0] == 'a'
|| buf->b_p_bt[0] == 't');
|| buf->b_p_bt[0] == 't'
|| buf->b_p_bt[0] == 'p');
}

/*
Expand All @@ -5651,7 +5665,9 @@ bt_nofile(buf_T *buf)
int
bt_dontwrite(buf_T *buf)
{
return buf != NULL && (buf->b_p_bt[0] == 'n' || buf->b_p_bt[0] == 't');
return buf != NULL && (buf->b_p_bt[0] == 'n'
|| buf->b_p_bt[0] == 't'
|| buf->b_p_bt[0] == 'p');
}

int
Expand Down
34 changes: 34 additions & 0 deletions src/channel.c
Expand Up @@ -5836,4 +5836,38 @@ job_stop(job_T *job, typval_T *argvars, char *type)
return 1;
}

void
invoke_prompt_callback(void)
{
typval_T rettv;
int dummy;
typval_T argv[2];
char_u *text;
char_u *prompt;
linenr_T lnum = curbuf->b_ml.ml_line_count;

// Add a new line for the prompt before invoking the callback, so that
// text can always be inserted above the last line.
ml_append(lnum, (char_u *)"", 0, FALSE);
curwin->w_cursor.lnum = lnum + 1;
curwin->w_cursor.col = 0;

if (curbuf->b_prompt_callback == NULL)
return;
text = ml_get(lnum);
prompt = prompt_text();
if (STRLEN(text) >= STRLEN(prompt))
text += STRLEN(prompt);
argv[0].v_type = VAR_STRING;
argv[0].vval.v_string = vim_strsave(text);
argv[1].v_type = VAR_UNKNOWN;

call_func(curbuf->b_prompt_callback,
(int)STRLEN(curbuf->b_prompt_callback),
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
curbuf->b_prompt_partial, NULL);
clear_tv(&argv[0]);
clear_tv(&rettv);
}

#endif /* FEAT_JOB_CHANNEL */
7 changes: 7 additions & 0 deletions src/diff.c
Expand Up @@ -2141,6 +2141,13 @@ nv_diffgetput(int put, long count)
exarg_T ea;
char_u buf[30];

#ifdef FEAT_JOB_CHANNEL
if (bt_prompt(curbuf))
{
vim_beep(BO_OPER);
return;
}
#endif
if (count == 0)
ea.arg = (char_u *)"";
else
Expand Down

0 comments on commit f273245

Please sign in to comment.