On 2020-06-02, Bram Moolenaar wrote:
> Gary Johnson wrote:
> 
> > > > > Would be nice to point to what's wrong.  Ah, I see that an
> > > > > Xfunctions.diff file is generated.  Hmm, but "diff" might not be
> > > > > available.
> > > > 
> > > > Yeah, but I don't know what to do about that.  I suppose I could
> > > > save the lists to Lists instead of files and do a rudimentary diff
> > > > of two Lists.  (Having Unix tools makes life so much easier.)
> > > 
> > > We probably should make assert_equalfile() better.  Show the context of
> > > where the difference was found.  However, in this case the question is
> > > also where the list comes from, that could be added as a third argument.
> > 
> > You have a better idea of the style you'd like than I do, but I can
> > take a stab at that if you'd like.
> > 
> > By a third argument for where the list comes from, do you mean an
> > optional {msg} argument as used by other assert_*() functions?
> 
> Yes, mentioning what is being compared already helps a bit.
> 
> > > > > The sorting should be done without ignoring case?  At least for a 
> > > > > binary
> > > > > search it should.
> > > > 
> > > > The type of sorting seems to differ between lists.  The
> > > > global_functions in evalfunc.c seems to be sorted in ASCII or "C"
> > > > order, which makes sense for source code, while the ":help
> > > > functions" in eval.txt seems to be sorted in dictionary order, i.e.,
> > > > ignoring case, which is reasonable for documentation.  I guess the
> > > > latter depends on the expectations of the reader.  I tried to follow
> > > > what was already there, although that was inconsistent.  I don't
> > > > personally have a preference.
> > > 
> > > In case of doubt I would prefer to do what ":sort" without arguments
> > > ends up with.  It's just easier to maintain that way.
> > 
> > I'll fix that in the source and in the test.
> 
> I removed the "i" argument from the sort command and it only found two
> places that needed adjustment.

A complete patch is attached.  This patch includes:

-  a sorted list of functions for ":help functions";
-  addition of functions missing from ":help function-list";
-  a new test for checking that lists remain complete and sorted;
-  fixes to a few misspellings.

The new test uses the new msg argument to assert_equalfile() to make
the failure messages a little more clear.  The function lists have
been updated since my earlier patch to include functions added since
then.

An issue with the new test is that if it fails, an external diff
program is required to produce meaningful output files for
debugging.  I looked briefly at writing an internal diff function,
but decided that it was more trouble than it was worth and one more
thing to maintain.  Also, now that the major problems with the lists
have been fixed, the test should fail only for a developer who has
added a new function and that person should know where the problem
lies.

The patch was based on Vim 8.2.895.

Regards,
Gary

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20200603224516.GI10889%40phoenix.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 62a5172b9..7f23d13c1 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2346,7 +2346,6 @@ assert_notmatch({pat}, {text} [, {msg}])
 				Number	assert {pat} not matches {text}
 assert_report({msg})		Number	report a test failure
 assert_true({actual} [, {msg}])	Number	assert {actual} is true
-asin({expr})			Float	arc sine of {expr}
 atan({expr})			Float	arc tangent of {expr}
 atan2({expr1}, {expr2})		Float	arc tangent of {expr1} / {expr2}
 balloon_gettext()		String	current text in the balloon
@@ -2437,12 +2436,12 @@ executable({expr})		Number	1 if executable {expr} exists
 execute({command})		String	execute {command} and get the output
 exepath({expr})			String	full path of the command {expr}
 exists({expr})			Number	|TRUE| if {expr} exists
-extend({expr1}, {expr2} [, {expr3}])
-				List/Dict insert items of {expr2} into {expr1}
 exp({expr})			Float	exponential of {expr}
 expand({expr} [, {nosuf} [, {list}]])
 				any	expand special keywords in {expr}
 expandcmd({expr})		String	expand {expr} like with `:edit`
+extend({expr1}, {expr2} [, {expr3}])
+				List/Dict insert items of {expr2} into {expr1}
 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
@@ -2537,8 +2536,8 @@ histadd({history}, {item})	Number	add an item to a history
 histdel({history} [, {item}])	Number	remove an item from a history
 histget({history} [, {index}])	String	get the item {index} from a history
 histnr({history})		Number	highest index of a history
-hlexists({name})		Number	|TRUE| if highlight group {name} exists
 hlID({name})			Number	syntax ID of highlight group {name}
+hlexists({name})		Number	|TRUE| if highlight group {name} exists
 hostname()			String	name of the machine Vim is running on
 iconv({expr}, {from}, {to})	String	convert encoding of {expr}
 indent({lnum})			Number	indent of line {lnum}
@@ -2638,16 +2637,16 @@ popup_findpreview()		Number	get window ID of preview popup window
 popup_getoptions({id})		Dict	get options of popup window {id}
 popup_getpos({id})		Dict	get position of popup window {id}
 popup_hide({id})		none	hide popup menu {id}
-popup_list()			List	get a list of window IDs of al popups
+popup_list()			List	get a list of window IDs of all popups
 popup_locate({row}, {col})	Number 	get window ID of popup at position
 popup_menu({what}, {options})	Number	create a popup window used as a menu
 popup_move({id}, {options})	none	set position of popup window {id}
 popup_notification({what}, {options})
 				Number	create a notification popup window
-popup_show({id})		none	unhide popup window {id}
 popup_setoptions({id}, {options})
 				none	set options for popup window {id}
 popup_settext({id}, {text})	none	set the text of popup window {id}
+popup_show({id})		none	unhide popup window {id}
 pow({x}, {y})			Float	{x} to the power of {y}
 prevnonblank({lnum})		Number	line nr of non-blank line <= {lnum}
 printf({fmt}, {expr1}...)	String	format text
@@ -2672,8 +2671,8 @@ prop_type_get([{name} [, {props}]])
 prop_type_list([{props}])	List	get list of property types
 pum_getpos()			Dict	position and size of pum if visible
 pumvisible()			Number	whether popup menu is visible
-pyeval({expr})			any	evaluate |Python| expression
 py3eval({expr})			any	evaluate |python3| expression
+pyeval({expr})			any	evaluate |Python| expression
 pyxeval({expr})			any	evaluate |python_x| expression
 rand([{expr}])			Number	get pseudo-random number
 range({expr} [, {max} [, {stride}]])
@@ -2800,9 +2799,9 @@ str2list({expr} [, {utf8}])	List	convert each character of {expr} to
 					ASCII/UTF8 value
 str2nr({expr} [, {base} [, {quoted}]])
 				Number	convert String to Number
-strchars({expr} [, {skipcc}])	Number	character length of the String {expr}
 strcharpart({str}, {start} [, {len}])
 				String	{len} characters of {str} at {start}
+strchars({expr} [, {skipcc}])	Number	character length of the String {expr}
 strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
 strftime({format} [, {time}])	String	format time with a specified format
 strgetchar({str}, {index})	Number	get char {index} from {str}
@@ -2835,8 +2834,8 @@ systemlist({expr} [, {input}])	List	output of shell command/filter {expr}
 tabpagebuflist([{arg}])		List	list of buffer numbers in tab page
 tabpagenr([{arg}])		Number	number of current or last tab page
 tabpagewinnr({tabarg} [, {arg}]) Number	number of current window in tab page
-taglist({expr} [, {filename}])	List	list of tags matching {expr}
 tagfiles()			List	tags files used
+taglist({expr} [, {filename}])	List	list of tags matching {expr}
 tan({expr})			Float	tangent of {expr}
 tanh({expr})			Float	hyperbolic tangent of {expr}
 tempname()			String	name for a temporary file
@@ -2860,9 +2859,9 @@ term_gettty({buf}, [{input}])	String	get the tty name of a terminal
 term_list()			List	get the list of terminal buffers
 term_scrape({buf}, {row})	List	get row of a terminal screen
 term_sendkeys({buf}, {keys})	none	send keystrokes to a terminal
-term_setapi({buf}, {expr})	none	set |terminal-api| function name prefix
 term_setansicolors({buf}, {colors})
 				none	set ANSI palette in GUI color mode
+term_setapi({buf}, {expr})	none	set |terminal-api| function name prefix
 term_setkill({buf}, {how})	none	set signal to stop job in terminal
 term_setrestore({buf}, {command}) none	set command to restore terminal
 term_setsize({buf}, {rows}, {cols})
@@ -2885,16 +2884,16 @@ test_null_job()			Job	null value for testing
 test_null_list()		List	null value for testing
 test_null_partial()		Funcref	null value for testing
 test_null_string()		String	null value for testing
-test_unknown()			any	unknown value for testing
-test_void()			any	void value for testing
 test_option_not_set({name})	none	reset flag indicating option was set
 test_override({expr}, {val})	none	test with Vim internal overrides
 test_refcount({expr})		Number	get the reference count of {expr}
 test_scrollbar({which}, {value}, {dragging})
 				none	scroll in the GUI for testing
 test_setmouse({row}, {col})	none	set the mouse position for testing
-test_srand_seed([seed])		none	set seed for testing srand()
 test_settime({expr})		none	set current time for testing
+test_srand_seed([seed])		none	set seed for testing srand()
+test_unknown()			any	unknown value for testing
+test_void()			any	void value for testing
 timer_info([{id}])		List	information about timers
 timer_pause({id}, {pause})	none	pause or unpause a timer
 timer_start({time}, {callback} [, {options}])
@@ -4397,7 +4396,7 @@ feedkeys({string} [, {mode}])				*feedkeys()*
 			script continues.
 			Note that if you manage to call feedkeys() while
 			executing commands, thus calling it recursively, then
-			all typehead will be consumed by the last call.
+			all typeahead will be consumed by the last call.
 		'!'	When used with 'x' will not end Insert mode. Can be
 			used in a test when a timer is set to exit Insert mode
 			a little later.  Useful for testing CursorHoldI.
@@ -4433,7 +4432,7 @@ filewritable({file})					*filewritable()*
 		directory, and we can write to it, the result is 2.
 
 		Can also be used as a |method|: >
-			GetName()->filewriteable()
+			GetName()->filewritable()
 
 
 filter({expr1}, {expr2})				*filter()*
@@ -5434,7 +5433,7 @@ getmousepos()						*getmousepos()*
 		"screenrow" and "screencol" are valid, the others are zero.
 
 		When on the status line below a window or the vertical
-		separater right of a window, the "line" and "column" values
+		separator right of a window, the "line" and "column" values
 		are zero.
 
 		When the position is after the text then "column" is the
@@ -6950,7 +6949,7 @@ mapset({mode}, {abbr}, {dict})				*mapset()*
 			call mapset('n', 0, save_map)
 <		Note that if you are going to replace a map in several modes,
 		e.g. with `:map!`, you need to save the mapping for all of
-		them, since they can differe.
+		them, since they can differ.
 
 
 match({expr}, {pat} [, {start} [, {count}]])			*match()*
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 0793a04ea..6401dc600 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -644,6 +644,7 @@ List manipulation:					*list-functions*
 	min()			minimum value in a List
 	count()			count number of times a value appears in a List
 	repeat()		repeat a List multiple times
+	reduce()		reduce a List or Blob to a single value
 
 Dictionary manipulation:				*dict-functions*
 	get()			get an entry without an error for a wrong key
@@ -687,6 +688,7 @@ Floating point computation:				*float-functions*
 	sinh()			hyperbolic sine
 	cosh()			hyperbolic cosine
 	tanh()			hyperbolic tangent
+	isinf()			check for infinity
 	isnan()			check for not a number
 
 Other computation:					*bitwise-function*
@@ -695,6 +697,8 @@ Other computation:					*bitwise-function*
 	or()			bitwise OR
 	xor()			bitwise XOR
 	sha256()		SHA-256 hash
+	rand()			get a pseudo-random number
+	srand()			initialize seed used by rand()
 
 Variables:						*var-functions*
 	type()			type of a variable
@@ -828,9 +832,11 @@ Buffers, windows and the argument list:
 	listener_remove()	remove a listener callback
 	win_findbuf()		find windows containing a buffer
 	win_getid()		get window ID of a window
+	win_gettype()		get type of window
 	win_gotoid()		go to window with ID
 	win_id2tabwin()		get tab and window nr from window ID
 	win_id2win()		get window nr from window ID
+	win_splitmove()		move window to a split of another window
 	getbufinfo()		get a list with buffer information
 	gettabinfo()		get a list with tab page information
 	getwininfo()		get a list with window information
@@ -907,6 +913,7 @@ Interactive:					*interactive-functions*
 	getchar()		get a character from the user
 	getcharmod()		get modifiers for the last typed character
 	getmousepos()		get last known mouse position
+	echoraw()		output characters as-is
 	feedkeys()		put characters in the typeahead queue
 	input()			get a line from the user
 	inputlist()		let the user pick an entry from a list
@@ -948,6 +955,7 @@ Mappings and Menus:			    *mapping-functions*
 	hasmapto()		check if a mapping exists
 	mapcheck()		check if a matching mapping exists
 	maparg()		get rhs of a mapping
+	mapset()		restore a mapping
 	menu_info()		get information about a menu item
 	wildmenumode()		check if the wildmode is active
 
@@ -968,11 +976,13 @@ Testing:				    *test-functions*
 	test_autochdir()	enable 'autochdir' during startup
 	test_override()		test with Vim internal overrides
 	test_garbagecollect_now()   free memory right now
+	test_garbagecollect_soon()  set a flag to free memory soon
 	test_getvalue()		get value of an internal variable
 	test_ignore_error()	ignore a specific error message
 	test_null_blob()	return a null Blob
 	test_null_channel()	return a null Channel
 	test_null_dict()	return a null Dict
+	test_null_function()	return a null Funcref
 	test_null_job()		return a null Job
 	test_null_list()	return a null List
 	test_null_partial()	return a null Partial function
@@ -982,6 +992,10 @@ Testing:				    *test-functions*
 	test_feedinput()	add key sequence to input buffer
 	test_option_not_set()	reset flag indicating option was set
 	test_scrollbar()	simulate scrollbar movement in the GUI
+	test_refcount()		return an expression's reference count
+	test_srand_seed()	set the seed value for srand()
+	test_unknown()		return a value with unknown type
+	test_void()		return a value with void type
 
 Inter-process communication:		    *channel-functions*
 	ch_canread()		check if there is something to read
@@ -993,8 +1007,8 @@ Inter-process communication:		    *channel-functions*
 	ch_readraw()		read a raw message from a channel
 	ch_sendexpr()		send a JSON message over a channel
 	ch_sendraw()		send a raw message over a channel
-	ch_evalexpr()		evaluates an expression over channel
-	ch_evalraw()		evaluates a raw string over channel
+	ch_evalexpr()		evaluate an expression over channel
+	ch_evalraw()		evaluate a raw string over channel
 	ch_status()		get status of a channel
 	ch_getbufnr()		get the buffer number of a channel
 	ch_getjob()		get the job associated with a channel
@@ -1007,7 +1021,7 @@ Inter-process communication:		    *channel-functions*
 	js_encode()		encode an expression to a JSON string
 	js_decode()		decode a JSON string to Vim types
 
-Jobs:		    			        *job-functions*
+Jobs:						*job-functions*
 	job_start()		start a job
 	job_stop()		stop a job
 	job_status()		get the status of a job
@@ -1050,6 +1064,7 @@ Terminal window:				*terminal-functions*
 	term_setkill()		set signal to stop job in a terminal
 	term_setrestore()	set command to restore a terminal
 	term_setsize()		set the size of a terminal
+	term_setapi()		set terminal JSON API function name prefix
 
 Popup window:					*popup-window-functions*
 	popup_create()		create popup centered in the screen
@@ -1068,9 +1083,13 @@ Popup window:					*popup-window-functions*
 	popup_close()		close one popup
 	popup_clear()		close all popups
 	popup_filter_menu()	select from a list of items
-	popup_filter_yesno()	blocks until 'y' or 'n' is pressed
+	popup_filter_yesno()	block until 'y' or 'n' is pressed
 	popup_getoptions()	get current options for a popup
 	popup_getpos()		get actual position and size of a popup
+	popup_findinfo()	get window ID for popup info window
+	popup_findpreview()	get window ID for popup preview window
+	popup_list()		get list of all popup window IDs
+	popup_locate()		get popup window ID from its screen position
 
 Timers:						*timer-functions*
 	timer_start()		create a timer
@@ -1090,8 +1109,27 @@ Prompt Buffer:					*promptbuffer-functions*
 	prompt_setinterrupt()	set interrupt callback for a buffer
 	prompt_setprompt()	set the prompt text for a buffer
 
+Text Properties:				*text-property-functions*
+	prop_add()		attach a property at a position
+	prop_clear()		remove all properties from a line or lines
+	prop_find()		search for a property
+	prop_list()		return a list of all properties in a line
+	prop_remove()		remove a property from a line
+	prop_type_add()		add/define a property type
+	prop_type_change()	change properties of a type
+	prop_type_delete()	remove a text property type
+	prop_type_get()		return the properties of a type
+	prop_type_list()	return a list of all property types
+
+Sound:							*sound-functions*
+	sound_clear()		stop playing all sounds
+	sound_playevent()	play an event's sound
+	sound_playfile()	play a sound file
+	sound_stop()		stop playing a sound
+
 Various:					*various-functions*
 	mode()			get current editing mode
+	state()			get current busy state
 	visualmode()		last visual mode used
 	exists()		check if a variable, function, etc. exists
 	has()			check if a feature is supported in Vim
@@ -1100,6 +1138,9 @@ Various:					*various-functions*
 	did_filetype()		check if a FileType autocommand was used
 	eventhandler()		check if invoked by an event handler
 	getpid()		get process ID of Vim
+	getimstatus()		check if IME status is active
+	interrupt()		interrupt script execution
+	windowsversion()	get MS-Windows version
 
 	libcall()		call a function in an external library
 	libcallnr()		idem, returning a number
@@ -1115,14 +1156,17 @@ Various:					*various-functions*
 
 	shiftwidth()		effective value of 'shiftwidth'
 
+	searchcount()		get or update last search count
 	wordcount()		get byte/word/char count of buffer
 
-	luaeval()		evaluate Lua expression
+	luaeval()		evaluate |Lua| expression
 	mzeval()		evaluate |MzScheme| expression
 	perleval()		evaluate Perl expression (|+perl|)
 	py3eval()		evaluate Python expression (|+python3|)
 	pyeval()		evaluate Python expression (|+python|)
 	pyxeval()		evaluate |python_x| expression
+	rubyeval()		evaluate |Ruby| expression
+
 	debugbreak()		interrupt a program being debugged
 
 ==============================================================================
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 7fad24b78..6b151d07c 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -139,6 +139,7 @@ NEW_TESTS = \
 	test_fnamemodify \
 	test_fold \
 	test_functions \
+	test_function_lists \
 	test_ga \
 	test_getcwd \
 	test_getvar \
@@ -374,6 +375,7 @@ NEW_TESTS_RES = \
 	test_fnameescape.res \
 	test_fold.res \
 	test_functions.res \
+	test_function_lists.res \
 	test_getcwd.res \
 	test_getvar.res \
 	test_gf.res \
diff --git a/src/testdir/test_function_lists.vim b/src/testdir/test_function_lists.vim
new file mode 100644
index 000000000..609b9bff3
--- /dev/null
+++ b/src/testdir/test_function_lists.vim
@@ -0,0 +1,105 @@
+" Test to verify that the three function lists,
+"
+"   global_functions[] in src/evalfunc.c
+"   *functions* in runtime/doc/eval.txt
+"   *function-list* in runtime/doc/usr_41.txt
+"
+" contain the same functions and that the global_functions and ":help
+" functions" lists are in ASCII order.
+
+func Test_function_lists()
+
+  " Delete any files left over from an earlier run of this test.
+
+  call delete("Xglobal_functions.diff")
+  call delete("Xfunctions.diff")
+  call delete("Xfunction-list.diff")
+
+  " Create a file of the functions in evalfunc.c:global_functions[].
+
+  enew!
+  read ../evalfunc.c
+  1,/^static funcentry_T global_functions\[\] =$/d
+  call search('^};$')
+  .,$d
+  v/^    {/d
+  %s/^    {"//
+  %s/".*//
+  w! Xglobal_functions
+
+  " Verify that those functions are in ASCII order.
+
+  sort u
+  w! Xsorted_global_functions
+  let l:unequal = assert_equalfile("Xsorted_global_functions", "Xglobal_functions",
+      \ "global_functions[] not sorted")
+  if l:unequal && executable("diff")
+    call system("diff -u Xsorted_global_functions Xglobal_functions > Xglobal_functions.diff")
+  endif
+
+  " Create a file of the functions in evalfunc.c:global_functions[] that are
+  " not obsolete, sorted in ASCII order.
+
+  enew!
+  read ../evalfunc.c
+  1,/^static funcentry_T global_functions\[\] =$/d
+  call search('^};$')
+  .,$d
+  v/^    {/d
+  g/\/\/ obsolete$/d
+  %s/^    {"//
+  %s/".*//
+  sort u
+  w! Xsorted_current_global_functions
+
+  " Verify that the ":help functions" list is complete and in ASCII order.
+
+  enew!
+  read ../../runtime/doc/eval.txt
+  call search('\*functions\*$')
+  call search('^USAGE')
+  1,.d
+  call search('\*\K\k*()\*$')
+  .,$d
+  v/^\S/d
+  %s/(.*//
+  let l:lines = getline(1, '$')
+  call uniq(l:lines)
+  call writefile(l:lines, "Xfunctions")
+  let l:unequal = assert_equalfile("Xsorted_current_global_functions", "Xfunctions",
+      \ "\":help functions\" not sorted or incomplete")
+  if l:unequal && executable("diff")
+    call system("diff -u Xsorted_current_global_functions Xfunctions > Xfunctions.diff")
+  endif
+
+  " Verify that the ":help function-list" list is complete.
+
+  enew!
+  read ../../runtime/doc/usr_41.txt
+  call search('\*function-list\*$')
+  1,.d
+  call search('^==*$')
+  .,$d
+  v/^\t\S/d
+  %s/(.*//
+  %left
+  sort u
+  w! Xfunction-list
+  let l:unequal = assert_equalfile("Xsorted_current_global_functions", "Xfunction-list",
+      \ "\":help functions-list\" incomplete")
+  if l:unequal && executable("diff")
+    call system("diff -u Xsorted_current_global_functions Xfunction-list > Xfunction-list.diff")
+  endif
+
+  " Clean up.
+
+  call delete("Xglobal_functions")
+  call delete("Xsorted_global_functions")
+  call delete("Xsorted_current_global_functions")
+  call delete("Xfunctions")
+  call delete("Xfunction-list")
+  enew!
+
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab

Raspunde prin e-mail lui