Repository navigation
IME composition breaks soft-wrap (and can drop jamo) after a Meta Bind widget is rendered #667
Description
Please fill out these Check-boxes
- I checked for existing similar issues
- I checked that the plugin is up to date
- The issue persists with all other plugins and themes disabled
Plugin Version
1.5.0
This Issue Occurs on
- Windows
- Linux
- macOS
- Android
- iOS
Debug Info
SYSTEM INFO:
Obsidian version: 1.13.1
Installer version: 1.10.3
Operating system: Windows 11 Education 10.0.26200
Login status: logged in
Language: ko
Catalyst license: insider
Insider build toggle: off
Live preview: on
Base theme: light
Community theme: Minimal 8.2.1
Snippets enabled: 12
Restricted mode: off
Plugins installed: 31
Plugins enabled: 31
1: Meta Bind v1.5.0
2: Advanced Tables v0.23.2
3: Custom File Explorer sorting v3.1.6
4: Dataview v0.5.68
5: Editing Toolbar v4.0.8
6: Force note view mode v1.2.2
7: Excalidraw v2.23.8
8: Hider v1.6.2
9: Highlightr v1.2.2
10: Homepage v4.4.4
11: Iconize v2.14.7
12: Journals v2.1.10
13: Metadata Menu v0.8.12
14: Minimal Theme Settings v8.2.3
15: Multi State CheckBox Switcher v1.0.4
16: Natural Language Dates Redux v0.8.28
17: Note Toolbar v1.32.15
18: Omnisearch v1.29.3
19: Pocket Bird v2026.5.15
20: Plugin Update Tracker v1.7.0
21: Outliner v4.10.1
22: Quick Explorer v0.2.16
23: QuickAdd v2.12.3
24: Recent Files v1.7.9
25: Style Settings v1.0.9
26: Supercharged Links v0.13.10
27: Tabs v1.1.9
28: Tag Wrangler v0.6.4
29: Tasks v8.0.0
30: Templater v2.20.5
31: Trash Explorer v1.2.4
RECOMMENDATIONS:
Custom theme and snippets: for cosmetic issues, please first try updating your theme and disabling your snippets. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community theme and snippets.
Community plugins: for bugs, please first try updating all your plugins to latest. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community plugins.
Describe the Issue
This bug is specific to Korean (Hangeul(Hangul)) input, so here's a short primer needed to understand it.
Korean is written in syllable blocks, each assembled from smaller letter units called jamo (an initial consonant, a medial vowel, and sometimes a final consonant). For example, 입 ("ip") = ㅇ + ㅣ + ㅂ. All Korean input goes through an IME that assembles syllables in real time, and each syllable stays in a temporary "composing" (pre-edit) state until it is finalized (committed). Normally, composing text is shown with an underline.
The bug appears only after a Meta Bind widget has been rendered in the current session. Concretely: once I open a note containing a Meta Bind button (or any Meta Bind widget), the bug starts and persists even after I close that note. It does not occur in a fresh vault until a Meta Bind widget is rendered at least once; restarting Obsidian with Meta Bind disabled clears it.
Once triggered, IME pre-edit (composing) text is no longer soft-wrapped correctly on list / callout / task lines. Two symptoms follow from this:
- Composing text overflows the editor width, and its display changes. If I keep typing (e.g. repeating ㅇ) past the right edge, the still-composing text runs past the editor boundary instead of wrapping to the next line. In this broken state the composing text is shown in gray, instead of the normal underline — so the display itself differs from a normal composition. This part is a display issue only: clicking elsewhere (which commits the composition) makes the overflowed text wrap correctly, and no characters are lost.
- Jamo loss at the wrap point. When the line does wrap while a syllable is mid-composition, part of that syllable's jamo is dropped. Typing 이것은 사과입니다. ("This is an apple.") produces 이것은 사과ㅂ니다. — the syllable 입 (ㅇ + ㅣ + ㅂ) loses its ㅇ + ㅣ, and only the final ㅂ ends up on the next line. Unlike symptom 1, this is actual data loss: the dropped jamo (ㅇ and ㅣ) never appear on screen at all and are gone from the entered text.
Both symptoms point to the same root cause: after a Meta Bind widget is rendered, the editor mishandles the IME composition/pre-edit state during soft-wrap.
Key finding (how it's tied to Meta Bind): in a clean vault with only Meta Bind installed, the bug does NOT appear — until I create and render a Meta Bind widget (e.g. a button). After that, it appears. In my main vault, the home page contains a Meta Bind button, so opening it once was enough to trigger the bug for the rest of the session. I confirmed this with all other plugins, themes, and CSS snippets disabled, and on a brand-new note.
Steps to Reproduce
- In a vault with Meta Bind enabled, create a note containing a Meta Bind widget (e.g. a button).
- Open that note once so the widget renders, then you may close it.
- Open or create any note and start a line with a bullet list (
-), numbered list (1.), callout (> [!note]), or task (- [ ]). - Narrow the editor pane so text will soft-wrap.
- Using a Korean IME, type Korean text past the right edge.
Observed:
- Symptom 1: repeatedly typing a composing character (e.g. ㅇ) makes the still-composing text overflow past the editor width without wrapping, shown in gray rather than the normal underline. Clicking elsewhere to commit the composition restores correct wrapping with no data loss.
- Symptom 2: when the line wraps mid-composition, jamo is dropped (e.g. 이것은 사과입니다. becomes 이것은 사과ㅂ니다.).
Note: in a clean vault, this does NOT reproduce until a Meta Bind widget has been rendered at least once in the session. Restarting Obsidian with Meta Bind disabled clears the state.
Expected Behavior
IME pre-edit (composing) text should soft-wrap the same way committed text does, regardless of whether a Meta Bind widget has been rendered. Typing 이것은 사과입니다. should produce exactly 이것은 사과입니다., with the composing text wrapping at the editor edge and no jamo dropped.
Activity
mProjectsCode commentedon Jun 21, 2026
I tested this a bit on version 1.13.1 (installer 1.12.6), and I can't seem to reproduce the issue. I am also not familiar with Korean and have no Korean keyboard, so I tested via pasting
ㅇinto a bullet list in a note. For me, it seems to wrap correctly in edit and LP mode.azure463 commentedon Jun 23, 2026
Thank you so much for taking the time to test this, I really appreciate it.
I think I know why it didn't reproduce: the key is that the text has to be typed through a Korean IME, not pasted. This bug happens specifically while a syllable is in the IME's composition (pre-edit) state — the brief, not-yet-finalized state a syllable passes through as you type its jamo. Pasted text is already committed, so it never enters that composing state, which is why pasting ㅇ wraps fine. The bug only shows up during live IME composition.
You don't need a physical Korean keyboard to test it, though — you can add the Korean IME to Windows and type with your existing keyboard:
Settings → Time & language → Language & region → Add a language → install Korean.
Once added, switch the input method to Korean (Win + Space toggles between input methods).
With Korean active, the keyboard maps to jamo. To type the syllable used in my report, 입:
press d → ㅇ (you'll see it appear underlined, meaning it's still composing)
press l → 이
press q → 입
You can also just hold/repeat d to get a run of ㅇ, which is the simplest way to see the wrapping problem.
Make sure a Meta Bind widget (e.g. a button) has been rendered in the session first — open a note containing one, then go to a bullet/callout/task line and type the Korean text so it runs to the line's right edge and wraps.
The underline under a character is the visual cue that it's still in composition — that's the state where the bug triggers. If you type (not paste) a long run of ㅇ past the right edge after a Meta Bind widget has rendered, you should see it either overflow without wrapping, or drop jamo at the wrap point.
Happy to record a short screen capture of the whole process if that would help. Thanks again for looking into this.
mProjectsCode commentedon Aug 1, 2026
Sorry that I haven't replied. I have had no real time to track this down, but now a second report poped up on another one of my plugins mProjectsCode/obsidian-shiki-plugin#89. I spoke with someone from the Obsidian team and they said that there are some currently known Obsidian bugs with the Korean language, see https://forum.obsidian.md/tag/korean/158. Maybe one of those fits your issue.
azure463 commentedon Aug 1, 2026
Thanks for the pointer to the Korean forum tag, and for checking with the Obsidian team.
I went through the topics tagged there, but none of them match the specific behavior I'm seeing. They're all Korean IME issues, but the symptoms are different — characters vanishing on backspace/edit, a line merging on macOS, bold not rendering on Android, and so on. None of them describe IME composition breaking at soft-wrap, which is what happens in my case.
To restate what's distinctive about my situation:
So it seems specific to how a rendered Meta Bind widget affects Korean IME composition during soft-wrap, rather than matching any of the general Korean bugs already reported on the forum.
Happy to record a short screen capture of the whole process if that would help.
mProjectsCode commentedon Aug 2, 2026
Can you test if this release fixes the issue for you: https://github.com/mProjectsCode/obsidian-meta-bind-plugin/releases/tag/1.5.1-canary.20260802T140138
You can either install it manually by downloading and replacing the files, or you can use the BRAT plugin.
dogfooter8750 commentedon Aug 4, 2026
Tested the canary. It does not fix this — both symptoms still reproduce.
I am a second reporter, not @azure463, on the same Windows build.
Followed the steps exactly: opened a note with a
meta-bind-buttononce so the widget rendered, then typed Korean past the right edge on a-bullet line in a narrowed pane.Symptom 2 reproduces exactly as described. Jamo is dropped when the line wraps mid-composition.
Symptom 1 reproduces, but presents differently on my setup, and I think the difference is informative. @azure463 saw the composing text overflow past the editor width, rendered in gray. I see the composing character not rendered at all — it is clipped rather than overflowing. Concretely: if
일이삼사is as much as fits on the line, typing일이삼사오still displays only일이삼사. The오is invisible while it is composing, and appears once the composition commits.Both are consistent with the same underlying cause — composing text not participating in the soft-wrap layout — but one overflows the container and the other is clipped by it. If the fix in this canary targeted the overflow presentation specifically, that would explain why it did not resolve either case here.
English control on the same line wraps normally. Typing
This is an example. This is an example. ...on the same bullet, same pane width, wraps correctly with nothing lost. So this is specific to an active composition, not to line length or to the list prefix.Two things that may narrow it down:
Happy to run more variants if it helps narrow the fix — different list prefixes, callouts, or a specific build. I can also capture the DOM state during composition if you want to see what the decoration layer looks like mid-preedit; testing this class of bug on a real Korean IME is something I have tooling and a machine for.
dogfooter8750 commentedon Aug 6, 2026
Correcting my own comment above. What I reported was accurate, but the premise under it was not: I was testing on the assumption that this is a Meta Bind bug. It is not.
I disabled Meta Bind completely and the bug still reproduces. Same vault, same list line, same narrow pane, same Korean IME. That is the one control I had not run when I posted, and it is the one that mattered.
So @mProjectsCode, your inability to reproduce is not just the missing Korean IME. This is not your bug, and the canary was never going to fix it. Sorry for the detour.
What the measurements show
I instrumented the editor with a
MutationObserveron.cm-contentplus composition-event hooks, and collected 757 events over 148 composition sessions.Wraps during composition still happen with the plugin off, and the symptoms come with them.
At the moment a line wraps mid-composition:
I traced what that added/removed node actually is. At all 4 wrap moments the target was
div.cm-content, not the line — it is CodeMirror's text-measurement probe fromDocView.measureTextSize(), which appends a temporarydiv.cm-lineinto the contenteditable and removes it. That fallback runs whenever it cannot find a short ASCII-only line to measure (/[^ -~]/), so a Korean document always takes it, and it fires when a never-before-seen line height appears — which a wrap during composition is by definition.I also built a standalone page with
@codemirror/view6.43.7 and no Obsidian, and drove composition through 13 configurations: inside and outside amarkdecoration, with other spans before and after the composing node, at end-of-line and mid-line, with areplacewidget on the line, and with decorations rebuilt on every update.findCompositionRangesucceeded in all 13 and nothing was lost. Plain CodeMirror does not reproduce it either, so the trigger is on the Obsidian side.One thing worth knowing about the canary's approach
The canary added a guard that skips widget reconciliation while
view.compositionStartedis true. I reproduced that same guard in the standalone page as one of four variants and typed Korean into all of them. The guarded variant was the only one that producedchildListmutations, and they landed atcompositionend— deferring the recomputation moves the DOM write to the moment the composition commits. That is a synthetic reproduction of the pattern rather than a measurement of your code, so treat it as a caution rather than a finding, but it is a reason not to keep the guard on the strength of this issue.Not just this plugin
The same two symptoms are filed independently against two other plugins by different reporters:
obsidian-shiki-pluginShut up and take my money! #89 — composing character not rendered until it commits, Windows onlyThree unrelated plugins, four reporters, same symptoms. Anything that causes view updates while you type widens the window, which is why it gets reported against whichever plugin the user has installed.
I am consolidating the evidence on the Obsidian forum, where there is an existing Korean-language report of the same thing that stalled on a translation request. I will link it here once it is up so this issue can be closed without the work being lost.
mProjectsCode commentedon Aug 6, 2026
Ok so this is not an issue on my end is what I take from this. Maybe the plugin could be a bit smarter in reducing the number of updates to widgets, but appart from that this seems like a CM or Obsidian issue.
Note that Obsidian uses a slightly older version of codemirror 6.43.5. Since then there have been some bug fixes regarding widgets, so maybe this is why you couldn't repro this with plain CM. (see https://codemirror.net/docs/changelog/)
dogfooter8750 commentedon Aug 6, 2026
Good catch on the version — I checked it and you are right.
I fingerprinted the CodeMirror bundled in Obsidian 1.13.4 (
%APPDATA%/obsidian/obsidian-1.13.4.asar) against the published packages rather than trusting a version string:#ffffff01is a string literal introduced in 6.43.7 for the Firefox 153 selection workaround. It does not appear in the asar.TileUpdateto guard the open-widget assignment:markCountstarts at-1and the write becameif (markCount > -1) this.openWidget = openEnd > markCount. The asar has the unguarded 6.43.5 form, minified as};this.openWidget=a>o.So Obsidian 1.13.4 ships
@codemirror/view6.43.5 exactly, and my repro was on 6.43.7. That is a real gap in what I reported and I should have checked it before drawing a conclusion.What landed in between is also on topic:
The last one is specifically about a line wrap point next to widgets, which is exactly the geometry this bug needs.
I have rebuilt the standalone page with both versions mounted side by side on the same page — same document, same decorations, same 200px wrapping width, one editor pair per version — so a single typing pass compares them directly. I will report back with the result.
If 6.43.5 reproduces and 6.43.7 does not, then this is already fixed upstream and the actionable item is Obsidian picking up the newer CodeMirror, which also explains why it surfaces through so many unrelated plugins at once. I will take that to the Obsidian side rather than leaving it on your tracker either way.
maybe fix mProjectsCode#667
chore(release): 1.5.1-nl.1