textyankpost_spec.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local clear, eval, eq = n.clear, n.eval, t.eq
  4. local feed, command, expect = n.feed, n.command, n.expect
  5. local api, fn, neq = n.api, n.fn, t.neq
  6. describe('TextYankPost', function()
  7. before_each(function()
  8. clear()
  9. -- emulate the clipboard so system clipboard isn't affected
  10. command('set rtp^=test/functional/fixtures')
  11. command('let g:count = 0')
  12. command('autocmd TextYankPost * let g:event = copy(v:event)')
  13. command('autocmd TextYankPost * let g:count += 1')
  14. api.nvim_buf_set_lines(0, 0, -1, true, {
  15. 'foo\0bar',
  16. 'baz text',
  17. })
  18. end)
  19. it('is executed after yank and handles register types', function()
  20. feed('yy')
  21. eq({
  22. inclusive = false,
  23. operator = 'y',
  24. regcontents = { 'foo\nbar' },
  25. regname = '',
  26. regtype = 'V',
  27. visual = false,
  28. }, eval('g:event'))
  29. eq(1, eval('g:count'))
  30. -- v:event is cleared after the autocommand is done
  31. eq({}, eval('v:event'))
  32. feed('+yw')
  33. eq({
  34. inclusive = false,
  35. operator = 'y',
  36. regcontents = { 'baz ' },
  37. regname = '',
  38. regtype = 'v',
  39. visual = false,
  40. }, eval('g:event'))
  41. eq(2, eval('g:count'))
  42. feed('<c-v>eky')
  43. eq({
  44. inclusive = true,
  45. operator = 'y',
  46. regcontents = { 'foo', 'baz' },
  47. regname = '',
  48. regtype = '\0223', -- ^V + block width
  49. visual = true,
  50. }, eval('g:event'))
  51. eq(3, eval('g:count'))
  52. end)
  53. it('makes v:event immutable', function()
  54. feed('yy')
  55. eq({
  56. inclusive = false,
  57. operator = 'y',
  58. regcontents = { 'foo\nbar' },
  59. regname = '',
  60. regtype = 'V',
  61. visual = false,
  62. }, eval('g:event'))
  63. command('set debug=msg')
  64. -- the regcontents should not be changed without copy.
  65. local status, err = pcall(command, 'call extend(g:event.regcontents, ["more text"])')
  66. eq(false, status)
  67. neq(nil, string.find(err, ':E742:'))
  68. -- can't mutate keys inside the autocommand
  69. command('autocmd! TextYankPost * let v:event.regcontents = 0')
  70. status, err = pcall(command, 'normal yy')
  71. eq(false, status)
  72. neq(nil, string.find(err, ':E46:'))
  73. -- can't add keys inside the autocommand
  74. command('autocmd! TextYankPost * let v:event.mykey = 0')
  75. status, err = pcall(command, 'normal yy')
  76. eq(false, status)
  77. neq(nil, string.find(err, ':E742:'))
  78. end)
  79. it('is not invoked recursively', function()
  80. command('autocmd TextYankPost * normal "+yy')
  81. feed('yy')
  82. eq({
  83. inclusive = false,
  84. operator = 'y',
  85. regcontents = { 'foo\nbar' },
  86. regname = '',
  87. regtype = 'V',
  88. visual = false,
  89. }, eval('g:event'))
  90. eq(1, eval('g:count'))
  91. eq({ 'foo\nbar' }, fn.getreg('+', 1, 1))
  92. end)
  93. it('is executed after delete and change', function()
  94. feed('dw')
  95. eq({
  96. inclusive = false,
  97. operator = 'd',
  98. regcontents = { 'foo' },
  99. regname = '',
  100. regtype = 'v',
  101. visual = false,
  102. }, eval('g:event'))
  103. eq(1, eval('g:count'))
  104. feed('dd')
  105. eq({
  106. inclusive = false,
  107. operator = 'd',
  108. regcontents = { '\nbar' },
  109. regname = '',
  110. regtype = 'V',
  111. visual = false,
  112. }, eval('g:event'))
  113. eq(2, eval('g:count'))
  114. feed('cwspam<esc>')
  115. eq({
  116. inclusive = true,
  117. operator = 'c',
  118. regcontents = { 'baz' },
  119. regname = '',
  120. regtype = 'v',
  121. visual = false,
  122. }, eval('g:event'))
  123. eq(3, eval('g:count'))
  124. end)
  125. it('is not executed after black-hole operation', function()
  126. feed('"_dd')
  127. eq(0, eval('g:count'))
  128. feed('"_cwgood<esc>')
  129. eq(0, eval('g:count'))
  130. expect([[
  131. good text]])
  132. feed('"_yy')
  133. eq(0, eval('g:count'))
  134. command('delete _')
  135. eq(0, eval('g:count'))
  136. end)
  137. it('gives the correct register name', function()
  138. feed('$"byiw')
  139. eq({
  140. inclusive = true,
  141. operator = 'y',
  142. regcontents = { 'bar' },
  143. regname = 'b',
  144. regtype = 'v',
  145. visual = false,
  146. }, eval('g:event'))
  147. feed('"*yy')
  148. eq({
  149. inclusive = true,
  150. operator = 'y',
  151. regcontents = { 'foo\nbar' },
  152. regname = '*',
  153. regtype = 'V',
  154. visual = false,
  155. }, eval('g:event'))
  156. command('set clipboard=unnamed')
  157. -- regname still shows the name the user requested
  158. feed('yy')
  159. eq({
  160. inclusive = true,
  161. operator = 'y',
  162. regcontents = { 'foo\nbar' },
  163. regname = '',
  164. regtype = 'V',
  165. visual = false,
  166. }, eval('g:event'))
  167. feed('"*yy')
  168. eq({
  169. inclusive = true,
  170. operator = 'y',
  171. regcontents = { 'foo\nbar' },
  172. regname = '*',
  173. regtype = 'V',
  174. visual = false,
  175. }, eval('g:event'))
  176. end)
  177. it('works with Ex commands', function()
  178. command('1delete +')
  179. eq({
  180. inclusive = false,
  181. operator = 'd',
  182. regcontents = { 'foo\nbar' },
  183. regname = '+',
  184. regtype = 'V',
  185. visual = false,
  186. }, eval('g:event'))
  187. eq(1, eval('g:count'))
  188. command('yank')
  189. eq({
  190. inclusive = false,
  191. operator = 'y',
  192. regcontents = { 'baz text' },
  193. regname = '',
  194. regtype = 'V',
  195. visual = false,
  196. }, eval('g:event'))
  197. eq(2, eval('g:count'))
  198. command('normal yw')
  199. eq({
  200. inclusive = false,
  201. operator = 'y',
  202. regcontents = { 'baz ' },
  203. regname = '',
  204. regtype = 'v',
  205. visual = false,
  206. }, eval('g:event'))
  207. eq(3, eval('g:count'))
  208. command('normal! dd')
  209. eq({
  210. inclusive = false,
  211. operator = 'd',
  212. regcontents = { 'baz text' },
  213. regname = '',
  214. regtype = 'V',
  215. visual = false,
  216. }, eval('g:event'))
  217. eq(4, eval('g:count'))
  218. end)
  219. it('updates numbered registers correctly #10225', function()
  220. command('autocmd TextYankPost * let g:reg = getreg("1")')
  221. feed('"adj')
  222. eq('foo\nbar\nbaz text\n', eval('g:reg'))
  223. end)
  224. end)