searchhl_spec.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local Screen = require('test.functional.ui.screen')
  3. local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
  4. local command = helpers.command
  5. local feed_command = helpers.feed_command
  6. local eq = helpers.eq
  7. local eval = helpers.eval
  8. local iswin = helpers.iswin
  9. local sleep = helpers.sleep
  10. describe('search highlighting', function()
  11. local screen
  12. local colors = Screen.colors
  13. before_each(function()
  14. clear()
  15. screen = Screen.new(40, 7)
  16. screen:attach()
  17. screen:set_default_attr_ids( {
  18. [1] = {bold=true, foreground=Screen.colors.Blue},
  19. [2] = {background = colors.Yellow}, -- Search
  20. [3] = {reverse = true},
  21. [4] = {foreground = colors.Red}, -- Message
  22. })
  23. end)
  24. it('is disabled by ":set nohlsearch"', function()
  25. feed_command('set nohlsearch')
  26. insert("some text\nmore text")
  27. feed("gg/text<cr>")
  28. screen:expect([[
  29. some ^text |
  30. more text |
  31. {1:~ }|
  32. {1:~ }|
  33. {1:~ }|
  34. {1:~ }|
  35. /text |
  36. ]])
  37. end)
  38. it('works', function()
  39. insert([[
  40. some text
  41. more textstuff
  42. stupidtexttextstuff
  43. a text word
  44. ]])
  45. -- 'hlsearch' is enabled by default. #2859
  46. feed("gg/text<cr>")
  47. screen:expect([[
  48. some {2:^text} |
  49. more {2:text}stuff |
  50. stupid{2:texttext}stuff |
  51. a {2:text} word |
  52. |
  53. {1:~ }|
  54. /text |
  55. ]])
  56. -- overlapping matches not allowed
  57. feed("3nx")
  58. screen:expect([[
  59. some {2:text} |
  60. more {2:text}stuff |
  61. stupid{2:text}^extstuff |
  62. a {2:text} word |
  63. |
  64. {1:~ }|
  65. /text |
  66. ]])
  67. feed("ggn*") -- search for entire word
  68. screen:expect([[
  69. some {2:text} |
  70. more textstuff |
  71. stupidtextextstuff |
  72. a {2:^text} word |
  73. |
  74. {1:~ }|
  75. /\<text\> |
  76. ]])
  77. feed_command("nohlsearch")
  78. screen:expect([[
  79. some text |
  80. more textstuff |
  81. stupidtextextstuff |
  82. a ^text word |
  83. |
  84. {1:~ }|
  85. :nohlsearch |
  86. ]])
  87. end)
  88. it('highlights after EOL', function()
  89. insert("\n\n\n\n\n\n")
  90. feed("gg/^<cr>")
  91. screen:expect([[
  92. {2: } |
  93. {2:^ } |
  94. {2: } |
  95. {2: } |
  96. {2: } |
  97. {2: } |
  98. /^ |
  99. ]])
  100. -- Test that highlights are preserved after moving the cursor.
  101. feed("j")
  102. screen:expect([[
  103. {2: } |
  104. {2: } |
  105. {2:^ } |
  106. {2: } |
  107. {2: } |
  108. {2: } |
  109. /^ |
  110. ]])
  111. -- Repeat the test in rightleft mode.
  112. command("nohlsearch")
  113. command("set rightleft")
  114. feed("gg/^<cr>")
  115. screen:expect([[
  116. {2: }|
  117. {2:^ }|
  118. {2: }|
  119. {2: }|
  120. {2: }|
  121. {2: }|
  122. ^/ |
  123. ]])
  124. feed("j")
  125. screen:expect([[
  126. {2: }|
  127. {2: }|
  128. {2:^ }|
  129. {2: }|
  130. {2: }|
  131. {2: }|
  132. ^/ |
  133. ]])
  134. end)
  135. it('is preserved during :terminal activity', function()
  136. if iswin() then
  137. feed([[:terminal for /L \%I in (1,1,5000) do @(echo xxx & echo xxx & echo xxx)<cr>]])
  138. else
  139. feed([[:terminal for i in $(seq 1 5000); do printf 'xxx\nxxx\nxxx\n'; done<cr>]])
  140. end
  141. feed(':file term<CR>')
  142. feed(':vnew<CR>')
  143. insert([[
  144. foo bar baz
  145. bar baz foo
  146. bar foo baz
  147. ]])
  148. feed('/foo')
  149. sleep(50) -- Allow some terminal activity.
  150. screen:expect([[
  151. {3:foo} bar baz {3:│}xxx |
  152. bar baz {2:foo} {3:│}xxx |
  153. bar {2:foo} baz {3:│}xxx |
  154. {3:│}xxx |
  155. {1:~ }{3:│}xxx |
  156. {5:[No Name] [+] }{3:term }|
  157. /foo^ |
  158. ]], { [1] = {bold = true, foreground = Screen.colors.Blue1},
  159. [2] = {background = Screen.colors.Yellow},
  160. [3] = {reverse = true},
  161. [4] = {foreground = Screen.colors.Red},
  162. [5] = {bold = true, reverse = true},
  163. })
  164. end)
  165. it('works with incsearch', function()
  166. feed_command('set hlsearch')
  167. feed_command('set incsearch')
  168. insert([[
  169. the first line
  170. in a little file
  171. ]])
  172. feed("gg/li")
  173. screen:expect([[
  174. the first {3:li}ne |
  175. in a {2:li}ttle file |
  176. |
  177. {1:~ }|
  178. {1:~ }|
  179. {1:~ }|
  180. /li^ |
  181. ]])
  182. -- check that consecutive matches are caught by C-g/C-t
  183. feed("<C-g>")
  184. screen:expect([[
  185. the first {2:li}ne |
  186. in a {3:li}ttle file |
  187. |
  188. {1:~ }|
  189. {1:~ }|
  190. {1:~ }|
  191. /li^ |
  192. ]])
  193. feed("<C-t>")
  194. screen:expect([[
  195. the first {3:li}ne |
  196. in a {2:li}ttle file |
  197. |
  198. {1:~ }|
  199. {1:~ }|
  200. {1:~ }|
  201. /li^ |
  202. ]])
  203. feed("t")
  204. screen:expect([[
  205. the first line |
  206. in a {3:lit}tle file |
  207. |
  208. {1:~ }|
  209. {1:~ }|
  210. {1:~ }|
  211. /lit^ |
  212. ]])
  213. feed("<cr>")
  214. screen:expect([[
  215. the first line |
  216. in a {2:^lit}tle file |
  217. |
  218. {1:~ }|
  219. {1:~ }|
  220. {1:~ }|
  221. /lit |
  222. ]])
  223. feed("/fir")
  224. screen:expect([[
  225. the {3:fir}st line |
  226. in a little file |
  227. |
  228. {1:~ }|
  229. {1:~ }|
  230. {1:~ }|
  231. /fir^ |
  232. ]])
  233. -- incsearch have priority over hlsearch
  234. feed("<esc>/ttle")
  235. screen:expect([[
  236. the first line |
  237. in a li{3:ttle} file |
  238. |
  239. {1:~ }|
  240. {1:~ }|
  241. {1:~ }|
  242. /ttle^ |
  243. ]])
  244. -- cancelling search resets to the old search term
  245. feed('<esc>')
  246. screen:expect([[
  247. the first line |
  248. in a {2:^lit}tle file |
  249. |
  250. {1:~ }|
  251. {1:~ }|
  252. {1:~ }|
  253. |
  254. ]])
  255. eq('lit', eval('@/'))
  256. -- cancelling inc search restores the hl state
  257. feed(':noh<cr>')
  258. screen:expect([[
  259. the first line |
  260. in a ^little file |
  261. |
  262. {1:~ }|
  263. {1:~ }|
  264. {1:~ }|
  265. :noh |
  266. ]])
  267. feed('/first')
  268. screen:expect([[
  269. the {3:first} line |
  270. in a little file |
  271. |
  272. {1:~ }|
  273. {1:~ }|
  274. {1:~ }|
  275. /first^ |
  276. ]])
  277. feed('<esc>')
  278. screen:expect([[
  279. the first line |
  280. in a ^little file |
  281. |
  282. {1:~ }|
  283. {1:~ }|
  284. {1:~ }|
  285. |
  286. ]])
  287. -- test that pressing C-g in an empty command line does not move the cursor
  288. feed('/<C-g>')
  289. screen:expect([[
  290. the first line |
  291. in a little file |
  292. |
  293. {1:~ }|
  294. {1:~ }|
  295. {1:~ }|
  296. /^ |
  297. ]])
  298. -- same, for C-t
  299. feed('<ESC>')
  300. screen:expect([[
  301. the first line |
  302. in a ^little file |
  303. |
  304. {1:~ }|
  305. {1:~ }|
  306. {1:~ }|
  307. |
  308. ]])
  309. feed('/<C-t>')
  310. screen:expect([[
  311. the first line |
  312. in a little file |
  313. |
  314. {1:~ }|
  315. {1:~ }|
  316. {1:~ }|
  317. /^ |
  318. ]])
  319. -- 8.0.1304, test that C-g and C-t works with incsearch and empty pattern
  320. feed('<esc>/fi<CR>')
  321. feed('//')
  322. screen:expect([[
  323. the {3:fi}rst line |
  324. in a little {2:fi}le |
  325. |
  326. {1:~ }|
  327. {1:~ }|
  328. {1:~ }|
  329. //^ |
  330. ]])
  331. feed('<C-g>')
  332. screen:expect([[
  333. the {2:fi}rst line |
  334. in a little {3:fi}le |
  335. |
  336. {1:~ }|
  337. {1:~ }|
  338. {1:~ }|
  339. //^ |
  340. ]])
  341. end)
  342. it('works with incsearch and offset', function()
  343. feed_command('set hlsearch')
  344. feed_command('set incsearch')
  345. insert([[
  346. not the match you're looking for
  347. the match is here]])
  348. feed("gg/mat/e")
  349. screen:expect([[
  350. not the {3:mat}ch you're looking for |
  351. the {2:mat}ch is here |
  352. {1:~ }|
  353. {1:~ }|
  354. {1:~ }|
  355. {1:~ }|
  356. /mat/e^ |
  357. ]])
  358. -- Search with count and /e offset fixed in Vim patch 7.4.532.
  359. feed("<esc>2/mat/e")
  360. screen:expect([[
  361. not the {2:mat}ch you're looking for |
  362. the {3:mat}ch is here |
  363. {1:~ }|
  364. {1:~ }|
  365. {1:~ }|
  366. {1:~ }|
  367. /mat/e^ |
  368. ]])
  369. feed("<cr>")
  370. screen:expect([[
  371. not the {2:mat}ch you're looking for |
  372. the {2:ma^t}ch is here |
  373. {1:~ }|
  374. {1:~ }|
  375. {1:~ }|
  376. {1:~ }|
  377. /mat/e |
  378. ]])
  379. end)
  380. it('works with multiline regexps', function()
  381. feed_command('set hlsearch')
  382. feed('4oa repeated line<esc>')
  383. feed('/line\\na<cr>')
  384. screen:expect([[
  385. |
  386. a repeated {2:^line} |
  387. {2:a} repeated {2:line} |
  388. {2:a} repeated {2:line} |
  389. {2:a} repeated line |
  390. {1:~ }|
  391. {4:search hit BOTTOM, continuing at TOP} |
  392. ]])
  393. -- it redraws rows above the changed one
  394. feed('4Grb')
  395. screen:expect([[
  396. |
  397. a repeated {2:line} |
  398. {2:a} repeated line |
  399. ^b repeated {2:line} |
  400. {2:a} repeated line |
  401. {1:~ }|
  402. {4:search hit BOTTOM, continuing at TOP} |
  403. ]])
  404. end)
  405. it('works with matchadd and syntax', function()
  406. screen:set_default_attr_ids( {
  407. [1] = {bold=true, foreground=Screen.colors.Blue},
  408. [2] = {background = colors.Yellow},
  409. [3] = {reverse = true},
  410. [4] = {foreground = colors.Red},
  411. [5] = {bold = true, background = colors.Green},
  412. [6] = {italic = true, background = colors.Magenta},
  413. [7] = {bold = true, background = colors.Yellow},
  414. } )
  415. feed_command('set hlsearch')
  416. insert([[
  417. very special text
  418. ]])
  419. feed_command("syntax on")
  420. feed_command("highlight MyGroup guibg=Green gui=bold")
  421. feed_command("highlight MyGroup2 guibg=Magenta gui=italic")
  422. feed_command("call matchadd('MyGroup', 'special')")
  423. feed_command("call matchadd('MyGroup2', 'text', 0)")
  424. -- searchhl and matchadd matches are exclusive, only the higest priority
  425. -- is used (and matches with lower priorities are not combined)
  426. feed_command("/ial te")
  427. screen:expect([[
  428. very {5:spec^ial}{2: te}{6:xt} |
  429. |
  430. {1:~ }|
  431. {1:~ }|
  432. {1:~ }|
  433. {1:~ }|
  434. {4:search hit BOTTOM, continuing at TOP} |
  435. ]])
  436. feed_command("call clearmatches()")
  437. screen:expect([[
  438. very spec{2:^ial te}xt |
  439. |
  440. {1:~ }|
  441. {1:~ }|
  442. {1:~ }|
  443. {1:~ }|
  444. :call clearmatches() |
  445. ]])
  446. -- searchhl has priority over syntax, but in this case
  447. -- nonconflicting attributes are combined
  448. feed_command("syntax keyword MyGroup special")
  449. screen:expect([[
  450. very {5:spec}{7:^ial}{2: te}xt |
  451. |
  452. {1:~ }|
  453. {1:~ }|
  454. {1:~ }|
  455. {1:~ }|
  456. :syntax keyword MyGroup special |
  457. ]])
  458. end)
  459. end)