macro_spec.lua (4860B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local eq = t.eq 5 local eval = n.eval 6 local feed = n.feed 7 local clear = n.clear 8 local expect = n.expect 9 local command = n.command 10 local fn = n.fn 11 local api = n.api 12 local insert = n.insert 13 14 describe('macros with default mappings', function() 15 before_each(function() 16 clear({ args_rm = { '--cmd' } }) 17 end) 18 19 it('can be recorded and replayed', function() 20 feed('qiahello<esc>q') 21 expect('hello') 22 eq('ahello', eval('@i')) 23 feed('@i') 24 expect('hellohello') 25 eq('ahello', eval('@i')) 26 end) 27 28 it('applies maps', function() 29 command('imap x l') 30 command('nmap l a') 31 feed('qilxxx<esc>q') 32 expect('lll') 33 eq('lxxx', eval('@i')) 34 feed('@i') 35 expect('llllll') 36 eq('lxxx', eval('@i')) 37 end) 38 39 it('can be replayed with Q', function() 40 insert [[ 41 hello 42 hello 43 hello]] 44 feed [[gg]] 45 46 feed [[qqAFOO<esc>q]] 47 expect [[ 48 helloFOO 49 hello 50 hello]] 51 52 feed [[Q]] 53 expect [[ 54 helloFOOFOO 55 hello 56 hello]] 57 58 feed [[G3Q]] 59 expect [[ 60 helloFOOFOO 61 hello 62 helloFOOFOOFOO]] 63 64 feed [[ggV3jQ]] 65 expect [[ 66 helloFOOFOOFOO 67 helloFOO 68 helloFOOFOOFOOFOO]] 69 end) 70 71 it('can be replayed with Q and @@', function() 72 insert [[ 73 hello 74 hello 75 hello]] 76 feed [[gg]] 77 78 feed [[qqAFOO<esc>q]] 79 expect [[ 80 helloFOO 81 hello 82 hello]] 83 84 feed [[Q]] 85 expect [[ 86 helloFOOFOO 87 hello 88 hello]] 89 90 feed [[G3@@]] 91 expect [[ 92 helloFOOFOO 93 hello 94 helloFOOFOOFOO]] 95 96 feed [[ggV2j@@]] 97 expect [[ 98 helloFOOFOOFOO 99 helloFOO 100 helloFOOFOOFOOFOO]] 101 end) 102 103 it('can be replayed with @ in linewise Visual mode', function() 104 insert [[ 105 hello 106 hello 107 hello]] 108 feed [[gg]] 109 110 feed [[qqAFOO<esc>qu]] 111 expect [[ 112 hello 113 hello 114 hello]] 115 116 feed [[qwA123<esc>qu]] 117 expect [[ 118 hello 119 hello 120 hello]] 121 122 feed [[V3j@q]] 123 expect [[ 124 helloFOO 125 helloFOO 126 helloFOO]] 127 128 feed [[ggVj@w]] 129 expect [[ 130 helloFOO123 131 helloFOO123 132 helloFOO]] 133 end) 134 135 it('can be recorded and replayed in Visual mode', function() 136 insert('foo BAR BAR foo BAR foo BAR BAR BAR foo BAR BAR') 137 feed('0vqifofRq') 138 eq({ 0, 1, 7, 0 }, fn.getpos('.')) 139 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 140 feed('Q') 141 eq({ 0, 1, 19, 0 }, fn.getpos('.')) 142 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 143 feed('Q') 144 eq({ 0, 1, 27, 0 }, fn.getpos('.')) 145 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 146 feed('@i') 147 eq({ 0, 1, 43, 0 }, fn.getpos('.')) 148 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 149 end) 150 151 it('can be recorded and replayed in Visual mode when ignorecase', function() 152 command('set ignorecase') 153 insert('foo BAR BAR foo BAR foo BAR BAR BAR foo BAR BAR') 154 feed('0vqifofRq') 155 eq({ 0, 1, 7, 0 }, fn.getpos('.')) 156 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 157 feed('Q') 158 eq({ 0, 1, 19, 0 }, fn.getpos('.')) 159 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 160 feed('Q') 161 eq({ 0, 1, 27, 0 }, fn.getpos('.')) 162 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 163 feed('@i') 164 eq({ 0, 1, 43, 0 }, fn.getpos('.')) 165 eq({ 0, 1, 1, 0 }, fn.getpos('v')) 166 end) 167 168 it('can be replayed with @ in blockwise Visual mode', function() 169 insert [[ 170 hello 171 hello 172 hello]] 173 feed [[gg]] 174 175 feed [[qqAFOO<esc>qu]] 176 expect [[ 177 hello 178 hello 179 hello]] 180 181 feed [[qwA123<esc>qu]] 182 expect [[ 183 hello 184 hello 185 hello]] 186 187 feed [[0<C-v>3jl@q]] 188 expect [[ 189 heFOOllo 190 heFOOllo 191 heFOOllo]] 192 193 feed [[gg0<C-v>j@w]] 194 expect [[ 195 h123eFOOllo 196 h123eFOOllo 197 heFOOllo]] 198 end) 199 end) 200 201 describe('immediately after a macro has finished executing,', function() 202 before_each(function() 203 clear() 204 command([[let @a = 'gg0']]) 205 end) 206 207 describe('reg_executing() from RPC returns an empty string', function() 208 it('if the macro does not end with a <Nop> mapping', function() 209 feed('@a') 210 eq('', fn.reg_executing()) 211 end) 212 213 it('if the macro ends with a <Nop> mapping', function() 214 command('nnoremap 0 <Nop>') 215 feed('@a') 216 eq('', fn.reg_executing()) 217 end) 218 end) 219 220 describe('characters from a mapping are not treated as a part of the macro #18015', function() 221 before_each(function() 222 command('nnoremap s qa') 223 end) 224 225 it('if the macro does not end with a <Nop> mapping', function() 226 feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op 227 eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) 228 expect('') 229 eq('', eval('@a')) 230 end) 231 232 it('if the macro ends with a <Nop> mapping', function() 233 command('nnoremap 0 <Nop>') 234 feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op 235 eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) 236 expect('') 237 eq('', eval('@a')) 238 end) 239 end) 240 end) 241 242 describe('reg_recorded()', function() 243 before_each(clear) 244 it('returns the correct value', function() 245 feed [[qqyyq]] 246 eq('q', eval('reg_recorded()')) 247 end) 248 end)