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/testdir/runtest.vim b/runtime/syntax/testdir/runtest.vim
index f9c0db0..0758bcb 100644
--- a/runtime/syntax/testdir/runtest.vim
+++ b/runtime/syntax/testdir/runtest.vim
@@ -115,13 +115,26 @@
   " Create a map of setup configuration filenames with their basenames as keys.
   let setup = glob('input/setup/*.vim', 1, 1)
     \ ->reduce({d, f -> extend(d, {fnamemodify(f, ':t:r'): f})}, {})
+  " Turn a subset of filenames etc. requested for testing into a pattern.
+  let filter = filereadable('../testdir/Xfilter')
+    \ ? readfile('../testdir/Xfilter')
+	\ ->map({_, v -> (v =~ '\.' ? '^' : '\.') .. v .. '$'})
+	\ ->join('\|')
+    \ : ''
 
-  if exists("$VIM_SYNTAX_SELF_TESTING")
+  " Treat "\.self-testing$" as a string NOT as a regexp.
+  if filter ==# '\.self-testing$'
     let dirpath = 'input/selftestdir/'
     let fnames = readdir(dirpath, {fname -> fname !~ '^README\.txt$'})
   else
     let dirpath = 'input/'
-    let fnames = readdir(dirpath, {fname -> fname !~ '\~$' && fname =~ '^.\+\..\+$'})
+    let filter ..= exists("$VIM_SYNTAX_TEST_FILTER") &&
+		\ !empty($VIM_SYNTAX_TEST_FILTER)
+      \ ? (empty(filter) ? '' : '\|') .. $VIM_SYNTAX_TEST_FILTER
+      \ : ''
+    let fnames = readdir(dirpath,
+	\ {subset -> {fname -> fname !~ '\~$' && fname =~# subset}}(
+		\ empty(filter) ? '^.\+\..\+$' : filter))
   endif
 
   for fname in fnames