mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 14:52:19 +03:00
Try to correctly render marked text
This commit is contained in:
parent
1d1c46c3fc
commit
e685ef3581
@ -17,6 +17,6 @@
|
||||
- (void)vimInput:(NSString * _Nonnull)input;
|
||||
- (void)vimInputMarkedText:(NSString *_Nonnull)markedText;
|
||||
|
||||
- (void)debugScreenLines;
|
||||
- (void)debug1;
|
||||
|
||||
@end
|
||||
|
@ -18,6 +18,4 @@
|
||||
- (void)vimInput:(NSString *_Nonnull)input;
|
||||
- (void)vimInputMarkedText:(NSString *_Nonnull)markedText;
|
||||
|
||||
- (void)debugScreenLines;
|
||||
|
||||
@end
|
||||
|
@ -18,6 +18,7 @@
|
||||
#import <nvim/event/signal.h>
|
||||
#import <nvim/main.h>
|
||||
|
||||
|
||||
#define pun_type(t, x) (*((t *)(&x)))
|
||||
|
||||
typedef struct {
|
||||
@ -48,9 +49,12 @@ static uv_cond_t _condition;
|
||||
|
||||
static id <NeoVimUiBridgeProtocol> _neo_vim_osx_ui;
|
||||
|
||||
static int _markedRow = 0;
|
||||
static int _markedColumn = 0;
|
||||
static NSString *_markedText = nil;
|
||||
static int _marked_row = 0;
|
||||
static int _marked_column = 0;
|
||||
static int _put_row = -1;
|
||||
static int _put_column = -1;
|
||||
static NSString *_marked_text = nil;
|
||||
static NSString *_backspace = nil;
|
||||
|
||||
static dispatch_queue_t _queue;
|
||||
|
||||
@ -129,234 +133,219 @@ static void suspend_event(void **argv) {
|
||||
|
||||
static void xpc_ui_resize(UI *ui __unused, int width, int height) {
|
||||
xpc_async(^{
|
||||
//printf("resize: %d:%d\n", width, height);
|
||||
[_neo_vim_osx_ui resizeToWidth:width height:height];
|
||||
[_neo_vim_osx_ui resizeToWidth:width height:height];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_clear(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("clear\n");
|
||||
[_neo_vim_osx_ui clear];
|
||||
[_neo_vim_osx_ui clear];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_eol_clear(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("eol clear\n");
|
||||
[_neo_vim_osx_ui eolClear];
|
||||
[_neo_vim_osx_ui eolClear];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_cursor_goto(UI *ui __unused, int row, int col) {
|
||||
xpc_async(^{
|
||||
//printf("cursor goto %d:%d\n", row, col);
|
||||
[_neo_vim_osx_ui cursorGotoRow:row column:col];
|
||||
_put_row = row;
|
||||
_put_column = col;
|
||||
|
||||
[_neo_vim_osx_ui gotoPosition:(Position) { .row = row, .column = col }
|
||||
screenCursor:(Position) { .row = cursorRow(), .column = cursorColumn() }
|
||||
bufferCursor:(Position) { .row = curwin->w_cursor.lnum - 1, .column = curwin->w_cursor.col }];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_update_menu(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("update menu\n");
|
||||
[_neo_vim_osx_ui updateMenu];
|
||||
[_neo_vim_osx_ui updateMenu];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_busy_start(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("busy start\n");
|
||||
[_neo_vim_osx_ui busyStart];
|
||||
[_neo_vim_osx_ui busyStart];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_busy_stop(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("busy stop\n");
|
||||
[_neo_vim_osx_ui busyStop];
|
||||
[_neo_vim_osx_ui busyStop];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_mouse_on(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("mouse on\n");
|
||||
[_neo_vim_osx_ui mouseOn];
|
||||
[_neo_vim_osx_ui mouseOn];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_mouse_off(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("mouse off\n");
|
||||
[_neo_vim_osx_ui mouseOff];
|
||||
[_neo_vim_osx_ui mouseOff];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_mode_change(UI *ui __unused, int mode) {
|
||||
xpc_async(^{
|
||||
//printf("mode change %04x\n", mode);
|
||||
[_neo_vim_osx_ui modeChange:mode];
|
||||
[_neo_vim_osx_ui modeChange:mode];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_set_scroll_region(UI *ui __unused, int top, int bot, int left, int right) {
|
||||
xpc_async(^{
|
||||
//printf("set scroll region: %d, %d, %d, %d\n", top, bot, left, right);
|
||||
[_neo_vim_osx_ui setScrollRegionToTop:top bottom:bot left:left right:right];
|
||||
[_neo_vim_osx_ui setScrollRegionToTop:top bottom:bot left:left right:right];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_scroll(UI *ui __unused, int count) {
|
||||
xpc_async(^{
|
||||
//printf("scroll %d\n", count);
|
||||
[_neo_vim_osx_ui scroll:count];
|
||||
[_neo_vim_osx_ui scroll:count];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_highlight_set(UI *ui __unused, HlAttrs attrs) {
|
||||
xpc_async(^{
|
||||
//printf("highlight set\n");
|
||||
FontTrait trait = FontTraitNone;
|
||||
if (attrs.italic) {
|
||||
trait |= FontTraitItalic;
|
||||
}
|
||||
if (attrs.bold) {
|
||||
trait |= FontTraitBold;
|
||||
}
|
||||
if (attrs.underline) {
|
||||
trait |= FontTraitUnderline;
|
||||
}
|
||||
if (attrs.undercurl) {
|
||||
trait |= FontTraitUndercurl;
|
||||
}
|
||||
CellAttributes cellAttrs;
|
||||
cellAttrs.fontTrait = trait;
|
||||
FontTrait trait = FontTraitNone;
|
||||
if (attrs.italic) {
|
||||
trait |= FontTraitItalic;
|
||||
}
|
||||
if (attrs.bold) {
|
||||
trait |= FontTraitBold;
|
||||
}
|
||||
if (attrs.underline) {
|
||||
trait |= FontTraitUnderline;
|
||||
}
|
||||
if (attrs.undercurl) {
|
||||
trait |= FontTraitUndercurl;
|
||||
}
|
||||
CellAttributes cellAttrs;
|
||||
cellAttrs.fontTrait = trait;
|
||||
|
||||
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);
|
||||
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 ? _default_special : pun_type(unsigned int, attrs.special);
|
||||
cellAttrs.foreground = attrs.reverse ? bg : fg;
|
||||
cellAttrs.background = attrs.reverse ? fg : bg;
|
||||
cellAttrs.special = attrs.special == -1 ? _default_special : pun_type(unsigned int, attrs.special);
|
||||
|
||||
[_neo_vim_osx_ui highlightSet:cellAttrs];
|
||||
[_neo_vim_osx_ui highlightSet:cellAttrs];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_put(UI *ui __unused, uint8_t *str, size_t len) {
|
||||
xpc_async(^{
|
||||
NSString *string = [[NSString alloc] initWithBytes:str length:len encoding:NSUTF8StringEncoding];
|
||||
// printf("put: %lu:'%s'\n", len, [string cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
NSString *string = [[NSString alloc] initWithBytes:str length:len encoding:NSUTF8StringEncoding];
|
||||
|
||||
if (_markedText != nil && _markedColumn == cursorColumn() && _markedRow == cursorRow()) {
|
||||
[_neo_vim_osx_ui putMarkedText:string];
|
||||
} else if (_markedText != nil && len == 0 && _markedColumn == cursorColumn() - 1) {
|
||||
[_neo_vim_osx_ui putMarkedText:string];
|
||||
} else {
|
||||
[_neo_vim_osx_ui put:string];
|
||||
}
|
||||
if (_marked_text != nil && _marked_row == _put_row && _marked_column == _put_column) {
|
||||
// NSLog(@"!!! putting marked text: '%@'", string);
|
||||
[_neo_vim_osx_ui putMarkedText:string];
|
||||
} else if (_marked_text != nil && len == 0 && _marked_row == _put_row && _marked_column == _put_column - 1) {
|
||||
// NSLog(@"!!! putting marked text cuz zero");
|
||||
[_neo_vim_osx_ui putMarkedText:string];
|
||||
} else {
|
||||
// NSLog(@"putting non-marked text: '%@'", string);
|
||||
[_neo_vim_osx_ui put:string];
|
||||
}
|
||||
|
||||
[string release];
|
||||
_put_column += 1;
|
||||
[string release];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_bell(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("bell\n");
|
||||
[_neo_vim_osx_ui bell];
|
||||
[_neo_vim_osx_ui bell];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_visual_bell(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("visual bell\n");
|
||||
[_neo_vim_osx_ui visualBell];
|
||||
[_neo_vim_osx_ui visualBell];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_flush(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("flush\n");
|
||||
[_neo_vim_osx_ui flush];
|
||||
[_neo_vim_osx_ui flush];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_update_fg(UI *ui __unused, int fg) {
|
||||
xpc_async(^{
|
||||
// printf("update fg: %x\n", fg);
|
||||
if (fg == -1) {
|
||||
[_neo_vim_osx_ui updateForeground:_default_foreground];
|
||||
return;
|
||||
}
|
||||
if (fg == -1) {
|
||||
[_neo_vim_osx_ui updateForeground:_default_foreground];
|
||||
return;
|
||||
}
|
||||
|
||||
_default_foreground = pun_type(unsigned int, fg);
|
||||
[_neo_vim_osx_ui updateForeground:fg];
|
||||
_default_foreground = pun_type(unsigned int, fg);
|
||||
[_neo_vim_osx_ui updateForeground:fg];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_update_bg(UI *ui __unused, int bg) {
|
||||
xpc_async(^{
|
||||
// printf("update bg: %x\n", bg);
|
||||
if (bg == -1) {
|
||||
[_neo_vim_osx_ui updateBackground:_default_background];
|
||||
return;
|
||||
}
|
||||
if (bg == -1) {
|
||||
[_neo_vim_osx_ui updateBackground:_default_background];
|
||||
return;
|
||||
}
|
||||
|
||||
_default_background = pun_type(unsigned int, bg);
|
||||
[_neo_vim_osx_ui updateBackground:bg];
|
||||
_default_background = pun_type(unsigned int, bg);
|
||||
[_neo_vim_osx_ui updateBackground:bg];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_update_sp(UI *ui __unused, int sp) {
|
||||
xpc_async(^{
|
||||
// printf("update sp: %x\n", sp);
|
||||
if (sp == -1) {
|
||||
[_neo_vim_osx_ui updateSpecial:_default_special];
|
||||
return;
|
||||
}
|
||||
if (sp == -1) {
|
||||
[_neo_vim_osx_ui updateSpecial:_default_special];
|
||||
return;
|
||||
}
|
||||
|
||||
_default_special = pun_type(unsigned int, sp);
|
||||
[_neo_vim_osx_ui updateSpecial:sp];
|
||||
_default_special = pun_type(unsigned int, sp);
|
||||
[_neo_vim_osx_ui updateSpecial:sp];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_suspend(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("suspend\n");
|
||||
[_neo_vim_osx_ui suspend];
|
||||
[_neo_vim_osx_ui suspend];
|
||||
|
||||
XpcUiData *data = ui->data;
|
||||
// FIXME: dunno whether we need this: copied from tui.c
|
||||
// kill(0, SIGTSTP) won't stop the UI thread, so we must poll for SIGCONT
|
||||
// before continuing. This is done in another callback to avoid
|
||||
// loop_poll_events recursion
|
||||
queue_put_event(data->loop->fast_events, event_create(1, suspend_event, 1, ui));
|
||||
XpcUiData *data = ui->data;
|
||||
// FIXME: dunno whether we need this: copied from tui.c
|
||||
// kill(0, SIGTSTP) won't stop the UI thread, so we must poll for SIGCONT
|
||||
// before continuing. This is done in another callback to avoid
|
||||
// loop_poll_events recursion
|
||||
queue_put_event(data->loop->fast_events, event_create(1, suspend_event, 1, ui));
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_set_title(UI *ui __unused, char *title) {
|
||||
xpc_async(^{
|
||||
//printf("set title: %s\n", title);
|
||||
NSString *string = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding];
|
||||
[_neo_vim_osx_ui setTitle:string];
|
||||
[string release];
|
||||
NSString *string = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding];
|
||||
[_neo_vim_osx_ui setTitle:string];
|
||||
[string release];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_set_icon(UI *ui __unused, char *icon) {
|
||||
xpc_async(^{
|
||||
//printf("set title: %s\n", icon);
|
||||
NSString *string = [[NSString alloc] initWithCString:icon encoding:NSUTF8StringEncoding];
|
||||
[_neo_vim_osx_ui setIcon:string];
|
||||
[string release];
|
||||
NSString *string = [[NSString alloc] initWithCString:icon encoding:NSUTF8StringEncoding];
|
||||
[_neo_vim_osx_ui setIcon:string];
|
||||
[string release];
|
||||
});
|
||||
}
|
||||
|
||||
static void xpc_ui_stop(UI *ui __unused) {
|
||||
xpc_async(^{
|
||||
//printf("stop\n");
|
||||
[_neo_vim_osx_ui stop];
|
||||
[_neo_vim_osx_ui stop];
|
||||
|
||||
XpcUiData *data = (XpcUiData *) ui->data;
|
||||
data->stop = true;
|
||||
XpcUiData *data = (XpcUiData *) ui->data;
|
||||
data->stop = true;
|
||||
});
|
||||
}
|
||||
|
||||
@ -442,14 +431,18 @@ static void neovim_input(void **argv) {
|
||||
uv_cond_destroy(&_condition);
|
||||
uv_mutex_destroy(&_mutex);
|
||||
|
||||
// casting because [ui retain] returns an NSObject
|
||||
_neo_vim_osx_ui = (id <NeoVimUiBridgeProtocol>) [ui retain];
|
||||
[ui retain];
|
||||
_neo_vim_osx_ui = ui;
|
||||
|
||||
_backspace = [[NSString alloc] initWithString:@"<BS>"];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_neo_vim_osx_ui release];
|
||||
[_backspace release];
|
||||
|
||||
// FIXME: uv_thread_join(&thread) here after terminating neovim
|
||||
|
||||
[super dealloc];
|
||||
@ -460,64 +453,64 @@ static void neovim_input(void **argv) {
|
||||
}
|
||||
|
||||
- (void)vimInput:(NSString *_Nonnull)input {
|
||||
|
||||
xpc_async(^{
|
||||
if (_markedText == nil) {
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [input retain])); // release in neovim_input
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle cases like ㅎ -> arrow key: The previously marked text is the same as the finalized text which should
|
||||
// inserted. Neovim's drawing code is optimized such that it does not call put in this case again, thus, we
|
||||
// have to manually unmark the cells in the main app.
|
||||
if ([_markedText isEqualToString:input]) {
|
||||
[_neo_vim_osx_ui unmarkRow:cursorRow() column:MAX(cursorColumn() - 1, 0)];
|
||||
if (ScreenLines[cursorRow() * screen_Columns + MAX(cursorColumn() - 1, 0)] == 0x00) {
|
||||
[_neo_vim_osx_ui unmarkRow:cursorRow() column:MAX(cursorColumn() - 2, 0)];
|
||||
}
|
||||
}
|
||||
|
||||
[self deleteMarkedText];
|
||||
if (_marked_text == nil) {
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [input retain])); // release in neovim_input
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle cases like ㅎ -> arrow key: The previously marked text is the same as the finalized text which should
|
||||
// inserted. Neovim's drawing code is optimized such that it does not call put in this case again, thus, we have
|
||||
// to manually unmark the cells in the main app.
|
||||
if ([_marked_text isEqualToString:input]) {
|
||||
// NSLog(@"unmarking text: '%@'\t now at %d:%d", input, _put_row, _put_column);
|
||||
const char *str = [_marked_text cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
size_t cellCount = mb_string2cells((const char_u *) str);
|
||||
for (int i = 1; i <= cellCount; i++) {
|
||||
// NSLog(@"unmarking at %d:%d", _put_row, _put_column - i);
|
||||
[_neo_vim_osx_ui unmarkRow:_put_row column:MAX(_put_column - i, 0)];
|
||||
}
|
||||
}
|
||||
|
||||
[self deleteMarkedText];
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [input retain])); // release in neovim_input
|
||||
});
|
||||
}
|
||||
|
||||
- (void)vimInputMarkedText:(NSString *_Nonnull)markedText {
|
||||
xpc_async(^{
|
||||
if (_markedText != nil) {
|
||||
[self deleteMarkedText];
|
||||
}
|
||||
if (_marked_text == nil) {
|
||||
_marked_row = _put_row;
|
||||
_marked_column = _put_column;
|
||||
} else {
|
||||
[self deleteMarkedText];
|
||||
}
|
||||
|
||||
[self insertMarkedText:markedText];
|
||||
// NSLog(@"inserting marked text '%@' at %d:%d", markedText, _put_row, _put_column);
|
||||
[self insertMarkedText:markedText];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)insertMarkedText:(NSString *_Nonnull)markedText {
|
||||
_markedRow = cursorRow();
|
||||
_markedColumn = cursorColumn();
|
||||
_markedText = [markedText retain]; // release when the final text is input in -vimInput
|
||||
_marked_text = [markedText retain]; // release when the final text is input in -vimInput
|
||||
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_markedText retain])); // release in neovim_input
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_marked_text retain])); // release in neovim_input
|
||||
}
|
||||
|
||||
- (void)deleteMarkedText {
|
||||
NSUInteger length = [_markedText lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
|
||||
NSUInteger length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
|
||||
|
||||
[_markedText release];
|
||||
_markedText = nil;
|
||||
[_marked_text release];
|
||||
_marked_text = nil;
|
||||
|
||||
NSString *backspace = [[NSString alloc] initWithString:@"<BS>"];
|
||||
for (int i = 0; i < length; i++) {
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [backspace retain])); // release in neovim_input
|
||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_backspace retain])); // release in neovim_input
|
||||
}
|
||||
[backspace release];
|
||||
}
|
||||
|
||||
- (void)debugScreenLines {
|
||||
NSLog(@"--- ScreenLines ---");
|
||||
for (int i = 0; i < 20; i++) {
|
||||
printf("%c,\n", ScreenLines[i]);
|
||||
}
|
||||
- (void)debug1 {
|
||||
NSLog(@"_marked position: %d:%d", _marked_row, _marked_column);
|
||||
NSLog(@"current cursor position: %d:%d", ui_current_row(), ui_current_col());
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -26,15 +26,12 @@ struct Cell: CustomStringConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
struct Position: CustomStringConvertible {
|
||||
extension Position: CustomStringConvertible {
|
||||
|
||||
static let zero = Position(row: 0, column: 0)
|
||||
static let null = Position(row: -1, column: -1)
|
||||
|
||||
var row: Int
|
||||
var column: Int
|
||||
|
||||
var description: String {
|
||||
public var description: String {
|
||||
return "Position<\(self.row):\(self.column)>"
|
||||
}
|
||||
}
|
||||
@ -78,7 +75,8 @@ class Grid: CustomStringConvertible {
|
||||
|
||||
private(set) var region = Region.zero
|
||||
private(set) var size = Size.zero
|
||||
private(set) var position = Position.zero
|
||||
private(set) var putPosition = Position.zero
|
||||
private(set) var screenCursor = Position.zero
|
||||
|
||||
var foreground = qDefaultForeground
|
||||
var background = qDefaultBackground
|
||||
@ -102,7 +100,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.position = Position.zero
|
||||
self.putPosition = Position.zero
|
||||
|
||||
let emptyCellAttrs = CellAttributes(fontTrait: .None,
|
||||
foreground: self.foreground, background: self.background, special: self.special)
|
||||
@ -117,7 +115,7 @@ class Grid: CustomStringConvertible {
|
||||
|
||||
func eolClear() {
|
||||
self.clearRegion(
|
||||
Region(top: self.position.row, bottom: self.position.row, left: self.position.column, right: self.region.right)
|
||||
Region(top: self.putPosition.row, bottom: self.putPosition.row, left: self.putPosition.column, right: self.region.right)
|
||||
)
|
||||
}
|
||||
|
||||
@ -156,7 +154,11 @@ class Grid: CustomStringConvertible {
|
||||
}
|
||||
|
||||
func goto(position: Position) {
|
||||
self.position = position
|
||||
self.putPosition = position
|
||||
}
|
||||
|
||||
func moveCursor(position: Position) {
|
||||
self.screenCursor = position
|
||||
}
|
||||
|
||||
func put(string: String) {
|
||||
@ -165,14 +167,17 @@ class Grid: CustomStringConvertible {
|
||||
// =>
|
||||
// |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.position.row][self.position.column] = Cell(string: string, attrs: self.attrs)
|
||||
self.position.column += 1
|
||||
self.cells[self.putPosition.row][self.putPosition.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
|
||||
}
|
||||
|
||||
func putMarkedText(string: String) {
|
||||
// NOTE: Maybe there's a better way to indicate marked text than inverting...
|
||||
self.cells[self.position.row][self.position.column] = Cell(string: string, attrs: self.attrs, marked: true)
|
||||
self.position.column += 1
|
||||
self.cells[self.putPosition.row][self.putPosition.column] = Cell(string: string, attrs: self.attrs, marked: true)
|
||||
self.putPosition.column += 1
|
||||
}
|
||||
|
||||
func unmarkCell(position: Position) {
|
||||
@ -200,13 +205,17 @@ class Grid: CustomStringConvertible {
|
||||
}
|
||||
|
||||
func isPreviousCellEmpty(position: Position) -> Bool {
|
||||
return self.isCellEmpty(Position(row: position.row, column: max(position.column - 1, 0)))
|
||||
return self.isCellEmpty(self.previousCellPosition(position))
|
||||
}
|
||||
|
||||
func isNextCellEmpty(position: Position) -> Bool {
|
||||
return self.isCellEmpty(Position(row: position.row, column: min(position.column + 1, self.size.width - 1)))
|
||||
return self.isCellEmpty(self.nextCellPosition(position))
|
||||
}
|
||||
|
||||
func previousCellPosition(position: Position) -> Position {
|
||||
return Position(row: position.row, column: max(position.column - 1, 0))
|
||||
}
|
||||
|
||||
func nextCellPosition(position: Position) -> Position {
|
||||
return Position(row: position.row, column: min(position.column + 1, self.size.width - 1))
|
||||
}
|
||||
|
@ -21,6 +21,11 @@ typedef struct {
|
||||
unsigned int special;
|
||||
} CellAttributes;
|
||||
|
||||
typedef struct {
|
||||
NSInteger row;
|
||||
NSInteger column;
|
||||
} Position;
|
||||
|
||||
#define qDefaultForeground 0xFF000000
|
||||
#define qDefaultBackground 0xFFFFFFFF
|
||||
#define qDefaultSpecial 0xFFFF0000
|
||||
@ -49,7 +54,7 @@ typedef struct {
|
||||
* 2. NeoVim wants to put the cursor at (row, column).
|
||||
* In case of 1. NeoVim will put in subsequent call. In case of 2. NeoVim seems to flush twice in a row.
|
||||
*/
|
||||
- (void)cursorGotoRow:(int)row column:(int)column;
|
||||
- (void)gotoPosition:(Position)position screenCursor:(Position)screenCursor bufferCursor:(Position)bufferCursor;
|
||||
|
||||
- (void)updateMenu;
|
||||
- (void)busyStart;
|
||||
|
@ -118,14 +118,15 @@ public class NeoVimView: NSView {
|
||||
|
||||
self.rowRunIntersecting(rects: dirtyRects).forEach { rowFrag in
|
||||
// For background drawing we don't filter out the put(0, 0)s: in some cases only the put(0, 0)-cells should be
|
||||
// redrawn.
|
||||
self.drawBackground(positions: rowFrag.range.map { self.positionOnView(rowFrag.row, column: $0) },
|
||||
// redrawn. => FIXME: probably we have to consider this also when drawing further down, ie when the range starts
|
||||
// with '0'...
|
||||
self.drawBackground(positions: rowFrag.range.map { self.pointInView(rowFrag.row, column: $0) },
|
||||
background: rowFrag.attrs.background)
|
||||
|
||||
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 }
|
||||
.map { self.positionOnView(rowFrag.row, column: $0) }
|
||||
.map { self.pointInView(rowFrag.row, column: $0) }
|
||||
|
||||
if positions.isEmpty {
|
||||
return
|
||||
@ -144,7 +145,7 @@ public class NeoVimView: NSView {
|
||||
|
||||
private func drawCursor(background: UInt32) {
|
||||
// FIXME: for now do some rudimentary cursor drawing
|
||||
let cursorPosition = self.grid.position
|
||||
let cursorPosition = self.grid.screenCursor
|
||||
// Swift.print("\(#function): \(cursorPosition)")
|
||||
|
||||
var cursorRect = self.cellRect(row: cursorPosition.row, column: cursorPosition.column)
|
||||
@ -153,7 +154,8 @@ public class NeoVimView: NSView {
|
||||
cursorRect = cursorRect.union(self.cellRect(row: nextPosition.row, column:nextPosition.column))
|
||||
}
|
||||
|
||||
ColorUtils.colorFromCodeIgnoringAlpha(background).set()
|
||||
// set cursor to an abhorrent color for debugging
|
||||
ColorUtils.colorFromCodeIgnoringAlpha(0xFF990000).set()
|
||||
NSRectFillUsingOperation(cursorRect, .CompositeDifference)
|
||||
}
|
||||
|
||||
@ -203,16 +205,24 @@ public class NeoVimView: NSView {
|
||||
} // All RowRuns for all Regions grouped by Region.
|
||||
.flatMap { $0 } // Flattened RowRuns for all Regions.
|
||||
}
|
||||
|
||||
func pointInView(position: Position) -> CGPoint {
|
||||
return self.pointInView(position.row, column: position.column)
|
||||
}
|
||||
|
||||
func positionOnView(row: Int, column: Int) -> CGPoint {
|
||||
func pointInView(row: Int, column: Int) -> CGPoint {
|
||||
return CGPoint(
|
||||
x: CGFloat(column) * self.cellSize.width,
|
||||
y: self.frame.size.height - CGFloat(row) * self.cellSize.height - self.cellSize.height
|
||||
)
|
||||
}
|
||||
|
||||
func cellRect(position: Position) -> CGRect {
|
||||
return self.cellRect(row: position.row, column: position.column)
|
||||
}
|
||||
|
||||
func cellRect(row row: Int, column: Int) -> CGRect {
|
||||
return CGRect(origin: self.positionOnView(row, column: column), size: self.cellSize)
|
||||
return CGRect(origin: self.pointInView(row, column: column), size: self.cellSize)
|
||||
}
|
||||
|
||||
func regionRect(region: Region) -> CGRect {
|
||||
|
@ -34,7 +34,7 @@ extension NeoVimView: NSTextInputClient {
|
||||
}
|
||||
|
||||
public func insertText(aString: AnyObject, replacementRange: NSRange) {
|
||||
NSLog("\(#function): \(replacementRange): \(aString)")
|
||||
NSLog("\(#function): \(replacementRange): '\(aString)'")
|
||||
|
||||
switch aString {
|
||||
case let string as String:
|
||||
@ -49,14 +49,14 @@ extension NeoVimView: NSTextInputClient {
|
||||
self.markedText = nil
|
||||
self.markedPosition = Position.null
|
||||
// TODO: necessary?
|
||||
self.setNeedsDisplayInRect(self.cellRect(row: self.grid.position.row, column: self.grid.position.column))
|
||||
self.setNeedsDisplayInRect(self.cellRect(row: self.grid.putPosition.row, column: self.grid.putPosition.column))
|
||||
self.keyDownDone = true
|
||||
}
|
||||
|
||||
public override func doCommandBySelector(aSelector: Selector) {
|
||||
// NSLog("\(#function): "\(aSelector)")
|
||||
|
||||
// TODO: handle when ㅎ -> delete
|
||||
// FIXME: handle when ㅎ -> delete
|
||||
|
||||
if self.respondsToSelector(aSelector) {
|
||||
Swift.print("\(#function): calling \(aSelector)")
|
||||
@ -72,7 +72,7 @@ extension NeoVimView: NSTextInputClient {
|
||||
public func setMarkedText(aString: AnyObject, selectedRange: NSRange, replacementRange: NSRange) {
|
||||
|
||||
if self.markedText == nil {
|
||||
self.markedPosition = self.grid.position
|
||||
self.markedPosition = self.grid.putPosition
|
||||
}
|
||||
|
||||
switch aString {
|
||||
@ -95,7 +95,7 @@ extension NeoVimView: NSTextInputClient {
|
||||
self.markedText = nil
|
||||
self.markedPosition = Position.null
|
||||
// TODO: necessary?
|
||||
self.setNeedsDisplayInRect(self.cellRect(row: self.grid.position.row, column: self.grid.position.column))
|
||||
self.setNeedsDisplayInRect(self.cellRect(row: self.grid.putPosition.row, column: self.grid.putPosition.column))
|
||||
self.keyDownDone = true
|
||||
}
|
||||
|
||||
@ -110,19 +110,19 @@ extension NeoVimView: NSTextInputClient {
|
||||
// }
|
||||
|
||||
// FIXME: do we have to handle positions at the column borders?
|
||||
if self.grid.isPreviousCellEmpty(self.grid.position) {
|
||||
if self.grid.isPreviousCellEmpty(self.grid.putPosition) {
|
||||
let result = NSRange(
|
||||
location: self.grid.singleIndexFrom(
|
||||
Position(row: self.grid.position.row, column: self.grid.position.column - 1)
|
||||
Position(row: self.grid.putPosition.row, column: self.grid.putPosition.column - 1)
|
||||
),
|
||||
length: 0
|
||||
)
|
||||
NSLog("\(#function): \(result)")
|
||||
// NSLog("\(#function): \(result)")
|
||||
return result
|
||||
}
|
||||
|
||||
let result = NSRange(location: self.grid.singleIndexFrom(self.grid.position), length: 0)
|
||||
NSLog("\(#function): \(result)")
|
||||
let result = NSRange(location: self.grid.singleIndexFrom(self.grid.putPosition), length: 0)
|
||||
// NSLog("\(#function): \(result)")
|
||||
return result
|
||||
}
|
||||
|
||||
@ -131,11 +131,11 @@ extension NeoVimView: NSTextInputClient {
|
||||
if let markedText = self.markedText {
|
||||
let result = NSRange(location: self.grid.singleIndexFrom(self.markedPosition),
|
||||
length: markedText.characters.count)
|
||||
NSLog("\(#function): \(result)")
|
||||
// NSLog("\(#function): \(result)")
|
||||
return result
|
||||
}
|
||||
|
||||
NSLog("\(#function): returning empty range")
|
||||
// NSLog("\(#function): returning empty range")
|
||||
return NSRange(location: NSNotFound, length: 0)
|
||||
}
|
||||
|
||||
@ -168,36 +168,29 @@ extension NeoVimView: NSTextInputClient {
|
||||
$0 + $1.string
|
||||
}
|
||||
actualRange[0].length = string.characters.count
|
||||
NSLog("\(#function): \(aRange), \(actualRange[0]): \(string)")
|
||||
// NSLog("\(#function): \(aRange), \(actualRange[0]): \(string)")
|
||||
return NSAttributedString(string: string)
|
||||
}
|
||||
|
||||
// TODO: maybe make Grid a Indexable or similar
|
||||
// FIXME: maybe make Grid a Indexable or similar
|
||||
var string = ""
|
||||
for i in location...(location + length) {
|
||||
string += self.grid.cellForSingleIndex(i).string
|
||||
}
|
||||
NSLog("\(#function): \(aRange), \(actualRange[0]): \(string)")
|
||||
// NSLog("\(#function): \(aRange), \(actualRange[0]): \(string)")
|
||||
return NSAttributedString(string: string)
|
||||
}
|
||||
|
||||
public func validAttributesForMarkedText() -> [String] {
|
||||
// Swift.print("\(#function): ")
|
||||
return []
|
||||
}
|
||||
|
||||
public func firstRectForCharacterRange(aRange: NSRange, actualRange: NSRangePointer) -> NSRect {
|
||||
NSLog("\(#function): \(aRange), \(actualRange[0])")
|
||||
if actualRange != nil {
|
||||
Swift.print("\(#function): \(aRange), \(actualRange[0])")
|
||||
} else {
|
||||
Swift.print("\(#function): \(aRange), nil")
|
||||
}
|
||||
let position = self.grid.positionFromSingleIndex(aRange.location)
|
||||
|
||||
NSLog("\(#function): \(aRange),\(actualRange[0]) -> \(position.row):\(position.column)")
|
||||
|
||||
let row = Int(floor(Double(aRange.location / self.grid.size.width)))
|
||||
let column = aRange.location - row * self.grid.size.width
|
||||
|
||||
let resultInSelf = self.cellRect(row: row, column: column)
|
||||
let resultInSelf = self.cellRect(row: position.row, column: position.column)
|
||||
let result = self.window?.convertRectToScreen(self.convertRect(resultInSelf, toView: nil))
|
||||
|
||||
return result!
|
||||
@ -229,95 +222,95 @@ extension NeoVimView: NSTextInputClient {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/*
|
||||
public func moveWordForward(sender: AnyObject?)
|
||||
public func moveWordBackward(sender: AnyObject?)
|
||||
public func moveToBeginningOfLine(sender: AnyObject?)
|
||||
public func moveToEndOfLine(sender: AnyObject?)
|
||||
public func moveToBeginningOfParagraph(sender: AnyObject?)
|
||||
public func moveToEndOfParagraph(sender: AnyObject?)
|
||||
public func moveToEndOfDocument(sender: AnyObject?)
|
||||
public func moveToBeginningOfDocument(sender: AnyObject?)
|
||||
public func pageDown(sender: AnyObject?)
|
||||
public func pageUp(sender: AnyObject?)
|
||||
public func centerSelectionInVisibleArea(sender: AnyObject?)
|
||||
|
||||
public func moveBackwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveForwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordForwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordBackwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveUpAndModifySelection(sender: AnyObject?)
|
||||
public func moveDownAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func moveToBeginningOfLineAndModifySelection(sender: AnyObject?)
|
||||
public func moveToEndOfLineAndModifySelection(sender: AnyObject?)
|
||||
public func moveToBeginningOfParagraphAndModifySelection(sender: AnyObject?)
|
||||
public func moveToEndOfParagraphAndModifySelection(sender: AnyObject?)
|
||||
public func moveToEndOfDocumentAndModifySelection(sender: AnyObject?)
|
||||
public func moveToBeginningOfDocumentAndModifySelection(sender: AnyObject?)
|
||||
public func pageDownAndModifySelection(sender: AnyObject?)
|
||||
public func pageUpAndModifySelection(sender: AnyObject?)
|
||||
public func moveParagraphForwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveParagraphBackwardAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func moveWordRight(sender: AnyObject?)
|
||||
public func moveWordLeft(sender: AnyObject?)
|
||||
public func moveRightAndModifySelection(sender: AnyObject?)
|
||||
public func moveLeftAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordRightAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordLeftAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func moveToLeftEndOfLine(sender: AnyObject?)
|
||||
public func moveToRightEndOfLine(sender: AnyObject?)
|
||||
public func moveToLeftEndOfLineAndModifySelection(sender: AnyObject?)
|
||||
public func moveToRightEndOfLineAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func scrollLineUp(sender: AnyObject?)
|
||||
public func scrollLineDown(sender: AnyObject?)
|
||||
|
||||
public func transpose(sender: AnyObject?)
|
||||
public func transposeWords(sender: AnyObject?)
|
||||
|
||||
public func selectAll(sender: AnyObject?)
|
||||
public func selectParagraph(sender: AnyObject?)
|
||||
public func selectLine(sender: AnyObject?)
|
||||
public func selectWord(sender: AnyObject?)
|
||||
|
||||
public func indent(sender: AnyObject?)
|
||||
public func insertTab(sender: AnyObject?)
|
||||
public func insertBacktab(sender: AnyObject?)
|
||||
public func insertNewline(sender: AnyObject?)
|
||||
public func insertParagraphSeparator(sender: AnyObject?)
|
||||
public func insertNewlineIgnoringFieldEditor(sender: AnyObject?)
|
||||
public func insertTabIgnoringFieldEditor(sender: AnyObject?)
|
||||
public func insertLineBreak(sender: AnyObject?)
|
||||
public func insertContainerBreak(sender: AnyObject?)
|
||||
public func insertSingleQuoteIgnoringSubstitution(sender: AnyObject?)
|
||||
public func insertDoubleQuoteIgnoringSubstitution(sender: AnyObject?)
|
||||
|
||||
public func changeCaseOfLetter(sender: AnyObject?)
|
||||
public func uppercaseWord(sender: AnyObject?)
|
||||
public func lowercaseWord(sender: AnyObject?)
|
||||
public func capitalizeWord(sender: AnyObject?)
|
||||
|
||||
public func deleteBackwardByDecomposingPreviousCharacter(sender: AnyObject?)
|
||||
public func deleteWordForward(sender: AnyObject?)
|
||||
public func deleteWordBackward(sender: AnyObject?)
|
||||
public func deleteToBeginningOfLine(sender: AnyObject?)
|
||||
public func deleteToEndOfLine(sender: AnyObject?)
|
||||
public func deleteToBeginningOfParagraph(sender: AnyObject?)
|
||||
public func deleteToEndOfParagraph(sender: AnyObject?)
|
||||
|
||||
public func yank(sender: AnyObject?)
|
||||
|
||||
public func complete(sender: AnyObject?)
|
||||
|
||||
public func setMark(sender: AnyObject?)
|
||||
public func deleteToMark(sender: AnyObject?)
|
||||
public func selectToMark(sender: AnyObject?)
|
||||
public func swapWithMark(sender: AnyObject?)
|
||||
|
||||
public func cancelOperation(sender: AnyObject?)
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
public func moveWordForward(sender: AnyObject?)
|
||||
public func moveWordBackward(sender: AnyObject?)
|
||||
public func moveToBeginningOfLine(sender: AnyObject?)
|
||||
public func moveToEndOfLine(sender: AnyObject?)
|
||||
public func moveToBeginningOfParagraph(sender: AnyObject?)
|
||||
public func moveToEndOfParagraph(sender: AnyObject?)
|
||||
public func moveToEndOfDocument(sender: AnyObject?)
|
||||
public func moveToBeginningOfDocument(sender: AnyObject?)
|
||||
public func pageDown(sender: AnyObject?)
|
||||
public func pageUp(sender: AnyObject?)
|
||||
public func centerSelectionInVisibleArea(sender: AnyObject?)
|
||||
|
||||
public func moveBackwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveForwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordForwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordBackwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveUpAndModifySelection(sender: AnyObject?)
|
||||
public func moveDownAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func moveToBeginningOfLineAndModifySelection(sender: AnyObject?)
|
||||
public func moveToEndOfLineAndModifySelection(sender: AnyObject?)
|
||||
public func moveToBeginningOfParagraphAndModifySelection(sender: AnyObject?)
|
||||
public func moveToEndOfParagraphAndModifySelection(sender: AnyObject?)
|
||||
public func moveToEndOfDocumentAndModifySelection(sender: AnyObject?)
|
||||
public func moveToBeginningOfDocumentAndModifySelection(sender: AnyObject?)
|
||||
public func pageDownAndModifySelection(sender: AnyObject?)
|
||||
public func pageUpAndModifySelection(sender: AnyObject?)
|
||||
public func moveParagraphForwardAndModifySelection(sender: AnyObject?)
|
||||
public func moveParagraphBackwardAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func moveWordRight(sender: AnyObject?)
|
||||
public func moveWordLeft(sender: AnyObject?)
|
||||
public func moveRightAndModifySelection(sender: AnyObject?)
|
||||
public func moveLeftAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordRightAndModifySelection(sender: AnyObject?)
|
||||
public func moveWordLeftAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func moveToLeftEndOfLine(sender: AnyObject?)
|
||||
public func moveToRightEndOfLine(sender: AnyObject?)
|
||||
public func moveToLeftEndOfLineAndModifySelection(sender: AnyObject?)
|
||||
public func moveToRightEndOfLineAndModifySelection(sender: AnyObject?)
|
||||
|
||||
public func scrollLineUp(sender: AnyObject?)
|
||||
public func scrollLineDown(sender: AnyObject?)
|
||||
|
||||
public func transpose(sender: AnyObject?)
|
||||
public func transposeWords(sender: AnyObject?)
|
||||
|
||||
public func selectAll(sender: AnyObject?)
|
||||
public func selectParagraph(sender: AnyObject?)
|
||||
public func selectLine(sender: AnyObject?)
|
||||
public func selectWord(sender: AnyObject?)
|
||||
|
||||
public func indent(sender: AnyObject?)
|
||||
public func insertTab(sender: AnyObject?)
|
||||
public func insertBacktab(sender: AnyObject?)
|
||||
public func insertNewline(sender: AnyObject?)
|
||||
public func insertParagraphSeparator(sender: AnyObject?)
|
||||
public func insertNewlineIgnoringFieldEditor(sender: AnyObject?)
|
||||
public func insertTabIgnoringFieldEditor(sender: AnyObject?)
|
||||
public func insertLineBreak(sender: AnyObject?)
|
||||
public func insertContainerBreak(sender: AnyObject?)
|
||||
public func insertSingleQuoteIgnoringSubstitution(sender: AnyObject?)
|
||||
public func insertDoubleQuoteIgnoringSubstitution(sender: AnyObject?)
|
||||
|
||||
public func changeCaseOfLetter(sender: AnyObject?)
|
||||
public func uppercaseWord(sender: AnyObject?)
|
||||
public func lowercaseWord(sender: AnyObject?)
|
||||
public func capitalizeWord(sender: AnyObject?)
|
||||
|
||||
public func deleteBackwardByDecomposingPreviousCharacter(sender: AnyObject?)
|
||||
public func deleteWordForward(sender: AnyObject?)
|
||||
public func deleteWordBackward(sender: AnyObject?)
|
||||
public func deleteToBeginningOfLine(sender: AnyObject?)
|
||||
public func deleteToEndOfLine(sender: AnyObject?)
|
||||
public func deleteToBeginningOfParagraph(sender: AnyObject?)
|
||||
public func deleteToEndOfParagraph(sender: AnyObject?)
|
||||
|
||||
public func yank(sender: AnyObject?)
|
||||
|
||||
public func complete(sender: AnyObject?)
|
||||
|
||||
public func setMark(sender: AnyObject?)
|
||||
public func deleteToMark(sender: AnyObject?)
|
||||
public func selectToMark(sender: AnyObject?)
|
||||
public func swapWithMark(sender: AnyObject?)
|
||||
|
||||
public func cancelOperation(sender: AnyObject?)
|
||||
*/
|
||||
|
@ -17,6 +17,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
// Swift.print("### resize to \(width):\(height)")
|
||||
self.grid.resize(Size(width: Int(width), height: Int(height)))
|
||||
self.delegate?.resizeToSize(rectSize)
|
||||
// TODO: set needs display?
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,9 +34,9 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
// Swift.print("### eol clear")
|
||||
self.grid.eolClear()
|
||||
|
||||
let origin = self.positionOnView(self.grid.position.row, column: self.grid.position.column)
|
||||
let origin = self.pointInView(self.grid.putPosition)
|
||||
let size = CGSize(
|
||||
width: CGFloat(self.grid.region.right - self.grid.position.column + 1) * self.cellSize.width,
|
||||
width: CGFloat(self.grid.region.right - self.grid.putPosition.column + 1) * self.cellSize.width,
|
||||
height: self.cellSize.height
|
||||
)
|
||||
let rect = CGRect(origin: origin, size: size)
|
||||
@ -43,12 +44,15 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
public func cursorGotoRow(row: Int32, column: Int32) {
|
||||
public func gotoPosition(position: Position, screenCursor: Position, bufferCursor: Position) {
|
||||
DispatchUtils.gui {
|
||||
NSLog("\(#function): \(row):\(column)")
|
||||
self.setCursorNeedsDisplay(self.grid.position)
|
||||
self.grid.goto(Position(row: Int(row), column: Int(column)))
|
||||
self.setCursorNeedsDisplay(self.grid.position)
|
||||
// NSLog("\(#function): \(position), \(screenCursor), \(bufferCursor)")
|
||||
|
||||
self.setNeedsDisplay(cellPosition: self.grid.screenCursor) // redraw where the cursor was till now
|
||||
self.setNeedsDisplay(screenCursor: screenCursor) // draw the new cursor
|
||||
|
||||
self.grid.goto(position)
|
||||
self.grid.moveCursor(screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +85,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
DispatchUtils.gui {
|
||||
let region = Region(top: Int(top), bottom: Int(bottom), left: Int(left), right: Int(right))
|
||||
self.grid.setScrollRegion(region)
|
||||
self.setNeedsDisplayInRect(self.regionRect(region))
|
||||
self.setNeedsDisplay(region: region)
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +94,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
|
||||
DispatchUtils.gui {
|
||||
self.grid.scroll(Int(count))
|
||||
self.setNeedsDisplayInRect(self.regionRect(self.grid.region))
|
||||
self.setNeedsDisplay(region: self.grid.region)
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,30 +107,26 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
|
||||
public func put(string: String) {
|
||||
DispatchUtils.gui {
|
||||
// Swift.print("\(#function): \(string)")
|
||||
let curPos = Position(row: self.grid.position.row, column: self.grid.position.column)
|
||||
// Swift.print("\(#function): \(curPos) -> \(string)")
|
||||
let curPos = self.grid.putPosition
|
||||
// NSLog("\(#function): \(curPos) -> \(string)")
|
||||
self.grid.put(string)
|
||||
|
||||
self.setNeedsDisplayAt(position: curPos)
|
||||
if string.characters.count == 0 {
|
||||
self.setNeedsDisplayAt(row: curPos.row, column: max(curPos.column - 1, 0))
|
||||
}
|
||||
self.setCursorNeedsDisplay(self.grid.position)
|
||||
self.setNeedsDisplay(cellPosition: curPos)
|
||||
|
||||
self.setNeedsDisplay(screenCursor: self.grid.screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
public func putMarkedText(markedText: String) {
|
||||
DispatchUtils.gui {
|
||||
// Swift.print("\(#function): \(markedText)")
|
||||
let curPos = Position(row: self.grid.position.row, column: self.grid.position.column)
|
||||
let curPos = self.grid.putPosition
|
||||
self.grid.putMarkedText(markedText)
|
||||
|
||||
self.setNeedsDisplayAt(position: curPos)
|
||||
self.setNeedsDisplay(position: curPos)
|
||||
if markedText.characters.count == 0 {
|
||||
self.setNeedsDisplayAt(row: curPos.row, column: max(curPos.column - 1, 0))
|
||||
self.setNeedsDisplay(position: self.grid.previousCellPosition(curPos))
|
||||
}
|
||||
self.setCursorNeedsDisplay(self.grid.position)
|
||||
self.setNeedsDisplay(screenCursor: self.grid.screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,8 +134,8 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
DispatchUtils.gui {
|
||||
// Swift.print("\(#function): \(row):\(column)")
|
||||
self.grid.unmarkCell(Position(row: Int(row), column: Int(column)))
|
||||
self.setNeedsDisplayAt(row: Int(row), column: Int(column))
|
||||
self.setCursorNeedsDisplay(self.grid.position)
|
||||
self.setNeedsDisplay(row: Int(row), column: Int(column))
|
||||
self.setNeedsDisplay(screenCursor: self.grid.screenCursor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,20 +191,36 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
public func stop() {
|
||||
// Swift.print("### stop")
|
||||
}
|
||||
|
||||
private func setNeedsDisplayAt(position position: Position) {
|
||||
self.setNeedsDisplayAt(row: position.row, column: position.column)
|
||||
|
||||
private func setNeedsDisplay(region region: Region) {
|
||||
self.setNeedsDisplayInRect(self.regionRect(region))
|
||||
}
|
||||
|
||||
private func setNeedsDisplay(cellPosition position: Position) {
|
||||
self.setNeedsDisplay(position: position)
|
||||
|
||||
if self.grid.isCellEmpty(position) {
|
||||
self.setNeedsDisplay(position: self.grid.previousCellPosition(position))
|
||||
}
|
||||
|
||||
if self.grid.isNextCellEmpty(position) {
|
||||
self.setNeedsDisplay(position: self.grid.nextCellPosition(position))
|
||||
}
|
||||
}
|
||||
|
||||
private func setNeedsDisplayAt(row row: Int, column: Int) {
|
||||
private func setNeedsDisplay(position position: Position) {
|
||||
self.setNeedsDisplay(row: position.row, column: position.column)
|
||||
}
|
||||
|
||||
private func setNeedsDisplay(row row: Int, column: Int) {
|
||||
// Swift.print("\(#function): \(row):\(column)")
|
||||
self.setNeedsDisplayInRect(self.cellRect(row: row, column: column))
|
||||
}
|
||||
|
||||
private func setCursorNeedsDisplay(position: Position) {
|
||||
self.setNeedsDisplayAt(position: position)
|
||||
private func setNeedsDisplay(screenCursor position: Position) {
|
||||
self.setNeedsDisplay(position: position)
|
||||
if self.grid.isNextCellEmpty(position) {
|
||||
self.setNeedsDisplayAt(position: self.grid.nextCellPosition(position))
|
||||
self.setNeedsDisplay(position: self.grid.nextCellPosition(position))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NeoVimViewDelegate {
|
||||
var neoVim: NeoVim!
|
||||
|
||||
@IBAction func debugSomething(sender: AnyObject!) {
|
||||
self.neoVim.view.debugInfo()
|
||||
self.neoVim.xpc.debug1()
|
||||
}
|
||||
|
||||
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
||||
|
@ -670,15 +670,15 @@
|
||||
<window title="nvox" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
|
||||
<rect key="contentRect" x="335" y="390" width="363" height="251"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="363" height="251"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZFX-rs-9SG">
|
||||
<rect key="frame" x="14" y="312" width="81" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0RU-xD-r4y">
|
||||
<rect key="frame" x="14" y="203" width="80" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Debug" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0RU-xD-r4y">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
@ -688,7 +688,7 @@
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="179" y="272"/>
|
||||
<point key="canvasLocation" x="274.5" y="441.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
||||
|
Loading…
Reference in New Issue
Block a user