private void replaceInputMethodText(@NotNull InputMethodEvent e) {
      if (myNeedToSelectPreviousChar && SystemInfo.isMac &&
          (Registry.is("ide.mac.pressAndHold.brute.workaround") || Registry.is("ide.mac.pressAndHold.workaround") &&
                                                                   (hasRelevantCommittedText(e) || e.getCaret() == null))) {
        // This is required to support input of accented characters using press-and-hold method (http://support.apple.com/kb/PH11264).
        // JDK currently properly supports this functionality only for TextComponent/JTextComponent descendants.
        // For our editor component, we need this workaround.
        // After https://bugs.openjdk.org/browse/JDK-8074882 is fixed, this workaround should be replaced with a proper solution.
        myNeedToSelectPreviousChar = false;
        getCaretModel().runForEachCaret(caret -> {
          int caretOffset = caret.getOffset();
          if (caretOffset > 0) {
            caret.setSelection(caretOffset - 1, caretOffset);
          }
        });
      }

      boolean isCaretMoved = false;
      int caretPositionToRestore = 0;
      int composedStartIndex = -1;

      int commitCount = e.getCommittedCharacterCount();
      AttributedCharacterIterator text = e.getText();

      // old composed text deletion
      Document doc = getDocument();

      if (inlayLeft != null || inlayRight != null) {
        composedStartIndex = inlayLeft != null ? inlayLeft.getOffset() : inlayRight.getOffset();
        if (inlayLeft != null) {
          Disposer.dispose(inlayLeft);
          inlayLeft = null;
        }
        if (inlayRight != null) {
          Disposer.dispose(inlayRight);
          inlayRight = null;
        }
      }
      if (composedRangeMarker != null) {
        if (!isViewer() && doc.isWritable()) {
          composedStartIndex = composedRangeMarker.getStartOffset();
          runUndoTransparent(() -> {
            if (composedRangeMarker.isValid()) {
              doc.deleteString(composedRangeMarker.getStartOffset(), composedRangeMarker.getEndOffset());
            }
          });
          if (composedRangeMarker.isValid()) {
            // IDEA-331578: Deleting a string from a document may move the range marker to the left (i.e. during inline rename)
            // We must use the new `startOffset` value here if the range marker is still valid
            composedStartIndex = composedRangeMarker.getStartOffset();
          }
        }
        composedRangeMarker.dispose();
        composedRangeMarker = null;
      }
      if (composedStartIndex >= 0) {
        isCaretMoved = getCaretModel().getOffset() != composedStartIndex;
        if (isCaretMoved) {
          caretPositionToRestore = getCaretModel().getCurrentCaret().getOffset();
          // if caret set further in the doc, we should add commitCount
          if (caretPositionToRestore > composedStartIndex) {
            caretPositionToRestore += commitCount;
          }
          getCaretModel().moveToOffset(composedStartIndex);
        }
      }

      if (text != null) {
        text.first();

        // committed text insertion
        if (commitCount > 0) {
          for (char c = text.current(); c != CharacterIterator.DONE && commitCount > 0; c = text.next(), commitCount--) {
            if (c >= 0x20 && c != 0x7F) { // Hack just like in javax.swing.text.DefaultEditorKit.DefaultKeyTypedAction
              processKeyTyped(c);
            }
          }
        }

        // new composed text insertion
        if (!isViewer() && doc.isWritable()) {
          int composedTextIndex = text.getIndex();
          if (composedTextIndex < text.getEndIndex()) {
            String composedString = createComposedString(composedTextIndex, text);
            if (Registry.is("editor.input.method.inlay")) {
              runUndoTransparent(() -> EditorModificationUtil.deleteSelectedTextForAllCarets(EditorImpl.this));

              var offset = getCaretModel().getCurrentCaret().getOffset();
              var caret = e.getCaret();
              var leftLength = caret != null ? caret.getInsertionIndex() : 0;
              if (leftLength > 0) {
                inlayLeft = getInlayModel().addInlineElement(offset, false, -IME_INLAY_PRIORITY,
                                                             new InputMethodInlayRenderer(composedString.substring(0, leftLength)));
              }
              if (leftLength < composedString.length()) {
                inlayRight = getInlayModel().addInlineElement(offset, true, IME_INLAY_PRIORITY,
                                                              new InputMethodInlayRenderer(composedString.substring(leftLength)));
              }
            }
            else {
              runUndoTransparent(() -> EditorModificationUtilEx.insertStringAtCaret(EditorImpl.this, composedString, false, false));
              composedRangeMarker =
                myDocument.createRangeMarker(getCaretModel().getOffset(), getCaretModel().getOffset() + composedString.length(), true);
            }
          }
        }
      }

      if (isCaretMoved) {
        getCaretModel().moveToOffset(caretPositionToRestore);
      }
    }
private void replaceInputMethodText(@NotNull InputMethodEvent e)