mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-29 16:56:40 +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,8 +91,7 @@ class Grid: CustomStringConvertible {
|
|||||||
|
|
||||||
fileprivate(set) var region = Region.zero
|
fileprivate(set) var region = Region.zero
|
||||||
fileprivate(set) var size = Size.zero
|
fileprivate(set) var size = Size.zero
|
||||||
fileprivate(set) var putPosition = Position.zero
|
fileprivate(set) var position = Position.zero
|
||||||
fileprivate(set) var screenCursor = Position.zero
|
|
||||||
|
|
||||||
var foreground = defaultForeground
|
var foreground = defaultForeground
|
||||||
var background = defaultBackground
|
var background = defaultBackground
|
||||||
@ -116,7 +115,7 @@ class Grid: CustomStringConvertible {
|
|||||||
func resize(_ size: Size) {
|
func resize(_ size: Size) {
|
||||||
self.region = Region(top: 0, bottom: size.height - 1, left: 0, right: size.width - 1)
|
self.region = Region(top: 0, bottom: size.height - 1, left: 0, right: size.width - 1)
|
||||||
self.size = size
|
self.size = size
|
||||||
self.putPosition = Position.zero
|
self.position = Position.zero
|
||||||
|
|
||||||
let emptyCellAttrs = CellAttributes(fontTrait: .none,
|
let emptyCellAttrs = CellAttributes(fontTrait: .none,
|
||||||
foreground: self.foreground, background: self.background, special: self.special)
|
foreground: self.foreground, background: self.background, special: self.special)
|
||||||
@ -131,8 +130,8 @@ class Grid: CustomStringConvertible {
|
|||||||
|
|
||||||
func eolClear() {
|
func eolClear() {
|
||||||
self.clearRegion(
|
self.clearRegion(
|
||||||
Region(top: self.putPosition.row, bottom: self.putPosition.row,
|
Region(top: self.position.row, bottom: self.position.row,
|
||||||
left: self.putPosition.column, right: self.region.right)
|
left: self.position.column, right: self.region.right)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,11 +170,7 @@ class Grid: CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func goto(_ position: Position) {
|
func goto(_ position: Position) {
|
||||||
self.putPosition = position
|
self.position = position
|
||||||
}
|
|
||||||
|
|
||||||
func moveCursor(_ position: Position) {
|
|
||||||
self.screenCursor = position
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func put(_ string: String) {
|
func put(_ string: String) {
|
||||||
@ -184,17 +179,17 @@ class Grid: CustomStringConvertible {
|
|||||||
// =>
|
// =>
|
||||||
// |abcde>| <- ">" at the end of the line is wrong -> the XPC could tell the main app whether the string occupies
|
// |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()
|
// |ㅎ | 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
|
// Increment the column of the put position because neovim calls sets the position only once when drawing
|
||||||
// consecutive cells in the same line
|
// consecutive cells in the same line
|
||||||
self.putPosition.column += 1
|
self.advancePosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
func putMarkedText(_ string: String) {
|
func putMarkedText(_ string: String) {
|
||||||
// NOTE: Maybe there's a better way to indicate marked text than inverting...
|
// 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.cells[self.position.row][self.position.column] = Cell(string: string, attrs: self.attrs, marked: true)
|
||||||
self.putPosition.column += 1
|
self.advancePosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarkCell(_ position: Position) {
|
func unmarkCell(_ position: Position) {
|
||||||
@ -302,4 +297,11 @@ class Grid: CustomStringConvertible {
|
|||||||
|
|
||||||
return true
|
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 {
|
fileprivate func cursorRegion() -> Region {
|
||||||
let cursorPosition: Position
|
let cursorPosition = self.grid.position
|
||||||
if self.mode == .cmdline
|
|
||||||
|| self.mode == .cmdlineInsert
|
|
||||||
|| self.mode == .cmdlineReplace {
|
|
||||||
cursorPosition = self.grid.putPosition
|
|
||||||
} else {
|
|
||||||
cursorPosition = self.grid.screenCursor
|
|
||||||
}
|
|
||||||
|
|
||||||
let saneRow = max(0, min(cursorPosition.row, self.grid.size.height - 1))
|
let saneRow = max(0, min(cursorPosition.row, self.grid.size.height - 1))
|
||||||
let saneColumn = max(0, min(cursorPosition.column, self.grid.size.width - 1))
|
let saneColumn = max(0, min(cursorPosition.column, self.grid.size.width - 1))
|
||||||
@ -104,6 +97,10 @@ extension NeoVimView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func drawCursor(context: CGContext) {
|
fileprivate func drawCursor(context: CGContext) {
|
||||||
|
guard self.shouldDrawCursor else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
context.saveGState()
|
context.saveGState()
|
||||||
defer { context.restoreGState() }
|
defer { context.restoreGState() }
|
||||||
|
|
||||||
@ -129,6 +126,8 @@ extension NeoVimView {
|
|||||||
// FIXME: take ligatures into account (is it a good idea to do this?)
|
// FIXME: take ligatures into account (is it a good idea to do this?)
|
||||||
let rowRun = RowRun(row: cursorRegion.top, range: cursorRegion.columnRange, attrs: attrs)
|
let rowRun = RowRun(row: cursorRegion.top, range: cursorRegion.columnRange, attrs: attrs)
|
||||||
self.draw(rowRun: rowRun, in: context)
|
self.draw(rowRun: rowRun, in: context)
|
||||||
|
|
||||||
|
self.shouldDrawCursor = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func drawBackground(positions: [CGPoint], background: Int, in context: CGContext) {
|
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) {
|
public func setMarkedText(_ aString: Any, selectedRange: NSRange, replacementRange: NSRange) {
|
||||||
if self.markedText == nil {
|
if self.markedText == nil {
|
||||||
self.markedPosition = self.grid.putPosition
|
self.markedPosition = self.grid.position
|
||||||
}
|
}
|
||||||
|
|
||||||
// eg 하 -> hanja popup, cf comment for self.lastMarkedText
|
// eg 하 -> hanja popup, cf comment for self.lastMarkedText
|
||||||
@ -112,7 +112,7 @@ extension NeoVimView {
|
|||||||
self.keyDownDone = true
|
self.keyDownDone = true
|
||||||
|
|
||||||
// TODO: necessary?
|
// 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).
|
/// 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)
|
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)")
|
// self.logger.debug("\(#function): \(result)")
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ extension NeoVimView {
|
|||||||
|
|
||||||
self.grid.eolClear()
|
self.grid.eolClear()
|
||||||
|
|
||||||
let putPosition = self.grid.putPosition
|
let putPosition = self.grid.position
|
||||||
let region = Region(top: putPosition.row,
|
let region = Region(top: putPosition.row,
|
||||||
bottom: putPosition.row,
|
bottom: putPosition.row,
|
||||||
left: putPosition.column,
|
left: putPosition.column,
|
||||||
@ -48,32 +48,8 @@ extension NeoVimView {
|
|||||||
self.bridgeLogger.debug("pos: \(position), screen: \(screenCursor), " +
|
self.bridgeLogger.debug("pos: \(position), screen: \(screenCursor), " +
|
||||||
"current-pos: \(currentPosition)")
|
"current-pos: \(currentPosition)")
|
||||||
|
|
||||||
self.currentPosition = currentPosition
|
self.markForRender(cellPosition: self.grid.position)
|
||||||
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.grid.goto(position)
|
self.grid.goto(position)
|
||||||
self.grid.moveCursor(screenCursor)
|
|
||||||
}
|
}
|
||||||
gui.async {
|
gui.async {
|
||||||
self.delegate?.cursor(to: currentPosition)
|
self.delegate?.cursor(to: currentPosition)
|
||||||
@ -84,7 +60,6 @@ extension NeoVimView {
|
|||||||
gui.async {
|
gui.async {
|
||||||
self.bridgeLogger.debug(cursorModeShapeName(mode))
|
self.bridgeLogger.debug(cursorModeShapeName(mode))
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.updateCursorWhenPutting(currentPosition: .zero, screenCursor: .zero)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +94,7 @@ extension NeoVimView {
|
|||||||
|
|
||||||
public func put(_ string: String, screenCursor: Position) {
|
public func put(_ string: String, screenCursor: Position) {
|
||||||
gui.async {
|
gui.async {
|
||||||
let curPos = self.grid.putPosition
|
let curPos = self.grid.position
|
||||||
self.bridgeLogger.debug("\(curPos) -> \(string) <- screen: \(screenCursor)")
|
self.bridgeLogger.debug("\(curPos) -> \(string) <- screen: \(screenCursor)")
|
||||||
|
|
||||||
self.grid.put(string)
|
self.grid.put(string)
|
||||||
@ -133,8 +108,6 @@ extension NeoVimView {
|
|||||||
} else {
|
} else {
|
||||||
self.markForRender(cellPosition: curPos)
|
self.markForRender(cellPosition: curPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.updateCursorWhenPutting(currentPosition: curPos, screenCursor: screenCursor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +115,7 @@ extension NeoVimView {
|
|||||||
gui.async {
|
gui.async {
|
||||||
self.bridgeLogger.debug("'\(markedText)' <- screen: \(screenCursor)")
|
self.bridgeLogger.debug("'\(markedText)' <- screen: \(screenCursor)")
|
||||||
|
|
||||||
let curPos = self.grid.putPosition
|
let curPos = self.grid.position
|
||||||
self.grid.putMarkedText(markedText)
|
self.grid.putMarkedText(markedText)
|
||||||
|
|
||||||
self.markForRender(position: curPos)
|
self.markForRender(position: curPos)
|
||||||
@ -151,8 +124,6 @@ extension NeoVimView {
|
|||||||
if markedText.characters.count == 0 {
|
if markedText.characters.count == 0 {
|
||||||
self.markForRender(position: self.grid.previousCellPosition(curPos))
|
self.markForRender(position: self.grid.previousCellPosition(curPos))
|
||||||
}
|
}
|
||||||
|
|
||||||
self.updateCursorWhenPutting(currentPosition: curPos, screenCursor: screenCursor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,14 +135,20 @@ extension NeoVimView {
|
|||||||
|
|
||||||
self.grid.unmarkCell(position)
|
self.grid.unmarkCell(position)
|
||||||
self.markForRender(position: position)
|
self.markForRender(position: position)
|
||||||
|
|
||||||
self.markForRender(screenCursor: self.grid.screenCursor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func flush() {
|
public func flush() {
|
||||||
gui.async {
|
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) {
|
public func autoCommandEvent(_ event: NeoVimAutoCommandEvent, bufferHandle: Int) {
|
||||||
gui.async {
|
gui.async {
|
||||||
// self.bridgeLogger.debug("\(neoVimAutoCommandEventName(event)) -> \(bufferHandle)")
|
self.bridgeLogger.debug("\(neoVimAutoCommandEventName(event)) -> \(bufferHandle)")
|
||||||
|
|
||||||
if event == .BUFWINENTER || event == .BUFWINLEAVE {
|
if event == .BUFWINENTER || event == .BUFWINLEAVE {
|
||||||
self.bufferListChanged()
|
self.bufferListChanged()
|
||||||
@ -386,21 +363,6 @@ extension NeoVimView {
|
|||||||
fileprivate func bufferListChanged() {
|
fileprivate func bufferListChanged() {
|
||||||
self.delegate?.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
|
fileprivate let gui = DispatchQueue.main
|
@ -184,6 +184,7 @@ public class NeoVimView: NSView,
|
|||||||
var currentEmoji = "😎"
|
var currentEmoji = "😎"
|
||||||
|
|
||||||
var _font = NeoVimView.defaultFont
|
var _font = NeoVimView.defaultFont
|
||||||
|
var shouldDrawCursor = false
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
fileprivate var _linespacing = NeoVimView.defaultLinespacing
|
fileprivate var _linespacing = NeoVimView.defaultLinespacing
|
||||||
|
Loading…
Reference in New Issue
Block a user