Files
openide/java/java-impl/src/com/intellij/javadoc/JavadocSnippetEnterHandler.java
Mathias Boulay e05667345c fix(javadoc): Missing character on new lines within snippets
#IDEA-358874 Fixed

GitOrigin-RevId: e03874f588e31c106d3a25518c05e0850b3fcd24
2024-09-17 16:28:17 +00:00

98 lines
4.4 KiB
Java

// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.javadoc;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtilEx;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.javadoc.PsiSnippetDocTag;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.DocumentUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapter {
@Override
public Result preprocessEnter(@NotNull PsiFile file,
@NotNull Editor editor,
@NotNull Ref<Integer> caretOffset,
@NotNull Ref<Integer> caretAdvance,
@NotNull DataContext dataContext,
EditorActionHandler originalHandler) {
PsiSnippetDocTag docTag = getHost(file, editor);
if (docTag == null) return Result.Continue;
if (PsiUtil.isInMarkdownDocComment(docTag)) {
// Markdown documentation has to be done in the preprocess, otherwise the file becomes invalid due to comment splitting
final Editor hostEditor = ((EditorWindow)editor).getDelegate();
final CaretModel caretModelHost = hostEditor.getCaretModel();
JavaDocMarkdownEnterHandler.preProcessEnterImpl(docTag.getContainingFile(), hostEditor, new Ref<>(caretModelHost.getOffset()), caretAdvance, dataContext, originalHandler);
}
return Result.Default;
}
@Override
public Result postProcessEnter(@NotNull PsiFile file,
@NotNull Editor editor,
@NotNull DataContext dataContext) {
final PsiSnippetDocTag host = getHost(file, editor);
if (host == null || PsiUtil.isInMarkdownDocComment(host)) return Result.Continue;
final Editor hostEditor = ((EditorWindow)editor).getDelegate();
final Document hostDocument = hostEditor.getDocument();
final CaretModel caretModelHost = hostEditor.getCaretModel();
int caretOffsetHost = caretModelHost.getOffset();
final int lineStartOffset = DocumentUtil.getLineStartOffset(caretOffsetHost, hostDocument);
int firstNonWsLineOffset = CharArrayUtil.shiftForward(hostDocument.getText(), lineStartOffset, " \t");
if (hostDocument.getText().charAt(firstNonWsLineOffset) != '*') {
final String prefix = calcPrefix(host);
hostDocument.insertString(lineStartOffset, prefix);
caretModelHost.moveToOffset(caretOffsetHost + prefix.length());
EditorModificationUtilEx.scrollToCaret(editor);
}
return Result.Default;
}
private static @Nullable PsiSnippetDocTag getHost(@NotNull PsiFile file, @NotNull Editor editor) {
if (!file.isValid()) return null;
if (!(editor instanceof EditorWindow)) return null;
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(file.getProject());
return ObjectUtils.tryCast(injectedLanguageManager.getInjectionHost(file), PsiSnippetDocTag.class);
}
private static String calcPrefix(PsiSnippetDocTag host) {
final PsiFile file = host.getContainingFile();
final String text = file.getText();
int offset = host.getTextOffset();
int asteriskOffset = offset;
while (text.charAt(offset) != '\n' && offset > 0) {
if (text.charAt(offset) == '*') asteriskOffset = offset;
offset --;
}
final String whitespacesPrefix = text.substring(offset + 1, asteriskOffset);
final JavaCodeStyleSettings settings = CodeStyle.getCustomSettings(file, JavaCodeStyleSettings.class);
return (settings.JD_LEADING_ASTERISKS_ARE_ENABLED) ? whitespacesPrefix + "* " : whitespacesPrefix;
}
}