Skip to content

Commit

Permalink
feat: parse and display indentation rules
Browse files Browse the repository at this point in the history
  • Loading branch information
sebthom committed Jan 29, 2024
1 parent ed0a861 commit 8a3ca98
Show file tree
Hide file tree
Showing 10 changed files with 379 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public final class LanguageConfigurationMessages extends NLS {
public static String LanguageConfigurationInfoWidget_comments_title;
public static String LanguageConfigurationInfoWidget_end;
public static String LanguageConfigurationInfoWidget_folding_title;
public static String LanguageConfigurationInfoWidget_indentationRules_title;
public static String LanguageConfigurationInfoWidget_indentationRules_decreaseIndentPattern;
public static String LanguageConfigurationInfoWidget_indentationRules_increaseIndentPattern;
public static String LanguageConfigurationInfoWidget_indentationRules_indentNextLinePattern;
public static String LanguageConfigurationInfoWidget_indentationRules_unIndentedLinePattern;
public static String LanguageConfigurationInfoWidget_lineComments;
public static String LanguageConfigurationInfoWidget_markers;
public static String LanguageConfigurationInfoWidget_offSide;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ LanguageConfigurationInfoWidget_brackets_title=Brackets
LanguageConfigurationInfoWidget_comments_title=Comments
LanguageConfigurationInfoWidget_end=End:
LanguageConfigurationInfoWidget_folding_title=Folding
LanguageConfigurationInfoWidget_indentationRules_title=Indentation Rules
LanguageConfigurationInfoWidget_indentationRules_decreaseIndentPattern=Decrease Indent Pattern:
LanguageConfigurationInfoWidget_indentationRules_increaseIndentPattern=Increase Indent Pattern:
LanguageConfigurationInfoWidget_indentationRules_indentNextLinePattern=Indent Next Line Pattern:
LanguageConfigurationInfoWidget_indentationRules_unIndentedLinePattern=Unindented Next Line Pattern:
LanguageConfigurationInfoWidget_lineComments=Line Comment:
LanguageConfigurationInfoWidget_markers=markers
LanguageConfigurationInfoWidget_offSide=Off Side:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2024 Vegard IT GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Initial code from https://github.com/microsoft/vscode/
* Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
* Initial license: MIT
*
* Contributors:
* - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
* - Sebastian Thomschke - translation and adaptation to Java
*/
package org.eclipse.tm4e.languageconfiguration.internal.model;

import org.eclipse.tm4e.core.internal.utils.StringUtils;

/**
* Describes indentation rules for a language.
*
* @see <a href=
* "https://github.com/microsoft/vscode/blob/8e2ec5a7ee1ae5500c645c05145359f2a814611c/src/vs/editor/common/languages/autoIndent.ts#L278">
* github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/autoIndent.ts#L278</a>
*/
public class IndentForEnter {

public final String beforeEnter;
public final String afterEnter;

public IndentForEnter(final String beforeEnter, final String afterEnter) {
this.beforeEnter = beforeEnter;
this.afterEnter = afterEnter;
}

@Override
public String toString() {
return StringUtils.toString(this, sb -> sb
.append("beforeEnter=").append(beforeEnter).append(", ")
.append("afterEnter=").append(afterEnter));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2024 Vegard IT GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Initial code from https://github.com/microsoft/vscode/
* Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
* Initial license: MIT
*
* Contributors:
* - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
* - Sebastian Thomschke - translation and adaptation to Java
*/
package org.eclipse.tm4e.languageconfiguration.internal.model;

import org.eclipse.jdt.annotation.Nullable;

/**
* Describes indentation rules for a language.
*
* @see <a href=
* "https://github.com/microsoft/vscode/blob/8e2ec5a7ee1ae5500c645c05145359f2a814611c/src/vs/editor/common/languages/languageConfiguration.ts#L105">
* github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/languageConfiguration.ts#L105</a>
*/
public class IndentationRules {

/**
* If a line matches this pattern, then all the lines after it should be unindented once (until another rule matches).
*/
public final RegExPattern decreaseIndentPattern;

/**
* If a line matches this pattern, then all the lines after it should be indented once (until another rule matches).
*/
public final RegExPattern increaseIndentPattern;

/**
* If a line matches this pattern, then **only the next line** after it should be indented once.
*/
public final @Nullable RegExPattern indentNextLinePattern;

/**
* If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules.
*/
public final @Nullable RegExPattern unIndentedLinePattern;

public IndentationRules(final RegExPattern decreaseIndentPattern, final RegExPattern increaseIndentPattern,
final @Nullable RegExPattern indentNextLinePattern, final @Nullable RegExPattern unIndentedLinePattern) {
this.decreaseIndentPattern = decreaseIndentPattern;
this.increaseIndentPattern = increaseIndentPattern;
this.indentNextLinePattern = indentNextLinePattern;
this.unIndentedLinePattern = unIndentedLinePattern;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
* Contributors:
* Lucas Bullen (Red Hat Inc.) - initial API and implementation
* Sebastian Thomschke (Vegard IT) - improve JSON parsing tolerance
* Sebastian Thomschke (Vegard IT) - improve JSON parsing tolerance, add indentation rules parsing
*/
package org.eclipse.tm4e.languageconfiguration.internal.model;

Expand Down Expand Up @@ -38,6 +38,8 @@
* automatic bracket insertion, automatic indentation etc.
*
* @see <a href=
* "https://code.visualstudio.com/api/language-extensions/language-configuration-guide">code.visualstudio.com/api/language-extensions/language-configuration-guide</a>
* @see <a href=
* "https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/languageConfiguration.ts">
* github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/languageConfiguration.ts</a>
*/
Expand Down Expand Up @@ -178,7 +180,7 @@ private static String removeTrailingCommas(String jsonString) {
open = getAsString(charsPair.get(0));
close = getAsString(charsPair.get(1));
} else if (json.isJsonObject()) {
// ex: {"open":"'","close":"'", "notIn": ["string", "comment"]}
// ex: {"open":"'","close":"'"}
final var autoClosePair = json.getAsJsonObject();
open = getAsString(autoClosePair.get("open")); //$NON-NLS-1$
close = getAsString(autoClosePair.get("close")); //$NON-NLS-1$
Expand Down Expand Up @@ -242,6 +244,26 @@ private static String removeTrailingCommas(String jsonString) {
}
return null;
})

.registerTypeAdapter(IndentationRules.class, (JsonDeserializer<IndentationRules>) (json, typeT, context) -> {
if (!json.isJsonObject()) {
return null;
}

final var jsonObj = json.getAsJsonObject();
final var decreaseIndentPattern = getAsPattern(jsonObj.get("decreaseIndentPattern"));
if (decreaseIndentPattern == null)
return null;
final var increaseIndentPattern = getAsPattern(jsonObj.get("increaseIndentPattern"));
if (increaseIndentPattern == null)
return null;

return new IndentationRules(
decreaseIndentPattern,
increaseIndentPattern,
getAsPattern(jsonObj.get("indentNextLinePattern")),
getAsPattern(jsonObj.get("unIndentedLinePattern")));
})
.create()
.fromJson(jsonString, LanguageConfiguration.class);

Expand Down Expand Up @@ -354,7 +376,14 @@ public List<CharacterPair> getBrackets() {
return wordPattern;
}

// TODO @Nullable IndentionRule getIndentionRules();
private @Nullable IndentationRules indentationRules;

/**
* The language's indentation settings.
*/
public @Nullable IndentationRules getIndentationRules() {
return indentationRules;
}

private List<OnEnterRule> onEnterRules = lazyNonNull();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.tm4e.languageconfiguration.internal.model.LanguageConfiguration;
import org.eclipse.tm4e.languageconfiguration.internal.supports.CharacterPairSupport;
import org.eclipse.tm4e.languageconfiguration.internal.supports.CommentSupport;
import org.eclipse.tm4e.languageconfiguration.internal.supports.IndentRulesSupport;
import org.eclipse.tm4e.languageconfiguration.internal.supports.OnEnterSupport;
import org.eclipse.tm4e.registry.TMResource;
import org.eclipse.tm4e.registry.XMLConstants;
Expand All @@ -42,6 +43,7 @@ public final class LanguageConfigurationDefinition extends TMResource implements

private @Nullable CharacterPairSupport characterPair;
private @Nullable OnEnterSupport onEnter;
private @Nullable IndentRulesSupport indentRules;
private @Nullable CommentSupport comment;

public LanguageConfigurationDefinition(final IContentType contentType, final String path) {
Expand Down Expand Up @@ -106,6 +108,21 @@ OnEnterSupport getOnEnter() {
return onEnter;
}

@Nullable
IndentRulesSupport getIndentRules() {
if (this.indentRules == null) {
final LanguageConfiguration conf = getLanguageConfiguration();
if (conf == null)
return null;

var indentRules = conf.getIndentationRules();
if (indentRules != null) {
this.indentRules = new IndentRulesSupport(indentRules);
}
}
return indentRules;
}

/**
* Returns the "comment" support and null otherwise.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Copyright (c) 2024 Vegard IT GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Initial code from https://github.com/microsoft/vscode/
* Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
* Initial license: MIT
*
* Contributors:
* - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
* - Sebastian Thomschke - translation and adaptation to Java
*/
package org.eclipse.tm4e.languageconfiguration.internal.supports;

import org.eclipse.tm4e.languageconfiguration.internal.model.IndentationRules;

/**
* @see <a href=
* "https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/supports/indentRules.ts">
* github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/supports/indentRules.ts</a>
*/
public class IndentRulesSupport {

public static final class IndentConsts {
public static final int INCREASE_MASK = 0b00000001;
public static final int DECREASE_MASK = 0b00000010;
public static final int INDENT_NEXTLINE_MASK = 0b00000100;
public static final int UNINDENT_MASK = 0b00001000;
}

private final IndentationRules _indentationRules;

public IndentRulesSupport(IndentationRules indentationRules) {
this._indentationRules = indentationRules;
}

public boolean shouldIncrease(final String text) {
return _indentationRules.increaseIndentPattern.matchesFully(text);

// if (this._indentationRules.indentNextLinePattern && this._indentationRules.indentNextLinePattern.test(text)) {
// return true;
// }
}

public boolean shouldDecrease(final String text) {
return _indentationRules.decreaseIndentPattern.matchesFully(text);
}

public boolean shouldIndentNextLine(final String text) {
return this._indentationRules.indentNextLinePattern != null && this._indentationRules.indentNextLinePattern.matchesFully(text);
}

public boolean shouldIgnore(final String text) {
// the text matches `unIndentedLinePattern`
return this._indentationRules.unIndentedLinePattern != null && this._indentationRules.unIndentedLinePattern.matchesFully(text);
}

public int getIndentMetadata(final String text) {
int ret = 0;
if (this.shouldIncrease(text)) {
ret += IndentConsts.INCREASE_MASK;
}
if (this.shouldDecrease(text)) {
ret += IndentConsts.DECREASE_MASK;
}
if (this.shouldIndentNextLine(text)) {
ret += IndentConsts.INDENT_NEXTLINE_MASK;
}
if (this.shouldIgnore(text)) {
ret += IndentConsts.UNINDENT_MASK;
}
return ret;
}
}
Loading

0 comments on commit 8a3ca98

Please sign in to comment.