mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
LineIndentProvider API with a simple example for JavaScript
This commit is contained in:
@@ -484,7 +484,7 @@ public class EnterHandler extends BaseEnterHandler {
|
||||
private int adjustLineIndent(CharSequence docChars) {
|
||||
int indentStart = CharArrayUtil.shiftBackwardUntil(docChars, myOffset - 1, "\n") + 1;
|
||||
int indentEnd = CharArrayUtil.shiftForward(docChars, indentStart, " \t");
|
||||
String newIndent = CodeStyleFacade.getInstance(getProject()).getLineIndent(myDocument, myOffset);
|
||||
String newIndent = CodeStyleFacade.getInstance(getProject()).getLineIndent(myEditor, myDocument, myOffset);
|
||||
if (newIndent == null) return myOffset;
|
||||
int delta = newIndent.length() - (indentEnd - indentStart);
|
||||
myDocument.replaceString(indentStart, indentEnd, newIndent);
|
||||
|
||||
+12
@@ -22,10 +22,12 @@ package com.intellij.psi.impl.source.codeStyle;
|
||||
import com.intellij.codeStyle.CodeStyleFacade;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -49,12 +51,22 @@ public class CodeStyleFacadeImpl extends CodeStyleFacade {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public String getLineIndent(@NotNull final Document document, int offset) {
|
||||
if (myProject == null) return null;
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(document);
|
||||
return CodeStyleManager.getInstance(myProject).getLineIndent(document, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLineIndent(@NotNull Editor editor, @NotNull Document document, int offset) {
|
||||
if (myProject == null) return null;
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
|
||||
PsiFile file = documentManager.getPsiFile(document);
|
||||
LineIndentProvider lineIndentProvider = LineIndentProviderEP.findLineIndentProvider(file);
|
||||
return lineIndentProvider != null ? lineIndentProvider.getLineIndent(myProject, editor, document, offset) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLineSeparator() {
|
||||
return CodeStyleSettingsManager.getSettings(myProject).getLineSeparator();
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.codeStyle;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Formatter-based line indent provider which calculates indent using formatting model.
|
||||
*/
|
||||
public class FormatterBasedLineIndentProvider implements LineIndentProvider {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getLineIndent(@NotNull Project project, @NotNull Editor editor, @NotNull Document document, int offset) {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document);
|
||||
return CodeStyleManager.getInstance(project).getLineIndent(document, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuitableFor(@Nullable PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.codeStyle;
|
||||
|
||||
import com.intellij.formatting.Indent;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A base class Java-like language line indent provider. If JavaLikeLangLineIndentProvider is unable to calculate
|
||||
* the indentation, it forwards the request to FormatterBasedLineIndentProvider.
|
||||
*/
|
||||
public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineIndentProvider {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getLineIndent(@NotNull Project project, @NotNull Editor editor, @NotNull Document document, int offset) {
|
||||
Indent.Type indent = getIndent(editor, document, offset);
|
||||
if (indent == Indent.Type.NONE) return null;
|
||||
return super.getLineIndent(project, editor, document, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isSuitableFor(@Nullable PsiFile file) {
|
||||
if (file != null) {
|
||||
return isSuitableForLanguage(file.getLanguage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract boolean isSuitableForLanguage(@NotNull Language language);
|
||||
|
||||
@Nullable
|
||||
protected Indent.Type getIndent(@NotNull Editor editor, @NotNull Document document, int offset) {
|
||||
CharSequence docChars = document.getCharsSequence();
|
||||
EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter();
|
||||
HighlighterIterator iterator = highlighter.createIterator(offset - 1);
|
||||
if (isWhitespace(iterator.getTokenType())) {
|
||||
if (containsLineBreaks(iterator, docChars)) {
|
||||
iterator.retreat();
|
||||
if (!iterator.atEnd()) {
|
||||
if (isEndOfCodeBlock(iterator)) return Indent.Type.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract boolean isWhitespace(@NotNull IElementType tokenType);
|
||||
|
||||
private static boolean containsLineBreaks(@NotNull HighlighterIterator iterator, @NotNull CharSequence chars) {
|
||||
return CharArrayUtil.containLineBreaks(chars, iterator.getStart(), iterator.getEnd());
|
||||
}
|
||||
|
||||
protected boolean isEndOfCodeBlock(@NotNull HighlighterIterator iterator) {
|
||||
if (isSemicolon(iterator.getTokenType())) iterator.retreat();
|
||||
if (!iterator.atEnd()) {
|
||||
if (isWhitespace(iterator.getTokenType())) iterator.retreat();
|
||||
if (!iterator.atEnd()) {
|
||||
return isBlockClosingBrace(iterator.getTokenType());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract boolean isSemicolon(@NotNull IElementType tokenType);
|
||||
|
||||
protected abstract boolean isBlockClosingBrace(@NotNull IElementType tokenType);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.codeStyle;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An interface for indentation calculation. Used in editor actions like Enter handling.
|
||||
*/
|
||||
public interface LineIndentProvider {
|
||||
|
||||
/**
|
||||
* Calculates the indent that should be used for the line at specified offset in the specified
|
||||
* document.
|
||||
*
|
||||
* @param project The current project.
|
||||
* @param editor The current editor.
|
||||
* @param document The document for which the indent should be calculated.
|
||||
* @param offset The caret offset in the editor.
|
||||
* @return The indent string (possibly consisting of tabs and/or white spaces), or null if
|
||||
* LineIndentProvider can't calculate the indent (in this case no indent adjustment will be made).
|
||||
*/
|
||||
@Nullable
|
||||
String getLineIndent(@NotNull Project project, @NotNull Editor editor, @NotNull Document document, int offset);
|
||||
|
||||
boolean isSuitableFor(@Nullable PsiFile file);
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.codeStyle;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Line indent provider extension point
|
||||
*/
|
||||
public class LineIndentProviderEP {
|
||||
public final static ExtensionPointName<LineIndentProvider> EP_NAME = ExtensionPointName.create("com.intellij.lineIndentProvider");
|
||||
|
||||
@Nullable
|
||||
public static LineIndentProvider findLineIndentProvider(@Nullable PsiFile psiFile) {
|
||||
LineIndentProvider foundProvider = null;
|
||||
for (LineIndentProvider provider : EP_NAME.getExtensions()) {
|
||||
if (foundProvider == null || provider.isSuitableFor(psiFile) && foundProvider.getClass().isInstance(provider)) {
|
||||
foundProvider = provider;
|
||||
}
|
||||
}
|
||||
return foundProvider;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ package com.intellij.codeStyle;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -46,9 +47,26 @@ public abstract class CodeStyleFacade {
|
||||
* @param offset the caret offset in the editor.
|
||||
* @return the indent string (containing of tabs and/or white spaces), or null if it
|
||||
* was not possible to calculate the indent.
|
||||
* @deprecated Use {@link #getLineIndent(Editor, Document, int)} instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public abstract String getLineIndent(@NotNull Document document, int offset);
|
||||
|
||||
/**
|
||||
* Calculates the indent that should be used for the line at specified offset in the specified
|
||||
* document.
|
||||
*
|
||||
* @param editor the editor for which the indent must be returned.
|
||||
* @param document the document for which the indent should be calculated.
|
||||
* @param offset the caret offset in the editor.
|
||||
* @return the indent string (containing of tabs and/or white spaces), or null if it
|
||||
* was not possible to calculate the indent.
|
||||
*/
|
||||
public String getLineIndent(@NotNull Editor editor, @NotNull Document document, int offset) {
|
||||
//noinspection deprecation
|
||||
return getLineIndent(document, offset);
|
||||
}
|
||||
|
||||
public abstract int getIndentSize(FileType fileType);
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@
|
||||
<extensionPoint name="preFormatProcessor" interface="com.intellij.psi.impl.source.codeStyle.PreFormatProcessor"/>
|
||||
<extensionPoint name="postFormatProcessor" interface="com.intellij.psi.impl.source.codeStyle.PostFormatProcessor"/>
|
||||
<extensionPoint name="disabledIndentRangesProvider" interface="com.intellij.psi.impl.source.DisabledIndentRangesProvider"/>
|
||||
<extensionPoint name="lineIndentProvider" interface="com.intellij.psi.impl.source.codeStyle.LineIndentProvider"/>
|
||||
|
||||
<extensionPoint name="declarationRangeHandler" beanClass="com.intellij.util.MixinEP">
|
||||
<with attribute="implementationClass" implements="com.intellij.codeInsight.hint.DeclarationRangeHandler"/>
|
||||
|
||||
@@ -953,6 +953,7 @@
|
||||
|
||||
<nonProjectFileWritingAccessExtension implementation="com.intellij.ide.actions.EditCustomPropertiesAction$AccessExtension"/>
|
||||
<nonProjectFileWritingAccessExtension implementation="com.intellij.ide.actions.EditCustomVmOptionsAction$AccessExtension"/>
|
||||
<lineIndentProvider implementation="com.intellij.psi.impl.source.codeStyle.FormatterBasedLineIndentProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user