Merge tag 'v8.0.0117' into HEAD
diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt
index 7310598..4fb55bf 100644
--- a/runtime/doc/channel.txt
+++ b/runtime/doc/channel.txt
@@ -155,7 +155,13 @@
func MyCloseHandler(channel)
< Vim will invoke callbacks that handle data before invoking
close_cb, thus when this function is called no more data will
- be received.
+ be passed to the callbacks.
+ *channel-drop*
+"drop" Specifies when to drop messages:
+ "auto" When there is no callback to handle a message.
+ The "close_cb" is also considered for this.
+ "never" All messages will be kept.
+
*waittime*
"waittime" The time to wait for the connection to be made in
milliseconds. A negative number waits forever.
@@ -418,7 +424,11 @@
message that is available: >
let output = ch_read(channel, {'timeout': 0})
When no message was available then the result is v:none for a JSON or JS mode
-channels, an empty string for a RAW or NL channel.
+channels, an empty string for a RAW or NL channel. You can use |ch_canread()|
+to check if there is something to read.
+
+Note that when there is no callback message are dropped. To avoid that add a
+close callback to the channel.
To read all output from a RAW channel that is available: >
let output = ch_readraw(channel)
@@ -470,6 +480,11 @@
of a pipe causes the read end to get EOF). To avoid this make the job sleep
for a short while before it exits.
+Note that if the job exits before you read the output, the output may be lost.
+This depends on the system (on Unix this happens because closing the write end
+of a pipe causes the read end to get EOF). To avoid this make the job sleep
+for a short while before it exits.
+
The handler defined for "out_cb" will not receive stderr. If you want to
handle that separately, add an "err_cb" handler: >
let job = job_start(command, {"out_cb": "MyHandler",
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index 8eb3a93..e05e6d3 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -359,8 +359,11 @@
List entries 6 to 12 from the search history: >
:history / 6,12
<
- List the recent five entries from all histories: >
- :history all -5,
+ List the penultimate entry from all histories: >
+ :history all -2
+<
+ List the most recent two entries from all histories: >
+ :history all -2,
:keepp[atterns] {command} *:keepp* *:keeppatterns*
Execute {command}, without adding anything to the search
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 1a11a41..75c2ea1 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2009,6 +2009,7 @@
call({func}, {arglist} [, {dict}])
any call {func} with arguments {arglist}
ceil({expr}) Float round {expr} up
+ch_canread({handle}) Number check if there is something to read
ch_close({handle}) none close {handle}
ch_close_in({handle}) none close in part of {handle}
ch_evalexpr({handle}, {expr} [, {options}])
@@ -2980,16 +2981,28 @@
don't fit, a vertical layout is used anyway. For some systems
the horizontal layout is always used.
+ch_canread({handle}) *ch_canread()*
+ Return non-zero when there is something to read from {handle}.
+ {handle} can be a Channel or a Job that has a Channel.
+
+ This is useful to read from a channel at a convenient time,
+ e.g. from a timer.
+
+ Note that messages are dropped when the channel does not have
+ a callback. Add a close callback to avoid that.
+
+ {only available when compiled with the |+channel| feature}
+
ch_close({handle}) *ch_close()*
Close {handle}. See |channel-close|.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
A close callback is not invoked.
{only available when compiled with the |+channel| feature}
ch_close_in({handle}) *ch_close_in()*
Close the "in" part of {handle}. See |channel-close-in|.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
A close callback is not invoked.
{only available when compiled with the |+channel| feature}
@@ -2998,7 +3011,7 @@
Send {expr} over {handle}. The {expr} is encoded
according to the type of channel. The function cannot be used
with a raw channel. See |channel-use|.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
*E917*
{options} must be a Dictionary. It must not have a "callback"
entry. It can have a "timeout" entry to specify the timeout
@@ -3012,7 +3025,7 @@
ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
Send {string} over {handle}.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
Works like |ch_evalexpr()|, but does not encode the request or
decode the response. The caller is responsible for the
@@ -3025,7 +3038,7 @@
ch_getbufnr({handle}, {what}) *ch_getbufnr()*
Get the buffer number that {handle} is using for {what}.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
{what} can be "err" for stderr, "out" for stdout or empty for
socket output.
Returns -1 when there is no buffer.
@@ -3099,7 +3112,7 @@
ch_read({handle} [, {options}]) *ch_read()*
Read from {handle} and return the received message.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
See |channel-more|.
{only available when compiled with the |+channel| feature}
@@ -3113,7 +3126,7 @@
according to the type of channel. The function cannot be used
with a raw channel.
See |channel-use|. *E912*
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
{only available when compiled with the |+channel| feature}
@@ -3134,7 +3147,7 @@
"timeout" default read timeout in msec
"mode" mode for the whole channel
See |ch_open()| for more explanation.
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
Note that changing the mode may cause queued messages to be
lost.
@@ -3148,7 +3161,7 @@
"open" channel can be used
"buffered" channel can be read, not written to
"closed" channel can not be used
- {handle} can be Channel or a Job that has a Channel.
+ {handle} can be a Channel or a Job that has a Channel.
"buffered" is used when the channel was closed but there is
still data that can be obtained with |ch_read()|.
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index 63f7fa9..b292720 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -81,6 +81,13 @@
STATIC_STDCPLUS=no
endif
+
+# Link against the shared version of libwinpthread by default. Set
+# STATIC_WINPTHREAD to "yes" to link against static version instead.
+ifndef STATIC_WINPTHREAD
+STATIC_WINPTHREAD=$(STATIC_STDCPLUS)
+endif
+
# If the user doesn't want gettext, undefine it.
ifeq (no, $(GETTEXT))
GETTEXT=
@@ -817,6 +824,10 @@
endif
endif
+ifeq (yes, $(STATIC_WINPTHREAD))
+LIB += -Wl,-Bstatic -lwinpthread -Wl,-Bdynamic
+endif
+
all: $(TARGET) vimrun.exe xxd/xxd.exe install.exe uninstal.exe GvimExt/gvimext.dll
vimrun.exe: vimrun.c
diff --git a/src/Makefile b/src/Makefile
index 7a65677..a24eb7b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1684,21 +1684,30 @@
objects/memfile.o \
objects/message.o
-JSON_TEST_OBJ = $(OBJ_COMMON) \
+OBJ_JSON_TEST = \
objects/memfile.o \
objects/message.o \
objects/json_test.o
-MEMFILE_TEST_OBJ = $(OBJ_COMMON) \
+JSON_TEST_OBJ = $(OBJ_COMMON) $(OBJ_JSON_TEST)
+
+OBJ_MEMFILE_TEST = \
objects/json.o \
objects/message.o \
objects/memfile_test.o
-MESSAGE_TEST_OBJ = $(OBJ_COMMON) \
+MEMFILE_TEST_OBJ = $(OBJ_COMMON) $(OBJ_MEMFILE_TEST)
+
+OBJ_MESSAGE_TEST = \
objects/json.o \
objects/memfile.o \
objects/message_test.o
+MESSAGE_TEST_OBJ = $(OBJ_COMMON) $(OBJ_MESSAGE_TEST)
+
+ALL_OBJ = $(OBJ_COMMON) $(OBJ_JSON_TEST) $(OBJ_MEMFILE_TEST) $(OBJ_MESSAGE_TEST)
+
+
PRO_AUTO = \
arabic.pro \
blowfish.pro \
@@ -2052,7 +2061,7 @@
test60 test64 test65 test66 test67 test68 test69 \
test70 test72 test73 test74 test75 test77 test78 test79 \
test80 test82 test83 test84 test85 test86 test87 test88 test89 \
- test90 test91 test92 test93 test94 test95 test97 test98 test99 \
+ test90 test91 test94 test95 test97 test98 test99 \
test100 test101 test103 test104 test107 test108:
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
@@ -2118,6 +2127,8 @@
test_matchadd_conceal_utf8 \
test_menu \
test_messages \
+ test_mksession \
+ test_mksession_utf8 \
test_nested_function \
test_netbeans \
test_normal \
@@ -2851,8 +2862,14 @@
# commands understand putting object files in another directory, it must be
# specified for each file separately.
-objects:
- mkdir objects
+objects objects/.dirstamp:
+ mkdir -p objects
+ touch objects/.dirstamp
+
+# All object files depend on the objects directory, so that parallel make
+# works. Can't depend on the directory itself, its timestamp changes all the
+# time.
+$(ALL_OBJ): objects/.dirstamp
objects/arabic.o: arabic.c
$(CCC) -o $@ arabic.c
diff --git a/src/buffer.c b/src/buffer.c
index e5d2dde..e77fc04 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4858,8 +4858,8 @@
wpnext = wp->w_next;
buf = wp->w_buffer;
if (buf->b_ffname == NULL
- || (!keep_tabs && buf->b_nwindows > 1)
- || wp->w_width != Columns)
+ || (!keep_tabs && (buf->b_nwindows > 1
+ || wp->w_width != Columns)))
i = opened_len;
else
{
diff --git a/src/channel.c b/src/channel.c
index 778a30e..32f3527 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1195,6 +1195,7 @@
if (opt->jo_set & JO_CLOSE_CALLBACK)
set_callback(&channel->ch_close_cb, &channel->ch_close_partial,
opt->jo_close_cb, opt->jo_close_partial);
+ channel->ch_drop_never = opt->jo_drop_never;
if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
{
@@ -1918,6 +1919,7 @@
clear_tv(&listtv);
else
{
+ item->jq_no_callback = FALSE;
item->jq_value = alloc_tv();
if (item->jq_value == NULL)
{
@@ -2050,11 +2052,17 @@
* When "id" is positive it must match the first number in the list.
* When "id" is zero or negative jut get the first message. But not the one
* with id ch_block_id.
+ * When "without_callback" is TRUE also get messages that were pushed back.
* Return OK when found and return the value in "rettv".
* Return FAIL otherwise.
*/
static int
-channel_get_json(channel_T *channel, ch_part_T part, int id, typval_T **rettv)
+channel_get_json(
+ channel_T *channel,
+ ch_part_T part,
+ int id,
+ int without_callback,
+ typval_T **rettv)
{
jsonq_T *head = &channel->ch_part[part].ch_json_head;
jsonq_T *item = head->jq_next;
@@ -2064,10 +2072,11 @@
list_T *l = item->jq_value->vval.v_list;
typval_T *tv = &l->lv_first->li_tv;
- if ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id)
+ if ((without_callback || !item->jq_no_callback)
+ && ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id)
|| (id <= 0 && (tv->v_type != VAR_NUMBER
|| tv->vval.v_number == 0
- || tv->vval.v_number != channel->ch_part[part].ch_block_id)))
+ || tv->vval.v_number != channel->ch_part[part].ch_block_id))))
{
*rettv = item->jq_value;
if (tv->v_type == VAR_NUMBER)
@@ -2080,6 +2089,65 @@
return FAIL;
}
+/*
+ * Put back "rettv" into the JSON queue, there was no callback for it.
+ * Takes over the values in "rettv".
+ */
+ static void
+channel_push_json(channel_T *channel, ch_part_T part, typval_T *rettv)
+{
+ jsonq_T *head = &channel->ch_part[part].ch_json_head;
+ jsonq_T *item = head->jq_next;
+ jsonq_T *newitem;
+
+ if (head->jq_prev != NULL && head->jq_prev->jq_no_callback)
+ /* last item was pushed back, append to the end */
+ item = NULL;
+ else while (item != NULL && item->jq_no_callback)
+ /* append after the last item that was pushed back */
+ item = item->jq_next;
+
+ newitem = (jsonq_T *)alloc((unsigned)sizeof(jsonq_T));
+ if (newitem == NULL)
+ clear_tv(rettv);
+ else
+ {
+ newitem->jq_value = alloc_tv();
+ if (newitem->jq_value == NULL)
+ {
+ vim_free(newitem);
+ clear_tv(rettv);
+ }
+ else
+ {
+ newitem->jq_no_callback = FALSE;
+ *newitem->jq_value = *rettv;
+ if (item == NULL)
+ {
+ /* append to the end */
+ newitem->jq_prev = head->jq_prev;
+ head->jq_prev = newitem;
+ newitem->jq_next = NULL;
+ if (newitem->jq_prev == NULL)
+ head->jq_next = newitem;
+ else
+ newitem->jq_prev->jq_next = newitem;
+ }
+ else
+ {
+ /* append after "item" */
+ newitem->jq_prev = item;
+ newitem->jq_next = item->jq_next;
+ item->jq_next = newitem;
+ if (newitem->jq_next == NULL)
+ head->jq_prev = newitem;
+ else
+ newitem->jq_next->jq_prev = newitem;
+ }
+ }
+ }
+}
+
#define CH_JSON_MAX_ARGS 4
/*
@@ -2410,11 +2478,11 @@
int argc = 0;
/* Get any json message in the queue. */
- if (channel_get_json(channel, part, -1, &listtv) == FAIL)
+ if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
{
/* Parse readahead, return when there is still no message. */
channel_parse_json(channel, part);
- if (channel_get_json(channel, part, -1, &listtv) == FAIL)
+ if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
return FALSE;
}
@@ -2454,7 +2522,7 @@
{
/* If there is a close callback it may use ch_read() to get the
* messages. */
- if (channel->ch_close_cb == NULL)
+ if (channel->ch_close_cb == NULL && !channel->ch_drop_never)
drop_messages(channel, part);
return FALSE;
}
@@ -2531,7 +2599,7 @@
{
int done = FALSE;
- /* invoke the one-time callback with the matching nr */
+ /* JSON or JS mode: invoke the one-time callback with the matching nr */
for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next)
if (cbitem->cq_seq_nr == seq_nr)
{
@@ -2540,7 +2608,17 @@
break;
}
if (!done)
- ch_logn(channel, "Dropping message %d without callback", seq_nr);
+ {
+ if (channel->ch_drop_never)
+ {
+ /* message must be read with ch_read() */
+ channel_push_json(channel, part, listtv);
+ listtv = NULL;
+ }
+ else
+ ch_logn(channel, "Dropping message %d without callback",
+ seq_nr);
+ }
}
else if (callback != NULL || buffer != NULL)
{
@@ -2567,7 +2645,7 @@
}
}
else
- ch_log(channel, "Dropping message");
+ ch_logn(channel, "Dropping message %d", seq_nr);
if (listtv != NULL)
free_tv(listtv);
@@ -2603,7 +2681,7 @@
/*
* Return TRUE if "channel" has JSON or other typeahead.
*/
- static int
+ int
channel_has_readahead(channel_T *channel, ch_part_T part)
{
ch_mode_T ch_mode = channel->ch_part[part].ch_mode;
@@ -2792,9 +2870,10 @@
redraw_after_callback();
}
- /* any remaining messages are useless now */
- for (part = PART_SOCK; part < PART_IN; ++part)
- drop_messages(channel, part);
+ if (!channel->ch_drop_never)
+ /* any remaining messages are useless now */
+ for (part = PART_SOCK; part < PART_IN; ++part)
+ drop_messages(channel, part);
}
channel->ch_nb_close_cb = NULL;
@@ -3091,9 +3170,9 @@
channel_close_now(channel_T *channel)
{
ch_log(channel, "Closing channel because all readable fds are closed");
- channel_close(channel, TRUE);
if (channel->ch_nb_close_cb != NULL)
(*channel->ch_nb_close_cb)();
+ channel_close(channel, TRUE);
}
/*
@@ -3243,7 +3322,7 @@
* When "id" is -1 accept any message;
* Blocks until the message is received or the timeout is reached.
*/
- int
+ static int
channel_read_json_block(
channel_T *channel,
ch_part_T part,
@@ -3264,7 +3343,7 @@
more = channel_parse_json(channel, part);
/* search for message "id" */
- if (channel_get_json(channel, part, id, rettv) == OK)
+ if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
{
chanpart->ch_block_id = 0;
return OK;
@@ -3815,6 +3894,11 @@
int ret = FALSE;
int r;
ch_part_T part = PART_SOCK;
+#ifdef ELAPSED_FUNC
+ ELAPSED_TYPE start_tv;
+
+ ELAPSED_INIT(start_tv);
+#endif
++safe_to_invoke_callback;
@@ -3859,7 +3943,14 @@
r = may_invoke_callback(channel, part);
if (r == OK)
ret = TRUE;
- if (channel_unref(channel) || r == OK)
+ if (channel_unref(channel) || (r == OK
+#ifdef ELAPSED_FUNC
+ /* Limit the time we loop here to 100 msec, otherwise
+ * Vim becomes unresponsive when the callback takes
+ * more than a bit of time. */
+ && ELAPSED_FUNC(start_tv) < 100L
+#endif
+ ))
{
/* channel was freed or something was done, start over */
channel = first_channel;
@@ -3888,6 +3979,31 @@
}
/*
+ * Return TRUE if any channel has readahead. That means we should not block on
+ * waiting for input.
+ */
+ int
+channel_any_readahead(void)
+{
+ channel_T *channel = first_channel;
+ ch_part_T part = PART_SOCK;
+
+ while (channel != NULL)
+ {
+ if (channel_has_readahead(channel, part))
+ return TRUE;
+ if (part < PART_ERR)
+ ++part;
+ else
+ {
+ channel = channel->ch_next;
+ part = PART_SOCK;
+ }
+ }
+ return FALSE;
+}
+
+/*
* Mark references to lists used in channels.
*/
int
@@ -4253,6 +4369,20 @@
return FAIL;
}
}
+ else if (STRCMP(hi->hi_key, "drop") == 0)
+ {
+ int never = FALSE;
+ val = get_tv_string(item);
+
+ if (STRCMP(val, "never") == 0)
+ never = TRUE;
+ else if (STRCMP(val, "auto") != 0)
+ {
+ EMSG2(_(e_invarg2), "drop");
+ return FAIL;
+ }
+ opt->jo_drop_never = never;
+ }
else if (STRCMP(hi->hi_key, "exit_cb") == 0)
{
if (!(supported & JO_EXIT_CB))
diff --git a/src/config.h.in b/src/config.h.in
index 5baac7d..38b0ccf 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -154,7 +154,6 @@
#undef BAD_GETCWD
/* Define if you the function: */
-#undef HAVE_BCMP
#undef HAVE_FCHDIR
#undef HAVE_FCHOWN
#undef HAVE_FSEEKO
@@ -170,7 +169,6 @@
#undef HAVE_ICONV
#undef HAVE_NL_LANGINFO_CODESET
#undef HAVE_LSTAT
-#undef HAVE_MEMCMP
#undef HAVE_MEMSET
#undef HAVE_MKDTEMP
#undef HAVE_NANOSLEEP
diff --git a/src/configure.ac b/src/configure.ac
index f6a4469..3a31f97 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -3594,8 +3594,8 @@
dnl Check for functions in one big call, to reduce the size of configure.
dnl Can only be used for functions that do not require any include.
-AC_CHECK_FUNCS(bcmp fchdir fchown fsync getcwd getpseudotty \
- getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
+AC_CHECK_FUNCS(fchdir fchown fsync getcwd getpseudotty \
+ getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat \
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 846a914..6721173 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -76,6 +76,7 @@
static void f_ceil(typval_T *argvars, typval_T *rettv);
#endif
#ifdef FEAT_JOB_CHANNEL
+static void f_ch_canread(typval_T *argvars, typval_T *rettv);
static void f_ch_close(typval_T *argvars, typval_T *rettv);
static void f_ch_close_in(typval_T *argvars, typval_T *rettv);
static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
@@ -499,6 +500,7 @@
{"ceil", 1, 1, f_ceil},
#endif
#ifdef FEAT_JOB_CHANNEL
+ {"ch_canread", 1, 1, f_ch_canread},
{"ch_close", 1, 1, f_ch_close},
{"ch_close_in", 1, 1, f_ch_close_in},
{"ch_evalexpr", 2, 3, f_ch_evalexpr},
@@ -1779,6 +1781,21 @@
#ifdef FEAT_JOB_CHANNEL
/*
+ * "ch_canread()" function
+ */
+ static void
+f_ch_canread(typval_T *argvars, typval_T *rettv)
+{
+ channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
+
+ rettv->vval.v_number = 0;
+ if (channel != NULL)
+ rettv->vval.v_number = channel_has_readahead(channel, PART_SOCK)
+ || channel_has_readahead(channel, PART_OUT)
+ || channel_has_readahead(channel, PART_ERR);
+}
+
+/*
* "ch_close()" function
*/
static void
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 02c5ed1..eae37bf 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2297,19 +2297,24 @@
# define GetTextWidthEnc(h, s, l) GetTextWidth((h), (s), (l))
#endif
+static void get_work_area(RECT *spi_rect);
+
/*
* A quick little routine that will center one window over another, handy for
- * dialog boxes. Taken from the Win32SDK samples.
+ * dialog boxes. Taken from the Win32SDK samples and modified for multiple
+ * monitors.
*/
static BOOL
CenterWindow(
HWND hwndChild,
HWND hwndParent)
{
- RECT rChild, rParent;
- int wChild, hChild, wParent, hParent;
- int wScreen, hScreen, xNew, yNew;
- HDC hdc;
+ HMONITOR mon;
+ MONITORINFO moninfo;
+ RECT rChild, rParent, rScreen;
+ int wChild, hChild, wParent, hParent;
+ int xNew, yNew;
+ HDC hdc;
GetWindowRect(hwndChild, &rChild);
wChild = rChild.right - rChild.left;
@@ -2317,32 +2322,39 @@
/* If Vim is minimized put the window in the middle of the screen. */
if (hwndParent == NULL || IsMinimized(hwndParent))
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rParent, 0);
+ get_work_area(&rParent);
else
GetWindowRect(hwndParent, &rParent);
wParent = rParent.right - rParent.left;
hParent = rParent.bottom - rParent.top;
- hdc = GetDC(hwndChild);
- wScreen = GetDeviceCaps (hdc, HORZRES);
- hScreen = GetDeviceCaps (hdc, VERTRES);
- ReleaseDC(hwndChild, hdc);
-
- xNew = rParent.left + ((wParent - wChild) /2);
- if (xNew < 0)
+ moninfo.cbSize = sizeof(MONITORINFO);
+ mon = MonitorFromWindow(hwndChild, MONITOR_DEFAULTTOPRIMARY);
+ if (mon != NULL && GetMonitorInfo(mon, &moninfo))
{
- xNew = 0;
+ rScreen = moninfo.rcWork;
}
- else if ((xNew+wChild) > wScreen)
+ else
{
- xNew = wScreen - wChild;
+ hdc = GetDC(hwndChild);
+ rScreen.left = 0;
+ rScreen.top = 0;
+ rScreen.right = GetDeviceCaps(hdc, HORZRES);
+ rScreen.bottom = GetDeviceCaps(hdc, VERTRES);
+ ReleaseDC(hwndChild, hdc);
}
- yNew = rParent.top + ((hParent - hChild) /2);
- if (yNew < 0)
- yNew = 0;
- else if ((yNew+hChild) > hScreen)
- yNew = hScreen - hChild;
+ xNew = rParent.left + ((wParent - wChild) / 2);
+ if (xNew < rScreen.left)
+ xNew = rScreen.left;
+ else if ((xNew + wChild) > rScreen.right)
+ xNew = rScreen.right - wChild;
+
+ yNew = rParent.top + ((hParent - hChild) / 2);
+ if (yNew < rScreen.top)
+ yNew = rScreen.top;
+ else if ((yNew + hChild) > rScreen.bottom)
+ yNew = rScreen.bottom - hChild;
return SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
@@ -3539,12 +3551,12 @@
filterp = convert_filterW(filter);
vim_memset(&fileStruct, 0, sizeof(OPENFILENAMEW));
-#ifdef OPENFILENAME_SIZE_VERSION_400W
+# ifdef OPENFILENAME_SIZE_VERSION_400W
/* be compatible with Windows NT 4.0 */
fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
-#else
+# else
fileStruct.lStructSize = sizeof(fileStruct);
-#endif
+# endif
if (title != NULL)
titlep = enc_to_utf16(title, NULL);
@@ -3581,10 +3593,10 @@
* Don't use OFN_OVERWRITEPROMPT, Vim has its own ":confirm" dialog.
*/
fileStruct.Flags = (OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY);
-#ifdef FEAT_SHORTCUT
+# ifdef FEAT_SHORTCUT
if (curbuf->b_p_bin)
fileStruct.Flags |= OFN_NODEREFERENCELINKS;
-#endif
+# endif
if (saving)
{
if (!GetSaveFileNameW(&fileStruct))
@@ -5559,7 +5571,7 @@
MONITORINFO moninfo;
/* work out which monitor the window is on, and get *it's* work area */
- mon = MonitorFromWindow(s_hwnd, 1 /*MONITOR_DEFAULTTOPRIMARY*/);
+ mon = MonitorFromWindow(s_hwnd, MONITOR_DEFAULTTOPRIMARY);
if (mon != NULL)
{
moninfo.cbSize = sizeof(MONITORINFO);
diff --git a/src/message.c b/src/message.c
index 32360a9..7dda6fa 100644
--- a/src/message.c
+++ b/src/message.c
@@ -42,6 +42,9 @@
static char_u *confirm_msg = NULL; /* ":confirm" message */
static char_u *confirm_msg_tail; /* tail of confirm_msg */
#endif
+#ifdef FEAT_JOB_CHANNEL
+static int emsg_to_channel_log = FALSE;
+#endif
struct msg_hist
{
@@ -166,6 +169,14 @@
&& STRCMP(s, last_msg_hist->msg)))
add_msg_hist(s, -1, attr);
+#ifdef FEAT_JOB_CHANNEL
+ if (emsg_to_channel_log)
+ {
+ /* Write message in the channel log. */
+ ch_logs(NULL, "ERROR: %s", (char *)s);
+ }
+#endif
+
/* When displaying keep_msg, don't let msg_start() free it, caller must do
* that. */
if (s == keep_msg)
@@ -556,6 +567,7 @@
{
int attr;
char_u *p;
+ int r;
#ifdef FEAT_EVAL
int ignore = FALSE;
int severe;
@@ -624,6 +636,9 @@
}
redir_write(s, -1);
}
+#ifdef FEAT_JOB_CHANNEL
+ ch_logs(NULL, "ERROR: %s", (char *)s);
+#endif
return TRUE;
}
@@ -650,6 +665,9 @@
* and a redraw is expected because
* msg_scrolled is non-zero */
+#ifdef FEAT_JOB_CHANNEL
+ emsg_to_channel_log = TRUE;
+#endif
/*
* Display name and line number for the source of the error.
*/
@@ -659,7 +677,12 @@
* Display the error message itself.
*/
msg_nowait = FALSE; /* wait for this msg */
- return msg_attr(s, attr);
+ r = msg_attr(s, attr);
+
+#ifdef FEAT_JOB_CHANNEL
+ emsg_to_channel_log = FALSE;
+#endif
+ return r;
}
diff --git a/src/misc2.c b/src/misc2.c
index 27d26be..baa614d 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1740,27 +1740,6 @@
}
#endif
-#ifdef VIM_MEMCMP
-/*
- * Return zero when "b1" and "b2" are the same for "len" bytes.
- * Return non-zero otherwise.
- */
- int
-vim_memcmp(void *b1, void *b2, size_t len)
-{
- char_u *p1 = (char_u *)b1, *p2 = (char_u *)b2;
-
- for ( ; len > 0; --len)
- {
- if (*p1 != *p2)
- return 1;
- ++p1;
- ++p2;
- }
- return 0;
-}
-#endif
-
/* skipped when generating prototypes, the prototype is in vim.h */
#ifdef VIM_MEMMOVE
/*
@@ -6263,3 +6242,31 @@
# endif
}
#endif
+
+#ifdef ELAPSED_TIMEVAL /* no PROTO here, proto is defined in vim.h */
+/*
+ * Return time in msec since "start_tv".
+ */
+ long
+elapsed(struct timeval *start_tv)
+{
+ struct timeval now_tv;
+
+ gettimeofday(&now_tv, NULL);
+ return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
+ + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
+}
+#endif
+
+#ifdef ELAPSED_TICKCOUNT
+/*
+ * Return time in msec since "start_tick".
+ */
+ long
+elapsed(DWORD start_tick)
+{
+ DWORD now = GetTickCount();
+
+ return (long)now - (long)start_tick;
+}
+#endif
diff --git a/src/option.c b/src/option.c
index 2b9ba2d..7356816 100644
--- a/src/option.c
+++ b/src/option.c
@@ -452,10 +452,11 @@
#define P_NFNAME 0x400000L /* only normal file name chars allowed */
#define P_INSECURE 0x800000L /* option was set from a modeline */
#define P_PRI_MKRC 0x1000000L /* priority for :mkvimrc (setting option has
- side effects) */
+ side effects) */
#define P_NO_ML 0x2000000L /* not allowed in modeline */
#define P_CURSWANT 0x4000000L /* update curswant required; not needed when
* there is a redraw flag */
+#define P_NDNAME 0x8000000L /* only normal dir name chars allowed */
#define ISK_LATIN1 (char_u *)"@,48-57,_,192-255"
@@ -992,7 +993,7 @@
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
- {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP,
+ {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME,
#ifdef FEAT_INS_EXPAND
(char_u *)&p_dict, PV_DICT,
#else
@@ -2058,7 +2059,7 @@
{(char_u *)NULL, (char_u *)0L}
#endif
SCRIPTID_INIT},
- {"printexpr", "pexpr", P_STRING|P_VI_DEF,
+ {"printexpr", "pexpr", P_STRING|P_VI_DEF|P_SECURE,
#ifdef FEAT_POSTSCRIPT
(char_u *)&p_pexpr, PV_NONE,
{(char_u *)"", (char_u *)0L}
@@ -2659,7 +2660,7 @@
{"textwidth", "tw", P_NUM|P_VI_DEF|P_VIM|P_RBUF,
(char_u *)&p_tw, PV_TW,
{(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
- {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP,
+ {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME,
#ifdef FEAT_INS_EXPAND
(char_u *)&p_tsr, PV_TSR,
#else
@@ -5876,11 +5877,15 @@
errmsg = e_secure;
}
- /* Check for a "normal" file name in some options. Disallow a path
- * separator (slash and/or backslash), wildcards and characters that are
- * often illegal in a file name. */
- else if ((options[opt_idx].flags & P_NFNAME)
- && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL)
+ /* Check for a "normal" directory or file name in some options. Disallow a
+ * path separator (slash and/or backslash), wildcards and characters that
+ * are often illegal in a file name. Be more permissive if "secure" is off.
+ */
+ else if (((options[opt_idx].flags & P_NFNAME)
+ && vim_strpbrk(*varp, (char_u *)(secure
+ ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
+ || ((options[opt_idx].flags & P_NDNAME)
+ && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL))
{
errmsg = e_invarg;
}
@@ -7021,6 +7026,7 @@
#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
+ /* 'toolbar' */
else if (varp == &p_toolbar)
{
if (opt_strings_flags(p_toolbar, p_toolbar_values,
@@ -7235,6 +7241,7 @@
#endif
#if defined(FEAT_RENDER_OPTIONS)
+ /* 'renderoptions' */
else if (varp == &p_rop && gui.in_use)
{
if (!gui_mch_set_rendering_options(p_rop))
@@ -7262,19 +7269,19 @@
else
{
p = NULL;
- if (varp == &p_ww)
+ if (varp == &p_ww) /* 'whichwrap' */
p = (char_u *)WW_ALL;
- if (varp == &p_shm)
+ if (varp == &p_shm) /* 'shortmess' */
p = (char_u *)SHM_ALL;
- else if (varp == &(p_cpo))
+ else if (varp == &(p_cpo)) /* 'cpoptions' */
p = (char_u *)CPO_ALL;
- else if (varp == &(curbuf->b_p_fo))
+ else if (varp == &(curbuf->b_p_fo)) /* 'formatoptions' */
p = (char_u *)FO_ALL;
#ifdef FEAT_CONCEAL
- else if (varp == &curwin->w_p_cocu)
+ else if (varp == &curwin->w_p_cocu) /* 'concealcursor' */
p = (char_u *)COCU_ALL;
#endif
- else if (varp == &p_mouse)
+ else if (varp == &p_mouse) /* 'mouse' */
{
#ifdef FEAT_MOUSE
p = (char_u *)MOUSE_ALL;
@@ -7284,7 +7291,7 @@
#endif
}
#if defined(FEAT_GUI)
- else if (varp == &p_go)
+ else if (varp == &p_go) /* 'guioptions' */
p = (char_u *)GO_ALL;
#endif
if (p != NULL)
diff --git a/src/os_mswin.c b/src/os_mswin.c
index dc55389..408438e 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -40,7 +40,7 @@
# include <dlgs.h>
# include <winspool.h>
# include <commdlg.h>
-#endif
+# endif
#endif /* PROTO */
@@ -1619,7 +1619,9 @@
if (psettings->n_uncollated_copies == 0)
psettings->n_uncollated_copies = 1;
- } else {
+ }
+ else
+ {
psettings->n_collated_copies = 1;
psettings->n_uncollated_copies = 1;
}
diff --git a/src/os_unix.c b/src/os_unix.c
index a63eb6e..aa3c3e5 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -376,21 +376,6 @@
RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL);
}
-#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-/*
- * Return time in msec since "start_tv".
- */
- static long
-elapsed(struct timeval *start_tv)
-{
- struct timeval now_tv;
-
- gettimeofday(&now_tv, NULL);
- return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
- + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
-}
-#endif
-
/*
* mch_inchar(): low level input function.
* Get a characters from the keyboard.
@@ -411,10 +396,10 @@
int did_start_blocking = FALSE;
long wait_time;
long elapsed_time = 0;
-#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- struct timeval start_tv;
+#ifdef ELAPSED_FUNC
+ ELAPSED_TYPE start_tv;
- gettimeofday(&start_tv, NULL);
+ ELAPSED_INIT(start_tv);
#endif
/* repeat until we got a character or waited long enough */
@@ -438,8 +423,8 @@
else
/* going to block after p_ut */
wait_time = p_ut;
-#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- elapsed_time = elapsed(&start_tv);
+#ifdef ELAPSED_FUNC
+ elapsed_time = ELAPSED_FUNC(start_tv);
#endif
wait_time -= elapsed_time;
if (wait_time < 0)
@@ -477,6 +462,10 @@
/* Checking if a job ended requires polling. Do this every 100 msec. */
if (has_pending_job() && (wait_time < 0 || wait_time > 100L))
wait_time = 100L;
+ /* If there is readahead then parse_queued_messages() timed out and we
+ * should call it again soon. */
+ if ((wait_time < 0 || wait_time > 100L) && channel_any_readahead())
+ wait_time = 10L;
#endif
/*
@@ -1554,18 +1543,16 @@
#ifdef FEAT_X11
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
+# if defined(ELAPSED_TIMEVAL) \
&& (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
-static void xopen_message(struct timeval *start_tv);
-
/*
* Give a message about the elapsed time for opening the X window.
*/
static void
-xopen_message(struct timeval *start_tv)
+xopen_message(long elapsed_msec)
{
- smsg((char_u *)_("Opening the X display took %ld msec"), elapsed(start_tv));
+ smsg((char_u *)_("Opening the X display took %ld msec"), elapsed_msec);
}
# endif
#endif
@@ -1864,11 +1851,11 @@
#endif
if (x11_display != NULL)
{
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
if (p_verbose > 0)
{
verbose_enter();
- xopen_message(&start_tv);
+ xopen_message(ELAPSED_FUNC(start_tv));
verbose_leave();
}
# endif
@@ -4630,8 +4617,8 @@
ga_init2(&ga, 1, BUFLEN);
noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- gettimeofday(&start_tv, NULL);
+# ifdef ELAPSED_FUNC
+ ELAPSED_INIT(start_tv);
# endif
for (;;)
{
@@ -4666,8 +4653,8 @@
/* Get extra characters when we don't have any.
* Reset the counter and timer. */
noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- gettimeofday(&start_tv, NULL);
+# ifdef ELAPSED_FUNC
+ ELAPSED_INIT(start_tv);
# endif
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
}
@@ -4886,10 +4873,10 @@
if (got_int)
break;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
if (wait_pid == 0)
{
- long msec = elapsed(&start_tv);
+ long msec = ELAPSED_FUNC(start_tv);
/* Avoid that we keep looping here without
* checking for a CTRL-C for a long time. Don't
@@ -5632,15 +5619,14 @@
/* May retry getting characters after an event was handled. */
# define MAY_LOOP
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
/* Remember at what time we started, so that we know how much longer we
* should wait after being interrupted. */
-# define USE_START_TV
long start_msec = msec;
- struct timeval start_tv;
+ ELAPSED_TYPE start_tv;
if (msec > 0)
- gettimeofday(&start_tv, NULL);
+ ELAPSED_INIT(start_tv);
# endif
/* Handle being called recursively. This may happen for the session
@@ -5947,9 +5933,9 @@
/* We're going to loop around again, find out for how long */
if (msec > 0)
{
-# ifdef USE_START_TV
+# ifdef ELAPSED_FUNC
/* Compute remaining wait time. */
- msec = start_msec - elapsed(&start_tv);
+ msec = start_msec - ELAPSED_FUNC(start_tv);
# else
/* Guess we got interrupted halfway. */
msec = msec / 2;
@@ -7046,11 +7032,11 @@
#if defined(HAVE_SETJMP_H)
int (*oldIOhandler)();
#endif
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- struct timeval start_tv;
+# ifdef ELAPSED_FUNC
+ ELAPSED_TYPE start_tv;
if (p_verbose > 0)
- gettimeofday(&start_tv, NULL);
+ ELAPSED_INIT(start_tv);
# endif
/* Ignore X errors while opening the display */
@@ -7092,11 +7078,11 @@
/* Catch terminating error of the X server connection. */
(void)XSetIOErrorHandler(x_IOerror_handler);
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
if (p_verbose > 0)
{
verbose_enter();
- xopen_message(&start_tv);
+ xopen_message(ELAPSED_FUNC(start_tv));
verbose_leave();
}
# endif
diff --git a/src/os_vms_conf.h b/src/os_vms_conf.h
index 5c110f2..9aa7526 100644
--- a/src/os_vms_conf.h
+++ b/src/os_vms_conf.h
@@ -101,7 +101,6 @@
#define HAVE_STRTOL
#define HAVE_TGETENT
#define HAVE_MEMSET
-#define HAVE_MEMCMP
#define HAVE_STRERROR
#define HAVE_FCHOWN
#define HAVE_RENAME
diff --git a/src/os_win32.c b/src/os_win32.c
index 34b2ca8..e08adcb 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1351,9 +1351,15 @@
DWORD dwWaitTime = dwEndTime - dwNow;
#ifdef FEAT_JOB_CHANNEL
- /* Check channel while waiting input. */
+ /* Check channel while waiting for input. */
if (dwWaitTime > 100)
+ {
dwWaitTime = 100;
+ /* If there is readahead then parse_queued_messages() timed out
+ * and we should call it again soon. */
+ if (channel_any_readahead())
+ dwWaitTime = 10;
+ }
#endif
#ifdef FEAT_MZSCHEME
if (mzthreads_allowed() && p_mzq > 0
@@ -4287,9 +4293,6 @@
/* Get extra characters when we don't have any. Reset the
* counter and timer. */
noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- gettimeofday(&start_tv, NULL);
-# endif
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
}
if (ta_len > 0 || len > 0)
diff --git a/src/osdef1.h.in b/src/osdef1.h.in
index a11e6ea..5519104 100644
--- a/src/osdef1.h.in
+++ b/src/osdef1.h.in
@@ -50,12 +50,7 @@
#ifdef HAVE_MEMSET
extern void *memset(void *, int, size_t);
#endif
-#ifdef HAVE_BCMP
-extern int bcmp(void *, void *, size_t);
-#endif
-#ifdef HAVE_MEMCMP
extern int memcmp(const void *, const void *, size_t);
-#endif
#ifdef HAVE_STRPBRK
extern char *strpbrk(const char *, const char *);
#endif
diff --git a/src/popupmnu.c b/src/popupmnu.c
index 19d215b..307dbbe 100644
--- a/src/popupmnu.c
+++ b/src/popupmnu.c
@@ -105,7 +105,8 @@
/* Put the pum below "row" if possible. If there are few lines decide on
* where there is more room. */
- if (row - above_row >= below_row - row)
+ if (row + 2 >= below_row - pum_height
+ && row - above_row > (below_row - above_row) / 2)
{
/* pum above "row" */
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 6a52d8b..a54d387 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -25,6 +25,7 @@
int channel_collapse(channel_T *channel, ch_part_T part, int want_nl);
int channel_can_write_to(channel_T *channel);
int channel_is_open(channel_T *channel);
+int channel_has_readahead(channel_T *channel, ch_part_T part);
char *channel_status(channel_T *channel, int req_part);
void channel_info(channel_T *channel, dict_T *dict);
void channel_close(channel_T *channel, int invoke_close_cb);
@@ -32,7 +33,6 @@
void channel_clear(channel_T *channel);
void channel_free_all(void);
char_u *channel_read_block(channel_T *channel, ch_part_T part, int timeout);
-int channel_read_json_block(channel_T *channel, ch_part_T part, int timeout_arg, int id, typval_T **rettv);
void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp);
void channel_handle_events(void);
@@ -44,6 +44,7 @@
int channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in);
int channel_select_check(int ret_in, void *rfds_in, void *wfds_in);
int channel_parse_messages(void);
+int channel_any_readahead(void);
int set_ref_in_channel(int copyID);
ch_part_T channel_part_send(channel_T *channel);
ch_part_T channel_part_read(channel_T *channel);
diff --git a/src/search.c b/src/search.c
index cedcad9..36410e5 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1695,7 +1695,8 @@
}
else
{
- if (vim_memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop)
+ if (memcmp(p + col, lastc_bytes, lastc_bytelen) == 0
+ && stop)
break;
}
stop = TRUE;
diff --git a/src/structs.h b/src/structs.h
index 1b73e37..3fdfb5f 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1474,6 +1474,7 @@
typval_T *jq_value;
jsonq_T *jq_next;
jsonq_T *jq_prev;
+ int jq_no_callback; /* TRUE when no callback was found */
};
struct cbq_S
@@ -1597,6 +1598,7 @@
partial_T *ch_partial;
char_u *ch_close_cb; /* call when channel is closed */
partial_T *ch_close_partial;
+ int ch_drop_never;
job_T *ch_job; /* Job that uses this channel; this does not
* count as a reference to avoid a circular
@@ -1684,6 +1686,7 @@
partial_T *jo_close_partial; /* not referenced! */
char_u *jo_exit_cb; /* not allocated! */
partial_T *jo_exit_partial; /* not referenced! */
+ int jo_drop_never;
int jo_waittime;
int jo_timeout;
int jo_out_timeout;
diff --git a/src/tag.c b/src/tag.c
index 14fdcf8..646cbcd 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -742,7 +742,7 @@
/* skip backslash used for escaping a command char or
* a backslash */
if (*p == '\\' && (*(p + 1) == *tagp.command
- || *(p + 1) == '\\'))
+ || *(p + 1) == '\\'))
++p;
if (*p == TAB)
@@ -1356,6 +1356,7 @@
char_u *help_lang_find = NULL; /* lang to be found */
char_u help_lang[3]; /* lang of current tags file */
char_u *saved_pat = NULL; /* copy of pat[] */
+ int is_txt = FALSE; /* flag of file extension */
#endif
pat_T orgpat; /* holds unconverted pattern info */
@@ -1388,7 +1389,7 @@
*/
switch (curbuf->b_tc_flags ? curbuf->b_tc_flags : tc_flags)
{
- case TC_FOLLOWIC: break;
+ case TC_FOLLOWIC: break;
case TC_IGNORE: p_ic = TRUE; break;
case TC_MATCH: p_ic = FALSE; break;
case TC_FOLLOWSCS: p_ic = ignorecase(pat); break;
@@ -1476,6 +1477,15 @@
* When the tag file is case-fold sorted, it is either one or the other.
* Only ignore case when TAG_NOIC not used or 'ignorecase' set.
*/
+#ifdef FEAT_MULTI_LANG
+ /* Set a flag if the file extension is .txt */
+ if ((flags & TAG_KEEP_LANG)
+ && help_lang_find == NULL
+ && curbuf->b_fname != NULL
+ && (i = (int)STRLEN(curbuf->b_fname)) > 4
+ && STRICMP(curbuf->b_fname + i - 4, ".txt") == 0)
+ is_txt = TRUE;
+#endif
#ifdef FEAT_TAG_BINS
orgpat.regmatch.rm_ic = ((p_ic || !noic)
&& (findall || orgpat.headlen == 0 || !p_tbs));
@@ -1509,14 +1519,19 @@
#ifdef FEAT_MULTI_LANG
if (curbuf->b_help)
{
- /* Prefer help tags according to 'helplang'. Put the
- * two-letter language name in help_lang[]. */
- i = (int)STRLEN(tag_fname);
- if (i > 3 && tag_fname[i - 3] == '-')
- STRCPY(help_lang, tag_fname + i - 2);
- else
+ /* Keep en if the file extension is .txt*/
+ if (is_txt)
STRCPY(help_lang, "en");
-
+ else
+ {
+ /* Prefer help tags according to 'helplang'. Put the
+ * two-letter language name in help_lang[]. */
+ i = (int)STRLEN(tag_fname);
+ if (i > 3 && tag_fname[i - 3] == '-')
+ STRCPY(help_lang, tag_fname + i - 2);
+ else
+ STRCPY(help_lang, "en");
+ }
/* When searching for a specific language skip tags files
* for other languages. */
if (help_lang_find != NULL
@@ -2400,7 +2415,7 @@
mfp2 = ((struct match_found **)
(ga_match[mtt].ga_data))[i];
if (mfp2->len == mfp->len
- && vim_memcmp(mfp2->match, mfp->match,
+ && memcmp(mfp2->match, mfp->match,
(size_t)mfp->len) == 0)
break;
fast_breakcheck();
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 49d2de0..17c70f3 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -63,8 +63,6 @@
test88.out \
test90.out \
test91.out \
- test92.out \
- test93.out \
test94.out \
test95.out \
test98.out \
@@ -167,6 +165,8 @@
test_man.res \
test_marks.res \
test_matchadd_conceal.res \
+ test_mksession.res \
+ test_mksession_utf8.res \
test_nested_function.res \
test_netbeans.res \
test_normal.res \
diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
index 6962cf0..43e1416 100644
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -92,7 +92,7 @@
test72.out test75.out \
test77a.out test78.out test79.out test80.out \
test82.out test84.out test88.out test89.out \
- test90.out test91.out test92.out test93.out test94.out \
+ test90.out test91.out test94.out \
test95.out test98.out test99.out \
test103.out test104.out \
test107.out test108.out\
diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim
index 45a2ea4..8160af3 100644
--- a/src/testdir/shared.vim
+++ b/src/testdir/shared.vim
@@ -88,7 +88,7 @@
call call(function(a:testfunc), [port])
catch
- call assert_false(1, "Caught exception: " . v:exception)
+ call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
finally
call s:kill_server(a:cmd)
endtry
diff --git a/src/testdir/test92.in b/src/testdir/test92.in
deleted file mode 100644
index 9593aec..0000000
--- a/src/testdir/test92.in
+++ /dev/null
@@ -1,48 +0,0 @@
-vim: set ft=vim fenc=utf-8:
-
-Tests if :mksession saves cursor columns correctly in presence of tab and
-multibyte characters when fileencoding=utf-8.
-
-STARTTEST
-:so mbyte.vim
-:if !has('mksession')
-: e! test.ok
-: wq! test.out
-:endif
-:set sessionoptions=buffers splitbelow fileencoding=utf-8
-/^start:
-:vsplit
-j16|:split
-j16|:split
-j16|:split
-j8|:split
-j8|:split
-j16|:split
-j16|:split
-j16|:wincmd l
-/^start:
-:set nowrap
-j16|3zl:split
-j016|3zl:split
-j016|3zl:split
-j08|3zl:split
-j08|3zl:split
-j016|3zl:split
-j016|3zl:split
-j016|3zl:split
-:mksession! test.out
-:new test.out
-:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
-:w! test.out
-:qa!
-ENDTEST
-
-start:
-no multibyte chAracter
- one leaDing tab
- four leadinG spaces
-two consecutive tabs
-two tabs in one line
-one … multibyteCharacter
-a “b” two multiByte characters
-“c”1€ three mulTibyte characters
diff --git a/src/testdir/test92.ok b/src/testdir/test92.ok
deleted file mode 100644
index cca5ec4..0000000
--- a/src/testdir/test92.ok
+++ /dev/null
@@ -1,26 +0,0 @@
-normal! 016|
-normal! 016|
-normal! 016|
-normal! 08|
-normal! 08|
-normal! 016|
-normal! 016|
-normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
diff --git a/src/testdir/test93.in b/src/testdir/test93.in
deleted file mode 100644
index 877838c..0000000
--- a/src/testdir/test93.in
+++ /dev/null
@@ -1,48 +0,0 @@
-vim: set ft=vim fenc=latin1:
-
-Tests if :mksession saves cursor columns correctly in presence of tab and
-multibyte characters when fileencoding=latin1.
-
-STARTTEST
-:so mbyte.vim
-:if !has('mksession')
-: e! test.ok
-: wq! test.out
-:endif
-:set sessionoptions=buffers splitbelow fileencoding=latin1
-/^start:
-:vsplit
-j16|:split
-j16|:split
-j16|:split
-j8|:split
-j8|:split
-j16|:split
-j16|:split
-j16|:wincmd l
-/^start:
-:set nowrap
-j16|3zl:split
-j016|3zl:split
-j016|3zl:split
-j08|3zl:split
-j08|3zl:split
-j016|3zl:split
-j016|3zl:split
-j016|3zl:split
-:mksession! test.out
-:new test.out
-:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
-:w! test.out
-:qa!
-ENDTEST
-
-start:
-no multibyte chAracter
- one leaDing tab
- four leadinG spaces
-two consecutive tabs
-two tabs in one line
-one ä multibyteCharacter
-aä Ä two multiByte characters
-Aäöü three mulTibyte characters
diff --git a/src/testdir/test93.ok b/src/testdir/test93.ok
deleted file mode 100644
index cca5ec4..0000000
--- a/src/testdir/test93.ok
+++ /dev/null
@@ -1,26 +0,0 @@
-normal! 016|
-normal! 016|
-normal! 016|
-normal! 08|
-normal! 08|
-normal! 016|
-normal! 016|
-normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index 42e0e04..31c2e50 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -58,6 +58,9 @@
" string with ][ should work
call assert_equal('this][that', ch_evalexpr(handle, 'echo this][that'))
+ " nothing to read now
+ call assert_equal(0, ch_canread(handle))
+
" sending three messages quickly then reading should work
for i in range(3)
call ch_sendexpr(handle, 'echo hello ' . i)
@@ -126,6 +129,9 @@
call ch_setoptions(handle, {'mode': 'json'})
call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475")
call ch_setoptions(handle, {'callback': ''})
+ call ch_setoptions(handle, {'drop': 'never'})
+ call ch_setoptions(handle, {'drop': 'auto'})
+ call assert_fails("call ch_setoptions(handle, {'drop': 'bad'})", "E475")
" Send an eval request that works.
call assert_equal('ok', ch_evalexpr(handle, 'eval-works'))
@@ -246,6 +252,7 @@
"""""""""
func Ch_handler(chan, msg)
+ call ch_log('Ch_handler()')
unlet g:Ch_reply
let g:Ch_reply = a:msg
endfunc
@@ -269,6 +276,7 @@
endfunc
func Test_channel_handler()
+call ch_logfile('channellog', 'w')
call ch_log('Test_channel_handler()')
let g:Ch_reply = ""
let s:chopt.callback = 'Ch_handler'
@@ -368,7 +376,7 @@
endif
call ch_setoptions(handle, {'mode': 'raw'})
- " The message are sent raw, we do our own JSON strings here.
+ " The messages are sent raw, we do our own JSON strings here.
call ch_sendraw(handle, "[1, \"hello!\"]\n", {'callback': 'Ch_handleRaw1'})
call WaitFor('g:Ch_reply1 != ""')
call assert_equal("[1, \"got it\"]", g:Ch_reply1)
@@ -431,7 +439,10 @@
return
endif
call ch_log('Test_raw_pipe()')
- let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
+ " Add a dummy close callback to avoid that messages are dropped when calling
+ " ch_canread().
+ let job = job_start(s:python . " test_channel_pipe.py",
+ \ {'mode': 'raw', 'drop': 'never'})
call assert_equal(v:t_job, type(job))
call assert_equal("run", job_status(job))
@@ -458,6 +469,9 @@
call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
call ch_sendraw(job, "double this\n")
+ let g:handle = job_getchannel(job)
+ call WaitFor('ch_canread(g:handle)')
+ unlet g:handle
let msg = ch_readraw(job)
call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
diff --git a/src/testdir/test_help_tagjump.vim b/src/testdir/test_help_tagjump.vim
index d11a1fa..1d44389 100644
--- a/src/testdir/test_help_tagjump.vim
+++ b/src/testdir/test_help_tagjump.vim
@@ -141,4 +141,36 @@
endtry
endfunc
+func Test_help_respect_current_file_lang()
+ try
+ let list = []
+ call s:doc_config_setup()
+
+ if has('multi_lang')
+ function s:check_help_file_ext(help_keyword, ext)
+ exec 'help ' . a:help_keyword
+ call assert_equal(a:ext, expand('%:e'))
+ call feedkeys("\<C-]>", 'tx')
+ call assert_equal(a:ext, expand('%:e'))
+ pop
+ helpclose
+ endfunc
+
+ set rtp+=Xdir1/doc-ab
+ set rtp+=Xdir1/doc-ja
+
+ set helplang=ab
+ call s:check_help_file_ext('test-char', 'abx')
+ call s:check_help_file_ext('test-char@ja', 'jax')
+ set helplang=ab,ja
+ call s:check_help_file_ext('test-char@ja', 'jax')
+ call s:check_help_file_ext('test-char@en', 'txt')
+ endif
+ catch
+ call assert_exception('X')
+ finally
+ call s:doc_config_teardown()
+ endtry
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_history.vim b/src/testdir/test_history.vim
index ee6acff..243ede7 100644
--- a/src/testdir/test_history.vim
+++ b/src/testdir/test_history.vim
@@ -31,6 +31,30 @@
call assert_equal('ls', histget(a:hist, -1))
call assert_equal(4, histnr(a:hist))
+ let a=execute('history ' . a:hist)
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history all')
+ call assert_match("^\n # .* history\n 3 buffers\n> 4 ls", a)
+
+ if len(a:hist) > 0
+ let a=execute('history ' . a:hist . ' 2')
+ call assert_match("^\n # \\S* history$", a)
+ let a=execute('history ' . a:hist . ' 3')
+ call assert_match("^\n # \\S* history\n 3 buffers$", a)
+ let a=execute('history ' . a:hist . ' 4')
+ call assert_match("^\n # \\S* history\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' 3,4')
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -1')
+ call assert_match("^\n # \\S* history\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -2')
+ call assert_match("^\n # \\S* history\n 3 buffers$", a)
+ let a=execute('history ' . a:hist . ' -2,')
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -3')
+ call assert_match("^\n # \\S* history$", a)
+ endif
+
" Test for removing entries matching a pattern
for i in range(1, 3)
call histadd(a:hist, 'text_' . i)
diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim
new file mode 100644
index 0000000..c19f3c5
--- /dev/null
+++ b/src/testdir/test_mksession.vim
@@ -0,0 +1,104 @@
+" Test for :mksession, :mkview and :loadview in latin1 encoding
+
+set encoding=latin1
+scriptencoding latin1
+
+if !has('multi_byte') || !has('mksession')
+ finish
+endif
+
+func Test_mksession()
+ tabnew
+ let wrap_save = &wrap
+ set sessionoptions=buffers splitbelow fileencoding=latin1
+ call setline(1, [
+ \ 'start:',
+ \ 'no multibyte chAracter',
+ \ ' one leaDing tab',
+ \ ' four leadinG spaces',
+ \ 'two consecutive tabs',
+ \ 'two tabs in one line',
+ \ 'one ä multibyteCharacter',
+ \ 'aä Ä two multiByte characters',
+ \ 'Aäöü three mulTibyte characters'
+ \ ])
+ let tmpfile = tempname()
+ exec 'w! ' . tmpfile
+ /^start:
+ set wrap
+ vsplit
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j8|
+ split
+ norm! j8|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ wincmd l
+
+ set nowrap
+ /^start:
+ norm! j16|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ call wincol()
+ mksession! test_mks.out
+ let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
+ let expected = [
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 08|',
+ \ 'normal! 08|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|"
+ \ ]
+ call assert_equal(expected, li)
+ tabclose!
+
+ call delete('test_mks.out')
+ call delete(tmpfile)
+ let &wrap = wrap_save
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_mksession_utf8.vim b/src/testdir/test_mksession_utf8.vim
new file mode 100644
index 0000000..c05a1d3
--- /dev/null
+++ b/src/testdir/test_mksession_utf8.vim
@@ -0,0 +1,104 @@
+" Test for :mksession, :mkview and :loadview in utf-8 encoding
+
+set encoding=utf-8
+scriptencoding utf-8
+
+if !has('multi_byte') || !has('mksession')
+ finish
+endif
+
+func Test_mksession_utf8()
+ tabnew
+ let wrap_save = &wrap
+ set sessionoptions=buffers splitbelow fileencoding=utf-8
+ call setline(1, [
+ \ 'start:',
+ \ 'no multibyte chAracter',
+ \ ' one leaDing tab',
+ \ ' four leadinG spaces',
+ \ 'two consecutive tabs',
+ \ 'two tabs in one line',
+ \ 'one … multibyteCharacter',
+ \ 'a “b” two multiByte characters',
+ \ '“c”1€ three mulTibyte characters'
+ \ ])
+ let tmpfile = tempname()
+ exec 'w! ' . tmpfile
+ /^start:
+ set wrap
+ vsplit
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j8|
+ split
+ norm! j8|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ wincmd l
+
+ set nowrap
+ /^start:
+ norm! j16|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ call wincol()
+ mksession! test_mks.out
+ let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
+ let expected = [
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 08|',
+ \ 'normal! 08|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|"
+ \ ]
+ call assert_equal(expected, li)
+ tabclose!
+
+ call delete('test_mks.out')
+ call delete(tmpfile)
+ let &wrap = wrap_save
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 3b6f662..6dfb1bb 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -106,3 +106,26 @@
call assert_fails(":set kmp=trunc\x00name", "E544:")
call assert_fails(":set kmp=trunc\x00name", "trunc")
endfunc
+
+func Check_dir_option(name)
+ " Check that it's possible to set the option.
+ exe 'set ' . a:name . '=/usr/share/dict/words'
+ call assert_equal('/usr/share/dict/words', eval('&' . a:name))
+ exe 'set ' . a:name . '=/usr/share/dict/words,/and/there'
+ call assert_equal('/usr/share/dict/words,/and/there', eval('&' . a:name))
+ exe 'set ' . a:name . '=/usr/share/dict\ words'
+ call assert_equal('/usr/share/dict words', eval('&' . a:name))
+
+ " Check rejecting weird characters.
+ call assert_fails("set " . a:name . "=/not&there", "E474:")
+ call assert_fails("set " . a:name . "=/not>there", "E474:")
+ call assert_fails("set " . a:name . "=/not.*there", "E474:")
+endfunc
+
+func Test_dictionary()
+ call Check_dir_option('dictionary')
+endfunc
+
+func Test_thesaurus()
+ call Check_dir_option('thesaurus')
+endfunc
diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim
index 3f69fb9..1720107 100644
--- a/src/testdir/test_tabpage.vim
+++ b/src/testdir/test_tabpage.vim
@@ -65,6 +65,15 @@
call assert_true(tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1)
tabclose
q
+ "
+ "
+ " Test for ":tab drop vertical-split-window" to jump test1 buffer
+ tabedit test1
+ vnew
+ tabfirst
+ tab drop test1
+ call assert_equal([2, 2, 2, 2], [tabpagenr('$'), tabpagenr(), tabpagewinnr(2, '$'), tabpagewinnr(2)])
+ 1tabonly
endif
"
"
diff --git a/src/version.c b/src/version.c
index 497746f..372d92f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,48 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 117,
+/**/
+ 116,
+/**/
+ 115,
+/**/
+ 114,
+/**/
+ 113,
+/**/
+ 112,
+/**/
+ 111,
+/**/
+ 110,
+/**/
+ 109,
+/**/
+ 108,
+/**/
+ 107,
+/**/
+ 106,
+/**/
+ 105,
+/**/
+ 104,
+/**/
+ 103,
+/**/
+ 102,
+/**/
+ 101,
+/**/
+ 100,
+/**/
+ 99,
+/**/
+ 98,
+/**/
+ 97,
+/**/
96,
/**/
95,
diff --git a/src/vim.h b/src/vim.h
index eec3e4f..de26c63 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1733,17 +1733,6 @@
void *vim_memset(void *, int, size_t);
#endif
-#ifdef HAVE_MEMCMP
-# define vim_memcmp(p1, p2, len) memcmp((p1), (p2), (len))
-#else
-# ifdef HAVE_BCMP
-# define vim_memcmp(p1, p2, len) bcmp((p1), (p2), (len))
-# else
-int vim_memcmp(void *, void *, size_t);
-# define VIM_MEMCMP
-# endif
-#endif
-
#if defined(UNIX) || defined(FEAT_GUI) || defined(VMS) \
|| defined(FEAT_CLIENTSERVER)
# define USE_INPUT_BUF
@@ -2503,4 +2492,20 @@
# define OPEN_CHR_FILES
#endif
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# define ELAPSED_TIMEVAL
+# define ELAPSED_INIT(v) gettimeofday(&v, NULL)
+# define ELAPSED_FUNC(v) elapsed(&v)
+# define ELAPSED_TYPE struct timeval
+ long elapsed(struct timeval *start_tv);
+#else
+# if defined(WIN32)
+# define ELAPSED_TICKCOUNT
+# define ELAPSED_INIT(v) v = GetTickCount()
+# define ELAPSED_FUNC(v) elapsed(v)
+# define ELAPSED_TYPE DWORD
+ long elapsed(DWORD start_tick);
+# endif
+#endif
+
#endif /* VIM__H */