Skip to content

Commit ff6516f

Browse files
committed
inline placeholder
1 parent c5f4970 commit ff6516f

2 files changed

Lines changed: 74 additions & 39 deletions

File tree

SquirrelInputController.m

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@
1010
@interface SquirrelInputController(Private)
1111
-(void)createSession;
1212
-(void)destroySession;
13-
-(void)rimeConsumeCommittedText;
13+
-(BOOL)rimeConsumeCommittedText;
1414
-(void)rimeUpdate;
1515
-(void)updateAppOptions;
1616
@end
1717

1818
const int N_KEY_ROLL_OVER = 50;
1919

2020
@implementation SquirrelInputController {
21-
id _currentClient;
22-
NSString *_preeditString;
21+
NSMutableAttributedString *_preeditString;
2322
NSRange _selRange;
2423
NSUInteger _caretPos;
2524
NSArray *_candidates;
@@ -29,6 +28,9 @@ @implementation SquirrelInputController {
2928
NSString *_schemaId;
3029
BOOL _inlinePreedit;
3130
BOOL _inlineCandidate;
31+
// app-specific bug fix
32+
BOOL _inlinePlaceHolder;
33+
BOOL _panellessCommitFix;
3234
// for chord-typing
3335
int _chordKeyCodes[N_KEY_ROLL_OVER];
3436
int _chordModifiers[N_KEY_ROLL_OVER];
@@ -49,9 +51,6 @@ - (BOOL)handleEvent:(NSEvent*)event client:(id)sender
4951
// Key processing will not continue in that case. In other words the
5052
// system will not deliver a key down event to the application.
5153
// Returning NO means the original key down will be passed on to the client.
52-
53-
_currentClient = sender;
54-
5554
NSUInteger modifiers = event.modifierFlags;
5655

5756
BOOL handled = NO;
@@ -64,7 +63,7 @@ - (BOOL)handleEvent:(NSEvent*)event client:(id)sender
6463
}
6564
}
6665

67-
NSString* app = [_currentClient bundleIdentifier];
66+
NSString* app = [sender bundleIdentifier];
6867

6968
if (![_currentApp isEqualToString:app]) {
7069
_currentApp = [app copy];
@@ -319,14 +318,13 @@ -(void)activateServer:(id)sender
319318
if (keyboardLayout) {
320319
[sender overrideKeyboardWithKeyboardNamed:keyboardLayout];
321320
}
322-
_preeditString = @"";
321+
_preeditString = nil;
323322
}
324323

325324
-(instancetype)initWithServer:(IMKServer*)server delegate:(id)delegate client:(id)inputClient
326325
{
327326
//NSLog(@"initWithServer:delegate:client:");
328327
if (self = [super initWithServer:server delegate:delegate client:inputClient]) {
329-
_currentClient = inputClient;
330328
[self createSession];
331329
}
332330
return self;
@@ -335,7 +333,6 @@ -(instancetype)initWithServer:(IMKServer*)server delegate:(id)delegate client:(i
335333
-(void)deactivateServer:(id)sender
336334
{
337335
//NSLog(@"deactivateServer:");
338-
[NSApp.squirrelAppDelegate.panel hide];
339336
[self commitComposition:sender];
340337
}
341338

@@ -402,54 +399,77 @@ -(NSArray*)candidates:(id)sender
402399
return _candidates;
403400
}
404401

405-
-(void)dealloc
402+
- (void)hidePalettes
403+
{
404+
[NSApp.squirrelAppDelegate.panel hide];
405+
}
406+
407+
- (void)dealloc
406408
{
407409
[self destroySession];
408410
}
409411

410-
-(void)commitString:(NSString*)string
412+
- (NSRange)selectionRange
413+
{
414+
return NSMakeRange(_caretPos, 0);
415+
}
416+
417+
- (NSRange)replacementRange
418+
{
419+
return NSMakeRange(NSNotFound, NSNotFound);
420+
}
421+
422+
- (void)commitString:(id)string
411423
{
412424
//NSLog(@"commitString:");
413-
[_currentClient insertText:string
414-
replacementRange:NSMakeRange(NSNotFound, 0)];
425+
[self.client insertText:string
426+
replacementRange:self.replacementRange];
427+
[self hidePalettes];
415428

416-
_preeditString = @"";
429+
_preeditString = nil;
430+
}
417431

418-
[NSApp.squirrelAppDelegate.panel hide];
432+
- (void)updateComposition
433+
{
434+
[self.client setMarkedText:_preeditString
435+
selectionRange:self.selectionRange
436+
replacementRange:self.replacementRange];
419437
}
420438

421439
-(void)showPreeditString:(NSString*)preedit
422440
selRange:(NSRange)range
423441
caretPos:(NSUInteger)pos
424442
{
425443
//NSLog(@"showPreeditString: '%@'", preedit);
426-
427-
if ([_preeditString isEqualToString:preedit] &&
428-
_caretPos == pos && _selRange.location == range.location && _selRange.length == range.length)
444+
if ([preedit isEqualToString:_preeditString.string] &&
445+
NSEqualRanges(range, _selRange) && pos == _caretPos) {
446+
if (_inlinePlaceHolder) {
447+
[self updateComposition];
448+
}
429449
return;
430-
431-
_preeditString = preedit;
450+
}
432451
_selRange = range;
433452
_caretPos = pos;
434453

435454
//NSLog(@"selRange.location = %ld, selRange.length = %ld; caretPos = %ld",
436455
// range.location, range.length, pos);
437-
NSDictionary* attrs;
438-
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:preedit];
456+
NSDictionary *attrs;
457+
_preeditString = [[NSMutableAttributedString alloc] initWithString:preedit];
439458
if (range.location > 0) {
440459
NSRange convertedRange = NSMakeRange(0, range.location);
441460
attrs = [self markForStyle:kTSMHiliteConvertedText atRange:convertedRange];
442-
[attrString setAttributes:attrs range:convertedRange];
461+
[_preeditString addAttributes:attrs range:convertedRange];
443462
}
444-
{
445-
NSRange remainingRange = NSMakeRange(range.location, preedit.length - range.location);
446-
attrs = [self markForStyle:kTSMHiliteSelectedRawText atRange:remainingRange];
447-
[attrString setAttributes:attrs range:remainingRange];
463+
if (range.location < pos) {
464+
attrs = [self markForStyle:kTSMHiliteSelectedConvertedText atRange:range];
465+
[_preeditString addAttributes:attrs range:range];
448466
}
449-
[_currentClient setMarkedText:attrString
450-
selectionRange:NSMakeRange(pos, 0)
451-
replacementRange:NSMakeRange(NSNotFound, 0)];
452-
467+
if (MIN(NSMaxRange(range), pos) < preedit.length) {
468+
NSRange rawRange = NSMakeRange(MIN(NSMaxRange(range), pos), preedit.length - MIN(NSMaxRange(range), pos));
469+
attrs = [self markForStyle:kTSMHiliteSelectedRawText atRange:rawRange];
470+
[_preeditString addAttributes:attrs range:rawRange];
471+
}
472+
[self updateComposition];
453473
}
454474

455475
-(void)showPanelWithPreedit:(NSString*)preedit
@@ -463,7 +483,7 @@ -(void)showPanelWithPreedit:(NSString*)preedit
463483
//NSLog(@"showPanelWithPreedit:...:");
464484
_candidates = candidates;
465485
NSRect inputPos;
466-
[_currentClient attributesForCharacterIndex:0 lineHeightRectangle:&inputPos];
486+
[self.client attributesForCharacterIndex:0 lineHeightRectangle:&inputPos];
467487
SquirrelPanel* panel = NSApp.squirrelAppDelegate.panel;
468488
panel.position = inputPos;
469489
panel.inputController = self;
@@ -485,7 +505,7 @@ @implementation SquirrelInputController(Private)
485505

486506
-(void)createSession
487507
{
488-
NSString* app = [_currentClient bundleIdentifier];
508+
NSString* app = [self.client bundleIdentifier];
489509
NSLog(@"createSession: %@", app);
490510
_currentApp = [app copy];
491511
_session = rime_get_api()->create_session();
@@ -508,6 +528,8 @@ -(void)updateAppOptions
508528
NSLog(@"set app option: %@ = %d", key, value);
509529
rime_get_api()->set_option(_session, key.UTF8String, value);
510530
}
531+
_panellessCommitFix = (appOptions[@"panelless_commit_fix"] ? : @(NO)).boolValue;
532+
_inlinePlaceHolder = (appOptions[@"inline_placeholder"] ? : @(NO)).boolValue;
511533
}
512534
}
513535

@@ -521,15 +543,19 @@ -(void)destroySession
521543
[self clearChord];
522544
}
523545

524-
-(void)rimeConsumeCommittedText
546+
-(BOOL)rimeConsumeCommittedText
525547
{
526548
RIME_STRUCT(RimeCommit, commit);
527549
if (rime_get_api()->get_commit(_session, &commit)) {
528550
NSString *commitText = @(commit.text);
529-
[self showPreeditString:@" " selRange:NSMakeRange(0, 0) caretPos:0];
551+
if (_preeditString.length == 0 && _panellessCommitFix) {
552+
[self showPreeditString:@" " selRange:NSMakeRange(0, 0) caretPos:0];
553+
}
530554
[self commitString:commitText];
531555
rime_get_api()->free_commit(&commit);
556+
return YES;
532557
}
558+
return NO;
533559
}
534560

535561
NSString *substr(const char *str, int length) {
@@ -542,7 +568,9 @@ -(void)rimeConsumeCommittedText
542568
-(void)rimeUpdate
543569
{
544570
//NSLog(@"rimeUpdate");
545-
[self rimeConsumeCommittedText];
571+
if ([self rimeConsumeCommittedText]) {
572+
return;
573+
}
546574

547575
RIME_STRUCT(RimeStatus, status);
548576
if (rime_get_api()->get_status(_session, &status)) {
@@ -592,11 +620,11 @@ -(void)rimeUpdate
592620
if (_inlinePreedit) {
593621
[self showPreeditString:preeditText selRange:selRange caretPos:caretPos];
594622
} else {
595-
NSRange empty = {0, 0};
596623
// TRICKY: display a non-empty string to prevent iTerm2 from echoing each character in preedit.
597624
// note this is a full-shape space U+3000; using half shape characters like "..." will result in
598625
// an unstable baseline when composing Chinese characters.
599-
[self showPreeditString:(preedit ? @" " : @"") selRange:empty caretPos:0];
626+
[self showPreeditString:(preedit && _inlinePlaceHolder ? @" " : @"")
627+
selRange:NSMakeRange(0, 0) caretPos:0];
600628
}
601629
}
602630
// update candidates

data/squirrel.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ app_options:
341341
com.apple.Terminal:
342342
ascii_mode: true
343343
no_inline: true
344+
inline_placeholder: true
344345
com.googlecode.iterm2:
345346
ascii_mode: true
346347
no_inline: true
@@ -350,6 +351,7 @@ app_options:
350351
vim_mode: true # 退出VIM插入模式自動切換輸入法狀態
351352
com.apple.dt.Xcode:
352353
ascii_mode: true
354+
no_inline: true
353355
com.barebones.textwrangler:
354356
ascii_mode: true
355357
com.macromates.TextMate.preview:
@@ -367,9 +369,14 @@ app_options:
367369
no_inline: true
368370
co.zeit.hyper:
369371
ascii_mode: true
372+
org.alacritty:
373+
ascii_mode: true
374+
vim_mode: true
375+
panelless_commit_fix: true
370376
com.google.Chrome:
371377
# 規避 https://github.com/rime/squirrel/issues/435
372378
inline: true
379+
inline_placeholder: true
373380
ru.keepcoder.Telegram:
374381
# 規避 https://github.com/rime/squirrel/issues/475
375382
inline: true

0 commit comments

Comments
 (0)