2008年1月11日金曜日

(続) MacVim インラインパッチ

ポップアップがどうにも耐えれなかったので,仕方なく自分でハック.結構時間を食ってしまった...
ついでに,IMオンの状態で画面にゴミが見えるbugもfix.

今のところ快適でいい感じ.やっと本業に戻れる.
時間を見つけてブラッシュアップして,本家にフィードバックしようかな.
ちなみに,コードと睨めっこしてたら,9日に書いたパッチはいまいちなことが発覚...orz


diff -u src.orig/MacVim/MMTextView.h src/MacVim/MMTextView.h
--- src.orig/MacVim/MMTextView.h 2008-01-11 15:53:57.000000000 +0900
+++ src/MacVim/MMTextView.h 2008-01-11 18:24:17.000000000 +0900
@@ -25,7 +25,9 @@
int insertionPointColumn;
int insertionPointShape;
int insertionPointFraction;
- NSTextField *markedTextField;
+ NSDictionary *markedTextAttributes;
+ NSAttributedString *markedText;
+ NSRange imRange;
int preEditRow;
int preEditColumn;
}
@@ -35,6 +37,5 @@
- (void)setPreEditRow:(int)row column:(int)col;
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
fraction:(int)percent color:(NSColor *)color;
-- (void)hideMarkedTextField;

@end
diff -u src.orig/MacVim/MMTextView.m src/MacVim/MMTextView.m
--- src.orig/MacVim/MMTextView.m 2008-01-11 15:53:57.000000000 +0900
+++ src/MacVim/MMTextView.m 2008-01-12 02:11:38.000000000 +0900
@@ -54,10 +54,10 @@

- (void)dealloc
{
- if (markedTextField) {
- [[markedTextField window] autorelease];
- [markedTextField release];
- markedTextField = nil;
+ if (markedText) {
+ imRange = NSMakeRange(0, 0);
+ [markedText release];
+ markedText = nil;
}

[lastMouseDownEvent release];
@@ -106,15 +106,6 @@
[self setInsertionPointColor:color];
}

-- (void)hideMarkedTextField
-{
- if (markedTextField) {
- NSWindow *win = [markedTextField window];
- [win close];
- [markedTextField setStringValue:@""];
- }
-}
-
- (BOOL)isOpaque
{
return NO;
@@ -156,6 +147,19 @@
// NSStringFromRect(ipRect), insertionPointShape,
// [self insertionPointColor]);
}
+
+ if ( [self hasMarkedText] ) {
+ int len = [markedText length];
+ MMTextStorage *ts = (MMTextStorage*)[self textStorage];
+ int wfrac = ([ts cellSize].width* insertionPointFraction + 99)/100 + 1;
+ int hfrac = ([ts cellSize].height* insertionPointFraction + 99)/100 + 1;
+
+ [markedText drawInRect:NSMakeRect(
+ insertionPointColumn*[ts cellSize].width+wfrac,
+ insertionPointRow*[ts cellSize].height,
+ [ts cellSize].width*2*len, [ts cellSize].height+hfrac)];
+ }
+
#if 0
// this code invalidates the shadow, so we don't
// get shifting ghost text on scroll and resize
@@ -183,6 +187,17 @@
//
// TODO: Figure out a way to disable Cocoa key bindings entirely, without
// affecting input management.
+ [NSCursor setHiddenUntilMouseMoves: YES];
+ if ([self hasMarkedText]) {
+ NSString *unmod = [event charactersIgnoringModifiers];
+ if (([markedText length] == 1 && [unmod characterAtIndex:0] == 0x7f)
+ || [unmod characterAtIndex:0] == 0x1b || [unmod characterAtIndex:0] == 0x0d) {
+ [self unmarkText];
+ }
+ [super keyDown:event];
+ [self setNeedsDisplay: YES];
+ return;
+ }
if ([event modifierFlags] & NSControlKeyMask) {
NSString *unmod = [event charactersIgnoringModifiers];
if ([unmod length] == 1 && [unmod characterAtIndex:0] <= 0x7f
@@ -211,7 +226,9 @@
// modifiers are already included and should not be added to the input
// buffer using CSI, K_MODIFIER).

- [self hideMarkedTextField];
+ if([self hasMarkedText]) {
+ [self unmarkText];
+ }

NSEvent *event = [NSApp currentEvent];

@@ -360,14 +377,12 @@
- (BOOL)hasMarkedText
{
//NSLog(@"%s", _cmd);
- return markedTextField && [[markedTextField stringValue] length] > 0;
+ return markedText && [markedText length] > 0;
}

-- (NSRange)markedRange
+- (NSRange)selectedRange
{
- //NSLog(@"%s", _cmd);
- unsigned len = [[markedTextField stringValue] length];
- return NSMakeRange(len > 0 ? 0 : NSNotFound, len);
+ return NSMakeRange(NSNotFound, 0);
}

- (void)setMarkedText:(id)text selectedRange:(NSRange)range
@@ -375,64 +390,32 @@
//NSLog(@"setMarkedText:'%@' selectedRange:%@", text,
// NSStringFromRange(range));

- MMTextStorage *ts = (MMTextStorage*)[self textStorage];
- if (!ts) return;
-
- if (!markedTextField) {
- // Create a text field and put it inside a floating panel. This field
- // is used to display marked text.
- NSSize cellSize = [ts cellSize];
- NSRect cellRect = { 0, 0, cellSize.width, cellSize.height };
-
- markedTextField = [[NSTextField alloc] initWithFrame:cellRect];
- [markedTextField setEditable:NO];
- [markedTextField setSelectable:NO];
- [markedTextField setBezeled:NO];
- [markedTextField setBordered:YES];
-
- NSPanel *panel = [[NSPanel alloc]
- initWithContentRect:cellRect
- styleMask:NSBorderlessWindowMask|NSUtilityWindowMask
- backing:NSBackingStoreBuffered
- defer:YES];
-
- //[panel setHidesOnDeactivate:NO];
- [panel setFloatingPanel:YES];
- [panel setBecomesKeyOnlyIfNeeded:YES];
- [panel setContentView:markedTextField];
- }
-
+ [self unmarkText];
if (text && [text length] > 0) {
- [markedTextField setFont:[ts font]];
+ MMTextStorage *ts = (MMTextStorage*)[self textStorage];
+ markedTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSColor greenColor], NSBackgroundColorAttributeName,
+ [NSColor blackColor], NSForegroundColorAttributeName,
+ [ts font], NSFontAttributeName,
+ [NSNumber numberWithInt:2],NSUnderlineStyleAttributeName,
+ NULL];
if ([text isKindOfClass:[NSAttributedString class]])
- [markedTextField setAttributedStringValue:text];
+ markedText=[[NSAttributedString alloc] initWithString:[text string]
+ attributes:[self markedTextAttributes]];
else
- [markedTextField setStringValue:text];
-
- [markedTextField sizeToFit];
- NSSize size = [markedTextField frame].size;
-
- // Convert coordinates (row,col) -> view -> window base -> screen
- NSPoint origin;
- if (![self convertRow:preEditRow+1 column:preEditColumn
- toPoint:&origin])
- return;
- origin = [self convertPoint:origin toView:nil];
- origin = [[self window] convertBaseToScreen:origin];
-
- NSWindow *win = [markedTextField window];
- [win setContentSize:size];
- [win setFrameOrigin:origin];
- [win orderFront:nil];
- } else {
- [self hideMarkedTextField];
+ markedText=[[NSAttributedString alloc] initWithString:text
+ attributes:[self markedTextAttributes]];
+ imRange = NSMakeRange(0, [markedText length]);
+ [self setNeedsDisplay: YES];
}
}

- (void)unmarkText
{
//NSLog(@"%s", _cmd);
- [self hideMarkedTextField];
+ imRange = NSMakeRange(0, 0);
+ [markedText release];
+ markedText = nil;
}

- (NSRect)firstRectForCharacterRange:(NSRange)range
diff -u src.orig/MacVim/MMWindowController.m src/MacVim/MMWindowController.m
--- src.orig/MacVim/MMWindowController.m 2008-01-11 15:53:57.000000000 +0900
+++ src/MacVim/MMWindowController.m 2008-01-10 18:56:03.000000000 +0900
@@ -580,9 +580,6 @@
- (void)windowDidResignMain:(NSNotification *)notification
{
[vimController sendMessage:LostFocusMsgID data:nil];
-
- if ([vimView textView])
- [[vimView textView] hideMarkedTextField];
}

- (BOOL)windowShouldClose:(id)sender

0 件のコメント: