@Nullable
  private static TextRange getWordOrLexemeSelectionRange(@Nullable Editor editor, @NotNull CharSequence editorText, int cursorOffset,
                                                         @NotNull CharCondition isWordPartCondition) {
    int length = editorText.length();
    if (length == 0) return null;
    if (cursorOffset == length ||
        cursorOffset > 0 && !isWordPartCondition.value(editorText.charAt(cursorOffset)) &&
        isWordPartCondition.value(editorText.charAt(cursorOffset - 1))) {
      cursorOffset--;
    }

    if (isWordPartCondition.value(editorText.charAt(cursorOffset))) {
      int start = cursorOffset;
      int end = cursorOffset;

      while (start > 0 && isWordPartCondition.value(editorText.charAt(start - 1)) &&
             (editor == null || !EditorActionUtil.isLexemeBoundary(editor, start))) {
        start--;
      }

      while (end < length && isWordPartCondition.value(editorText.charAt(end)) &&
             (end == start || editor == null || !EditorActionUtil.isLexemeBoundary(editor, end))) {
        end++;
      }

      return new TextRange(start, end);
    }

    return null;
  }
@Nullable
  private static TextRange getWordOrLexemeSelectionRange(@Nullable Editor editor, @NotNull CharSequence editorText, int cursorOffset,
                                                         @NotNull CharCondition isWordPartCondition)