message: Use ITextDocument API for syntax highlighting
  On Windows, use temporary attributes (similarly to what is done on
  macOS) for syntax highlighting. This is *much* more performant and
  fixes lag during input as well as cursor flicker.
  Fixes
diff: #include <comdef.h>
  #include <tom.h>
  _COM_SMARTPTR_TYPEDEF(ITextDocument, __uuidof(ITextDocument));
  + _COM_SMARTPTR_TYPEDEF(ITextRange, __uuidof(ITextRange));
  + _COM_SMARTPTR_TYPEDEF(ITextFont, __uuidof(ITextFont));
  #endif
  #include "colorscheme.h"
  @@ -110,6 +112,30 @@ inline ITextDocumentPtr TextDocument(wxTextCtrl *ctrl)
  return doc;
  }
  +// Use temporary styles (used e.g. by spellchecker too) for syntax highlighting.
  +// See this nice summary of resources:
  +// https://stackoverflow.com/questions/55366383/how-to-clear-temporary-tomapplytmp-formatting-from-a-richedit
  +inline void SetTOMTmpStyle(const ITextDocumentPtr& doc, int from, int to, const wxTextAttr& attr)
  +{
  + ITextRangePtr range;
  + doc->Range(from, to, &range);
  + if (!range)
  + return;
  + ITextFontPtr font;
  + range->GetFont(&font);
  + if (!font)
  + return;
  + font->Reset(tomApplyTmp);
  +
  + auto fg = attr.GetTextColour();
  + auto bg = attr.GetBackgroundColour();
  + if (fg.IsOk())
  + font->SetForeColor(fg.GetPixel());
  + if (bg.IsOk())
  + font->SetBackColor(bg.GetPixel());
  + font->Reset(tomApplyNow);
  +}
  +
  // Temporarily suppresses recording of changes for Undo/Redo functionality
  // See http://stackoverflow.com/questions/4138981/temporaily-disabling-the-c-sharp-rich-edit-undo-buffer-while-performing-syntax-h
  // and http://forums.codeguru.com/showthread.php?325068-Realizing-Undo-Redo-functionality-for-RichEdit-Syntax-Highlighter
  @@ -751,20 +777,31 @@ void AnyTranslatableTextCtrl::HighlightText()
  #else // !__WXOSX__
  -#ifndef __WXGTK__
  - // Freezing (and more to the point, thawing) the window from inside wxEVT_TEXT
  - // handler breaks pasting under GTK+ (selection is not replaced).
  - // See https://github.com/vslavik/poedit/issues/139
  - wxWindowUpdateLocker noupd(this);
  -#endif
  -
  wxEventBlocker block(this, wxEVT_TEXT);
  - #ifdef __WXMSW__
  - UndoSuppressor blockUndo(this);
  - #endif
  auto deflt = m_attrs->Default();
  deflt.SetFont(GetFont());
  +
  + #ifdef __WXMSW__
  + UndoSuppressor blockUndo(this);
  +
  + auto doc = TextDocument(this);
  + if (IsEditable() && doc)
  + {
  + // If possible, use TOM interface to apply temporary styles, which is much
  + // more efficient. Unfortunately, it's not possible to do with read-only controls.
  + SetTOMTmpStyle(doc, 0, text.length(), deflt);
  +
  + if (m_syntax)
  + {
  + m_syntax->Highlight(text, [=](int a, int b, SyntaxHighlighter::TextKind kind){
  + SetTOMTmpStyle(doc, a, b, m_attrs->For(kind));
  + });
  + }
  + }
  + else
  + #endif // __WXMSW___
  + {
  SetStyle(0, text.length(), deflt);
  if (m_syntax)
  @@ -773,6 +810,7 @@ void AnyTranslatableTextCtrl::HighlightText()
  SetStyle(a, b, m_attrs->For(kind));
  });
  }
  + }
  #endif // __WXOSX__/!__WXOSX__
  }
  