Implement special options for line and line number decorations

* onlyEmpty
* onlyNonEmpty
* onlyHead
* omitEmptyLastLine
This commit is contained in:
Nathan Sobo
2017-03-06 14:54:21 -07:00
committed by Antonio Scandurra
parent ff325c0151
commit 09f8a52b9d
3 changed files with 97 additions and 17 deletions

View File

@@ -424,30 +424,48 @@ class TextEditorComponent {
const reversed = marker.isReversed()
for (let i = 0, length = decorations.length; i < decorations.length; i++) {
const decoration = decorations[i]
this.addToDecorationsToRender(decoration.type, decoration, screenRange, reversed)
this.addDecorationToRender(decoration.type, decoration, screenRange, reversed)
}
})
}
addToDecorationsToRender (type, decoration, screenRange, reversed) {
addDecorationToRender (type, decoration, screenRange, reversed) {
if (Array.isArray(type)) {
for (let i = 0, length = type.length; i < length; i++) {
this.addToDecorationsToRender(type[i], decoration, screenRange, reversed)
this.addDecorationToRender(type[i], decoration, screenRange, reversed)
}
} else {
switch (type) {
case 'line-number':
for (let row = screenRange.start.row; row <= screenRange.end.row; row++) {
const currentClassName = this.decorationsToRender.lineNumbers.get(row)
const newClassName = currentClassName ? currentClassName + ' ' + decoration.class : decoration.class
this.decorationsToRender.lineNumbers.set(row, newClassName)
}
break
case 'line':
for (let row = screenRange.start.row; row <= screenRange.end.row; row++) {
const currentClassName = this.decorationsToRender.lines.get(row)
case 'line-number':
const decorationsByRow = (type === 'line') ? this.decorationsToRender.lines : this.decorationsToRender.lineNumbers
let omitLastRow = false
if (screenRange.isEmpty()) {
if (decoration.onlyNonEmpty) return
} else {
if (decoration.onlyEmpty) return
if (decoration.omitEmptyLastRow !== false) {
omitLastRow = screenRange.end.column === 0
}
}
let startRow = screenRange.start.row
let endRow = screenRange.end.row
if (decoration.onlyHead) {
if (reversed) {
endRow = startRow
} else {
startRow = endRow
}
}
for (let row = startRow; row <= endRow; row++) {
if (omitLastRow && row === endRow) break
const currentClassName = decorationsByRow.get(row)
const newClassName = currentClassName ? currentClassName + ' ' + decoration.class : decoration.class
this.decorationsToRender.lines.set(row, newClassName)
decorationsByRow.set(row, newClassName)
}
break
}

View File

@@ -1752,16 +1752,20 @@ class TextEditor extends Model
# line, highlight, or overlay.
# * `item` (optional) An {HTMLElement} or a model {Object} with a
# corresponding view registered. Only applicable to the `gutter`,
# `overlay` and `block` types.
# `overlay` and `block` decoration types.
# * `onlyHead` (optional) If `true`, the decoration will only be applied to
# the head of the `DisplayMarker`. Only applicable to the `line` and
# `line-number` types.
# `line-number` decoration types.
# * `onlyEmpty` (optional) If `true`, the decoration will only be applied if
# the associated `DisplayMarker` is empty. Only applicable to the `gutter`,
# `line`, and `line-number` types.
# `line`, and `line-number` decoration types.
# * `onlyNonEmpty` (optional) If `true`, the decoration will only be applied
# if the associated `DisplayMarker` is non-empty. Only applicable to the
# `gutter`, `line`, and `line-number` types.
# `gutter`, `line`, and `line-number` decoration types.
# * `omitEmptyLastRow` (optional) If `false`, the decoration will be applied
# to the last row of a non-empty range, even if it ends at column 0.
# Defaults to `true`. Only applicable to the `gutter`, `line`, and
# `line-number` decoration types.
# * `position` (optional) Only applicable to decorations of type `overlay` and `block`.
# Controls where the view is positioned relative to the `TextEditorMarker`.
# Values can be `'head'` (the default) or `'tail'` for overlay decorations, and