Merge remote-tracking branch 'vim/master'

This commit is contained in:
Yee Cheng Chin
2019-06-09 15:08:49 -07:00
25 changed files with 663 additions and 155 deletions
+3
View File
@@ -88,6 +88,7 @@ SRC_ALL = \
src/search.c \
src/sha256.c \
src/sign.c \
src/sound.c \
src/spell.c \
src/spell.h \
src/spellfile.c \
@@ -150,6 +151,7 @@ SRC_ALL = \
src/testdir/samples/test000 \
src/testdir/if_ver*.vim \
src/testdir/color_ramp.vim \
src/testdir/silent.wav \
src/proto.h \
src/protodef.h \
src/proto/arabic.pro \
@@ -209,6 +211,7 @@ SRC_ALL = \
src/proto/search.pro \
src/proto/sha256.pro \
src/proto/sign.pro \
src/proto/sound.pro \
src/proto/spell.pro \
src/proto/spellfile.pro \
src/proto/syntax.pro \
+59
View File
@@ -2326,6 +2326,7 @@ extend({expr1}, {expr2} [, {expr3}])
exp({expr}) Float exponential of {expr}
expand({expr} [, {nosuf} [, {list}]])
any expand special keywords in {expr}
expandcmd({expr}) String expand {expr} like with `:edit`
feedkeys({string} [, {mode}]) Number add key sequence to typeahead buffer
filereadable({file}) Number |TRUE| if {file} is a readable file
filewritable({file}) Number |TRUE| if {file} is a writable file
@@ -2622,6 +2623,12 @@ sin({expr}) Float sine of {expr}
sinh({expr}) Float hyperbolic sine of {expr}
sort({list} [, {func} [, {dict}]])
List sort {list}, using {func} to compare
sound_playevent({name} [, {callback}])
Number play an event sound
sound_playfile({name} [, {callback}])
Number play a sound file
sound_stop({id}) none stop playing sound {id}
sound_stopall() none stop playing all sounds
soundfold({word}) String sound-fold {word}
spellbadword() String badly spelled word at cursor
spellsuggest({word} [, {max} [, {capital}]])
@@ -4212,6 +4219,14 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
See |glob()| for finding existing files. See |system()| for
getting the raw output of an external command.
expandcmd({expr}) *expandcmd()*
Expand special items in {expr} like what is done for an Ex
command such as `:edit`. This expands special keywords, like
with |expand()|, and environment variables, anywhere in
{expr}. Returns the expanded string.
Example: >
:echo expandcmd('make %<.o')
<
extend({expr1}, {expr2} [, {expr3}]) *extend()*
{expr1} and {expr2} must be both |Lists| or both
|Dictionaries|.
@@ -8837,6 +8852,49 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702*
return a:i1 - a:i2
endfunc
<
*sound_playevent()*
sound_playevent({name} [, {callback}])
Play a sound identified by {name}. Which event names are
supported depends on the system. Often the XDG sound names
are used. On Ubuntu they may be found in
/usr/share/sounds/freedesktop/stereo. Example: >
call sound_playevent('bell')
< When {callback} is specified it is invoked when the sound is
finished. The first argument is the sound ID, the second
argument is the status:
0 sound was played to the end
1 sound was interruped
2 error occured after sound started
Example: >
func Callback(id, status)
echomsg "sound " .. a:id .. " finished with " .. a:status
endfunc
call sound_playevent('bell', 'Callback')
< Returns the sound ID, which can be passed to `sound_stop()`.
Returns zero if the sound could not be played.
{only available when compiled with the +sound feature}
*sound_playfile()*
sound_playfile({name} [, {callback}])
Like `sound_playevent()` but play sound file {name}. {name}
must be a full path. On Ubuntu you may find files to play
with this command: >
:!find /usr/share/sounds -type f | grep -v index.theme
< {only available when compiled with the +sound feature}
sound_stop({id}) *sound_stop()*
Stop playing sound {id}. {id} must be previously returned by
`sound_playevent()` or `sound_playfile()`.
{only available when compiled with the +sound feature}
sound_stopall() *sound_stopall()*
Stop playing all sounds.
{only available when compiled with the +sound feature}
*soundfold()*
soundfold({word})
Return the sound-folded equivalent of {word}. Uses the first
@@ -10759,6 +10817,7 @@ scrollbind Compiled with 'scrollbind' support. (always true)
showcmd Compiled with 'showcmd' support.
signs Compiled with |:sign| support.
smartindent Compiled with 'smartindent' support.
sound Compiled with sound support, e.g. `sound_playevent()`
spell Compiled with spell checking support |spell|.
startuptime Compiled with |--startuptime| support.
statusline Compiled with support for 'statusline', 'rulerformat'
+5
View File
@@ -6220,6 +6220,7 @@ exp() eval.txt /*exp()*
expand() eval.txt /*expand()*
expand-env options.txt /*expand-env*
expand-environment-var options.txt /*expand-environment-var*
expandcmd() eval.txt /*expandcmd()*
expr eval.txt /*expr*
expr-! eval.txt /*expr-!*
expr-!= eval.txt /*expr-!=*
@@ -8812,6 +8813,10 @@ slow-terminal term.txt /*slow-terminal*
socket-interface channel.txt /*socket-interface*
sort() eval.txt /*sort()*
sorting change.txt /*sorting*
sound_playevent() eval.txt /*sound_playevent()*
sound_playfile() eval.txt /*sound_playfile()*
sound_stop() eval.txt /*sound_stop()*
sound_stopall() eval.txt /*sound_stopall()*
soundfold() eval.txt /*soundfold()*
space intro.txt /*space*
spec-customizing pi_spec.txt /*spec-customizing*
+2 -1
View File
@@ -1,4 +1,4 @@
*usr_41.txt* For Vim version 8.1. Last change: 2019 May 29
*usr_41.txt* For Vim version 8.1. Last change: 2019 Jun 09
VIM USER MANUAL - by Bram Moolenaar
@@ -609,6 +609,7 @@ String manipulation: *string-functions*
strcharpart() get part of a string using char index
strgetchar() get character from a string using char index
expand() expand special keywords
expandcmd() expand a command like done for `:edit`
iconv() convert text from one encoding to another
byteidx() byte index of a character in a string
byteidxcomp() like byteidx() but count composing characters
+10
View File
@@ -1645,6 +1645,7 @@ BASIC_SRC = \
search.c \
sha256.c \
sign.c \
sound.c \
spell.c \
spellfile.c \
syntax.c \
@@ -1760,6 +1761,7 @@ OBJ_COMMON = \
objects/search.o \
objects/sha256.o \
objects/sign.o \
objects/sound.o \
objects/spell.o \
objects/spellfile.o \
objects/syntax.o \
@@ -1900,6 +1902,7 @@ PRO_AUTO = \
search.pro \
sha256.pro \
sign.pro \
sound.pro \
spell.pro \
spellfile.pro \
syntax.pro \
@@ -3261,6 +3264,9 @@ objects/sha256.o: sha256.c
objects/sign.o: sign.c
$(CCC) -o $@ sign.c
objects/sound.o: sound.c
$(CCC) -o $@ sound.c
objects/spell.o: spell.c
$(CCC) -o $@ spell.c
@@ -3707,6 +3713,10 @@ objects/sign.o: sign.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
proto.h globals.h
objects/sound.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
proto.h globals.h
objects/spell.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
+72 -123
View File
@@ -9414,28 +9414,8 @@ fi
if test -z "$SKIP_GTK2"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5
$as_echo_n "checking --disable-gtktest argument... " >&6; }
# Check whether --enable-gtktest was given.
if test "${enable_gtktest+set}" = set; then :
enableval=$enable_gtktest;
else
enable_gtktest=yes
fi
if test "x$enable_gtktest" = "xyes" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5
$as_echo "gtk test enabled" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5
$as_echo "gtk test disabled" >&6; }
fi
if test "X$PKG_CONFIG" = "X"; then
if test -n "$ac_tool_prefix"; then
if test "X$PKG_CONFIG" = "X"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -9533,6 +9513,26 @@ else
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
fi
fi
if test -z "$SKIP_GTK2"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5
$as_echo_n "checking --disable-gtktest argument... " >&6; }
# Check whether --enable-gtktest was given.
if test "${enable_gtktest+set}" = set; then :
enableval=$enable_gtktest;
else
enable_gtktest=yes
fi
if test "x$enable_gtktest" = "xyes" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5
$as_echo "gtk test enabled" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5
$as_echo "gtk test disabled" >&6; }
fi
if test "x$PKG_CONFIG" != "xno"; then
@@ -9788,107 +9788,6 @@ $as_echo "gtk test enabled" >&6; }
$as_echo "gtk test disabled" >&6; }
fi
if test "X$PKG_CONFIG" = "X"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PKG_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
if test -n "$PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
$as_echo "$PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_PKG_CONFIG"; then
ac_pt_PKG_CONFIG=$PKG_CONFIG
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_PKG_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
if test -n "$ac_pt_PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
$as_echo "$ac_pt_PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_PKG_CONFIG" = x; then
PKG_CONFIG="no"
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
PKG_CONFIG=$ac_pt_PKG_CONFIG
fi
else
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
fi
fi
if test "x$PKG_CONFIG" != "xno"; then
if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then
@@ -13137,6 +13036,56 @@ rm -rf conftest*
fi
if test "x$PKG_CONFIG" != "xno"; then
canberra_lib=`$PKG_CONFIG --libs libcanberrax 2>/dev/null`
canberra_cflags=`$PKG_CONFIG --cflags libcanberrax 2>/dev/null`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_lib: $canberra_lib" >&5
$as_echo "canberra_lib: $canberra_lib" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_cflags: $canberra_cflags" >&5
$as_echo "canberra_cflags: $canberra_cflags" >&6; }
fi
if test "x$canberra_lib" = "x"; then
canberra_lib=-lcanberra
canberra_cflags=-D_REENTRANT
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_lib: $canberra_lib" >&5
$as_echo "canberra_lib: $canberra_lib" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_cflags: $canberra_cflags" >&5
$as_echo "canberra_cflags: $canberra_cflags" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcanberra" >&5
$as_echo_n "checking for libcanberra... " >&6; }
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $canberra_cflags"
LIBS="$LIBS $canberra_lib"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
# include <canberra.h>
int
main ()
{
ca_context *hello;
ca_context_create(&hello);
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }; $as_echo "#define HAVE_CANBERRA 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }; CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS"
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_blksize" >&5
$as_echo_n "checking for st_blksize... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+73 -10
View File
@@ -2179,11 +2179,67 @@ remove_json_node(jsonq_T *head, jsonq_T *node)
vim_free(node);
}
/*
* Add "id" to the list of JSON message IDs we are waiting on.
*/
static void
channel_add_block_id(chanpart_T *chanpart, int id)
{
garray_T *gap = &chanpart->ch_block_ids;
if (gap->ga_growsize == 0)
ga_init2(gap, (int)sizeof(int), 10);
if (ga_grow(gap, 1) == OK)
{
((int *)gap->ga_data)[gap->ga_len] = id;
++gap->ga_len;
}
}
/*
* Remove "id" from the list of JSON message IDs we are waiting on.
*/
static void
channel_remove_block_id(chanpart_T *chanpart, int id)
{
garray_T *gap = &chanpart->ch_block_ids;
int i;
for (i = 0; i < gap->ga_len; ++i)
if (((int *)gap->ga_data)[i] == id)
{
--gap->ga_len;
if (i < gap->ga_len)
{
int *p = ((int *)gap->ga_data) + i;
mch_memmove(p, p + 1, (gap->ga_len - i) * sizeof(int));
}
return;
}
siemsg("INTERNAL: channel_remove_block_id: cannot find id %d", id);
}
/*
* Return TRUE if "id" is in the list of JSON message IDs we are waiting on.
*/
static int
channel_has_block_id(chanpart_T *chanpart, int id)
{
garray_T *gap = &chanpart->ch_block_ids;
int i;
for (i = 0; i < gap->ga_len; ++i)
if (((int *)gap->ga_data)[i] == id)
return TRUE;
return FALSE;
}
/*
* Get a message from the JSON queue for channel "channel".
* 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 "id" is zero or negative jut get the first message. But not one
* in the ch_block_ids list.
* 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.
@@ -2208,7 +2264,8 @@ channel_get_json(
&& ((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))))
|| !channel_has_block_id(
&channel->ch_part[part], tv->vval.v_number)))))
{
*rettv = item->jq_value;
if (tv->v_type == VAR_NUMBER)
@@ -3076,6 +3133,7 @@ channel_clear_one(channel_T *channel, ch_part_T part)
}
free_callback(&ch_part->ch_callback);
ga_clear(&ch_part->ch_block_ids);
while (ch_part->ch_writeque.wq_next != NULL)
remove_from_writeque(&ch_part->ch_writeque,
@@ -3506,6 +3564,8 @@ channel_read_block(
* result in "rettv".
* When "id" is -1 accept any message;
* Blocks until the message is received or the timeout is reached.
* In corner cases this can be called recursively, that is why ch_block_ids is
* a list.
*/
static int
channel_read_json_block(
@@ -3520,17 +3580,19 @@ channel_read_json_block(
int timeout;
chanpart_T *chanpart = &channel->ch_part[part];
ch_log(channel, "Reading JSON");
if (id != -1)
chanpart->ch_block_id = id;
ch_log(channel, "Blocking read JSON for id %d", id);
if (id >= 0)
channel_add_block_id(chanpart, id);
for (;;)
{
more = channel_parse_json(channel, part);
/* search for message "id" */
// search for message "id"
if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
{
chanpart->ch_block_id = 0;
if (id >= 0)
channel_remove_block_id(chanpart, id);
ch_log(channel, "Received JSON for id %d", id);
return OK;
}
@@ -3577,7 +3639,7 @@ channel_read_json_block(
if (timeout == timeout_arg)
{
if (fd != INVALID_FD)
ch_log(channel, "Timed out");
ch_log(channel, "Timed out on id %d", id);
break;
}
}
@@ -3585,7 +3647,8 @@ channel_read_json_block(
channel_read(channel, part, "channel_read_json_block");
}
}
chanpart->ch_block_id = 0;
if (id >= 0)
channel_remove_block_id(chanpart, id);
return FAIL;
}
+1
View File
@@ -207,6 +207,7 @@
#undef HAVE_STRNICMP
#undef HAVE_STRPBRK
#undef HAVE_STRTOL
#undef HAVE_CANBERRA
#undef HAVE_ST_BLKSIZE
#undef HAVE_SYSCONF
#undef HAVE_SYSCTL
+27 -8
View File
@@ -2787,6 +2787,10 @@ AC_DEFUN([GNOME_INIT],[
GNOME_INIT_HOOK([],fail)
])
if test "X$PKG_CONFIG" = "X"; then
AC_PATH_TOOL(PKG_CONFIG, pkg-config, no)
fi
dnl ---------------------------------------------------------------------------
dnl Check for GTK2. If it fails, then continue on for Motif as before...
@@ -2802,10 +2806,6 @@ if test -z "$SKIP_GTK2"; then
AC_MSG_RESULT(gtk test disabled)
fi
if test "X$PKG_CONFIG" = "X"; then
AC_PATH_TOOL(PKG_CONFIG, pkg-config, no)
fi
if test "x$PKG_CONFIG" != "xno"; then
dnl First try finding version 2.2.0 or later. The 2.0.x series has
dnl problems (bold fonts, --remote doesn't work).
@@ -2854,10 +2854,6 @@ if test -z "$SKIP_GTK3"; then
AC_MSG_RESULT(gtk test disabled)
fi
if test "X$PKG_CONFIG" = "X"; then
AC_PATH_TOOL(PKG_CONFIG, pkg-config, no)
fi
if test "x$PKG_CONFIG" != "xno"; then
AM_PATH_GTK(3.0.0,
[GUI_LIB_LOC="$GTK_LIBDIR"
@@ -3840,6 +3836,29 @@ dnl define _LARGE_FILES, _FILE_OFFSET_BITS and _LARGEFILE_SOURCE when
dnl appropriate, so that off_t is 64 bits when needed.
AC_SYS_LARGEFILE
if test "x$PKG_CONFIG" != "xno"; then
canberra_lib=`$PKG_CONFIG --libs libcanberra 2>/dev/null`
canberra_cflags=`$PKG_CONFIG --cflags libcanberra 2>/dev/null`
fi
if test "x$canberra_lib" = "x"; then
canberra_lib=-lcanberra
canberra_cflags=-D_REENTRANT
fi
AC_MSG_CHECKING(for libcanberra)
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $canberra_cflags"
LIBS="$LIBS $canberra_lib"
AC_TRY_LINK([
# include <canberra.h>
], [
ca_context *hello;
ca_context_create(&hello);],
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_CANBERRA),
AC_MSG_RESULT(no); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS")
dnl fstatfs() can take 2 to 4 arguments, try to use st_blksize if possible
AC_MSG_CHECKING(for st_blksize)
AC_TRY_COMPILE(
+40
View File
@@ -149,6 +149,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv);
static void f_exp(typval_T *argvars, typval_T *rettv);
#endif
static void f_expand(typval_T *argvars, typval_T *rettv);
static void f_expandcmd(typval_T *argvars, typval_T *rettv);
static void f_extend(typval_T *argvars, typval_T *rettv);
static void f_feedkeys(typval_T *argvars, typval_T *rettv);
static void f_filereadable(typval_T *argvars, typval_T *rettv);
@@ -646,6 +647,7 @@ static struct fst
{"exp", 1, 1, f_exp},
#endif
{"expand", 1, 3, f_expand},
{"expandcmd", 1, 1, f_expandcmd},
{"extend", 2, 3, f_extend},
{"feedkeys", 1, 2, f_feedkeys},
{"file_readable", 1, 1, f_filereadable}, /* obsolete */
@@ -925,6 +927,12 @@ static struct fst
{"sinh", 1, 1, f_sinh},
#endif
{"sort", 1, 3, f_sort},
#ifdef FEAT_SOUND
{"sound_playevent", 1, 2, f_sound_playevent},
{"sound_playfile", 1, 2, f_sound_playfile},
{"sound_stop", 1, 1, f_sound_stop},
{"sound_stopall", 0, 0, f_sound_stopall},
#endif
{"soundfold", 1, 1, f_soundfold},
{"spellbadword", 0, 1, f_spellbadword},
{"spellsuggest", 1, 3, f_spellsuggest},
@@ -3784,6 +3792,35 @@ f_expand(typval_T *argvars, typval_T *rettv)
}
}
/*
* "expandcmd()" function
* Expand all the special characters in a command string.
*/
static void
f_expandcmd(typval_T *argvars, typval_T *rettv)
{
exarg_T eap;
char_u *cmdstr;
char *errormsg = NULL;
rettv->v_type = VAR_STRING;
cmdstr = vim_strsave(tv_get_string(&argvars[0]));
memset(&eap, 0, sizeof(eap));
eap.cmd = cmdstr;
eap.arg = cmdstr;
eap.argt |= NOSPC;
eap.usefilter = FALSE;
eap.nextcmd = NULL;
eap.cmdidx = CMD_USER;
expand_filename(&eap, &cmdstr, &errormsg);
if (errormsg != NULL && *errormsg != NUL)
emsg(errormsg);
rettv->vval.v_string = cmdstr;
}
/*
* "extend(list, list [, idx])" function
* "extend(dict, dict [, action])" function
@@ -6799,6 +6836,9 @@ f_has(typval_T *argvars, typval_T *rettv)
#ifdef FEAT_ODB_EDITOR
"odbeditor",
#endif
#ifdef FEAT_SOUND
"sound",
#endif
#ifdef FEAT_SPELL
"spell",
#endif
+7
View File
@@ -663,6 +663,13 @@
# define FEAT_TERM_POPUP_MENU
#endif
/*
* sound - currently only with libcanberra
*/
#if !defined(FEAT_SOUND) && defined(FEAT_BIG) && defined(HAVE_CANBERRA)
# define FEAT_SOUND
#endif
/* There are two ways to use XPM. */
#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
|| defined(HAVE_X11_XPM_H)
+3 -3
View File
@@ -1454,9 +1454,9 @@ prompt_for_number(int *mouse_used)
i = get_number(TRUE, mouse_used);
if (KeyTyped)
{
/* don't call wait_return() now */
/* msg_putchar('\n'); */
cmdline_row = msg_row - 1;
// don't call wait_return() now
if (msg_row > 0)
cmdline_row = msg_row - 1;
need_wait_return = FALSE;
msg_didany = FALSE;
msg_didout = FALSE;
+1
View File
@@ -183,6 +183,7 @@ void qsort(void *base, size_t elm_count, size_t elm_size, int (*cmp)(const void
# ifdef FEAT_SIGNS
# include "sign.pro"
# endif
# include "sound.pro"
# include "spell.pro"
# include "spellfile.pro"
# include "syntax.pro"
+7
View File
@@ -0,0 +1,7 @@
/* sound.c */
void f_sound_playevent(typval_T *argvars, typval_T *rettv);
void f_sound_playfile(typval_T *argvars, typval_T *rettv);
void f_sound_stop(typval_T *argvars, typval_T *rettv);
void f_sound_stopall(typval_T *argvars, typval_T *rettv);
void sound_free(void);
/* vim: set ft=c : */
+4 -5
View File
@@ -3961,12 +3961,11 @@ win_line(
/*
* Handle highlighting the last used search pattern and matches.
* Do this for both search_hl and the match list.
* Not in a popup window.
* Do not use search_hl in a popup window.
*/
cur = wp->w_match_head;
shl_flag = FALSE;
while ((cur != NULL || shl_flag == FALSE) && !number_only
&& !(screen_line_flags & SLF_POPUP))
shl_flag = (screen_line_flags & SLF_POPUP);
while ((cur != NULL || shl_flag == FALSE) && !number_only)
{
if (shl_flag == FALSE)
{
@@ -4442,7 +4441,7 @@ win_line(
*/
v = (long)(ptr - line);
cur = wp->w_match_head;
shl_flag = FALSE;
shl_flag = (screen_line_flags & SLF_POPUP);
while (cur != NULL || shl_flag == FALSE)
{
if (shl_flag == FALSE
+193
View File
@@ -0,0 +1,193 @@
/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
/*
* sound.c: functions related making noise
*/
#include "vim.h"
#if (defined(FEAT_SOUND) && defined(HAVE_CANBERRA)) || defined(PROTO)
#include <canberra.h>
static long sound_id = 0;
static ca_context *context = NULL;
typedef struct soundcb_S soundcb_T;
struct soundcb_S {
callback_T snd_callback;
soundcb_T *snd_next;
};
static soundcb_T *first_callback = NULL;
static soundcb_T *
get_sound_callback(typval_T *arg)
{
callback_T callback;
soundcb_T *soundcb;
if (arg->v_type == VAR_UNKNOWN)
return NULL;
callback = get_callback(arg);
if (callback.cb_name == NULL)
return NULL;
soundcb = ALLOC_ONE(soundcb_T);
if (soundcb == NULL)
free_callback(&callback);
else
{
soundcb->snd_next = first_callback;
first_callback = soundcb;
set_callback(&soundcb->snd_callback, &callback);
}
return soundcb;
}
/*
* Delete "soundcb" from the list of pending callbacks.
*/
static void
delete_sound_callback(soundcb_T *soundcb)
{
soundcb_T *p;
soundcb_T *prev = NULL;
for (p = first_callback; p != NULL; prev = p, p = p->snd_next)
if (p == soundcb)
{
if (prev == NULL)
first_callback = p->snd_next;
else
prev->snd_next = p->snd_next;
free_callback(&p->snd_callback);
vim_free(p);
break;
}
}
static void
sound_callback(
ca_context *c UNUSED,
uint32_t id,
int error_code,
void *userdata)
{
soundcb_T *soundcb = (soundcb_T *)userdata;
typval_T argv[3];
typval_T rettv;
int dummy;
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = id;
argv[1].v_type = VAR_NUMBER;
argv[1].vval.v_number = error_code == CA_SUCCESS ? 0
: error_code == CA_ERROR_CANCELED
|| error_code == CA_ERROR_DESTROYED
? 1 : 2;
argv[2].v_type = VAR_UNKNOWN;
call_callback(&soundcb->snd_callback, -1,
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
delete_sound_callback(soundcb);
redraw_after_callback(TRUE);
}
static void
sound_play_common(typval_T *argvars, typval_T *rettv, int playfile)
{
if (context == NULL)
ca_context_create(&context);
if (context != NULL)
{
soundcb_T *soundcb = get_sound_callback(&argvars[1]);
int res = CA_ERROR_INVALID;
++sound_id;
if (soundcb == NULL)
{
res = ca_context_play(context, sound_id,
playfile ? CA_PROP_MEDIA_FILENAME : CA_PROP_EVENT_ID,
tv_get_string(&argvars[0]),
CA_PROP_CANBERRA_CACHE_CONTROL, "volatile",
NULL);
}
else
{
static ca_proplist *proplist = NULL;
ca_proplist_create(&proplist);
if (proplist != NULL)
{
if (playfile)
ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME,
(char *)tv_get_string(&argvars[0]));
else
ca_proplist_sets(proplist, CA_PROP_EVENT_ID,
(char *)tv_get_string(&argvars[0]));
ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL,
"volatile");
res = ca_context_play_full(context, sound_id, proplist,
sound_callback, soundcb);
if (res != CA_SUCCESS)
delete_sound_callback(soundcb);
ca_proplist_destroy(proplist);
}
}
rettv->vval.v_number = res == CA_SUCCESS ? sound_id : 0;
}
}
void
f_sound_playevent(typval_T *argvars, typval_T *rettv)
{
sound_play_common(argvars, rettv, FALSE);
}
void
f_sound_playfile(typval_T *argvars, typval_T *rettv)
{
sound_play_common(argvars, rettv, TRUE);
}
void
f_sound_stop(typval_T *argvars, typval_T *rettv UNUSED)
{
if (context != NULL)
ca_context_cancel(context, tv_get_number(&argvars[0]));
}
void
f_sound_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
{
if (context != NULL)
{
ca_context_destroy(context);
context = NULL;
}
}
#if defined(EXITFREE) || defined(PROTO)
void
sound_free(void)
{
if (context != NULL)
ca_context_destroy(context);
while (first_callback != NULL)
delete_sound_callback(first_callback);
}
#endif
#endif // FEAT_SOUND && HAVE_CANBERRA
+2 -2
View File
@@ -1683,8 +1683,8 @@ typedef struct {
readq_T ch_head; /* header for circular raw read queue */
jsonq_T ch_json_head; /* header for circular json read queue */
int ch_block_id; /* ID that channel_read_json_block() is
waiting for */
garray_T ch_block_ids; /* list of IDs that channel_read_json_block()
is waiting for */
/* When ch_wait_len is non-zero use ch_deadline to wait for incomplete
* message to be complete. The value is the length of the incomplete
* message when the deadline was set. If it gets longer (something was
+2
View File
@@ -228,6 +228,7 @@ NEW_TESTS = \
test_signs \
test_smartindent \
test_sort \
test_sound \
test_source \
test_source_utf8 \
test_spell \
@@ -399,6 +400,7 @@ NEW_TESTS_RES = \
test_signals.res \
test_signs.res \
test_smartindent.res \
test_sound.res \
test_source.res \
test_spell.res \
test_startup.res \
+3 -3
View File
@@ -85,9 +85,9 @@ RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG)
clean:
-rm -rf *.out *.failed *.res *.rej *.orig
-rm opt_test.vim test.log test_result.log messages
-rm $(RM_ON_RUN) $(RM_ON_START)
-rm valgrind.*
-rm -f opt_test.vim test.log test_result.log messages
-rm -f $(RM_ON_RUN) $(RM_ON_START)
-rm -f valgrind.*
test1.out: test1.in
-rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize
@@ -0,0 +1,10 @@
|1+0#ffffff16#e000002@2| +0#0000000#ffffff0|2@2| |3@2| @63
>4+0#ffffff16#e000002@2| +0#0000000#ffffff0|5@2| |6+0&#ffff4012@2| +0&#ffffff0@63
|~+0#4040ff13&| @7|╔+0#0000001#ffd7ff255|═@10|╗| +0#4040ff13#ffffff0@52
|~| @7|║+0#0000001#ffd7ff255|1+0#ffffff16#e000002@2| +0#0000001#ffd7ff255|2@2| |3@2|║| +0#4040ff13#ffffff0@52
|~| @7|║+0#0000001#ffd7ff255|4@2| |5+0#ffffff16#e000002@2| +0#0000001#ffd7ff255|6@2|║| +0#4040ff13#ffffff0@52
|~| @7|╚+0#0000001#ffd7ff255|═@10|╝| +0#4040ff13#ffffff0@52
|~| @73
|~| @73
|~| @73
| +0#0000000&@56|2|,|1| @10|A|l@1|
Binary file not shown.
+34
View File
@@ -47,3 +47,37 @@ func Test_expand_tilde_filename()
call assert_match('\~', expand('%:p'))
bwipe!
endfunc
func Test_expandcmd()
let $FOO = 'Test'
call assert_equal('e x/Test/y', expandcmd('e x/$FOO/y'))
unlet $FOO
new
edit Xfile1
call assert_equal('e Xfile1', expandcmd('e %'))
edit Xfile2
edit Xfile1
call assert_equal('e Xfile2', expandcmd('e #'))
edit Xfile2
edit Xfile3
edit Xfile4
let bnum = bufnr('Xfile2')
call assert_equal('e Xfile2', expandcmd('e #' . bnum))
call setline('.', 'Vim!@#')
call assert_equal('e Vim', expandcmd('e <cword>'))
call assert_equal('e Vim!@#', expandcmd('e <cWORD>'))
enew!
edit Xfile.java
call assert_equal('e Xfile.py', expandcmd('e %:r.py'))
call assert_equal('make abc.java', expandcmd('make abc.%:e'))
call assert_equal('make Xabc.java', expandcmd('make %:s?file?abc?'))
edit a1a2a3.rb
call assert_equal('make b1b2b3.rb a1a2a3 Xfile.o', expandcmd('make %:gs?a?b? %< #<.o'))
call assert_fails('call expandcmd("make <afile>")', 'E495:')
call assert_fails('call expandcmd("make <afile>")', 'E495:')
enew
call assert_fails('call expandcmd("make %")', 'E499:')
close
endfunc
+26
View File
@@ -188,6 +188,32 @@ func Test_popup_with_syntax_setbufvar()
call delete('XtestPopup')
endfunc
func Test_popup_with_matches()
if !CanRunVimInTerminal()
throw 'Skipped: cannot make screendumps'
endif
let lines =<< trim END
call setline(1, ['111 222 333', '444 555 666'])
let winid = popup_create([
\ '111 222 333',
\ '444 555 666',
\], {'line': 3, 'col': 10, 'border': []})
set hlsearch
/666
call matchadd('ErrorMsg', '111')
call matchadd('ErrorMsg', '444')
call win_execute(winid, "call matchadd('ErrorMsg', '111')")
call win_execute(winid, "call matchadd('ErrorMsg', '555')")
END
call writefile(lines, 'XtestPopupMatches')
let buf = RunVimInTerminal('-S XtestPopupMatches', {'rows': 10})
call VerifyScreenDump(buf, 'Test_popupwin_matches', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopupMatches')
endfunc
func Test_popup_all_corners()
if !CanRunVimInTerminal()
throw 'Skipped: cannot make screendumps'
+47
View File
@@ -0,0 +1,47 @@
" Tests for the sound feature
if !has('sound')
throw 'Skipped: sound feature not available'
endif
func PlayCallback(id, result)
let g:id = a:id
let g:result = a:result
endfunc
func Test_play_event()
let id = sound_playevent('bell', 'PlayCallback')
if id == 0
throw 'Skipped: bell event not available'
endif
" Stop it quickly, avoid annoying the user.
sleep 20m
call sound_stop(id)
sleep 20m
call assert_equal(id, g:id)
call assert_equal(1, g:result) " sound was aborted
endfunc
func Test_play_silent()
let fname = fnamemodify('silent.wav', '%p')
" play without callback
let id1 = sound_playfile(fname)
if id1 == 0
throw 'Skipped: playing a sound is not working'
endif
" play until the end
let id2 = sound_playfile(fname, 'PlayCallback')
call assert_true(id2 > 0)
sleep 500m
call assert_equal(id2, g:id)
call assert_equal(0, g:result)
let id2 = sound_playfile(fname, 'PlayCallback')
call assert_true(id2 > 0)
sleep 20m
call sound_stopall()
call assert_equal(id2, g:id)
call assert_equal(1, g:result)
endfunc
+32
View File
@@ -590,6 +590,16 @@ static char *(features[]) =
#else
"-smartindent",
#endif
#ifdef FEAT_SOUND
"+sound",
#else
"-sound",
#endif
#ifdef FEAT_SPELL
"+spell",
#else
"-spell",
#endif
#ifdef STARTUPTIME
"+startuptime",
#else
@@ -782,6 +792,28 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1512,
/**/
1511,
/**/
1510,
/**/
1509,
/**/
1508,
/**/
1507,
/**/
1506,
/**/
1505,
/**/
1504,
/**/
1503,
/**/
1502,
/**/
1501,
/**/