cursor_spec.lua 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local Screen = require('test.functional.ui.screen')
  3. local clear, meths = helpers.clear, helpers.meths
  4. local eq = helpers.eq
  5. local command = helpers.command
  6. describe('ui/cursor', function()
  7. local screen
  8. before_each(function()
  9. clear()
  10. screen = Screen.new(25, 5)
  11. screen:attach()
  12. end)
  13. after_each(function()
  14. screen:detach()
  15. end)
  16. it("'guicursor' is published as a UI event", function()
  17. local expected_mode_info = {
  18. [1] = {
  19. blinkoff = 0,
  20. blinkon = 0,
  21. blinkwait = 0,
  22. cell_percentage = 0,
  23. cursor_shape = 'block',
  24. name = 'normal',
  25. hl_id = 0,
  26. id_lm = 0,
  27. attr = {},
  28. attr_lm = {},
  29. mouse_shape = 0,
  30. short_name = 'n' },
  31. [2] = {
  32. blinkoff = 0,
  33. blinkon = 0,
  34. blinkwait = 0,
  35. cell_percentage = 0,
  36. cursor_shape = 'block',
  37. name = 'visual',
  38. hl_id = 0,
  39. id_lm = 0,
  40. attr = {},
  41. attr_lm = {},
  42. mouse_shape = 0,
  43. short_name = 'v' },
  44. [3] = {
  45. blinkoff = 0,
  46. blinkon = 0,
  47. blinkwait = 0,
  48. cell_percentage = 25,
  49. cursor_shape = 'vertical',
  50. name = 'insert',
  51. hl_id = 0,
  52. id_lm = 0,
  53. attr = {},
  54. attr_lm = {},
  55. mouse_shape = 0,
  56. short_name = 'i' },
  57. [4] = {
  58. blinkoff = 0,
  59. blinkon = 0,
  60. blinkwait = 0,
  61. cell_percentage = 20,
  62. cursor_shape = 'horizontal',
  63. name = 'replace',
  64. hl_id = 0,
  65. id_lm = 0,
  66. attr = {},
  67. attr_lm = {},
  68. mouse_shape = 0,
  69. short_name = 'r' },
  70. [5] = {
  71. blinkoff = 0,
  72. blinkon = 0,
  73. blinkwait = 0,
  74. cell_percentage = 0,
  75. cursor_shape = 'block',
  76. name = 'cmdline_normal',
  77. hl_id = 0,
  78. id_lm = 0,
  79. attr = {},
  80. attr_lm = {},
  81. mouse_shape = 0,
  82. short_name = 'c' },
  83. [6] = {
  84. blinkoff = 0,
  85. blinkon = 0,
  86. blinkwait = 0,
  87. cell_percentage = 25,
  88. cursor_shape = 'vertical',
  89. name = 'cmdline_insert',
  90. hl_id = 0,
  91. id_lm = 0,
  92. attr = {},
  93. attr_lm = {},
  94. mouse_shape = 0,
  95. short_name = 'ci' },
  96. [7] = {
  97. blinkoff = 0,
  98. blinkon = 0,
  99. blinkwait = 0,
  100. cell_percentage = 20,
  101. cursor_shape = 'horizontal',
  102. name = 'cmdline_replace',
  103. hl_id = 0,
  104. id_lm = 0,
  105. attr = {},
  106. attr_lm = {},
  107. mouse_shape = 0,
  108. short_name = 'cr' },
  109. [8] = {
  110. blinkoff = 0,
  111. blinkon = 0,
  112. blinkwait = 0,
  113. cell_percentage = 20,
  114. cursor_shape = 'horizontal',
  115. name = 'operator',
  116. hl_id = 0,
  117. id_lm = 0,
  118. attr = {},
  119. attr_lm = {},
  120. mouse_shape = 0,
  121. short_name = 'o' },
  122. [9] = {
  123. blinkoff = 0,
  124. blinkon = 0,
  125. blinkwait = 0,
  126. cell_percentage = 25,
  127. cursor_shape = 'vertical',
  128. name = 'visual_select',
  129. hl_id = 0,
  130. id_lm = 0,
  131. attr = {},
  132. attr_lm = {},
  133. mouse_shape = 0,
  134. short_name = 've' },
  135. [10] = {
  136. name = 'cmdline_hover',
  137. mouse_shape = 0,
  138. short_name = 'e' },
  139. [11] = {
  140. name = 'statusline_hover',
  141. mouse_shape = 0,
  142. short_name = 's' },
  143. [12] = {
  144. name = 'statusline_drag',
  145. mouse_shape = 0,
  146. short_name = 'sd' },
  147. [13] = {
  148. name = 'vsep_hover',
  149. mouse_shape = 0,
  150. short_name = 'vs' },
  151. [14] = {
  152. name = 'vsep_drag',
  153. mouse_shape = 0,
  154. short_name = 'vd' },
  155. [15] = {
  156. name = 'more',
  157. mouse_shape = 0,
  158. short_name = 'm' },
  159. [16] = {
  160. name = 'more_lastline',
  161. mouse_shape = 0,
  162. short_name = 'ml' },
  163. [17] = {
  164. blinkoff = 0,
  165. blinkon = 0,
  166. blinkwait = 0,
  167. cell_percentage = 0,
  168. cursor_shape = 'block',
  169. name = 'showmatch',
  170. hl_id = 0,
  171. id_lm = 0,
  172. attr = {},
  173. attr_lm = {},
  174. short_name = 'sm' },
  175. }
  176. screen:expect(function()
  177. -- Default 'guicursor', published on startup.
  178. eq(expected_mode_info, screen._mode_info)
  179. eq(true, screen._cursor_style_enabled)
  180. eq('normal', screen.mode)
  181. end)
  182. -- Event is published ONLY if the cursor style changed.
  183. screen._mode_info = nil
  184. command("echo 'test'")
  185. screen:expect{grid=[[
  186. ^ |
  187. ~ |
  188. ~ |
  189. ~ |
  190. test |
  191. ]], condition=function()
  192. eq(nil, screen._mode_info)
  193. end}
  194. -- Change the cursor style.
  195. helpers.command('hi Cursor guibg=DarkGray')
  196. helpers.command('set guicursor=n-v-c:block,i-ci-ve:ver25,r-cr-o:hor20'
  197. ..',a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor'
  198. ..',sm:block-blinkwait175-blinkoff150-blinkon175')
  199. -- Update the expected values.
  200. for _, m in ipairs(expected_mode_info) do
  201. if m.name == 'showmatch' then
  202. if m.blinkon then m.blinkon = 175 end
  203. if m.blinkoff then m.blinkoff = 150 end
  204. if m.blinkwait then m.blinkwait = 175 end
  205. else
  206. if m.blinkon then m.blinkon = 250 end
  207. if m.blinkoff then m.blinkoff = 400 end
  208. if m.blinkwait then m.blinkwait = 700 end
  209. end
  210. if m.hl_id then
  211. m.hl_id = 49
  212. m.attr = {background = Screen.colors.DarkGray}
  213. end
  214. if m.id_lm then m.id_lm = 50 end
  215. end
  216. -- Assert the new expectation.
  217. screen:expect(function()
  218. eq(expected_mode_info, screen._mode_info)
  219. eq(true, screen._cursor_style_enabled)
  220. eq('normal', screen.mode)
  221. end)
  222. -- Change hl groups only, should update the styles
  223. helpers.command('hi Cursor guibg=Red')
  224. helpers.command('hi lCursor guibg=Green')
  225. -- Update the expected values.
  226. for _, m in ipairs(expected_mode_info) do
  227. if m.hl_id then
  228. m.attr = {background = Screen.colors.Red}
  229. end
  230. if m.id_lm then
  231. m.attr_lm = {background = Screen.colors.Green}
  232. end
  233. end
  234. -- Assert the new expectation.
  235. screen:expect(function()
  236. eq(expected_mode_info, screen._mode_info)
  237. eq(true, screen._cursor_style_enabled)
  238. eq('normal', screen.mode)
  239. end)
  240. -- Another cursor style.
  241. meths.set_option('guicursor', 'n-v-c:ver35-blinkwait171-blinkoff172-blinkon173'
  242. ..',ve:hor35,o:ver50,i-ci:block,r-cr:hor90,sm:ver42')
  243. screen:expect(function()
  244. local named = {}
  245. for _, m in ipairs(screen._mode_info) do
  246. named[m.name] = m
  247. end
  248. eq('vertical', named.normal.cursor_shape)
  249. eq(35, named.normal.cell_percentage)
  250. eq('horizontal', named.visual_select.cursor_shape)
  251. eq(35, named.visual_select.cell_percentage)
  252. eq('vertical', named.operator.cursor_shape)
  253. eq(50, named.operator.cell_percentage)
  254. eq('block', named.insert.cursor_shape)
  255. eq('vertical', named.showmatch.cursor_shape)
  256. eq(90, named.cmdline_replace.cell_percentage)
  257. eq(171, named.normal.blinkwait)
  258. eq(172, named.normal.blinkoff)
  259. eq(173, named.normal.blinkon)
  260. eq(42, named.showmatch.cell_percentage)
  261. end)
  262. end)
  263. it("empty 'guicursor' sets cursor_shape=block in all modes", function()
  264. meths.set_option('guicursor', '')
  265. screen:expect(function()
  266. -- Empty 'guicursor' sets enabled=false.
  267. eq(false, screen._cursor_style_enabled)
  268. for _, m in ipairs(screen._mode_info) do
  269. if m['cursor_shape'] ~= nil then
  270. eq('block', m.cursor_shape)
  271. eq(0, m.blinkon)
  272. end
  273. end
  274. end)
  275. end)
  276. end)