poly-cms 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (460) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/Gemfile +27 -0
  4. data/Gemfile.lock +95 -0
  5. data/README.md +3 -0
  6. data/Rakefile +45 -0
  7. data/bin/poly +88 -0
  8. data/config.ru +3 -0
  9. data/core/admin/assets/images/icons/cache-clear.svg +11 -0
  10. data/core/admin/assets/images/icons/delete-dark.svg +10 -0
  11. data/core/admin/assets/images/icons/delete.svg +10 -0
  12. data/core/admin/assets/images/icons/handle.svg +12 -0
  13. data/core/admin/assets/images/icons/logout.svg +13 -0
  14. data/core/admin/assets/images/icons/move.svg +10 -0
  15. data/core/admin/assets/images/icons/new.svg +9 -0
  16. data/core/admin/assets/images/icons/prompt.svg +11 -0
  17. data/core/admin/assets/images/icons/refresh.svg +40 -0
  18. data/core/admin/assets/images/icons/save.svg +7 -0
  19. data/core/admin/assets/images/poly-small-boxed.svg +51 -0
  20. data/core/admin/assets/images/poly-small.svg +52 -0
  21. data/core/admin/assets/images/poly.svg +36 -0
  22. data/core/admin/assets/js/app/file-ext.js +15 -0
  23. data/core/admin/assets/js/app/views/editor.js +300 -0
  24. data/core/admin/assets/js/app/views/git.js +65 -0
  25. data/core/admin/assets/js/app/views/main.js +59 -0
  26. data/core/admin/assets/js/main.js +44 -0
  27. data/core/admin/assets/js/routes.js +25 -0
  28. data/core/admin/assets/js/vendor/backbone.js +4 -0
  29. data/core/admin/assets/js/vendor/codemirror/.gitattributes +8 -0
  30. data/core/admin/assets/js/vendor/codemirror/.gitignore +6 -0
  31. data/core/admin/assets/js/vendor/codemirror/.travis.yml +3 -0
  32. data/core/admin/assets/js/vendor/codemirror/addon/comment/comment.js +145 -0
  33. data/core/admin/assets/js/vendor/codemirror/addon/comment/continuecomment.js +54 -0
  34. data/core/admin/assets/js/vendor/codemirror/addon/dialog/dialog.css +32 -0
  35. data/core/admin/assets/js/vendor/codemirror/addon/dialog/dialog.js +80 -0
  36. data/core/admin/assets/js/vendor/codemirror/addon/display/fullscreen.css +6 -0
  37. data/core/admin/assets/js/vendor/codemirror/addon/display/fullscreen.js +30 -0
  38. data/core/admin/assets/js/vendor/codemirror/addon/display/placeholder.js +54 -0
  39. data/core/admin/assets/js/vendor/codemirror/addon/edit/closebrackets.js +82 -0
  40. data/core/admin/assets/js/vendor/codemirror/addon/edit/closetag.js +87 -0
  41. data/core/admin/assets/js/vendor/codemirror/addon/edit/continuelist.js +25 -0
  42. data/core/admin/assets/js/vendor/codemirror/addon/edit/matchbrackets.js +86 -0
  43. data/core/admin/assets/js/vendor/codemirror/addon/edit/matchtags.js +56 -0
  44. data/core/admin/assets/js/vendor/codemirror/addon/edit/trailingspace.js +15 -0
  45. data/core/admin/assets/js/vendor/codemirror/addon/fold/brace-fold.js +93 -0
  46. data/core/admin/assets/js/vendor/codemirror/addon/fold/comment-fold.js +40 -0
  47. data/core/admin/assets/js/vendor/codemirror/addon/fold/foldcode.js +75 -0
  48. data/core/admin/assets/js/vendor/codemirror/addon/fold/foldgutter.css +21 -0
  49. data/core/admin/assets/js/vendor/codemirror/addon/fold/foldgutter.js +124 -0
  50. data/core/admin/assets/js/vendor/codemirror/addon/fold/indent-fold.js +26 -0
  51. data/core/admin/assets/js/vendor/codemirror/addon/fold/xml-fold.js +167 -0
  52. data/core/admin/assets/js/vendor/codemirror/addon/hint/anyword-hint.js +34 -0
  53. data/core/admin/assets/js/vendor/codemirror/addon/hint/css-hint.js +50 -0
  54. data/core/admin/assets/js/vendor/codemirror/addon/hint/html-hint.js +337 -0
  55. data/core/admin/assets/js/vendor/codemirror/addon/hint/javascript-hint.js +130 -0
  56. data/core/admin/assets/js/vendor/codemirror/addon/hint/pig-hint.js +121 -0
  57. data/core/admin/assets/js/vendor/codemirror/addon/hint/python-hint.js +95 -0
  58. data/core/admin/assets/js/vendor/codemirror/addon/hint/show-hint.css +38 -0
  59. data/core/admin/assets/js/vendor/codemirror/addon/hint/show-hint.js +274 -0
  60. data/core/admin/assets/js/vendor/codemirror/addon/hint/sql-hint.js +105 -0
  61. data/core/admin/assets/js/vendor/codemirror/addon/hint/xml-hint.js +69 -0
  62. data/core/admin/assets/js/vendor/codemirror/addon/lint/coffeescript-lint.js +27 -0
  63. data/core/admin/assets/js/vendor/codemirror/addon/lint/css-lint.js +19 -0
  64. data/core/admin/assets/js/vendor/codemirror/addon/lint/javascript-lint.js +126 -0
  65. data/core/admin/assets/js/vendor/codemirror/addon/lint/json-lint.js +17 -0
  66. data/core/admin/assets/js/vendor/codemirror/addon/lint/lint.css +73 -0
  67. data/core/admin/assets/js/vendor/codemirror/addon/lint/lint.js +203 -0
  68. data/core/admin/assets/js/vendor/codemirror/addon/merge/dep/diff_match_patch.js +50 -0
  69. data/core/admin/assets/js/vendor/codemirror/addon/merge/merge.css +92 -0
  70. data/core/admin/assets/js/vendor/codemirror/addon/merge/merge.js +474 -0
  71. data/core/admin/assets/js/vendor/codemirror/addon/mode/loadmode.js +51 -0
  72. data/core/admin/assets/js/vendor/codemirror/addon/mode/multiplex.js +101 -0
  73. data/core/admin/assets/js/vendor/codemirror/addon/mode/multiplex_test.js +30 -0
  74. data/core/admin/assets/js/vendor/codemirror/addon/mode/overlay.js +59 -0
  75. data/core/admin/assets/js/vendor/codemirror/addon/runmode/colorize.js +29 -0
  76. data/core/admin/assets/js/vendor/codemirror/addon/runmode/runmode-standalone.js +136 -0
  77. data/core/admin/assets/js/vendor/codemirror/addon/runmode/runmode.js +56 -0
  78. data/core/admin/assets/js/vendor/codemirror/addon/runmode/runmode.node.js +103 -0
  79. data/core/admin/assets/js/vendor/codemirror/addon/scroll/scrollpastend.js +34 -0
  80. data/core/admin/assets/js/vendor/codemirror/addon/search/match-highlighter.js +91 -0
  81. data/core/admin/assets/js/vendor/codemirror/addon/search/search.js +133 -0
  82. data/core/admin/assets/js/vendor/codemirror/addon/search/searchcursor.js +143 -0
  83. data/core/admin/assets/js/vendor/codemirror/addon/selection/active-line.js +39 -0
  84. data/core/admin/assets/js/vendor/codemirror/addon/selection/mark-selection.js +108 -0
  85. data/core/admin/assets/js/vendor/codemirror/addon/tern/tern.css +85 -0
  86. data/core/admin/assets/js/vendor/codemirror/addon/tern/tern.js +632 -0
  87. data/core/admin/assets/js/vendor/codemirror/addon/tern/worker.js +41 -0
  88. data/core/admin/assets/js/vendor/codemirror/addon/wrap/hardwrap.js +99 -0
  89. data/core/admin/assets/js/vendor/codemirror/bin/authors.sh +6 -0
  90. data/core/admin/assets/js/vendor/codemirror/bin/compress +92 -0
  91. data/core/admin/assets/js/vendor/codemirror/bin/lint +16 -0
  92. data/core/admin/assets/js/vendor/codemirror/bin/source-highlight +61 -0
  93. data/core/admin/assets/js/vendor/codemirror/bower.json +15 -0
  94. data/core/admin/assets/js/vendor/codemirror/demo/activeline.html +78 -0
  95. data/core/admin/assets/js/vendor/codemirror/demo/anywordhint.html +79 -0
  96. data/core/admin/assets/js/vendor/codemirror/demo/bidi.html +74 -0
  97. data/core/admin/assets/js/vendor/codemirror/demo/btree.html +86 -0
  98. data/core/admin/assets/js/vendor/codemirror/demo/buffers.html +109 -0
  99. data/core/admin/assets/js/vendor/codemirror/demo/changemode.html +59 -0
  100. data/core/admin/assets/js/vendor/codemirror/demo/closebrackets.html +63 -0
  101. data/core/admin/assets/js/vendor/codemirror/demo/closetag.html +40 -0
  102. data/core/admin/assets/js/vendor/codemirror/demo/complete.html +80 -0
  103. data/core/admin/assets/js/vendor/codemirror/demo/emacs.html +75 -0
  104. data/core/admin/assets/js/vendor/codemirror/demo/folding.html +75 -0
  105. data/core/admin/assets/js/vendor/codemirror/demo/fullscreen.html +130 -0
  106. data/core/admin/assets/js/vendor/codemirror/demo/hardwrap.html +69 -0
  107. data/core/admin/assets/js/vendor/codemirror/demo/html5complete.html +54 -0
  108. data/core/admin/assets/js/vendor/codemirror/demo/indentwrap.html +58 -0
  109. data/core/admin/assets/js/vendor/codemirror/demo/lint.html +171 -0
  110. data/core/admin/assets/js/vendor/codemirror/demo/loadmode.html +49 -0
  111. data/core/admin/assets/js/vendor/codemirror/demo/marker.html +52 -0
  112. data/core/admin/assets/js/vendor/codemirror/demo/markselection.html +45 -0
  113. data/core/admin/assets/js/vendor/codemirror/demo/matchhighlighter.html +47 -0
  114. data/core/admin/assets/js/vendor/codemirror/demo/matchtags.html +49 -0
  115. data/core/admin/assets/js/vendor/codemirror/demo/merge.html +82 -0
  116. data/core/admin/assets/js/vendor/codemirror/demo/multiplex.html +75 -0
  117. data/core/admin/assets/js/vendor/codemirror/demo/mustache.html +68 -0
  118. data/core/admin/assets/js/vendor/codemirror/demo/placeholder.html +45 -0
  119. data/core/admin/assets/js/vendor/codemirror/demo/preview.html +88 -0
  120. data/core/admin/assets/js/vendor/codemirror/demo/resize.html +58 -0
  121. data/core/admin/assets/js/vendor/codemirror/demo/runmode.html +62 -0
  122. data/core/admin/assets/js/vendor/codemirror/demo/search.html +94 -0
  123. data/core/admin/assets/js/vendor/codemirror/demo/spanaffectswrapping_shim.html +85 -0
  124. data/core/admin/assets/js/vendor/codemirror/demo/tern.html +128 -0
  125. data/core/admin/assets/js/vendor/codemirror/demo/theme.html +121 -0
  126. data/core/admin/assets/js/vendor/codemirror/demo/trailingspace.html +48 -0
  127. data/core/admin/assets/js/vendor/codemirror/demo/variableheight.html +61 -0
  128. data/core/admin/assets/js/vendor/codemirror/demo/vim.html +74 -0
  129. data/core/admin/assets/js/vendor/codemirror/demo/visibletabs.html +62 -0
  130. data/core/admin/assets/js/vendor/codemirror/demo/widget.html +85 -0
  131. data/core/admin/assets/js/vendor/codemirror/demo/xmlcomplete.html +116 -0
  132. data/core/admin/assets/js/vendor/codemirror/doc/activebookmark.js +42 -0
  133. data/core/admin/assets/js/vendor/codemirror/doc/compress.html +231 -0
  134. data/core/admin/assets/js/vendor/codemirror/doc/docs.css +226 -0
  135. data/core/admin/assets/js/vendor/codemirror/doc/internals.html +503 -0
  136. data/core/admin/assets/js/vendor/codemirror/doc/logo.png +0 -0
  137. data/core/admin/assets/js/vendor/codemirror/doc/logo.svg +147 -0
  138. data/core/admin/assets/js/vendor/codemirror/doc/manual.html +2512 -0
  139. data/core/admin/assets/js/vendor/codemirror/doc/realworld.html +134 -0
  140. data/core/admin/assets/js/vendor/codemirror/doc/releases.html +779 -0
  141. data/core/admin/assets/js/vendor/codemirror/doc/reporting.html +61 -0
  142. data/core/admin/assets/js/vendor/codemirror/doc/upgrade_v2.2.html +96 -0
  143. data/core/admin/assets/js/vendor/codemirror/doc/upgrade_v3.html +230 -0
  144. data/core/admin/assets/js/vendor/codemirror/index.html +192 -0
  145. data/core/admin/assets/js/vendor/codemirror/keymap/emacs.js +387 -0
  146. data/core/admin/assets/js/vendor/codemirror/keymap/extra.js +43 -0
  147. data/core/admin/assets/js/vendor/codemirror/keymap/vim.js +3704 -0
  148. data/core/admin/assets/js/vendor/codemirror/lib/codemirror.css +263 -0
  149. data/core/admin/assets/js/vendor/codemirror/lib/codemirror.js +5910 -0
  150. data/core/admin/assets/js/vendor/codemirror/mode/apl/apl.js +160 -0
  151. data/core/admin/assets/js/vendor/codemirror/mode/apl/index.html +72 -0
  152. data/core/admin/assets/js/vendor/codemirror/mode/asterisk/asterisk.js +183 -0
  153. data/core/admin/assets/js/vendor/codemirror/mode/asterisk/index.html +154 -0
  154. data/core/admin/assets/js/vendor/codemirror/mode/clike/clike.js +362 -0
  155. data/core/admin/assets/js/vendor/codemirror/mode/clike/index.html +195 -0
  156. data/core/admin/assets/js/vendor/codemirror/mode/clike/scala.html +767 -0
  157. data/core/admin/assets/js/vendor/codemirror/mode/clojure/clojure.js +224 -0
  158. data/core/admin/assets/js/vendor/codemirror/mode/clojure/index.html +88 -0
  159. data/core/admin/assets/js/vendor/codemirror/mode/cobol/cobol.js +240 -0
  160. data/core/admin/assets/js/vendor/codemirror/mode/cobol/index.html +210 -0
  161. data/core/admin/assets/js/vendor/codemirror/mode/coffeescript/coffeescript.js +349 -0
  162. data/core/admin/assets/js/vendor/codemirror/mode/coffeescript/index.html +740 -0
  163. data/core/admin/assets/js/vendor/codemirror/mode/commonlisp/commonlisp.js +105 -0
  164. data/core/admin/assets/js/vendor/codemirror/mode/commonlisp/index.html +177 -0
  165. data/core/admin/assets/js/vendor/codemirror/mode/css/css.js +639 -0
  166. data/core/admin/assets/js/vendor/codemirror/mode/css/index.html +70 -0
  167. data/core/admin/assets/js/vendor/codemirror/mode/css/scss.html +157 -0
  168. data/core/admin/assets/js/vendor/codemirror/mode/css/scss_test.js +84 -0
  169. data/core/admin/assets/js/vendor/codemirror/mode/css/test.js +130 -0
  170. data/core/admin/assets/js/vendor/codemirror/mode/d/d.js +205 -0
  171. data/core/admin/assets/js/vendor/codemirror/mode/d/index.html +273 -0
  172. data/core/admin/assets/js/vendor/codemirror/mode/diff/diff.js +32 -0
  173. data/core/admin/assets/js/vendor/codemirror/mode/diff/index.html +117 -0
  174. data/core/admin/assets/js/vendor/codemirror/mode/dtd/dtd.js +127 -0
  175. data/core/admin/assets/js/vendor/codemirror/mode/dtd/index.html +89 -0
  176. data/core/admin/assets/js/vendor/codemirror/mode/ecl/ecl.js +192 -0
  177. data/core/admin/assets/js/vendor/codemirror/mode/ecl/index.html +52 -0
  178. data/core/admin/assets/js/vendor/codemirror/mode/eiffel/eiffel.js +147 -0
  179. data/core/admin/assets/js/vendor/codemirror/mode/eiffel/index.html +430 -0
  180. data/core/admin/assets/js/vendor/codemirror/mode/erlang/erlang.js +484 -0
  181. data/core/admin/assets/js/vendor/codemirror/mode/erlang/index.html +75 -0
  182. data/core/admin/assets/js/vendor/codemirror/mode/fortran/fortran.js +173 -0
  183. data/core/admin/assets/js/vendor/codemirror/mode/fortran/index.html +81 -0
  184. data/core/admin/assets/js/vendor/codemirror/mode/gas/gas.js +330 -0
  185. data/core/admin/assets/js/vendor/codemirror/mode/gas/index.html +68 -0
  186. data/core/admin/assets/js/vendor/codemirror/mode/gfm/gfm.js +97 -0
  187. data/core/admin/assets/js/vendor/codemirror/mode/gfm/index.html +82 -0
  188. data/core/admin/assets/js/vendor/codemirror/mode/gfm/test.js +112 -0
  189. data/core/admin/assets/js/vendor/codemirror/mode/gherkin/gherkin.js +168 -0
  190. data/core/admin/assets/js/vendor/codemirror/mode/gherkin/index.html +48 -0
  191. data/core/admin/assets/js/vendor/codemirror/mode/go/go.js +168 -0
  192. data/core/admin/assets/js/vendor/codemirror/mode/go/index.html +85 -0
  193. data/core/admin/assets/js/vendor/codemirror/mode/groovy/groovy.js +211 -0
  194. data/core/admin/assets/js/vendor/codemirror/mode/groovy/index.html +84 -0
  195. data/core/admin/assets/js/vendor/codemirror/mode/haml/haml.js +153 -0
  196. data/core/admin/assets/js/vendor/codemirror/mode/haml/index.html +79 -0
  197. data/core/admin/assets/js/vendor/codemirror/mode/haml/test.js +94 -0
  198. data/core/admin/assets/js/vendor/codemirror/mode/haskell/haskell.js +250 -0
  199. data/core/admin/assets/js/vendor/codemirror/mode/haskell/index.html +73 -0
  200. data/core/admin/assets/js/vendor/codemirror/mode/haxe/haxe.js +429 -0
  201. data/core/admin/assets/js/vendor/codemirror/mode/haxe/index.html +103 -0
  202. data/core/admin/assets/js/vendor/codemirror/mode/htmlembedded/htmlembedded.js +73 -0
  203. data/core/admin/assets/js/vendor/codemirror/mode/htmlembedded/index.html +60 -0
  204. data/core/admin/assets/js/vendor/codemirror/mode/htmlmixed/htmlmixed.js +104 -0
  205. data/core/admin/assets/js/vendor/codemirror/mode/htmlmixed/index.html +85 -0
  206. data/core/admin/assets/js/vendor/codemirror/mode/http/http.js +98 -0
  207. data/core/admin/assets/js/vendor/codemirror/mode/http/index.html +45 -0
  208. data/core/admin/assets/js/vendor/codemirror/mode/index.html +112 -0
  209. data/core/admin/assets/js/vendor/codemirror/mode/jade/index.html +66 -0
  210. data/core/admin/assets/js/vendor/codemirror/mode/jade/jade.js +90 -0
  211. data/core/admin/assets/js/vendor/codemirror/mode/javascript/index.html +107 -0
  212. data/core/admin/assets/js/vendor/codemirror/mode/javascript/javascript.js +480 -0
  213. data/core/admin/assets/js/vendor/codemirror/mode/javascript/test.js +10 -0
  214. data/core/admin/assets/js/vendor/codemirror/mode/javascript/typescript.html +61 -0
  215. data/core/admin/assets/js/vendor/codemirror/mode/jinja2/index.html +50 -0
  216. data/core/admin/assets/js/vendor/codemirror/mode/jinja2/jinja2.js +42 -0
  217. data/core/admin/assets/js/vendor/codemirror/mode/less/index.html +753 -0
  218. data/core/admin/assets/js/vendor/codemirror/mode/less/less.js +344 -0
  219. data/core/admin/assets/js/vendor/codemirror/mode/livescript/index.html +459 -0
  220. data/core/admin/assets/js/vendor/codemirror/mode/livescript/livescript.js +267 -0
  221. data/core/admin/assets/js/vendor/codemirror/mode/livescript/livescript.ls +266 -0
  222. data/core/admin/assets/js/vendor/codemirror/mode/lua/index.html +86 -0
  223. data/core/admin/assets/js/vendor/codemirror/mode/lua/lua.js +144 -0
  224. data/core/admin/assets/js/vendor/codemirror/mode/markdown/index.html +359 -0
  225. data/core/admin/assets/js/vendor/codemirror/mode/markdown/markdown.js +551 -0
  226. data/core/admin/assets/js/vendor/codemirror/mode/markdown/test.js +656 -0
  227. data/core/admin/assets/js/vendor/codemirror/mode/meta.js +89 -0
  228. data/core/admin/assets/js/vendor/codemirror/mode/mirc/index.html +161 -0
  229. data/core/admin/assets/js/vendor/codemirror/mode/mirc/mirc.js +177 -0
  230. data/core/admin/assets/js/vendor/codemirror/mode/nginx/index.html +181 -0
  231. data/core/admin/assets/js/vendor/codemirror/mode/nginx/nginx.js +163 -0
  232. data/core/admin/assets/js/vendor/codemirror/mode/ntriples/index.html +45 -0
  233. data/core/admin/assets/js/vendor/codemirror/mode/ntriples/ntriples.js +170 -0
  234. data/core/admin/assets/js/vendor/codemirror/mode/ocaml/index.html +146 -0
  235. data/core/admin/assets/js/vendor/codemirror/mode/ocaml/ocaml.js +116 -0
  236. data/core/admin/assets/js/vendor/codemirror/mode/octave/index.html +95 -0
  237. data/core/admin/assets/js/vendor/codemirror/mode/octave/octave.js +118 -0
  238. data/core/admin/assets/js/vendor/codemirror/mode/pascal/index.html +61 -0
  239. data/core/admin/assets/js/vendor/codemirror/mode/pascal/pascal.js +94 -0
  240. data/core/admin/assets/js/vendor/codemirror/mode/perl/index.html +75 -0
  241. data/core/admin/assets/js/vendor/codemirror/mode/perl/perl.js +816 -0
  242. data/core/admin/assets/js/vendor/codemirror/mode/php/index.html +62 -0
  243. data/core/admin/assets/js/vendor/codemirror/mode/php/php.js +132 -0
  244. data/core/admin/assets/js/vendor/codemirror/mode/pig/index.html +55 -0
  245. data/core/admin/assets/js/vendor/codemirror/mode/pig/pig.js +171 -0
  246. data/core/admin/assets/js/vendor/codemirror/mode/properties/index.html +53 -0
  247. data/core/admin/assets/js/vendor/codemirror/mode/properties/properties.js +63 -0
  248. data/core/admin/assets/js/vendor/codemirror/mode/python/index.html +187 -0
  249. data/core/admin/assets/js/vendor/codemirror/mode/python/python.js +368 -0
  250. data/core/admin/assets/js/vendor/codemirror/mode/q/index.html +144 -0
  251. data/core/admin/assets/js/vendor/codemirror/mode/q/q.js +124 -0
  252. data/core/admin/assets/js/vendor/codemirror/mode/r/index.html +86 -0
  253. data/core/admin/assets/js/vendor/codemirror/mode/r/r.js +141 -0
  254. data/core/admin/assets/js/vendor/codemirror/mode/rpm/changes/changes.js +19 -0
  255. data/core/admin/assets/js/vendor/codemirror/mode/rpm/changes/index.html +67 -0
  256. data/core/admin/assets/js/vendor/codemirror/mode/rpm/spec/index.html +114 -0
  257. data/core/admin/assets/js/vendor/codemirror/mode/rpm/spec/spec.css +5 -0
  258. data/core/admin/assets/js/vendor/codemirror/mode/rpm/spec/spec.js +66 -0
  259. data/core/admin/assets/js/vendor/codemirror/mode/rst/index.html +534 -0
  260. data/core/admin/assets/js/vendor/codemirror/mode/rst/rst.js +560 -0
  261. data/core/admin/assets/js/vendor/codemirror/mode/ruby/index.html +185 -0
  262. data/core/admin/assets/js/vendor/codemirror/mode/ruby/ruby.js +247 -0
  263. data/core/admin/assets/js/vendor/codemirror/mode/rust/index.html +61 -0
  264. data/core/admin/assets/js/vendor/codemirror/mode/rust/rust.js +436 -0
  265. data/core/admin/assets/js/vendor/codemirror/mode/sass/index.html +66 -0
  266. data/core/admin/assets/js/vendor/codemirror/mode/sass/sass.js +330 -0
  267. data/core/admin/assets/js/vendor/codemirror/mode/scheme/index.html +77 -0
  268. data/core/admin/assets/js/vendor/codemirror/mode/scheme/scheme.js +232 -0
  269. data/core/admin/assets/js/vendor/codemirror/mode/shell/index.html +66 -0
  270. data/core/admin/assets/js/vendor/codemirror/mode/shell/shell.js +118 -0
  271. data/core/admin/assets/js/vendor/codemirror/mode/sieve/index.html +93 -0
  272. data/core/admin/assets/js/vendor/codemirror/mode/sieve/sieve.js +183 -0
  273. data/core/admin/assets/js/vendor/codemirror/mode/smalltalk/index.html +68 -0
  274. data/core/admin/assets/js/vendor/codemirror/mode/smalltalk/smalltalk.js +151 -0
  275. data/core/admin/assets/js/vendor/codemirror/mode/smarty/index.html +136 -0
  276. data/core/admin/assets/js/vendor/codemirror/mode/smarty/smarty.js +205 -0
  277. data/core/admin/assets/js/vendor/codemirror/mode/smartymixed/index.html +114 -0
  278. data/core/admin/assets/js/vendor/codemirror/mode/smartymixed/smartymixed.js +175 -0
  279. data/core/admin/assets/js/vendor/codemirror/mode/sparql/index.html +54 -0
  280. data/core/admin/assets/js/vendor/codemirror/mode/sparql/sparql.js +145 -0
  281. data/core/admin/assets/js/vendor/codemirror/mode/sql/index.html +75 -0
  282. data/core/admin/assets/js/vendor/codemirror/mode/sql/sql.js +365 -0
  283. data/core/admin/assets/js/vendor/codemirror/mode/stex/index.html +110 -0
  284. data/core/admin/assets/js/vendor/codemirror/mode/stex/stex.js +246 -0
  285. data/core/admin/assets/js/vendor/codemirror/mode/stex/test.js +120 -0
  286. data/core/admin/assets/js/vendor/codemirror/mode/tcl/index.html +143 -0
  287. data/core/admin/assets/js/vendor/codemirror/mode/tcl/tcl.js +131 -0
  288. data/core/admin/assets/js/vendor/codemirror/mode/tiddlywiki/index.html +155 -0
  289. data/core/admin/assets/js/vendor/codemirror/mode/tiddlywiki/tiddlywiki.css +14 -0
  290. data/core/admin/assets/js/vendor/codemirror/mode/tiddlywiki/tiddlywiki.js +353 -0
  291. data/core/admin/assets/js/vendor/codemirror/mode/tiki/index.html +95 -0
  292. data/core/admin/assets/js/vendor/codemirror/mode/tiki/tiki.css +26 -0
  293. data/core/admin/assets/js/vendor/codemirror/mode/tiki/tiki.js +308 -0
  294. data/core/admin/assets/js/vendor/codemirror/mode/toml/index.html +73 -0
  295. data/core/admin/assets/js/vendor/codemirror/mode/toml/toml.js +71 -0
  296. data/core/admin/assets/js/vendor/codemirror/mode/turtle/index.html +51 -0
  297. data/core/admin/assets/js/vendor/codemirror/mode/turtle/turtle.js +145 -0
  298. data/core/admin/assets/js/vendor/codemirror/mode/vb/index.html +103 -0
  299. data/core/admin/assets/js/vendor/codemirror/mode/vb/vb.js +259 -0
  300. data/core/admin/assets/js/vendor/codemirror/mode/vbscript/index.html +55 -0
  301. data/core/admin/assets/js/vendor/codemirror/mode/vbscript/vbscript.js +334 -0
  302. data/core/admin/assets/js/vendor/codemirror/mode/velocity/index.html +119 -0
  303. data/core/admin/assets/js/vendor/codemirror/mode/velocity/velocity.js +186 -0
  304. data/core/admin/assets/js/vendor/codemirror/mode/verilog/index.html +132 -0
  305. data/core/admin/assets/js/vendor/codemirror/mode/verilog/verilog.js +182 -0
  306. data/core/admin/assets/js/vendor/codemirror/mode/xml/index.html +57 -0
  307. data/core/admin/assets/js/vendor/codemirror/mode/xml/xml.js +345 -0
  308. data/core/admin/assets/js/vendor/codemirror/mode/xquery/index.html +210 -0
  309. data/core/admin/assets/js/vendor/codemirror/mode/xquery/test.js +64 -0
  310. data/core/admin/assets/js/vendor/codemirror/mode/xquery/xquery.js +432 -0
  311. data/core/admin/assets/js/vendor/codemirror/mode/yaml/index.html +80 -0
  312. data/core/admin/assets/js/vendor/codemirror/mode/yaml/yaml.js +97 -0
  313. data/core/admin/assets/js/vendor/codemirror/mode/z80/index.html +52 -0
  314. data/core/admin/assets/js/vendor/codemirror/mode/z80/z80.js +85 -0
  315. data/core/admin/assets/js/vendor/codemirror/package.json +19 -0
  316. data/core/admin/assets/js/vendor/codemirror/test/comment_test.js +51 -0
  317. data/core/admin/assets/js/vendor/codemirror/test/doc_test.js +329 -0
  318. data/core/admin/assets/js/vendor/codemirror/test/driver.js +139 -0
  319. data/core/admin/assets/js/vendor/codemirror/test/emacs_test.js +135 -0
  320. data/core/admin/assets/js/vendor/codemirror/test/index.html +209 -0
  321. data/core/admin/assets/js/vendor/codemirror/test/lint/acorn.js +1593 -0
  322. data/core/admin/assets/js/vendor/codemirror/test/lint/lint.js +139 -0
  323. data/core/admin/assets/js/vendor/codemirror/test/lint/walk.js +216 -0
  324. data/core/admin/assets/js/vendor/codemirror/test/mode_test.css +10 -0
  325. data/core/admin/assets/js/vendor/codemirror/test/mode_test.js +200 -0
  326. data/core/admin/assets/js/vendor/codemirror/test/phantom_driver.js +31 -0
  327. data/core/admin/assets/js/vendor/codemirror/test/run.js +34 -0
  328. data/core/admin/assets/js/vendor/codemirror/test/test.js +1562 -0
  329. data/core/admin/assets/js/vendor/codemirror/test/vim_test.js +2391 -0
  330. data/core/admin/assets/js/vendor/codemirror/theme/3024-day.css +34 -0
  331. data/core/admin/assets/js/vendor/codemirror/theme/3024-night.css +34 -0
  332. data/core/admin/assets/js/vendor/codemirror/theme/ambiance-mobile.css +5 -0
  333. data/core/admin/assets/js/vendor/codemirror/theme/ambiance.css +75 -0
  334. data/core/admin/assets/js/vendor/codemirror/theme/base16-dark.css +34 -0
  335. data/core/admin/assets/js/vendor/codemirror/theme/base16-light.css +34 -0
  336. data/core/admin/assets/js/vendor/codemirror/theme/blackboard.css +28 -0
  337. data/core/admin/assets/js/vendor/codemirror/theme/cobalt.css +21 -0
  338. data/core/admin/assets/js/vendor/codemirror/theme/eclipse.css +23 -0
  339. data/core/admin/assets/js/vendor/codemirror/theme/elegant.css +13 -0
  340. data/core/admin/assets/js/vendor/codemirror/theme/erlang-dark.css +30 -0
  341. data/core/admin/assets/js/vendor/codemirror/theme/lesser-dark.css +47 -0
  342. data/core/admin/assets/js/vendor/codemirror/theme/mbo.css +35 -0
  343. data/core/admin/assets/js/vendor/codemirror/theme/midnight.css +43 -0
  344. data/core/admin/assets/js/vendor/codemirror/theme/monokai.css +29 -0
  345. data/core/admin/assets/js/vendor/codemirror/theme/neat.css +12 -0
  346. data/core/admin/assets/js/vendor/codemirror/theme/night.css +24 -0
  347. data/core/admin/assets/js/vendor/codemirror/theme/paraiso-dark.css +34 -0
  348. data/core/admin/assets/js/vendor/codemirror/theme/paraiso-light.css +34 -0
  349. data/core/admin/assets/js/vendor/codemirror/theme/rubyblue.css +23 -0
  350. data/core/admin/assets/js/vendor/codemirror/theme/solarized-mod.css +181 -0
  351. data/core/admin/assets/js/vendor/codemirror/theme/solarized.css +180 -0
  352. data/core/admin/assets/js/vendor/codemirror/theme/the-matrix.css +26 -0
  353. data/core/admin/assets/js/vendor/codemirror/theme/tomorrow-night-eighties.css +34 -0
  354. data/core/admin/assets/js/vendor/codemirror/theme/twilight.css +28 -0
  355. data/core/admin/assets/js/vendor/codemirror/theme/vibrant-ink.css +30 -0
  356. data/core/admin/assets/js/vendor/codemirror/theme/xq-dark.css +49 -0
  357. data/core/admin/assets/js/vendor/codemirror/theme/xq-light.css +43 -0
  358. data/core/admin/assets/js/vendor/fastclick.js +777 -0
  359. data/core/admin/assets/js/vendor/jquery.js +6 -0
  360. data/core/admin/assets/js/vendor/lodash.underscore.js +38 -0
  361. data/core/admin/assets/js/vendor/require.js +36 -0
  362. data/core/admin/assets/scss/bootstrap.scss +18 -0
  363. data/core/admin/assets/scss/modules/_all.scss +7 -0
  364. data/core/admin/assets/scss/modules/_colors.scss +7 -0
  365. data/core/admin/assets/scss/modules/_extensions.scss +24 -0
  366. data/core/admin/assets/scss/modules/_mixins.scss +18 -0
  367. data/core/admin/assets/scss/modules/_susy.scss +7 -0
  368. data/core/admin/assets/scss/partials/_base.scss +33 -0
  369. data/core/admin/assets/scss/partials/_buttons.scss +9 -0
  370. data/core/admin/assets/scss/partials/_links.scss +15 -0
  371. data/core/admin/assets/scss/partials/_main.scss +14 -0
  372. data/core/admin/assets/scss/partials/_typography.scss +15 -0
  373. data/core/admin/assets/scss/sections/_editor.scss +274 -0
  374. data/core/admin/assets/scss/sections/_login.scss +34 -0
  375. data/core/admin/assets/scss/vendor/_normalize.scss +406 -0
  376. data/core/admin/layouts/admin.haml +67 -0
  377. data/core/admin/partials/_head.haml +23 -0
  378. data/core/admin/partials/_tree.haml +3 -0
  379. data/core/admin/partials/_treeitem.haml +4 -0
  380. data/core/admin/settings.yml +4 -0
  381. data/core/app.rb +21 -0
  382. data/core/classes/cached.rb +35 -0
  383. data/core/classes/checker.rb +37 -0
  384. data/core/classes/commit.rb +62 -0
  385. data/core/classes/error.rb +9 -0
  386. data/core/classes/page.rb +165 -0
  387. data/core/classes/partial.rb +13 -0
  388. data/core/classes/path.rb +30 -0
  389. data/core/classes/persona.rb +55 -0
  390. data/core/classes/sassfile.rb +95 -0
  391. data/core/classes/settings.rb +19 -0
  392. data/core/classes/theme.rb +55 -0
  393. data/core/helpers/base.rb +46 -0
  394. data/core/helpers/render.rb +26 -0
  395. data/core/helpers/truncate.rb +17 -0
  396. data/core/routes/admin.rb +139 -0
  397. data/core/routes/assetcompiler.rb +23 -0
  398. data/core/routes/base.rb +22 -0
  399. data/core/routes/bootstrap.rb +35 -0
  400. data/core/routes/cache.rb +52 -0
  401. data/core/routes/deploy.rb +16 -0
  402. data/core/routes/git.rb +23 -0
  403. data/poly.gemspec +29 -0
  404. data/sample/.cabi-data +0 -0
  405. data/sample/data/home/index.haml +22 -0
  406. data/sample/data/other/nav/links.yml +4 -0
  407. data/sample/data/page/about/index.haml +12 -0
  408. data/sample/data/page/contact-us/index.haml +11 -0
  409. data/sample/data/page/dynamic-page/index.haml +14 -0
  410. data/sample/data/page/error/index.haml +8 -0
  411. data/sample/data/page/html/index.html +4 -0
  412. data/sample/data/page/no-front-matter/index.haml +7 -0
  413. data/sample/data/page/not-found/index.haml +8 -0
  414. data/sample/data/page/static-page/index.haml +14 -0
  415. data/sample/data/post/about-life/index.md +12 -0
  416. data/sample/data/post/sample-post/index.haml +12 -0
  417. data/sample/data/post/technology/index.haml +12 -0
  418. data/sample/data/post/the-40-hour-workweek/index.haml +9 -0
  419. data/sample/data/post/things-are-changing/index.haml +9 -0
  420. data/sample/data/post/yet-another-post/index.haml +11 -0
  421. data/sample/plugins/my-plugin/plugin.rb +15 -0
  422. data/sample/settings.yml +21 -0
  423. data/sample/themes/base/assets/css/readme.txt +6 -0
  424. data/sample/themes/base/assets/images/poly.svg +36 -0
  425. data/sample/themes/base/assets/js/app/views/main.js +13 -0
  426. data/sample/themes/base/assets/js/main.js +31 -0
  427. data/sample/themes/base/assets/js/vendor/backbone.js +4 -0
  428. data/sample/themes/base/assets/js/vendor/jquery.js +6 -0
  429. data/sample/themes/base/assets/js/vendor/lodash.underscore.js +38 -0
  430. data/sample/themes/base/assets/js/vendor/require.js +36 -0
  431. data/sample/themes/base/assets/scss/bootstrap.scss +20 -0
  432. data/sample/themes/base/assets/scss/modules/_all.scss +7 -0
  433. data/sample/themes/base/assets/scss/modules/_colors.scss +7 -0
  434. data/sample/themes/base/assets/scss/modules/_extensions.scss +13 -0
  435. data/sample/themes/base/assets/scss/modules/_mixins.scss +11 -0
  436. data/sample/themes/base/assets/scss/modules/_susy.scss +7 -0
  437. data/sample/themes/base/assets/scss/partials/_base.scss +33 -0
  438. data/sample/themes/base/assets/scss/partials/_buttons.scss +0 -0
  439. data/sample/themes/base/assets/scss/partials/_links.scss +15 -0
  440. data/sample/themes/base/assets/scss/partials/_main.scss +39 -0
  441. data/sample/themes/base/assets/scss/partials/_typography.scss +15 -0
  442. data/sample/themes/base/assets/scss/sections/_footer.scss +22 -0
  443. data/sample/themes/base/assets/scss/sections/_header.scss +23 -0
  444. data/sample/themes/base/assets/scss/sections/_home.scss +13 -0
  445. data/sample/themes/base/assets/scss/sections/_pages.scss +11 -0
  446. data/sample/themes/base/assets/scss/vendor/_normalize.scss +406 -0
  447. data/sample/themes/base/layouts/default.haml +14 -0
  448. data/sample/themes/base/layouts/post.haml +15 -0
  449. data/sample/themes/base/partials/_footer.haml +9 -0
  450. data/sample/themes/base/partials/_ga.haml +10 -0
  451. data/sample/themes/base/partials/_head.haml +20 -0
  452. data/sample/themes/base/partials/_header.haml +5 -0
  453. data/sample/themes/base/settings.yml +4 -0
  454. data/test/data/post-receive-hook.json +146 -0
  455. data/test/test_basics.rb +50 -0
  456. data/test/test_data.rb +14 -0
  457. data/test/test_deploy.rb +23 -0
  458. data/test/test_includes.rb +43 -0
  459. data/test/test_page.rb +47 -0
  460. metadata +1049 -0
@@ -0,0 +1,2391 @@
1
+ var code = '' +
2
+ ' wOrd1 (#%\n' +
3
+ ' word3] \n' +
4
+ 'aopop pop 0 1 2 3 4\n' +
5
+ ' (a) [b] {c} \n' +
6
+ 'int getchar(void) {\n' +
7
+ ' static char buf[BUFSIZ];\n' +
8
+ ' static char *bufp = buf;\n' +
9
+ ' if (n == 0) { /* buffer is empty */\n' +
10
+ ' n = read(0, buf, sizeof buf);\n' +
11
+ ' bufp = buf;\n' +
12
+ ' }\n' +
13
+ '\n' +
14
+ ' return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' +
15
+ ' \n' +
16
+ '}\n';
17
+
18
+ var lines = (function() {
19
+ lineText = code.split('\n');
20
+ var ret = [];
21
+ for (var i = 0; i < lineText.length; i++) {
22
+ ret[i] = {
23
+ line: i,
24
+ length: lineText[i].length,
25
+ lineText: lineText[i],
26
+ textStart: /^\s*/.exec(lineText[i])[0].length
27
+ };
28
+ }
29
+ return ret;
30
+ })();
31
+ var endOfDocument = makeCursor(lines.length - 1,
32
+ lines[lines.length - 1].length);
33
+ var wordLine = lines[0];
34
+ var bigWordLine = lines[1];
35
+ var charLine = lines[2];
36
+ var bracesLine = lines[3];
37
+ var seekBraceLine = lines[4];
38
+
39
+ var word1 = {
40
+ start: { line: wordLine.line, ch: 1 },
41
+ end: { line: wordLine.line, ch: 5 }
42
+ };
43
+ var word2 = {
44
+ start: { line: wordLine.line, ch: word1.end.ch + 2 },
45
+ end: { line: wordLine.line, ch: word1.end.ch + 4 }
46
+ };
47
+ var word3 = {
48
+ start: { line: bigWordLine.line, ch: 1 },
49
+ end: { line: bigWordLine.line, ch: 5 }
50
+ };
51
+ var bigWord1 = word1;
52
+ var bigWord2 = word2;
53
+ var bigWord3 = {
54
+ start: { line: bigWordLine.line, ch: 1 },
55
+ end: { line: bigWordLine.line, ch: 7 }
56
+ };
57
+ var bigWord4 = {
58
+ start: { line: bigWordLine.line, ch: bigWord1.end.ch + 3 },
59
+ end: { line: bigWordLine.line, ch: bigWord1.end.ch + 7 }
60
+ };
61
+
62
+ var oChars = [ { line: charLine.line, ch: 1 },
63
+ { line: charLine.line, ch: 3 },
64
+ { line: charLine.line, ch: 7 } ];
65
+ var pChars = [ { line: charLine.line, ch: 2 },
66
+ { line: charLine.line, ch: 4 },
67
+ { line: charLine.line, ch: 6 },
68
+ { line: charLine.line, ch: 8 } ];
69
+ var numChars = [ { line: charLine.line, ch: 10 },
70
+ { line: charLine.line, ch: 12 },
71
+ { line: charLine.line, ch: 14 },
72
+ { line: charLine.line, ch: 16 },
73
+ { line: charLine.line, ch: 18 }];
74
+ var parens1 = {
75
+ start: { line: bracesLine.line, ch: 1 },
76
+ end: { line: bracesLine.line, ch: 3 }
77
+ };
78
+ var squares1 = {
79
+ start: { line: bracesLine.line, ch: 5 },
80
+ end: { line: bracesLine.line, ch: 7 }
81
+ };
82
+ var curlys1 = {
83
+ start: { line: bracesLine.line, ch: 9 },
84
+ end: { line: bracesLine.line, ch: 11 }
85
+ };
86
+ var seekOutside = {
87
+ start: { line: seekBraceLine.line, ch: 1 },
88
+ end: { line: seekBraceLine.line, ch: 16 }
89
+ };
90
+ var seekInside = {
91
+ start: { line: seekBraceLine.line, ch: 14 },
92
+ end: { line: seekBraceLine.line, ch: 11 }
93
+ };
94
+
95
+ function copyCursor(cur) {
96
+ return { ch: cur.ch, line: cur.line };
97
+ }
98
+
99
+ function testVim(name, run, opts, expectedFail) {
100
+ var vimOpts = {
101
+ lineNumbers: true,
102
+ vimMode: true,
103
+ showCursorWhenSelecting: true,
104
+ value: code
105
+ };
106
+ for (var prop in opts) {
107
+ if (opts.hasOwnProperty(prop)) {
108
+ vimOpts[prop] = opts[prop];
109
+ }
110
+ }
111
+ return test('vim_' + name, function() {
112
+ var place = document.getElementById("testground");
113
+ var cm = CodeMirror(place, vimOpts);
114
+ var vim = CodeMirror.Vim.maybeInitVimState_(cm);
115
+
116
+ function doKeysFn(cm) {
117
+ return function(args) {
118
+ if (args instanceof Array) {
119
+ arguments = args;
120
+ }
121
+ for (var i = 0; i < arguments.length; i++) {
122
+ CodeMirror.Vim.handleKey(cm, arguments[i]);
123
+ }
124
+ }
125
+ }
126
+ function doInsertModeKeysFn(cm) {
127
+ return function(args) {
128
+ if (args instanceof Array) { arguments = args; }
129
+ function executeHandler(handler) {
130
+ if (typeof handler == 'string') {
131
+ CodeMirror.commands[handler](cm);
132
+ } else {
133
+ handler(cm);
134
+ }
135
+ return true;
136
+ }
137
+ for (var i = 0; i < arguments.length; i++) {
138
+ var key = arguments[i];
139
+ // Find key in keymap and handle.
140
+ var handled = CodeMirror.lookupKey(key, ['vim-insert'], executeHandler);
141
+ // Record for insert mode.
142
+ if (handled === true && cm.state.vim.insertMode && arguments[i] != 'Esc') {
143
+ var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges;
144
+ if (lastChange) {
145
+ lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key));
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ function doExFn(cm) {
152
+ return function(command) {
153
+ cm.openDialog = helpers.fakeOpenDialog(command);
154
+ helpers.doKeys(':');
155
+ }
156
+ }
157
+ function assertCursorAtFn(cm) {
158
+ return function(line, ch) {
159
+ var pos;
160
+ if (ch == null && typeof line.line == 'number') {
161
+ pos = line;
162
+ } else {
163
+ pos = makeCursor(line, ch);
164
+ }
165
+ eqPos(pos, cm.getCursor());
166
+ }
167
+ }
168
+ function fakeOpenDialog(result) {
169
+ return function(text, callback) {
170
+ return callback(result);
171
+ }
172
+ }
173
+ var helpers = {
174
+ doKeys: doKeysFn(cm),
175
+ // Warning: Only emulates keymap events, not character insertions. Use
176
+ // replaceRange to simulate character insertions.
177
+ // Keys are in CodeMirror format, NOT vim format.
178
+ doInsertModeKeys: doInsertModeKeysFn(cm),
179
+ doEx: doExFn(cm),
180
+ assertCursorAt: assertCursorAtFn(cm),
181
+ fakeOpenDialog: fakeOpenDialog,
182
+ getRegisterController: function() {
183
+ return CodeMirror.Vim.getRegisterController();
184
+ }
185
+ }
186
+ CodeMirror.Vim.resetVimGlobalState_();
187
+ var successful = false;
188
+ try {
189
+ run(cm, vim, helpers);
190
+ successful = true;
191
+ } finally {
192
+ if ((debug && !successful) || verbose) {
193
+ place.style.visibility = "visible";
194
+ } else {
195
+ place.removeChild(cm.getWrapperElement());
196
+ }
197
+ }
198
+ }, expectedFail);
199
+ };
200
+ testVim('qq@q', function(cm, vim, helpers) {
201
+ cm.setCursor(0, 0);
202
+ helpers.doKeys('q', 'q', 'l', 'l', 'q');
203
+ helpers.assertCursorAt(0,2);
204
+ helpers.doKeys('@', 'q');
205
+ helpers.assertCursorAt(0,4);
206
+ }, { value: ' '});
207
+ testVim('@@', function(cm, vim, helpers) {
208
+ cm.setCursor(0, 0);
209
+ helpers.doKeys('q', 'q', 'l', 'l', 'q');
210
+ helpers.assertCursorAt(0,2);
211
+ helpers.doKeys('@', 'q');
212
+ helpers.assertCursorAt(0,4);
213
+ helpers.doKeys('@', '@');
214
+ helpers.assertCursorAt(0,6);
215
+ }, { value: ' '});
216
+ var jumplistScene = ''+
217
+ 'word\n'+
218
+ '(word)\n'+
219
+ '{word\n'+
220
+ 'word.\n'+
221
+ '\n'+
222
+ 'word search\n'+
223
+ '}word\n'+
224
+ 'word\n'+
225
+ 'word\n';
226
+ function testJumplist(name, keys, endPos, startPos, dialog) {
227
+ endPos = makeCursor(endPos[0], endPos[1]);
228
+ startPos = makeCursor(startPos[0], startPos[1]);
229
+ testVim(name, function(cm, vim, helpers) {
230
+ CodeMirror.Vim.resetVimGlobalState_();
231
+ if(dialog)cm.openDialog = helpers.fakeOpenDialog('word');
232
+ cm.setCursor(startPos);
233
+ helpers.doKeys.apply(null, keys);
234
+ helpers.assertCursorAt(endPos);
235
+ }, {value: jumplistScene});
236
+ };
237
+ testJumplist('jumplist_H', ['H', '<C-o>'], [5,2], [5,2]);
238
+ testJumplist('jumplist_M', ['M', '<C-o>'], [2,2], [2,2]);
239
+ testJumplist('jumplist_L', ['L', '<C-o>'], [2,2], [2,2]);
240
+ testJumplist('jumplist_[[', ['[', '[', '<C-o>'], [5,2], [5,2]);
241
+ testJumplist('jumplist_]]', [']', ']', '<C-o>'], [2,2], [2,2]);
242
+ testJumplist('jumplist_G', ['G', '<C-o>'], [5,2], [5,2]);
243
+ testJumplist('jumplist_gg', ['g', 'g', '<C-o>'], [5,2], [5,2]);
244
+ testJumplist('jumplist_%', ['%', '<C-o>'], [1,5], [1,5]);
245
+ testJumplist('jumplist_{', ['{', '<C-o>'], [1,5], [1,5]);
246
+ testJumplist('jumplist_}', ['}', '<C-o>'], [1,5], [1,5]);
247
+ testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', '<C-i>'], [1,5], [1,5]);
248
+ testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', '<C-i>'], [1,5], [1,5]);
249
+ testJumplist('jumplist_*_cachedCursor', ['*', '<C-o>'], [1,3], [1,3]);
250
+ testJumplist('jumplist_#_cachedCursor', ['#', '<C-o>'], [1,3], [1,3]);
251
+ testJumplist('jumplist_n', ['#', 'n', '<C-o>'], [1,1], [2,3]);
252
+ testJumplist('jumplist_N', ['#', 'N', '<C-o>'], [1,1], [2,3]);
253
+ testJumplist('jumplist_repeat_<c-o>', ['*', '*', '*', '3', '<C-o>'], [2,3], [2,3]);
254
+ testJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'], [5,0], [2,3]);
255
+ testJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);
256
+ testJumplist('jumplist_/', ['/', '<C-o>'], [2,3], [2,3], 'dialog');
257
+ testJumplist('jumplist_?', ['?', '<C-o>'], [2,3], [2,3], 'dialog');
258
+ testJumplist('jumplist_skip_delted_mark<c-o>',
259
+ ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],
260
+ [0,2], [0,2]);
261
+ testJumplist('jumplist_skip_delted_mark<c-i>',
262
+ ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-i>', '<C-i>'],
263
+ [1,0], [0,2]);
264
+ /**
265
+ * @param name Name of the test
266
+ * @param keys An array of keys or a string with a single key to simulate.
267
+ * @param endPos The expected end position of the cursor.
268
+ * @param startPos The position the cursor should start at, defaults to 0, 0.
269
+ */
270
+ function testMotion(name, keys, endPos, startPos) {
271
+ testVim(name, function(cm, vim, helpers) {
272
+ if (!startPos) {
273
+ startPos = { line: 0, ch: 0 };
274
+ }
275
+ cm.setCursor(startPos);
276
+ helpers.doKeys(keys);
277
+ helpers.assertCursorAt(endPos);
278
+ });
279
+ };
280
+
281
+ function makeCursor(line, ch) {
282
+ return { line: line, ch: ch };
283
+ };
284
+
285
+ function offsetCursor(cur, offsetLine, offsetCh) {
286
+ return { line: cur.line + offsetLine, ch: cur.ch + offsetCh };
287
+ };
288
+
289
+ // Motion tests
290
+ testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4));
291
+ testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4));
292
+ testMotion('h', 'h', makeCursor(0, 0), word1.start);
293
+ testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end);
294
+ testMotion('l', 'l', makeCursor(0, 1));
295
+ testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2));
296
+ testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end);
297
+ testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end);
298
+ testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument);
299
+ testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end);
300
+ testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4));
301
+ testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4));
302
+ testMotion('w', 'w', word1.start);
303
+ testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2));
304
+ testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51));
305
+ testMotion('w_repeat', ['2', 'w'], word2.start);
306
+ testMotion('w_wrap', ['w'], word3.start, word2.start);
307
+ testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument);
308
+ testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0));
309
+ testMotion('W', 'W', bigWord1.start);
310
+ testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start);
311
+ testMotion('e', 'e', word1.end);
312
+ testMotion('e_repeat', ['2', 'e'], word2.end);
313
+ testMotion('e_wrap', 'e', word3.end, word2.end);
314
+ testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument);
315
+ testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0));
316
+ testMotion('b', 'b', word3.start, word3.end);
317
+ testMotion('b_repeat', ['2', 'b'], word2.start, word3.end);
318
+ testMotion('b_wrap', 'b', word2.start, word3.start);
319
+ testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0));
320
+ testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument);
321
+ testMotion('ge', ['g', 'e'], word2.end, word3.end);
322
+ testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start);
323
+ testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start);
324
+ testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0),
325
+ makeCursor(0, 0));
326
+ testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument);
327
+ testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart),
328
+ makeCursor(3, 1));
329
+ testMotion('gg_repeat', ['3', 'g', 'g'],
330
+ makeCursor(lines[2].line, lines[2].textStart));
331
+ testMotion('G', 'G',
332
+ makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart),
333
+ makeCursor(3, 1));
334
+ testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line,
335
+ lines[2].textStart));
336
+ // TODO: Make the test code long enough to test Ctrl-F and Ctrl-B.
337
+ testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8));
338
+ testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8));
339
+ testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8));
340
+ testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4));
341
+ testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8));
342
+ testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1));
343
+ testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1),
344
+ makeCursor(0, 3));
345
+ testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0));
346
+ testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]);
347
+ testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0));
348
+ testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1),
349
+ makeCursor(charLine.line, 0));
350
+ testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1),
351
+ pChars[0]);
352
+ testMotion('F', ['F', 'p'], pChars[0], pChars[1]);
353
+ testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]);
354
+ testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]);
355
+ testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]);
356
+ testMotion('%_parens', ['%'], parens1.end, parens1.start);
357
+ testMotion('%_squares', ['%'], squares1.end, squares1.start);
358
+ testMotion('%_braces', ['%'], curlys1.end, curlys1.start);
359
+ testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start);
360
+ testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start);
361
+ testVim('%_seek_skip', function(cm, vim, helpers) {
362
+ cm.setCursor(0,0);
363
+ helpers.doKeys(['%']);
364
+ helpers.assertCursorAt(0,9);
365
+ }, {value:'01234"("()'});
366
+ testVim('%_skip_string', function(cm, vim, helpers) {
367
+ cm.setCursor(0,0);
368
+ helpers.doKeys(['%']);
369
+ helpers.assertCursorAt(0,4);
370
+ cm.setCursor(0,2);
371
+ helpers.doKeys(['%']);
372
+ helpers.assertCursorAt(0,0);
373
+ }, {value:'(")")'});
374
+ (')')
375
+ testVim('%_skip_comment', function(cm, vim, helpers) {
376
+ cm.setCursor(0,0);
377
+ helpers.doKeys(['%']);
378
+ helpers.assertCursorAt(0,6);
379
+ cm.setCursor(0,3);
380
+ helpers.doKeys(['%']);
381
+ helpers.assertCursorAt(0,0);
382
+ }, {value:'(/*)*/)'});
383
+ // Make sure that moving down after going to the end of a line always leaves you
384
+ // at the end of a line, but preserves the offset in other cases
385
+ testVim('Changing lines after Eol operation', function(cm, vim, helpers) {
386
+ cm.setCursor(0,0);
387
+ helpers.doKeys(['$']);
388
+ helpers.doKeys(['j']);
389
+ // After moving to Eol and then down, we should be at Eol of line 2
390
+ helpers.assertCursorAt({ line: 1, ch: lines[1].length - 1 });
391
+ helpers.doKeys(['j']);
392
+ // After moving down, we should be at Eol of line 3
393
+ helpers.assertCursorAt({ line: 2, ch: lines[2].length - 1 });
394
+ helpers.doKeys(['h']);
395
+ helpers.doKeys(['j']);
396
+ // After moving back one space and then down, since line 4 is shorter than line 2, we should
397
+ // be at Eol of line 2 - 1
398
+ helpers.assertCursorAt({ line: 3, ch: lines[3].length - 1 });
399
+ helpers.doKeys(['j']);
400
+ helpers.doKeys(['j']);
401
+ // After moving down again, since line 3 has enough characters, we should be back to the
402
+ // same place we were at on line 1
403
+ helpers.assertCursorAt({ line: 5, ch: lines[2].length - 2 });
404
+ });
405
+ //making sure gj and gk recover from clipping
406
+ testVim('gj_gk_clipping', function(cm,vim,helpers){
407
+ cm.setCursor(0, 1);
408
+ helpers.doKeys('g','j','g','j');
409
+ helpers.assertCursorAt(2, 1);
410
+ helpers.doKeys('g','k','g','k');
411
+ helpers.assertCursorAt(0, 1);
412
+ },{value: 'line 1\n\nline 2'});
413
+ //testing a mix of j/k and gj/gk
414
+ testVim('j_k_and_gj_gk', function(cm,vim,helpers){
415
+ cm.setSize(120);
416
+ cm.setCursor(0, 0);
417
+ //go to the last character on the first line
418
+ helpers.doKeys('$');
419
+ //move up/down on the column within the wrapped line
420
+ //side-effect: cursor is not locked to eol anymore
421
+ helpers.doKeys('g','k');
422
+ var cur=cm.getCursor();
423
+ eq(cur.line,0);
424
+ is((cur.ch<176),'gk didn\'t move cursor back (1)');
425
+ helpers.doKeys('g','j');
426
+ helpers.assertCursorAt(0, 176);
427
+ //should move to character 177 on line 2 (j/k preserve character index within line)
428
+ helpers.doKeys('j');
429
+ //due to different line wrapping, the cursor can be on a different screen-x now
430
+ //gj and gk preserve screen-x on movement, much like moveV
431
+ helpers.doKeys('3','g','k');
432
+ cur=cm.getCursor();
433
+ eq(cur.line,1);
434
+ is((cur.ch<176),'gk didn\'t move cursor back (2)');
435
+ helpers.doKeys('g','j','2','g','j');
436
+ //should return to the same character-index
437
+ helpers.doKeys('k');
438
+ helpers.assertCursorAt(0, 176);
439
+ },{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'});
440
+ testVim('gj_gk', function(cm, vim, helpers) {
441
+ if (phantom) return;
442
+ cm.setSize(120);
443
+ // Test top of document edge case.
444
+ cm.setCursor(0, 4);
445
+ helpers.doKeys('g', 'j');
446
+ helpers.doKeys('10', 'g', 'k');
447
+ helpers.assertCursorAt(0, 4);
448
+
449
+ // Test moving down preserves column position.
450
+ helpers.doKeys('g', 'j');
451
+ var pos1 = cm.getCursor();
452
+ var expectedPos2 = { line: 0, ch: (pos1.ch - 4) * 2 + 4};
453
+ helpers.doKeys('g', 'j');
454
+ helpers.assertCursorAt(expectedPos2);
455
+
456
+ // Move to the last character
457
+ cm.setCursor(0, 0);
458
+ // Move left to reset HSPos
459
+ helpers.doKeys('h');
460
+ // Test bottom of document edge case.
461
+ helpers.doKeys('100', 'g', 'j');
462
+ var endingPos = cm.getCursor();
463
+ is(endingPos != 0, 'gj should not be on wrapped line 0');
464
+ var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
465
+ var endingCharCoords = cm.charCoords(endingPos);
466
+ is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
467
+ },{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentiallylongtotestmovementofgjandgkoverwrappedlines.' });
468
+ testVim('}', function(cm, vim, helpers) {
469
+ cm.setCursor(0, 0);
470
+ helpers.doKeys('}');
471
+ helpers.assertCursorAt(1, 0);
472
+ cm.setCursor(0, 0);
473
+ helpers.doKeys('2', '}');
474
+ helpers.assertCursorAt(4, 0);
475
+ cm.setCursor(0, 0);
476
+ helpers.doKeys('6', '}');
477
+ helpers.assertCursorAt(5, 0);
478
+ }, { value: 'a\n\nb\nc\n\nd' });
479
+ testVim('{', function(cm, vim, helpers) {
480
+ cm.setCursor(5, 0);
481
+ helpers.doKeys('{');
482
+ helpers.assertCursorAt(4, 0);
483
+ cm.setCursor(5, 0);
484
+ helpers.doKeys('2', '{');
485
+ helpers.assertCursorAt(1, 0);
486
+ cm.setCursor(5, 0);
487
+ helpers.doKeys('6', '{');
488
+ helpers.assertCursorAt(0, 0);
489
+ }, { value: 'a\n\nb\nc\n\nd' });
490
+
491
+ // Operator tests
492
+ testVim('dl', function(cm, vim, helpers) {
493
+ var curStart = makeCursor(0, 0);
494
+ cm.setCursor(curStart);
495
+ helpers.doKeys('d', 'l');
496
+ eq('word1 ', cm.getValue());
497
+ var register = helpers.getRegisterController().getRegister();
498
+ eq(' ', register.text);
499
+ is(!register.linewise);
500
+ eqPos(curStart, cm.getCursor());
501
+ }, { value: ' word1 ' });
502
+ testVim('dl_eol', function(cm, vim, helpers) {
503
+ cm.setCursor(0, 6);
504
+ helpers.doKeys('d', 'l');
505
+ eq(' word1', cm.getValue());
506
+ var register = helpers.getRegisterController().getRegister();
507
+ eq(' ', register.text);
508
+ is(!register.linewise);
509
+ helpers.assertCursorAt(0, 5);
510
+ }, { value: ' word1 ' });
511
+ testVim('dl_repeat', function(cm, vim, helpers) {
512
+ var curStart = makeCursor(0, 0);
513
+ cm.setCursor(curStart);
514
+ helpers.doKeys('2', 'd', 'l');
515
+ eq('ord1 ', cm.getValue());
516
+ var register = helpers.getRegisterController().getRegister();
517
+ eq(' w', register.text);
518
+ is(!register.linewise);
519
+ eqPos(curStart, cm.getCursor());
520
+ }, { value: ' word1 ' });
521
+ testVim('dh', function(cm, vim, helpers) {
522
+ var curStart = makeCursor(0, 3);
523
+ cm.setCursor(curStart);
524
+ helpers.doKeys('d', 'h');
525
+ eq(' wrd1 ', cm.getValue());
526
+ var register = helpers.getRegisterController().getRegister();
527
+ eq('o', register.text);
528
+ is(!register.linewise);
529
+ eqPos(offsetCursor(curStart, 0 , -1), cm.getCursor());
530
+ }, { value: ' word1 ' });
531
+ testVim('dj', function(cm, vim, helpers) {
532
+ var curStart = makeCursor(0, 3);
533
+ cm.setCursor(curStart);
534
+ helpers.doKeys('d', 'j');
535
+ eq(' word3', cm.getValue());
536
+ var register = helpers.getRegisterController().getRegister();
537
+ eq(' word1\nword2\n', register.text);
538
+ is(register.linewise);
539
+ helpers.assertCursorAt(0, 1);
540
+ }, { value: ' word1\nword2\n word3' });
541
+ testVim('dj_end_of_document', function(cm, vim, helpers) {
542
+ var curStart = makeCursor(0, 3);
543
+ cm.setCursor(curStart);
544
+ helpers.doKeys('d', 'j');
545
+ eq(' word1 ', cm.getValue());
546
+ var register = helpers.getRegisterController().getRegister();
547
+ eq('', register.text);
548
+ is(!register.linewise);
549
+ helpers.assertCursorAt(0, 3);
550
+ }, { value: ' word1 ' });
551
+ testVim('dk', function(cm, vim, helpers) {
552
+ var curStart = makeCursor(1, 3);
553
+ cm.setCursor(curStart);
554
+ helpers.doKeys('d', 'k');
555
+ eq(' word3', cm.getValue());
556
+ var register = helpers.getRegisterController().getRegister();
557
+ eq(' word1\nword2\n', register.text);
558
+ is(register.linewise);
559
+ helpers.assertCursorAt(0, 1);
560
+ }, { value: ' word1\nword2\n word3' });
561
+ testVim('dk_start_of_document', function(cm, vim, helpers) {
562
+ var curStart = makeCursor(0, 3);
563
+ cm.setCursor(curStart);
564
+ helpers.doKeys('d', 'k');
565
+ eq(' word1 ', cm.getValue());
566
+ var register = helpers.getRegisterController().getRegister();
567
+ eq('', register.text);
568
+ is(!register.linewise);
569
+ helpers.assertCursorAt(0, 3);
570
+ }, { value: ' word1 ' });
571
+ testVim('dw_space', function(cm, vim, helpers) {
572
+ var curStart = makeCursor(0, 0);
573
+ cm.setCursor(curStart);
574
+ helpers.doKeys('d', 'w');
575
+ eq('word1 ', cm.getValue());
576
+ var register = helpers.getRegisterController().getRegister();
577
+ eq(' ', register.text);
578
+ is(!register.linewise);
579
+ eqPos(curStart, cm.getCursor());
580
+ }, { value: ' word1 ' });
581
+ testVim('dw_word', function(cm, vim, helpers) {
582
+ var curStart = makeCursor(0, 1);
583
+ cm.setCursor(curStart);
584
+ helpers.doKeys('d', 'w');
585
+ eq(' word2', cm.getValue());
586
+ var register = helpers.getRegisterController().getRegister();
587
+ eq('word1 ', register.text);
588
+ is(!register.linewise);
589
+ eqPos(curStart, cm.getCursor());
590
+ }, { value: ' word1 word2' });
591
+ testVim('dw_only_word', function(cm, vim, helpers) {
592
+ // Test that if there is only 1 word left, dw deletes till the end of the
593
+ // line.
594
+ cm.setCursor(0, 1);
595
+ helpers.doKeys('d', 'w');
596
+ eq(' ', cm.getValue());
597
+ var register = helpers.getRegisterController().getRegister();
598
+ eq('word1 ', register.text);
599
+ is(!register.linewise);
600
+ helpers.assertCursorAt(0, 0);
601
+ }, { value: ' word1 ' });
602
+ testVim('dw_eol', function(cm, vim, helpers) {
603
+ // Assert that dw does not delete the newline if last word to delete is at end
604
+ // of line.
605
+ cm.setCursor(0, 1);
606
+ helpers.doKeys('d', 'w');
607
+ eq(' \nword2', cm.getValue());
608
+ var register = helpers.getRegisterController().getRegister();
609
+ eq('word1', register.text);
610
+ is(!register.linewise);
611
+ helpers.assertCursorAt(0, 0);
612
+ }, { value: ' word1\nword2' });
613
+ testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) {
614
+ // Assert that dw does not delete the newline if last word to delete is at end
615
+ // of line and it is followed by multiple newlines.
616
+ cm.setCursor(0, 1);
617
+ helpers.doKeys('d', 'w');
618
+ eq(' \n\nword2', cm.getValue());
619
+ var register = helpers.getRegisterController().getRegister();
620
+ eq('word1', register.text);
621
+ is(!register.linewise);
622
+ helpers.assertCursorAt(0, 0);
623
+ }, { value: ' word1\n\nword2' });
624
+ testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) {
625
+ cm.setCursor(0, 0);
626
+ helpers.doKeys('d', 'w');
627
+ eq(' \nword', cm.getValue());
628
+ }, { value: '\n \nword' });
629
+ testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) {
630
+ cm.setCursor(0, 0);
631
+ helpers.doKeys('d', 'w');
632
+ eq('word', cm.getValue());
633
+ }, { value: '\nword' });
634
+ testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) {
635
+ cm.setCursor(0, 0);
636
+ helpers.doKeys('d', 'w');
637
+ eq('\n', cm.getValue());
638
+ }, { value: '\n\n' });
639
+ testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) {
640
+ cm.setCursor(0, 0);
641
+ helpers.doKeys('d', 'w');
642
+ eq('\n \n', cm.getValue());
643
+ }, { value: ' \n \n' });
644
+ testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) {
645
+ cm.setCursor(0, 0);
646
+ helpers.doKeys('d', 'w');
647
+ eq('\n\n', cm.getValue());
648
+ }, { value: ' \n\n' });
649
+ testVim('dw_word_whitespace_word', function(cm, vim, helpers) {
650
+ cm.setCursor(0, 0);
651
+ helpers.doKeys('d', 'w');
652
+ eq('\n \nword2', cm.getValue());
653
+ }, { value: 'word1\n \nword2'})
654
+ testVim('dw_end_of_document', function(cm, vim, helpers) {
655
+ cm.setCursor(1, 2);
656
+ helpers.doKeys('d', 'w');
657
+ eq('\nab', cm.getValue());
658
+ }, { value: '\nabc' });
659
+ testVim('dw_repeat', function(cm, vim, helpers) {
660
+ // Assert that dw does delete newline if it should go to the next line, and
661
+ // that repeat works properly.
662
+ cm.setCursor(0, 1);
663
+ helpers.doKeys('d', '2', 'w');
664
+ eq(' ', cm.getValue());
665
+ var register = helpers.getRegisterController().getRegister();
666
+ eq('word1\nword2', register.text);
667
+ is(!register.linewise);
668
+ helpers.assertCursorAt(0, 0);
669
+ }, { value: ' word1\nword2' });
670
+ testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) {
671
+ cm.setCursor(0, 0);
672
+ helpers.doKeys('d', 'e');
673
+ eq('\n\n', cm.getValue());
674
+ }, { value: 'word\n\n' });
675
+ testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) {
676
+ cm.setCursor(0, 3);
677
+ helpers.doKeys('d', 'e');
678
+ eq('wor', cm.getValue());
679
+ }, { value: 'word\n\n\n' });
680
+ testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) {
681
+ cm.setCursor(0, 0);
682
+ helpers.doKeys('d', 'e');
683
+ eq('', cm.getValue());
684
+ }, { value: ' \n\n\n' });
685
+ testVim('de_end_of_document', function(cm, vim, helpers) {
686
+ cm.setCursor(1, 2);
687
+ helpers.doKeys('d', 'e');
688
+ eq('\nab', cm.getValue());
689
+ }, { value: '\nabc' });
690
+ testVim('db_empty_lines', function(cm, vim, helpers) {
691
+ cm.setCursor(2, 0);
692
+ helpers.doKeys('d', 'b');
693
+ eq('\n\n', cm.getValue());
694
+ }, { value: '\n\n\n' });
695
+ testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) {
696
+ cm.setCursor(2, 0);
697
+ helpers.doKeys('d', 'b');
698
+ eq('\nword', cm.getValue());
699
+ }, { value: '\n\nword' });
700
+ testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) {
701
+ cm.setCursor(2, 3);
702
+ helpers.doKeys('d', 'b');
703
+ eq('\n\nd', cm.getValue());
704
+ }, { value: '\n\nword' });
705
+ testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) {
706
+ cm.setCursor(2, 0);
707
+ helpers.doKeys('d', 'b');
708
+ eq('', cm.getValue());
709
+ }, { value: '\n \n' });
710
+ testVim('db_start_of_document', function(cm, vim, helpers) {
711
+ cm.setCursor(0, 0);
712
+ helpers.doKeys('d', 'b');
713
+ eq('abc\n', cm.getValue());
714
+ }, { value: 'abc\n' });
715
+ testVim('dge_empty_lines', function(cm, vim, helpers) {
716
+ cm.setCursor(1, 0);
717
+ helpers.doKeys('d', 'g', 'e');
718
+ // Note: In real VIM the result should be '', but it's not quite consistent,
719
+ // since 2 newlines are deleted. But in the similar case of word\n\n, only
720
+ // 1 newline is deleted. We'll diverge from VIM's behavior since it's much
721
+ // easier this way.
722
+ eq('\n', cm.getValue());
723
+ }, { value: '\n\n' });
724
+ testVim('dge_word_and_empty_lines', function(cm, vim, helpers) {
725
+ cm.setCursor(1, 0);
726
+ helpers.doKeys('d', 'g', 'e');
727
+ eq('wor\n', cm.getValue());
728
+ }, { value: 'word\n\n'});
729
+ testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) {
730
+ cm.setCursor(2, 0);
731
+ helpers.doKeys('d', 'g', 'e');
732
+ eq('', cm.getValue());
733
+ }, { value: '\n \n' });
734
+ testVim('dge_start_of_document', function(cm, vim, helpers) {
735
+ cm.setCursor(0, 0);
736
+ helpers.doKeys('d', 'g', 'e');
737
+ eq('bc\n', cm.getValue());
738
+ }, { value: 'abc\n' });
739
+ testVim('d_inclusive', function(cm, vim, helpers) {
740
+ // Assert that when inclusive is set, the character the cursor is on gets
741
+ // deleted too.
742
+ var curStart = makeCursor(0, 1);
743
+ cm.setCursor(curStart);
744
+ helpers.doKeys('d', 'e');
745
+ eq(' ', cm.getValue());
746
+ var register = helpers.getRegisterController().getRegister();
747
+ eq('word1', register.text);
748
+ is(!register.linewise);
749
+ eqPos(curStart, cm.getCursor());
750
+ }, { value: ' word1 ' });
751
+ testVim('d_reverse', function(cm, vim, helpers) {
752
+ // Test that deleting in reverse works.
753
+ cm.setCursor(1, 0);
754
+ helpers.doKeys('d', 'b');
755
+ eq(' word2 ', cm.getValue());
756
+ var register = helpers.getRegisterController().getRegister();
757
+ eq('word1\n', register.text);
758
+ is(!register.linewise);
759
+ helpers.assertCursorAt(0, 1);
760
+ }, { value: ' word1\nword2 ' });
761
+ testVim('dd', function(cm, vim, helpers) {
762
+ cm.setCursor(0, 3);
763
+ var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
764
+ { line: 1, ch: 0 });
765
+ var expectedLineCount = cm.lineCount() - 1;
766
+ helpers.doKeys('d', 'd');
767
+ eq(expectedLineCount, cm.lineCount());
768
+ var register = helpers.getRegisterController().getRegister();
769
+ eq(expectedBuffer, register.text);
770
+ is(register.linewise);
771
+ helpers.assertCursorAt(0, lines[1].textStart);
772
+ });
773
+ testVim('dd_prefix_repeat', function(cm, vim, helpers) {
774
+ cm.setCursor(0, 3);
775
+ var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
776
+ { line: 2, ch: 0 });
777
+ var expectedLineCount = cm.lineCount() - 2;
778
+ helpers.doKeys('2', 'd', 'd');
779
+ eq(expectedLineCount, cm.lineCount());
780
+ var register = helpers.getRegisterController().getRegister();
781
+ eq(expectedBuffer, register.text);
782
+ is(register.linewise);
783
+ helpers.assertCursorAt(0, lines[2].textStart);
784
+ });
785
+ testVim('dd_motion_repeat', function(cm, vim, helpers) {
786
+ cm.setCursor(0, 3);
787
+ var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
788
+ { line: 2, ch: 0 });
789
+ var expectedLineCount = cm.lineCount() - 2;
790
+ helpers.doKeys('d', '2', 'd');
791
+ eq(expectedLineCount, cm.lineCount());
792
+ var register = helpers.getRegisterController().getRegister();
793
+ eq(expectedBuffer, register.text);
794
+ is(register.linewise);
795
+ helpers.assertCursorAt(0, lines[2].textStart);
796
+ });
797
+ testVim('dd_multiply_repeat', function(cm, vim, helpers) {
798
+ cm.setCursor(0, 3);
799
+ var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
800
+ { line: 6, ch: 0 });
801
+ var expectedLineCount = cm.lineCount() - 6;
802
+ helpers.doKeys('2', 'd', '3', 'd');
803
+ eq(expectedLineCount, cm.lineCount());
804
+ var register = helpers.getRegisterController().getRegister();
805
+ eq(expectedBuffer, register.text);
806
+ is(register.linewise);
807
+ helpers.assertCursorAt(0, lines[6].textStart);
808
+ });
809
+ testVim('dd_lastline', function(cm, vim, helpers) {
810
+ cm.setCursor(cm.lineCount(), 0);
811
+ var expectedLineCount = cm.lineCount() - 1;
812
+ helpers.doKeys('d', 'd');
813
+ eq(expectedLineCount, cm.lineCount());
814
+ helpers.assertCursorAt(cm.lineCount() - 1, 0);
815
+ });
816
+ // Yank commands should behave the exact same as d commands, expect that nothing
817
+ // gets deleted.
818
+ testVim('yw_repeat', function(cm, vim, helpers) {
819
+ // Assert that yw does yank newline if it should go to the next line, and
820
+ // that repeat works properly.
821
+ var curStart = makeCursor(0, 1);
822
+ cm.setCursor(curStart);
823
+ helpers.doKeys('y', '2', 'w');
824
+ eq(' word1\nword2', cm.getValue());
825
+ var register = helpers.getRegisterController().getRegister();
826
+ eq('word1\nword2', register.text);
827
+ is(!register.linewise);
828
+ eqPos(curStart, cm.getCursor());
829
+ }, { value: ' word1\nword2' });
830
+ testVim('yy_multiply_repeat', function(cm, vim, helpers) {
831
+ var curStart = makeCursor(0, 3);
832
+ cm.setCursor(curStart);
833
+ var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
834
+ { line: 6, ch: 0 });
835
+ var expectedLineCount = cm.lineCount();
836
+ helpers.doKeys('2', 'y', '3', 'y');
837
+ eq(expectedLineCount, cm.lineCount());
838
+ var register = helpers.getRegisterController().getRegister();
839
+ eq(expectedBuffer, register.text);
840
+ is(register.linewise);
841
+ eqPos(curStart, cm.getCursor());
842
+ });
843
+ // Change commands behave like d commands except that it also enters insert
844
+ // mode. In addition, when the change is linewise, an additional newline is
845
+ // inserted so that insert mode starts on that line.
846
+ testVim('cw', function(cm, vim, helpers) {
847
+ cm.setCursor(0, 0);
848
+ helpers.doKeys('c', '2', 'w');
849
+ eq(' word3', cm.getValue());
850
+ helpers.assertCursorAt(0, 0);
851
+ }, { value: 'word1 word2 word3'});
852
+ testVim('cw_repeat', function(cm, vim, helpers) {
853
+ // Assert that cw does delete newline if it should go to the next line, and
854
+ // that repeat works properly.
855
+ var curStart = makeCursor(0, 1);
856
+ cm.setCursor(curStart);
857
+ helpers.doKeys('c', '2', 'w');
858
+ eq(' ', cm.getValue());
859
+ var register = helpers.getRegisterController().getRegister();
860
+ eq('word1\nword2', register.text);
861
+ is(!register.linewise);
862
+ eqPos(curStart, cm.getCursor());
863
+ eq('vim-insert', cm.getOption('keyMap'));
864
+ }, { value: ' word1\nword2' });
865
+ testVim('cc_multiply_repeat', function(cm, vim, helpers) {
866
+ cm.setCursor(0, 3);
867
+ var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
868
+ { line: 6, ch: 0 });
869
+ var expectedLineCount = cm.lineCount() - 5;
870
+ helpers.doKeys('2', 'c', '3', 'c');
871
+ eq(expectedLineCount, cm.lineCount());
872
+ var register = helpers.getRegisterController().getRegister();
873
+ eq(expectedBuffer, register.text);
874
+ is(register.linewise);
875
+ eq('vim-insert', cm.getOption('keyMap'));
876
+ });
877
+ testVim('cc_append', function(cm, vim, helpers) {
878
+ var expectedLineCount = cm.lineCount();
879
+ cm.setCursor(cm.lastLine(), 0);
880
+ helpers.doKeys('c', 'c');
881
+ eq(expectedLineCount, cm.lineCount());
882
+ });
883
+ // Swapcase commands edit in place and do not modify registers.
884
+ testVim('g~w_repeat', function(cm, vim, helpers) {
885
+ // Assert that dw does delete newline if it should go to the next line, and
886
+ // that repeat works properly.
887
+ var curStart = makeCursor(0, 1);
888
+ cm.setCursor(curStart);
889
+ helpers.doKeys('g', '~', '2', 'w');
890
+ eq(' WORD1\nWORD2', cm.getValue());
891
+ var register = helpers.getRegisterController().getRegister();
892
+ eq('', register.text);
893
+ is(!register.linewise);
894
+ eqPos(curStart, cm.getCursor());
895
+ }, { value: ' word1\nword2' });
896
+ testVim('g~g~', function(cm, vim, helpers) {
897
+ var curStart = makeCursor(0, 3);
898
+ cm.setCursor(curStart);
899
+ var expectedLineCount = cm.lineCount();
900
+ var expectedValue = cm.getValue().toUpperCase();
901
+ helpers.doKeys('2', 'g', '~', '3', 'g', '~');
902
+ eq(expectedValue, cm.getValue());
903
+ var register = helpers.getRegisterController().getRegister();
904
+ eq('', register.text);
905
+ is(!register.linewise);
906
+ eqPos(curStart, cm.getCursor());
907
+ }, { value: ' word1\nword2\nword3\nword4\nword5\nword6' });
908
+ testVim('>{motion}', function(cm, vim, helpers) {
909
+ cm.setCursor(1, 3);
910
+ var expectedLineCount = cm.lineCount();
911
+ var expectedValue = ' word1\n word2\nword3 ';
912
+ helpers.doKeys('>', 'k');
913
+ eq(expectedValue, cm.getValue());
914
+ var register = helpers.getRegisterController().getRegister();
915
+ eq('', register.text);
916
+ is(!register.linewise);
917
+ helpers.assertCursorAt(0, 3);
918
+ }, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
919
+ testVim('>>', function(cm, vim, helpers) {
920
+ cm.setCursor(0, 3);
921
+ var expectedLineCount = cm.lineCount();
922
+ var expectedValue = ' word1\n word2\nword3 ';
923
+ helpers.doKeys('2', '>', '>');
924
+ eq(expectedValue, cm.getValue());
925
+ var register = helpers.getRegisterController().getRegister();
926
+ eq('', register.text);
927
+ is(!register.linewise);
928
+ helpers.assertCursorAt(0, 3);
929
+ }, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
930
+ testVim('<{motion}', function(cm, vim, helpers) {
931
+ cm.setCursor(1, 3);
932
+ var expectedLineCount = cm.lineCount();
933
+ var expectedValue = ' word1\nword2\nword3 ';
934
+ helpers.doKeys('<', 'k');
935
+ eq(expectedValue, cm.getValue());
936
+ var register = helpers.getRegisterController().getRegister();
937
+ eq('', register.text);
938
+ is(!register.linewise);
939
+ helpers.assertCursorAt(0, 1);
940
+ }, { value: ' word1\n word2\nword3 ', indentUnit: 2 });
941
+ testVim('<<', function(cm, vim, helpers) {
942
+ cm.setCursor(0, 3);
943
+ var expectedLineCount = cm.lineCount();
944
+ var expectedValue = ' word1\nword2\nword3 ';
945
+ helpers.doKeys('2', '<', '<');
946
+ eq(expectedValue, cm.getValue());
947
+ var register = helpers.getRegisterController().getRegister();
948
+ eq('', register.text);
949
+ is(!register.linewise);
950
+ helpers.assertCursorAt(0, 1);
951
+ }, { value: ' word1\n word2\nword3 ', indentUnit: 2 });
952
+
953
+ // Edit tests
954
+ function testEdit(name, before, pos, edit, after) {
955
+ return testVim(name, function(cm, vim, helpers) {
956
+ cm.setCursor(0, before.search(pos));
957
+ helpers.doKeys.apply(this, edit.split(''));
958
+ eq(after, cm.getValue());
959
+ }, {value: before});
960
+ }
961
+
962
+ // These Delete tests effectively cover word-wise Change, Visual & Yank.
963
+ // Tabs are used as differentiated whitespace to catch edge cases.
964
+ // Normal word:
965
+ testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz');
966
+ testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz');
967
+ testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz');
968
+ testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz');
969
+ testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz');
970
+ testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz');
971
+ testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz');
972
+ testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz');
973
+ testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz');
974
+ testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz');
975
+ testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t');
976
+ testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo');
977
+ testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.');
978
+ testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.');
979
+ // Big word:
980
+ testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz');
981
+ testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz');
982
+ testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz');
983
+ testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz');
984
+ testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz');
985
+ testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz');
986
+ testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz');
987
+ testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz');
988
+ testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz');
989
+ testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz');
990
+ testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t');
991
+ testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo');
992
+ testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t');
993
+ testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo');
994
+
995
+ // Operator-motion tests
996
+ testVim('D', function(cm, vim, helpers) {
997
+ cm.setCursor(0, 3);
998
+ helpers.doKeys('D');
999
+ eq(' wo\nword2\n word3', cm.getValue());
1000
+ var register = helpers.getRegisterController().getRegister();
1001
+ eq('rd1', register.text);
1002
+ is(!register.linewise);
1003
+ helpers.assertCursorAt(0, 2);
1004
+ }, { value: ' word1\nword2\n word3' });
1005
+ testVim('C', function(cm, vim, helpers) {
1006
+ var curStart = makeCursor(0, 3);
1007
+ cm.setCursor(curStart);
1008
+ helpers.doKeys('C');
1009
+ eq(' wo\nword2\n word3', cm.getValue());
1010
+ var register = helpers.getRegisterController().getRegister();
1011
+ eq('rd1', register.text);
1012
+ is(!register.linewise);
1013
+ eqPos(curStart, cm.getCursor());
1014
+ eq('vim-insert', cm.getOption('keyMap'));
1015
+ }, { value: ' word1\nword2\n word3' });
1016
+ testVim('Y', function(cm, vim, helpers) {
1017
+ var curStart = makeCursor(0, 3);
1018
+ cm.setCursor(curStart);
1019
+ helpers.doKeys('Y');
1020
+ eq(' word1\nword2\n word3', cm.getValue());
1021
+ var register = helpers.getRegisterController().getRegister();
1022
+ eq('rd1', register.text);
1023
+ is(!register.linewise);
1024
+ helpers.assertCursorAt(0, 3);
1025
+ }, { value: ' word1\nword2\n word3' });
1026
+ testVim('~', function(cm, vim, helpers) {
1027
+ helpers.doKeys('3', '~');
1028
+ eq('ABCdefg', cm.getValue());
1029
+ helpers.assertCursorAt(0, 3);
1030
+ }, { value: 'abcdefg' });
1031
+
1032
+ // Action tests
1033
+ testVim('ctrl-a', function(cm, vim, helpers) {
1034
+ cm.setCursor(0, 0);
1035
+ helpers.doKeys('<C-a>');
1036
+ eq('-9', cm.getValue());
1037
+ helpers.assertCursorAt(0, 1);
1038
+ helpers.doKeys('2','<C-a>');
1039
+ eq('-7', cm.getValue());
1040
+ }, {value: '-10'});
1041
+ testVim('ctrl-x', function(cm, vim, helpers) {
1042
+ cm.setCursor(0, 0);
1043
+ helpers.doKeys('<C-x>');
1044
+ eq('-1', cm.getValue());
1045
+ helpers.assertCursorAt(0, 1);
1046
+ helpers.doKeys('2','<C-x>');
1047
+ eq('-3', cm.getValue());
1048
+ }, {value: '0'});
1049
+ testVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {
1050
+ ['<C-x>', '<C-a>'].forEach(function(key) {
1051
+ cm.setCursor(0, 0);
1052
+ helpers.doKeys(key);
1053
+ helpers.assertCursorAt(0, 5);
1054
+ helpers.doKeys('l');
1055
+ helpers.doKeys(key);
1056
+ helpers.assertCursorAt(0, 10);
1057
+ cm.setCursor(0, 11);
1058
+ helpers.doKeys(key);
1059
+ helpers.assertCursorAt(0, 11);
1060
+ });
1061
+ }, {value: '__jmp1 jmp2 jmp'});
1062
+ testVim('a', function(cm, vim, helpers) {
1063
+ cm.setCursor(0, 1);
1064
+ helpers.doKeys('a');
1065
+ helpers.assertCursorAt(0, 2);
1066
+ eq('vim-insert', cm.getOption('keyMap'));
1067
+ });
1068
+ testVim('a_eol', function(cm, vim, helpers) {
1069
+ cm.setCursor(0, lines[0].length - 1);
1070
+ helpers.doKeys('a');
1071
+ helpers.assertCursorAt(0, lines[0].length);
1072
+ eq('vim-insert', cm.getOption('keyMap'));
1073
+ });
1074
+ testVim('i', function(cm, vim, helpers) {
1075
+ cm.setCursor(0, 1);
1076
+ helpers.doKeys('i');
1077
+ helpers.assertCursorAt(0, 1);
1078
+ eq('vim-insert', cm.getOption('keyMap'));
1079
+ });
1080
+ testVim('i_repeat', function(cm, vim, helpers) {
1081
+ helpers.doKeys('3', 'i');
1082
+ cm.replaceRange('test', cm.getCursor());
1083
+ helpers.doInsertModeKeys('Esc');
1084
+ eq('testtesttest', cm.getValue());
1085
+ helpers.assertCursorAt(0, 11);
1086
+ }, { value: '' });
1087
+ testVim('i_repeat_delete', function(cm, vim, helpers) {
1088
+ cm.setCursor(0, 4);
1089
+ helpers.doKeys('2', 'i');
1090
+ cm.replaceRange('z', cm.getCursor());
1091
+ helpers.doInsertModeKeys('Backspace', 'Backspace', 'Esc');
1092
+ eq('abe', cm.getValue());
1093
+ helpers.assertCursorAt(0, 1);
1094
+ }, { value: 'abcde' });
1095
+ testVim('A', function(cm, vim, helpers) {
1096
+ helpers.doKeys('A');
1097
+ helpers.assertCursorAt(0, lines[0].length);
1098
+ eq('vim-insert', cm.getOption('keyMap'));
1099
+ });
1100
+ testVim('I', function(cm, vim, helpers) {
1101
+ cm.setCursor(0, 4);
1102
+ helpers.doKeys('I');
1103
+ helpers.assertCursorAt(0, lines[0].textStart);
1104
+ eq('vim-insert', cm.getOption('keyMap'));
1105
+ });
1106
+ testVim('I_repeat', function(cm, vim, helpers) {
1107
+ cm.setCursor(0, 1);
1108
+ helpers.doKeys('3', 'I');
1109
+ cm.replaceRange('test', cm.getCursor());
1110
+ helpers.doInsertModeKeys('Esc');
1111
+ eq('testtesttestblah', cm.getValue());
1112
+ helpers.assertCursorAt(0, 11);
1113
+ }, { value: 'blah' });
1114
+ testVim('o', function(cm, vim, helpers) {
1115
+ cm.setCursor(0, 4);
1116
+ helpers.doKeys('o');
1117
+ eq('word1\n\nword2', cm.getValue());
1118
+ helpers.assertCursorAt(1, 0);
1119
+ eq('vim-insert', cm.getOption('keyMap'));
1120
+ }, { value: 'word1\nword2' });
1121
+ testVim('o_repeat', function(cm, vim, helpers) {
1122
+ cm.setCursor(0, 0);
1123
+ helpers.doKeys('3', 'o');
1124
+ cm.replaceRange('test', cm.getCursor());
1125
+ helpers.doInsertModeKeys('Esc');
1126
+ eq('\ntest\ntest\ntest', cm.getValue());
1127
+ helpers.assertCursorAt(3, 3);
1128
+ }, { value: '' });
1129
+ testVim('O', function(cm, vim, helpers) {
1130
+ cm.setCursor(0, 4);
1131
+ helpers.doKeys('O');
1132
+ eq('\nword1\nword2', cm.getValue());
1133
+ helpers.assertCursorAt(0, 0);
1134
+ eq('vim-insert', cm.getOption('keyMap'));
1135
+ }, { value: 'word1\nword2' });
1136
+ testVim('J', function(cm, vim, helpers) {
1137
+ cm.setCursor(0, 4);
1138
+ helpers.doKeys('J');
1139
+ var expectedValue = 'word1 word2\nword3\n word4';
1140
+ eq(expectedValue, cm.getValue());
1141
+ helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1);
1142
+ }, { value: 'word1 \n word2\nword3\n word4' });
1143
+ testVim('J_repeat', function(cm, vim, helpers) {
1144
+ cm.setCursor(0, 4);
1145
+ helpers.doKeys('3', 'J');
1146
+ var expectedValue = 'word1 word2 word3\n word4';
1147
+ eq(expectedValue, cm.getValue());
1148
+ helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1);
1149
+ }, { value: 'word1 \n word2\nword3\n word4' });
1150
+ testVim('p', function(cm, vim, helpers) {
1151
+ cm.setCursor(0, 1);
1152
+ helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
1153
+ helpers.doKeys('p');
1154
+ eq('__abc\ndef_', cm.getValue());
1155
+ helpers.assertCursorAt(1, 2);
1156
+ }, { value: '___' });
1157
+ testVim('p_register', function(cm, vim, helpers) {
1158
+ cm.setCursor(0, 1);
1159
+ helpers.getRegisterController().getRegister('a').set('abc\ndef', false);
1160
+ helpers.doKeys('"', 'a', 'p');
1161
+ eq('__abc\ndef_', cm.getValue());
1162
+ helpers.assertCursorAt(1, 2);
1163
+ }, { value: '___' });
1164
+ testVim('p_wrong_register', function(cm, vim, helpers) {
1165
+ cm.setCursor(0, 1);
1166
+ helpers.getRegisterController().getRegister('a').set('abc\ndef', false);
1167
+ helpers.doKeys('p');
1168
+ eq('___', cm.getValue());
1169
+ helpers.assertCursorAt(0, 1);
1170
+ }, { value: '___' });
1171
+ testVim('p_line', function(cm, vim, helpers) {
1172
+ cm.setCursor(0, 1);
1173
+ helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true);
1174
+ helpers.doKeys('2', 'p');
1175
+ eq('___\n a\nd\n a\nd', cm.getValue());
1176
+ helpers.assertCursorAt(1, 2);
1177
+ }, { value: '___' });
1178
+ testVim('p_lastline', function(cm, vim, helpers) {
1179
+ cm.setCursor(0, 1);
1180
+ helpers.getRegisterController().pushText('"', 'yank', ' a\nd', true);
1181
+ helpers.doKeys('2', 'p');
1182
+ eq('___\n a\nd\n a\nd', cm.getValue());
1183
+ helpers.assertCursorAt(1, 2);
1184
+ }, { value: '___' });
1185
+ testVim('P', function(cm, vim, helpers) {
1186
+ cm.setCursor(0, 1);
1187
+ helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
1188
+ helpers.doKeys('P');
1189
+ eq('_abc\ndef__', cm.getValue());
1190
+ helpers.assertCursorAt(1, 3);
1191
+ }, { value: '___' });
1192
+ testVim('P_line', function(cm, vim, helpers) {
1193
+ cm.setCursor(0, 1);
1194
+ helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true);
1195
+ helpers.doKeys('2', 'P');
1196
+ eq(' a\nd\n a\nd\n___', cm.getValue());
1197
+ helpers.assertCursorAt(0, 2);
1198
+ }, { value: '___' });
1199
+ testVim('r', function(cm, vim, helpers) {
1200
+ cm.setCursor(0, 1);
1201
+ helpers.doKeys('3', 'r', 'u');
1202
+ eq('wuuuet\nanother', cm.getValue(),'3r failed');
1203
+ helpers.assertCursorAt(0, 3);
1204
+ cm.setCursor(0, 4);
1205
+ helpers.doKeys('v', 'j', 'h', 'r', '<Space>');
1206
+ eq('wuuu \n her', cm.getValue(),'Replacing selection by space-characters failed');
1207
+ }, { value: 'wordet\nanother' });
1208
+ testVim('R', function(cm, vim, helpers) {
1209
+ cm.setCursor(0, 1);
1210
+ helpers.doKeys('R');
1211
+ helpers.assertCursorAt(0, 1);
1212
+ eq('vim-replace', cm.getOption('keyMap'));
1213
+ is(cm.state.overwrite, 'Setting overwrite state failed');
1214
+ });
1215
+ testVim('mark', function(cm, vim, helpers) {
1216
+ cm.setCursor(2, 2);
1217
+ helpers.doKeys('m', 't');
1218
+ cm.setCursor(0, 0);
1219
+ helpers.doKeys('\'', 't');
1220
+ helpers.assertCursorAt(2, 2);
1221
+ cm.setCursor(0, 0);
1222
+ helpers.doKeys('`', 't');
1223
+ helpers.assertCursorAt(2, 2);
1224
+ });
1225
+ testVim('jumpToMark_next', function(cm, vim, helpers) {
1226
+ cm.setCursor(2, 2);
1227
+ helpers.doKeys('m', 't');
1228
+ cm.setCursor(0, 0);
1229
+ helpers.doKeys(']', '`');
1230
+ helpers.assertCursorAt(2, 2);
1231
+ cm.setCursor(0, 0);
1232
+ helpers.doKeys(']', '\'');
1233
+ helpers.assertCursorAt(2, 0);
1234
+ });
1235
+ testVim('jumpToMark_next_repeat', function(cm, vim, helpers) {
1236
+ cm.setCursor(2, 2);
1237
+ helpers.doKeys('m', 'a');
1238
+ cm.setCursor(3, 2);
1239
+ helpers.doKeys('m', 'b');
1240
+ cm.setCursor(4, 2);
1241
+ helpers.doKeys('m', 'c');
1242
+ cm.setCursor(0, 0);
1243
+ helpers.doKeys('2', ']', '`');
1244
+ helpers.assertCursorAt(3, 2);
1245
+ cm.setCursor(0, 0);
1246
+ helpers.doKeys('2', ']', '\'');
1247
+ helpers.assertCursorAt(3, 1);
1248
+ });
1249
+ testVim('jumpToMark_next_sameline', function(cm, vim, helpers) {
1250
+ cm.setCursor(2, 0);
1251
+ helpers.doKeys('m', 'a');
1252
+ cm.setCursor(2, 4);
1253
+ helpers.doKeys('m', 'b');
1254
+ cm.setCursor(2, 2);
1255
+ helpers.doKeys(']', '`');
1256
+ helpers.assertCursorAt(2, 4);
1257
+ });
1258
+ testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) {
1259
+ cm.setCursor(2, 0);
1260
+ helpers.doKeys('m', 'a');
1261
+ cm.setCursor(4, 0);
1262
+ helpers.doKeys(']', '`');
1263
+ helpers.assertCursorAt(4, 0);
1264
+ });
1265
+ testVim('jumpToMark_next_nomark', function(cm, vim, helpers) {
1266
+ cm.setCursor(2, 2);
1267
+ helpers.doKeys(']', '`');
1268
+ helpers.assertCursorAt(2, 2);
1269
+ helpers.doKeys(']', '\'');
1270
+ helpers.assertCursorAt(2, 0);
1271
+ });
1272
+ testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) {
1273
+ cm.setCursor(2, 2);
1274
+ helpers.doKeys('m', 'a');
1275
+ cm.setCursor(3, 4);
1276
+ helpers.doKeys('m', 'b');
1277
+ cm.setCursor(2, 1);
1278
+ helpers.doKeys(']', '\'');
1279
+ helpers.assertCursorAt(3, 1);
1280
+ });
1281
+ testVim('jumpToMark_next_action', function(cm, vim, helpers) {
1282
+ cm.setCursor(2, 2);
1283
+ helpers.doKeys('m', 't');
1284
+ cm.setCursor(0, 0);
1285
+ helpers.doKeys('d', ']', '`');
1286
+ helpers.assertCursorAt(0, 0);
1287
+ var actual = cm.getLine(0);
1288
+ var expected = 'pop pop 0 1 2 3 4';
1289
+ eq(actual, expected, "Deleting while jumping to the next mark failed.");
1290
+ });
1291
+ testVim('jumpToMark_next_line_action', function(cm, vim, helpers) {
1292
+ cm.setCursor(2, 2);
1293
+ helpers.doKeys('m', 't');
1294
+ cm.setCursor(0, 0);
1295
+ helpers.doKeys('d', ']', '\'');
1296
+ helpers.assertCursorAt(0, 1);
1297
+ var actual = cm.getLine(0);
1298
+ var expected = ' (a) [b] {c} '
1299
+ eq(actual, expected, "Deleting while jumping to the next mark line failed.");
1300
+ });
1301
+ testVim('jumpToMark_prev', function(cm, vim, helpers) {
1302
+ cm.setCursor(2, 2);
1303
+ helpers.doKeys('m', 't');
1304
+ cm.setCursor(4, 0);
1305
+ helpers.doKeys('[', '`');
1306
+ helpers.assertCursorAt(2, 2);
1307
+ cm.setCursor(4, 0);
1308
+ helpers.doKeys('[', '\'');
1309
+ helpers.assertCursorAt(2, 0);
1310
+ });
1311
+ testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) {
1312
+ cm.setCursor(2, 2);
1313
+ helpers.doKeys('m', 'a');
1314
+ cm.setCursor(3, 2);
1315
+ helpers.doKeys('m', 'b');
1316
+ cm.setCursor(4, 2);
1317
+ helpers.doKeys('m', 'c');
1318
+ cm.setCursor(5, 0);
1319
+ helpers.doKeys('2', '[', '`');
1320
+ helpers.assertCursorAt(3, 2);
1321
+ cm.setCursor(5, 0);
1322
+ helpers.doKeys('2', '[', '\'');
1323
+ helpers.assertCursorAt(3, 1);
1324
+ });
1325
+ testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) {
1326
+ cm.setCursor(2, 0);
1327
+ helpers.doKeys('m', 'a');
1328
+ cm.setCursor(2, 4);
1329
+ helpers.doKeys('m', 'b');
1330
+ cm.setCursor(2, 2);
1331
+ helpers.doKeys('[', '`');
1332
+ helpers.assertCursorAt(2, 0);
1333
+ });
1334
+ testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) {
1335
+ cm.setCursor(4, 4);
1336
+ helpers.doKeys('m', 'a');
1337
+ cm.setCursor(2, 0);
1338
+ helpers.doKeys('[', '`');
1339
+ helpers.assertCursorAt(2, 0);
1340
+ });
1341
+ testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) {
1342
+ cm.setCursor(2, 2);
1343
+ helpers.doKeys('[', '`');
1344
+ helpers.assertCursorAt(2, 2);
1345
+ helpers.doKeys('[', '\'');
1346
+ helpers.assertCursorAt(2, 0);
1347
+ });
1348
+ testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) {
1349
+ cm.setCursor(2, 2);
1350
+ helpers.doKeys('m', 'a');
1351
+ cm.setCursor(3, 4);
1352
+ helpers.doKeys('m', 'b');
1353
+ cm.setCursor(3, 6);
1354
+ helpers.doKeys('[', '\'');
1355
+ helpers.assertCursorAt(2, 0);
1356
+ });
1357
+ testVim('delmark_single', function(cm, vim, helpers) {
1358
+ cm.setCursor(1, 2);
1359
+ helpers.doKeys('m', 't');
1360
+ helpers.doEx('delmarks t');
1361
+ cm.setCursor(0, 0);
1362
+ helpers.doKeys('`', 't');
1363
+ helpers.assertCursorAt(0, 0);
1364
+ });
1365
+ testVim('delmark_range', function(cm, vim, helpers) {
1366
+ cm.setCursor(1, 2);
1367
+ helpers.doKeys('m', 'a');
1368
+ cm.setCursor(2, 2);
1369
+ helpers.doKeys('m', 'b');
1370
+ cm.setCursor(3, 2);
1371
+ helpers.doKeys('m', 'c');
1372
+ cm.setCursor(4, 2);
1373
+ helpers.doKeys('m', 'd');
1374
+ cm.setCursor(5, 2);
1375
+ helpers.doKeys('m', 'e');
1376
+ helpers.doEx('delmarks b-d');
1377
+ cm.setCursor(0, 0);
1378
+ helpers.doKeys('`', 'a');
1379
+ helpers.assertCursorAt(1, 2);
1380
+ helpers.doKeys('`', 'b');
1381
+ helpers.assertCursorAt(1, 2);
1382
+ helpers.doKeys('`', 'c');
1383
+ helpers.assertCursorAt(1, 2);
1384
+ helpers.doKeys('`', 'd');
1385
+ helpers.assertCursorAt(1, 2);
1386
+ helpers.doKeys('`', 'e');
1387
+ helpers.assertCursorAt(5, 2);
1388
+ });
1389
+ testVim('delmark_multi', function(cm, vim, helpers) {
1390
+ cm.setCursor(1, 2);
1391
+ helpers.doKeys('m', 'a');
1392
+ cm.setCursor(2, 2);
1393
+ helpers.doKeys('m', 'b');
1394
+ cm.setCursor(3, 2);
1395
+ helpers.doKeys('m', 'c');
1396
+ cm.setCursor(4, 2);
1397
+ helpers.doKeys('m', 'd');
1398
+ cm.setCursor(5, 2);
1399
+ helpers.doKeys('m', 'e');
1400
+ helpers.doEx('delmarks bcd');
1401
+ cm.setCursor(0, 0);
1402
+ helpers.doKeys('`', 'a');
1403
+ helpers.assertCursorAt(1, 2);
1404
+ helpers.doKeys('`', 'b');
1405
+ helpers.assertCursorAt(1, 2);
1406
+ helpers.doKeys('`', 'c');
1407
+ helpers.assertCursorAt(1, 2);
1408
+ helpers.doKeys('`', 'd');
1409
+ helpers.assertCursorAt(1, 2);
1410
+ helpers.doKeys('`', 'e');
1411
+ helpers.assertCursorAt(5, 2);
1412
+ });
1413
+ testVim('delmark_multi_space', function(cm, vim, helpers) {
1414
+ cm.setCursor(1, 2);
1415
+ helpers.doKeys('m', 'a');
1416
+ cm.setCursor(2, 2);
1417
+ helpers.doKeys('m', 'b');
1418
+ cm.setCursor(3, 2);
1419
+ helpers.doKeys('m', 'c');
1420
+ cm.setCursor(4, 2);
1421
+ helpers.doKeys('m', 'd');
1422
+ cm.setCursor(5, 2);
1423
+ helpers.doKeys('m', 'e');
1424
+ helpers.doEx('delmarks b c d');
1425
+ cm.setCursor(0, 0);
1426
+ helpers.doKeys('`', 'a');
1427
+ helpers.assertCursorAt(1, 2);
1428
+ helpers.doKeys('`', 'b');
1429
+ helpers.assertCursorAt(1, 2);
1430
+ helpers.doKeys('`', 'c');
1431
+ helpers.assertCursorAt(1, 2);
1432
+ helpers.doKeys('`', 'd');
1433
+ helpers.assertCursorAt(1, 2);
1434
+ helpers.doKeys('`', 'e');
1435
+ helpers.assertCursorAt(5, 2);
1436
+ });
1437
+ testVim('delmark_all', function(cm, vim, helpers) {
1438
+ cm.setCursor(1, 2);
1439
+ helpers.doKeys('m', 'a');
1440
+ cm.setCursor(2, 2);
1441
+ helpers.doKeys('m', 'b');
1442
+ cm.setCursor(3, 2);
1443
+ helpers.doKeys('m', 'c');
1444
+ cm.setCursor(4, 2);
1445
+ helpers.doKeys('m', 'd');
1446
+ cm.setCursor(5, 2);
1447
+ helpers.doKeys('m', 'e');
1448
+ helpers.doEx('delmarks a b-de');
1449
+ cm.setCursor(0, 0);
1450
+ helpers.doKeys('`', 'a');
1451
+ helpers.assertCursorAt(0, 0);
1452
+ helpers.doKeys('`', 'b');
1453
+ helpers.assertCursorAt(0, 0);
1454
+ helpers.doKeys('`', 'c');
1455
+ helpers.assertCursorAt(0, 0);
1456
+ helpers.doKeys('`', 'd');
1457
+ helpers.assertCursorAt(0, 0);
1458
+ helpers.doKeys('`', 'e');
1459
+ helpers.assertCursorAt(0, 0);
1460
+ });
1461
+ testVim('visual', function(cm, vim, helpers) {
1462
+ helpers.doKeys('l', 'v', 'l', 'l');
1463
+ helpers.assertCursorAt(0, 3);
1464
+ eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
1465
+ helpers.doKeys('d');
1466
+ eq('15', cm.getValue());
1467
+ }, { value: '12345' });
1468
+ testVim('visual_line', function(cm, vim, helpers) {
1469
+ helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');
1470
+ eq(' 4\n 5', cm.getValue());
1471
+ }, { value: ' 1\n 2\n 3\n 4\n 5' });
1472
+ testVim('visual_marks', function(cm, vim, helpers) {
1473
+ helpers.doKeys('l', 'v', 'l', 'l', 'v');
1474
+ // Test visual mode marks
1475
+ cm.setCursor(0, 0);
1476
+ helpers.doKeys('\'', '<');
1477
+ helpers.assertCursorAt(0, 1);
1478
+ helpers.doKeys('\'', '>');
1479
+ helpers.assertCursorAt(0, 3);
1480
+ });
1481
+ testVim('visual_join', function(cm, vim, helpers) {
1482
+ helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J');
1483
+ eq(' 1 2 3\n 4\n 5', cm.getValue());
1484
+ }, { value: ' 1\n 2\n 3\n 4\n 5' });
1485
+ testVim('visual_blank', function(cm, vim, helpers) {
1486
+ helpers.doKeys('v', 'k');
1487
+ eq(vim.visualMode, true);
1488
+ }, { value: '\n' });
1489
+ testVim('s_normal', function(cm, vim, helpers) {
1490
+ cm.setCursor(0, 1);
1491
+ helpers.doKeys('s');
1492
+ helpers.doInsertModeKeys('Esc');
1493
+ helpers.assertCursorAt(0, 0);
1494
+ eq('ac', cm.getValue());
1495
+ }, { value: 'abc'});
1496
+ testVim('s_visual', function(cm, vim, helpers) {
1497
+ cm.setCursor(0, 1);
1498
+ helpers.doKeys('v', 's');
1499
+ helpers.doInsertModeKeys('Esc');
1500
+ helpers.assertCursorAt(0, 0);
1501
+ eq('ac', cm.getValue());
1502
+ }, { value: 'abc'});
1503
+ testVim('S_normal', function(cm, vim, helpers) {
1504
+ cm.setCursor(0, 1);
1505
+ helpers.doKeys('j', 'S');
1506
+ helpers.doInsertModeKeys('Esc');
1507
+ helpers.assertCursorAt(1, 0);
1508
+ eq('aa\n\ncc', cm.getValue());
1509
+ }, { value: 'aa\nbb\ncc'});
1510
+ testVim('S_visual', function(cm, vim, helpers) {
1511
+ cm.setCursor(0, 1);
1512
+ helpers.doKeys('v', 'j', 'S');
1513
+ helpers.doInsertModeKeys('Esc');
1514
+ helpers.assertCursorAt(0, 0);
1515
+ eq('\ncc', cm.getValue());
1516
+ }, { value: 'aa\nbb\ncc'});
1517
+ testVim('/ and n/N', function(cm, vim, helpers) {
1518
+ cm.openDialog = helpers.fakeOpenDialog('match');
1519
+ helpers.doKeys('/');
1520
+ helpers.assertCursorAt(0, 11);
1521
+ helpers.doKeys('n');
1522
+ helpers.assertCursorAt(1, 6);
1523
+ helpers.doKeys('N');
1524
+ helpers.assertCursorAt(0, 11);
1525
+
1526
+ cm.setCursor(0, 0);
1527
+ helpers.doKeys('2', '/');
1528
+ helpers.assertCursorAt(1, 6);
1529
+ }, { value: 'match nope match \n nope Match' });
1530
+ testVim('/_case', function(cm, vim, helpers) {
1531
+ cm.openDialog = helpers.fakeOpenDialog('Match');
1532
+ helpers.doKeys('/');
1533
+ helpers.assertCursorAt(1, 6);
1534
+ }, { value: 'match nope match \n nope Match' });
1535
+ testVim('/_nongreedy', function(cm, vim, helpers) {
1536
+ cm.openDialog = helpers.fakeOpenDialog('aa');
1537
+ helpers.doKeys('/');
1538
+ helpers.assertCursorAt(0, 4);
1539
+ helpers.doKeys('n');
1540
+ helpers.assertCursorAt(1, 3);
1541
+ helpers.doKeys('n');
1542
+ helpers.assertCursorAt(0, 0);
1543
+ }, { value: 'aaa aa \n a aa'});
1544
+ testVim('?_nongreedy', function(cm, vim, helpers) {
1545
+ cm.openDialog = helpers.fakeOpenDialog('aa');
1546
+ helpers.doKeys('?');
1547
+ helpers.assertCursorAt(1, 3);
1548
+ helpers.doKeys('n');
1549
+ helpers.assertCursorAt(0, 4);
1550
+ helpers.doKeys('n');
1551
+ helpers.assertCursorAt(0, 0);
1552
+ }, { value: 'aaa aa \n a aa'});
1553
+ testVim('/_greedy', function(cm, vim, helpers) {
1554
+ cm.openDialog = helpers.fakeOpenDialog('a+');
1555
+ helpers.doKeys('/');
1556
+ helpers.assertCursorAt(0, 4);
1557
+ helpers.doKeys('n');
1558
+ helpers.assertCursorAt(1, 1);
1559
+ helpers.doKeys('n');
1560
+ helpers.assertCursorAt(1, 3);
1561
+ helpers.doKeys('n');
1562
+ helpers.assertCursorAt(0, 0);
1563
+ }, { value: 'aaa aa \n a aa'});
1564
+ testVim('?_greedy', function(cm, vim, helpers) {
1565
+ cm.openDialog = helpers.fakeOpenDialog('a+');
1566
+ helpers.doKeys('?');
1567
+ helpers.assertCursorAt(1, 3);
1568
+ helpers.doKeys('n');
1569
+ helpers.assertCursorAt(1, 1);
1570
+ helpers.doKeys('n');
1571
+ helpers.assertCursorAt(0, 4);
1572
+ helpers.doKeys('n');
1573
+ helpers.assertCursorAt(0, 0);
1574
+ }, { value: 'aaa aa \n a aa'});
1575
+ testVim('/_greedy_0_or_more', function(cm, vim, helpers) {
1576
+ cm.openDialog = helpers.fakeOpenDialog('a*');
1577
+ helpers.doKeys('/');
1578
+ helpers.assertCursorAt(0, 3);
1579
+ helpers.doKeys('n');
1580
+ helpers.assertCursorAt(0, 4);
1581
+ helpers.doKeys('n');
1582
+ helpers.assertCursorAt(0, 5);
1583
+ helpers.doKeys('n');
1584
+ helpers.assertCursorAt(1, 0);
1585
+ helpers.doKeys('n');
1586
+ helpers.assertCursorAt(1, 1);
1587
+ helpers.doKeys('n');
1588
+ helpers.assertCursorAt(0, 0);
1589
+ }, { value: 'aaa aa\n aa'});
1590
+ testVim('?_greedy_0_or_more', function(cm, vim, helpers) {
1591
+ cm.openDialog = helpers.fakeOpenDialog('a*');
1592
+ helpers.doKeys('?');
1593
+ helpers.assertCursorAt(1, 1);
1594
+ helpers.doKeys('n');
1595
+ helpers.assertCursorAt(1, 0);
1596
+ helpers.doKeys('n');
1597
+ helpers.assertCursorAt(0, 5);
1598
+ helpers.doKeys('n');
1599
+ helpers.assertCursorAt(0, 4);
1600
+ helpers.doKeys('n');
1601
+ helpers.assertCursorAt(0, 3);
1602
+ helpers.doKeys('n');
1603
+ helpers.assertCursorAt(0, 0);
1604
+ }, { value: 'aaa aa\n aa'});
1605
+ testVim('? and n/N', function(cm, vim, helpers) {
1606
+ cm.openDialog = helpers.fakeOpenDialog('match');
1607
+ helpers.doKeys('?');
1608
+ helpers.assertCursorAt(1, 6);
1609
+ helpers.doKeys('n');
1610
+ helpers.assertCursorAt(0, 11);
1611
+ helpers.doKeys('N');
1612
+ helpers.assertCursorAt(1, 6);
1613
+
1614
+ cm.setCursor(0, 0);
1615
+ helpers.doKeys('2', '?');
1616
+ helpers.assertCursorAt(0, 11);
1617
+ }, { value: 'match nope match \n nope Match' });
1618
+ testVim('*', function(cm, vim, helpers) {
1619
+ cm.setCursor(0, 9);
1620
+ helpers.doKeys('*');
1621
+ helpers.assertCursorAt(0, 22);
1622
+
1623
+ cm.setCursor(0, 9);
1624
+ helpers.doKeys('2', '*');
1625
+ helpers.assertCursorAt(1, 8);
1626
+ }, { value: 'nomatch match nomatch match \nnomatch Match' });
1627
+ testVim('*_no_word', function(cm, vim, helpers) {
1628
+ cm.setCursor(0, 0);
1629
+ helpers.doKeys('*');
1630
+ helpers.assertCursorAt(0, 0);
1631
+ }, { value: ' \n match \n' });
1632
+ testVim('*_symbol', function(cm, vim, helpers) {
1633
+ cm.setCursor(0, 0);
1634
+ helpers.doKeys('*');
1635
+ helpers.assertCursorAt(1, 0);
1636
+ }, { value: ' /}\n/} match \n' });
1637
+ testVim('#', function(cm, vim, helpers) {
1638
+ cm.setCursor(0, 9);
1639
+ helpers.doKeys('#');
1640
+ helpers.assertCursorAt(1, 8);
1641
+
1642
+ cm.setCursor(0, 9);
1643
+ helpers.doKeys('2', '#');
1644
+ helpers.assertCursorAt(0, 22);
1645
+ }, { value: 'nomatch match nomatch match \nnomatch Match' });
1646
+ testVim('*_seek', function(cm, vim, helpers) {
1647
+ // Should skip over space and symbols.
1648
+ cm.setCursor(0, 3);
1649
+ helpers.doKeys('*');
1650
+ helpers.assertCursorAt(0, 22);
1651
+ }, { value: ' := match nomatch match \nnomatch Match' });
1652
+ testVim('#', function(cm, vim, helpers) {
1653
+ // Should skip over space and symbols.
1654
+ cm.setCursor(0, 3);
1655
+ helpers.doKeys('#');
1656
+ helpers.assertCursorAt(1, 8);
1657
+ }, { value: ' := match nomatch match \nnomatch Match' });
1658
+ testVim('.', function(cm, vim, helpers) {
1659
+ cm.setCursor(0, 0);
1660
+ helpers.doKeys('2', 'd', 'w');
1661
+ helpers.doKeys('.');
1662
+ eq('5 6', cm.getValue());
1663
+ }, { value: '1 2 3 4 5 6'});
1664
+ testVim('._repeat', function(cm, vim, helpers) {
1665
+ cm.setCursor(0, 0);
1666
+ helpers.doKeys('2', 'd', 'w');
1667
+ helpers.doKeys('3', '.');
1668
+ eq('6', cm.getValue());
1669
+ }, { value: '1 2 3 4 5 6'});
1670
+ testVim('._insert', function(cm, vim, helpers) {
1671
+ helpers.doKeys('i');
1672
+ cm.replaceRange('test', cm.getCursor());
1673
+ helpers.doInsertModeKeys('Esc');
1674
+ helpers.doKeys('.');
1675
+ eq('testestt', cm.getValue());
1676
+ helpers.assertCursorAt(0, 6);
1677
+ }, { value: ''});
1678
+ testVim('._insert_repeat', function(cm, vim, helpers) {
1679
+ helpers.doKeys('i');
1680
+ cm.replaceRange('test', cm.getCursor());
1681
+ cm.setCursor(0, 4);
1682
+ helpers.doInsertModeKeys('Esc');
1683
+ helpers.doKeys('2', '.');
1684
+ eq('testesttestt', cm.getValue());
1685
+ helpers.assertCursorAt(0, 10);
1686
+ }, { value: ''});
1687
+ testVim('._repeat_insert', function(cm, vim, helpers) {
1688
+ helpers.doKeys('3', 'i');
1689
+ cm.replaceRange('te', cm.getCursor());
1690
+ cm.setCursor(0, 2);
1691
+ helpers.doInsertModeKeys('Esc');
1692
+ helpers.doKeys('.');
1693
+ eq('tetettetetee', cm.getValue());
1694
+ helpers.assertCursorAt(0, 10);
1695
+ }, { value: ''});
1696
+ testVim('._insert_o', function(cm, vim, helpers) {
1697
+ helpers.doKeys('o');
1698
+ cm.replaceRange('z', cm.getCursor());
1699
+ cm.setCursor(1, 1);
1700
+ helpers.doInsertModeKeys('Esc');
1701
+ helpers.doKeys('.');
1702
+ eq('\nz\nz', cm.getValue());
1703
+ helpers.assertCursorAt(2, 0);
1704
+ }, { value: ''});
1705
+ testVim('._insert_o_repeat', function(cm, vim, helpers) {
1706
+ helpers.doKeys('o');
1707
+ cm.replaceRange('z', cm.getCursor());
1708
+ helpers.doInsertModeKeys('Esc');
1709
+ cm.setCursor(1, 0);
1710
+ helpers.doKeys('2', '.');
1711
+ eq('\nz\nz\nz', cm.getValue());
1712
+ helpers.assertCursorAt(3, 0);
1713
+ }, { value: ''});
1714
+ testVim('._insert_o_indent', function(cm, vim, helpers) {
1715
+ helpers.doKeys('o');
1716
+ cm.replaceRange('z', cm.getCursor());
1717
+ helpers.doInsertModeKeys('Esc');
1718
+ cm.setCursor(1, 2);
1719
+ helpers.doKeys('.');
1720
+ eq('{\n z\n z', cm.getValue());
1721
+ helpers.assertCursorAt(2, 2);
1722
+ }, { value: '{'});
1723
+ testVim('._insert_cw', function(cm, vim, helpers) {
1724
+ helpers.doKeys('c', 'w');
1725
+ cm.replaceRange('test', cm.getCursor());
1726
+ helpers.doInsertModeKeys('Esc');
1727
+ cm.setCursor(0, 3);
1728
+ helpers.doKeys('2', 'l');
1729
+ helpers.doKeys('.');
1730
+ eq('test test word3', cm.getValue());
1731
+ helpers.assertCursorAt(0, 8);
1732
+ }, { value: 'word1 word2 word3' });
1733
+ testVim('._insert_cw_repeat', function(cm, vim, helpers) {
1734
+ // For some reason, repeat cw in desktop VIM will does not repeat insert mode
1735
+ // changes. Will conform to that behavior.
1736
+ helpers.doKeys('c', 'w');
1737
+ cm.replaceRange('test', cm.getCursor());
1738
+ helpers.doInsertModeKeys('Esc');
1739
+ cm.setCursor(0, 4);
1740
+ helpers.doKeys('l');
1741
+ helpers.doKeys('2', '.');
1742
+ eq('test test', cm.getValue());
1743
+ helpers.assertCursorAt(0, 8);
1744
+ }, { value: 'word1 word2 word3' });
1745
+ testVim('._delete', function(cm, vim, helpers) {
1746
+ cm.setCursor(0, 5);
1747
+ helpers.doKeys('i');
1748
+ helpers.doInsertModeKeys('Backspace', 'Esc');
1749
+ helpers.doKeys('.');
1750
+ eq('zace', cm.getValue());
1751
+ helpers.assertCursorAt(0, 1);
1752
+ }, { value: 'zabcde'});
1753
+ testVim('._delete_repeat', function(cm, vim, helpers) {
1754
+ cm.setCursor(0, 6);
1755
+ helpers.doKeys('i');
1756
+ helpers.doInsertModeKeys('Backspace', 'Esc');
1757
+ helpers.doKeys('2', '.');
1758
+ eq('zzce', cm.getValue());
1759
+ helpers.assertCursorAt(0, 1);
1760
+ }, { value: 'zzabcde'});
1761
+ testVim('f;', function(cm, vim, helpers) {
1762
+ cm.setCursor(0, 0);
1763
+ helpers.doKeys('f', 'x');
1764
+ helpers.doKeys(';');
1765
+ helpers.doKeys('2', ';');
1766
+ eq(9, cm.getCursor().ch);
1767
+ }, { value: '01x3xx678x'});
1768
+ testVim('F;', function(cm, vim, helpers) {
1769
+ cm.setCursor(0, 8);
1770
+ helpers.doKeys('F', 'x');
1771
+ helpers.doKeys(';');
1772
+ helpers.doKeys('2', ';');
1773
+ eq(2, cm.getCursor().ch);
1774
+ }, { value: '01x3xx6x8x'});
1775
+ testVim('t;', function(cm, vim, helpers) {
1776
+ cm.setCursor(0, 0);
1777
+ helpers.doKeys('t', 'x');
1778
+ helpers.doKeys(';');
1779
+ helpers.doKeys('2', ';');
1780
+ eq(8, cm.getCursor().ch);
1781
+ }, { value: '01x3xx678x'});
1782
+ testVim('T;', function(cm, vim, helpers) {
1783
+ cm.setCursor(0, 9);
1784
+ helpers.doKeys('T', 'x');
1785
+ helpers.doKeys(';');
1786
+ helpers.doKeys('2', ';');
1787
+ eq(2, cm.getCursor().ch);
1788
+ }, { value: '0xx3xx678x'});
1789
+ testVim('f,', function(cm, vim, helpers) {
1790
+ cm.setCursor(0, 6);
1791
+ helpers.doKeys('f', 'x');
1792
+ helpers.doKeys(',');
1793
+ helpers.doKeys('2', ',');
1794
+ eq(2, cm.getCursor().ch);
1795
+ }, { value: '01x3xx678x'});
1796
+ testVim('F,', function(cm, vim, helpers) {
1797
+ cm.setCursor(0, 3);
1798
+ helpers.doKeys('F', 'x');
1799
+ helpers.doKeys(',');
1800
+ helpers.doKeys('2', ',');
1801
+ eq(9, cm.getCursor().ch);
1802
+ }, { value: '01x3xx678x'});
1803
+ testVim('t,', function(cm, vim, helpers) {
1804
+ cm.setCursor(0, 6);
1805
+ helpers.doKeys('t', 'x');
1806
+ helpers.doKeys(',');
1807
+ helpers.doKeys('2', ',');
1808
+ eq(3, cm.getCursor().ch);
1809
+ }, { value: '01x3xx678x'});
1810
+ testVim('T,', function(cm, vim, helpers) {
1811
+ cm.setCursor(0, 4);
1812
+ helpers.doKeys('T', 'x');
1813
+ helpers.doKeys(',');
1814
+ helpers.doKeys('2', ',');
1815
+ eq(8, cm.getCursor().ch);
1816
+ }, { value: '01x3xx67xx'});
1817
+ testVim('fd,;', function(cm, vim, helpers) {
1818
+ cm.setCursor(0, 0);
1819
+ helpers.doKeys('f', '4');
1820
+ cm.setCursor(0, 0);
1821
+ helpers.doKeys('d', ';');
1822
+ eq('56789', cm.getValue());
1823
+ helpers.doKeys('u');
1824
+ cm.setCursor(0, 9);
1825
+ helpers.doKeys('d', ',');
1826
+ eq('01239', cm.getValue());
1827
+ }, { value: '0123456789'});
1828
+ testVim('Fd,;', function(cm, vim, helpers) {
1829
+ cm.setCursor(0, 9);
1830
+ helpers.doKeys('F', '4');
1831
+ cm.setCursor(0, 9);
1832
+ helpers.doKeys('d', ';');
1833
+ eq('01239', cm.getValue());
1834
+ helpers.doKeys('u');
1835
+ cm.setCursor(0, 0);
1836
+ helpers.doKeys('d', ',');
1837
+ eq('56789', cm.getValue());
1838
+ }, { value: '0123456789'});
1839
+ testVim('td,;', function(cm, vim, helpers) {
1840
+ cm.setCursor(0, 0);
1841
+ helpers.doKeys('t', '4');
1842
+ cm.setCursor(0, 0);
1843
+ helpers.doKeys('d', ';');
1844
+ eq('456789', cm.getValue());
1845
+ helpers.doKeys('u');
1846
+ cm.setCursor(0, 9);
1847
+ helpers.doKeys('d', ',');
1848
+ eq('012349', cm.getValue());
1849
+ }, { value: '0123456789'});
1850
+ testVim('Td,;', function(cm, vim, helpers) {
1851
+ cm.setCursor(0, 9);
1852
+ helpers.doKeys('T', '4');
1853
+ cm.setCursor(0, 9);
1854
+ helpers.doKeys('d', ';');
1855
+ eq('012349', cm.getValue());
1856
+ helpers.doKeys('u');
1857
+ cm.setCursor(0, 0);
1858
+ helpers.doKeys('d', ',');
1859
+ eq('456789', cm.getValue());
1860
+ }, { value: '0123456789'});
1861
+ testVim('fc,;', function(cm, vim, helpers) {
1862
+ cm.setCursor(0, 0);
1863
+ helpers.doKeys('f', '4');
1864
+ cm.setCursor(0, 0);
1865
+ helpers.doKeys('c', ';', 'Esc');
1866
+ eq('56789', cm.getValue());
1867
+ helpers.doKeys('u');
1868
+ cm.setCursor(0, 9);
1869
+ helpers.doKeys('c', ',');
1870
+ eq('01239', cm.getValue());
1871
+ }, { value: '0123456789'});
1872
+ testVim('Fc,;', function(cm, vim, helpers) {
1873
+ cm.setCursor(0, 9);
1874
+ helpers.doKeys('F', '4');
1875
+ cm.setCursor(0, 9);
1876
+ helpers.doKeys('c', ';', 'Esc');
1877
+ eq('01239', cm.getValue());
1878
+ helpers.doKeys('u');
1879
+ cm.setCursor(0, 0);
1880
+ helpers.doKeys('c', ',');
1881
+ eq('56789', cm.getValue());
1882
+ }, { value: '0123456789'});
1883
+ testVim('tc,;', function(cm, vim, helpers) {
1884
+ cm.setCursor(0, 0);
1885
+ helpers.doKeys('t', '4');
1886
+ cm.setCursor(0, 0);
1887
+ helpers.doKeys('c', ';', 'Esc');
1888
+ eq('456789', cm.getValue());
1889
+ helpers.doKeys('u');
1890
+ cm.setCursor(0, 9);
1891
+ helpers.doKeys('c', ',');
1892
+ eq('012349', cm.getValue());
1893
+ }, { value: '0123456789'});
1894
+ testVim('Tc,;', function(cm, vim, helpers) {
1895
+ cm.setCursor(0, 9);
1896
+ helpers.doKeys('T', '4');
1897
+ cm.setCursor(0, 9);
1898
+ helpers.doKeys('c', ';', 'Esc');
1899
+ eq('012349', cm.getValue());
1900
+ helpers.doKeys('u');
1901
+ cm.setCursor(0, 0);
1902
+ helpers.doKeys('c', ',');
1903
+ eq('456789', cm.getValue());
1904
+ }, { value: '0123456789'});
1905
+ testVim('fy,;', function(cm, vim, helpers) {
1906
+ cm.setCursor(0, 0);
1907
+ helpers.doKeys('f', '4');
1908
+ cm.setCursor(0, 0);
1909
+ helpers.doKeys('y', ';', 'P');
1910
+ eq('012340123456789', cm.getValue());
1911
+ helpers.doKeys('u');
1912
+ cm.setCursor(0, 9);
1913
+ helpers.doKeys('y', ',', 'P');
1914
+ eq('012345678456789', cm.getValue());
1915
+ }, { value: '0123456789'});
1916
+ testVim('Fy,;', function(cm, vim, helpers) {
1917
+ cm.setCursor(0, 9);
1918
+ helpers.doKeys('F', '4');
1919
+ cm.setCursor(0, 9);
1920
+ helpers.doKeys('y', ';', 'p');
1921
+ eq('012345678945678', cm.getValue());
1922
+ helpers.doKeys('u');
1923
+ cm.setCursor(0, 0);
1924
+ helpers.doKeys('y', ',', 'P');
1925
+ eq('012340123456789', cm.getValue());
1926
+ }, { value: '0123456789'});
1927
+ testVim('ty,;', function(cm, vim, helpers) {
1928
+ cm.setCursor(0, 0);
1929
+ helpers.doKeys('t', '4');
1930
+ cm.setCursor(0, 0);
1931
+ helpers.doKeys('y', ';', 'P');
1932
+ eq('01230123456789', cm.getValue());
1933
+ helpers.doKeys('u');
1934
+ cm.setCursor(0, 9);
1935
+ helpers.doKeys('y', ',', 'p');
1936
+ eq('01234567895678', cm.getValue());
1937
+ }, { value: '0123456789'});
1938
+ testVim('Ty,;', function(cm, vim, helpers) {
1939
+ cm.setCursor(0, 9);
1940
+ helpers.doKeys('T', '4');
1941
+ cm.setCursor(0, 9);
1942
+ helpers.doKeys('y', ';', 'p');
1943
+ eq('01234567895678', cm.getValue());
1944
+ helpers.doKeys('u');
1945
+ cm.setCursor(0, 0);
1946
+ helpers.doKeys('y', ',', 'P');
1947
+ eq('01230123456789', cm.getValue());
1948
+ }, { value: '0123456789'});
1949
+ testVim('HML', function(cm, vim, helpers) {
1950
+ var lines = 35;
1951
+ var textHeight = cm.defaultTextHeight();
1952
+ cm.setSize(600, lines*textHeight);
1953
+ cm.setCursor(120, 0);
1954
+ helpers.doKeys('H');
1955
+ helpers.assertCursorAt(86, 2);
1956
+ helpers.doKeys('L');
1957
+ helpers.assertCursorAt(120, 4);
1958
+ helpers.doKeys('M');
1959
+ helpers.assertCursorAt(103,4);
1960
+ }, { value: (function(){
1961
+ var lines = new Array(100);
1962
+ var upper = ' xx\n';
1963
+ var lower = ' xx\n';
1964
+ upper = lines.join(upper);
1965
+ lower = lines.join(lower);
1966
+ return upper + lower;
1967
+ })()});
1968
+
1969
+ var zVals = ['zb','zz','zt','z-','z.','z<CR>'].map(function(e, idx){
1970
+ var lineNum = 250;
1971
+ var lines = 35;
1972
+ testVim(e, function(cm, vim, helpers) {
1973
+ var k1 = e[0];
1974
+ var k2 = e.substring(1);
1975
+ var textHeight = cm.defaultTextHeight();
1976
+ cm.setSize(600, lines*textHeight);
1977
+ cm.setCursor(lineNum, 0);
1978
+ helpers.doKeys(k1, k2);
1979
+ zVals[idx] = cm.getScrollInfo().top;
1980
+ }, { value: (function(){
1981
+ return new Array(500).join('\n');
1982
+ })()});
1983
+ });
1984
+ testVim('zb<zz', function(cm, vim, helpers){
1985
+ eq(zVals[0]<zVals[1], true);
1986
+ });
1987
+ testVim('zz<zt', function(cm, vim, helpers){
1988
+ eq(zVals[1]<zVals[2], true);
1989
+ });
1990
+ testVim('zb==z-', function(cm, vim, helpers){
1991
+ eq(zVals[0], zVals[3]);
1992
+ });
1993
+ testVim('zz==z.', function(cm, vim, helpers){
1994
+ eq(zVals[1], zVals[4]);
1995
+ });
1996
+ testVim('zt==z<CR>', function(cm, vim, helpers){
1997
+ eq(zVals[2], zVals[5]);
1998
+ });
1999
+
2000
+ var squareBracketMotionSandbox = ''+
2001
+ '({\n'+//0
2002
+ ' ({\n'+//11
2003
+ ' /*comment {\n'+//2
2004
+ ' */(\n'+//3
2005
+ '#else \n'+//4
2006
+ ' /* )\n'+//5
2007
+ '#if }\n'+//6
2008
+ ' )}*/\n'+//7
2009
+ ')}\n'+//8
2010
+ '{}\n'+//9
2011
+ '#else {{\n'+//10
2012
+ '{}\n'+//11
2013
+ '}\n'+//12
2014
+ '{\n'+//13
2015
+ '#endif\n'+//14
2016
+ '}\n'+//15
2017
+ '}\n'+//16
2018
+ '#else';//17
2019
+ testVim('[[, ]]', function(cm, vim, helpers) {
2020
+ cm.setCursor(0, 0);
2021
+ helpers.doKeys(']', ']');
2022
+ helpers.assertCursorAt(9,0);
2023
+ helpers.doKeys('2', ']', ']');
2024
+ helpers.assertCursorAt(13,0);
2025
+ helpers.doKeys(']', ']');
2026
+ helpers.assertCursorAt(17,0);
2027
+ helpers.doKeys('[', '[');
2028
+ helpers.assertCursorAt(13,0);
2029
+ helpers.doKeys('2', '[', '[');
2030
+ helpers.assertCursorAt(9,0);
2031
+ helpers.doKeys('[', '[');
2032
+ helpers.assertCursorAt(0,0);
2033
+ }, { value: squareBracketMotionSandbox});
2034
+ testVim('[], ][', function(cm, vim, helpers) {
2035
+ cm.setCursor(0, 0);
2036
+ helpers.doKeys(']', '[');
2037
+ helpers.assertCursorAt(12,0);
2038
+ helpers.doKeys('2', ']', '[');
2039
+ helpers.assertCursorAt(16,0);
2040
+ helpers.doKeys(']', '[');
2041
+ helpers.assertCursorAt(17,0);
2042
+ helpers.doKeys('[', ']');
2043
+ helpers.assertCursorAt(16,0);
2044
+ helpers.doKeys('2', '[', ']');
2045
+ helpers.assertCursorAt(12,0);
2046
+ helpers.doKeys('[', ']');
2047
+ helpers.assertCursorAt(0,0);
2048
+ }, { value: squareBracketMotionSandbox});
2049
+ testVim('[{, ]}', function(cm, vim, helpers) {
2050
+ cm.setCursor(4, 10);
2051
+ helpers.doKeys('[', '{');
2052
+ helpers.assertCursorAt(2,12);
2053
+ helpers.doKeys('2', '[', '{');
2054
+ helpers.assertCursorAt(0,1);
2055
+ cm.setCursor(4, 10);
2056
+ helpers.doKeys(']', '}');
2057
+ helpers.assertCursorAt(6,11);
2058
+ helpers.doKeys('2', ']', '}');
2059
+ helpers.assertCursorAt(8,1);
2060
+ cm.setCursor(0,1);
2061
+ helpers.doKeys(']', '}');
2062
+ helpers.assertCursorAt(8,1);
2063
+ helpers.doKeys('[', '{');
2064
+ helpers.assertCursorAt(0,1);
2065
+ }, { value: squareBracketMotionSandbox});
2066
+ testVim('[(, ])', function(cm, vim, helpers) {
2067
+ cm.setCursor(4, 10);
2068
+ helpers.doKeys('[', '(');
2069
+ helpers.assertCursorAt(3,14);
2070
+ helpers.doKeys('2', '[', '(');
2071
+ helpers.assertCursorAt(0,0);
2072
+ cm.setCursor(4, 10);
2073
+ helpers.doKeys(']', ')');
2074
+ helpers.assertCursorAt(5,11);
2075
+ helpers.doKeys('2', ']', ')');
2076
+ helpers.assertCursorAt(8,0);
2077
+ helpers.doKeys('[', '(');
2078
+ helpers.assertCursorAt(0,0);
2079
+ helpers.doKeys(']', ')');
2080
+ helpers.assertCursorAt(8,0);
2081
+ }, { value: squareBracketMotionSandbox});
2082
+ testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) {
2083
+ ['*', '/'].forEach(function(key){
2084
+ cm.setCursor(7, 0);
2085
+ helpers.doKeys('2', '[', key);
2086
+ helpers.assertCursorAt(2,2);
2087
+ helpers.doKeys('2', ']', key);
2088
+ helpers.assertCursorAt(7,5);
2089
+ });
2090
+ }, { value: squareBracketMotionSandbox});
2091
+ testVim('[#, ]#', function(cm, vim, helpers) {
2092
+ cm.setCursor(10, 3);
2093
+ helpers.doKeys('2', '[', '#');
2094
+ helpers.assertCursorAt(4,0);
2095
+ helpers.doKeys('5', ']', '#');
2096
+ helpers.assertCursorAt(17,0);
2097
+ cm.setCursor(10, 3);
2098
+ helpers.doKeys(']', '#');
2099
+ helpers.assertCursorAt(14,0);
2100
+ }, { value: squareBracketMotionSandbox});
2101
+ testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) {
2102
+ cm.setCursor(11, 0);
2103
+ helpers.doKeys('[', 'm');
2104
+ helpers.assertCursorAt(10,7);
2105
+ helpers.doKeys('4', '[', 'm');
2106
+ helpers.assertCursorAt(1,3);
2107
+ helpers.doKeys('5', ']', 'm');
2108
+ helpers.assertCursorAt(11,0);
2109
+ helpers.doKeys('[', 'M');
2110
+ helpers.assertCursorAt(9,1);
2111
+ helpers.doKeys('3', ']', 'M');
2112
+ helpers.assertCursorAt(15,0);
2113
+ helpers.doKeys('5', '[', 'M');
2114
+ helpers.assertCursorAt(7,3);
2115
+ }, { value: squareBracketMotionSandbox});
2116
+
2117
+ // Ex mode tests
2118
+ testVim('ex_go_to_line', function(cm, vim, helpers) {
2119
+ cm.setCursor(0, 0);
2120
+ helpers.doEx('4');
2121
+ helpers.assertCursorAt(3, 0);
2122
+ }, { value: 'a\nb\nc\nd\ne\n'});
2123
+ testVim('ex_write', function(cm, vim, helpers) {
2124
+ var tmp = CodeMirror.commands.save;
2125
+ var written;
2126
+ var actualCm;
2127
+ CodeMirror.commands.save = function(cm) {
2128
+ written = true;
2129
+ actualCm = cm;
2130
+ };
2131
+ // Test that w, wr, wri ... write all trigger :write.
2132
+ var command = 'write';
2133
+ for (var i = 1; i < command.length; i++) {
2134
+ written = false;
2135
+ actualCm = null;
2136
+ helpers.doEx(command.substring(0, i));
2137
+ eq(written, true);
2138
+ eq(actualCm, cm);
2139
+ }
2140
+ CodeMirror.commands.save = tmp;
2141
+ });
2142
+ testVim('ex_sort', function(cm, vim, helpers) {
2143
+ helpers.doEx('sort');
2144
+ eq('Z\na\nb\nc\nd', cm.getValue());
2145
+ }, { value: 'b\nZ\nd\nc\na'});
2146
+ testVim('ex_sort_reverse', function(cm, vim, helpers) {
2147
+ helpers.doEx('sort!');
2148
+ eq('d\nc\nb\na', cm.getValue());
2149
+ }, { value: 'b\nd\nc\na'});
2150
+ testVim('ex_sort_range', function(cm, vim, helpers) {
2151
+ helpers.doEx('2,3sort');
2152
+ eq('b\nc\nd\na', cm.getValue());
2153
+ }, { value: 'b\nd\nc\na'});
2154
+ testVim('ex_sort_oneline', function(cm, vim, helpers) {
2155
+ helpers.doEx('2sort');
2156
+ // Expect no change.
2157
+ eq('b\nd\nc\na', cm.getValue());
2158
+ }, { value: 'b\nd\nc\na'});
2159
+ testVim('ex_sort_ignoreCase', function(cm, vim, helpers) {
2160
+ helpers.doEx('sort i');
2161
+ eq('a\nb\nc\nd\nZ', cm.getValue());
2162
+ }, { value: 'b\nZ\nd\nc\na'});
2163
+ testVim('ex_sort_unique', function(cm, vim, helpers) {
2164
+ helpers.doEx('sort u');
2165
+ eq('Z\na\nb\nc\nd', cm.getValue());
2166
+ }, { value: 'b\nZ\na\na\nd\na\nc\na'});
2167
+ testVim('ex_sort_decimal', function(cm, vim, helpers) {
2168
+ helpers.doEx('sort d');
2169
+ eq('d3\n s5\n6\n.9', cm.getValue());
2170
+ }, { value: '6\nd3\n s5\n.9'});
2171
+ testVim('ex_sort_decimal_negative', function(cm, vim, helpers) {
2172
+ helpers.doEx('sort d');
2173
+ eq('z-9\nd3\n s5\n6\n.9', cm.getValue());
2174
+ }, { value: '6\nd3\n s5\n.9\nz-9'});
2175
+ testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) {
2176
+ helpers.doEx('sort! d');
2177
+ eq('.9\n6\n s5\nd3', cm.getValue());
2178
+ }, { value: '6\nd3\n s5\n.9'});
2179
+ testVim('ex_sort_hex', function(cm, vim, helpers) {
2180
+ helpers.doEx('sort x');
2181
+ eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue());
2182
+ }, { value: '6\nd3\n s5\n&0xB\n.9'});
2183
+ testVim('ex_sort_octal', function(cm, vim, helpers) {
2184
+ helpers.doEx('sort o');
2185
+ eq('.8\n.9\nd3\n s5\n6', cm.getValue());
2186
+ }, { value: '6\nd3\n s5\n.9\n.8'});
2187
+ testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) {
2188
+ helpers.doEx('sort d');
2189
+ eq('y\nz\nc1\nb2\na3', cm.getValue());
2190
+ }, { value: 'a3\nz\nc1\ny\nb2'});
2191
+ testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) {
2192
+ helpers.doEx('sort! d');
2193
+ eq('a3\nb2\nc1\nz\ny', cm.getValue());
2194
+ }, { value: 'a3\nz\nc1\ny\nb2'});
2195
+ testVim('ex_substitute_same_line', function(cm, vim, helpers) {
2196
+ cm.setCursor(1, 0);
2197
+ helpers.doEx('s/one/two');
2198
+ eq('one one\n two two', cm.getValue());
2199
+ }, { value: 'one one\n one one'});
2200
+ testVim('ex_substitute_global', function(cm, vim, helpers) {
2201
+ cm.setCursor(1, 0);
2202
+ helpers.doEx('%s/one/two');
2203
+ eq('two two\n two two', cm.getValue());
2204
+ }, { value: 'one one\n one one'});
2205
+ testVim('ex_substitute_input_range', function(cm, vim, helpers) {
2206
+ cm.setCursor(1, 0);
2207
+ helpers.doEx('1,3s/\\d/0');
2208
+ eq('0\n0\n0\n4', cm.getValue());
2209
+ }, { value: '1\n2\n3\n4' });
2210
+ testVim('ex_substitute_visual_range', function(cm, vim, helpers) {
2211
+ cm.setCursor(1, 0);
2212
+ // Set last visual mode selection marks '< and '> at lines 2 and 4
2213
+ helpers.doKeys('V', '2', 'j', 'v');
2214
+ helpers.doEx('\'<,\'>s/\\d/0');
2215
+ eq('1\n0\n0\n0\n5', cm.getValue());
2216
+ }, { value: '1\n2\n3\n4\n5' });
2217
+ testVim('ex_substitute_capture', function(cm, vim, helpers) {
2218
+ cm.setCursor(1, 0);
2219
+ helpers.doEx('s/(\\d+)/$1$1/')
2220
+ eq('a1111 a1212 a1313', cm.getValue());
2221
+ }, { value: 'a11 a12 a13' });
2222
+ testVim('ex_substitute_empty_query', function(cm, vim, helpers) {
2223
+ // If the query is empty, use last query.
2224
+ cm.setCursor(1, 0);
2225
+ cm.openDialog = helpers.fakeOpenDialog('1');
2226
+ helpers.doKeys('/');
2227
+ helpers.doEx('s//b');
2228
+ eq('abb ab2 ab3', cm.getValue());
2229
+ }, { value: 'a11 a12 a13' });
2230
+ testVim('ex_substitute_count', function(cm, vim, helpers) {
2231
+ cm.setCursor(1, 0);
2232
+ helpers.doEx('s/\\d/0/i 2');
2233
+ eq('1\n0\n0\n4', cm.getValue());
2234
+ }, { value: '1\n2\n3\n4' });
2235
+ testVim('ex_substitute_count_with_range', function(cm, vim, helpers) {
2236
+ cm.setCursor(1, 0);
2237
+ helpers.doEx('1,3s/\\d/0/ 3');
2238
+ eq('1\n2\n0\n0', cm.getValue());
2239
+ }, { value: '1\n2\n3\n4' });
2240
+ function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) {
2241
+ testVim(name, function(cm, vim, helpers) {
2242
+ var savedOpenDialog = cm.openDialog;
2243
+ var savedKeyName = CodeMirror.keyName;
2244
+ var onKeyDown;
2245
+ var recordedCallback;
2246
+ var closed = true; // Start out closed, set false on second openDialog.
2247
+ function close() {
2248
+ closed = true;
2249
+ }
2250
+ // First openDialog should save callback.
2251
+ cm.openDialog = function(template, callback, options) {
2252
+ recordedCallback = callback;
2253
+ }
2254
+ // Do first openDialog.
2255
+ helpers.doKeys(':');
2256
+ // Second openDialog should save keyDown handler.
2257
+ cm.openDialog = function(template, callback, options) {
2258
+ onKeyDown = options.onKeyDown;
2259
+ closed = false;
2260
+ };
2261
+ // Return the command to Vim and trigger second openDialog.
2262
+ recordedCallback(command);
2263
+ // The event should really use keyCode, but here just mock it out and use
2264
+ // key and replace keyName to just return key.
2265
+ CodeMirror.keyName = function (e) { return e.key; }
2266
+ keys = keys.toUpperCase();
2267
+ for (var i = 0; i < keys.length; i++) {
2268
+ is(!closed);
2269
+ onKeyDown({ key: keys.charAt(i) }, '', close);
2270
+ }
2271
+ try {
2272
+ eq(expectedValue, cm.getValue());
2273
+ helpers.assertCursorAt(finalPos);
2274
+ is(closed);
2275
+ } catch(e) {
2276
+ throw e
2277
+ } finally {
2278
+ // Restore overriden functions.
2279
+ CodeMirror.keyName = savedKeyName;
2280
+ cm.openDialog = savedOpenDialog;
2281
+ }
2282
+ }, { value: initialValue });
2283
+ };
2284
+ testSubstituteConfirm('ex_substitute_confirm_emptydoc',
2285
+ '%s/x/b/c', '', '', '', makeCursor(0, 0));
2286
+ testSubstituteConfirm('ex_substitute_confirm_nomatch',
2287
+ '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0));
2288
+ testSubstituteConfirm('ex_substitute_confirm_accept',
2289
+ '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1));
2290
+ testSubstituteConfirm('ex_substitute_confirm_random_keys',
2291
+ '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1));
2292
+ testSubstituteConfirm('ex_substitute_confirm_some',
2293
+ '%s/a/b/c', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1));
2294
+ testSubstituteConfirm('ex_substitute_confirm_all',
2295
+ '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1));
2296
+ testSubstituteConfirm('ex_substitute_confirm_accept_then_all',
2297
+ '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1));
2298
+ testSubstituteConfirm('ex_substitute_confirm_quit',
2299
+ '%s/a/b/c', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3));
2300
+ testSubstituteConfirm('ex_substitute_confirm_last',
2301
+ '%s/a/b/c', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
2302
+ testSubstituteConfirm('ex_substitute_confirm_oneline',
2303
+ '1s/a/b/c', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
2304
+ testSubstituteConfirm('ex_substitute_confirm_range_accept',
2305
+ '1,2s/a/b/c', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0));
2306
+ testSubstituteConfirm('ex_substitute_confirm_range_some',
2307
+ '1,3s/a/b/c', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0));
2308
+ testSubstituteConfirm('ex_substitute_confirm_range_all',
2309
+ '1,3s/a/b/c', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0));
2310
+ testSubstituteConfirm('ex_substitute_confirm_range_last',
2311
+ '1,3s/a/b/c', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0));
2312
+ //:noh should clear highlighting of search-results but allow to resume search through n
2313
+ testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
2314
+ cm.openDialog = helpers.fakeOpenDialog('match');
2315
+ helpers.doKeys('?');
2316
+ helpers.doEx('noh');
2317
+ eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared');
2318
+ helpers.doKeys('n');
2319
+ helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting');
2320
+ }, { value: 'match nope match \n nope Match' });
2321
+ // TODO: Reset key maps after each test.
2322
+ testVim('ex_map_key2key', function(cm, vim, helpers) {
2323
+ helpers.doEx('map a x');
2324
+ helpers.doKeys('a');
2325
+ helpers.assertCursorAt(0, 0);
2326
+ eq('bc', cm.getValue());
2327
+ }, { value: 'abc' });
2328
+ testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) {
2329
+ helpers.doEx('map ; :');
2330
+ var dialogOpened = false;
2331
+ cm.openDialog = function() {
2332
+ dialogOpened = true;
2333
+ }
2334
+ helpers.doKeys(';');
2335
+ eq(dialogOpened, true);
2336
+ });
2337
+ testVim('ex_map_ex2key:', function(cm, vim, helpers) {
2338
+ helpers.doEx('map :del x');
2339
+ helpers.doEx('del');
2340
+ helpers.assertCursorAt(0, 0);
2341
+ eq('bc', cm.getValue());
2342
+ }, { value: 'abc' });
2343
+ testVim('ex_map_ex2ex', function(cm, vim, helpers) {
2344
+ helpers.doEx('map :del :w');
2345
+ var tmp = CodeMirror.commands.save;
2346
+ var written = false;
2347
+ var actualCm;
2348
+ CodeMirror.commands.save = function(cm) {
2349
+ written = true;
2350
+ actualCm = cm;
2351
+ };
2352
+ helpers.doEx('del');
2353
+ CodeMirror.commands.save = tmp;
2354
+ eq(written, true);
2355
+ eq(actualCm, cm);
2356
+ });
2357
+ testVim('ex_map_key2ex', function(cm, vim, helpers) {
2358
+ helpers.doEx('map a :w');
2359
+ var tmp = CodeMirror.commands.save;
2360
+ var written = false;
2361
+ var actualCm;
2362
+ CodeMirror.commands.save = function(cm) {
2363
+ written = true;
2364
+ actualCm = cm;
2365
+ };
2366
+ helpers.doKeys('a');
2367
+ CodeMirror.commands.save = tmp;
2368
+ eq(written, true);
2369
+ eq(actualCm, cm);
2370
+ });
2371
+ // Testing registration of functions as ex-commands and mapping to <Key>-keys
2372
+ testVim('ex_api_test', function(cm, vim, helpers) {
2373
+ var res=false;
2374
+ var val='from';
2375
+ CodeMirror.Vim.defineEx('extest','ext',function(cm,params){
2376
+ if(params.args)val=params.args[0];
2377
+ else res=true;
2378
+ });
2379
+ helpers.doEx(':ext to');
2380
+ eq(val,'to','Defining ex-command failed');
2381
+ CodeMirror.Vim.map('<C-CR><Space>',':ext');
2382
+ helpers.doKeys('<C-CR>','<Space>');
2383
+ is(res,'Mapping to key failed');
2384
+ });
2385
+ // For now, this test needs to be last because it messes up : for future tests.
2386
+ testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {
2387
+ helpers.doEx('map : x');
2388
+ helpers.doKeys(':');
2389
+ helpers.assertCursorAt(0, 0);
2390
+ eq('bc', cm.getValue());
2391
+ }, { value: 'abc' });