1
1
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:
Tae Won Ha 2017-06-05 14:22:12 +02:00
parent 93b9366a66
commit 5d3aca696d
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
5 changed files with 43 additions and 79 deletions

View File

@ -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
}
}
}

View File

@ -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) {

View File

@ -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
}

View File

@ -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

View File

@ -184,6 +184,7 @@ public class NeoVimView: NSView,
var currentEmoji = "😎"
var _font = NeoVimView.defaultFont
var shouldDrawCursor = false
// MARK: - Private
fileprivate var _linespacing = NeoVimView.defaultLinespacing