patch 9.1.0763: tests: cannot run single syntax tests

Problem:  tests: cannot run single syntax tests
Solution: Support running a subset of syntax tests
          (Aliaksei Budavei)

Two methods of assembling a subset of test filenames for
selection are provided:

* Filename and filetype Make targets will be generated, and
  multiple such targets can be passed before the mandated
  trailing "test" target, e.g. "make html markdown test".

* Filenames and their parts can be specified as a regular
  expression that is assigned to a "VIM_SYNTAX_TEST_FILTER"
  environment variable, and used with the test Make target,
  e.g. "VIM_SYNTAX_TEST_FILTER=html\\\|markdown make test".
  (This variable will be ignored and the whole suite will be
  run when Make is GNU Make and a parent Makefile is used.)

Methods can be used alone or together, with the Make targets
having the higher precedence. Neither method will influence
the order of test execution.

closes: #15670

Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/syntax/Makefile b/runtime/syntax/Makefile
index bc6de0b..cbea54a 100644
--- a/runtime/syntax/Makefile
+++ b/runtime/syntax/Makefile
@@ -31,10 +31,38 @@
 	@echo "../$(VIMPROG)" > testdir/vimcmd
 	@echo "$(RUN_VIMTEST)" >> testdir/vimcmd
 	VIMRUNTIME=$(VIMRUNTIME) $(ENVVARS) $(VIMPROG) --clean --not-a-term $(DEBUGLOG) -u testdir/runtest.vim
+	@rm -f testdir/Xfilter
 	@# FIXME: Temporarily show the whole file to find out what goes wrong
 	@#if [ -f testdir/messages ]; then tail -n 6 testdir/messages; fi
 	@if [ -f testdir/messages ]; then cat testdir/messages; fi
 
 
 clean testclean:
-	rm -f testdir/failed/* testdir/done/* testdir/vimcmd testdir/messages testdir/Xtestscript
+	rm -f testdir/failed/* testdir/done/* testdir/vimcmd testdir/messages testdir/Xtestscript testdir/Xfilter
+
+# All initial phony targets; these names may clash with file extensions.
+phonies = clean test testclean
+
+# Collect all input filenames and their file extensions.
+testnames != set +f; \
+awk 'BEGIN { \
+    for (i = 1; i < ARGC; i++) { \
+        split(ARGV[i], names, /\//); \
+        split(names[3], parts, /\./); \
+        exts[parts[2]]; \
+        print names[3]; \
+    } \
+    split("$(phonies)", scratch); \
+    for (phony in scratch) \
+        phonies[scratch[phony]]; \
+    for (ext in exts) \
+        print ext ((ext in phonies) ? "_" : ""); \
+}' testdir/input/*.*
+
+.PHONY: self-testing $(testnames)
+
+$(testnames)::
+	@echo $@ >> testdir/Xfilter
+
+self-testing:: $(testnames)
+	@echo self-testing > testdir/Xfilter