test_indent.vim 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. " Test for various indent options
  2. source shared.vim
  3. source check.vim
  4. func Test_preserveindent()
  5. new
  6. " Test for autoindent copying indent from the previous line
  7. setlocal autoindent
  8. call setline(1, [repeat(' ', 16) .. 'line1'])
  9. call feedkeys("A\nline2", 'xt')
  10. call assert_equal("\t\tline2", getline(2))
  11. setlocal autoindent&
  12. " Test for using CTRL-T with and without 'preserveindent'
  13. set shiftwidth=4
  14. call cursor(1, 1)
  15. call setline(1, " \t ")
  16. call feedkeys("Al\<C-T>", 'xt')
  17. call assert_equal("\t\tl", getline(1))
  18. set preserveindent
  19. call setline(1, " \t ")
  20. call feedkeys("Al\<C-T>", 'xt')
  21. call assert_equal(" \t \tl", getline(1))
  22. set pi& sw&
  23. " Test for using CTRL-T with 'expandtab' and 'preserveindent'
  24. call cursor(1, 1)
  25. call setline(1, "\t \t")
  26. set shiftwidth=4 expandtab preserveindent
  27. call feedkeys("Al\<C-T>", 'xt')
  28. call assert_equal("\t \t l", getline(1))
  29. set sw& et& pi&
  30. close!
  31. endfunc
  32. " Test for indent()
  33. func Test_indent_func()
  34. call assert_equal(-1, indent(-1))
  35. new
  36. call setline(1, "\tabc")
  37. call assert_equal(8, indent(1))
  38. call setline(1, " abc")
  39. call assert_equal(4, indent(1))
  40. call setline(1, " \t abc")
  41. call assert_equal(12, indent(1))
  42. close!
  43. endfunc
  44. " Test for reindenting a line using the '=' operator
  45. func Test_reindent()
  46. new
  47. call setline(1, 'abc')
  48. set nomodifiable
  49. call assert_fails('normal ==', 'E21:')
  50. set modifiable
  51. call setline(1, ['foo', 'bar'])
  52. call feedkeys('ggVG=', 'xt')
  53. call assert_equal(['foo', 'bar'], getline(1, 2))
  54. close!
  55. endfunc
  56. " Test indent operator creating one undo entry
  57. func Test_indent_operator_undo()
  58. enew
  59. call setline(1, range(12)->map('"\t" .. v:val'))
  60. func FoldExpr()
  61. let g:foldcount += 1
  62. return '='
  63. endfunc
  64. set foldmethod=expr foldexpr=FoldExpr()
  65. let g:foldcount = 0
  66. redraw
  67. call assert_equal(12, g:foldcount)
  68. normal gg=G
  69. call assert_equal(24, g:foldcount)
  70. undo
  71. call assert_equal(38, g:foldcount)
  72. bwipe!
  73. set foldmethod& foldexpr=
  74. delfunc FoldExpr
  75. unlet g:foldcount
  76. endfunc
  77. " Test for shifting a line with a preprocessor directive ('#')
  78. func Test_preproc_indent()
  79. new
  80. set sw=4
  81. call setline(1, '#define FOO 1')
  82. normal >>
  83. call assert_equal(' #define FOO 1', getline(1))
  84. " with 'smartindent'
  85. call setline(1, '#define FOO 1')
  86. set smartindent
  87. normal >>
  88. call assert_equal('#define FOO 1', getline(1))
  89. set smartindent&
  90. " with 'cindent'
  91. set cindent
  92. normal >>
  93. call assert_equal('#define FOO 1', getline(1))
  94. set cindent&
  95. close!
  96. endfunc
  97. func Test_userlabel_indent()
  98. new
  99. call setline(1, ['{', 'label:'])
  100. normal GV=
  101. call assert_equal('label:', getline(2))
  102. call setline(2, 'läbél:')
  103. normal GV=
  104. call assert_equal('läbél:', getline(2))
  105. close!
  106. endfunc
  107. " Test for 'copyindent'
  108. func Test_copyindent()
  109. new
  110. set shiftwidth=4 autoindent expandtab copyindent
  111. call setline(1, " \t abc")
  112. call feedkeys("ol", 'xt')
  113. call assert_equal(" \t l", getline(2))
  114. set noexpandtab
  115. call setline(1, " \t abc")
  116. call feedkeys("ol", 'xt')
  117. call assert_equal(" \t l", getline(2))
  118. set sw& ai& et& ci&
  119. close!
  120. endfunc
  121. " Test for changing multiple lines with lisp indent
  122. func Test_lisp_indent_change_multiline()
  123. new
  124. setlocal lisp autoindent
  125. call setline(1, ['(if a', ' (if b', ' (return 5)))'])
  126. normal! jc2j(return 4))
  127. call assert_equal(' (return 4))', getline(2))
  128. close!
  129. endfunc
  130. func Test_lisp_indent()
  131. new
  132. setlocal lisp autoindent
  133. call setline(1, ['(if a', ' ;; comment', ' \ abc', '', ' " str1\', ' " st\b', ' (return 5)'])
  134. normal! jo;; comment
  135. normal! jo\ abc
  136. normal! jo;; ret
  137. normal! jostr1"
  138. normal! jostr2"
  139. call assert_equal([' ;; comment', ' ;; comment', ' \ abc', ' \ abc', '', ' ;; ret', ' " str1\', ' str1"', ' " st\b', ' str2"'], getline(2, 11))
  140. close!
  141. endfunc
  142. func Test_lisp_indent_quoted()
  143. " This was going past the end of the line
  144. new
  145. setlocal lisp autoindent
  146. call setline(1, ['"[', '='])
  147. normal Gvk=
  148. bwipe!
  149. endfunc
  150. " Test for setting the 'indentexpr' from a modeline
  151. func Test_modeline_indent_expr()
  152. let modeline = &modeline
  153. set modeline
  154. func GetIndent()
  155. return line('.') * 2
  156. endfunc
  157. call writefile(['# vim: indentexpr=GetIndent()'], 'Xfile.txt')
  158. set modelineexpr
  159. new Xfile.txt
  160. call assert_equal('GetIndent()', &indentexpr)
  161. exe "normal Oa\nb\n"
  162. call assert_equal([' a', ' b'], getline(1, 2))
  163. set modelineexpr&
  164. delfunc GetIndent
  165. let &modeline = modeline
  166. close!
  167. call delete('Xfile.txt')
  168. endfunc
  169. func Test_indent_func_with_gq()
  170. function GetTeXIndent()
  171. " Sample indent expression for TeX files
  172. let lnum = prevnonblank(v:lnum - 1)
  173. " At the start of the file use zero indent.
  174. if lnum == 0
  175. return 0
  176. endif
  177. let line = getline(lnum)
  178. let ind = indent(lnum)
  179. " Add a 'shiftwidth' after beginning of environments.
  180. if line =~ '\\begin{center}'
  181. let ind = ind + shiftwidth()
  182. endif
  183. return ind
  184. endfunction
  185. new
  186. setl et sw=2 sts=2 ts=2 tw=50 indentexpr=GetTeXIndent()
  187. put =[ '\documentclass{article}', '', '\begin{document}', '',
  188. \ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ut enim non',
  189. \ 'libero efficitur aliquet. Maecenas metus justo, facilisis convallis blandit',
  190. \ 'non, semper eu urna. Suspendisse diam diam, iaculis faucibus lorem eu,',
  191. \ 'fringilla condimentum lectus. Quisque euismod diam at convallis vulputate.',
  192. \ 'Pellentesque laoreet tortor sit amet mauris euismod ornare. Sed varius',
  193. \ 'bibendum orci vel vehicula. Pellentesque tempor, ipsum et auctor accumsan,',
  194. \ 'metus lectus ultrices odio, sed elementum mi ante at arcu.', '', '\begin{center}', '',
  195. \ 'Proin nec risus consequat nunc dapibus consectetur. Mauris lacinia est a augue',
  196. \ 'tristique accumsan. Morbi pretium, felis molestie eleifend condimentum, arcu',
  197. \ 'ipsum congue nisl, quis euismod purus libero in ante.', '',
  198. \ 'Donec id semper purus.',
  199. \ 'Suspendisse eget aliquam nunc. Maecenas fringilla mauris vitae maximus',
  200. \ 'condimentum. Cras a quam in mi dictum eleifend at a lorem. Sed convallis',
  201. \ 'ante a commodo facilisis. Nam suscipit vulputate odio, vel dapibus nisl',
  202. \ 'dignissim facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et',
  203. \ 'ultrices posuere cubilia curae;', '', '']
  204. 1d_
  205. call cursor(5, 1)
  206. ka
  207. call cursor(14, 1)
  208. kb
  209. norm! 'agqap
  210. norm! 'bgqG
  211. let expected = [ '\documentclass{article}', '', '\begin{document}', '',
  212. \ 'Lorem ipsum dolor sit amet, consectetur adipiscing',
  213. \ 'elit. Fusce ut enim non libero efficitur aliquet.',
  214. \ 'Maecenas metus justo, facilisis convallis blandit',
  215. \ 'non, semper eu urna. Suspendisse diam diam,',
  216. \ 'iaculis faucibus lorem eu, fringilla condimentum',
  217. \ 'lectus. Quisque euismod diam at convallis',
  218. \ 'vulputate. Pellentesque laoreet tortor sit amet',
  219. \ 'mauris euismod ornare. Sed varius bibendum orci',
  220. \ 'vel vehicula. Pellentesque tempor, ipsum et auctor',
  221. \ 'accumsan, metus lectus ultrices odio, sed',
  222. \ 'elementum mi ante at arcu.', '', '\begin{center}', '',
  223. \ ' Proin nec risus consequat nunc dapibus',
  224. \ ' consectetur. Mauris lacinia est a augue',
  225. \ ' tristique accumsan. Morbi pretium, felis',
  226. \ ' molestie eleifend condimentum, arcu ipsum congue',
  227. \ ' nisl, quis euismod purus libero in ante.',
  228. \ '',
  229. \ ' Donec id semper purus. Suspendisse eget aliquam',
  230. \ ' nunc. Maecenas fringilla mauris vitae maximus',
  231. \ ' condimentum. Cras a quam in mi dictum eleifend',
  232. \ ' at a lorem. Sed convallis ante a commodo',
  233. \ ' facilisis. Nam suscipit vulputate odio, vel',
  234. \ ' dapibus nisl dignissim facilisis. Vestibulum',
  235. \ ' ante ipsum primis in faucibus orci luctus et',
  236. \ ' ultrices posuere cubilia curae;', '', '']
  237. call assert_equal(expected, getline(1, '$'))
  238. bwipe!
  239. delmark ab
  240. delfunction GetTeXIndent
  241. endfu
  242. func Test_formatting_keeps_first_line_indent()
  243. let lines =<< trim END
  244. foo()
  245. {
  246. int x; // manually positioned
  247. // more text that will be formatted
  248. // but not reindented
  249. END
  250. new
  251. call setline(1, lines)
  252. setlocal sw=4 cindent tw=45 et
  253. normal! 4Ggqj
  254. let expected =<< trim END
  255. foo()
  256. {
  257. int x; // manually positioned
  258. // more text that will be
  259. // formatted but not
  260. // reindented
  261. END
  262. call assert_equal(expected, getline(1, '$'))
  263. bwipe!
  264. endfunc
  265. " Test for indenting with large amount, causes overflow
  266. func Test_indent_overflow_count()
  267. throw 'skipped: TODO: '
  268. new
  269. setl sw=8
  270. call setline(1, "abc")
  271. norm! V2147483647>
  272. " indents by INT_MAX
  273. call assert_equal(2147483647, indent(1))
  274. close!
  275. endfunc
  276. func Test_indent_overflow_count2()
  277. throw 'skipped: Nvim does not support 64-bit number options'
  278. new
  279. " this only works, when long is 64bits
  280. try
  281. setl sw=0x180000000
  282. catch /^Vim\%((\a\+)\)\=:E487:/
  283. throw 'Skipped: value negative on this platform'
  284. endtry
  285. call setline(1, "\tabc")
  286. norm! <<
  287. call assert_equal(0, indent(1))
  288. close!
  289. endfunc
  290. " Test that mouse shape is restored to Normal mode after using "gq" when
  291. " 'indentexpr' executes :normal.
  292. func Test_mouse_shape_indent_norm_with_gq()
  293. CheckFeature mouseshape
  294. CheckCanRunGui
  295. let lines =<< trim END
  296. func Indent()
  297. exe "normal! \<Ignore>"
  298. return 0
  299. endfunc
  300. setlocal indentexpr=Indent()
  301. END
  302. call writefile(lines, 'Xindentexpr.vim', 'D')
  303. let lines =<< trim END
  304. vim9script
  305. var mouse_shapes = []
  306. setline(1, [repeat('a', 80), repeat('b', 80)])
  307. feedkeys('ggVG')
  308. timer_start(50, (_) => {
  309. mouse_shapes += [getmouseshape()]
  310. timer_start(50, (_) => {
  311. feedkeys('gq')
  312. timer_start(50, (_) => {
  313. mouse_shapes += [getmouseshape()]
  314. timer_start(50, (_) => {
  315. writefile(mouse_shapes, 'Xmouseshapes')
  316. quit!
  317. })
  318. })
  319. })
  320. })
  321. END
  322. call writefile(lines, 'Xmouseshape.vim', 'D')
  323. call RunVim([], [], "-g -S Xindentexpr.vim -S Xmouseshape.vim")
  324. call WaitForAssert({-> assert_equal(['rightup-arrow', 'arrow'],
  325. \ readfile('Xmouseshapes'))}, 300)
  326. call delete('Xmouseshapes')
  327. endfunc
  328. " vim: shiftwidth=2 sts=2 expandtab