From 027d4fb0223eaad0b9e4e2f201643abd181520c1 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Mon, 16 Sep 2024 14:55:52 +0200 Subject: [PATCH] fix(javadoc-handler): insert leading tokens before start of comment GitOrigin-RevId: 2fc351433f7841f9753d67e2a8d925a9991a1716 --- .../javadoc/JavaDocMarkdownEnterHandler.java | 30 +++++++++++++++---- .../enterhandler/afterEnterAtEdge3.java | 9 ++++++ .../enterhandler/afterInsideLeadingToken.java | 6 ++++ .../enterhandler/beforeEnterAtEdge3.java | 7 +++++ .../beforeInsideLeadingToken.java | 5 ++++ 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterEnterAtEdge3.java create mode 100644 java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterInsideLeadingToken.java create mode 100644 java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeEnterAtEdge3.java create mode 100644 java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeInsideLeadingToken.java diff --git a/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java b/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java index 95fa6636e276..28da11e06a3e 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java +++ b/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java @@ -8,13 +8,19 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiMarkdownCodeBlock; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.DocumentUtil; +import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter { @Override public Result preprocessEnter(@NotNull PsiFile file, @@ -30,14 +36,28 @@ public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter { @ApiStatus.Internal static Result preProcessEnterImpl(@NotNull PsiFile file, - @NotNull Editor editor, - @NotNull Ref caretOffset, - @NotNull Ref caretAdvance, - @NotNull DataContext dataContext, - EditorActionHandler originalHandler) { + @NotNull Editor editor, + @NotNull Ref caretOffset, + @NotNull Ref caretAdvance, + @NotNull DataContext dataContext, + EditorActionHandler originalHandler) { PsiElement caretElement = file.findElementAt(caretOffset.get()); if (caretElement == null) return Result.Continue; + if (caretElement.getNode().getElementType() == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { + TextRange textRange = caretElement.getTextRange(); + + if (textRange.getStartOffset() == caretOffset.get() && + Objects.requireNonNull(PsiTreeUtil.getParentOfType(caretElement, PsiDocComment.class)).getTextOffset() == textRange.getStartOffset()) { + // Bail out if the caret is placed are before the start of the comment + return Result.Continue; + } + + // Avoid breaking a comment by placing the caret beyond the leading token, taking into account a potential space + int newOffset = textRange.getEndOffset(); + caretOffset.set(editor.getDocument().getCharsSequence().charAt(newOffset) == ' ' ? newOffset + 1 : newOffset); + } + // EOL whitespace is not useful, we only need the tokens behind it if (caretElement instanceof PsiWhiteSpace) { // In multiline whitespaces, check cursor position to check whether the handler should trigger diff --git a/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterEnterAtEdge3.java b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterEnterAtEdge3.java new file mode 100644 index 000000000000..975cc6af8aa4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterEnterAtEdge3.java @@ -0,0 +1,9 @@ +// "_ignore" "true" + + +/// - [the `java.util` package][java.util] +/// - [a class][String] +/// - [a field][String#CASE_INSENSITIVE_ORDER] +/// - [a method][String#chars()] + +class C{} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterInsideLeadingToken.java b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterInsideLeadingToken.java new file mode 100644 index 000000000000..0058d16d7435 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/afterInsideLeadingToken.java @@ -0,0 +1,6 @@ +// "_ignore" "true" + +/// Hello there +/// +/// ```````` +class C{} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeEnterAtEdge3.java b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeEnterAtEdge3.java new file mode 100644 index 000000000000..449665812aaf --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeEnterAtEdge3.java @@ -0,0 +1,7 @@ +// "_ignore" "true" + +/// - [the `java.util` package][java.util] +/// - [a class][String] +/// - [a field][String#CASE_INSENSITIVE_ORDER] +/// - [a method][String#chars()] +class C{} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeInsideLeadingToken.java b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeInsideLeadingToken.java new file mode 100644 index 000000000000..bb11f56b892f --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/markdown/enterhandler/beforeInsideLeadingToken.java @@ -0,0 +1,5 @@ +// "_ignore" "true" + +/// Hello there +/// ```````` +class C{} \ No newline at end of file