Java Code Examples for com.intellij.openapi.editor.Document#insertString()

The following examples show how to use com.intellij.openapi.editor.Document#insertString() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CSharpSmartEnterProcessor.java    From consulo-csharp with Apache License 2.0 6 votes vote down vote up
@RequiredReadAction
private void insertStringAtEndWithReformat(@Nonnull String text, @Nonnull PsiElement anchor, @Nonnull Editor editor, int moveOffset, boolean commit)
{
	PsiFile containingFile = anchor.getContainingFile();

	Document document = editor.getDocument();
	TextRange range = anchor.getTextRange();
	int endOffset = range.getEndOffset();
	document.insertString(endOffset, text);
	editor.getCaretModel().moveToOffset(endOffset + moveOffset);
	if(commit)
	{
		commit(editor);
	}

	reformatRange(containingFile, new TextRange(range.getStartOffset(), endOffset + moveOffset));
}
 
Example 2
Source File: SuppressLineActionFix.java    From eslint-plugin with MIT License 6 votes vote down vote up
@Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
//        final PsiFile file = element.getContainingFile();
        if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;

//  InspectionManager inspectionManager = InspectionManager.getInstance(project);
//  ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(element, element, "", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);

        final JSElement property = PsiTreeUtil.getParentOfType(element, JSElement.class);
        LOG.assertTrue(property != null);
        final int start = property.getTextRange().getStartOffset();

        @NonNls final Document doc = PsiDocumentManager.getInstance(project).getDocument(file);
        LOG.assertTrue(doc != null);
        final int line = doc.getLineNumber(start);
        final int lineEnd = doc.getLineEndOffset(line);
        doc.insertString(lineEnd, " //eslint-disable-line " + rule);
        DaemonCodeAnalyzer.getInstance(project).restart(file);
    }
 
Example 3
Source File: SuppressActionFix.java    From eslint-plugin with MIT License 6 votes vote down vote up
@Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
//        final PsiFile file = element.getContainingFile();
        if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;

//  InspectionManager inspectionManager = InspectionManager.getInstance(project);
//  ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(element, element, "", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);

        final JSElement property = PsiTreeUtil.getParentOfType(element, JSElement.class);
        LOG.assertTrue(property != null);
        final int start = property.getTextRange().getStartOffset();

        @NonNls final Document doc = PsiDocumentManager.getInstance(project).getDocument(file);
        LOG.assertTrue(doc != null);
        final int line = doc.getLineNumber(start);
        final int lineStart = doc.getLineStartOffset(line);

        doc.insertString(lineStart, "/*eslint " + rule + ":0*/\n");
        DaemonCodeAnalyzer.getInstance(project).restart(file);
    }
 
Example 4
Source File: Change.java    From consulo with Apache License 2.0 6 votes vote down vote up
/**
 * Applies the text from the original marker to the target marker.
 * @return the resulting TextRange from the target document, or null if the document if not writable.
 */
@Nullable
private static TextRange modifyDocument(@Nonnull Project project, @Nonnull RangeMarker original, @Nonnull RangeMarker target) {
  Document document = target.getDocument();
  if (!ReadonlyStatusHandler.ensureDocumentWritable(project, document)) { return null; }
  if (DocumentUtil.isEmpty(original)) {
    int offset = target.getStartOffset();
    document.deleteString(offset, target.getEndOffset());
  }
  String text = DocumentUtil.getText(original);
  int startOffset = target.getStartOffset();
  if (DocumentUtil.isEmpty(target)) {
    document.insertString(startOffset, text);
  } else {
    document.replaceString(startOffset, target.getEndOffset(), text);
  }
  return new TextRange(startOffset, startOffset + text.length());
}
 
Example 5
Source File: DialogEditorAction.java    From idea-latex with MIT License 6 votes vote down vote up
@NotNull
protected Runnable getDialogAction(@NotNull final T dialog, @NotNull final TextEditor editor) {
    return new Runnable() {
        @Override
        public void run() {
            final Document document = editor.getEditor().getDocument();
            final CaretModel caretModel = editor.getEditor().getCaretModel();
            final String content = getContent(dialog);

            int offset = caretModel.getOffset();

            document.insertString(offset, content);
            caretModel.moveToOffset(offset + content.length());
        }
    };
}
 
Example 6
Source File: CommonMacroCompletionContributor.java    From intellij with Apache License 2.0 6 votes vote down vote up
/**
 * Rough insertion of load statement somewhere near top of file, preferentially near other load
 * statements.
 *
 * <p>Doesn't try to combine with existing load statements with the same package (we've already
 * checked whether the symbol is already available).
 *
 * <p>TODO(brendandouglas): use buildozer instead.
 */
private static void insertLoadStatement(
    InsertionContext context, BuildFile file, String packageLocation, String symbol) {
  EventLoggingService.getInstance()
      .logEvent(
          CommonMacroCompletionContributor.class,
          "completed",
          ImmutableMap.of(symbol, packageLocation));

  String text = String.format("load(\"%s\", \"%s\")\n", packageLocation, symbol);

  Document doc = context.getEditor().getDocument();
  PsiElement anchor = findAnchorElement(file);
  int lineNumber = anchor == null ? 0 : doc.getLineNumber(anchor.getTextRange().getStartOffset());
  int offset = doc.getLineStartOffset(lineNumber);
  doc.insertString(offset, text);
}
 
Example 7
Source File: BashUnmatchedBraceEnterProcessor.java    From BashSupport with Apache License 2.0 6 votes vote down vote up
@Override
public Result preprocessEnter(@NotNull PsiFile file, @NotNull Editor editor, @NotNull Ref<Integer> caretOffset, @NotNull Ref<Integer> caretAdvance, @NotNull DataContext dataContext, @Nullable EditorActionHandler originalHandler) {
    Project project = editor.getProject();

    if (CodeInsightSettings.getInstance().INSERT_BRACE_ON_ENTER && file instanceof BashFile && project != null) {
        Document document = editor.getDocument();
        CharSequence chars = document.getCharsSequence();

        int offset = caretOffset.get();
        int length = chars.length();

        if (offset < length && offset >= 1 && chars.charAt(offset - 1) == '{') {
            int start = offset + 1;
            int end = offset + 1 + "function".length();

            if (start < length && end < length && "function".contentEquals(chars.subSequence(start, end))) {
                document.insertString(start, "\n");
                PsiDocumentManager.getInstance(project).commitDocument(document);
            }
        }
    }

    return Result.Continue;
}
 
Example 8
Source File: BookmarkManagerTest.java    From consulo with Apache License 2.0 6 votes vote down vote up
public void testBookmarkManagerDoesNotHardReferenceDocuments() throws IOException {
  @NonNls String text =
    "public class Test {\n" +
    "}";

  myVFile = getSourceRoot().createChildData(null, getTestName(false) + ".txt");
  VfsUtil.saveText(myVFile, text);

  Bookmark bookmark = getManager().addTextBookmark(myVFile, 1, "xxx");
  assertNotNull(bookmark);
  LeakHunter.checkLeak(getManager(), Document.class);

  Document document = FileDocumentManager.getInstance().getDocument(myVFile);
  assertNotNull(document);

  document.insertString(0, "line 0\n");
  assertEquals(2, bookmark.getLine());

  myEditor = createEditor(myVFile);
  checkBookmarkNavigation(bookmark);
}
 
Example 9
Source File: CompletionUtil.java    From consulo with Apache License 2.0 5 votes vote down vote up
public static void emulateInsertion(LookupElement item, int offset, InsertionContext context) {
  setOffsets(context, offset, offset);

  final Editor editor = context.getEditor();
  final Document document = editor.getDocument();
  final String lookupString = item.getLookupString();

  document.insertString(offset, lookupString);
  editor.getCaretModel().moveToOffset(context.getTailOffset());
  PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
  item.handleInsert(context);
  PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(document);
}
 
Example 10
Source File: MyTypedHandler.java    From intellij-sdk-docs with Apache License 2.0 5 votes vote down vote up
@NotNull
@Override
public Result charTyped(char c, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
  // Get the document and project
  final Document document = editor.getDocument();
  // Construct the runnable to substitute the string at offset 0 in the document
  Runnable runnable = () -> document.insertString(0, "editor_basics\n");
  // Make the document change in the context of a write action.
  WriteCommandAction.runWriteCommandAction(project, runnable);
  return Result.STOP;
}
 
Example 11
Source File: TfIgnoreUtil.java    From azure-devops-intellij with MIT License 5 votes vote down vote up
private static void addLineToFile(VirtualFile file, String line) {
    FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
    Document document = ObjectUtils.assertNotNull(fileDocumentManager.getDocument(file));
    CharSequence contents = document.getCharsSequence();
    if (!StringUtil.isEmpty(contents) && !StringUtil.endsWith(contents, "\n")) {
        document.insertString(contents.length(), "\n");
    }
    document.insertString(document.getTextLength(), line);
    fileDocumentManager.saveDocument(document);
}
 
Example 12
Source File: TailType.java    From consulo with Apache License 2.0 5 votes vote down vote up
public static int insertChar(Editor editor, int tailOffset, char c, boolean overwrite) {
  Document document = editor.getDocument();
  int textLength = document.getTextLength();
  CharSequence chars = document.getCharsSequence();
  if (tailOffset == textLength || !overwrite || chars.charAt(tailOffset) != c){
    document.insertString(tailOffset, String.valueOf(c));
  }
  return moveCaret(editor, tailOffset, 1);
}
 
Example 13
Source File: VariableInsertHandler.java    From intellij-xquery with Apache License 2.0 5 votes vote down vote up
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
    final Editor editor = context.getEditor();
    final Document document = editor.getDocument();
    context.commitDocument();
    PsiElement element = findElementBeforeNameFragment(context);
    if (element instanceof LeafPsiElement
            && ((LeafPsiElement) element).getElementType() != XQueryTypes.DOLLAR_SIGN) {
        document.insertString(context.getStartOffset(), "$");
    }
    InsertHandlerUtils.removePreviousNamespaceAndColonIfPresent(context);
}
 
Example 14
Source File: RefactorUtils.java    From intellij-plugin-v4 with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public static void insertText(final Project project, final Document doc,
                              final int where,
                              final String text)
{
	WriteCommandAction setTextAction = new WriteCommandAction(project) {
		@Override
		protected void run(final Result result) throws Throwable {
			doc.insertString(where, text);
		}
	};
	setTextAction.execute();
}
 
Example 15
Source File: InjectTextAction.java    From PackageTemplates with Apache License 2.0 5 votes vote down vote up
private void injectText(PsiFile psiFile) {
    ReadonlyStatusHandler.OperationStatus status = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(psiFile.getVirtualFile());
    if (status.hasReadonlyFiles()) {
        ReportHelper.setState(ExecutionState.FAILED);
        ReportHelper.putReport(new FailedActionReport(this, Localizer.get("error.ReadOnlyFile"), "InjectTextAction ReadOnlyFile"));
        Logger.log("InjectTextAction ReadOnlyFile");
        return;
    }

    Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
    if (document == null) {
        ReportHelper.setState(ExecutionState.FAILED);
        ReportHelper.putReport(new FailedActionReport(this, Localizer.get("error.internalError"), "InjectTextAction document==nul"));
        Logger.log("InjectTextAction document==nul");
        return;
    }

    int offset = getOffset(document, textInjection.getInjectDirection());
    if (offset == -1) {
        return;
    }

    String textToInsert = fromVelocity(textInjection.getTextToInject());
    if (textToInsert == null) {
        return;
    }

    // Replace
    if (textInjection.getInjectDirection() == InjectDirection.REPLACE) {
        doReplace(document, textToInsert);
    }
    // Insert
    else {
        document.insertString(offset, textToInsert);
    }
}
 
Example 16
Source File: JSGraphQLEndpointCreateDefinitionIntention.java    From js-graphql-intellij-plugin with MIT License 4 votes vote down vote up
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {

    final JSGraphQLEndpointNamedTypePsiElement unknownNamedType = getUnknownNamedType(element);
    if (unknownNamedType != null) {
        JSGraphQLEndpointNamedTypeDefinition definition = PsiTreeUtil.getParentOfType(element, JSGraphQLEndpointNamedTypeDefinition.class);
        if (definition == null) {
            // nearest type before cursor if not inside a type definition
            definition = PsiTreeUtil.getPrevSiblingOfType(unknownNamedType, JSGraphQLEndpointNamedTypeDefinition.class);
        }
        if (definition != null) {
            final IElementType type = getSupportedDefinitionType();
            final String definitionText;
            final boolean insertBefore = (type == JSGraphQLEndpointTokenTypes.INPUT);
            Ref<Integer> caretOffsetAfterInsert = new Ref<>();
            boolean indent = false;
            if (type == JSGraphQLEndpointTokenTypes.UNION) {
                definitionText = "\n\nunion " + unknownNamedType.getText() + " = \n";
                caretOffsetAfterInsert.set(definitionText.length() - 1);
            } else if (type == JSGraphQLEndpointTokenTypes.SCALAR) {
                definitionText = "\n\nscalar " + unknownNamedType.getText() + "\n";
            } else {
                // all other types are <name> { ... }
                final String beforeLines = insertBefore ? "" : "\n\n";
                final String afterLines = insertBefore ? "\n\n" : "\n";
                final int caretOffsetDelta = insertBefore ? 4 : 3; // we want the caret to be placed before closing '}' and the trailing newlines
                definitionText = beforeLines + type.toString().toLowerCase() + " " + unknownNamedType.getText() + " {\n\n}" + afterLines;
                caretOffsetAfterInsert.set(definitionText.length() - caretOffsetDelta);
                indent = true;
            }
            final Document document = editor.getDocument();
            final int insertOffset;
            if(insertBefore) {
                final PsiComment documentationStartElement = JSGraphQLEndpointDocPsiUtil.getDocumentationStartElement(definition);
                if(documentationStartElement != null) {
                    insertOffset = documentationStartElement.getTextRange().getStartOffset();
                } else {
                    insertOffset = definition.getTextRange().getStartOffset();
                }
            } else {
                insertOffset = definition.getTextRange().getEndOffset();
            }
            document.insertString(insertOffset, definitionText);
            if (caretOffsetAfterInsert.get() != null) {
                // move caret to new position
                PsiDocumentManager.getInstance(element.getProject()).commitDocument(document);
                editor.getCaretModel().moveToOffset(insertOffset + caretOffsetAfterInsert.get());
                if (indent) {
                    AnAction editorLineEnd = ActionManager.getInstance().getAction("EditorLineEnd");
                    if (editorLineEnd != null) {
                        final AnActionEvent actionEvent = AnActionEvent.createFromDataContext(
                                ActionPlaces.UNKNOWN,
                                null,
                                new DataManagerImpl.MyDataContext(editor.getComponent())
                        );
                        editorLineEnd.actionPerformed(actionEvent);
                    }
                }
            }
        }
    }
}
 
Example 17
Source File: EnterBetweenBracesHandler.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
public Result preprocessEnter(@Nonnull final PsiFile file, @Nonnull final Editor editor, @Nonnull final Ref<Integer> caretOffsetRef, @Nonnull final Ref<Integer> caretAdvance,
                              @Nonnull final DataContext dataContext, final EditorActionHandler originalHandler) {
  Document document = editor.getDocument();
  CharSequence text = document.getCharsSequence();
  int caretOffset = caretOffsetRef.get().intValue();
  if (!CodeInsightSettings.getInstance().SMART_INDENT_ON_ENTER) {
    return Result.Continue;
  }

  int prevCharOffset = CharArrayUtil.shiftBackward(text, caretOffset - 1, " \t");
  int nextCharOffset = CharArrayUtil.shiftForward(text, caretOffset, " \t");

  if (!isValidOffset(prevCharOffset, text) || !isValidOffset(nextCharOffset, text) ||
      !isBracePair(text.charAt(prevCharOffset), text.charAt(nextCharOffset))) {
    return Result.Continue;
  }

  PsiDocumentManager.getInstance(file.getProject()).commitDocument(editor.getDocument());
  if (file.findElementAt(prevCharOffset) == file.findElementAt(nextCharOffset)) {
    return Result.Continue;
  }

  final int line = document.getLineNumber(caretOffset);
  final int start = document.getLineStartOffset(line);
  final CodeDocumentationUtil.CommentContext commentContext =
          CodeDocumentationUtil.tryParseCommentContext(file, text, caretOffset, start);

  // special case: enter inside "()" or "{}"
  String indentInsideJavadoc = isInComment(caretOffset, file) && commentContext.docAsterisk
                               ? CodeDocumentationUtil.getIndentInsideJavadoc(document, caretOffset)
                               : null;

  originalHandler.execute(editor, editor.getCaretModel().getCurrentCaret(), dataContext);

  Project project = editor.getProject();
  if (indentInsideJavadoc != null && project != null && CodeStyleSettingsManager.getSettings(project).JD_LEADING_ASTERISKS_ARE_ENABLED) {
    document.insertString(editor.getCaretModel().getOffset(), "*" + indentInsideJavadoc);
  }

  PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
  try {
    CodeStyleManager.getInstance(file.getProject()).adjustLineIndent(file, editor.getCaretModel().getOffset());
  }
  catch (IncorrectOperationException e) {
    LOG.error(e);
  }
  return indentInsideJavadoc == null ? Result.Continue : Result.DefaultForceIndent;
}
 
Example 18
Source File: BracesInsertHandler.java    From consulo-unity3d with Apache License 2.0 4 votes vote down vote up
@Override
public void handleInsert(final InsertionContext context, final T item)
{
	final Editor editor = context.getEditor();
	final Document document = editor.getDocument();
	context.commitDocument();
	PsiElement element = findNextToken(context);

	final char completionChar = context.getCompletionChar();
	final boolean putCaretInside = completionChar == '{' || placeCaretInsideParentheses(context, item);

	if(completionChar == '{')
	{
		context.setAddCompletionChar(false);
	}

	if(isToken(element, "{"))
	{
		int lparenthOffset = element.getTextRange().getStartOffset();
		if(mySpaceBeforeParentheses && lparenthOffset == context.getTailOffset())
		{
			document.insertString(context.getTailOffset(), " ");
			lparenthOffset++;
		}

		if(completionChar == '{' || completionChar == '\t')
		{
			editor.getCaretModel().moveToOffset(lparenthOffset + 1);
		}
		else
		{
			editor.getCaretModel().moveToOffset(context.getTailOffset());
		}

		context.setTailOffset(lparenthOffset + 1);

		PsiElement list = element.getParent();
		PsiElement last = list.getLastChild();
		if(isToken(last, "}"))
		{
			int rparenthOffset = last.getTextRange().getStartOffset();
			context.setTailOffset(rparenthOffset + 1);
			if(!putCaretInside)
			{
				for(int i = lparenthOffset + 1; i < rparenthOffset; i++)
				{
					if(!Character.isWhitespace(document.getCharsSequence().charAt(i)))
					{
						return;
					}
				}
				editor.getCaretModel().moveToOffset(context.getTailOffset());
			}
			else if(mySpaceBetweenParentheses && document.getCharsSequence().charAt(lparenthOffset) == ' ')
			{
				editor.getCaretModel().moveToOffset(lparenthOffset + 2);
			}
			else
			{
				editor.getCaretModel().moveToOffset(lparenthOffset + 1);
			}
			return;
		}
	}
	else
	{
		document.insertString(context.getTailOffset(), getSpace(mySpaceBeforeParentheses) + '{' + getSpace(mySpaceBetweenParentheses));
		editor.getCaretModel().moveToOffset(context.getTailOffset());
	}

	if(!myMayInsertRightParenthesis)
	{
		return;
	}

	if(context.getCompletionChar() == '{')
	{
		int tail = context.getTailOffset();
		if(tail < document.getTextLength() && StringUtil.isJavaIdentifierPart(document.getCharsSequence().charAt(tail)))
		{
			return;
		}
	}

	document.insertString(context.getTailOffset(), getSpace(mySpaceBetweenParentheses) + "}");
	if(!putCaretInside)
	{
		editor.getCaretModel().moveToOffset(context.getTailOffset());
	}
}
 
Example 19
Source File: ParenthesesInsertHandler.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
public void handleInsert(final InsertionContext context, final T item) {
  final Editor editor = context.getEditor();
  final Document document = editor.getDocument();
  context.commitDocument();
  PsiElement lParen = findExistingLeftParenthesis(context);

  final char completionChar = context.getCompletionChar();
  final boolean putCaretInside = completionChar == myLeftParenthesis || placeCaretInsideParentheses(context, item);

  if (completionChar == myLeftParenthesis) {
    context.setAddCompletionChar(false);
  }

  if (lParen != null) {
    int lparenthOffset = lParen.getTextRange().getStartOffset();
    if (mySpaceBeforeParentheses && lparenthOffset == context.getTailOffset()) {
      document.insertString(context.getTailOffset(), " ");
      lparenthOffset++;
    }

    if (completionChar == myLeftParenthesis || completionChar == '\t') {
      editor.getCaretModel().moveToOffset(lparenthOffset + 1);
    }
    else {
      editor.getCaretModel().moveToOffset(context.getTailOffset());
    }

    context.setTailOffset(lparenthOffset + 1);

    PsiElement list = lParen.getParent();
    PsiElement last = list.getLastChild();
    if (isToken(last, String.valueOf(myRightParenthesis))) {
      int rparenthOffset = last.getTextRange().getStartOffset();
      context.setTailOffset(rparenthOffset + 1);
      if (!putCaretInside) {
        for (int i = lparenthOffset + 1; i < rparenthOffset; i++) {
          if (!Character.isWhitespace(document.getCharsSequence().charAt(i))) {
            return;
          }
        }
        editor.getCaretModel().moveToOffset(context.getTailOffset());
      }
      else if (mySpaceBetweenParentheses && document.getCharsSequence().charAt(lparenthOffset) == ' ') {
        editor.getCaretModel().moveToOffset(lparenthOffset + 2);
      }
      else {
        editor.getCaretModel().moveToOffset(lparenthOffset + 1);
      }
      return;
    }
  }
  else {
    document.insertString(context.getTailOffset(), getSpace(mySpaceBeforeParentheses) + myLeftParenthesis + getSpace(mySpaceBetweenParentheses));
    editor.getCaretModel().moveToOffset(context.getTailOffset());
  }

  if (!myMayInsertRightParenthesis) return;

  if (context.getCompletionChar() == myLeftParenthesis) {
    //todo use BraceMatchingUtil.isPairedBracesAllowedBeforeTypeInFileType
    int tail = context.getTailOffset();
    if (tail < document.getTextLength() && StringUtil.isJavaIdentifierPart(document.getCharsSequence().charAt(tail))) {
      return;
    }
  }

  document.insertString(context.getTailOffset(), getSpace(mySpaceBetweenParentheses) + myRightParenthesis);
  if (!putCaretInside) {
    editor.getCaretModel().moveToOffset(context.getTailOffset());
  }
}
 
Example 20
Source File: QuoteHandler.java    From bamboo-soy with Apache License 2.0 4 votes vote down vote up
@Override
public Result beforeCharTyped(char charTyped, final Project project, final Editor editor,
    final PsiFile file, final FileType fileType) {
  if (file.getFileType() != SoyFileType.INSTANCE && file.getFileType() != HtmlFileType.INSTANCE) {
    return Result.CONTINUE;
  }

  Document document = editor.getDocument();
  int caretOffset = editor.getCaretModel().getOffset();

  String prevChar = getPreviousChar(document, caretOffset);
  String nextChar = getNextChar(document, caretOffset);

  int lineNumber = document.getLineNumber(caretOffset);
  String textBeforeCaret =
      document.getText(new TextRange(document.getLineStartOffset(lineNumber),
          caretOffset));
  String textAfterCaret =
      document.getText(new TextRange(caretOffset,
          document.getLineEndOffset(lineNumber)));

  Pair<Character, Character> matchingPairReverse = getMatchingPair(charTyped,
      p -> p.getSecond());
  if (matchingPairReverse != null && nextChar.equals(charTyped + "")) {
    boolean pairOfEqualChars = (matchingPairReverse.first == matchingPairReverse.second);

    // Number of opens on the left of the caret.
    int countLeft = computeCount(textBeforeCaret, matchingPairReverse.first,
        matchingPairReverse.second);

    // Number of closes on the right of the caret.
    int countRight = computeCount(textAfterCaret, matchingPairReverse.second,
        matchingPairReverse.first);

    // When the pair is made of equal characters (like quotes) then only trigger if there is
    // a balance of 1-1 around the caret, which means that the quote is already closed and
    // inserting a new quote would create an imbalance.
    if (((!pairOfEqualChars && countLeft <= countRight) || (pairOfEqualChars
        && countLeft == countRight)) && countRight > 0) {
      editor.getCaretModel().moveToOffset(caretOffset + 1);
      return Result.STOP;
    }
  } else {
    Pair<Character, Character> matchingPair = getMatchingPair(charTyped,
        p -> p.getFirst());
    if (matchingPair != null) {
      if ((alwaysCloseCharacters.contains(matchingPair.first) || (allowedPreviousCharacters
          .contains(prevChar)) && allowedNextCharacters.contains(nextChar)
          && !nextChar.equals(matchingPair.second + ""))) {
        document.insertString(editor.getCaretModel().getOffset(), matchingPair.second + "");

        if (editor.getProject() != null) {
          PsiDocumentManager.getInstance(editor.getProject()).commitDocument(document);
        }
      }
    }
  }

  return Result.CONTINUE;
}