Skip to content

Commit

Permalink
Make wrap-on-typing work for AsciiDoc without chopping an existing li…
Browse files Browse the repository at this point in the history
…ne into small chunks (#1653)
  • Loading branch information
ahus1 committed Dec 20, 2024
1 parent f837bc7 commit fa281af
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This document provides a high-level view of the changes introduced by release.

- Update docs and templates to recommend an absolute path for the `pdf-themesdir` (#1750)
- When rendering the preview for Antora, automatically switch to highlight.js syntax highlighting (#1736)
- Make wrap-on-typing work for AsciiDoc without chopping an existing line into small chunks (#1653)

=== 0.43.4

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.asciidoc.intellij.formatting;

import com.intellij.codeInsight.editorActions.AutoHardWrapHandler;
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiFile;
import org.asciidoc.intellij.file.AsciiDocFileType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* This handler copies the auto-wrap-in-progress-flag from the handler-specific data context to the editor's data-content,
* as the handler-specific data context is not available in the {@link AsciiDocLineIndentProvider}.
*
* @author Alexander Schwartz
*/
public class AsciiDocEnterHandlerDelegate implements EnterHandlerDelegate {
@Override
public Result preprocessEnter(@NotNull PsiFile file, @NotNull Editor editor, @NotNull Ref<Integer> caretOffset, @NotNull Ref<Integer> caretAdvance, @NotNull DataContext dataContext, @Nullable EditorActionHandler originalHandler) {
if (file.getFileType() == AsciiDocFileType.INSTANCE) {
if (DataManager.getInstance().loadFromDataContext(dataContext, AutoHardWrapHandler.AUTO_WRAP_LINE_IN_PROGRESS_KEY) == Boolean.TRUE) {
editor.putUserData(AutoHardWrapHandler.AUTO_WRAP_LINE_IN_PROGRESS_KEY, true);
}
}
return EnterHandlerDelegate.Result.Continue;
}

@Override
public Result postProcessEnter(@NotNull PsiFile file, @NotNull Editor editor, @NotNull DataContext dataContext) {
if (file.getFileType() == AsciiDocFileType.INSTANCE) {
if (editor.getUserData(AutoHardWrapHandler.AUTO_WRAP_LINE_IN_PROGRESS_KEY) == Boolean.TRUE) {
editor.putUserData(AutoHardWrapHandler.AUTO_WRAP_LINE_IN_PROGRESS_KEY, null);
}
}
return EnterHandlerDelegate.Result.Continue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.asciidoc.intellij.formatting;

import com.intellij.codeInsight.editorActions.AutoHardWrapHandler;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider;
import com.intellij.psi.impl.source.codeStyle.lineIndent.FormatterBasedLineIndentProvider;
import org.asciidoc.intellij.AsciiDocLanguage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* When auto-wrapping of lines in in-progress, don't adjust the line's indent to avoid confusing the logic in
* {@link AutoHardWrapHandler#wrapLineIfNecessary}.
*
* @author Alexander Schwartz
*/
public class AsciiDocLineIndentProvider extends FormatterBasedLineIndentProvider {

@Override
public @Nullable String getLineIndent(@NotNull Project project, @NotNull Editor editor, @Nullable Language language, int offset) {
if (editor.getUserData(AutoHardWrapHandler.AUTO_WRAP_LINE_IN_PROGRESS_KEY) == Boolean.TRUE) {
return LineIndentProvider.DO_NOT_ADJUST;
} else {
return super.getLineIndent(project, editor, language, offset);
}
}

@Override
public boolean isSuitableFor(@Nullable Language language) {
return language == AsciiDocLanguage.INSTANCE;
}
}
2 changes: 2 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
<customPasteProvider implementation="org.asciidoc.intellij.pasteProvider.AsciiDocPasteImageProvider" order="before asciidoc-paste-html-provider"/>
<customPasteProvider implementation="org.asciidoc.intellij.pasteProvider.AsciiDocPasteLinkProvider" order="before asciidoc-paste-html-provider"/>
<customPasteProvider implementation="org.asciidoc.intellij.pasteProvider.AsciiDocPasteHtmlProvider" id="asciidoc-paste-html-provider" />
<lineIndentProvider implementation="org.asciidoc.intellij.formatting.AsciiDocLineIndentProvider" />
<filePasteProvider implementation="org.asciidoc.intellij.pasteProvider.AsciiDocPasteImageProvider" />
<fileType name="AsciiDoc" extensions="adoc;asciidoc;ad" fileNames=".asciidoctorconfig" language="AsciiDoc"
implementationClass="org.asciidoc.intellij.file.AsciiDocFileType" fieldName="INSTANCE"/>
Expand All @@ -221,6 +222,7 @@
<spellchecker.bundledDictionaryProvider implementation="org.asciidoc.intellij.AsciiDocBundledDictionaryProvider" />
<lang.commenter language="AsciiDoc" implementationClass="org.asciidoc.intellij.AsciiDocCommenter"/>
<extendWordSelectionHandler implementation="org.asciidoc.intellij.editor.ExtendWordSelectionHandler"/>
<enterHandlerDelegate implementation="org.asciidoc.intellij.formatting.AsciiDocEnterHandlerDelegate"/>
<braceMatcher filetype="AsciiDoc" implementationClass="org.asciidoc.intellij.braces.AsciiDocBraceMatcher"/>
<quoteHandler fileType="AsciiDoc" className="org.asciidoc.intellij.braces.AsciiDocQuoteHandler"/>
<todoIndexer filetype="AsciiDoc" implementationClass="org.asciidoc.intellij.indexer.AsciiDocTodoIndexer"/>
Expand Down
69 changes: 69 additions & 0 deletions src/test/java/org/asciidoc/intellij/editor/AbstractWrapTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.asciidoc.intellij.editor;

import com.intellij.application.options.CodeStyle;
import com.intellij.openapi.editor.impl.view.FontLayoutService;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
import com.intellij.testFramework.MockFontLayoutService;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.NotNull;

/**
* This copied parts from by com.intellij.codeInsight.wrap.AbstractWrapTest and its base classes.
*
* @author Alexander Schwartz
*/
public abstract class AbstractWrapTest extends LightPlatformCodeInsightTestCase {

@SuppressWarnings("checkstyle:VisibilityModifier")
protected CodeStyleSettings mySettings;

protected void checkWrapOnTyping(@NotNull FileType fileType,
@NotNull String textToType,
@NotNull String initial,
@NotNull String expected) {
String name = "test." + fileType.getDefaultExtension();
configureFromFileText(name, initial);
assertFileTypeResolved(fileType, name);
for (char c : textToType.toCharArray()) {
type(c);
}
checkResultByText(expected);
}

public static final int TEST_CHAR_WIDTH = 10; // char width matches the one in EditorTestUtil.configureSoftWraps
public static final int TEST_LINE_HEIGHT = 10;
public static final int TEST_DESCENT = 2;

@Override
protected void setUp() throws Exception {
super.setUp();
mySettings = CodeStyle.createTestSettings(CodeStyle.getSettings(getProject()));
mySettings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = true;

CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(mySettings);
FontLayoutService.setInstance(new MockFontLayoutService(TEST_CHAR_WIDTH, TEST_LINE_HEIGHT, TEST_DESCENT));
}

@Override
protected void tearDown() throws Exception {
try {
FontLayoutService.setInstance(null);
} catch (Throwable e) {
addSuppressedException(e);
} finally {
super.tearDown();
}
}

protected static void assertFileTypeResolved(@NotNull FileType type, @NotNull String path) {
String name = PathUtil.getFileName(path);
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name);
assertEquals(type + " file type must be in this test classpath, but only " + fileType + " was found by '" +
name + "' file name (with default extension '" + fileType.getDefaultExtension() + "')", type, fileType);
}

}
24 changes: 24 additions & 0 deletions src/test/java/org/asciidoc/intellij/editor/AsciiDocWrapTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.asciidoc.intellij.editor;

import org.asciidoc.intellij.file.AsciiDocFileType;

/**
* Testing auto-wrapping when typing.
*
* @author Alexander Schwartz
*/
public class AsciiDocWrapTest extends AbstractWrapTest {

public void testWrapAfterSpaceOnMargin() {
mySettings.setDefaultRightMargin(10);
// this will wrap three additional characters as it is not a plain text editor.
checkWrapOnTyping(AsciiDocFileType.INSTANCE, "a", "text text <caret>", "text \ntext a<caret>");
}

public void testWrapWithNextLine() {
mySettings.setDefaultRightMargin(20);
// this will wrap three additional characters as it is not a plain text editor. This
checkWrapOnTyping(AsciiDocFileType.INSTANCE, "1234567890", "else <caret>if else if else\nold text", "else 1234567890if \nelse if else\nold text");
}

}

0 comments on commit fa281af

Please sign in to comment.