forked from aniani/vim
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Problem: Difficult to make a plugin that feeds a line to a job. Solution: Add the nitial code for the "prompt" buftype.
This commit is contained in:
@@ -22,6 +22,7 @@ The Netbeans interface also uses a channel. |netbeans|
|
|||||||
9. Starting a job without a channel |job-start-nochannel|
|
9. Starting a job without a channel |job-start-nochannel|
|
||||||
10. Job options |job-options|
|
10. Job options |job-options|
|
||||||
11. Controlling a job |job-control|
|
11. Controlling a job |job-control|
|
||||||
|
12. Using a prompt buffer |prompt-buffer|
|
||||||
|
|
||||||
{Vi does not have any of these features}
|
{Vi does not have any of these features}
|
||||||
{only when compiled with the |+channel| feature for channel stuff}
|
{only when compiled with the |+channel| feature for channel stuff}
|
||||||
@@ -770,5 +771,43 @@ signals. E.g. to force a job to stop, "kill it": >
|
|||||||
|
|
||||||
For more options see |job_stop()|.
|
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:
|
vim:tw=78:ts=8:ft=help:norl:
|
||||||
|
|||||||
@@ -2294,6 +2294,9 @@ perleval({expr}) any evaluate |Perl| expression
|
|||||||
pow({x}, {y}) Float {x} to the power of {y}
|
pow({x}, {y}) Float {x} to the power of {y}
|
||||||
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
|
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
|
||||||
printf({fmt}, {expr1}...) String format text
|
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
|
pumvisible() Number whether popup menu is visible
|
||||||
pyeval({expr}) any evaluate |Python| expression
|
pyeval({expr}) any evaluate |Python| expression
|
||||||
py3eval({expr}) any evaluate |python3| expression
|
py3eval({expr}) any evaluate |python3| expression
|
||||||
@@ -2302,7 +2305,7 @@ range({expr} [, {max} [, {stride}]])
|
|||||||
List items from {expr} to {max}
|
List items from {expr} to {max}
|
||||||
readfile({fname} [, {binary} [, {max}]])
|
readfile({fname} [, {binary} [, {max}]])
|
||||||
List get list of lines from file {fname}
|
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
|
reg_recording() String get the recording register name
|
||||||
reltime([{start} [, {end}]]) List get time value
|
reltime([{start} [, {end}]]) List get time value
|
||||||
reltimefloat({time}) Float turn the time value into a Float
|
reltimefloat({time}) Float turn the time value into a Float
|
||||||
@@ -4650,7 +4653,7 @@ getline({lnum} [, {end}])
|
|||||||
from the current buffer. Example: >
|
from the current buffer. Example: >
|
||||||
getline(1)
|
getline(1)
|
||||||
< When {lnum} is a String that doesn't start with a
|
< 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: >
|
To get the line under the cursor: >
|
||||||
getline(".")
|
getline(".")
|
||||||
< When {lnum} is smaller than 1 or bigger than the number of
|
< When {lnum} is smaller than 1 or bigger than the number of
|
||||||
@@ -6475,6 +6478,42 @@ printf({fmt}, {expr1} ...) *printf()*
|
|||||||
arguments an error is given. Up to 18 arguments can be used.
|
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()*
|
pumvisible() *pumvisible()*
|
||||||
Returns non-zero when the popup menu is visible, zero
|
Returns non-zero when the popup menu is visible, zero
|
||||||
otherwise. See |ins-completion-menu|.
|
otherwise. See |ins-completion-menu|.
|
||||||
|
|||||||
@@ -1394,6 +1394,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
manually)
|
manually)
|
||||||
terminal buffer for a |terminal| (you are not supposed to set
|
terminal buffer for a |terminal| (you are not supposed to set
|
||||||
this manually)
|
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
|
This option is used together with 'bufhidden' and 'swapfile' to
|
||||||
specify special kinds of buffers. See |special-buffers|.
|
specify special kinds of buffers. See |special-buffers|.
|
||||||
@@ -4264,7 +4267,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
'imactivatefunc' 'imaf' string (default "")
|
'imactivatefunc' 'imaf' string (default "")
|
||||||
global
|
global
|
||||||
{not in Vi}
|
{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
|
This option specifies a function that will be called to
|
||||||
activate or deactivate the Input Method.
|
activate or deactivate the Input Method.
|
||||||
It is not used in the GUI.
|
It is not used in the GUI.
|
||||||
@@ -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)
|
'imcmdline' 'imc' boolean (default off)
|
||||||
global
|
global
|
||||||
{not in Vi}
|
{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
|
When set the Input Method is always on when starting to edit a command
|
||||||
line, unless entering a search pattern (see 'imsearch' for that).
|
line, unless entering a search pattern (see 'imsearch' for that).
|
||||||
Setting this option is useful when your input method allows entering
|
Setting this option is useful when your input method allows entering
|
||||||
@@ -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))
|
'imdisable' 'imd' boolean (default off, on for some systems (SGI))
|
||||||
global
|
global
|
||||||
{not in Vi}
|
{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
|
When set the Input Method is never used. This is useful to disable
|
||||||
the IM when it doesn't work properly.
|
the IM when it doesn't work properly.
|
||||||
Currently this option is on by default for SGI/IRIX machines. This
|
Currently this option is on by default for SGI/IRIX machines. This
|
||||||
@@ -4380,7 +4386,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
'imstatusfunc' 'imsf' string (default "")
|
'imstatusfunc' 'imsf' string (default "")
|
||||||
global
|
global
|
||||||
{not in Vi}
|
{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
|
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.
|
of Input Method. It must return a positive number when IME is active.
|
||||||
It is not used in the GUI.
|
It is not used in the GUI.
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ browser use: https://github.com/vim/vim/issues/1234
|
|||||||
*known-bugs*
|
*known-bugs*
|
||||||
-------------------- Known bugs and current work -----------------------
|
-------------------- Known bugs and current work -----------------------
|
||||||
|
|
||||||
|
Prompt buffer:
|
||||||
|
- Add a command line history.
|
||||||
|
- delay next prompt until plugin gives OK?
|
||||||
|
|
||||||
Terminal emulator window:
|
Terminal emulator window:
|
||||||
- Win32: Termdebug doesn't work, because gdb does not support mi2 on a tty.
|
- 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,
|
This plugin: https://github.com/cpiger/NeoDebug runs gdb as a job,
|
||||||
@@ -71,9 +75,15 @@ 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'.
|
On Win32 when not in the console and t_Co >= 256, allow using 'tgc'.
|
||||||
(Nobuhiro Takasaki, #2833) Also check t_Co.
|
(Nobuhiro Takasaki, #2833) Also check t_Co.
|
||||||
|
|
||||||
balloon_show() does not work properly in the terminal. (Ben Jackson, 2017 Dec
|
Patch to fix arguments of :edit. (Dominique Pelle, 2018 May 28 #2966)
|
||||||
20, #2481)
|
|
||||||
Also see #2352, want better control over balloon, perhaps set the position.
|
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:
|
Errors found with random data:
|
||||||
heap-buffer-overflow in alist_add (#2472)
|
heap-buffer-overflow in alist_add (#2472)
|
||||||
@@ -81,6 +91,22 @@ Errors found with random data:
|
|||||||
More warnings from static analysis:
|
More warnings from static analysis:
|
||||||
https://lgtm.com/projects/g/vim/vim/alerts/?mode=list
|
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
|
Script generated by :mksession does not work well if there are windows with
|
||||||
modified buffers
|
modified buffers
|
||||||
change "silent only" into "silent only!"
|
change "silent only" into "silent only!"
|
||||||
@@ -88,16 +114,27 @@ modified buffers
|
|||||||
skip "badd fname" if "fname" is already in the buffer list
|
skip "badd fname" if "fname" is already in the buffer list
|
||||||
remove remark about unloading buffers from documentation
|
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):
|
Compiler warnings (geeknik, 2017 Oct 26):
|
||||||
- signed integer overflow in do_sub() (#2249)
|
- signed integer overflow in do_sub() (#2249)
|
||||||
- signed integer overflow in get_address() (#2248)
|
- signed integer overflow in get_address() (#2248)
|
||||||
- signed integer overflow in getdecchrs() (#2254)
|
- signed integer overflow in getdecchrs() (#2254)
|
||||||
- undefined left shift in get_string_tv() (#2250)
|
- undefined left shift in get_string_tv() (#2250)
|
||||||
|
|
||||||
|
Patch for more quickfix refactoring. (Yegappan Lakshmanan, #2950)
|
||||||
|
|
||||||
Tests failing for "make testgui" with GTK:
|
Tests failing for "make testgui" with GTK:
|
||||||
- Test_setbufvar_options()
|
- Test_setbufvar_options()
|
||||||
- Test_exit_callback_interval()
|
- 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:
|
Try out background make plugin:
|
||||||
https://github.com/AndrewVos/vim-make-background
|
https://github.com/AndrewVos/vim-make-background
|
||||||
or asyncmake:
|
or asyncmake:
|
||||||
@@ -112,6 +149,8 @@ used for git temp files.
|
|||||||
|
|
||||||
Cursor in wrong position when line wraps. (#2540)
|
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
|
Add an option similar to 'lazyredraw' to skip redrawing while executing a
|
||||||
script or function.
|
script or function.
|
||||||
|
|
||||||
@@ -141,6 +180,9 @@ How to test that it works well for all Vim users?
|
|||||||
|
|
||||||
Alternative manpager.vim. (Enno, 2018 Jan 5, #2529)
|
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
|
Does setting 'cursorline' cause syntax highlighting to slow down? Perhaps is
|
||||||
mess up the cache? (Mike Lee Williams, 2018 Jan 27, #2539)
|
mess up the cache? (Mike Lee Williams, 2018 Jan 27, #2539)
|
||||||
Also: 'foldtext' is evaluated too often. (Daniel Hahler, #2773)
|
Also: 'foldtext' is evaluated too often. (Daniel Hahler, #2773)
|
||||||
|
|||||||
@@ -2252,6 +2252,7 @@ test_arglist \
|
|||||||
test_popup \
|
test_popup \
|
||||||
test_preview \
|
test_preview \
|
||||||
test_profile \
|
test_profile \
|
||||||
|
test_prompt_buffer \
|
||||||
test_put \
|
test_put \
|
||||||
test_python2 \
|
test_python2 \
|
||||||
test_python3 \
|
test_python3 \
|
||||||
|
|||||||
20
src/buffer.c
20
src/buffer.c
@@ -851,6 +851,10 @@ free_buffer(buf_T *buf)
|
|||||||
#ifdef FEAT_TERMINAL
|
#ifdef FEAT_TERMINAL
|
||||||
free_terminal(buf);
|
free_terminal(buf);
|
||||||
#endif
|
#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);
|
buf_hashtab_remove(buf);
|
||||||
|
|
||||||
@@ -5633,6 +5637,15 @@ bt_help(buf_T *buf)
|
|||||||
return buf != NULL && buf->b_help;
|
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.
|
* Return TRUE if "buf" is a "nofile", "acwrite" or "terminal" buffer.
|
||||||
* This means the buffer name is not a file name.
|
* This means the buffer name is not a file name.
|
||||||
@@ -5642,7 +5655,8 @@ bt_nofile(buf_T *buf)
|
|||||||
{
|
{
|
||||||
return buf != NULL && ((buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f')
|
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] == 'a'
|
||||||
|| buf->b_p_bt[0] == 't');
|
|| buf->b_p_bt[0] == 't'
|
||||||
|
|| buf->b_p_bt[0] == 'p');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5651,7 +5665,9 @@ bt_nofile(buf_T *buf)
|
|||||||
int
|
int
|
||||||
bt_dontwrite(buf_T *buf)
|
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
|
int
|
||||||
|
|||||||
@@ -5836,4 +5836,38 @@ job_stop(job_T *job, typval_T *argvars, char *type)
|
|||||||
return 1;
|
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 */
|
#endif /* FEAT_JOB_CHANNEL */
|
||||||
|
|||||||
@@ -2141,6 +2141,13 @@ nv_diffgetput(int put, long count)
|
|||||||
exarg_T ea;
|
exarg_T ea;
|
||||||
char_u buf[30];
|
char_u buf[30];
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf))
|
||||||
|
{
|
||||||
|
vim_beep(BO_OPER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
ea.arg = (char_u *)"";
|
ea.arg = (char_u *)"";
|
||||||
else
|
else
|
||||||
|
|||||||
78
src/edit.c
78
src/edit.c
@@ -203,6 +203,9 @@ static unsigned quote_meta(char_u *dest, char_u *str, int len);
|
|||||||
|
|
||||||
static void ins_redraw(int ready);
|
static void ins_redraw(int ready);
|
||||||
static void ins_ctrl_v(void);
|
static void ins_ctrl_v(void);
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
static void init_prompt(int cmdchar_todo);
|
||||||
|
#endif
|
||||||
static void undisplay_dollar(void);
|
static void undisplay_dollar(void);
|
||||||
static void insert_special(int, int, int);
|
static void insert_special(int, int, int);
|
||||||
static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c);
|
static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c);
|
||||||
@@ -351,6 +354,9 @@ edit(
|
|||||||
int inserted_space = FALSE; /* just inserted a space */
|
int inserted_space = FALSE; /* just inserted a space */
|
||||||
int replaceState = REPLACE;
|
int replaceState = REPLACE;
|
||||||
int nomove = FALSE; /* don't move cursor on return */
|
int nomove = FALSE; /* don't move cursor on return */
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
int cmdchar_todo = cmdchar;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Remember whether editing was restarted after CTRL-O. */
|
/* Remember whether editing was restarted after CTRL-O. */
|
||||||
did_restart_edit = restart_edit;
|
did_restart_edit = restart_edit;
|
||||||
@@ -707,6 +713,14 @@ edit(
|
|||||||
foldCheckClose();
|
foldCheckClose();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf))
|
||||||
|
{
|
||||||
|
init_prompt(cmdchar_todo);
|
||||||
|
cmdchar_todo = NUL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we inserted a character at the last position of the last line in
|
* If we inserted a character at the last position of the last line in
|
||||||
* the window, scroll the window one line up. This avoids an extra
|
* the window, scroll the window one line up. This avoids an extra
|
||||||
@@ -1373,6 +1387,18 @@ doESCkey:
|
|||||||
cmdwin_result = CAR;
|
cmdwin_result = CAR;
|
||||||
goto doESCkey;
|
goto doESCkey;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf))
|
||||||
|
{
|
||||||
|
buf_T *buf = curbuf;
|
||||||
|
|
||||||
|
invoke_prompt_callback();
|
||||||
|
if (curbuf != buf)
|
||||||
|
// buffer changed, get out of Insert mode
|
||||||
|
goto doESCkey;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ins_eol(c) == FAIL && !p_im)
|
if (ins_eol(c) == FAIL && !p_im)
|
||||||
goto doESCkey; /* out of memory */
|
goto doESCkey; /* out of memory */
|
||||||
@@ -1808,6 +1834,58 @@ edit_putchar(int c, int highlight)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_prompt(int cmdchar_todo)
|
||||||
|
{
|
||||||
|
char_u *prompt = prompt_text();
|
||||||
|
char_u *text;
|
||||||
|
|
||||||
|
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
|
||||||
|
text = ml_get_curline();
|
||||||
|
if (STRNCMP(text, prompt, STRLEN(prompt)) != 0)
|
||||||
|
{
|
||||||
|
// prompt is missing, insert it or append a line with it
|
||||||
|
if (*text == NUL)
|
||||||
|
ml_replace(curbuf->b_ml.ml_line_count, prompt, TRUE);
|
||||||
|
else
|
||||||
|
ml_append(curbuf->b_ml.ml_line_count, prompt, 0, FALSE);
|
||||||
|
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
|
||||||
|
coladvance((colnr_T)MAXCOL);
|
||||||
|
changed_bytes(curbuf->b_ml.ml_line_count, 0);
|
||||||
|
}
|
||||||
|
if (cmdchar_todo == 'A')
|
||||||
|
coladvance((colnr_T)MAXCOL);
|
||||||
|
if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt))
|
||||||
|
curwin->w_cursor.col = STRLEN(prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if the cursor is in the editable position of the prompt line.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
prompt_curpos_editable()
|
||||||
|
{
|
||||||
|
return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count
|
||||||
|
&& curwin->w_cursor.col >= (int)STRLEN(prompt_text());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Undo the previous edit_putchar().
|
* Undo the previous edit_putchar().
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -294,6 +294,10 @@ static void f_pow(typval_T *argvars, typval_T *rettv);
|
|||||||
#endif
|
#endif
|
||||||
static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
|
static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_printf(typval_T *argvars, typval_T *rettv);
|
static void f_printf(typval_T *argvars, typval_T *rettv);
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv);
|
||||||
|
#endif
|
||||||
static void f_pumvisible(typval_T *argvars, typval_T *rettv);
|
static void f_pumvisible(typval_T *argvars, typval_T *rettv);
|
||||||
#ifdef FEAT_PYTHON3
|
#ifdef FEAT_PYTHON3
|
||||||
static void f_py3eval(typval_T *argvars, typval_T *rettv);
|
static void f_py3eval(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -744,6 +748,10 @@ static struct fst
|
|||||||
#endif
|
#endif
|
||||||
{"prevnonblank", 1, 1, f_prevnonblank},
|
{"prevnonblank", 1, 1, f_prevnonblank},
|
||||||
{"printf", 1, 19, f_printf},
|
{"printf", 1, 19, f_printf},
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
{"prompt_setcallback", 2, 2, f_prompt_setcallback},
|
||||||
|
{"prompt_setprompt", 2, 2, f_prompt_setprompt},
|
||||||
|
#endif
|
||||||
{"pumvisible", 0, 0, f_pumvisible},
|
{"pumvisible", 0, 0, f_pumvisible},
|
||||||
#ifdef FEAT_PYTHON3
|
#ifdef FEAT_PYTHON3
|
||||||
{"py3eval", 1, 1, f_py3eval},
|
{"py3eval", 1, 1, f_py3eval},
|
||||||
@@ -1240,6 +1248,11 @@ f_append(typval_T *argvars, typval_T *rettv)
|
|||||||
appended_lines_mark(lnum, added);
|
appended_lines_mark(lnum, added);
|
||||||
if (curwin->w_cursor.lnum > lnum)
|
if (curwin->w_cursor.lnum > lnum)
|
||||||
curwin->w_cursor.lnum += added;
|
curwin->w_cursor.lnum += added;
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf) && (State & INSERT))
|
||||||
|
// show the line with the prompt
|
||||||
|
update_topline();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rettv->vval.v_number = 1; /* Failed */
|
rettv->vval.v_number = 1; /* Failed */
|
||||||
@@ -8379,6 +8392,57 @@ f_printf(typval_T *argvars, typval_T *rettv)
|
|||||||
did_emsg |= saved_did_emsg;
|
did_emsg |= saved_did_emsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
/*
|
||||||
|
* "prompt_setcallback({buffer}, {callback})" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
buf_T *buf;
|
||||||
|
char_u *callback;
|
||||||
|
partial_T *partial;
|
||||||
|
|
||||||
|
if (check_secure())
|
||||||
|
return;
|
||||||
|
buf = get_buf_tv(&argvars[0], FALSE);
|
||||||
|
if (buf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
callback = get_callback(&argvars[1], &partial);
|
||||||
|
if (callback == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free_callback(buf->b_prompt_callback, buf->b_prompt_partial);
|
||||||
|
if (partial == NULL)
|
||||||
|
buf->b_prompt_callback = vim_strsave(callback);
|
||||||
|
else
|
||||||
|
/* pointer into the partial */
|
||||||
|
buf->b_prompt_callback = callback;
|
||||||
|
buf->b_prompt_partial = partial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "prompt_setprompt({buffer}, {text})" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_prompt_setprompt(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
buf_T *buf;
|
||||||
|
char_u *text;
|
||||||
|
|
||||||
|
if (check_secure())
|
||||||
|
return;
|
||||||
|
buf = get_buf_tv(&argvars[0], FALSE);
|
||||||
|
if (buf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
text = get_tv_string(&argvars[1]);
|
||||||
|
vim_free(buf->b_prompt_text);
|
||||||
|
buf->b_prompt_text = vim_strsave(text);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "pumvisible()" function
|
* "pumvisible()" function
|
||||||
*/
|
*/
|
||||||
|
|||||||
65
src/normal.c
65
src/normal.c
@@ -4180,6 +4180,11 @@ nv_help(cmdarg_T *cap)
|
|||||||
static void
|
static void
|
||||||
nv_addsub(cmdarg_T *cap)
|
nv_addsub(cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf) && !prompt_curpos_editable())
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (!VIsual_active && cap->oap->op_type == OP_NOP)
|
if (!VIsual_active && cap->oap->op_type == OP_NOP)
|
||||||
{
|
{
|
||||||
prep_redo_cmd(cap);
|
prep_redo_cmd(cap);
|
||||||
@@ -6213,6 +6218,17 @@ nv_down(cmdarg_T *cap)
|
|||||||
if (cmdwin_type != 0 && cap->cmdchar == CAR)
|
if (cmdwin_type != 0 && cap->cmdchar == CAR)
|
||||||
cmdwin_result = CAR;
|
cmdwin_result = CAR;
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
/* In a prompt buffer a <CR> in the last line invokes the callback. */
|
||||||
|
if (bt_prompt(curbuf) && cap->cmdchar == CAR
|
||||||
|
&& curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
|
||||||
|
{
|
||||||
|
invoke_prompt_callback();
|
||||||
|
if (restart_edit == 0)
|
||||||
|
restart_edit = 'a';
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
cap->oap->motion_type = MLINE;
|
cap->oap->motion_type = MLINE;
|
||||||
@@ -6972,6 +6988,13 @@ nv_kundo(cmdarg_T *cap)
|
|||||||
{
|
{
|
||||||
if (!checkclearopq(cap->oap))
|
if (!checkclearopq(cap->oap))
|
||||||
{
|
{
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf))
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
u_undo((int)cap->count1);
|
u_undo((int)cap->count1);
|
||||||
curwin->w_set_curswant = TRUE;
|
curwin->w_set_curswant = TRUE;
|
||||||
}
|
}
|
||||||
@@ -6989,6 +7012,13 @@ nv_replace(cmdarg_T *cap)
|
|||||||
|
|
||||||
if (checkclearop(cap->oap))
|
if (checkclearop(cap->oap))
|
||||||
return;
|
return;
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf) && !prompt_curpos_editable())
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get another character */
|
/* get another character */
|
||||||
if (cap->nchar == Ctrl_V)
|
if (cap->nchar == Ctrl_V)
|
||||||
@@ -7464,6 +7494,13 @@ nv_subst(cmdarg_T *cap)
|
|||||||
/* When showing output of term_dumpdiff() swap the top and botom. */
|
/* When showing output of term_dumpdiff() swap the top and botom. */
|
||||||
if (term_swap_diff() == OK)
|
if (term_swap_diff() == OK)
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf) && !prompt_curpos_editable())
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (VIsual_active) /* "vs" and "vS" are the same as "vc" */
|
if (VIsual_active) /* "vs" and "vS" are the same as "vc" */
|
||||||
{
|
{
|
||||||
@@ -8570,7 +8607,16 @@ nv_Undo(cmdarg_T *cap)
|
|||||||
nv_tilde(cmdarg_T *cap)
|
nv_tilde(cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
if (!p_to && !VIsual_active && cap->oap->op_type != OP_TILDE)
|
if (!p_to && !VIsual_active && cap->oap->op_type != OP_TILDE)
|
||||||
|
{
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf) && !prompt_curpos_editable())
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
n_swapchar(cap);
|
n_swapchar(cap);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
nv_operator(cap);
|
nv_operator(cap);
|
||||||
}
|
}
|
||||||
@@ -8585,6 +8631,13 @@ nv_operator(cmdarg_T *cap)
|
|||||||
int op_type;
|
int op_type;
|
||||||
|
|
||||||
op_type = get_op_type(cap->cmdchar, cap->nchar);
|
op_type = get_op_type(cap->cmdchar, cap->nchar);
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (bt_prompt(curbuf) && op_is_change(op_type) && !prompt_curpos_editable())
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (op_type == cap->oap->op_type) /* double operator works on lines */
|
if (op_type == cap->oap->op_type) /* double operator works on lines */
|
||||||
nv_lineop(cap);
|
nv_lineop(cap);
|
||||||
@@ -9426,6 +9479,12 @@ nv_put(cmdarg_T *cap)
|
|||||||
#endif
|
#endif
|
||||||
clearopbeep(cap->oap);
|
clearopbeep(cap->oap);
|
||||||
}
|
}
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
else if (bt_prompt(curbuf) && !prompt_curpos_editable())
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dir = (cap->cmdchar == 'P'
|
dir = (cap->cmdchar == 'P'
|
||||||
@@ -9551,6 +9610,12 @@ nv_open(cmdarg_T *cap)
|
|||||||
#endif
|
#endif
|
||||||
if (VIsual_active) /* switch start and end of visual */
|
if (VIsual_active) /* switch start and end of visual */
|
||||||
v_swap_corners(cap->cmdchar);
|
v_swap_corners(cap->cmdchar);
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
else if (bt_prompt(curbuf))
|
||||||
|
{
|
||||||
|
clearopbeep(cap->oap);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
n_opencmd(cap);
|
n_opencmd(cap);
|
||||||
}
|
}
|
||||||
|
|||||||
77
src/ops.c
77
src/ops.c
@@ -126,43 +126,47 @@ static int fmt_check_par(linenr_T, int *, char_u **, int do_comments);
|
|||||||
static int fmt_check_par(linenr_T);
|
static int fmt_check_par(linenr_T);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Flags for third item in "opchars".
|
||||||
|
#define OPF_LINES 1 // operator always works on lines
|
||||||
|
#define OPF_CHANGE 2 // operator changes text
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The names of operators.
|
* The names of operators.
|
||||||
* IMPORTANT: Index must correspond with defines in vim.h!!!
|
* IMPORTANT: Index must correspond with defines in vim.h!!!
|
||||||
* The third field indicates whether the operator always works on lines.
|
* The third field holds OPF_ flags.
|
||||||
*/
|
*/
|
||||||
static char opchars[][3] =
|
static char opchars[][3] =
|
||||||
{
|
{
|
||||||
{NUL, NUL, FALSE}, /* OP_NOP */
|
{NUL, NUL, 0}, // OP_NOP
|
||||||
{'d', NUL, FALSE}, /* OP_DELETE */
|
{'d', NUL, OPF_CHANGE}, // OP_DELETE
|
||||||
{'y', NUL, FALSE}, /* OP_YANK */
|
{'y', NUL, 0}, // OP_YANK
|
||||||
{'c', NUL, FALSE}, /* OP_CHANGE */
|
{'c', NUL, OPF_CHANGE}, // OP_CHANGE
|
||||||
{'<', NUL, TRUE}, /* OP_LSHIFT */
|
{'<', NUL, OPF_LINES | OPF_CHANGE}, // OP_LSHIFT
|
||||||
{'>', NUL, TRUE}, /* OP_RSHIFT */
|
{'>', NUL, OPF_LINES | OPF_CHANGE}, // OP_RSHIFT
|
||||||
{'!', NUL, TRUE}, /* OP_FILTER */
|
{'!', NUL, OPF_LINES | OPF_CHANGE}, // OP_FILTER
|
||||||
{'g', '~', FALSE}, /* OP_TILDE */
|
{'g', '~', OPF_CHANGE}, // OP_TILDE
|
||||||
{'=', NUL, TRUE}, /* OP_INDENT */
|
{'=', NUL, OPF_LINES | OPF_CHANGE}, // OP_INDENT
|
||||||
{'g', 'q', TRUE}, /* OP_FORMAT */
|
{'g', 'q', OPF_LINES | OPF_CHANGE}, // OP_FORMAT
|
||||||
{':', NUL, TRUE}, /* OP_COLON */
|
{':', NUL, OPF_LINES}, // OP_COLON
|
||||||
{'g', 'U', FALSE}, /* OP_UPPER */
|
{'g', 'U', OPF_CHANGE}, // OP_UPPER
|
||||||
{'g', 'u', FALSE}, /* OP_LOWER */
|
{'g', 'u', OPF_CHANGE}, // OP_LOWER
|
||||||
{'J', NUL, TRUE}, /* DO_JOIN */
|
{'J', NUL, OPF_LINES | OPF_CHANGE}, // DO_JOIN
|
||||||
{'g', 'J', TRUE}, /* DO_JOIN_NS */
|
{'g', 'J', OPF_LINES | OPF_CHANGE}, // DO_JOIN_NS
|
||||||
{'g', '?', FALSE}, /* OP_ROT13 */
|
{'g', '?', OPF_CHANGE}, // OP_ROT13
|
||||||
{'r', NUL, FALSE}, /* OP_REPLACE */
|
{'r', NUL, OPF_CHANGE}, // OP_REPLACE
|
||||||
{'I', NUL, FALSE}, /* OP_INSERT */
|
{'I', NUL, OPF_CHANGE}, // OP_INSERT
|
||||||
{'A', NUL, FALSE}, /* OP_APPEND */
|
{'A', NUL, OPF_CHANGE}, // OP_APPEND
|
||||||
{'z', 'f', TRUE}, /* OP_FOLD */
|
{'z', 'f', OPF_LINES}, // OP_FOLD
|
||||||
{'z', 'o', TRUE}, /* OP_FOLDOPEN */
|
{'z', 'o', OPF_LINES}, // OP_FOLDOPEN
|
||||||
{'z', 'O', TRUE}, /* OP_FOLDOPENREC */
|
{'z', 'O', OPF_LINES}, // OP_FOLDOPENREC
|
||||||
{'z', 'c', TRUE}, /* OP_FOLDCLOSE */
|
{'z', 'c', OPF_LINES}, // OP_FOLDCLOSE
|
||||||
{'z', 'C', TRUE}, /* OP_FOLDCLOSEREC */
|
{'z', 'C', OPF_LINES}, // OP_FOLDCLOSEREC
|
||||||
{'z', 'd', TRUE}, /* OP_FOLDDEL */
|
{'z', 'd', OPF_LINES}, // OP_FOLDDEL
|
||||||
{'z', 'D', TRUE}, /* OP_FOLDDELREC */
|
{'z', 'D', OPF_LINES}, // OP_FOLDDELREC
|
||||||
{'g', 'w', TRUE}, /* OP_FORMAT2 */
|
{'g', 'w', OPF_LINES | OPF_CHANGE}, // OP_FORMAT2
|
||||||
{'g', '@', FALSE}, /* OP_FUNCTION */
|
{'g', '@', OPF_CHANGE}, // OP_FUNCTION
|
||||||
{Ctrl_A, NUL, FALSE}, /* OP_NR_ADD */
|
{Ctrl_A, NUL, OPF_CHANGE}, // OP_NR_ADD
|
||||||
{Ctrl_X, NUL, FALSE}, /* OP_NR_SUB */
|
{Ctrl_X, NUL, OPF_CHANGE}, // OP_NR_SUB
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -201,7 +205,16 @@ get_op_type(int char1, int char2)
|
|||||||
int
|
int
|
||||||
op_on_lines(int op)
|
op_on_lines(int op)
|
||||||
{
|
{
|
||||||
return opchars[op][2];
|
return opchars[op][2] & OPF_LINES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if operator "op" changes text.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
op_is_change(int op)
|
||||||
|
{
|
||||||
|
return opchars[op][2] & OPF_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -3229,7 +3229,7 @@ static char *(p_bsdir_values[]) = {"current", "last", "buffer", NULL};
|
|||||||
static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
|
static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
|
||||||
static char *(p_debug_values[]) = {"msg", "throw", "beep", NULL};
|
static char *(p_debug_values[]) = {"msg", "throw", "beep", NULL};
|
||||||
static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
|
static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
|
||||||
static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", "terminal", "acwrite", NULL};
|
static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", "terminal", "acwrite", "prompt", NULL};
|
||||||
static char *(p_bufhidden_values[]) = {"hide", "unload", "delete", "wipe", NULL};
|
static char *(p_bufhidden_values[]) = {"hide", "unload", "delete", "wipe", NULL};
|
||||||
static char *(p_bs_values[]) = {"indent", "eol", "start", NULL};
|
static char *(p_bs_values[]) = {"indent", "eol", "start", NULL};
|
||||||
#ifdef FEAT_FOLDING
|
#ifdef FEAT_FOLDING
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ void write_viminfo_bufferlist(FILE *fp);
|
|||||||
int bt_quickfix(buf_T *buf);
|
int bt_quickfix(buf_T *buf);
|
||||||
int bt_terminal(buf_T *buf);
|
int bt_terminal(buf_T *buf);
|
||||||
int bt_help(buf_T *buf);
|
int bt_help(buf_T *buf);
|
||||||
|
int bt_prompt(buf_T *buf);
|
||||||
int bt_nofile(buf_T *buf);
|
int bt_nofile(buf_T *buf);
|
||||||
int bt_dontwrite(buf_T *buf);
|
int bt_dontwrite(buf_T *buf);
|
||||||
int bt_dontwrite_msg(buf_T *buf);
|
int bt_dontwrite_msg(buf_T *buf);
|
||||||
|
|||||||
@@ -71,4 +71,5 @@ char *job_status(job_T *job);
|
|||||||
void job_info(job_T *job, dict_T *dict);
|
void job_info(job_T *job, dict_T *dict);
|
||||||
void job_info_all(list_T *l);
|
void job_info_all(list_T *l);
|
||||||
int job_stop(job_T *job, typval_T *argvars, char *type);
|
int job_stop(job_T *job, typval_T *argvars, char *type);
|
||||||
|
void invoke_prompt_callback(void);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/* edit.c */
|
/* edit.c */
|
||||||
int edit(int cmdchar, int startln, long count);
|
int edit(int cmdchar, int startln, long count);
|
||||||
void edit_putchar(int c, int highlight);
|
void edit_putchar(int c, int highlight);
|
||||||
|
char_u *prompt_text(void);
|
||||||
|
int prompt_curpos_editable(void);
|
||||||
void edit_unputchar(void);
|
void edit_unputchar(void);
|
||||||
void display_dollar(colnr_T col);
|
void display_dollar(colnr_T col);
|
||||||
void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes);
|
void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* ops.c */
|
/* ops.c */
|
||||||
int get_op_type(int char1, int char2);
|
int get_op_type(int char1, int char2);
|
||||||
int op_on_lines(int op);
|
int op_on_lines(int op);
|
||||||
|
int op_is_change(int op);
|
||||||
int get_op_char(int optype);
|
int get_op_char(int optype);
|
||||||
int get_extra_op_char(int optype);
|
int get_extra_op_char(int optype);
|
||||||
void op_shift(oparg_T *oap, int curs_top, int amount);
|
void op_shift(oparg_T *oap, int curs_top, int amount);
|
||||||
|
|||||||
@@ -2356,6 +2356,11 @@ struct file_buffer
|
|||||||
|
|
||||||
int b_shortname; /* this file has an 8.3 file name */
|
int b_shortname; /* this file has an 8.3 file name */
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
char_u *b_prompt_text; // set by prompt_setprompt()
|
||||||
|
char_u *b_prompt_callback; // set by prompt_setcallback()
|
||||||
|
partial_T *b_prompt_partial; // set by prompt_setcallback()
|
||||||
|
#endif
|
||||||
#ifdef FEAT_MZSCHEME
|
#ifdef FEAT_MZSCHEME
|
||||||
void *b_mzscheme_ref; /* The MzScheme reference to this buffer */
|
void *b_mzscheme_ref; /* The MzScheme reference to this buffer */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ NEW_TESTS = test_arabic.res \
|
|||||||
test_perl.res \
|
test_perl.res \
|
||||||
test_plus_arg_edit.res \
|
test_plus_arg_edit.res \
|
||||||
test_preview.res \
|
test_preview.res \
|
||||||
|
test_prompt_buffer.res \
|
||||||
test_profile.res \
|
test_profile.res \
|
||||||
test_python2.res \
|
test_python2.res \
|
||||||
test_python3.res \
|
test_python3.res \
|
||||||
|
|||||||
@@ -5,19 +5,18 @@ if exists('*CanRunVimInTerminal')
|
|||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Need to be able to run terminal Vim with 256 colors. On MS-Windows the
|
" For most tests we need to be able to run terminal Vim with 256 colors. On
|
||||||
" console only has 16 colors and the GUI can't run in a terminal.
|
" MS-Windows the console only has 16 colors and the GUI can't run in a
|
||||||
if !has('terminal') || has('win32')
|
" terminal.
|
||||||
func CanRunVimInTerminal()
|
func CanRunVimInTerminal()
|
||||||
return 0
|
return has('terminal') && !has('win32')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Skip the rest if there is no terminal feature at all.
|
||||||
|
if !has('terminal')
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
func CanRunVimInTerminal()
|
|
||||||
return 1
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
source shared.vim
|
source shared.vim
|
||||||
|
|
||||||
" Run Vim with "arguments" in a new terminal window.
|
" Run Vim with "arguments" in a new terminal window.
|
||||||
@@ -54,6 +53,7 @@ func RunVimInTerminal(arguments, options)
|
|||||||
let cols = get(a:options, 'cols', 75)
|
let cols = get(a:options, 'cols', 75)
|
||||||
|
|
||||||
let cmd = GetVimCommandClean()
|
let cmd = GetVimCommandClean()
|
||||||
|
|
||||||
" Add -v to have gvim run in the terminal (if possible)
|
" Add -v to have gvim run in the terminal (if possible)
|
||||||
let cmd .= ' -v ' . a:arguments
|
let cmd .= ' -v ' . a:arguments
|
||||||
let buf = term_start(cmd, {'curwin': 1, 'term_rows': rows, 'term_cols': cols})
|
let buf = term_start(cmd, {'curwin': 1, 'term_rows': rows, 'term_cols': cols})
|
||||||
@@ -64,11 +64,12 @@ func RunVimInTerminal(arguments, options)
|
|||||||
let cols = term_getsize(buf)[1]
|
let cols = term_getsize(buf)[1]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Wait for "All" or "Top" of the ruler in the status line to be shown. This
|
" Wait for "All" or "Top" of the ruler to be shown in the last line or in
|
||||||
" can be quite slow (e.g. when using valgrind).
|
" the status line of the last window. This can be quite slow (e.g. when
|
||||||
|
" using valgrind).
|
||||||
" If it fails then show the terminal contents for debugging.
|
" If it fails then show the terminal contents for debugging.
|
||||||
try
|
try
|
||||||
call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1})
|
call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - 1)) >= cols - 1})
|
||||||
catch /timed out after/
|
catch /timed out after/
|
||||||
let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
|
let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
|
||||||
call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
|
call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
|
||||||
@@ -80,7 +81,7 @@ endfunc
|
|||||||
" Stop a Vim running in terminal buffer "buf".
|
" Stop a Vim running in terminal buffer "buf".
|
||||||
func StopVimInTerminal(buf)
|
func StopVimInTerminal(buf)
|
||||||
call assert_equal("running", term_getstatus(a:buf))
|
call assert_equal("running", term_getstatus(a:buf))
|
||||||
call term_sendkeys(a:buf, "\<Esc>\<Esc>:qa!\<cr>")
|
call term_sendkeys(a:buf, "\<Esc>:qa!\<cr>")
|
||||||
call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
|
call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
|
||||||
only!
|
only!
|
||||||
endfunc
|
endfunc
|
||||||
|
|||||||
55
src/testdir/test_prompt_buffer.vim
Normal file
55
src/testdir/test_prompt_buffer.vim
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
" Tests for setting 'buftype' to "prompt"
|
||||||
|
|
||||||
|
if !has('channel')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
source shared.vim
|
||||||
|
source screendump.vim
|
||||||
|
|
||||||
|
func Test_prompt_basic()
|
||||||
|
" We need to use a terminal window to be able to feed keys without leaving
|
||||||
|
" Insert mode.
|
||||||
|
if !has('terminal')
|
||||||
|
call assert_report('no terminal')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call writefile([
|
||||||
|
\ 'func TextEntered(text)',
|
||||||
|
\ ' if a:text == "exit"',
|
||||||
|
\ ' stopinsert',
|
||||||
|
\ ' close',
|
||||||
|
\ ' else',
|
||||||
|
\ ' " Add the output above the current prompt.',
|
||||||
|
\ ' call append(line("$") - 1, "Command: \"" . a:text . "\"")',
|
||||||
|
\ ' " Reset &modified to allow the buffer to be closed.',
|
||||||
|
\ ' set nomodified',
|
||||||
|
\ ' call timer_start(20, {id -> TimerFunc(a:text)})',
|
||||||
|
\ ' endif',
|
||||||
|
\ 'endfunc',
|
||||||
|
\ '',
|
||||||
|
\ 'func TimerFunc(text)',
|
||||||
|
\ ' " Add the output above the current prompt.',
|
||||||
|
\ ' call append(line("$") - 1, "Result: \"" . a:text . "\"")',
|
||||||
|
\ 'endfunc',
|
||||||
|
\ '',
|
||||||
|
\ 'call setline(1, "other buffer")',
|
||||||
|
\ 'new',
|
||||||
|
\ 'set buftype=prompt',
|
||||||
|
\ 'call prompt_setcallback(bufnr(""), function("TextEntered"))',
|
||||||
|
\ 'startinsert',
|
||||||
|
\ ], 'Xpromptscript')
|
||||||
|
let buf = RunVimInTerminal('-S Xpromptscript', {})
|
||||||
|
call WaitForAssert({-> assert_equal('%', term_getline(buf, 1))})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "hello\<CR>")
|
||||||
|
call WaitForAssert({-> assert_equal('% hello', term_getline(buf, 1))})
|
||||||
|
call WaitForAssert({-> assert_equal('Command: "hello"', term_getline(buf, 2))})
|
||||||
|
call WaitForAssert({-> assert_equal('Result: "hello"', term_getline(buf, 3))})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "exit\<CR>")
|
||||||
|
call WaitForAssert({-> assert_equal('other buffer', term_getline(buf, 1))})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xpromptscript')
|
||||||
|
endfunc
|
||||||
@@ -761,6 +761,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
27,
|
||||||
/**/
|
/**/
|
||||||
26,
|
26,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user