mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
+18
-5
@@ -1,4 +1,4 @@
|
||||
*channel.txt* For Vim version 7.4. Last change: 2016 May 24
|
||||
*channel.txt* For Vim version 7.4. Last change: 2016 May 29
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -578,8 +578,8 @@ See |job_setoptions()| and |ch_setoptions()|.
|
||||
"exit_cb": handler Callback for when the job ends. The arguments are the
|
||||
job and the exit status.
|
||||
Vim checks about every 10 seconds for jobs that ended.
|
||||
The callback can also be triggered by calling
|
||||
|job_status()|.
|
||||
The check also be triggered by calling |job_status()|,
|
||||
which may then invoke the exit_cb handler.
|
||||
Note that data can be buffered, callbacks may still be
|
||||
called after the process ends.
|
||||
*job-timeout*
|
||||
@@ -625,18 +625,22 @@ See |job_setoptions()| and |ch_setoptions()|.
|
||||
"out_io": "null" disconnect stdout (goes to /dev/null)
|
||||
"out_io": "pipe" stdout is connected to the channel (default)
|
||||
"out_io": "file" stdout writes to a file
|
||||
"out_io": "buffer" stdout appends to a buffer
|
||||
"out_io": "buffer" stdout appends to a buffer (see below)
|
||||
"out_name": "/path/file" the name of the file or buffer to write to
|
||||
"out_buf": number the number of the buffer to write to
|
||||
"out_modifiable": 0 when writing to a buffer, 'modifiable' will be off
|
||||
(see below)
|
||||
|
||||
*job-err_io* *err_name* *err_buf*
|
||||
"err_io": "out" stderr messages to go to stdout
|
||||
"err_io": "null" disconnect stderr (goes to /dev/null)
|
||||
"err_io": "pipe" stderr is connected to the channel (default)
|
||||
"err_io": "file" stderr writes to a file
|
||||
"err_io": "buffer" stderr appends to a buffer
|
||||
"err_io": "buffer" stderr appends to a buffer (see below)
|
||||
"err_name": "/path/file" the name of the file or buffer to write to
|
||||
"err_buf": number the number of the buffer to write to
|
||||
"err_modifiable": 0 when writing to a buffer, 'modifiable' will be off
|
||||
(see below)
|
||||
|
||||
"block_write": number only for testing: pretend every other write to stdin
|
||||
will block
|
||||
@@ -663,6 +667,15 @@ used to get the buffer number.
|
||||
For a new buffer 'buftype' is set to "nofile" and 'bufhidden' to "hide". If
|
||||
you prefer other settings, create the buffer first and pass the buffer number.
|
||||
|
||||
The "out_modifiable" and "err_modifiable" options can be used to set the
|
||||
'modifiable' option off, or write to a buffer that has 'modifiable' off. That
|
||||
means that lines will be appended to the buffer, but the user can't easily
|
||||
change the buffer.
|
||||
|
||||
When an existing buffer is to be written where 'modifiable' is off and the
|
||||
"out_modifiable" or "err_modifiable" options is not zero, an error is given
|
||||
and the buffer will not be written to.
|
||||
|
||||
When the buffer written to is displayed in a window and the cursor is in the
|
||||
first column of the last line, the cursor will be moved to the newly added
|
||||
line and the window is scrolled up to show the cursor if needed.
|
||||
|
||||
+6
-1
@@ -582,7 +582,7 @@ CClink = $(CC)
|
||||
#CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes
|
||||
|
||||
# Use this with GCC to check for mistakes, unused arguments, etc.
|
||||
#CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
|
||||
#CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
|
||||
#CFLAGS = -g -O2 -Wall -Wextra -Wmissing-prototypes -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DU_DEBUG
|
||||
#PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
|
||||
#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
|
||||
@@ -1960,6 +1960,10 @@ test check:
|
||||
cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||
$(MAKE) -f Makefile unittest
|
||||
|
||||
# Run the tests with the GUI. Assumes vim/gvim was already built
|
||||
testgui:
|
||||
cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) GUI_FLAG=-g $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||
|
||||
benchmark:
|
||||
cd testdir; $(MAKE) -f Makefile benchmark VIMPROG=../$(VIMTARGET) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||
|
||||
@@ -2074,6 +2078,7 @@ test_arglist \
|
||||
test_viminfo \
|
||||
test_viml \
|
||||
test_visual \
|
||||
test_window_cmd \
|
||||
test_window_id \
|
||||
test_alot_latin \
|
||||
test_alot_utf8 \
|
||||
|
||||
+2
-1
@@ -1653,6 +1653,7 @@ do_autochdir(void)
|
||||
* If (flags & BLN_CURBUF) is TRUE, may use current buffer.
|
||||
* If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
|
||||
* If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
|
||||
* If (flags & BLN_NEW) is TRUE, don't use an existing buffer.
|
||||
* This is the ONLY way to create a new buffer.
|
||||
*/
|
||||
static int top_file_num = 1; /* highest file number */
|
||||
@@ -1680,7 +1681,7 @@ buflist_new(
|
||||
if (sfname == NULL || mch_stat((char *)sfname, &st) < 0)
|
||||
st.st_dev = (dev_T)-1;
|
||||
#endif
|
||||
if (ffname != NULL && !(flags & BLN_DUMMY) && (buf =
|
||||
if (ffname != NULL && !(flags & (BLN_DUMMY | BLN_NEW)) && (buf =
|
||||
#ifdef UNIX
|
||||
buflist_findname_stat(ffname, &st)
|
||||
#else
|
||||
|
||||
+91
-28
@@ -1100,11 +1100,15 @@ find_buffer(char_u *name, int err)
|
||||
buf_T *save_curbuf = curbuf;
|
||||
|
||||
if (name != NULL && *name != NUL)
|
||||
{
|
||||
buf = buflist_findname(name);
|
||||
if (buf == NULL)
|
||||
buf = buflist_findname_exp(name);
|
||||
}
|
||||
if (buf == NULL)
|
||||
{
|
||||
buf = buflist_new(name == NULL || *name == NUL ? NULL : name,
|
||||
NULL, (linenr_T)0, BLN_LISTED);
|
||||
NULL, (linenr_T)0, BLN_LISTED | BLN_NEW);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
buf_copy_options(buf, BCO_ENTER);
|
||||
@@ -1230,9 +1234,20 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
|
||||
}
|
||||
if (buf != NULL)
|
||||
{
|
||||
ch_logs(channel, "writing out to buffer '%s'",
|
||||
if (opt->jo_set & JO_OUT_MODIFIABLE)
|
||||
channel->ch_part[PART_OUT].ch_nomodifiable =
|
||||
!opt->jo_modifiable[PART_OUT];
|
||||
|
||||
if (!buf->b_p_ma && !channel->ch_part[PART_OUT].ch_nomodifiable)
|
||||
{
|
||||
EMSG(_(e_modifiable));
|
||||
}
|
||||
else
|
||||
{
|
||||
ch_logs(channel, "writing out to buffer '%s'",
|
||||
(char *)buf->b_ffname);
|
||||
channel->ch_part[PART_OUT].ch_buffer = buf;
|
||||
channel->ch_part[PART_OUT].ch_buffer = buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1257,9 +1272,19 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
|
||||
buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE);
|
||||
if (buf != NULL)
|
||||
{
|
||||
ch_logs(channel, "writing err to buffer '%s'",
|
||||
if (opt->jo_set & JO_ERR_MODIFIABLE)
|
||||
channel->ch_part[PART_ERR].ch_nomodifiable =
|
||||
!opt->jo_modifiable[PART_ERR];
|
||||
if (!buf->b_p_ma && !channel->ch_part[PART_ERR].ch_nomodifiable)
|
||||
{
|
||||
EMSG(_(e_modifiable));
|
||||
}
|
||||
else
|
||||
{
|
||||
ch_logs(channel, "writing err to buffer '%s'",
|
||||
(char *)buf->b_ffname);
|
||||
channel->ch_part[PART_ERR].ch_buffer = buf;
|
||||
channel->ch_part[PART_ERR].ch_buffer = buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1306,6 +1331,7 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
|
||||
int len = (int)STRLEN(line);
|
||||
char_u *p;
|
||||
|
||||
/* Need to make a copy to be able to append a NL. */
|
||||
if ((p = alloc(len + 2)) == NULL)
|
||||
return;
|
||||
STRCPY(p, line);
|
||||
@@ -2127,11 +2153,23 @@ invoke_one_time_callback(
|
||||
}
|
||||
|
||||
static void
|
||||
append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel)
|
||||
append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, int part)
|
||||
{
|
||||
buf_T *save_curbuf = curbuf;
|
||||
linenr_T lnum = buffer->b_ml.ml_line_count;
|
||||
int save_write_to = buffer->b_write_to_channel;
|
||||
chanpart_T *ch_part = &channel->ch_part[part];
|
||||
int save_p_ma = buffer->b_p_ma;
|
||||
|
||||
if (!buffer->b_p_ma && !ch_part->ch_nomodifiable)
|
||||
{
|
||||
if (!ch_part->ch_nomod_error)
|
||||
{
|
||||
ch_error(channel, "Buffer is not modifiable, cannot append");
|
||||
ch_part->ch_nomod_error = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the buffer is also used as input insert above the last
|
||||
* line. Don't write these lines. */
|
||||
@@ -2144,6 +2182,7 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel)
|
||||
/* Append to the buffer */
|
||||
ch_logn(channel, "appending line %d to buffer", (int)lnum + 1);
|
||||
|
||||
buffer->b_p_ma = TRUE;
|
||||
curbuf = buffer;
|
||||
u_sync(TRUE);
|
||||
/* ignore undo failure, undo is not very useful here */
|
||||
@@ -2152,6 +2191,10 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel)
|
||||
ml_append(lnum, msg, 0, FALSE);
|
||||
appended_lines_mark(lnum, 1L);
|
||||
curbuf = save_curbuf;
|
||||
if (ch_part->ch_nomodifiable)
|
||||
buffer->b_p_ma = FALSE;
|
||||
else
|
||||
buffer->b_p_ma = save_p_ma;
|
||||
|
||||
if (buffer->b_nwindows > 0)
|
||||
{
|
||||
@@ -2379,7 +2422,7 @@ may_invoke_callback(channel_T *channel, int part)
|
||||
/* JSON or JS mode: re-encode the message. */
|
||||
msg = json_encode(listtv, ch_mode);
|
||||
if (msg != NULL)
|
||||
append_to_buffer(buffer, msg, channel);
|
||||
append_to_buffer(buffer, msg, channel, part);
|
||||
}
|
||||
|
||||
if (callback != NULL)
|
||||
@@ -2587,7 +2630,6 @@ channel_close(channel_T *channel, int invoke_close_cb)
|
||||
clear_tv(&rettv);
|
||||
channel_need_redraw = TRUE;
|
||||
}
|
||||
--channel->ch_refcount;
|
||||
|
||||
/* the callback is only called once */
|
||||
vim_free(channel->ch_close_cb);
|
||||
@@ -2595,6 +2637,8 @@ channel_close(channel_T *channel, int invoke_close_cb)
|
||||
partial_unref(channel->ch_close_partial);
|
||||
channel->ch_close_partial = NULL;
|
||||
|
||||
--channel->ch_refcount;
|
||||
|
||||
if (channel_need_redraw)
|
||||
{
|
||||
channel_need_redraw = FALSE;
|
||||
@@ -2889,6 +2933,11 @@ channel_close_on_error(channel_T *channel, char *func)
|
||||
* died. Don't close the channel right away, it may be the wrong moment
|
||||
* to invoke callbacks. */
|
||||
channel->ch_to_be_closed = TRUE;
|
||||
|
||||
#ifdef FEAT_GUI
|
||||
/* Stop listening to GUI events right away. */
|
||||
channel_gui_unregister(channel);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2903,7 +2952,7 @@ channel_close_now(channel_T *channel)
|
||||
/*
|
||||
* Read from channel "channel" for as long as there is something to read.
|
||||
* "part" is PART_SOCK, PART_OUT or PART_ERR.
|
||||
* The data is put in the read queue.
|
||||
* The data is put in the read queue. No callbacks are invoked here.
|
||||
*/
|
||||
#ifndef FEAT_GUI_MACVIM
|
||||
static void
|
||||
@@ -3815,6 +3864,8 @@ free_job_options(jobopt_T *opt)
|
||||
partial_unref(opt->jo_err_partial);
|
||||
if (opt->jo_close_partial != NULL)
|
||||
partial_unref(opt->jo_close_partial);
|
||||
if (opt->jo_exit_partial != NULL)
|
||||
partial_unref(opt->jo_exit_partial);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3933,6 +3984,16 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "out_modifiable") == 0
|
||||
|| STRCMP(hi->hi_key, "err_modifiable") == 0)
|
||||
{
|
||||
part = part_from_char(*hi->hi_key);
|
||||
|
||||
if (!(supported & JO_OUT_IO))
|
||||
break;
|
||||
opt->jo_set |= JO_OUT_MODIFIABLE << (part - PART_OUT);
|
||||
opt->jo_modifiable[part] = get_tv_number(item);
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "in_top") == 0
|
||||
|| STRCMP(hi->hi_key, "in_bot") == 0)
|
||||
{
|
||||
@@ -4017,6 +4078,18 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "exit_cb") == 0)
|
||||
{
|
||||
if (!(supported & JO_EXIT_CB))
|
||||
break;
|
||||
opt->jo_set |= JO_EXIT_CB;
|
||||
opt->jo_exit_cb = get_callback(item, &opt->jo_exit_partial);
|
||||
if (opt->jo_exit_cb == NULL)
|
||||
{
|
||||
EMSG2(_(e_invarg2), "exit_cb");
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "waittime") == 0)
|
||||
{
|
||||
if (!(supported & JO_WAITTIME))
|
||||
@@ -4079,25 +4152,6 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "exit_cb") == 0)
|
||||
{
|
||||
if (!(supported & JO_EXIT_CB))
|
||||
break;
|
||||
opt->jo_set |= JO_EXIT_CB;
|
||||
if (item->v_type == VAR_PARTIAL && item->vval.v_partial != NULL)
|
||||
{
|
||||
opt->jo_exit_partial = item->vval.v_partial;
|
||||
opt->jo_exit_cb = item->vval.v_partial->pt_name;
|
||||
}
|
||||
else
|
||||
opt->jo_exit_cb = get_tv_string_buf_chk(
|
||||
item, opt->jo_ecb_buf);
|
||||
if (opt->jo_exit_cb == NULL)
|
||||
{
|
||||
EMSG2(_(e_invarg2), "exit_cb");
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "block_write") == 0)
|
||||
{
|
||||
if (!(supported & JO_BLOCK_WRITE))
|
||||
@@ -4203,6 +4257,15 @@ job_free(job_T *job)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(EXITFREE) || defined(PROTO)
|
||||
void
|
||||
job_free_all(void)
|
||||
{
|
||||
while (first_job != NULL)
|
||||
job_free(first_job);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return TRUE if the job should not be freed yet. Do not free the job when
|
||||
* it has not ended yet and there is a "stoponexit" flag, an exit callback
|
||||
|
||||
+88
-50
@@ -445,16 +445,17 @@ static long list_idx_of_item(list_T *l, listitem_T *item);
|
||||
static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
|
||||
static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
|
||||
static list_T *list_copy(list_T *orig, int deep, int copyID);
|
||||
static char_u *list2string(typval_T *tv, int copyID);
|
||||
static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap);
|
||||
static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID);
|
||||
static char_u *list2string(typval_T *tv, int copyID, int restore_copyID);
|
||||
static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap);
|
||||
static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID);
|
||||
static int free_unref_items(int copyID);
|
||||
static dictitem_T *dictitem_copy(dictitem_T *org);
|
||||
static void dictitem_remove(dict_T *dict, dictitem_T *item);
|
||||
static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
|
||||
static long dict_len(dict_T *d);
|
||||
static char_u *dict2string(typval_T *tv, int copyID);
|
||||
static char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
|
||||
static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
|
||||
static char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int dict_val);
|
||||
static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
|
||||
static char_u *string_quote(char_u *str, int function);
|
||||
static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
|
||||
@@ -1462,7 +1463,7 @@ eval_to_string(
|
||||
ga_init2(&ga, (int)sizeof(char), 80);
|
||||
if (tv.vval.v_list != NULL)
|
||||
{
|
||||
list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
|
||||
list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
|
||||
if (tv.vval.v_list->lv_len > 0)
|
||||
ga_append(&ga, NL);
|
||||
}
|
||||
@@ -6766,7 +6767,7 @@ vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
|
||||
* May return NULL.
|
||||
*/
|
||||
static char_u *
|
||||
list2string(typval_T *tv, int copyID)
|
||||
list2string(typval_T *tv, int copyID, int restore_copyID)
|
||||
{
|
||||
garray_T ga;
|
||||
|
||||
@@ -6774,7 +6775,8 @@ list2string(typval_T *tv, int copyID)
|
||||
return NULL;
|
||||
ga_init2(&ga, (int)sizeof(char), 80);
|
||||
ga_append(&ga, '[');
|
||||
if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL)
|
||||
if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
|
||||
FALSE, restore_copyID, copyID) == FAIL)
|
||||
{
|
||||
vim_free(ga.ga_data);
|
||||
return NULL;
|
||||
@@ -6795,6 +6797,7 @@ list_join_inner(
|
||||
list_T *l,
|
||||
char_u *sep,
|
||||
int echo_style,
|
||||
int restore_copyID,
|
||||
int copyID,
|
||||
garray_T *join_gap) /* to keep each list item string */
|
||||
{
|
||||
@@ -6811,10 +6814,8 @@ list_join_inner(
|
||||
/* Stringify each item in the list. */
|
||||
for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
|
||||
{
|
||||
if (echo_style)
|
||||
s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
|
||||
else
|
||||
s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
|
||||
s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
|
||||
echo_style, restore_copyID, FALSE);
|
||||
if (s == NULL)
|
||||
return FAIL;
|
||||
|
||||
@@ -6873,6 +6874,7 @@ list_join(
|
||||
list_T *l,
|
||||
char_u *sep,
|
||||
int echo_style,
|
||||
int restore_copyID,
|
||||
int copyID)
|
||||
{
|
||||
garray_T join_ga;
|
||||
@@ -6883,7 +6885,8 @@ list_join(
|
||||
if (l->lv_len < 1)
|
||||
return OK; /* nothing to do */
|
||||
ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
|
||||
retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
|
||||
retval = list_join_inner(gap, l, sep, echo_style, restore_copyID,
|
||||
copyID, &join_ga);
|
||||
|
||||
/* Dispose each item in join_ga. */
|
||||
if (join_ga.ga_data != NULL)
|
||||
@@ -7046,6 +7049,10 @@ garbage_collect(int testing)
|
||||
abort = abort || set_ref_in_nb_channel(copyID);
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_TIMERS
|
||||
abort = abort || set_ref_in_timer(copyID);
|
||||
#endif
|
||||
|
||||
if (!abort)
|
||||
{
|
||||
/*
|
||||
@@ -7829,7 +7836,7 @@ get_dict_number(dict_T *d, char_u *key)
|
||||
* May return NULL.
|
||||
*/
|
||||
static char_u *
|
||||
dict2string(typval_T *tv, int copyID)
|
||||
dict2string(typval_T *tv, int copyID, int restore_copyID)
|
||||
{
|
||||
garray_T ga;
|
||||
int first = TRUE;
|
||||
@@ -7864,7 +7871,8 @@ dict2string(typval_T *tv, int copyID)
|
||||
vim_free(tofree);
|
||||
}
|
||||
ga_concat(&ga, (char_u *)": ");
|
||||
s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
|
||||
s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID,
|
||||
FALSE, restore_copyID, TRUE);
|
||||
if (s != NULL)
|
||||
ga_concat(&ga, s);
|
||||
vim_free(tofree);
|
||||
@@ -8022,16 +8030,23 @@ get_var_special_name(int nr)
|
||||
* Return a string with the string representation of a variable.
|
||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||
* "numbuf" is used for a number.
|
||||
* Does not put quotes around strings, as ":echo" displays values.
|
||||
* When "copyID" is not NULL replace recursive lists and dicts with "...".
|
||||
* When both "echo_style" and "dict_val" are FALSE, put quotes around stings as
|
||||
* "string()", otherwise does not put quotes around strings, as ":echo"
|
||||
* displays values.
|
||||
* When "restore_copyID" is FALSE, repeated items in dictionaries and lists
|
||||
* are replaced with "...".
|
||||
* May return NULL.
|
||||
*/
|
||||
static char_u *
|
||||
echo_string(
|
||||
echo_string_core(
|
||||
typval_T *tv,
|
||||
char_u **tofree,
|
||||
char_u *numbuf,
|
||||
int copyID)
|
||||
int copyID,
|
||||
int echo_style,
|
||||
int restore_copyID,
|
||||
int dict_val)
|
||||
{
|
||||
static int recurse = 0;
|
||||
char_u *r = NULL;
|
||||
@@ -8053,9 +8068,30 @@ echo_string(
|
||||
|
||||
switch (tv->v_type)
|
||||
{
|
||||
case VAR_STRING:
|
||||
if (echo_style && !dict_val)
|
||||
{
|
||||
*tofree = NULL;
|
||||
r = get_tv_string_buf(tv, numbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
*tofree = string_quote(tv->vval.v_string, FALSE);
|
||||
r = *tofree;
|
||||
}
|
||||
break;
|
||||
|
||||
case VAR_FUNC:
|
||||
*tofree = NULL;
|
||||
r = tv->vval.v_string;
|
||||
if (echo_style)
|
||||
{
|
||||
*tofree = NULL;
|
||||
r = tv->vval.v_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tofree = string_quote(tv->vval.v_string, TRUE);
|
||||
r = *tofree;
|
||||
}
|
||||
break;
|
||||
|
||||
case VAR_PARTIAL:
|
||||
@@ -8110,15 +8146,20 @@ echo_string(
|
||||
*tofree = NULL;
|
||||
r = NULL;
|
||||
}
|
||||
else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
|
||||
else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
|
||||
&& tv->vval.v_list->lv_len > 0)
|
||||
{
|
||||
*tofree = NULL;
|
||||
r = (char_u *)"[...]";
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_copyID = tv->vval.v_list->lv_copyID;
|
||||
|
||||
tv->vval.v_list->lv_copyID = copyID;
|
||||
*tofree = list2string(tv, copyID);
|
||||
*tofree = list2string(tv, copyID, restore_copyID);
|
||||
if (restore_copyID)
|
||||
tv->vval.v_list->lv_copyID = old_copyID;
|
||||
r = *tofree;
|
||||
}
|
||||
break;
|
||||
@@ -8129,20 +8170,23 @@ echo_string(
|
||||
*tofree = NULL;
|
||||
r = NULL;
|
||||
}
|
||||
else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
|
||||
else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
|
||||
&& tv->vval.v_dict->dv_hashtab.ht_used != 0)
|
||||
{
|
||||
*tofree = NULL;
|
||||
r = (char_u *)"{...}";
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_copyID = tv->vval.v_dict->dv_copyID;
|
||||
tv->vval.v_dict->dv_copyID = copyID;
|
||||
*tofree = dict2string(tv, copyID);
|
||||
*tofree = dict2string(tv, copyID, restore_copyID);
|
||||
if (restore_copyID)
|
||||
tv->vval.v_dict->dv_copyID = old_copyID;
|
||||
r = *tofree;
|
||||
}
|
||||
break;
|
||||
|
||||
case VAR_STRING:
|
||||
case VAR_NUMBER:
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_JOB:
|
||||
@@ -8170,6 +8214,24 @@ echo_string(
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string with the string representation of a variable.
|
||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||
* "numbuf" is used for a number.
|
||||
* Does not put quotes around strings, as ":echo" displays values.
|
||||
* When "copyID" is not NULL replace recursive lists and dicts with "...".
|
||||
* May return NULL.
|
||||
*/
|
||||
static char_u *
|
||||
echo_string(
|
||||
typval_T *tv,
|
||||
char_u **tofree,
|
||||
char_u *numbuf,
|
||||
int copyID)
|
||||
{
|
||||
return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string with the string representation of a variable.
|
||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||
@@ -8184,31 +8246,7 @@ tv2string(
|
||||
char_u *numbuf,
|
||||
int copyID)
|
||||
{
|
||||
switch (tv->v_type)
|
||||
{
|
||||
case VAR_FUNC:
|
||||
*tofree = string_quote(tv->vval.v_string, TRUE);
|
||||
return *tofree;
|
||||
case VAR_STRING:
|
||||
*tofree = string_quote(tv->vval.v_string, FALSE);
|
||||
return *tofree;
|
||||
case VAR_FLOAT:
|
||||
#ifdef FEAT_FLOAT
|
||||
*tofree = NULL;
|
||||
vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float);
|
||||
return numbuf;
|
||||
#endif
|
||||
case VAR_NUMBER:
|
||||
case VAR_LIST:
|
||||
case VAR_DICT:
|
||||
case VAR_PARTIAL:
|
||||
case VAR_SPECIAL:
|
||||
case VAR_JOB:
|
||||
case VAR_CHANNEL:
|
||||
case VAR_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
return echo_string(tv, tofree, numbuf, copyID);
|
||||
return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -15197,7 +15235,7 @@ f_join(typval_T *argvars, typval_T *rettv)
|
||||
if (sep != NULL)
|
||||
{
|
||||
ga_init2(&ga, (int)sizeof(char), 80);
|
||||
list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
|
||||
list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0);
|
||||
ga_append(&ga, NUL);
|
||||
rettv->vval.v_string = (char_u *)ga.ga_data;
|
||||
}
|
||||
|
||||
+25
-6
@@ -1252,6 +1252,25 @@ stop_timer(timer_T *timer)
|
||||
remove_timer(timer);
|
||||
free_timer(timer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark references in partials of timers.
|
||||
*/
|
||||
int
|
||||
set_ref_in_timer(int copyID)
|
||||
{
|
||||
int abort = FALSE;
|
||||
timer_T *timer;
|
||||
typval_T tv;
|
||||
|
||||
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
|
||||
{
|
||||
tv.v_type = VAR_PARTIAL;
|
||||
tv.vval.v_partial = timer->tr_partial;
|
||||
abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL);
|
||||
}
|
||||
return abort;
|
||||
}
|
||||
# endif
|
||||
|
||||
#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT)
|
||||
@@ -3397,10 +3416,10 @@ add_pack_plugin(char_u *fname, void *cookie)
|
||||
int c;
|
||||
char_u *new_rtp;
|
||||
int keep;
|
||||
int oldlen;
|
||||
int addlen;
|
||||
size_t oldlen;
|
||||
size_t addlen;
|
||||
char_u *afterdir;
|
||||
int afterlen = 0;
|
||||
size_t afterlen = 0;
|
||||
char_u *ffname = fix_fname(fname);
|
||||
|
||||
if (ffname == NULL)
|
||||
@@ -3440,9 +3459,9 @@ add_pack_plugin(char_u *fname, void *cookie)
|
||||
if (afterdir != NULL && mch_isdir(afterdir))
|
||||
afterlen = STRLEN(afterdir) + 1; /* add one for comma */
|
||||
|
||||
oldlen = (int)STRLEN(p_rtp);
|
||||
addlen = (int)STRLEN(ffname) + 1; /* add one for comma */
|
||||
new_rtp = alloc(oldlen + addlen + afterlen + 1); /* add one for NUL */
|
||||
oldlen = STRLEN(p_rtp);
|
||||
addlen = STRLEN(ffname) + 1; /* add one for comma */
|
||||
new_rtp = alloc((int)(oldlen + addlen + afterlen + 1)); /* add one for NUL */
|
||||
if (new_rtp == NULL)
|
||||
goto theend;
|
||||
keep = (int)(insp - p_rtp);
|
||||
|
||||
+4
-3
@@ -1126,9 +1126,6 @@ free_all_mem(void)
|
||||
# endif
|
||||
# ifdef FEAT_DIFF
|
||||
diff_clear(curtab);
|
||||
# endif
|
||||
# ifdef FEAT_JOB_CHANNEL
|
||||
channel_free_all();
|
||||
# endif
|
||||
clear_sb_text(); /* free any scrollback text */
|
||||
|
||||
@@ -1221,6 +1218,10 @@ free_all_mem(void)
|
||||
# ifdef FEAT_EVAL
|
||||
eval_clear();
|
||||
# endif
|
||||
# ifdef FEAT_JOB_CHANNEL
|
||||
channel_free_all();
|
||||
job_free_all();
|
||||
# endif
|
||||
|
||||
free_termoptions();
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ void clear_job_options(jobopt_T *opt);
|
||||
void free_job_options(jobopt_T *opt);
|
||||
int get_job_options(typval_T *tv, jobopt_T *opt, int supported);
|
||||
channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, int part);
|
||||
void job_free_all(void);
|
||||
int set_ref_in_job(int copyID);
|
||||
void job_unref(job_T *job);
|
||||
int free_unused_jobs_contents(int copyID, int mask);
|
||||
|
||||
@@ -22,6 +22,7 @@ timer_T *create_timer(long msec, int repeats);
|
||||
long check_due_timer(void);
|
||||
timer_T *find_timer(int id);
|
||||
void stop_timer(timer_T *timer);
|
||||
int set_ref_in_timer(int copyID);
|
||||
void profile_divide(proftime_T *tm, int count, proftime_T *tm2);
|
||||
void profile_add(proftime_T *tm, proftime_T *tm2);
|
||||
void profile_self(proftime_T *self, proftime_T *total, proftime_T *children);
|
||||
|
||||
+5
-1
@@ -1404,6 +1404,8 @@ typedef struct {
|
||||
partial_T *ch_partial;
|
||||
|
||||
buf_T *ch_buffer; /* buffer to read from or write to */
|
||||
int ch_nomodifiable; /* TRUE when buffer can be 'nomodifiable' */
|
||||
int ch_nomod_error; /* TRUE when e_modifiable was given */
|
||||
int ch_buf_append; /* write appended lines instead top-bot */
|
||||
linenr_T ch_buf_top; /* next line to send */
|
||||
linenr_T ch_buf_bot; /* last line to send */
|
||||
@@ -1480,6 +1482,8 @@ struct channel_S {
|
||||
#define JO_IN_BUF 0x4000000 /* "in_buf" (JO_OUT_BUF << 2) */
|
||||
#define JO_CHANNEL 0x8000000 /* "channel" */
|
||||
#define JO_BLOCK_WRITE 0x10000000 /* "block_write" */
|
||||
#define JO_OUT_MODIFIABLE 0x20000000 /* "out_modifiable" */
|
||||
#define JO_ERR_MODIFIABLE 0x40000000 /* "err_modifiable" (JO_OUT_ << 1) */
|
||||
#define JO_ALL 0x7fffffff
|
||||
|
||||
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
|
||||
@@ -1503,6 +1507,7 @@ typedef struct
|
||||
char_u jo_io_name_buf[4][NUMBUFLEN];
|
||||
char_u *jo_io_name[4]; /* not allocated! */
|
||||
int jo_io_buf[4];
|
||||
int jo_modifiable[4];
|
||||
channel_T *jo_channel;
|
||||
|
||||
linenr_T jo_in_top;
|
||||
@@ -1527,7 +1532,6 @@ typedef struct
|
||||
int jo_id;
|
||||
char_u jo_soe_buf[NUMBUFLEN];
|
||||
char_u *jo_stoponexit;
|
||||
char_u jo_ecb_buf[NUMBUFLEN];
|
||||
} jobopt_T;
|
||||
|
||||
|
||||
|
||||
+6
-7
@@ -8487,11 +8487,11 @@ color_name2handle(char_u *name)
|
||||
#ifdef FEAT_GUI
|
||||
return gui.norm_pixel;
|
||||
#endif
|
||||
#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI)
|
||||
else
|
||||
#endif
|
||||
#ifdef FEAT_TERMGUICOLORS
|
||||
if (cterm_normal_fg_gui_color != (long_u)INVALCOLOR)
|
||||
return cterm_normal_fg_gui_color;
|
||||
/* Guess that the foreground is black or white. */
|
||||
return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white"));
|
||||
#endif
|
||||
}
|
||||
if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0)
|
||||
@@ -8502,11 +8502,11 @@ color_name2handle(char_u *name)
|
||||
#ifdef FEAT_GUI
|
||||
return gui.back_pixel;
|
||||
#endif
|
||||
#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI)
|
||||
else
|
||||
#endif
|
||||
#ifdef FEAT_TERMGUICOLORS
|
||||
if (cterm_normal_bg_gui_color != (long_u)INVALCOLOR)
|
||||
return cterm_normal_bg_gui_color;
|
||||
/* Guess that the background is white or black. */
|
||||
return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black"));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -8596,7 +8596,6 @@ get_attr_entry(garray_T *table, attrentry_T *aep)
|
||||
&& aep->ae_u.cterm.bg_rgb
|
||||
== taep->ae_u.cterm.bg_rgb
|
||||
#endif
|
||||
|
||||
)))
|
||||
|
||||
return i + ATTR_OFF;
|
||||
|
||||
@@ -12,7 +12,7 @@ SCRIPTSOURCE = ../../runtime
|
||||
# The output goes into a file "valgrind.testN"
|
||||
# Vim should be compiled with EXITFREE to avoid false warnings.
|
||||
# This will make testing about 10 times as slow.
|
||||
# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --log-file=valgrind.$*
|
||||
# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind.$*
|
||||
|
||||
default: nongui
|
||||
|
||||
@@ -52,7 +52,7 @@ $(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS): $(SCRIPTS_FIRST)
|
||||
|
||||
RM_ON_RUN = test.out X* viminfo
|
||||
RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok benchmark.out
|
||||
RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f -u unix.vim $(NO_PLUGIN) -s dotest.in
|
||||
RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_PLUGIN) -s dotest.in
|
||||
|
||||
clean:
|
||||
-rm -rf *.out *.failed *.res *.rej *.orig test.log messages $(RM_ON_RUN) $(RM_ON_START) valgrind.*
|
||||
@@ -118,7 +118,7 @@ nolog:
|
||||
# New style of tests uses Vim script with assert calls. These are easier
|
||||
# to write and a lot easier to read and debug.
|
||||
# Limitation: Only works with the +eval feature.
|
||||
RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f -u unix.vim $(NO_PLUGIN)
|
||||
RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_PLUGIN)
|
||||
|
||||
newtests: newtestssilent
|
||||
@/bin/sh -c "if test -f messages && grep -q 'FAILED' messages; then cat messages && cat test.log; fi"
|
||||
|
||||
@@ -484,7 +484,7 @@ psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_reb
|
||||
psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
|
||||
psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
|
||||
psaC: <vim.Function 'SelfArgs'>
|
||||
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
|
||||
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}]}>
|
||||
s(a): function('Args')
|
||||
s(pa1): function('Args', ['abcArgsPA1'])
|
||||
s(pa2): function('Args')
|
||||
|
||||
@@ -484,7 +484,7 @@ psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_reb
|
||||
psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
|
||||
psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
|
||||
psaC: <vim.Function 'SelfArgs'>
|
||||
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
|
||||
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}]}>
|
||||
s(a): function('Args')
|
||||
s(pa1): function('Args', ['abcArgsPA1'])
|
||||
s(pa2): function('Args')
|
||||
|
||||
@@ -676,7 +676,7 @@ func Test_nl_write_both_file()
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
func Run_test_pipe_to_buffer(use_name)
|
||||
func Run_test_pipe_to_buffer(use_name, nomod)
|
||||
if !has('job')
|
||||
return
|
||||
endif
|
||||
@@ -691,6 +691,9 @@ func Run_test_pipe_to_buffer(use_name)
|
||||
quit
|
||||
let firstline = ''
|
||||
endif
|
||||
if a:nomod
|
||||
let options['out_modifiable'] = 0
|
||||
endif
|
||||
let job = job_start(s:python . " test_channel_pipe.py", options)
|
||||
call assert_equal("run", job_status(job))
|
||||
try
|
||||
@@ -705,6 +708,11 @@ func Run_test_pipe_to_buffer(use_name)
|
||||
$del
|
||||
endif
|
||||
call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$'))
|
||||
if a:nomod
|
||||
call assert_equal(0, &modifiable)
|
||||
else
|
||||
call assert_equal(1, &modifiable)
|
||||
endif
|
||||
bwipe!
|
||||
finally
|
||||
call job_stop(job)
|
||||
@@ -712,14 +720,18 @@ func Run_test_pipe_to_buffer(use_name)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_to_buffer_name()
|
||||
call Run_test_pipe_to_buffer(1)
|
||||
call Run_test_pipe_to_buffer(1, 0)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_to_buffer_nr()
|
||||
call Run_test_pipe_to_buffer(0)
|
||||
call Run_test_pipe_to_buffer(0, 0)
|
||||
endfunc
|
||||
|
||||
func Run_test_pipe_err_to_buffer(use_name)
|
||||
func Test_pipe_to_buffer_name_nomod()
|
||||
call Run_test_pipe_to_buffer(1, 1)
|
||||
endfunc
|
||||
|
||||
func Run_test_pipe_err_to_buffer(use_name, nomod)
|
||||
if !has('job')
|
||||
return
|
||||
endif
|
||||
@@ -734,6 +746,9 @@ func Run_test_pipe_err_to_buffer(use_name)
|
||||
quit
|
||||
let firstline = ''
|
||||
endif
|
||||
if a:nomod
|
||||
let options['err_modifiable'] = 0
|
||||
endif
|
||||
let job = job_start(s:python . " test_channel_pipe.py", options)
|
||||
call assert_equal("run", job_status(job))
|
||||
try
|
||||
@@ -745,6 +760,11 @@ func Run_test_pipe_err_to_buffer(use_name)
|
||||
sp pipe-err
|
||||
call s:waitFor('line("$") >= 5')
|
||||
call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$'))
|
||||
if a:nomod
|
||||
call assert_equal(0, &modifiable)
|
||||
else
|
||||
call assert_equal(1, &modifiable)
|
||||
endif
|
||||
bwipe!
|
||||
finally
|
||||
call job_stop(job)
|
||||
@@ -752,11 +772,15 @@ func Run_test_pipe_err_to_buffer(use_name)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_err_to_buffer_name()
|
||||
call Run_test_pipe_err_to_buffer(1)
|
||||
call Run_test_pipe_err_to_buffer(1, 0)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_err_to_buffer_nr()
|
||||
call Run_test_pipe_err_to_buffer(0)
|
||||
call Run_test_pipe_err_to_buffer(0, 0)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_err_to_buffer_name_nomod()
|
||||
call Run_test_pipe_err_to_buffer(1, 1)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_both_to_buffer()
|
||||
|
||||
@@ -250,6 +250,25 @@ func Test_cycle_partial_job()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_job_start_fails()
|
||||
if has('job')
|
||||
let job = job_start('axdfxsdf')
|
||||
for i in range(100)
|
||||
let status = job_status(job)
|
||||
if status == 'dead' || status == 'fail'
|
||||
break
|
||||
endif
|
||||
sleep 10m
|
||||
endfor
|
||||
if has('unix')
|
||||
call assert_equal('dead', job_status(job))
|
||||
else
|
||||
call assert_equal('fail', job_status(job))
|
||||
endif
|
||||
unlet job
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_ref_job_partial_dict()
|
||||
if has('job')
|
||||
let g:ref_job = job_start('echo')
|
||||
|
||||
@@ -27,7 +27,7 @@ func Test_missing_attr()
|
||||
if fontname == ''
|
||||
let fontname = 'something'
|
||||
endif
|
||||
exe 'hi Mine guifg=blue guibg=red font=' . escape(fontname, ' \')
|
||||
exe "hi Mine guifg=blue guibg=red font='" . fontname . "'"
|
||||
call assert_equal('blue', synIDattr(hlID("Mine"), "fg", 'gui'))
|
||||
call assert_equal('red', synIDattr(hlID("Mine"), "bg", 'gui'))
|
||||
call assert_equal(fontname, synIDattr(hlID("Mine"), "font", 'gui'))
|
||||
|
||||
@@ -8,6 +8,10 @@ func MyHandler(timer)
|
||||
let s:val += 1
|
||||
endfunc
|
||||
|
||||
func MyHandlerWithLists(lists, timer)
|
||||
let x = string(a:lists)
|
||||
endfunc
|
||||
|
||||
func Test_oneshot()
|
||||
let s:val = 0
|
||||
let timer = timer_start(50, 'MyHandler')
|
||||
@@ -42,4 +46,10 @@ func Test_with_partial_callback()
|
||||
sleep 200m
|
||||
call assert_equal(1, s:val)
|
||||
endfunc
|
||||
|
||||
func Test_retain_partial()
|
||||
call timer_start(100, function('MyHandlerWithLists', [['a']]))
|
||||
call test_garbagecollect_now()
|
||||
sleep 200m
|
||||
endfunc
|
||||
" vim: ts=2 sw=0 et
|
||||
|
||||
@@ -1052,6 +1052,150 @@ func Test_skip()
|
||||
|
||||
endfunc
|
||||
|
||||
"-------------------------------------------------------------------------------
|
||||
" Test 93: :echo and string() {{{1
|
||||
"-------------------------------------------------------------------------------
|
||||
|
||||
func Test_echo_and_string()
|
||||
" String
|
||||
let a = 'foo bar'
|
||||
redir => result
|
||||
echo a
|
||||
echo string(a)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["foo bar",
|
||||
\ "'foo bar'"], l)
|
||||
|
||||
" Float
|
||||
if has('float')
|
||||
let a = -1.2e0
|
||||
redir => result
|
||||
echo a
|
||||
echo string(a)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["-1.2",
|
||||
\ "-1.2"], l)
|
||||
endif
|
||||
|
||||
" Funcref
|
||||
redir => result
|
||||
echo function('string')
|
||||
echo string(function('string'))
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["string",
|
||||
\ "function('string')"], l)
|
||||
|
||||
" Recursive dictionary
|
||||
let a = {}
|
||||
let a["a"] = a
|
||||
redir => result
|
||||
echo a
|
||||
echo string(a)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["{'a': {...}}",
|
||||
\ "{'a': {...}}"], l)
|
||||
|
||||
" Recursive list
|
||||
let a = [0]
|
||||
let a[0] = a
|
||||
redir => result
|
||||
echo a
|
||||
echo string(a)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["[[...]]",
|
||||
\ "[[...]]"], l)
|
||||
|
||||
" Empty dictionaries in a list
|
||||
let a = {}
|
||||
redir => result
|
||||
echo [a, a, a]
|
||||
echo string([a, a, a])
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["[{}, {}, {}]",
|
||||
\ "[{}, {}, {}]"], l)
|
||||
|
||||
" Empty dictionaries in a dictionary
|
||||
let a = {}
|
||||
let b = {"a": a, "b": a}
|
||||
redir => result
|
||||
echo b
|
||||
echo string(b)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["{'a': {}, 'b': {}}",
|
||||
\ "{'a': {}, 'b': {}}"], l)
|
||||
|
||||
" Empty lists in a list
|
||||
let a = []
|
||||
redir => result
|
||||
echo [a, a, a]
|
||||
echo string([a, a, a])
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["[[], [], []]",
|
||||
\ "[[], [], []]"], l)
|
||||
|
||||
" Empty lists in a dictionary
|
||||
let a = []
|
||||
let b = {"a": a, "b": a}
|
||||
redir => result
|
||||
echo b
|
||||
echo string(b)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["{'a': [], 'b': []}",
|
||||
\ "{'a': [], 'b': []}"], l)
|
||||
|
||||
" Dictionaries in a list
|
||||
let a = {"one": "yes", "two": "yes", "three": "yes"}
|
||||
redir => result
|
||||
echo [a, a, a]
|
||||
echo string([a, a, a])
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
|
||||
\ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
|
||||
|
||||
" Dictionaries in a dictionary
|
||||
let a = {"one": "yes", "two": "yes", "three": "yes"}
|
||||
let b = {"a": a, "b": a}
|
||||
redir => result
|
||||
echo b
|
||||
echo string(b)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
|
||||
\ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
|
||||
|
||||
" Lists in a list
|
||||
let a = [1, 2, 3]
|
||||
redir => result
|
||||
echo [a, a, a]
|
||||
echo string([a, a, a])
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["[[1, 2, 3], [...], [...]]",
|
||||
\ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
|
||||
|
||||
" Lists in a dictionary
|
||||
let a = [1, 2, 3]
|
||||
let b = {"a": a, "b": a}
|
||||
redir => result
|
||||
echo b
|
||||
echo string(b)
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
|
||||
\ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
|
||||
|
||||
endfunc
|
||||
|
||||
"-------------------------------------------------------------------------------
|
||||
" Modelines {{{1
|
||||
" vim: ts=8 sw=4 tw=80 fdm=marker
|
||||
|
||||
@@ -768,6 +768,32 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1862,
|
||||
/**/
|
||||
1861,
|
||||
/**/
|
||||
1860,
|
||||
/**/
|
||||
1859,
|
||||
/**/
|
||||
1858,
|
||||
/**/
|
||||
1857,
|
||||
/**/
|
||||
1856,
|
||||
/**/
|
||||
1855,
|
||||
/**/
|
||||
1854,
|
||||
/**/
|
||||
1853,
|
||||
/**/
|
||||
1852,
|
||||
/**/
|
||||
1851,
|
||||
/**/
|
||||
1850,
|
||||
/**/
|
||||
1849,
|
||||
/**/
|
||||
|
||||
@@ -910,9 +910,10 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
||||
#define GETF_SWITCH 0x04 /* respect 'switchbuf' settings when jumping */
|
||||
|
||||
/* Values for buflist_new() flags */
|
||||
#define BLN_CURBUF 1 /* May re-use curbuf for new buffer */
|
||||
#define BLN_LISTED 2 /* Put new buffer in buffer list */
|
||||
#define BLN_DUMMY 4 /* Allocating dummy buffer */
|
||||
#define BLN_CURBUF 1 /* may re-use curbuf for new buffer */
|
||||
#define BLN_LISTED 2 /* put new buffer in buffer list */
|
||||
#define BLN_DUMMY 4 /* allocating dummy buffer */
|
||||
#define BLN_NEW 8 /* create a new buffer */
|
||||
|
||||
/* Values for in_cinkeys() */
|
||||
#define KEY_OPEN_FORW 0x101
|
||||
|
||||
Reference in New Issue
Block a user