mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-28 08:13:17 +03:00
Refactor cursor drawing
- draw only when flushed and use the normal position from goto
This commit is contained in:
parent
93b9366a66
commit
5d3aca696d
@ -91,9 +91,8 @@ class Grid: CustomStringConvertible {
|
||||
|
||||
fileprivate(set) var region = Region.zero
|
||||
fileprivate(set) var size = Size.zero
|
||||
fileprivate(set) var putPosition = Position.zero
|
||||
fileprivate(set) var screenCursor = Position.zero
|
||||
|
||||
fileprivate(set) var position = Position.zero
|
||||
|
||||
var foreground = defaultForeground
|
||||
var background = defaultBackground
|
||||
var special = defaultSpecial
|
||||
@ -116,7 +115,7 @@ class Grid: CustomStringConvertible {
|
||||
func resize(_ size: Size) {
|
||||
self.region = Region(top: 0, bottom: size.height - 1, left: 0, right: size.width - 1)
|
||||
self.size = size
|
||||
self.putPosition = Position.zero
|
||||
self.position = Position.zero
|
||||
|
||||
let emptyCellAttrs = CellAttributes(fontTrait: .none,
|
||||
foreground: self.foreground, background: self.background, special: self.special)
|
||||
@ -131,8 +130,8 @@ class Grid: CustomStringConvertible {
|
||||
|
||||
func eolClear() {
|
||||
self.clearRegion(
|
||||
Region(top: self.putPosition.row, bottom: self.putPosition.row,
|
||||
left: self.putPosition.column, right: self.region.right)
|
||||
Region(top: self.position.row, bottom: self.position.row,
|
||||
left: self.position.column, right: self.region.right)
|
||||
)
|
||||
}
|
||||
|
||||
@ -171,30 +170,26 @@ class Grid: CustomStringConvertible {
|
||||
}
|
||||
|
||||
func goto(_ position: Position) {
|
||||
self.putPosition = position
|
||||
self.position = position
|
||||
}
|
||||
|
||||
func moveCursor(_ position: Position) {
|
||||
self.screenCursor = position
|
||||
}
|
||||
|
||||
|
||||
func put(_ string: String) {
|
||||
// FIXME: handle the following situation:
|
||||
// |abcde | <- type ㅎ
|
||||
// =>
|
||||
// |abcde>| <- ">" at the end of the line is wrong -> the XPC could tell the main app whether the string occupies
|
||||
// |ㅎ | two cells using vim_strwidth()
|
||||
self.cells[self.putPosition.row][self.putPosition.column] = Cell(string: string, attrs: self.attrs)
|
||||
self.cells[self.position.row][self.position.column] = Cell(string: string, attrs: self.attrs)
|
||||
|
||||
// Increment the column of the put position because neovim calls sets the position only once when drawing
|
||||
// consecutive cells in the same line
|
||||
self.putPosition.column += 1
|
||||
self.advancePosition()
|
||||
}
|
||||
|
||||
func putMarkedText(_ string: String) {
|
||||
// NOTE: Maybe there's a better way to indicate marked text than inverting...
|
||||
self.cells[self.putPosition.row][self.putPosition.column] = Cell(string: string, attrs: self.attrs, marked: true)
|
||||
self.putPosition.column += 1
|
||||
self.cells[self.position.row][self.position.column] = Cell(string: string, attrs: self.attrs, marked: true)
|
||||
self.advancePosition()
|
||||
}
|
||||
|
||||
func unmarkCell(_ position: Position) {
|
||||
@ -302,4 +297,11 @@ class Grid: CustomStringConvertible {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fileprivate func advancePosition() {
|
||||
self.position.column += 1
|
||||
if self.position.column >= self.size.width {
|
||||
self.position.column -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,14 +79,7 @@ extension NeoVimView {
|
||||
}
|
||||
|
||||
fileprivate func cursorRegion() -> Region {
|
||||
let cursorPosition: Position
|
||||
if self.mode == .cmdline
|
||||
|| self.mode == .cmdlineInsert
|
||||
|| self.mode == .cmdlineReplace {
|
||||
cursorPosition = self.grid.putPosition
|
||||
} else {
|
||||
cursorPosition = self.grid.screenCursor
|
||||
}
|
||||
let cursorPosition = self.grid.position
|
||||
|
||||
let saneRow = max(0, min(cursorPosition.row, self.grid.size.height - 1))
|
||||
let saneColumn = max(0, min(cursorPosition.column, self.grid.size.width - 1))
|
||||
@ -104,6 +97,10 @@ extension NeoVimView {
|
||||
}
|
||||
|
||||
fileprivate func drawCursor(context: CGContext) {
|
||||
guard self.shouldDrawCursor else {
|
||||
return
|
||||
}
|
||||
|
||||
context.saveGState()
|
||||
defer { context.restoreGState() }
|
||||
|
||||
@ -129,6 +126,8 @@ extension NeoVimView {
|
||||
// FIXME: take ligatures into account (is it a good idea to do this?)
|
||||
let rowRun = RowRun(row: cursorRegion.top, range: cursorRegion.columnRange, attrs: attrs)
|
||||
self.draw(rowRun: rowRun, in: context)
|
||||
|
||||
self.shouldDrawCursor = false
|
||||
}
|
||||
|
||||
fileprivate func drawBackground(positions: [CGPoint], background: Int, in context: CGContext) {
|
||||
|
@ -82,7 +82,7 @@ extension NeoVimView {
|
||||
|
||||
public func setMarkedText(_ aString: Any, selectedRange: NSRange, replacementRange: NSRange) {
|
||||
if self.markedText == nil {
|
||||
self.markedPosition = self.grid.putPosition
|
||||
self.markedPosition = self.grid.position
|
||||
}
|
||||
|
||||
// eg 하 -> hanja popup, cf comment for self.lastMarkedText
|
||||
@ -112,7 +112,7 @@ extension NeoVimView {
|
||||
self.keyDownDone = true
|
||||
|
||||
// TODO: necessary?
|
||||
self.markForRender(row: self.grid.putPosition.row, column: self.grid.putPosition.column)
|
||||
self.markForRender(row: self.grid.position.row, column: self.grid.position.column)
|
||||
}
|
||||
|
||||
/// Return the current selection (or the position of the cursor with empty-length range).
|
||||
@ -126,7 +126,7 @@ extension NeoVimView {
|
||||
return NSRange(location: NSNotFound, length: 0)
|
||||
}
|
||||
|
||||
let result = NSRange(location: self.grid.singleIndexFrom(self.grid.putPosition), length: 0)
|
||||
let result = NSRange(location: self.grid.singleIndexFrom(self.grid.position), length: 0)
|
||||
// self.logger.debug("\(#function): \(result)")
|
||||
return result
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ extension NeoVimView {
|
||||
|
||||
self.grid.eolClear()
|
||||
|
||||
let putPosition = self.grid.putPosition
|
||||
let putPosition = self.grid.position
|
||||
let region = Region(top: putPosition.row,
|
||||
bottom: putPosition.row,
|
||||
left: putPosition.column,
|
||||
@ -48,32 +48,8 @@ extension NeoVimView {
|
||||
self.bridgeLogger.debug("pos: \(position), screen: \(screenCursor), " +
|
||||
"current-pos: \(currentPosition)")
|
||||
|
||||
self.currentPosition = currentPosition
|
||||
let curScreenCursor = self.grid.screenCursor
|
||||
|
||||
// Because neovim fills blank space with "Space" and when we enter "Space"
|
||||
// we don't get the puts, thus we have to redraw the put position.
|
||||
if self.usesLigatures {
|
||||
self.markForRender(region: self.grid.regionOfWord(at: self.grid.putPosition))
|
||||
self.markForRender(region: self.grid.regionOfWord(at: curScreenCursor))
|
||||
self.markForRender(region: self.grid.regionOfWord(at: position))
|
||||
self.markForRender(region: self.grid.regionOfWord(at: screenCursor))
|
||||
} else {
|
||||
self.markForRender(cellPosition: self.grid.putPosition)
|
||||
// Redraw where the cursor has been till now, ie remove the current cursor.
|
||||
self.markForRender(cellPosition: curScreenCursor)
|
||||
if self.grid.isPreviousCellEmpty(curScreenCursor) {
|
||||
self.markForRender(cellPosition: self.grid.previousCellPosition(curScreenCursor))
|
||||
}
|
||||
if self.grid.isNextCellEmpty(curScreenCursor) {
|
||||
self.markForRender(cellPosition: self.grid.nextCellPosition(curScreenCursor))
|
||||
}
|
||||
self.markForRender(cellPosition: position)
|
||||
self.markForRender(cellPosition: screenCursor)
|
||||
}
|
||||
|
||||
self.markForRender(cellPosition: self.grid.position)
|
||||
self.grid.goto(position)
|
||||
self.grid.moveCursor(screenCursor)
|
||||
}
|
||||
gui.async {
|
||||
self.delegate?.cursor(to: currentPosition)
|
||||
@ -84,7 +60,6 @@ extension NeoVimView {
|
||||
gui.async {
|
||||
self.bridgeLogger.debug(cursorModeShapeName(mode))
|
||||
self.mode = mode
|
||||
self.updateCursorWhenPutting(currentPosition: .zero, screenCursor: .zero)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +94,7 @@ extension NeoVimView {
|
||||
|
||||
public func put(_ string: String, screenCursor: Position) {
|
||||
gui.async {
|
||||
let curPos = self.grid.putPosition
|
||||
let curPos = self.grid.position
|
||||
self.bridgeLogger.debug("\(curPos) -> \(string) <- screen: \(screenCursor)")
|
||||
|
||||
self.grid.put(string)
|
||||
@ -133,8 +108,6 @@ extension NeoVimView {
|
||||
} else {
|
||||
self.markForRender(cellPosition: curPos)
|
||||
}
|
||||
|
||||
self.updateCursorWhenPutting(currentPosition: curPos, screenCursor: screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +115,7 @@ extension NeoVimView {
|
||||
gui.async {
|
||||
self.bridgeLogger.debug("'\(markedText)' <- screen: \(screenCursor)")
|
||||
|
||||
let curPos = self.grid.putPosition
|
||||
let curPos = self.grid.position
|
||||
self.grid.putMarkedText(markedText)
|
||||
|
||||
self.markForRender(position: curPos)
|
||||
@ -151,8 +124,6 @@ extension NeoVimView {
|
||||
if markedText.characters.count == 0 {
|
||||
self.markForRender(position: self.grid.previousCellPosition(curPos))
|
||||
}
|
||||
|
||||
self.updateCursorWhenPutting(currentPosition: curPos, screenCursor: screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,14 +135,20 @@ extension NeoVimView {
|
||||
|
||||
self.grid.unmarkCell(position)
|
||||
self.markForRender(position: position)
|
||||
|
||||
self.markForRender(screenCursor: self.grid.screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
public func flush() {
|
||||
gui.async {
|
||||
self.bridgeLogger.debug("-----------------------------")
|
||||
self.bridgeLogger.hr()
|
||||
|
||||
self.shouldDrawCursor = true
|
||||
|
||||
if self.usesLigatures {
|
||||
self.markForRender(region: self.grid.regionOfWord(at: self.grid.position))
|
||||
} else {
|
||||
self.markForRender(cellPosition: self.grid.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +196,7 @@ extension NeoVimView {
|
||||
|
||||
public func autoCommandEvent(_ event: NeoVimAutoCommandEvent, bufferHandle: Int) {
|
||||
gui.async {
|
||||
// self.bridgeLogger.debug("\(neoVimAutoCommandEventName(event)) -> \(bufferHandle)")
|
||||
self.bridgeLogger.debug("\(neoVimAutoCommandEventName(event)) -> \(bufferHandle)")
|
||||
|
||||
if event == .BUFWINENTER || event == .BUFWINLEAVE {
|
||||
self.bufferListChanged()
|
||||
@ -386,21 +363,6 @@ extension NeoVimView {
|
||||
fileprivate func bufferListChanged() {
|
||||
self.delegate?.bufferListChanged()
|
||||
}
|
||||
|
||||
fileprivate func updateCursorWhenPutting(currentPosition curPos: Position,
|
||||
screenCursor: Position) {
|
||||
|
||||
if self.mode == .cmdline {
|
||||
// When the cursor is in the command line, then we need this...
|
||||
self.markForRender(cellPosition: self.grid.previousCellPosition(curPos))
|
||||
self.markForRender(cellPosition: self.grid.nextCellPosition(curPos))
|
||||
self.markForRender(screenCursor: self.grid.putPosition)
|
||||
}
|
||||
|
||||
self.markForRender(screenCursor: screenCursor)
|
||||
self.markForRender(cellPosition: self.grid.screenCursor)
|
||||
self.grid.moveCursor(screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate let gui = DispatchQueue.main
|
@ -184,6 +184,7 @@ public class NeoVimView: NSView,
|
||||
var currentEmoji = "😎"
|
||||
|
||||
var _font = NeoVimView.defaultFont
|
||||
var shouldDrawCursor = false
|
||||
|
||||
// MARK: - Private
|
||||
fileprivate var _linespacing = NeoVimView.defaultLinespacing
|
||||
|
Loading…
Reference in New Issue
Block a user