diff --git a/NvimView/NvimView/CellAttributesCollection.swift b/NvimView/NvimView/CellAttributesCollection.swift index bacdc88b..fb269064 100644 --- a/NvimView/NvimView/CellAttributesCollection.swift +++ b/NvimView/NvimView/CellAttributesCollection.swift @@ -8,6 +8,7 @@ import Foundation final class CellAttributesCollection { static let defaultAttributesId = 0 + static let reversedDefaultAttributesId = Int.max private(set) var defaultAttributes = CellAttributes( fontTrait: [], @@ -23,10 +24,20 @@ final class CellAttributesCollection { } func attributes(of id: Int) -> CellAttributes? { - guard let attrs = self.attributes[id] else { + if id == Int.max { + return self.defaultAttributes.reversed + } + + let absId = abs(id) + + guard let attrs = self.attributes[absId] else { return nil } + if id < 0 { + return attrs.replacingDefaults(with: self.defaultAttributes).reversed + } + return attrs.replacingDefaults(with: self.defaultAttributes) } diff --git a/NvimView/NvimView/NvimView+UiBridge.swift b/NvimView/NvimView/NvimView+UiBridge.swift index e61cc671..20d6670e 100644 --- a/NvimView/NvimView/NvimView+UiBridge.swift +++ b/NvimView/NvimView/NvimView+UiBridge.swift @@ -234,6 +234,13 @@ extension NvimView { top: row, bottom: row, left: endCol, right: max(endCol, clearCol - 1) )) } + + if row == self.markedPosition.row + && startCol <= self.markedPosition.column + && self.markedPosition.column <= endCol + { + self.ugrid.markCell(at: self.markedPosition) + } } private func doGoto(position: Position) { @@ -353,7 +360,7 @@ extension NvimView { else { self.bridgeLogger.error("Could not get highlight attributes from " + - "\(value)") + "\(value)") return } let trait = FontTrait(rawValue: UInt(rawTrait)) diff --git a/NvimView/NvimView/UGrid.swift b/NvimView/NvimView/UGrid.swift index 78612006..ed3de846 100644 --- a/NvimView/NvimView/UGrid.swift +++ b/NvimView/NvimView/UGrid.swift @@ -23,6 +23,21 @@ final class UGrid { return !self.cells.isEmpty } + func markCell(at position: Position) { + let attrId = self.cells[position.row][position.column].attrId + let markedAttrId: Int + if attrId == CellAttributesCollection.defaultAttributesId { + markedAttrId = CellAttributesCollection.reversedDefaultAttributesId + } else { + markedAttrId = (-1) * attrId + } + self.cells[position.row][position.column].attrId = markedAttrId + + if self.isNextCellEmpty(position) { + self.cells[position.row][position.column + 1].attrId = markedAttrId + } + } + func position(from flattenedIndex: Int) -> Position { let row = min( self.size.height - 1, diff --git a/NvimView/NvimViewTests/UGridTest.swift b/NvimView/NvimViewTests/UGridTest.swift index 87e82ea7..cf4c59d6 100644 --- a/NvimView/NvimViewTests/UGridTest.swift +++ b/NvimView/NvimViewTests/UGridTest.swift @@ -13,6 +13,51 @@ class UGridTest: XCTestCase { private let ugrid = UGrid() + func testMarkPosition() { + self.ugrid.resize(Size(width: 20, height: 10)) + self.ugrid.update( + row: 9, + startCol: 0, + endCol: 9, + clearCol: 0, + clearAttr: 0, + chunk: Array("0123456789".compactMap { String($0) }), + attrIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + ) + self.ugrid.markCell(at: Position(row: 9, column: 4)) + expect(self.ugrid.cells[9][4].attrId).to(equal(-4)) + + self.ugrid.update( + row: 7, + startCol: 0, + endCol: 9, + clearCol: 0, + clearAttr: 0, + chunk: Array("23456789".compactMap { String($0) }) + ["하", ""], + attrIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 8] + ) + self.ugrid.markCell(at: Position(row: 7, column: 8)) + expect(self.ugrid.cells[7][8].attrId) + .to(equal(-8)) + expect(self.ugrid.cells[7][9].attrId) + .to(equal(-8)) + + self.ugrid.update( + row: 8, + startCol: 0, + endCol: 9, + clearCol: 0, + clearAttr: 0, + chunk: ["하", ""] + Array("23456789".compactMap { String($0) }), + attrIds: [0, 0, 2, 3, 4, 5, 6, 7, 8, 9] + ) + self.ugrid.markCell(at: Position(row: 8, column: 0)) + expect(self.ugrid.cells[8][0].attrId) + .to(equal(CellAttributesCollection.reversedDefaultAttributesId)) + expect(self.ugrid.cells[8][1].attrId) + .to(equal(CellAttributesCollection.reversedDefaultAttributesId)) + } + func testFlattenedIndex() { self.ugrid.resize(Size(width: 20, height: 10)) expect(