diff --git a/app/ime.go b/app/ime.go index df944da8..b60c9a21 100644 --- a/app/ime.go +++ b/app/ime.go @@ -5,6 +5,7 @@ package app import ( "unicode" "unicode/utf16" + "unicode/utf8" "gioui.org/io/input" "gioui.org/io/key" @@ -117,3 +118,28 @@ func (e *editorState) RunesIndex(chars int) int { // Assume runes after snippets are one UTF-16 character each. return runes + chars } + +// areSnippetsConsistent reports whether the content of the old snippet is +// consistent with the content of the new. +func areSnippetsConsistent(old, new key.Snippet) bool { + // Compute the overlapping range. + r := old.Range + r.Start = max(r.Start, new.Start) + r.End = max(r.End, r.Start) + r.End = min(r.End, new.End) + return snippetSubstring(old, r) == snippetSubstring(new, r) +} + +func snippetSubstring(s key.Snippet, r key.Range) string { + for r.Start > s.Start && r.Start < s.End { + _, n := utf8.DecodeRuneInString(s.Text) + s.Text = s.Text[n:] + s.Start++ + } + for r.End < s.End && r.End > s.Start { + _, n := utf8.DecodeLastRuneInString(s.Text) + s.Text = s.Text[:len(s.Text)-n] + s.End-- + } + return s.Text +} diff --git a/app/os_macos.go b/app/os_macos.go index 375ddb81..3a01ef25 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -534,7 +534,7 @@ func (w *window) SetCursor(cursor pointer.Cursor) { } func (w *window) EditorStateChanged(old, new editorState) { - if old.Selection.Range != new.Selection.Range || old.Snippet != new.Snippet { + if old.Selection.Range != new.Selection.Range || !areSnippetsConsistent(old.Snippet, new.Snippet) { C.discardMarkedText(w.view) w.w.SetComposingRegion(key.Range{Start: -1, End: -1}) }