comment-fold.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. ;(function (mod) {
  4. if (typeof exports == 'object' && typeof module == 'object')
  5. // CommonJS
  6. mod(require('../../lib/codemirror'))
  7. else if (typeof define == 'function' && define.amd)
  8. // AMD
  9. define(['../../lib/codemirror'], mod)
  10. // Plain browser env
  11. else mod(CodeMirror)
  12. })(function (CodeMirror) {
  13. 'use strict'
  14. CodeMirror.registerGlobalHelper(
  15. 'fold',
  16. 'comment',
  17. function (mode) {
  18. return mode.blockCommentStart && mode.blockCommentEnd
  19. },
  20. function (cm, start) {
  21. var mode = cm.getModeAt(start),
  22. startToken = mode.blockCommentStart,
  23. endToken = mode.blockCommentEnd
  24. if (!startToken || !endToken) return
  25. var line = start.line,
  26. lineText = cm.getLine(line)
  27. var startCh
  28. for (var at = start.ch, pass = 0; ; ) {
  29. var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1)
  30. if (found == -1) {
  31. if (pass == 1) return
  32. pass = 1
  33. at = lineText.length
  34. continue
  35. }
  36. if (pass == 1 && found < start.ch) return
  37. if (
  38. /comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
  39. (found == 0 || lineText.slice(found - endToken.length, found) == endToken || !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))
  40. ) {
  41. startCh = found + startToken.length
  42. break
  43. }
  44. at = found - 1
  45. }
  46. var depth = 1,
  47. lastLine = cm.lastLine(),
  48. end,
  49. endCh
  50. outer: for (var i = line; i <= lastLine; ++i) {
  51. var text = cm.getLine(i),
  52. pos = i == line ? startCh : 0
  53. for (;;) {
  54. var nextOpen = text.indexOf(startToken, pos),
  55. nextClose = text.indexOf(endToken, pos)
  56. if (nextOpen < 0) nextOpen = text.length
  57. if (nextClose < 0) nextClose = text.length
  58. pos = Math.min(nextOpen, nextClose)
  59. if (pos == text.length) break
  60. if (pos == nextOpen) ++depth
  61. else if (!--depth) {
  62. end = i
  63. endCh = pos
  64. break outer
  65. }
  66. ++pos
  67. }
  68. }
  69. if (end == null || (line == end && endCh == startCh)) return
  70. return { from: CodeMirror.Pos(line, startCh), to: CodeMirror.Pos(end, endCh) }
  71. }
  72. )
  73. })