langmap_spec.lua 7.9 KB

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