changeset 18906:bb87c5c1e29b v8.2.0014

patch 8.2.0014: test69 and test95 are old style Commit: https://github.com/vim/vim/commit/afc13bd8271819c7871ff2ae2cfebb22190a0d39 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 16 22:43:31 2019 +0100 patch 8.2.0014: test69 and test95 are old style Problem: Test69 and test95 are old style. Solution: Convert to new style tests. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/5365)
author Bram Moolenaar <Bram@vim.org>
date Mon, 16 Dec 2019 22:45:04 +0100
parents c1b0da0ac838
children 0d1b04508830
files src/Makefile src/testdir/Make_all.mak src/testdir/Make_vms.mms src/testdir/test69.in src/testdir/test69.ok src/testdir/test95.in src/testdir/test95.ok src/testdir/test_regexp_utf8.vim src/testdir/test_textformat.vim src/version.c
diffstat 10 files changed, 568 insertions(+), 622 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile
+++ b/src/Makefile
@@ -2255,10 +2255,9 @@ test1 \
 	test_eval \
 	test42 test44 test49 \
 	test52 test59 \
-	test69 \
 	test70 \
 	test86 test87 \
-	test95 test99:
+	test99:
 	cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
 
 # Run individual NEW style test.
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -15,9 +15,7 @@ SCRIPTS_FIRST = \
 SCRIPTS_ALL = \
 	test42.out \
 	test44.out \
-	test69.out \
 	test70.out \
-	test95.out \
 	test99.out \
 	test_eval.out
 
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -75,9 +75,8 @@ VIMPROG = <->vim.exe
 
 SCRIPT = test1.out \
        test42.out test44.out test49.out \
-       test69.out \
        test77a.out \
-       test95.out test99.out \
+       test99.out \
        test_eval.out
 
 # Known problems:
deleted file mode 100644
--- a/src/testdir/test69.in
+++ /dev/null
@@ -1,177 +0,0 @@
-Test for multi-byte text formatting.
-Also test, that 'mps' with multibyte chars works.
-And test "ra" on multi-byte characters.
-Also test byteidx() and byteidxcomp()
-
-STARTTEST
-:so mbyte.vim
-:set encoding=utf-8
-ENDTEST
-
-Results of test69:
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=t
-gqgqjgqgqo
-XYZ
-abc XYZ
-ENDTEST
-
-{
-XYZ
-abc XYZ
-}
-
-STARTTEST
-/^{/+1
-:set tw=1 fo=tm
-gqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-X a
-XY
-X Y
-ENDTEST
-
-{
-X
-Xa
-X a
-XY
-X Y
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=tm
-gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-X a
-XY
-X Y
-aX
-abX
-abcX
-abX c
-abXY
-ENDTEST
-
-{
-X
-Xa
-X a
-XY
-X Y
-aX
-abX
-abcX
-abX c
-abXY
-}
-
-STARTTEST
-/^{/+1
-:set ai tw=2 fo=tm
-gqgqjgqgqo
-X
-Xa
-ENDTEST
-
-{
-  X
-  Xa
-}
-
-STARTTEST
-/^{/+1
-:set noai tw=2 fo=tm
-gqgqjgqgqo
-  X
-  Xa
-ENDTEST
-
-{
-  X
-  Xa
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=cqm comments=n:X
-gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-XaY
-XY
-XYZ
-X Y
-X YZ
-XX
-XXa
-XXY
-ENDTEST
-
-{
-X
-Xa
-XaY
-XY
-XYZ
-X Y
-X YZ
-XX
-XXa
-XXY
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=tm
-RXa
-ENDTEST
-
-{
-
-}
-
-STARTTEST
-/^{/+1
-:set mps+=u2018:u2019
-d%
-ENDTEST
-
-{
-‘ two three ’ four
-}
-STARTTEST
-/^ra test
-jVjra
-ENDTEST
-
-ra test
-abba
-aab
-
-STARTTEST
-:set whichwrap+=h
-/^x
-dh
-:set whichwrap-=h
-ENDTEST
-

-x
-
-STARTTEST
-/^substitute
-:let y = substitute('123', '\zs', 'a', 'g')    | put =y
-ENDTEST
-
-substitute
-
-STARTTEST
-:g/^STARTTEST/.,/^ENDTEST/d
-:1;/^Results/,$wq! test.out
-ENDTEST
deleted file mode 100644
--- a/src/testdir/test69.ok
+++ /dev/null
@@ -1,158 +0,0 @@
-Results of test69:
-
-
-{
-XYZ
-abc
-XYZ
-
-XYZ
-abc
-XYZ
-}
-
-
-{
-X
-X
-a
-X
-a
-X
-Y
-X
-Y
-
-X
-X
-a
-X
-a
-X
-Y
-X
-Y
-}
-
-
-{
-X
-X
-a
-X
-a
-X
-Y
-X
-Y
-a
-X
-ab
-X
-abc
-X
-ab
-X
-c
-ab
-X
-Y
-
-X
-X
-a
-X
-a
-X
-Y
-X
-Y
-a
-X
-ab
-X
-abc
-X
-ab
-X
-c
-ab
-X
-Y
-}
-
-
-{
-  X
-  X
-  a
-
-  X
-  X
-  a
-}
-
-
-{
-  X
-  X
-a
-
-  X
-  X
-a
-}
-
-
-{
-X
-Xa
-Xa
-XY
-XY
-XY
-XZ
-X Y
-X Y
-X Z
-XX
-XXa
-XXY
-
-X
-Xa
-Xa
-XY
-XY
-XY
-XZ
-X Y
-X Y
-X Z
-XX
-XXa
-XXY
-}
-
-
-{
-X
-a
-}
-
-
-{
- four
-}
-
-ra test
-aaaa
-aaa
-
-
-áx
-
-
-substitute
-a1a2a3a
-
deleted file mode 100644
--- a/src/testdir/test95.in
+++ /dev/null
@@ -1,141 +0,0 @@
-Test for regexp patterns with multi-byte support, using utf-8.
-See test_regexp_latin.vim for the non-multi-byte tests.
-
-A pattern that gives the expected result produces OK, so that we know it was
-actually tried.
-
-STARTTEST
-:so small.vim
-:so mbyte.vim
-:set nocp encoding=utf-8 viminfo+=nviminfo nomore
-:" tl is a List of Lists with:
-:"    2: test auto/old/new  0: test auto/old  1: test auto/new
-:"    regexp pattern
-:"    text to test the pattern on
-:"    expected match (optional)
-:"    expected submatch 1 (optional)
-:"    expected submatch 2 (optional)
-:"    etc.
-:"  When there is no match use only the first two items.
-:let tl = []
-:
-:"""" Multi-byte character tests. These will fail unless vim is compiled
-:"""" with Multibyte (FEAT_MBYTE) or BIG/HUGE features.
-:call add(tl, [2, '[[:alpha:][=a=]]\+', '879 aiaãâaiuvna ', 'aiaãâaiuvna'])
-:call add(tl, [2, '[[=a=]]\+', 'ddaãâbcd', 'aãâ'])								" equivalence classes
-:call add(tl, [2, '[^ม ]\+', 'มม oijasoifjos ifjoisj f osij j มมมมม abcd', 'oijasoifjos'])
-:call add(tl, [2, ' [^ ]\+', 'start มabcdม ', ' มabcdม'])
-:call add(tl, [2, '[ม[:alpha:][=a=]]\+', '879 aiaãมâมaiuvna ', 'aiaãมâมaiuvna'])
-:
-:" this is not a normal "i" but 0xec
-:call add(tl, [2, '\p\+', 'ìa', 'ìa'])
-:call add(tl, [2, '\p*', 'aあ', 'aあ'])
-:
-:"""" Test recognition of some character classes
-:call add(tl, [2, '\i\+', '&*¨xx ', 'xx'])
-:call add(tl, [2, '\f\+', '&*Ÿfname ', 'fname'])
-:
-:"""" Test composing character matching
-:call add(tl, [2, '.ม', 'xม่x yมy', 'yม'])
-:call add(tl, [2, '.ม่', 'xม่x yมy', 'xม่'])
-:call add(tl, [2, "\u05b9", " x\u05b9 ", "x\u05b9"])
-:call add(tl, [2, ".\u05b9", " x\u05b9 ", "x\u05b9"])
-:call add(tl, [2, "\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
-:call add(tl, [2, ".\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
-:call add(tl, [2, "\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
-:call add(tl, [2, ".\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
-:call add(tl, [2, "\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"])
-:call add(tl, [2, ".\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"])
-:call add(tl, [2, "\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"])
-:call add(tl, [2, ".\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"])
-:call add(tl, [1, "\u05b9\u05bb", " y\u05b9 x\u05b9\u05bb ", "x\u05b9\u05bb"])
-:call add(tl, [2, ".\u05b9\u05bb", " y\u05bb x\u05b9\u05bb ", "x\u05b9\u05bb"])
-:call add(tl, [2, "a", "ca\u0300t"])
-:call add(tl, [2, "ca", "ca\u0300t"])
-:call add(tl, [2, "a\u0300", "ca\u0300t", "a\u0300"])
-:call add(tl, [2, 'a\%C', "ca\u0300t", "a\u0300"])
-:call add(tl, [2, 'ca\%C', "ca\u0300t", "ca\u0300"])
-:call add(tl, [2, 'ca\%Ct', "ca\u0300t", "ca\u0300t"])
-:
-:
-:"""" Test \Z
-:call add(tl, [2, 'ú\Z', 'x'])
-:call add(tl, [2, 'יהוה\Z', 'יהוה', 'יהוה'])
-:call add(tl, [2, 'יְהוָה\Z', 'יהוה', 'יהוה'])
-:call add(tl, [2, 'יהוה\Z', 'יְהוָה', 'יְהוָה'])
-:call add(tl, [2, 'יְהוָה\Z', 'יְהוָה', 'יְהוָה'])
-:call add(tl, [2, 'יְ\Z', 'וְיַ', 'יַ'])
-:call add(tl, [2, "ק\u200d\u05b9x\\Z", "xק\u200d\u05b9xy", "ק\u200d\u05b9x"])
-:call add(tl, [2, "ק\u200d\u05b9x\\Z", "xק\u200dxy", "ק\u200dx"])
-:call add(tl, [2, "ק\u200dx\\Z", "xק\u200d\u05b9xy", "ק\u200d\u05b9x"])
-:call add(tl, [2, "ק\u200dx\\Z", "xק\u200dxy", "ק\u200dx"])
-:call add(tl, [2, "\u05b9\\Z", "xyz"])
-:call add(tl, [2, "\\Z\u05b9", "xyz"])
-:call add(tl, [2, "\u05b9\\Z", "xy\u05b9z", "y\u05b9"])
-:call add(tl, [2, "\\Z\u05b9", "xy\u05b9z", "y\u05b9"])
-:call add(tl, [1, "\u05b9\\+\\Z", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"])
-:call add(tl, [1, "\\Z\u05b9\\+", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"])
-:
-:"""" Combining different tests and features
-:call add(tl, [2, '[^[=a=]]\+', 'ddaãâbcd', 'dd'])
-:
-:"""" Run the tests
-:
-:"
-:for t in tl
-:  let re = t[0]
-:  let pat = t[1]
-:  let text = t[2]
-:  let matchidx = 3
-:  for engine in [0, 1, 2]
-:    if engine == 2 && re == 0 || engine == 1 && re == 1
-:      continue
-:    endif
-:    let &regexpengine = engine
-:    try
-:      let l = matchlist(text, pat)
-:    catch
-:      $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"'
-:    endtry
-:" check the match itself
-:    if len(l) == 0 && len(t) > matchidx
-:      $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"'
-:    elseif len(l) > 0 && len(t) == matchidx
-:      $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match'
-:    elseif len(t) > matchidx && l[0] != t[matchidx]
-:      $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"'
-:    else
-:      $put ='OK ' . engine . ' - ' . pat
-:    endif
-:    if len(l) > 0
-:"   check all the nine submatches
-:      for i in range(1, 9)
-:        if len(t) <= matchidx + i
-:          let e = ''
-:        else
-:          let e = t[matchidx + i]
-:        endif
-:        if l[i] != e
-:          $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
-:        endif
-:      endfor
-:      unlet i
-:    endif
-:  endfor
-:endfor
-:unlet t tl e l
-:
-:" check that 'ambiwidth' does not change the meaning of \p
-:set regexpengine=1 ambiwidth=single
-:$put ='eng 1 ambi single: ' . match(\"\u00EC\", '\p')
-:set regexpengine=1 ambiwidth=double
-:$put ='eng 1 ambi double: ' . match(\"\u00EC\", '\p')
-:set regexpengine=2 ambiwidth=single
-:$put ='eng 2 ambi single: ' . match(\"\u00EC\", '\p')
-:set regexpengine=2 ambiwidth=double
-:$put ='eng 2 ambi double: ' . match(\"\u00EC\", '\p')
-:
-:/\%#=1^Results/,$wq! test.out
-ENDTEST
-
-Results of test95:
deleted file mode 100644
--- a/src/testdir/test95.ok
+++ /dev/null
@@ -1,140 +0,0 @@
-Results of test95:
-OK 0 - [[:alpha:][=a=]]\+
-OK 1 - [[:alpha:][=a=]]\+
-OK 2 - [[:alpha:][=a=]]\+
-OK 0 - [[=a=]]\+
-OK 1 - [[=a=]]\+
-OK 2 - [[=a=]]\+
-OK 0 - [^ม ]\+
-OK 1 - [^ม ]\+
-OK 2 - [^ม ]\+
-OK 0 -  [^ ]\+
-OK 1 -  [^ ]\+
-OK 2 -  [^ ]\+
-OK 0 - [ม[:alpha:][=a=]]\+
-OK 1 - [ม[:alpha:][=a=]]\+
-OK 2 - [ม[:alpha:][=a=]]\+
-OK 0 - \p\+
-OK 1 - \p\+
-OK 2 - \p\+
-OK 0 - \p*
-OK 1 - \p*
-OK 2 - \p*
-OK 0 - \i\+
-OK 1 - \i\+
-OK 2 - \i\+
-OK 0 - \f\+
-OK 1 - \f\+
-OK 2 - \f\+
-OK 0 - .ม
-OK 1 - .ม
-OK 2 - .ม
-OK 0 - .ม่
-OK 1 - .ม่
-OK 2 - .ม่
-OK 0 - ֹ
-OK 1 - ֹ
-OK 2 - ֹ
-OK 0 - .ֹ
-OK 1 - .ֹ
-OK 2 - .ֹ
-OK 0 - ֹֻ
-OK 1 - ֹֻ
-OK 2 - ֹֻ
-OK 0 - .ֹֻ
-OK 1 - .ֹֻ
-OK 2 - .ֹֻ
-OK 0 - ֹֻ
-OK 1 - ֹֻ
-OK 2 - ֹֻ
-OK 0 - .ֹֻ
-OK 1 - .ֹֻ
-OK 2 - .ֹֻ
-OK 0 - ֹ
-OK 1 - ֹ
-OK 2 - ֹ
-OK 0 - .ֹ
-OK 1 - .ֹ
-OK 2 - .ֹ
-OK 0 - ֹ
-OK 1 - ֹ
-OK 2 - ֹ
-OK 0 - .ֹ
-OK 1 - .ֹ
-OK 2 - .ֹ
-OK 0 - ֹֻ
-OK 2 - ֹֻ
-OK 0 - .ֹֻ
-OK 1 - .ֹֻ
-OK 2 - .ֹֻ
-OK 0 - a
-OK 1 - a
-OK 2 - a
-OK 0 - ca
-OK 1 - ca
-OK 2 - ca
-OK 0 - à
-OK 1 - à
-OK 2 - à
-OK 0 - a\%C
-OK 1 - a\%C
-OK 2 - a\%C
-OK 0 - ca\%C
-OK 1 - ca\%C
-OK 2 - ca\%C
-OK 0 - ca\%Ct
-OK 1 - ca\%Ct
-OK 2 - ca\%Ct
-OK 0 - ú\Z
-OK 1 - ú\Z
-OK 2 - ú\Z
-OK 0 - יהוה\Z
-OK 1 - יהוה\Z
-OK 2 - יהוה\Z
-OK 0 - יְהוָה\Z
-OK 1 - יְהוָה\Z
-OK 2 - יְהוָה\Z
-OK 0 - יהוה\Z
-OK 1 - יהוה\Z
-OK 2 - יהוה\Z
-OK 0 - יְהוָה\Z
-OK 1 - יְהוָה\Z
-OK 2 - יְהוָה\Z
-OK 0 - יְ\Z
-OK 1 - יְ\Z
-OK 2 - יְ\Z
-OK 0 - ק‍ֹx\Z
-OK 1 - ק‍ֹx\Z
-OK 2 - ק‍ֹx\Z
-OK 0 - ק‍ֹx\Z
-OK 1 - ק‍ֹx\Z
-OK 2 - ק‍ֹx\Z
-OK 0 - ק‍x\Z
-OK 1 - ק‍x\Z
-OK 2 - ק‍x\Z
-OK 0 - ק‍x\Z
-OK 1 - ק‍x\Z
-OK 2 - ק‍x\Z
-OK 0 - ֹ\Z
-OK 1 - ֹ\Z
-OK 2 - ֹ\Z
-OK 0 - \Zֹ
-OK 1 - \Zֹ
-OK 2 - \Zֹ
-OK 0 - ֹ\Z
-OK 1 - ֹ\Z
-OK 2 - ֹ\Z
-OK 0 - \Zֹ
-OK 1 - \Zֹ
-OK 2 - \Zֹ
-OK 0 - ֹ\+\Z
-OK 2 - ֹ\+\Z
-OK 0 - \Zֹ\+
-OK 2 - \Zֹ\+
-OK 0 - [^[=a=]]\+
-OK 1 - [^[=a=]]\+
-OK 2 - [^[=a=]]\+
-eng 1 ambi single: 0
-eng 1 ambi double: 0
-eng 2 ambi single: 0
-eng 2 ambi double: 0
--- a/src/testdir/test_regexp_utf8.vim
+++ b/src/testdir/test_regexp_utf8.vim
@@ -215,3 +215,144 @@ func Test_optmatch_toolong()
   set re=0
 endfunc
 
+" Test for regexp patterns with multi-byte support, using utf-8.
+func Test_multibyte_chars()
+  " tl is a List of Lists with:
+  "    2: test auto/old/new  0: test auto/old  1: test auto/new
+  "    regexp pattern
+  "    text to test the pattern on
+  "    expected match (optional)
+  "    expected submatch 1 (optional)
+  "    expected submatch 2 (optional)
+  "    etc.
+  "  When there is no match use only the first two items.
+  let tl = []
+
+  " Multi-byte character tests. These will fail unless vim is compiled
+  " with Multibyte (FEAT_MBYTE) or BIG/HUGE features.
+  call add(tl, [2, '[[:alpha:][=a=]]\+', '879 aiaãâaiuvna ', 'aiaãâaiuvna'])
+  call add(tl, [2, '[[=a=]]\+', 'ddaãâbcd', 'aãâ'])								" equivalence classes
+  call add(tl, [2, '[^ม ]\+', 'มม oijasoifjos ifjoisj f osij j มมมมม abcd', 'oijasoifjos'])
+  call add(tl, [2, ' [^ ]\+', 'start มabcdม ', ' มabcdม'])
+  call add(tl, [2, '[ม[:alpha:][=a=]]\+', '879 aiaãมâมaiuvna ', 'aiaãมâมaiuvna'])
+
+  " this is not a normal "i" but 0xec
+  call add(tl, [2, '\p\+', 'ìa', 'ìa'])
+  call add(tl, [2, '\p*', 'aあ', 'aあ'])
+
+  " Test recognition of some character classes
+  call add(tl, [2, '\i\+', '&*¨xx ', 'xx'])
+  call add(tl, [2, '\f\+', '&*Ÿfname ', 'fname'])
+
+  " Test composing character matching
+  call add(tl, [2, '.ม', 'xม่x yมy', 'yม'])
+  call add(tl, [2, '.ม่', 'xม่x yมy', 'xม่'])
+  call add(tl, [2, "\u05b9", " x\u05b9 ", "x\u05b9"])
+  call add(tl, [2, ".\u05b9", " x\u05b9 ", "x\u05b9"])
+  call add(tl, [2, "\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+  call add(tl, [2, ".\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+  call add(tl, [2, "\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+  call add(tl, [2, ".\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+  call add(tl, [2, "\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"])
+  call add(tl, [2, ".\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"])
+  call add(tl, [2, "\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"])
+  call add(tl, [2, ".\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"])
+  call add(tl, [1, "\u05b9\u05bb", " y\u05b9 x\u05b9\u05bb ", "x\u05b9\u05bb"])
+  call add(tl, [2, ".\u05b9\u05bb", " y\u05bb x\u05b9\u05bb ", "x\u05b9\u05bb"])
+  call add(tl, [2, "a", "ca\u0300t"])
+  call add(tl, [2, "ca", "ca\u0300t"])
+  call add(tl, [2, "a\u0300", "ca\u0300t", "a\u0300"])
+  call add(tl, [2, 'a\%C', "ca\u0300t", "a\u0300"])
+  call add(tl, [2, 'ca\%C', "ca\u0300t", "ca\u0300"])
+  call add(tl, [2, 'ca\%Ct', "ca\u0300t", "ca\u0300t"])
+
+  " Test \Z
+  call add(tl, [2, 'ú\Z', 'x'])
+  call add(tl, [2, 'יהוה\Z', 'יהוה', 'יהוה'])
+  call add(tl, [2, 'יְהוָה\Z', 'יהוה', 'יהוה'])
+  call add(tl, [2, 'יהוה\Z', 'יְהוָה', 'יְהוָה'])
+  call add(tl, [2, 'יְהוָה\Z', 'יְהוָה', 'יְהוָה'])
+  call add(tl, [2, 'יְ\Z', 'וְיַ', 'יַ'])
+  call add(tl, [2, "ק\u200d\u05b9x\\Z", "xק\u200d\u05b9xy", "ק\u200d\u05b9x"])
+  call add(tl, [2, "ק\u200d\u05b9x\\Z", "xק\u200dxy", "ק\u200dx"])
+  call add(tl, [2, "ק\u200dx\\Z", "xק\u200d\u05b9xy", "ק\u200d\u05b9x"])
+  call add(tl, [2, "ק\u200dx\\Z", "xק\u200dxy", "ק\u200dx"])
+  call add(tl, [2, "\u05b9\\Z", "xyz"])
+  call add(tl, [2, "\\Z\u05b9", "xyz"])
+  call add(tl, [2, "\u05b9\\Z", "xy\u05b9z", "y\u05b9"])
+  call add(tl, [2, "\\Z\u05b9", "xy\u05b9z", "y\u05b9"])
+  call add(tl, [1, "\u05b9\\+\\Z", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"])
+  call add(tl, [1, "\\Z\u05b9\\+", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"])
+
+  " Combining different tests and features
+  call add(tl, [2, '[^[=a=]]\+', 'ddaãâbcd', 'dd'])
+
+  " Run the tests
+  for t in tl
+    let re = t[0]
+    let pat = t[1]
+    let text = t[2]
+    let matchidx = 3
+    for engine in [0, 1, 2]
+      if engine == 2 && re == 0 || engine == 1 && re == 1
+        continue
+      endif
+      let &regexpengine = engine
+      try
+        let l = matchlist(text, pat)
+      catch
+        call assert_report('Error ' . engine . ': pat: \"' . pat .
+		    \ '\", text: \"' . text .
+		    \ '\", caused an exception: \"' . v:exception . '\"')
+      endtry
+      " check the match itself
+      if len(l) == 0 && len(t) > matchidx
+        call assert_report('Error ' . engine . ': pat: \"' . pat .
+		    \ '\", text: \"' . text .
+		    \ '\", did not match, expected: \"' . t[matchidx] . '\"')
+      elseif len(l) > 0 && len(t) == matchidx
+        call assert_report('Error ' . engine . ': pat: \"' . pat .
+		    \ '\", text: \"' . text . '\", match: \"' . l[0] .
+		    \ '\", expected no match')
+      elseif len(t) > matchidx && l[0] != t[matchidx]
+        call assert_report('Error ' . engine . ': pat: \"' . pat .
+		    \ '\", text: \"' . text . '\", match: \"' . l[0] .
+		    \ '\", expected: \"' . t[matchidx] . '\"')
+      else
+        " Test passed
+      endif
+      if len(l) > 0
+        " check all the nine submatches
+        for i in range(1, 9)
+          if len(t) <= matchidx + i
+            let e = ''
+          else
+            let e = t[matchidx + i]
+          endif
+          if l[i] != e
+            call assert_report('Error ' . engine . ': pat: \"' . pat .
+                  \ '\", text: \"' . text . '\", submatch ' . i .
+                  \ ': \"' . l[i] . '\", expected: \"' . e . '\"')
+          endif
+        endfor
+        unlet i
+      endif
+    endfor
+  endfor
+  set regexpengine&
+endfunc
+
+" check that 'ambiwidth' does not change the meaning of \p
+func Test_ambiwidth()
+  set regexpengine=1 ambiwidth=single
+  call assert_equal(0, match("\u00EC", '\p'))
+  set regexpengine=1 ambiwidth=double
+  call assert_equal(0, match("\u00EC", '\p'))
+  set regexpengine=2 ambiwidth=single
+  call assert_equal(0, match("\u00EC", '\p'))
+  set regexpengine=2 ambiwidth=double
+  call assert_equal(0, match("\u00EC", '\p'))
+  set regexpengine& ambiwidth&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_textformat.vim
+++ b/src/testdir/test_textformat.vim
@@ -509,3 +509,426 @@ func Test_crash_github_issue_5095()
   augroup END
   augroup! testing
 endfunc
+
+" Test for formatting multi-byte text with 'fo=t'
+func Test_tw_2_fo_t()
+  new
+  let t =<< trim END
+    {
+    XYZ
+    abc XYZ
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set tw=2 fo=t
+  let t =<< trim END
+    XYZ
+    abc XYZ
+  END
+  exe "normal gqgqjgqgq"
+  exe "normal o\n" . join(t, "\n")
+
+  let expected =<< trim END
+    {
+    XYZ
+    abc
+    XYZ
+
+    XYZ
+    abc
+    XYZ
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo&
+  bwipe!
+endfunc
+
+" Test for formatting multi-byte text with 'fo=tm' and 'tw=1'
+func Test_tw_1_fo_tm()
+  new
+  let t =<< trim END
+    {
+    X
+    Xa
+    X a
+    XY
+    X Y
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set tw=1 fo=tm
+  let t =<< trim END
+    X
+    Xa
+    X a
+    XY
+    X Y
+  END
+  exe "normal gqgqjgqgqjgqgqjgqgqjgqgq"
+  exe "normal o\n" . join(t, "\n")
+
+  let expected =<< trim END
+    {
+    X
+    X
+    a
+    X
+    a
+    X
+    Y
+    X
+    Y
+
+    X
+    X
+    a
+    X
+    a
+    X
+    Y
+    X
+    Y
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo&
+  bwipe!
+endfunc
+
+" Test for formatting multi-byte text with 'fo=tm' and 'tw=2'
+func Test_tw_2_fo_tm()
+  new
+  let t =<< trim END
+    {
+    X
+    Xa
+    X a
+    XY
+    X Y
+    aX
+    abX
+    abcX
+    abX c
+    abXY
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set tw=2 fo=tm
+  let t =<< trim END
+    X
+    Xa
+    X a
+    XY
+    X Y
+    aX
+    abX
+    abcX
+    abX c
+    abXY
+  END
+  exe "normal gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgq"
+  exe "normal o\n" . join(t, "\n")
+
+  let expected =<< trim END
+    {
+    X
+    X
+    a
+    X
+    a
+    X
+    Y
+    X
+    Y
+    a
+    X
+    ab
+    X
+    abc
+    X
+    ab
+    X
+    c
+    ab
+    X
+    Y
+
+    X
+    X
+    a
+    X
+    a
+    X
+    Y
+    X
+    Y
+    a
+    X
+    ab
+    X
+    abc
+    X
+    ab
+    X
+    c
+    ab
+    X
+    Y
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo&
+  bwipe!
+endfunc
+
+" Test for formatting multi-byte text with 'fo=tm', 'tw=2' and 'autoindent'.
+func Test_tw_2_fo_tm_ai()
+  new
+  let t =<< trim END
+    {
+      X
+      Xa
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set ai tw=2 fo=tm
+  let t =<< trim END
+    X
+    Xa
+  END
+  exe "normal gqgqjgqgq"
+  exe "normal o\n" . join(t, "\n")
+
+  let expected =<< trim END
+    {
+      X
+      X
+      a
+
+      X
+      X
+      a
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo& ai&
+  bwipe!
+endfunc
+
+" Test for formatting multi-byte text with 'fo=tm', 'tw=2' and 'noai'.
+func Test_tw_2_fo_tm_noai()
+  new
+  let t =<< trim END
+    {
+      X
+      Xa
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set noai tw=2 fo=tm
+  exe "normal gqgqjgqgqo\n  X\n  Xa"
+
+  let expected =<< trim END
+    {
+      X
+      X
+    a
+
+      X
+      X
+    a
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo& ai&
+  bwipe!
+endfunc
+
+func Test_tw_2_fo_cqm_com()
+  new
+  let t =<< trim END
+    {
+    X
+    Xa
+    XaY
+    XY
+    XYZ
+    X Y
+    X YZ
+    XX
+    XXa
+    XXY
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set tw=2 fo=cqm comments=n:X
+  exe "normal gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgq"
+  let t =<< trim END
+    X
+    Xa
+    XaY
+    XY
+    XYZ
+    X Y
+    X YZ
+    XX
+    XXa
+    XXY
+  END
+  exe "normal o\n" . join(t, "\n")
+
+  let expected =<< trim END
+    {
+    X
+    Xa
+    Xa
+    XY
+    XY
+    XY
+    XZ
+    X Y
+    X Y
+    X Z
+    XX
+    XXa
+    XXY
+
+    X
+    Xa
+    Xa
+    XY
+    XY
+    XY
+    XZ
+    X Y
+    X Y
+    X Z
+    XX
+    XXa
+    XXY
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo& comments&
+  bwipe!
+endfunc
+
+func Test_tw_2_fo_tm_replace()
+  new
+  let t =<< trim END
+    {
+
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set tw=2 fo=tm
+  exe "normal RXa"
+
+  let expected =<< trim END
+    {
+    X
+    a
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set tw& fo&
+  bwipe!
+endfunc
+
+" Test for 'matchpairs' with multibyte chars
+func Test_mps()
+  new
+  let t =<< trim END
+    {
+    ‘ two three ’ four
+    }
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  exe "set mps+=\u2018:\u2019"
+  normal d%
+
+  let expected =<< trim END
+    {
+     four
+    }
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  set mps&
+  bwipe!
+endfunc
+
+" Test for ra on multi-byte characters
+func Test_ra_multibyte()
+  new
+  let t =<< trim END
+    ra test
+    abba
+    aab
+  END
+  call setline(1, t)
+  call cursor(1, 1)
+
+  normal jVjra
+
+  let expected =<< trim END
+    ra test
+    aaaa
+    aaa
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  bwipe!
+endfunc
+
+" Test for 'whichwrap' with multi-byte character
+func Test_whichwrap()
+  new
+  let t =<< trim END
+    á
+    x
+  END
+  call setline(1, t)
+  call cursor(2, 1)
+
+  set whichwrap+=h
+  normal dh
+  set whichwrap-=h
+
+  let expected =<< trim END
+    áx
+  END
+  call assert_equal(expected, getline(1, '$'))
+
+  bwipe!
+endfunc
+
+func Test_substitute()
+  call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    14,
+/**/
     13,
 /**/
     12,