@Override
  public void doExecute(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
    final SelectionModel selectionModel = editor.getSelectionModel();
    final CaretModel caretModel = editor.getCaretModel();
    ScrollingModel scrollingModel = editor.getScrollingModel();

    if (selectionModel.hasSelection() && (!(editor instanceof EditorEx) || !((EditorEx)editor).isStickySelection())) {
      int start = selectionModel.getSelectionStart();
      int end = selectionModel.getSelectionEnd();
      int caretOffset = caretModel.getOffset();

      if (start <= caretOffset && end >= caretOffset) { // See IDEADEV-36957

        VisualPosition targetPosition = myDirection == Direction.RIGHT ? caret.getSelectionEndPosition()
                                                                       : caret.getSelectionStartPosition();

        Runnable runnable = () -> {
          selectionModel.removeSelection();
          caretModel.moveToVisualPosition(targetPosition);
          if (caret == editor.getCaretModel().getPrimaryCaret()) {
            scrollingModel.scrollToCaret(ScrollType.RELATIVE);
          }
        };
        EditorUtil.runWithAnimationDisabled(editor, runnable);
        return;
      }
    }

    Runnable runnable = () -> {
      VisualPosition currentPosition = caret.getVisualPosition();
      if (caret.isAtBidiRunBoundary() && (myDirection == Direction.RIGHT ^ currentPosition.leansRight)) {
        caret.moveToVisualPosition(currentPosition.leanRight(!currentPosition.leansRight));
      }
      else {
        final boolean scrollToCaret = (!(editor instanceof EditorImpl) || ((EditorImpl)editor).isScrollToCaret())
                                      && caret == editor.getCaretModel().getPrimaryCaret();
        caretModel.moveCaretRelatively(myDirection == Direction.RIGHT ? 1 : -1, 0, false, false, scrollToCaret);
      }
    };
    EditorUtil.runWithAnimationDisabled(editor, runnable);
  }
@Override
  public void doExecute(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext)