substitute_spec.lua (8359B)
1 -- Test for *sub-replace-special* and *sub-replace-expression* on substitute(). 2 -- Test for submatch() on substitute(). 3 -- Test for *:s%* on :substitute. 4 5 local t = require('test.testutil') 6 local n = require('test.functional.testnvim')() 7 local Screen = require('test.functional.ui.screen') 8 9 local feed, insert = n.feed, n.insert 10 local exec = n.exec 11 local clear, feed_command, expect = n.clear, n.feed_command, n.expect 12 local eq, eval = t.eq, n.eval 13 14 describe('substitute()', function() 15 before_each(clear) 16 17 -- The original test contained several TEST_X lines to delimit different 18 -- parts. These where used to split the test into different it() blocks. 19 -- The TEST_X strings are repeated in the description of the blocks to make 20 -- it easier to incorporate upstream changes. 21 22 local function test_1_and_2() 23 eq('AA', eval("substitute('A', 'A', '&&', '')")) 24 eq('&', eval([[substitute('B', 'B', '\&', '')]])) 25 eq( 26 'C123456789987654321', 27 eval( 28 [[substitute('C123456789', ]] 29 .. [['C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] 30 .. [['\0\9\8\7\6\5\4\3\2\1', '')]] 31 ) 32 ) 33 eq('d', eval("substitute('D', 'D', 'd', '')")) 34 eq('~', eval("substitute('E', 'E', '~', '')")) 35 eq('~', eval([[substitute('F', 'F', '\~', '')]])) 36 eq('Gg', eval([[substitute('G', 'G', '\ugg', '')]])) 37 eq('Hh', eval([[substitute('H', 'H', '\Uh\Eh', '')]])) 38 eq('iI', eval([[substitute('I', 'I', '\lII', '')]])) 39 eq('jJ', eval([[substitute('J', 'J', '\LJ\EJ', '')]])) 40 eq('Kk', eval([[substitute('K', 'K', '\Uk\ek', '')]])) 41 eq('l\rl', eval("substitute('lLl', 'L', '\r', '')")) 42 eq('m\rm', eval([[substitute('mMm', 'M', '\r', '')]])) 43 eq('n\rn', eval("substitute('nNn', 'N', '\\\r', '')")) 44 eq('o\no', eval([[substitute('oOo', 'O', '\n', '')]])) 45 eq('p\bp', eval([[substitute('pPp', 'P', '\b', '')]])) 46 eq('q\tq', eval([[substitute('qQq', 'Q', '\t', '')]])) 47 eq('r\\r', eval([[substitute('rRr', 'R', '\\', '')]])) 48 eq('scs', eval([[substitute('sSs', 'S', '\c', '')]])) 49 eq('t\rt', eval([[substitute('tTt', 'T', "\r", '')]])) 50 eq('u\nu', eval([[substitute('uUu', 'U', "\n", '')]])) 51 eq('v\bv', eval([[substitute('vVv', 'V', "\b", '')]])) 52 eq('w\\w', eval([[substitute('wWw', 'W', "\\", '')]])) 53 eq('XxxX', eval([[substitute('X', 'X', '\L\uxXx\l\EX', '')]])) 54 eq('yYYy', eval([[substitute('Y', 'Y', '\U\lYyY\u\Ey', '')]])) 55 end 56 57 it('with "set magic" (TEST_1)', function() 58 feed_command('set magic') 59 test_1_and_2() 60 end) 61 62 it('with "set nomagic" (TEST_2)', function() 63 feed_command('set nomagic') 64 test_1_and_2() 65 end) 66 67 it('with sub-replace-expression (TEST_3)', function() 68 feed_command('set magic&') 69 eq('a\\a', eval([[substitute('aAa', 'A', '\="\\"', '')]])) 70 eq('b\\\\b', eval([[substitute('bBb', 'B', '\="\\\\"', '')]])) 71 eq('c\rc', eval([[substitute('cCc', 'C', '\="]] .. '\r' .. [["', '')]])) 72 eq('d\\\rd', eval([[substitute('dDd', 'D', '\="\\]] .. '\r' .. [["', '')]])) 73 eq('e\\\\\re', eval([[substitute('eEe', 'E', '\="\\\\]] .. '\r' .. [["', '')]])) 74 eq('f\\rf', eval([[substitute('fFf', 'F', '\="\\r"', '')]])) 75 eq('j\\nj', eval([[substitute('jJj', 'J', '\="\\n"', '')]])) 76 eq('k\rk', eval([[substitute('kKk', 'K', '\="\r"', '')]])) 77 eq('l\nl', eval([[substitute('lLl', 'L', '\="\n"', '')]])) 78 end) 79 80 it('with submatch() (TEST_4)', function() 81 feed_command('set magic&') 82 eq( 83 'a\\a', 84 eval([[substitute('aAa', 'A', ]] .. [['\=substitute(submatch(0), ".", "\\", "")', '')]]) 85 ) 86 eq( 87 'b\\b', 88 eval([[substitute('bBb', 'B', ]] .. [['\=substitute(submatch(0), ".", "\\\\", "")', '')]]) 89 ) 90 eq( 91 'c\rc', 92 eval( 93 [[substitute('cCc', 'C', ]] 94 .. [['\=substitute(submatch(0), ".", "]] 95 .. '\r' 96 .. [[", "")', '')]] 97 ) 98 ) 99 eq( 100 'd\rd', 101 eval( 102 [[substitute('dDd', 'D', ]] 103 .. [['\=substitute(submatch(0), ".", "\\]] 104 .. '\r' 105 .. [[", "")', '')]] 106 ) 107 ) 108 eq( 109 'e\\\re', 110 eval( 111 [[substitute('eEe', 'E', ]] 112 .. [['\=substitute(submatch(0), ".", "\\\\]] 113 .. '\r' 114 .. [[", "")', '')]] 115 ) 116 ) 117 eq( 118 'f\rf', 119 eval([[substitute('fFf', 'F', ]] .. [['\=substitute(submatch(0), ".", "\\r", "")', '')]]) 120 ) 121 eq( 122 'j\nj', 123 eval([[substitute('jJj', 'J', ]] .. [['\=substitute(submatch(0), ".", "\\n", "")', '')]]) 124 ) 125 eq( 126 'k\rk', 127 eval([[substitute('kKk', 'K', ]] .. [['\=substitute(submatch(0), ".", "\r", "")', '')]]) 128 ) 129 eq( 130 'l\nl', 131 eval([[substitute('lLl', 'L', ]] .. [['\=substitute(submatch(0), ".", "\n", "")', '')]]) 132 ) 133 end) 134 135 it('with submatch() (TEST_5)', function() 136 feed_command('set magic&') 137 eq( 138 'A123456789987654321', 139 eval( 140 [[substitute('A123456789', ]] 141 .. [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] 142 .. [['\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . ]] 143 .. [[submatch(6) . submatch(5) . submatch(4) . submatch(3) . ]] 144 .. [[submatch(2) . submatch(1)', '')]] 145 ) 146 ) 147 eq( 148 "[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], " .. "['2'], ['1']]", 149 eval( 150 [[substitute('A123456789', ]] 151 .. [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] 152 .. [['\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), ]] 153 .. [[submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), ]] 154 .. [[submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')]] 155 ) 156 ) 157 end) 158 159 -- TEST_6 was about the 'cpoptions' flag / which was removed in pull request 160 -- #2943. 161 162 it('with submatch or \\ze (TEST_7)', function() 163 feed_command('set magic&') 164 eq('A\rA', eval("substitute('A\rA', 'A.', '\\=submatch(0)', '')")) 165 eq('B\nB', eval([[substitute("B\nB", 'B.', '\=submatch(0)', '')]])) 166 eq("['B\n']B", eval([[substitute("B\nB", 'B.', '\=string(submatch(0, 1))', '')]])) 167 eq('-abab', eval([[substitute('-bb', '\zeb', 'a', 'g')]])) 168 eq('c-cbcbc', eval([[substitute('-bb', '\ze', 'c', 'g')]])) 169 end) 170 171 it('with \\zs and \\ze (TEST_10)', function() 172 feed_command('set magic&') 173 eq('a1a2a3a', eval([[substitute('123', '\zs', 'a', 'g')]])) 174 eq('aaa', eval([[substitute('123', '\zs.', 'a', 'g')]])) 175 eq('1a2a3a', eval([[substitute('123', '.\zs', 'a', 'g')]])) 176 eq('a1a2a3a', eval([[substitute('123', '\ze', 'a', 'g')]])) 177 eq('a1a2a3', eval([[substitute('123', '\ze.', 'a', 'g')]])) 178 eq('aaa', eval([[substitute('123', '.\ze', 'a', 'g')]])) 179 eq('aa2a3a', eval([[substitute('123', '1\|\ze', 'a', 'g')]])) 180 eq('1aaa', eval([[substitute('123', '1\zs\|[23]', 'a', 'g')]])) 181 end) 182 end) 183 184 describe(':substitute', function() 185 before_each(clear) 186 187 it('with \\ze and \\zs and confirmation dialog (TEST_8)', function() 188 insert([[ 189 ,,X 190 ,,Y 191 ,,Z]]) 192 feed_command('set magic&') 193 feed_command([[1s/\(^\|,\)\ze\(,\|X\)/\1N/g]]) 194 feed_command([[2s/\(^\|,\)\ze\(,\|Y\)/\1N/gc]]) 195 feed('a') -- For the dialog of the previous :s command. 196 feed_command([[3s/\(^\|,\)\ze\(,\|Z\)/\1N/gc]]) 197 feed('yy') -- For the dialog of the previous :s command. 198 expect([[ 199 N,,NX 200 N,,NY 201 N,,NZ]]) 202 end) 203 204 it('with confirmation dialog (TEST_9)', function() 205 insert('xxx') 206 feed_command('set magic&') 207 feed_command('s/x/X/gc') 208 feed('yyq') -- For the dialog of the previous :s command. 209 expect('XXx') 210 end) 211 212 it('first char is highlighted with confirmation dialog and empty match', function() 213 local screen = Screen.new(60, 8) 214 exec([[ 215 set nohlsearch noincsearch 216 call setline(1, ['one', 'two', 'three']) 217 ]]) 218 feed(':%s/^/ /c<CR>') 219 screen:expect([[ 220 {2:o}ne | 221 two | 222 three | 223 {1:~ }|*2 224 {3: }| 225 {6:replace with ? (y)es/(n)o/(a)ll/(q)uit/(l)ast/scroll up(^}| 226 {6:E)/down(^Y)}^ | 227 ]]) 228 end) 229 end)