-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Move Element Left/Right action
- Loading branch information
1 parent
288e7af
commit 2241f84
Showing
9 changed files
with
293 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/main/java/org/nixos/idea/lang/NixMoveElementLeftRightHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.nixos.idea.lang; | ||
|
||
import com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementLeftRightHandler; | ||
import com.intellij.psi.PsiElement; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.nixos.idea.psi.NixBindInherit; | ||
import org.nixos.idea.psi.NixExprApp; | ||
import org.nixos.idea.psi.NixExprAttrs; | ||
import org.nixos.idea.psi.NixExprLambda; | ||
import org.nixos.idea.psi.NixExprLet; | ||
import org.nixos.idea.psi.NixExprList; | ||
import org.nixos.idea.psi.NixFormals; | ||
import org.nixos.idea.psi.NixPsiUtil; | ||
|
||
import java.util.Collection; | ||
|
||
public final class NixMoveElementLeftRightHandler extends MoveElementLeftRightHandler { | ||
@Override | ||
public PsiElement @NotNull [] getMovableSubElements(@NotNull PsiElement element) { | ||
if (element instanceof NixExprList list) { | ||
return asArray(list.getItems()); | ||
} else if (element instanceof NixBindInherit inherit) { | ||
return asArray(inherit.getAttributes()); | ||
} else if (element instanceof NixExprAttrs attrs) { | ||
return asArray(attrs.getBindList()); | ||
} else if (element instanceof NixExprLet let) { | ||
return asArray(let.getBindList()); | ||
} else if (element instanceof NixExprLambda lambda) { | ||
return new PsiElement[]{lambda.getArgument(), lambda.getFormals()}; | ||
} else if (element instanceof NixFormals formals) { | ||
return asArray(formals.getFormalList()); | ||
} else if (element instanceof NixExprApp app) { | ||
return asArray(NixPsiUtil.getArguments(app)); | ||
} else { | ||
return PsiElement.EMPTY_ARRAY; | ||
} | ||
} | ||
|
||
private PsiElement @NotNull [] asArray(@NotNull Collection<? extends PsiElement> items) { | ||
return items.toArray(PsiElement[]::new); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
231 changes: 231 additions & 0 deletions
231
src/test/java/org/nixos/idea/lang/NixMoveElementLeftRightHandlerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
package org.nixos.idea.lang; | ||
|
||
import com.intellij.openapi.actionSystem.IdeActions; | ||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture; | ||
import org.intellij.lang.annotations.Language; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.nixos.idea._testutil.WithIdeaPlatform; | ||
import org.nixos.idea.file.NixFileType; | ||
|
||
@WithIdeaPlatform.OnEdt | ||
@WithIdeaPlatform.CodeInsight | ||
final class NixMoveElementLeftRightHandlerTest { | ||
|
||
private final CodeInsightTestFixture myFixture; | ||
|
||
NixMoveElementLeftRightHandlerTest(CodeInsightTestFixture fixture) { | ||
myFixture = fixture; | ||
} | ||
|
||
@Nested | ||
final class List { | ||
@Test | ||
void moveLeft() { | ||
setup("[a b c d e f<caret>]"); | ||
doMoveLeft(); | ||
expect("[a b c d f<caret> e]"); | ||
doMoveLeft(); | ||
expect("[a b c f<caret> d e]"); | ||
doMoveLeft(); | ||
expect("[a b f<caret> c d e]"); | ||
doMoveLeft(); | ||
expect("[a f<caret> b c d e]"); | ||
doMoveLeft(); | ||
expect("[f<caret> a b c d e]"); | ||
doMoveLeft(); | ||
expect("[f<caret> a b c d e]"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("[ <caret>a b c d ]"); | ||
doMoveRight(); | ||
expect("[ b <caret>a c d ]"); | ||
doMoveRight(); | ||
expect("[ b c <caret>a d ]"); | ||
doMoveRight(); | ||
expect("[ b c d <caret>a ]"); | ||
doMoveRight(); | ||
expect("[ b c d <caret>a ]"); | ||
} | ||
} | ||
|
||
@Nested | ||
final class BindInherit { | ||
@Test | ||
void moveLeft() { | ||
setup("{ inherit (x) a b <caret>c; }"); | ||
doMoveLeft(); | ||
expect("{ inherit (x) a <caret>c b; }"); | ||
doMoveLeft(); | ||
expect("{ inherit (x) <caret>c a b; }"); | ||
doMoveLeft(); | ||
expect("{ inherit (x) <caret>c a b; }"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("{ inherit (x) a<caret> b c; }"); | ||
doMoveRight(); | ||
expect("{ inherit (x) b a<caret> c; }"); | ||
doMoveRight(); | ||
expect("{ inherit (x) b c a<caret>; }"); | ||
doMoveRight(); | ||
expect("{ inherit (x) b c a<caret>; }"); | ||
} | ||
} | ||
|
||
@Nested | ||
final class Attrs { | ||
@Test | ||
void moveLeft() { | ||
setup("{ a = A; b = B; c <caret>= C; }"); | ||
doMoveLeft(); | ||
expect("{ a = A; c <caret>= C; b = B; }"); | ||
doMoveLeft(); | ||
expect("{ c <caret>= C; a = A; b = B; }"); | ||
doMoveLeft(); | ||
expect("{ c <caret>= C; a = A; b = B; }"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("rec { a =<caret> A; b = B; c = C; }"); | ||
doMoveRight(); | ||
expect("rec { b = B; a =<caret> A; c = C; }"); | ||
doMoveRight(); | ||
expect("rec { b = B; c = C; a =<caret> A; }"); | ||
doMoveRight(); | ||
expect("rec { b = B; c = C; a =<caret> A; }"); | ||
} | ||
} | ||
|
||
@Nested | ||
final class Let { | ||
@Test | ||
void moveLeft() { | ||
setup("let a = A; b = B; c <caret>= C; in _"); | ||
doMoveLeft(); | ||
expect("let a = A; c <caret>= C; b = B; in _"); | ||
doMoveLeft(); | ||
expect("let c <caret>= C; a = A; b = B; in _"); | ||
doMoveLeft(); | ||
expect("let c <caret>= C; a = A; b = B; in _"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("let a =<caret> A; b = B; c = C; in _"); | ||
doMoveRight(); | ||
expect("let b = B; a =<caret> A; c = C; in _"); | ||
doMoveRight(); | ||
expect("let b = B; c = C; a =<caret> A; in _"); | ||
doMoveRight(); | ||
expect("let b = B; c = C; a =<caret> A; in _"); | ||
} | ||
} | ||
|
||
@Nested | ||
final class Lambda { | ||
@Test | ||
void moveLeft() { | ||
setup("{ x } @ a<caret>: _"); | ||
doMoveLeft(); | ||
expect("a @ { x }: _"); | ||
doMoveLeft(); | ||
expect("a @ { x }: _"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("a<caret> @ { x, y }: _"); | ||
doMoveRight(); | ||
expect("{ x, y } @ a<caret>: _"); | ||
doMoveRight(); | ||
expect("{ x, y } @ a<caret>: _"); | ||
} | ||
} | ||
|
||
@Nested | ||
final class LambdaFormals { | ||
@Test | ||
void moveLeft() { | ||
setup("{ a, b, c<caret> } @ x: _"); | ||
doMoveLeft(); | ||
expect("{ a, c<caret>, b } @ x: _"); | ||
doMoveLeft(); | ||
expect("{ c<caret>, a, b } @ x: _"); | ||
doMoveLeft(); | ||
expect("{ c<caret>, a, b } @ x: _"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("{ a<caret>, b, c } @ x: _"); | ||
doMoveRight(); | ||
expect("{ b, a<caret>, c } @ x: _"); | ||
doMoveRight(); | ||
expect("{ b, c, a<caret> } @ x: _"); | ||
doMoveRight(); | ||
expect("{ b, c, a<caret> } @ x: _"); | ||
} | ||
} | ||
|
||
@Nested | ||
final class App { | ||
@Test | ||
void doNotMoveFunction() { | ||
setup("f<caret> a b c"); | ||
doMoveLeft(); | ||
expect("f<caret> a b c"); | ||
} | ||
|
||
@Test | ||
void moveLeft() { | ||
setup("f a b <caret>c"); | ||
doMoveLeft(); | ||
expect("f a <caret>c b"); | ||
doMoveLeft(); | ||
expect("f <caret>c a b"); | ||
doMoveLeft(); | ||
expect("f <caret>c a b"); | ||
} | ||
|
||
@Test | ||
void moveRight() { | ||
setup("f <caret>a b c"); | ||
doMoveRight(); | ||
expect("f b <caret>a c"); | ||
doMoveRight(); | ||
expect("f b c <caret>a"); | ||
doMoveRight(); | ||
expect("f b c <caret>a"); | ||
} | ||
} | ||
|
||
private void setup(@Language("HTML") String code) { | ||
myFixture.configureByText(NixFileType.INSTANCE, code); | ||
} | ||
|
||
private void doMoveLeft() { | ||
myFixture.performEditorAction(IdeActions.MOVE_ELEMENT_LEFT); | ||
} | ||
|
||
private void doMoveRight() { | ||
myFixture.performEditorAction(IdeActions.MOVE_ELEMENT_RIGHT); | ||
} | ||
|
||
private void expect(@Language("HTML") String code) { | ||
int caretMarker = code.indexOf(CodeInsightTestFixture.CARET_MARKER); | ||
if (caretMarker >= 0) { | ||
code = code.substring(0, caretMarker) + | ||
code.substring(caretMarker + CodeInsightTestFixture.CARET_MARKER.length()); | ||
} | ||
Assertions.assertEquals(code, myFixture.getEditor().getDocument().getText()); | ||
if (caretMarker >= 0) { | ||
Assertions.assertEquals(caretMarker, myFixture.getCaretOffset()); | ||
} | ||
} | ||
} |