mirror of
https://github.com/qvacua/vimr.git
synced 2024-10-27 10:23:12 +03:00
Implement update fg/bg/sp
This commit is contained in:
parent
edffb8956b
commit
bbc0096019
@ -18,6 +18,7 @@
|
||||
#import <nvim/event/signal.h>
|
||||
#import <nvim/main.h>
|
||||
|
||||
#define pun_type(t, x) (*((t *)(&x)))
|
||||
|
||||
// We declare nvim_main because it's not declared in any header files of neovim
|
||||
extern int nvim_main(int argc, char **argv);
|
||||
@ -32,6 +33,10 @@ static uv_cond_t condition;
|
||||
|
||||
static id <NeoVimUiBridgeProtocol> neo_vim_osx_ui;
|
||||
|
||||
static unsigned int default_foreground = qDefaultForeground;
|
||||
static unsigned int default_background = qDefaultBackground;
|
||||
static unsigned int default_special = qDefaultSpecial;
|
||||
|
||||
typedef struct {
|
||||
UIBridgeData *bridge;
|
||||
Loop *loop;
|
||||
@ -182,12 +187,12 @@ static void xpc_ui_highlight_set(UI *ui __unused, HlAttrs attrs) {
|
||||
CellAttributes cellAttrs;
|
||||
cellAttrs.fontTrait = trait;
|
||||
|
||||
unsigned int fg = attrs.foreground == -1 ? qDefaultForeground : *((unsigned int*)(&attrs.foreground));
|
||||
unsigned int bg = attrs.background == -1 ? qDefaultBackground : *((unsigned int*)(&attrs.background));
|
||||
unsigned int fg = attrs.foreground == -1 ? default_foreground : pun_type(unsigned int, attrs.foreground);
|
||||
unsigned int bg = attrs.background == -1 ? default_background : pun_type(unsigned int, attrs.background);
|
||||
|
||||
cellAttrs.foreground = attrs.reverse ? bg : fg;
|
||||
cellAttrs.background = attrs.reverse ? fg : bg;
|
||||
cellAttrs.special = attrs.special == -1 ? qDefaultSpecial : *((unsigned int*)(&attrs.special));
|
||||
cellAttrs.special = attrs.special == -1 ? default_special : pun_type(unsigned int, attrs.special);
|
||||
|
||||
[neo_vim_osx_ui highlightSet:cellAttrs];
|
||||
}
|
||||
@ -215,17 +220,26 @@ static void xpc_ui_flush(UI *ui __unused) {
|
||||
}
|
||||
|
||||
static void xpc_ui_update_fg(UI *ui __unused, int fg) {
|
||||
//printf("update fg\n");
|
||||
// printf("update fg: %x\n", fg);
|
||||
if (fg != -1) {
|
||||
default_foreground = pun_type(unsigned int, fg);
|
||||
}
|
||||
[neo_vim_osx_ui updateForeground:fg];
|
||||
}
|
||||
|
||||
static void xpc_ui_update_bg(UI *ui __unused, int bg) {
|
||||
//printf("update bg\n");
|
||||
// printf("update bg: %x\n", bg);
|
||||
if (bg != -1) {
|
||||
default_background = pun_type(unsigned int, bg);
|
||||
}
|
||||
[neo_vim_osx_ui updateBackground:bg];
|
||||
}
|
||||
|
||||
static void xpc_ui_update_sp(UI *ui __unused, int sp) {
|
||||
//printf("update sp\n");
|
||||
// printf("update sp: %x\n", sp);
|
||||
if (sp != -1) {
|
||||
default_special = pun_type(unsigned int, sp);
|
||||
}
|
||||
[neo_vim_osx_ui updateSpecial:sp];
|
||||
}
|
||||
|
||||
@ -365,7 +379,7 @@ static void wait_input_enqueue(void **argv) {
|
||||
}
|
||||
|
||||
- (void)vimInput:(NSString *)input {
|
||||
// we retain, but not release here since it will be released in wait_input_enqueue
|
||||
// We retain, but not release here since it will be released in wait_input_enqueue.
|
||||
loop_schedule(&main_loop, event_create(1, wait_input_enqueue, 1, [input retain]));
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,10 @@ class Grid: CustomStringConvertible {
|
||||
self.size = size
|
||||
self.position = Position.zero
|
||||
|
||||
let emptyRow = Array(count: size.width, repeatedValue: Cell(string: " ", attrs: qEmptyCellAttributes))
|
||||
let emptyCellAttrs = CellAttributes(fontTrait: .None,
|
||||
foreground: self.foreground, background: self.background, special: self.special)
|
||||
|
||||
let emptyRow = Array(count: size.width, repeatedValue: Cell(string: " ", attrs: emptyCellAttrs))
|
||||
self.cells = Array(count: size.height, repeatedValue: emptyRow)
|
||||
}
|
||||
|
||||
@ -167,4 +170,4 @@ class Grid: CustomStringConvertible {
|
||||
self.cells[i].replaceRange(region.left...region.right, with: clearedRow)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
@import Cocoa;
|
||||
@import CoreText;
|
||||
|
||||
CTFontRef lookupFont(NSMutableArray *fontCache, const unichar *chars, UniCharCount count, CTFontRef currFontRef);
|
||||
CFAttributedStringRef attributedStringForString(NSString *string, const CTFontRef font, BOOL useLigatures);
|
||||
UniCharCount fetchGlyphsAndAdvances(const CTLineRef line, CGGlyph *glyphs, CGSize *advances, UniCharCount length);
|
||||
UniCharCount gatherGlyphs(CGGlyph glyphs[], UniCharCount count);
|
||||
UniCharCount ligatureGlyphsForChars(const unichar *chars, CGGlyph *glyphs, CGPoint *positions, UniCharCount length, CTFontRef font);
|
||||
void recurseDraw(const unichar *chars, CGGlyph *glyphs, CGPoint *positions, UniCharCount length, CGContextRef context, CTFontRef fontRef, NSMutableArray *fontCache, BOOL useLigatures);
|
||||
void recurseDraw(
|
||||
const unichar *chars,
|
||||
CGGlyph *glyphs, CGPoint *positions, UniCharCount length,
|
||||
CGContextRef context,
|
||||
CTFontRef fontRef,
|
||||
NSMutableArray *fontCache,
|
||||
BOOL useLigatures
|
||||
);
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#import "MMCoreTextView.h"
|
||||
|
||||
CTFontRef
|
||||
static CTFontRef
|
||||
lookupFont(NSMutableArray *fontCache, const unichar *chars, UniCharCount count,
|
||||
CTFontRef currFontRef)
|
||||
{
|
||||
@ -48,7 +48,7 @@ lookupFont(NSMutableArray *fontCache, const unichar *chars, UniCharCount count,
|
||||
return newFontRef;
|
||||
}
|
||||
|
||||
CFAttributedStringRef
|
||||
static CFAttributedStringRef
|
||||
attributedStringForString(NSString *string, const CTFontRef font,
|
||||
BOOL useLigatures)
|
||||
{
|
||||
@ -66,7 +66,7 @@ attributedStringForString(NSString *string, const CTFontRef font,
|
||||
(CFDictionaryRef)attrs);
|
||||
}
|
||||
|
||||
UniCharCount
|
||||
static UniCharCount
|
||||
fetchGlyphsAndAdvances(const CTLineRef line, CGGlyph *glyphs, CGSize *advances,
|
||||
UniCharCount length)
|
||||
{
|
||||
@ -96,7 +96,7 @@ fetchGlyphsAndAdvances(const CTLineRef line, CGGlyph *glyphs, CGSize *advances,
|
||||
return offset;
|
||||
}
|
||||
|
||||
UniCharCount
|
||||
static UniCharCount
|
||||
gatherGlyphs(CGGlyph glyphs[], UniCharCount count)
|
||||
{
|
||||
// Gather scattered glyphs that was happended by Surrogate pair chars
|
||||
@ -112,7 +112,7 @@ gatherGlyphs(CGGlyph glyphs[], UniCharCount count)
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
UniCharCount
|
||||
static UniCharCount
|
||||
ligatureGlyphsForChars(const unichar *chars, CGGlyph *glyphs,
|
||||
CGPoint *positions, UniCharCount length, CTFontRef font)
|
||||
{
|
||||
|
@ -76,15 +76,18 @@ typedef struct {
|
||||
- (void)flush;
|
||||
|
||||
/**
|
||||
* Set the foreground color.
|
||||
* Set the default foreground color.
|
||||
*/
|
||||
- (void)updateForeground:(int)fg;
|
||||
|
||||
/**
|
||||
* Set the background color.
|
||||
* Set the default background color.
|
||||
*/
|
||||
- (void)updateBackground:(int)bg;
|
||||
|
||||
/**
|
||||
* Set the default special color, eg curly underline for spelling errors.
|
||||
*/
|
||||
- (void)updateSpecial:(int)sp;
|
||||
- (void)suspend;
|
||||
- (void)setTitle:(NSString *)title;
|
||||
|
@ -19,24 +19,22 @@ func != (left: CellAttributes, right: CellAttributes) -> Bool {
|
||||
return !(left == right)
|
||||
}
|
||||
|
||||
private struct RowFragment: CustomStringConvertible {
|
||||
|
||||
let row: Int
|
||||
let range: Range<Int>
|
||||
|
||||
var description: String {
|
||||
return "RowFragment<\(row): \(range)>"
|
||||
extension CellAttributes: CustomStringConvertible {
|
||||
|
||||
public var description: String {
|
||||
return "CellAttributes<fg: \(String(format: "%x", self.foreground)), bg: \(String(format: "%x", self.background)))"
|
||||
}
|
||||
}
|
||||
|
||||
private struct AttributedRowFragment: CustomStringConvertible {
|
||||
/// Contiguous piece of cells of a row that has the same attributes.
|
||||
private struct RowRun: CustomStringConvertible {
|
||||
|
||||
let row: Int
|
||||
let range: Range<Int>
|
||||
let attrs: CellAttributes
|
||||
|
||||
var description: String {
|
||||
return "AttributedRowFragment<\(row): \(range)\n\(attrs)>"
|
||||
return "RowRun<\(row): \(range)\n\(attrs)>"
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +83,7 @@ public class NeoVimView: NSView {
|
||||
guard self.grid.hasData else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let context = NSGraphicsContext.currentContext()!.CGContext
|
||||
|
||||
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
||||
@ -93,7 +91,7 @@ public class NeoVimView: NSView {
|
||||
|
||||
let dirtyRects = self.rectsBeingDrawn()
|
||||
|
||||
self.attributedRowFragmentsIntersecting(rects: dirtyRects).forEach { rowFrag in
|
||||
self.rowRunIntersecting(rects: dirtyRects).forEach { rowFrag in
|
||||
let positions = rowFrag.range
|
||||
// filter out the put(0, 0)s (after a wide character)
|
||||
.filter { self.grid.cells[rowFrag.row][$0].string.characters.count > 0 }
|
||||
@ -119,32 +117,7 @@ public class NeoVimView: NSView {
|
||||
backgroundRect.fill()
|
||||
}
|
||||
|
||||
private func attributedRowFragmentsIntersecting(rects rects: [CGRect]) -> [AttributedRowFragment] {
|
||||
return self.rowFragmentsIntersecting(rects: rects)
|
||||
.map { rowFrag -> [AttributedRowFragment] in
|
||||
let row = rowFrag.row
|
||||
let rowCells = self.grid.cells[rowFrag.row]
|
||||
let range = rowFrag.range
|
||||
let startIndex = range.startIndex
|
||||
|
||||
var result = [
|
||||
AttributedRowFragment(row: row, range: startIndex...startIndex, attrs: rowCells[startIndex].attrs)
|
||||
]
|
||||
range.forEach { idx in
|
||||
if rowCells[idx].attrs == result.last!.attrs {
|
||||
let last = result.popLast()!
|
||||
result.append(AttributedRowFragment(row: row, range: last.range.startIndex...idx, attrs: last.attrs))
|
||||
} else {
|
||||
result.append(AttributedRowFragment(row: row, range: idx...idx, attrs: rowCells[idx].attrs))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
.flatMap { $0 }
|
||||
}
|
||||
|
||||
private func rowFragmentsIntersecting(rects rects: [CGRect]) -> [RowFragment] {
|
||||
private func rowRunIntersecting(rects rects: [CGRect]) -> [RowRun] {
|
||||
return rects
|
||||
.map { rect -> Region in
|
||||
let rowStart = Int(floor((self.frame.height - (rect.origin.y + rect.size.height)) / self.cellSize.height))
|
||||
@ -153,10 +126,30 @@ public class NeoVimView: NSView {
|
||||
let columnEnd = Int(ceil((rect.origin.x + rect.size.width) / self.cellSize.width)) - 1
|
||||
return Region(top: rowStart, bottom: rowEnd, left: columnStart, right: columnEnd)
|
||||
} // There can be overlaps between the Regions, but for the time being we ignore them.
|
||||
.map { region -> [RowFragment] in
|
||||
return (region.rowRange).map { RowFragment(row: $0, range: region.columnRange) }
|
||||
}
|
||||
.flatMap { $0 }
|
||||
.map { region -> [RowRun] in
|
||||
return (region.rowRange)
|
||||
.map { row -> [RowRun] in
|
||||
let range = region.columnRange
|
||||
let rowCells = self.grid.cells[row]
|
||||
let startIndex = range.startIndex
|
||||
|
||||
var result = [
|
||||
RowRun(row: row, range: startIndex...startIndex, attrs: rowCells[startIndex].attrs)
|
||||
]
|
||||
range.forEach { idx in
|
||||
if rowCells[idx].attrs == result.last!.attrs {
|
||||
let last = result.popLast()!
|
||||
result.append(RowRun(row: row, range: last.range.startIndex...idx, attrs: last.attrs))
|
||||
} else {
|
||||
result.append(RowRun(row: row, range: idx...idx, attrs: rowCells[idx].attrs))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
} // -> [[RowRun]]
|
||||
.flatMap { $0 } // -> [RowRun]
|
||||
} // -> [[RowRun]]
|
||||
.flatMap { $0 } // -> [RowRun]
|
||||
}
|
||||
|
||||
private func positionOnView(row: Int, column: Int) -> CGPoint {
|
||||
@ -255,20 +248,19 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
Swift.print("### scroll count: \(count)")
|
||||
|
||||
gui {
|
||||
// Swift.print("before scroll: \(self.grid)")
|
||||
self.grid.scroll(Int(count))
|
||||
// Swift.print("after scroll: \(self.grid)")
|
||||
|
||||
let top = CGFloat(self.grid.region.top)
|
||||
let bottom = CGFloat(self.grid.region.bottom)
|
||||
let left = CGFloat(self.grid.region.left)
|
||||
let right = CGFloat(self.grid.region.right)
|
||||
let region = self.grid.region
|
||||
let top = CGFloat(region.top)
|
||||
let bottom = CGFloat(region.bottom)
|
||||
let left = CGFloat(region.left)
|
||||
let right = CGFloat(region.right)
|
||||
|
||||
let width = right - left + 1
|
||||
let height = bottom - top + 1
|
||||
|
||||
let rect = CGRect(x: left * self.cellSize.width, y: bottom * self.cellSize.height,
|
||||
width: width * self.cellSize.width, height: height * self.cellSize.height)
|
||||
width: width * self.cellSize.width, height: height * self.cellSize.height)
|
||||
self.setNeedsDisplayInRect(rect)
|
||||
}
|
||||
}
|
||||
@ -309,15 +301,24 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
}
|
||||
|
||||
public func updateForeground(fg: Int32) {
|
||||
// Swift.print("### update fg: \(colorFromCode(fg))")
|
||||
// Swift.print("### update fg: \(String(format: "%x", fg))")
|
||||
gui {
|
||||
self.grid.foreground = UInt32(bitPattern: fg)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateBackground(bg: Int32) {
|
||||
// Swift.print("### update bg: \(colorFromCode(bg, kind: .Background))")
|
||||
// Swift.print("### update bg: \(String(format: "%x", bg))")
|
||||
gui {
|
||||
self.grid.background = UInt32(bitPattern: bg)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateSpecial(sp: Int32) {
|
||||
// Swift.print("### update sp: \(colorFromCode(sp, kind: .Special))")
|
||||
// Swift.print("### update sp: \(String(format: "%x", sp)")
|
||||
gui {
|
||||
self.grid.special = UInt32(bitPattern: sp)
|
||||
}
|
||||
}
|
||||
|
||||
public func suspend() {
|
||||
|
Loading…
Reference in New Issue
Block a user