From fb730d25fc2151766578ea2356f951abd69efead Mon Sep 17 00:00:00 2001 From: azerr Date: Fri, 28 Oct 2022 12:35:33 +0200 Subject: [PATCH] On enter rule don't use the proper insert spaces / tab width when those settings are changed Fixes #460 Signed-off-by: azerr --- ...LanguageConfigurationAutoEditStrategy.java | 80 +++++++++++++------ .../internal/utils/TextUtils.java | 21 +---- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/LanguageConfigurationAutoEditStrategy.java b/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/LanguageConfigurationAutoEditStrategy.java index 35ee25d41..0a46a18aa 100644 --- a/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/LanguageConfigurationAutoEditStrategy.java +++ b/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/LanguageConfigurationAutoEditStrategy.java @@ -16,6 +16,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy; import org.eclipse.jface.text.DocumentCommand; @@ -25,7 +26,6 @@ import org.eclipse.tm4e.core.model.TMToken; import org.eclipse.tm4e.languageconfiguration.internal.model.AutoClosingPairConditional; import org.eclipse.tm4e.languageconfiguration.internal.registry.LanguageConfigurationRegistryManager; -import org.eclipse.tm4e.languageconfiguration.internal.utils.TabSpacesInfo; import org.eclipse.tm4e.languageconfiguration.internal.utils.TextUtils; import org.eclipse.tm4e.ui.internal.model.TMModelManager; import org.eclipse.tm4e.ui.internal.utils.ContentTypeHelper; @@ -33,11 +33,16 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; +import org.eclipse.ui.texteditor.ITextEditor; +// import org.eclipse.ui.texteditor.ITextEditorAware; +import org.eclipse.ui.texteditor.ITextEditorAware; /** * {@link IAutoEditStrategy} which uses VSCode language-configuration.json. */ -public class LanguageConfigurationAutoEditStrategy implements IAutoEditStrategy { +public class LanguageConfigurationAutoEditStrategy implements IAutoEditStrategy, ITextEditorAware { @Nullable private IDocument document; @@ -45,10 +50,15 @@ public class LanguageConfigurationAutoEditStrategy implements IAutoEditStrategy private IContentType @Nullable [] contentTypes; @Nullable - private TabSpacesInfo tabSpacesInfo; + private ITextViewer viewer; @Nullable - private ITextViewer viewer; + private ITextEditor editor; + + @Override + public void setEditor(ITextEditor editor) { + this.editor = editor; + } @Override public void customizeDocumentCommand(@Nullable final IDocument document, @Nullable final DocumentCommand command) { @@ -63,7 +73,7 @@ public void customizeDocumentCommand(@Nullable final IDocument document, @Nullab if (TextUtils.isEnter(document, command)) { // key enter pressed - onEnter(document, command); + onEnter(document, command, editor); return; } @@ -178,7 +188,7 @@ private static boolean isFollowedBy(final IDocument document, int offset, final return true; } - private void onEnter(final IDocument document, final DocumentCommand command) { + private void onEnter(final IDocument document, final DocumentCommand command, ITextEditor editor) { final var registry = LanguageConfigurationRegistryManager.getInstance(); if (contentTypes != null) { for (final IContentType contentType : contentTypes) { @@ -192,7 +202,8 @@ private void onEnter(final IDocument document, final DocumentCommand command) { switch (enterAction.indentAction) { case None: { // Nothing special - final String increasedIndent = normalizeIndentation(enterAction.indentation + enterAction.appendText); + final String increasedIndent = normalizeIndentation( + enterAction.indentation + enterAction.appendText); final String typeText = delim + increasedIndent; command.text = typeText; @@ -202,7 +213,8 @@ private void onEnter(final IDocument document, final DocumentCommand command) { } case Indent: { // Indent once - final String increasedIndent = normalizeIndentation(enterAction.indentation + enterAction.appendText); + final String increasedIndent = normalizeIndentation( + enterAction.indentation + enterAction.appendText); final String typeText = delim + increasedIndent; command.text = typeText; @@ -213,7 +225,8 @@ private void onEnter(final IDocument document, final DocumentCommand command) { case IndentOutdent: { // Ultra special final String normalIndent = normalizeIndentation(enterAction.indentation); - final String increasedIndent = normalizeIndentation(enterAction.indentation + enterAction.appendText); + final String increasedIndent = normalizeIndentation( + enterAction.indentation + enterAction.appendText); final String typeText = delim + increasedIndent + delim + normalIndent; command.text = typeText; @@ -223,7 +236,7 @@ private void onEnter(final IDocument document, final DocumentCommand command) { } case Outdent: final String indentation = TextUtils.getIndentationFromWhitespace(enterAction.indentation, - getTabSpaces()); + getTabSize(), isInsertSpaces()); final String outdentedText = outdentString( normalizeIndentation(indentation + enterAction.appendText)); @@ -259,9 +272,9 @@ private String outdentString(final String str) { if (str.startsWith("\t")) {//$NON-NLS-1$ return str.substring(1); } - final TabSpacesInfo tabSpaces = getTabSpaces(); - if (tabSpaces.isInsertSpaces()) { - final char[] chars = new char[tabSpaces.getTabSize()]; + boolean insertSpaces = isInsertSpaces(); + if (isInsertSpaces()) { + final char[] chars = new char[getTabSize()]; Arrays.fill(chars, ' '); final String spaces = new String(chars); if (str.startsWith(spaces)) { @@ -272,26 +285,41 @@ private String outdentString(final String str) { } private String normalizeIndentation(final String str) { - final TabSpacesInfo tabSpaces = getTabSpaces(); - return TextUtils.normalizeIndentation(str, tabSpaces.getTabSize(), tabSpaces.isInsertSpaces()); + int tabSize = getTabSize(); + boolean insertSpaces = isInsertSpaces(); + return TextUtils.normalizeIndentation(str, tabSize, insertSpaces); } - private TabSpacesInfo getTabSpaces() { - // For performance reason, tab spaces info are cached. - // If user change preferences (tab size, insert spaces), he must close the editor - // FIXME : how to detect changes of (tab size, insert spaces) with a generic mean? - if (tabSpacesInfo != null) { - return tabSpacesInfo; + private int getTabSize() { + String name = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH; + return getPreferenceStoreFor(name).getInt(name); + } + + private boolean isInsertSpaces() { + String name = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS; + return getPreferenceStoreFor(name).getBoolean(name); + } + + private IPreferenceStore getPreferenceStoreFor(String name) { + IPreferenceStore editorPreferenceStore = editor != null ? editor.getAdapter(IPreferenceStore.class) : null; + if (editorPreferenceStore != null && editorPreferenceStore.contains(name)) { + return editorPreferenceStore; } - tabSpacesInfo = TextUtils.getTabSpaces(viewer); - return tabSpacesInfo; + return EditorsUI.getPreferenceStore(); } private void installViewer() { if (viewer == null) { - final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - final IEditorPart editorPart = page.getActiveEditor(); - viewer = editorPart.getAdapter(ITextViewer.class); + IEditorPart editorPart = null; + if (editor != null) { + editorPart = editor; + } else { + final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + editorPart = page.getActiveEditor(); + } + if (editorPart != null) { + viewer = editorPart.getAdapter(ITextViewer.class); + } } } } diff --git a/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/utils/TextUtils.java b/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/utils/TextUtils.java index 7d05514c0..0022e11b3 100644 --- a/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/utils/TextUtils.java +++ b/org.eclipse.tm4e.languageconfiguration/src/main/java/org/eclipse/tm4e/languageconfiguration/internal/utils/TextUtils.java @@ -105,17 +105,17 @@ private static int firstNonWhitespaceIndex(final String str) { return -1; } - public static String getIndentationFromWhitespace(final String whitespace, final TabSpacesInfo tabSpaces) { + public static String getIndentationFromWhitespace(final String whitespace, final int tabSize, boolean insertSpaces) { final var tab = "\t"; //$NON-NLS-1$ int indentOffset = 0; boolean startsWithTab = true; boolean startsWithSpaces = true; - final String spaces = tabSpaces.isInsertSpaces() - ? " ".repeat(tabSpaces.getTabSize()) + final String spaces = insertSpaces + ? " ".repeat(tabSize) : ""; while (startsWithTab || startsWithSpaces) { startsWithTab = whitespace.startsWith(tab, indentOffset); - startsWithSpaces = tabSpaces.isInsertSpaces() && whitespace.startsWith(spaces, indentOffset); + startsWithSpaces = insertSpaces && whitespace.startsWith(spaces, indentOffset); if (startsWithTab) { indentOffset += tab.length(); } @@ -170,19 +170,6 @@ private static int findEndOfWhiteSpace(final IDocument document, int offset, fin return end; } - public static TabSpacesInfo getTabSpaces(@Nullable final ITextViewer viewer) { - if (viewer != null) { - final TabsToSpacesConverter converter = ClassHelper.getFieldValue(viewer, "fTabsToSpacesConverter", //$NON-NLS-1$ - TextViewer.class); - if (converter != null) { - @SuppressWarnings("null") - final int tabSize = ClassHelper.getFieldValue(converter, "fTabRatio", TabsToSpacesConverter.class); //$NON-NLS-1$ - return new TabSpacesInfo(tabSize, true); - } - } - return new TabSpacesInfo(4, false); - } - /** * Determines if all the characters at any offset of the specified document range are space or tab characters. *