1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-07-30 09:59:08 +02:00

Merge branch 'matching-comments'

This commit is contained in:
Andrey Vlasovskikh 2015-04-24 16:08:54 +03:00
commit ae5b1385ea
4 changed files with 141 additions and 3 deletions
src/com/maddyhome/idea/vim/helper
test/org/jetbrains/plugins/ideavim

View File

@ -109,7 +109,7 @@ public class PsiHelper {
}
@Nullable
private static PsiFile getFile(@NotNull Editor editor) {
public static PsiFile getFile(@NotNull Editor editor) {
VirtualFile vf = EditorData.getVirtualFile(editor);
if (vf != null) {
Project proj = editor.getProject();

View File

@ -18,9 +18,14 @@
package com.maddyhome.idea.vim.helper;
import com.intellij.lang.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.*;
import com.maddyhome.idea.vim.common.TextRange;
import com.maddyhome.idea.vim.option.ListOption;
import com.maddyhome.idea.vim.option.OptionChangeEvent;
@ -143,6 +148,42 @@ public class SearchHelper {
return new TextRange(bstart, bend);
}
private static int findMatchingBlockCommentPair(@NotNull PsiComment comment, int pos, @Nullable String prefix,
@Nullable String suffix) {
if (prefix != null && suffix != null) {
final String commentText = comment.getText();
if (commentText.startsWith(prefix) && commentText.endsWith(suffix)) {
final int endOffset = comment.getTextOffset() + comment.getTextLength();
if (pos < comment.getTextOffset() + prefix.length()) {
return endOffset;
}
else if (pos >= endOffset - suffix.length()) {
return comment.getTextOffset();
}
}
}
return -1;
}
private static int findMatchingBlockCommentPair(@NotNull PsiElement element, int pos) {
final Language language = PsiUtil.findLanguageFromElement(element);
final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(language);
final PsiComment comment = PsiTreeUtil.getParentOfType(element, PsiComment.class, false);
if (comment != null) {
final int ret = findMatchingBlockCommentPair(comment, pos, commenter.getBlockCommentPrefix(),
commenter.getBlockCommentSuffix());
if (ret >= 0) {
return ret;
}
if (commenter instanceof CodeDocumentationAwareCommenter) {
final CodeDocumentationAwareCommenter docCommenter = (CodeDocumentationAwareCommenter)commenter;
return findMatchingBlockCommentPair(comment, pos, docCommenter.getDocumentationCommentPrefix(),
docCommenter.getDocumentationCommentSuffix());
}
}
return -1;
}
/**
* This looks on the current line, starting at the cursor position for one of {, }, (, ), [, or ]. It then searches
* forward or backward, as appropriate for the associated match pair. String in double quotes are skipped over.
@ -153,10 +194,16 @@ public class SearchHelper {
* were found on the remainder of the current line.
*/
public static int findMatchingPairOnCurrentLine(@NotNull Editor editor) {
int pos = editor.getCaretModel().getOffset();
final int commentPos = findMatchingComment(editor, pos);
if (commentPos >= 0) {
return commentPos;
}
int line = editor.getCaretModel().getLogicalPosition().line;
int end = EditorHelper.getLineEndOffset(editor, line, true);
CharSequence chars = editor.getDocument().getCharsSequence();
int pos = editor.getCaretModel().getOffset();
int loc = -1;
// Search the remainder of the current line for one of the candidate characters
while (pos < end) {
@ -182,6 +229,20 @@ public class SearchHelper {
return res;
}
/**
* If on the start/end of a block comment, jump to the matching of that comment, or vice versa.
*/
private static int findMatchingComment(@NotNull Editor editor, int pos) {
final PsiFile psiFile = PsiHelper.getFile(editor);
if (psiFile != null) {
final PsiElement element = psiFile.findElementAt(pos);
if (element != null) {
return findMatchingBlockCommentPair(element, pos);
}
}
return -1;
}
private static int findBlockLocation(@NotNull CharSequence chars, char found, char match, int dir, int pos, int cnt) {
int res = -1;
final int inCheckPos = dir < 0 && pos > 0 ? pos - 1 : pos;
@ -235,7 +296,7 @@ public class SearchHelper {
private final int value;
private Direction(int i) {
Direction(int i) {
value = i;
}

View File

@ -1,6 +1,7 @@
package org.jetbrains.plugins.ideavim;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
@ -92,6 +93,12 @@ public abstract class VimTestCase extends UsefulTestCase {
return myFixture.getEditor();
}
@NotNull
protected Editor configureByXmlText(@NotNull String content) {
myFixture.configureByText(XmlFileType.INSTANCE, content);
return myFixture.getEditor();
}
@NotNull
protected Editor typeText(@NotNull final List<KeyStroke> keys) {
final Editor editor = myFixture.getEditor();

View File

@ -426,6 +426,76 @@ public class MotionActionTest extends VimTestCase {
assertOffset(3);
}
// |%|
public void testPercentMatchXmlCommentStart() {
configureByXmlText("<caret><!-- foo -->");
typeText(parseKeys("%"));
myFixture.checkResult("<!-- foo --<caret>>");
}
// |%|
public void testPercentDoesntMatchPartialXmlComment() {
configureByXmlText("<!<caret>-- ");
typeText(parseKeys("%"));
myFixture.checkResult("<!<caret>-- ");
}
// |%|
public void testPercentMatchXmlCommentEnd() {
configureByXmlText("<!-- foo --<caret>>");
typeText(parseKeys("%"));
myFixture.checkResult("<caret><!-- foo -->");
}
// |%|
public void testPercentMatchJavaCommentStart() {
configureByJavaText("/<caret>* foo */");
typeText(parseKeys("%"));
myFixture.checkResult("/* foo *<caret>/");
}
// |%|
public void testPercentDoesntMatchPartialJavaComment() {
configureByJavaText("<caret>/* ");
typeText(parseKeys("%"));
myFixture.checkResult("<caret>/* ");
}
// |%|
public void testPercentMatchJavaCommentEnd() {
configureByJavaText("/* foo <caret>*/");
typeText(parseKeys("%"));
myFixture.checkResult("<caret>/* foo */");
}
// |%|
public void testPercentMatchJavaDocCommentStart() {
configureByJavaText("/*<caret>* foo */");
typeText(parseKeys("%"));
myFixture.checkResult("/** foo *<caret>/");
}
// |%|
public void testPercentMatchJavaDocCommentEnd() {
configureByJavaText("/** foo *<caret>/");
typeText(parseKeys("%"));
myFixture.checkResult("<caret>/** foo */");
}
// |%|
public void testPercentDoesntMatchAfterCommentStart() {
configureByJavaText("/*<caret> foo */");
typeText(parseKeys("%"));
myFixture.checkResult("/*<caret> foo */");
}
// |%|
public void testPercentDoesntMatchBeforeCommentEnd() {
configureByJavaText("/* foo <caret> */");
typeText(parseKeys("%"));
myFixture.checkResult("/* foo <caret> */");
}
// |[(|
public void testUnmatchedOpenParenthesis() {
typeTextInFile(parseKeys("[("),