Skip to content

Commit

Permalink
prevent commit keystroke being hijacked & inline placeholder &fix ter…
Browse files Browse the repository at this point in the history
…minal non-inline
  • Loading branch information
groverlynn committed Feb 6, 2024
1 parent 7de3919 commit 3ed14e7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
85 changes: 54 additions & 31 deletions SquirrelInputController.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ -(void)updateAppOptions;
@end

const int N_KEY_ROLL_OVER = 50;
static NSString *const kFullWidthSpace = @" ";

@implementation SquirrelInputController {
id _currentClient;
NSString *_preeditString;
NSMutableAttributedString *_preeditString;
NSRange _selRange;
NSUInteger _caretPos;
NSArray *_candidates;
Expand All @@ -29,6 +30,9 @@ @implementation SquirrelInputController {
NSString *_schemaId;
BOOL _inlinePreedit;
BOOL _inlineCandidate;
// app-specific bug fix
BOOL _inlinePlaceHolder;
BOOL _panellessCommitFix;
// for chord-typing
int _chordKeyCodes[N_KEY_ROLL_OVER];
int _chordModifiers[N_KEY_ROLL_OVER];
Expand All @@ -49,9 +53,6 @@ - (BOOL)handleEvent:(NSEvent*)event client:(id)sender
// Key processing will not continue in that case. In other words the
// system will not deliver a key down event to the application.
// Returning NO means the original key down will be passed on to the client.

_currentClient = sender;

NSUInteger modifiers = event.modifierFlags;

BOOL handled = NO;
Expand Down Expand Up @@ -196,6 +197,13 @@ -(BOOL)processKey:(int)rime_keycode modifiers:(int)rime_modifiers
rime_get_api()->set_option(_session, "ascii_mode", True);
// NSLog(@"turned Chinese mode off in vim-like editor's command mode");
}

if (_panellessCommitFix && (rime_keycode == XK_Delete ||
(rime_keycode >= XK_Home && rime_keycode <= XK_KP_Delete) ||
(rime_keycode >= XK_BackSpace && rime_keycode <= XK_Escape))) {
[self showPlaceHolder:@""];
return NO;
}
}

// Simulate key-ups for every interesting key-down for chord-typing.
Expand Down Expand Up @@ -319,7 +327,7 @@ -(void)activateServer:(id)sender
if (keyboardLayout) {
[sender overrideKeyboardWithKeyboardNamed:keyboardLayout];
}
_preeditString = @"";
_preeditString = nil;
}

-(instancetype)initWithServer:(IMKServer*)server delegate:(id)delegate client:(id)inputClient
Expand All @@ -335,7 +343,6 @@ -(instancetype)initWithServer:(IMKServer*)server delegate:(id)delegate client:(i
-(void)deactivateServer:(id)sender
{
//NSLog(@"deactivateServer:");
[NSApp.squirrelAppDelegate.panel hide];
[self commitComposition:sender];
}

Expand Down Expand Up @@ -402,54 +409,65 @@ -(NSArray*)candidates:(id)sender
return _candidates;
}

-(void)dealloc
- (void)hidePalettes
{
[NSApp.squirrelAppDelegate.panel hide];
}

- (void)dealloc
{
[self destroySession];
}

-(void)commitString:(NSString*)string
- (void)commitString:(id)string
{
//NSLog(@"commitString:");
[_currentClient insertText:string
replacementRange:NSMakeRange(NSNotFound, 0)];
replacementRange:NSMakeRange(NSNotFound, NSNotFound)];

_preeditString = @"";
_preeditString = nil;
}

[NSApp.squirrelAppDelegate.panel hide];
- (void)showPlaceHolder:(NSString *)placeHolder
{
NSAttributedString *markedText = [[NSAttributedString alloc] initWithString:placeHolder
attributes:@{NSMarkedClauseSegmentAttributeName : @(kTSMHiliteConvertedText)}];
[_currentClient setMarkedText:markedText
selectionRange:NSMakeRange(0, placeHolder.length)
replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
}

-(void)showPreeditString:(NSString*)preedit
selRange:(NSRange)range
caretPos:(NSUInteger)pos
{
//NSLog(@"showPreeditString: '%@'", preedit);

if ([_preeditString isEqualToString:preedit] &&
_caretPos == pos && _selRange.location == range.location && _selRange.length == range.length)
if ([preedit isEqualToString:_preeditString.string] &&
NSEqualRanges(range, _selRange) && pos == _caretPos) {
if (_inlinePlaceHolder) {
[self updateComposition];
}
return;

_preeditString = preedit;
}
_selRange = range;
_caretPos = pos;

//NSLog(@"selRange.location = %ld, selRange.length = %ld; caretPos = %ld",
// range.location, range.length, pos);
NSDictionary* attrs;
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:preedit];
NSDictionary *attrs;
_preeditString = [[NSMutableAttributedString alloc] initWithString:preedit];
if (range.location > 0) {
NSRange convertedRange = NSMakeRange(0, range.location);
attrs = [self markForStyle:kTSMHiliteConvertedText atRange:convertedRange];
[attrString setAttributes:attrs range:convertedRange];
[_preeditString addAttributes:attrs range:convertedRange];
}
{
NSRange remainingRange = NSMakeRange(range.location, preedit.length - range.location);
attrs = [self markForStyle:kTSMHiliteSelectedRawText atRange:remainingRange];
[attrString setAttributes:attrs range:remainingRange];
if (range.location < pos) {
attrs = [self markForStyle:kTSMHiliteSelectedRawText atRange:range];
[_preeditString addAttributes:attrs range:range];
}
[_currentClient setMarkedText:attrString
selectionRange:NSMakeRange(pos, 0)
replacementRange:NSMakeRange(NSNotFound, 0)];

[_currentClient setMarkedText:_preeditString
selectionRange:NSMakeRange(_caretPos, 0)
replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
}

-(void)showPanelWithPreedit:(NSString*)preedit
Expand Down Expand Up @@ -508,6 +526,8 @@ -(void)updateAppOptions
NSLog(@"set app option: %@ = %d", key, value);
rime_get_api()->set_option(_session, key.UTF8String, value);
}
_panellessCommitFix = (appOptions[@"panelless_commit_fix"] ? : @(NO)).boolValue;
_inlinePlaceHolder = (appOptions[@"inline_placeholder"] ? : @(NO)).boolValue;
}
}

Expand All @@ -525,8 +545,11 @@ -(void)rimeConsumeCommittedText
{
RIME_STRUCT(RimeCommit, commit);
if (rime_get_api()->get_commit(_session, &commit)) {
NSString *commitText = @(commit.text);
[self commitString: commitText];
NSString *commitText = commit.text ? @(commit.text) : nil;
if (_panellessCommitFix && self.client.markedRange.length == 0) {
[self showPlaceHolder:commitText];
}
[self commitString:commitText];
rime_get_api()->free_commit(&commit);
}
}
Expand Down Expand Up @@ -591,11 +614,11 @@ -(void)rimeUpdate
if (_inlinePreedit) {
[self showPreeditString:preeditText selRange:selRange caretPos:caretPos];
} else {
NSRange empty = {0, 0};
// TRICKY: display a non-empty string to prevent iTerm2 from echoing each character in preedit.
// note this is a full-shape space U+3000; using half shape characters like "..." will result in
// an unstable baseline when composing Chinese characters.
[self showPreeditString:(preedit ? @" " : @"") selRange:empty caretPos:0];
[self showPreeditString:(preedit && _inlinePlaceHolder ? kFullWidthSpace : @"")
selRange:NSMakeRange(0, 0) caretPos:0];
}
}
// update candidates
Expand Down
7 changes: 7 additions & 0 deletions data/squirrel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ app_options:
com.apple.Terminal:
ascii_mode: true
no_inline: true
inline_placeholder: true
com.googlecode.iterm2:
ascii_mode: true
no_inline: true
Expand All @@ -350,6 +351,7 @@ app_options:
vim_mode: true # 退出VIM插入模式自動切換輸入法狀態
com.apple.dt.Xcode:
ascii_mode: true
no_inline: true
com.barebones.textwrangler:
ascii_mode: true
com.macromates.TextMate.preview:
Expand All @@ -367,9 +369,14 @@ app_options:
no_inline: true
co.zeit.hyper:
ascii_mode: true
org.alacritty:
ascii_mode: true
vim_mode: true
panelless_commit_fix: true
com.google.Chrome:
# 規避 https://github.com/rime/squirrel/issues/435
inline: true
inline_placeholder: true
ru.keepcoder.Telegram:
# 規避 https://github.com/rime/squirrel/issues/475
inline: true

0 comments on commit 3ed14e7

Please sign in to comment.