private static void insertTabAtCaret(Editor editor, @NotNull Caret caret, @Nullable Project project) {
    EditorUIUtil.hideCursorInEditor(editor);
    int columnNumber;
    if (caret.hasSelection()) {
      columnNumber = editor.visualToLogicalPosition(caret.getSelectionStartPosition()).column;
    }
    else {
      columnNumber = editor.getCaretModel().getLogicalPosition().column;
    }

    CodeStyleSettings settings = project != null ? CodeStyle.getSettings(project) : CodeStyle.getDefaultSettings();

    final Document doc = editor.getDocument();
    CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptionsByDocument(project, doc);

    int tabSize = indentOptions.INDENT_SIZE;
    int spacesToAddCount = tabSize - columnNumber % Math.max(1,tabSize);

    boolean useTab = editor.getSettings().isUseTabCharacter(project);

    CharSequence chars = doc.getCharsSequence();
    if (useTab && indentOptions.SMART_TABS) {
      int offset = editor.getCaretModel().getOffset();
      while (offset > 0) {
        offset--;
        if (chars.charAt(offset) == '\t') continue;
        if (chars.charAt(offset) == '\n') break;
        useTab = false;
        break;
      }
    }

    doc.startGuardedBlockChecking();
    try {
      EditorModificationUtil.insertStringAtCaret(editor, useTab ? "\t" : StringUtil.repeatSymbol(' ', spacesToAddCount), false, true);
    }
    catch (ReadOnlyFragmentModificationException e) {
      EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
    }
    finally {
      doc.stopGuardedBlockChecking();
    }
  }
private static void insertTabAtCaret(Editor editor, @NotNull Caret caret, @Nullable Project project)