Skip to content

Commit 3180b52

Browse files
feat: Add composition preview for Korean/CJK IME input
Display a small "조합중: X" indicator in the top-right corner during IME composition. This helps users see what character is being composed before it's finalized. Korean is a compositional writing system where characters are built step-by-step (e.g., ㅅ → 세 → 셰). This visual feedback makes the composition process clearer. Closes hongsw#2 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent f572fa1 commit 3180b52

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

lib/terminal.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export class Terminal implements ITerminalCore {
6969
private inputHandler?: InputHandler;
7070
private selectionManager?: SelectionManager;
7171
private canvas?: HTMLCanvasElement;
72+
private compositionPreview?: HTMLDivElement;
7273

7374
// Link detection system
7475
private linkDetector?: LinkDetector;
@@ -400,6 +401,32 @@ export class Terminal implements ITerminalCore {
400401
this.textarea.style.resize = 'none';
401402
parent.appendChild(this.textarea);
402403

404+
// Create composition preview element for IME input (Korean, Chinese, Japanese)
405+
this.compositionPreview = document.createElement('div');
406+
this.compositionPreview.style.position = 'absolute';
407+
this.compositionPreview.style.top = '4px';
408+
this.compositionPreview.style.right = '4px';
409+
this.compositionPreview.style.padding = '2px 8px';
410+
this.compositionPreview.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
411+
this.compositionPreview.style.color = '#ffcc00';
412+
this.compositionPreview.style.fontFamily = 'monospace';
413+
this.compositionPreview.style.fontSize = '12px';
414+
this.compositionPreview.style.borderRadius = '3px';
415+
this.compositionPreview.style.display = 'none';
416+
this.compositionPreview.style.zIndex = '1000';
417+
parent.appendChild(this.compositionPreview);
418+
419+
// Listen to composition events for preview
420+
this.textarea.addEventListener('compositionupdate', (e: CompositionEvent) => {
421+
if (e.data) {
422+
this.compositionPreview!.textContent = `조합중: ${e.data}`;
423+
this.compositionPreview!.style.display = 'block';
424+
}
425+
});
426+
this.textarea.addEventListener('compositionend', () => {
427+
this.compositionPreview!.style.display = 'none';
428+
});
429+
403430
// Focus textarea on interaction - preventDefault before focus
404431
const textarea = this.textarea;
405432
// Desktop: mousedown
@@ -1201,6 +1228,12 @@ export class Terminal implements ITerminalCore {
12011228
this.textarea = undefined;
12021229
}
12031230

1231+
// Remove composition preview from DOM
1232+
if (this.compositionPreview && this.compositionPreview.parentNode) {
1233+
this.compositionPreview.parentNode.removeChild(this.compositionPreview);
1234+
this.compositionPreview = undefined;
1235+
}
1236+
12041237
// Remove event listeners
12051238
if (this.element) {
12061239
this.element.removeEventListener('wheel', this.handleWheel);

0 commit comments

Comments
 (0)