(cm, line, context, forceToEnd)
| 61 | // style strings), which is used to highlight the tokens on the |
| 62 | // line. |
| 63 | export function highlightLine(cm, line, context, forceToEnd) { |
| 64 | // A styles array always starts with a number identifying the |
| 65 | // mode/overlays that it is based on (for easy invalidation). |
| 66 | let st = [cm.state.modeGen], lineClasses = {} |
| 67 | // Compute the base array of styles |
| 68 | runMode(cm, line.text, cm.doc.mode, context, (end, style) => st.push(end, style), |
| 69 | lineClasses, forceToEnd) |
| 70 | let state = context.state |
| 71 | |
| 72 | // Run overlays, adjust style array. |
| 73 | for (let o = 0; o < cm.state.overlays.length; ++o) { |
| 74 | context.baseTokens = st |
| 75 | let overlay = cm.state.overlays[o], i = 1, at = 0 |
| 76 | context.state = true |
| 77 | runMode(cm, line.text, overlay.mode, context, (end, style) => { |
| 78 | let start = i |
| 79 | // Ensure there's a token end at the current position, and that i points at it |
| 80 | while (at < end) { |
| 81 | let i_end = st[i] |
| 82 | if (i_end > end) |
| 83 | st.splice(i, 1, end, st[i+1], i_end) |
| 84 | i += 2 |
| 85 | at = Math.min(end, i_end) |
| 86 | } |
| 87 | if (!style) return |
| 88 | if (overlay.opaque) { |
| 89 | st.splice(start, i - start, end, "overlay " + style) |
| 90 | i = start + 2 |
| 91 | } else { |
| 92 | for (; start < i; start += 2) { |
| 93 | let cur = st[start+1] |
| 94 | st[start+1] = (cur ? cur + " " : "") + "overlay " + style |
| 95 | } |
| 96 | } |
| 97 | }, lineClasses) |
| 98 | context.state = state |
| 99 | context.baseTokens = null |
| 100 | context.baseTokenPos = 1 |
| 101 | } |
| 102 | |
| 103 | return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null} |
| 104 | } |
| 105 | |
| 106 | export function getLineStyles(cm, line, updateFrontier) { |
| 107 | if (!line.styles || line.styles[0] != cm.state.modeGen) { |
no test coverage detected