Skip to content

Commit

Permalink
On enter rule don't use the proper insert spaces / tab width when those
Browse files Browse the repository at this point in the history
settings are changed

Fixes eclipse-tm4e#460

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Oct 28, 2022
1 parent cb5f472 commit fb730d2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,30 +26,39 @@
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;
import org.eclipse.tm4e.ui.internal.utils.ContentTypeInfo;
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;

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) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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));

Expand Down Expand Up @@ -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)) {
Expand All @@ -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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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.
*
Expand Down

0 comments on commit fb730d2

Please sign in to comment.