clipboard_spec.lua 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. -- Test clipboard provider support
  2. local helpers = require('test.functional.helpers')(after_each)
  3. local Screen = require('test.functional.ui.screen')
  4. local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
  5. local feed_command, expect, eq, eval, source = helpers.feed_command, helpers.expect, helpers.eq, helpers.eval, helpers.source
  6. local command = helpers.command
  7. local meths = helpers.meths
  8. local function basic_register_test(noblock)
  9. insert("some words")
  10. feed('^dwP')
  11. expect('some words')
  12. feed('veyP')
  13. expect('some words words')
  14. feed('^dwywe"-p')
  15. expect('wordssome words')
  16. feed('p')
  17. expect('wordssome words words')
  18. feed('yyp')
  19. expect([[
  20. wordssome words words
  21. wordssome words words]])
  22. feed('d-')
  23. insert([[
  24. some text, and some more
  25. random text stuff]])
  26. feed('ggtav+2ed$p')
  27. expect([[
  28. some text, stuff and some more
  29. random text]])
  30. -- deleting line or word uses "1/"- and doesn't clobber "0
  31. -- and deleting word to unnamed doesn't clobber "1
  32. feed('ggyyjdddw"0p"1p"-P')
  33. expect([[
  34. text, stuff and some more
  35. some text, stuff and some more
  36. some random text]])
  37. -- delete line doesn't clobber "-
  38. feed('dd"-P')
  39. expect([[
  40. text, stuff and some more
  41. some some text, stuff and some more]])
  42. -- deleting a word to named ("a) updates "1 (and not "-)
  43. feed('gg"adwj"1P^"-P')
  44. expect([[
  45. , stuff and some more
  46. some textsome some text, stuff and some more]])
  47. -- deleting a line does update ""
  48. feed('ggdd""P')
  49. expect([[
  50. , stuff and some more
  51. some textsome some text, stuff and some more]])
  52. feed('ggw<c-v>jwyggP')
  53. if noblock then
  54. expect([[
  55. stuf
  56. me t
  57. , stuff and some more
  58. some textsome some text, stuff and some more]])
  59. else
  60. expect([[
  61. stuf, stuff and some more
  62. me tsome textsome some text, stuff and some more]])
  63. end
  64. -- pasting in visual does unnamed delete of visual selection
  65. feed('ggdG')
  66. insert("one and two and three")
  67. feed('"ayiwbbviw"ap^viwp$viw"-p')
  68. expect("two and three and one")
  69. end
  70. describe('clipboard', function()
  71. local screen
  72. before_each(function()
  73. clear()
  74. screen = Screen.new(72, 4)
  75. screen:set_default_attr_ids({
  76. [0] = {bold = true, foreground = Screen.colors.Blue},
  77. [1] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
  78. [2] = {bold = true, foreground = Screen.colors.SeaGreen4},
  79. })
  80. screen:attach()
  81. command("set display-=msgsep")
  82. end)
  83. it('unnamed register works without provider', function()
  84. eq('"', eval('v:register'))
  85. basic_register_test()
  86. end)
  87. it('`:redir @+>` with invalid g:clipboard shows exactly one error #7184',
  88. function()
  89. command("let g:clipboard = 'bogus'")
  90. feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END')
  91. screen:expect([[
  92. ^ |
  93. {0:~ }|
  94. {0:~ }|
  95. clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
  96. ]])
  97. end)
  98. it('`:redir @+>|bogus_cmd|redir END` + invalid g:clipboard must not recurse #7184',
  99. function()
  100. command("let g:clipboard = 'bogus'")
  101. feed_command('redir @+> | bogus_cmd | redir END')
  102. screen:expect{grid=[[
  103. {0:~ }|
  104. clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
  105. {1:E492: Not an editor command: bogus_cmd | redir END} |
  106. {2:Press ENTER or type command to continue}^ |
  107. ]]}
  108. end)
  109. it('invalid g:clipboard shows hint if :redir is not active', function()
  110. command("let g:clipboard = 'bogus'")
  111. eq('', eval('provider#clipboard#Executable()'))
  112. eq('clipboard: invalid g:clipboard', eval('provider#clipboard#Error()'))
  113. command("let g:clipboard = 'bogus'")
  114. -- Explicit clipboard attempt, should show a hint message.
  115. feed_command('let @+="foo"')
  116. screen:expect([[
  117. ^ |
  118. {0:~ }|
  119. {0:~ }|
  120. clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
  121. ]])
  122. end)
  123. it('valid g:clipboard', function()
  124. -- provider#clipboard#Executable() only checks the structure.
  125. meths.set_var('clipboard', {
  126. ['name'] = 'clippy!',
  127. ['copy'] = { ['+'] = 'any command', ['*'] = 'some other' },
  128. ['paste'] = { ['+'] = 'any command', ['*'] = 'some other' },
  129. })
  130. eq('clippy!', eval('provider#clipboard#Executable()'))
  131. eq('', eval('provider#clipboard#Error()'))
  132. end)
  133. it('g:clipboard using lists', function()
  134. source([[let g:clipboard = {
  135. \ 'name': 'custom',
  136. \ 'copy': { '+': ['any', 'command'], '*': ['some', 'other'] },
  137. \ 'paste': { '+': ['any', 'command'], '*': ['some', 'other'] },
  138. \}]])
  139. eq('custom', eval('provider#clipboard#Executable()'))
  140. eq('', eval('provider#clipboard#Error()'))
  141. end)
  142. it('g:clipboard using VimL functions', function()
  143. -- Implements a fake clipboard provider. cache_enabled is meaningless here.
  144. source([[let g:clipboard = {
  145. \ 'name': 'custom',
  146. \ 'copy': {
  147. \ '+': {lines, regtype -> extend(g:, {'dummy_clipboard_plus': [lines, regtype]}) },
  148. \ '*': {lines, regtype -> extend(g:, {'dummy_clipboard_star': [lines, regtype]}) },
  149. \ },
  150. \ 'paste': {
  151. \ '+': {-> get(g:, 'dummy_clipboard_plus', [])},
  152. \ '*': {-> get(g:, 'dummy_clipboard_star', [])},
  153. \ },
  154. \ 'cache_enabled': 1,
  155. \}]])
  156. eq('', eval('provider#clipboard#Error()'))
  157. eq('custom', eval('provider#clipboard#Executable()'))
  158. eq('', eval("getreg('*')"))
  159. eq('', eval("getreg('+')"))
  160. command('call setreg("*", "star")')
  161. command('call setreg("+", "plus")')
  162. eq('star', eval("getreg('*')"))
  163. eq('plus', eval("getreg('+')"))
  164. command('call setreg("*", "star", "v")')
  165. eq({{'star'}, 'v'}, eval("g:dummy_clipboard_star"))
  166. command('call setreg("*", "star", "V")')
  167. eq({{'star', ''}, 'V'}, eval("g:dummy_clipboard_star"))
  168. command('call setreg("*", "star", "b")')
  169. eq({{'star', ''}, 'b'}, eval("g:dummy_clipboard_star"))
  170. end)
  171. describe('g:clipboard[paste] VimL function', function()
  172. it('can return empty list for empty clipboard', function()
  173. source([[let g:dummy_clipboard = []
  174. let g:clipboard = {
  175. \ 'name': 'custom',
  176. \ 'copy': { '*': {lines, regtype -> 0} },
  177. \ 'paste': { '*': {-> g:dummy_clipboard} },
  178. \}]])
  179. eq('', eval('provider#clipboard#Error()'))
  180. eq('custom', eval('provider#clipboard#Executable()'))
  181. eq('', eval("getreg('*')"))
  182. end)
  183. it('can return a list with a single string', function()
  184. source([=[let g:dummy_clipboard = ['hello']
  185. let g:clipboard = {
  186. \ 'name': 'custom',
  187. \ 'copy': { '*': {lines, regtype -> 0} },
  188. \ 'paste': { '*': {-> g:dummy_clipboard} },
  189. \}]=])
  190. eq('', eval('provider#clipboard#Error()'))
  191. eq('custom', eval('provider#clipboard#Executable()'))
  192. eq('hello', eval("getreg('*')"))
  193. source([[let g:dummy_clipboard = [''] ]])
  194. eq('', eval("getreg('*')"))
  195. end)
  196. it('can return a list of lines if a regtype is provided', function()
  197. source([=[let g:dummy_clipboard = [['hello'], 'v']
  198. let g:clipboard = {
  199. \ 'name': 'custom',
  200. \ 'copy': { '*': {lines, regtype -> 0} },
  201. \ 'paste': { '*': {-> g:dummy_clipboard} },
  202. \}]=])
  203. eq('', eval('provider#clipboard#Error()'))
  204. eq('custom', eval('provider#clipboard#Executable()'))
  205. eq('hello', eval("getreg('*')"))
  206. end)
  207. it('can return a list of lines instead of [lines, regtype]', function()
  208. source([=[let g:dummy_clipboard = ['hello', 'v']
  209. let g:clipboard = {
  210. \ 'name': 'custom',
  211. \ 'copy': { '*': {lines, regtype -> 0} },
  212. \ 'paste': { '*': {-> g:dummy_clipboard} },
  213. \}]=])
  214. eq('', eval('provider#clipboard#Error()'))
  215. eq('custom', eval('provider#clipboard#Executable()'))
  216. eq('hello\nv', eval("getreg('*')"))
  217. end)
  218. end)
  219. end)
  220. describe('clipboard (with fake clipboard.vim)', function()
  221. local function reset(...)
  222. clear('--cmd', 'let &rtp = "test/functional/fixtures,".&rtp', ...)
  223. end
  224. before_each(function()
  225. reset()
  226. feed_command('call getreg("*")') -- force load of provider
  227. end)
  228. it('`:redir @+>` invokes clipboard once-per-message', function()
  229. eq(0, eval("g:clip_called_set"))
  230. feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END')
  231. -- Assuming CONTRIBUTING.md has >100 lines.
  232. assert(eval("g:clip_called_set") > 100)
  233. end)
  234. it('`:redir @">` does NOT invoke clipboard', function()
  235. -- :redir to a non-clipboard register, with `:set clipboard=unnamed` does
  236. -- NOT propagate to the clipboard. This is consistent with Vim.
  237. command("set clipboard=unnamedplus")
  238. eq(0, eval("g:clip_called_set"))
  239. feed_command('redir @"> | :silent echo system("cat CONTRIBUTING.md") | redir END')
  240. eq(0, eval("g:clip_called_set"))
  241. end)
  242. it('`:redir @+>|bogus_cmd|redir END` must not recurse #7184',
  243. function()
  244. local screen = Screen.new(72, 4)
  245. screen:attach()
  246. screen:set_default_attr_ids({
  247. [0] = {bold = true, foreground = Screen.colors.Blue},
  248. [1] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
  249. })
  250. feed_command('redir @+> | bogus_cmd | redir END')
  251. screen:expect([[
  252. ^ |
  253. {0:~ }|
  254. {0:~ }|
  255. {1:E492: Not an editor command: bogus_cmd | redir END} |
  256. ]])
  257. end)
  258. it('has independent "* and unnamed registers by default', function()
  259. insert("some words")
  260. feed('^"*dwdw"*P')
  261. expect('some ')
  262. eq({{'some '}, 'v'}, eval("g:test_clip['*']"))
  263. eq('words', eval("getreg('\"', 1)"))
  264. end)
  265. it('supports separate "* and "+ when the provider supports it', function()
  266. insert([[
  267. text:
  268. first line
  269. secound line
  270. third line]])
  271. feed('G"+dd"*dddd"+p"*pp')
  272. expect([[
  273. text:
  274. third line
  275. secound line
  276. first line]])
  277. -- linewise selection should be encoded as an extra newline
  278. eq({{'third line', ''}, 'V'}, eval("g:test_clip['+']"))
  279. eq({{'secound line', ''}, 'V'}, eval("g:test_clip['*']"))
  280. end)
  281. it('handles null bytes when pasting and in getreg', function()
  282. insert("some\022000text\n\022000very binary\022000")
  283. feed('"*y-+"*p')
  284. eq({{'some\ntext', '\nvery binary\n',''}, 'V'}, eval("g:test_clip['*']"))
  285. expect("some\00text\n\00very binary\00\nsome\00text\n\00very binary\00")
  286. -- test getreg/getregtype
  287. eq('some\ntext\n\nvery binary\n\n', eval("getreg('*', 1)"))
  288. eq("V", eval("getregtype('*')"))
  289. -- getreg supports three arguments
  290. eq('some\ntext\n\nvery binary\n\n', eval("getreg('*', 1, 0)"))
  291. eq({'some\ntext', '\nvery binary\n'}, eval("getreg('*', 1, 1)"))
  292. end)
  293. it('autodetects regtype', function()
  294. feed_command("let g:test_clip['*'] = ['linewise stuff','']")
  295. feed_command("let g:test_clip['+'] = ['charwise','stuff']")
  296. eq("V", eval("getregtype('*')"))
  297. eq("v", eval("getregtype('+')"))
  298. insert("just some text")
  299. feed('"*p"+p')
  300. expect([[
  301. just some text
  302. lcharwise
  303. stuffinewise stuff]])
  304. end)
  305. it('support blockwise operations', function()
  306. insert([[
  307. much
  308. text]])
  309. feed_command("let g:test_clip['*'] = [['very','block'],'b']")
  310. feed('gg"*P')
  311. expect([[
  312. very much
  313. blocktext]])
  314. eq("\0225", eval("getregtype('*')"))
  315. feed('gg4l<c-v>j4l"+ygg"+P')
  316. expect([[
  317. muchvery much
  318. ktextblocktext]])
  319. eq({{' much', 'ktext', ''}, 'b'}, eval("g:test_clip['+']"))
  320. end)
  321. it('supports setreg()', function()
  322. feed_command('call setreg("*", "setted\\ntext", "c")')
  323. feed_command('call setreg("+", "explicitly\\nlines", "l")')
  324. feed('"+P"*p')
  325. expect([[
  326. esetted
  327. textxplicitly
  328. lines
  329. ]])
  330. feed_command('call setreg("+", "blocky\\nindeed", "b")')
  331. feed('"+p')
  332. expect([[
  333. esblockyetted
  334. teindeedxtxplicitly
  335. lines
  336. ]])
  337. end)
  338. it('supports :let @+ (issue #1427)', function()
  339. feed_command("let @+ = 'some'")
  340. feed_command("let @* = ' other stuff'")
  341. eq({{'some'}, 'v'}, eval("g:test_clip['+']"))
  342. eq({{' other stuff'}, 'v'}, eval("g:test_clip['*']"))
  343. feed('"+p"*p')
  344. expect('some other stuff')
  345. feed_command("let @+ .= ' more'")
  346. feed('dd"+p')
  347. expect('some more')
  348. end)
  349. it('pastes unnamed register if the provider fails', function()
  350. insert('the text')
  351. feed('yy')
  352. feed_command("let g:cliperror = 1")
  353. feed('"*p')
  354. expect([[
  355. the text
  356. the text]])
  357. end)
  358. describe('with clipboard=unnamed', function()
  359. -- the basic behavior of unnamed register should be the same
  360. -- even when handled by clipboard provider
  361. before_each(function()
  362. feed_command('set clipboard=unnamed')
  363. end)
  364. it('works', function()
  365. basic_register_test()
  366. end)
  367. it('works with pure text clipboard', function()
  368. feed_command("let g:cliplossy = 1")
  369. -- expect failure for block mode
  370. basic_register_test(true)
  371. end)
  372. it('links the "* and unnamed registers', function()
  373. -- with cb=unnamed, "* and unnamed will be the same register
  374. insert("some words")
  375. feed('^"*dwdw"*P')
  376. expect('words')
  377. eq({{'words'}, 'v'}, eval("g:test_clip['*']"))
  378. -- "+ shouldn't have changed
  379. eq({''}, eval("g:test_clip['+']"))
  380. feed_command("let g:test_clip['*'] = ['linewise stuff','']")
  381. feed('p')
  382. expect([[
  383. words
  384. linewise stuff]])
  385. end)
  386. it('does not clobber "0 when pasting', function()
  387. insert('a line')
  388. feed('yy')
  389. feed_command("let g:test_clip['*'] = ['b line','']")
  390. feed('"0pp"0p')
  391. expect([[
  392. a line
  393. a line
  394. b line
  395. a line]])
  396. end)
  397. it('supports v:register and getreg() without parameters', function()
  398. eq('*', eval('v:register'))
  399. feed_command("let g:test_clip['*'] = [['some block',''], 'b']")
  400. eq('some block', eval('getreg()'))
  401. eq('\02210', eval('getregtype()'))
  402. end)
  403. it('yanks visual selection when pasting', function()
  404. insert("indeed visual")
  405. feed_command("let g:test_clip['*'] = [['clipboard'], 'c']")
  406. feed("viwp")
  407. eq({{'visual'}, 'v'}, eval("g:test_clip['*']"))
  408. expect("indeed clipboard")
  409. -- explicit "* should do the same
  410. feed_command("let g:test_clip['*'] = [['star'], 'c']")
  411. feed('viw"*p')
  412. eq({{'clipboard'}, 'v'}, eval("g:test_clip['*']"))
  413. expect("indeed star")
  414. end)
  415. it('unamed operations work even if the provider fails', function()
  416. insert('the text')
  417. feed('yy')
  418. feed_command("let g:cliperror = 1")
  419. feed('p')
  420. expect([[
  421. the text
  422. the text]])
  423. end)
  424. it('is updated on global changes', function()
  425. insert([[
  426. text
  427. match
  428. match
  429. text
  430. ]])
  431. feed_command('g/match/d')
  432. eq('match\n', eval('getreg("*")'))
  433. feed('u')
  434. eval('setreg("*", "---")')
  435. feed_command('g/test/')
  436. feed('<esc>')
  437. eq('---', eval('getreg("*")'))
  438. end)
  439. it('works in the cmdline window', function()
  440. feed('q:itext<esc>yy')
  441. eq({{'text', ''}, 'V'}, eval("g:test_clip['*']"))
  442. command("let g:test_clip['*'] = [['star'], 'c']")
  443. feed('p')
  444. eq('textstar', meths.get_current_line())
  445. end)
  446. it('Block paste works currectly', function()
  447. insert([[
  448. aabbcc
  449. ddeeff
  450. ]])
  451. feed('gg^<C-v>') -- Goto start of top line enter visual block mode
  452. feed('3ljy^k') -- yank 4x2 block & goto initial location
  453. feed('P') -- Paste it infront
  454. expect([[
  455. aabbaabbcc
  456. ddeeddeeff
  457. ]])
  458. end)
  459. end)
  460. describe('clipboard=unnamedplus', function()
  461. before_each(function()
  462. feed_command('set clipboard=unnamedplus')
  463. end)
  464. it('links the "+ and unnamed registers', function()
  465. eq('+', eval('v:register'))
  466. insert("one two")
  467. feed('^"+dwdw"+P')
  468. expect('two')
  469. eq({{'two'}, 'v'}, eval("g:test_clip['+']"))
  470. -- "* shouldn't have changed
  471. eq({''}, eval("g:test_clip['*']"))
  472. feed_command("let g:test_clip['+'] = ['three']")
  473. feed('p')
  474. expect('twothree')
  475. end)
  476. it('and unnamed, yanks to both', function()
  477. feed_command('set clipboard=unnamedplus,unnamed')
  478. insert([[
  479. really unnamed
  480. text]])
  481. feed('ggdd"*p"+p')
  482. expect([[
  483. text
  484. really unnamed
  485. really unnamed]])
  486. eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['+']"))
  487. eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['*']"))
  488. -- unnamedplus takes predecence when pasting
  489. eq('+', eval('v:register'))
  490. feed_command("let g:test_clip['+'] = ['the plus','']")
  491. feed_command("let g:test_clip['*'] = ['the star','']")
  492. feed("p")
  493. expect([[
  494. text
  495. really unnamed
  496. really unnamed
  497. the plus]])
  498. end)
  499. it('is updated on global changes', function()
  500. insert([[
  501. text
  502. match
  503. match
  504. text
  505. ]])
  506. feed_command('g/match/d')
  507. eq('match\n', eval('getreg("+")'))
  508. feed('u')
  509. eval('setreg("+", "---")')
  510. feed_command('g/test/')
  511. feed('<esc>')
  512. eq('---', eval('getreg("+")'))
  513. end)
  514. end)
  515. it('sets v:register after startup', function()
  516. reset()
  517. eq('"', eval('v:register'))
  518. reset('--cmd', 'set clipboard=unnamed')
  519. eq('*', eval('v:register'))
  520. end)
  521. it('supports :put', function()
  522. insert("a line")
  523. feed_command("let g:test_clip['*'] = ['some text']")
  524. feed_command("let g:test_clip['+'] = ['more', 'text', '']")
  525. feed_command(":put *")
  526. expect([[
  527. a line
  528. some text]])
  529. feed_command(":put +")
  530. expect([[
  531. a line
  532. some text
  533. more
  534. text]])
  535. end)
  536. it('supports "+ and "* in registers', function()
  537. local screen = Screen.new(60, 10)
  538. screen:attach()
  539. feed_command("let g:test_clip['*'] = ['some', 'star data','']")
  540. feed_command("let g:test_clip['+'] = ['such', 'plus', 'stuff']")
  541. feed_command("registers")
  542. screen:expect([[
  543. |
  544. {0:~ }|
  545. {0:~ }|
  546. {4: }|
  547. :registers |
  548. {1:Type Name Content} |
  549. l "* some{2:^J}star data{2:^J} |
  550. c "+ such{2:^J}plus{2:^J}stuff |
  551. c ": let g:test_clip['+'] = ['such', 'plus', 'stuff'] |
  552. {3:Press ENTER or type command to continue}^ |
  553. ]], {
  554. [0] = {bold = true, foreground = Screen.colors.Blue},
  555. [1] = {bold = true, foreground = Screen.colors.Fuchsia},
  556. [2] = {foreground = Screen.colors.Blue},
  557. [3] = {bold = true, foreground = Screen.colors.SeaGreen},
  558. [4] = {bold = true, reverse = true}})
  559. feed('<cr>') -- clear out of Press ENTER screen
  560. end)
  561. it('can paste "* to the commandline', function()
  562. insert('s/s/t/')
  563. feed('gg"*y$:<c-r>*<cr>')
  564. expect('t/s/t/')
  565. feed_command("let g:test_clip['*'] = ['s/s/u']")
  566. feed(':<c-r>*<cr>')
  567. expect('t/u/t/')
  568. end)
  569. it('supports :redir @*>', function()
  570. feed_command("let g:test_clip['*'] = ['stuff']")
  571. feed_command('redir @*>')
  572. -- it is made empty
  573. eq({{''}, 'v'}, eval("g:test_clip['*']"))
  574. feed_command('let g:test = doesnotexist')
  575. feed('<cr>')
  576. eq({{
  577. '',
  578. '',
  579. 'E121: Undefined variable: doesnotexist',
  580. 'E15: Invalid expression: doesnotexist',
  581. }, 'v'}, eval("g:test_clip['*']"))
  582. feed_command(':echo "Howdy!"')
  583. eq({{
  584. '',
  585. '',
  586. 'E121: Undefined variable: doesnotexist',
  587. 'E15: Invalid expression: doesnotexist',
  588. '',
  589. 'Howdy!',
  590. }, 'v'}, eval("g:test_clip['*']"))
  591. end)
  592. it('handles middleclick correctly', function()
  593. feed_command('set mouse=a')
  594. local screen = Screen.new(30, 5)
  595. screen:set_default_attr_ids({
  596. [0] = {bold = true, foreground = Screen.colors.Blue},
  597. })
  598. screen:attach()
  599. insert([[
  600. the source
  601. a target]])
  602. feed('gg"*ywwyw')
  603. -- clicking depends on the exact visual layout, so expect it:
  604. screen:expect([[
  605. the ^source |
  606. a target |
  607. {0:~ }|
  608. {0:~ }|
  609. |
  610. ]])
  611. feed('<MiddleMouse><0,1>')
  612. expect([[
  613. the source
  614. the a target]])
  615. -- on error, fall back to unnamed register
  616. feed_command("let g:cliperror = 1")
  617. feed('<MiddleMouse><6,1>')
  618. expect([[
  619. the source
  620. the a sourcetarget]])
  621. end)
  622. it('setreg("*") with clipboard=unnamed #5646', function()
  623. source([=[
  624. function! Paste_without_yank(direction) range
  625. let [reg_save,regtype_save] = [getreg('*'), getregtype('*')]
  626. normal! gvp
  627. call setreg('*', reg_save, regtype_save)
  628. endfunction
  629. xnoremap p :call Paste_without_yank('p')<CR>
  630. set clipboard=unnamed
  631. ]=])
  632. insert('some words')
  633. feed('gg0yiw')
  634. feed('wviwp')
  635. expect('some some')
  636. eq('some', eval('getreg("*")'))
  637. end)
  638. end)