langmap_spec.lua 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local eq, neq, call = helpers.eq, helpers.neq, helpers.call
  3. local eval, feed, clear = helpers.eval, helpers.feed, helpers.clear
  4. local command, insert, expect = helpers.command, helpers.insert, helpers.expect
  5. local feed_command = helpers.feed_command
  6. local curwin = helpers.curwin
  7. describe("'langmap'", function()
  8. before_each(function()
  9. clear()
  10. insert('iii www')
  11. command('set langmap=iw,wi')
  12. feed('gg0')
  13. end)
  14. it("converts keys in normal mode", function()
  15. feed('ix')
  16. expect('iii ww')
  17. feed('whello<esc>')
  18. expect('iii helloww')
  19. end)
  20. it("gives characters that are mapped by :nmap.", function()
  21. command('map i 0x')
  22. feed('w')
  23. expect('ii www')
  24. end)
  25. describe("'langnoremap' option.", function()
  26. before_each(function()
  27. command('nmapclear')
  28. end)
  29. it("'langnoremap' is by default ON", function()
  30. eq(eval('&langnoremap'), 1)
  31. end)
  32. it("Results of maps are not converted when 'langnoremap' ON.",
  33. function()
  34. command('nmap x i')
  35. feed('xdl<esc>')
  36. expect('dliii www')
  37. end)
  38. it("applies when deciding whether to map recursively", function()
  39. command('nmap l i')
  40. command('nmap w j')
  41. feed('ll')
  42. expect('liii www')
  43. end)
  44. it("does not stop applying 'langmap' on first character of a mapping",
  45. function()
  46. command('1t1')
  47. command('1t1')
  48. command('goto 1')
  49. command('nmap w j')
  50. feed('iiahello')
  51. expect([[
  52. iii www
  53. iii www
  54. ihelloii www]])
  55. end)
  56. it("Results of maps are converted when 'langnoremap' OFF.",
  57. function()
  58. command('set nolangnoremap')
  59. command('nmap x i')
  60. feed('xdl<esc>')
  61. expect('iii ww')
  62. end)
  63. end)
  64. -- e.g. CTRL-W_j , mj , 'j and "jp
  65. it('conversions are applied to keys in middle of command',
  66. function()
  67. -- Works in middle of window command
  68. feed('<C-w>s')
  69. local origwin = curwin()
  70. feed('<C-w>i')
  71. neq(curwin(), origwin)
  72. -- Works when setting a mark
  73. feed('yy3p3gg0mwgg0mi')
  74. eq(call('getpos', "'i"), {0, 3, 1, 0})
  75. eq(call('getpos', "'w"), {0, 1, 1, 0})
  76. feed('3dd')
  77. -- Works when moving to a mark
  78. feed("'i")
  79. eq(call('getpos', '.'), {0, 1, 1, 0})
  80. -- Works when selecting a register
  81. feed('qillqqwhhq')
  82. eq(eval('@i'), 'hh')
  83. eq(eval('@w'), 'll')
  84. feed('a<C-r>i<esc>')
  85. expect('illii www')
  86. feed('"ip')
  87. expect('illllii www')
  88. -- Works with i_CTRL-O
  89. feed('0a<C-O>ihi<esc>')
  90. expect('illllii hiwww')
  91. end)
  92. describe('exceptions', function()
  93. -- All "command characters" that 'langmap' does not apply to.
  94. -- These tests consist of those places where some subset of ASCII
  95. -- characters define certain commands, yet 'langmap' is not applied to
  96. -- them.
  97. -- n.b. I think these shouldn't be exceptions.
  98. it(':s///c confirmation', function()
  99. command('set langmap=yn,ny')
  100. feed('qa')
  101. feed_command('s/i/w/gc')
  102. feed('yynq')
  103. expect('wwi www')
  104. feed('u@a')
  105. expect('wwi www')
  106. eq(eval('@a'), ':s/i/w/gc\ryyn')
  107. end)
  108. it('insert-mode CTRL-G', function()
  109. command('set langmap=jk,kj')
  110. command('d')
  111. insert([[
  112. hello
  113. hello
  114. hello]])
  115. expect([[
  116. hello
  117. hello
  118. hello]])
  119. feed('qa')
  120. feed('gg3|ahello<C-G>jx<esc>')
  121. feed('q')
  122. expect([[
  123. helhellolo
  124. helxlo
  125. hello]])
  126. eq(eval('@a'), 'gg3|ahellojx')
  127. end)
  128. it('command-line CTRL-\\', function()
  129. command('set langmap=en,ne')
  130. feed(':<C-\\>e\'hello\'\r<C-B>put ="<C-E>"<CR>')
  131. expect([[
  132. iii www
  133. hello]])
  134. end)
  135. it('command-line CTRL-R', function()
  136. helpers.source([[
  137. let i_value = 0
  138. let j_value = 0
  139. call setreg('i', 'i_value')
  140. call setreg('j', 'j_value')
  141. set langmap=ij,ji
  142. ]])
  143. feed(':let <C-R>i=1<CR>')
  144. eq(eval('i_value'), 1)
  145. eq(eval('j_value'), 0)
  146. end)
  147. -- it('-- More -- prompt', function()
  148. -- -- The 'b' 'j' 'd' 'f' commands at the -- More -- prompt
  149. -- end)
  150. it('ask yes/no after backwards range', function()
  151. command('set langmap=yn,ny')
  152. feed('dd')
  153. insert([[
  154. hello
  155. there
  156. these
  157. are
  158. some
  159. lines
  160. ]])
  161. feed_command('4,2d')
  162. feed('n')
  163. expect([[
  164. hello
  165. there
  166. these
  167. are
  168. some
  169. lines
  170. ]])
  171. end)
  172. it('prompt for number', function()
  173. command('set langmap=12,21')
  174. helpers.source([[
  175. let gotten_one = 0
  176. function Map()
  177. let answer = inputlist(['a', '1.', '2.', '3.'])
  178. if answer == 1
  179. let g:gotten_one = 1
  180. endif
  181. endfunction
  182. nnoremap x :call Map()<CR>
  183. ]])
  184. feed('x1<CR>')
  185. eq(eval('gotten_one'), 1)
  186. command('let g:gotten_one = 0')
  187. feed_command('call Map()')
  188. feed('1<CR>')
  189. eq(eval('gotten_one'), 1)
  190. end)
  191. end)
  192. it('conversions are not applied during setreg()',
  193. function()
  194. call('setreg', 'i', 'ww')
  195. eq(eval('@i'), 'ww')
  196. end)
  197. it('conversions not applied in insert mode', function()
  198. feed('aiiiwww')
  199. expect('iiiiwwwii www')
  200. end)
  201. it('conversions not applied in search mode', function()
  202. feed('/iii<cr>x')
  203. expect('ii www')
  204. end)
  205. it('conversions not applied in cmdline mode', function()
  206. feed(':call append(1, "iii")<cr>')
  207. expect([[
  208. iii www
  209. iii]])
  210. end)
  211. local function testrecording(command_string, expect_string, setup_function)
  212. if setup_function then setup_function() end
  213. feed('qa' .. command_string .. 'q')
  214. expect(expect_string)
  215. eq(helpers.funcs.nvim_replace_termcodes(command_string, true, true, true),
  216. eval('@a'))
  217. if setup_function then setup_function() end
  218. -- n.b. may need nvim_replace_termcodes() here.
  219. feed('@a')
  220. expect(expect_string)
  221. end
  222. local function local_setup()
  223. -- Can't use `insert` as it uses `i` and we've swapped the meaning of that
  224. -- with the `langmap` setting.
  225. command('%d')
  226. command("put ='hello'")
  227. command('1d')
  228. end
  229. it('does not affect recording special keys', function()
  230. testrecording('A<BS><esc>', 'hell', local_setup)
  231. testrecording('>><lt><lt>', 'hello', local_setup)
  232. command('nnoremap \\ x')
  233. testrecording('\\', 'ello', local_setup)
  234. testrecording('A<C-V><BS><esc>', 'hello<BS>', local_setup)
  235. end)
  236. pending('Translates modified keys correctly', function()
  237. command('nnoremap <M-i> x')
  238. command('nnoremap <M-w> l')
  239. testrecording('<M-w>', 'ello', local_setup)
  240. testrecording('<M-i>x', 'hllo', local_setup)
  241. end)
  242. pending('handles multi-byte characters', function()
  243. command('set langmap=ïx')
  244. testrecording('ï', 'ello', local_setup)
  245. -- The test below checks that what's recorded is correct.
  246. -- It doesn't check the behaviour, as in order to cause some behaviour we
  247. -- need to map the multi-byte character, and there is a known bug
  248. -- preventing this from working (see the test below).
  249. command('set langmap=xï')
  250. testrecording('x', 'hello', local_setup)
  251. end)
  252. pending('handles multibyte mappings', function()
  253. -- See this vim issue for the problem, may as well add a test.
  254. -- https://github.com/vim/vim/issues/297
  255. command('set langmap=ïx')
  256. command('nnoremap x diw')
  257. testrecording('ï', '', local_setup)
  258. command('set nolangnoremap')
  259. command('set langmap=xï')
  260. command('nnoremap ï ix<esc>')
  261. testrecording('x', 'xhello', local_setup)
  262. end)
  263. -- This test is to ensure the behaviour doesn't change from what's already
  264. -- around. I (hardenedapple) personally think this behaviour should be
  265. -- changed.
  266. it('treats control modified keys as characters', function()
  267. command('nnoremap <C-w> iw<esc>')
  268. command('nnoremap <C-i> ii<esc>')
  269. testrecording('<C-w>', 'whello', local_setup)
  270. testrecording('<C-i>', 'ihello', local_setup)
  271. end)
  272. end)