==============================================================================
5. 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|.
- 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.
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. 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
to delete a word). When leaving the window Insert mode will be stopped. When
coming back to the prompt window Insert mode will be restored.
Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
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. >vim
" Function handling a line of text that has been typed.
func TextEntered(text)
" Send the text to a shell with Enter appended.
call chansend(g:shell_job, [a:text, ''])
endfunc
" Function handling output from the shell: Add it above the prompt.
func GotOutput(channel, msg, name)
call append(line("$") - 1, a:msg)
endfunc
" Function handling the shell exits: close the window.
func JobExit(job, status, event)
quit!
endfunc
" Start a shell in the background.
let shell_job = jobstart(["/bin/sh"], #{
\ on_stdout: function('GotOutput'),
\ on_stderr: function('GotOutput'),
\ on_exit: function('JobExit'),
\ })
new
set buftype=prompt
let buf = bufnr('')
call prompt_setcallback(buf, function("TextEntered"))
call prompt_setprompt(buf, "shell command: ")
" start accepting shell commands
startinsert
<
vim:tw=78:ts=8:noet:ft=help:norl: