injections support for Emmet edit point searching (WEB-362)

This commit is contained in:
Dennis Ushakov
2015-01-20 20:26:38 +03:00
parent f27bc7bc6f
commit 5f5c7e5538
@@ -15,12 +15,15 @@
*/
package com.intellij.codeInsight.template.emmet.actions;
import com.intellij.lang.Language;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlText;
@@ -31,26 +34,20 @@ import com.intellij.psi.xml.XmlTokenType;
*/
public class EmmetEditPointUtil {
public static void moveForward(Editor editor, PsiFile file) {
int offset = editor.getCaretModel().getOffset();
PsiElement element = file.findElementAt(offset);
if (element == null || !element.getLanguage().isKindOf(XMLLanguage.INSTANCE)) return;
moveToNextPoint(editor, file, offset, 1);
if (!isApplicableFile(file)) return;
moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), 1);
}
public static void moveBackward(Editor editor, PsiFile file) {
final int offset = editor.getCaretModel().getOffset();
PsiElement element = file.findElementAt(offset);
element = element == null ? file.findElementAt(offset - 1) : element;
if (element == null || !element.getLanguage().isKindOf(XMLLanguage.INSTANCE)) return;
moveToNextPoint(editor, file, offset, -1);
if (!isApplicableFile(file)) return;
moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), -1);
}
private static void moveToNextPoint(Editor editor, PsiFile file, int offset, int inc) {
final Document doc = editor.getDocument();
PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc);
for (int i = offset + inc; i < doc.getTextLength() && i >= 0; i += inc) {
PsiElement current = file.findElementAt(i);
PsiElement current = InjectedLanguageUtil.findElementAtNoCommit(file, i);
if (current == null) continue;
if (current.getParent() instanceof XmlText) {
@@ -60,20 +57,22 @@ public class EmmetEditPointUtil {
if (lineEnd == offset) continue;
final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd);
if (StringUtil.isEmptyOrSpaces(text)) {
editor.getCaretModel().moveToOffset(lineEnd);
if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) {
return;
}
} else if (isEmptyEditPoint(current)) {
final int elementStart = current.getTextRange().getStartOffset();
if (elementStart == offset) continue;
editor.getCaretModel().moveToOffset(elementStart);
} else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) {
return;
}
}
}
private static boolean moveCaret(Editor editor, PsiElement current, int offset) {
editor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, current.getContainingFile());
if (editor.getCaretModel().getOffset() == offset) return false;
editor.getCaretModel().moveToOffset(offset);
return true;
}
private static boolean isEmptyEditPoint(PsiElement element) {
final IElementType type = element.getNode().getElementType();
if (type == XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER) {
@@ -86,4 +85,11 @@ public class EmmetEditPointUtil {
}
return false;
}
static boolean isApplicableFile(PsiFile file) {
for (Language language : file.getViewProvider().getLanguages()) {
if (language.isKindOf(XMLLanguage.INSTANCE)) return true;
}
return false;
}
}