1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-03-06 00:32:52 +01:00

Multicaret support for go to line

This commit is contained in:
Vitalii Karavaev 2018-07-26 14:52:40 +03:00
parent f38bf65656
commit 2efb0dfb17
9 changed files with 99 additions and 40 deletions

View File

@ -38,6 +38,10 @@ public class ExCommand {
return ranges.getLine(editor, context);
}
public int getLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context) {
return ranges.getLine(editor, caret, context);
}
public int getCount(@NotNull Editor editor, DataContext context, int defaultCount, boolean checkCount) {
int count = -1;
if (checkCount) {

View File

@ -19,7 +19,9 @@
package com.maddyhome.idea.vim.ex;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import org.jetbrains.annotations.NotNull;
/**
* Represents an Ex command range
@ -35,6 +37,8 @@ public interface Range {
*/
int getLine(Editor editor, DataContext context, boolean lastZero);
int getLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context, boolean lastZero);
/**
* Should the cursor be moved to this range's line?
*

View File

@ -240,14 +240,14 @@ public class Ranges {
}
private void processRange(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context) {
if (done) return;
//if (done) return;
startLine = defaultLine == -1 ? caret.getLogicalPosition().line : defaultLine;
endLine = startLine;
boolean lastZero = false;
for (Range range : ranges) {
startLine = endLine;
endLine = range.getLine(editor, context, lastZero);
endLine = range.getLine(editor, caret, context, lastZero);
if (range.isMove()) MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLine(editor, endLine));
@ -257,7 +257,7 @@ public class Ranges {
if (count == 1) startLine = endLine;
done = true;
//done = true;
}
@NotNull

View File

@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.ex.CommandHandler;
import com.maddyhome.idea.vim.ex.ExCommand;
import com.maddyhome.idea.vim.ex.ExException;
import com.maddyhome.idea.vim.group.MotionGroup;
import com.maddyhome.idea.vim.handler.CaretOrder;
import com.maddyhome.idea.vim.helper.EditorHelper;
import org.jetbrains.annotations.NotNull;
@ -39,34 +40,29 @@ public class GotoLineHandler extends CommandHandler {
* Create the handler
*/
public GotoLineHandler() {
super(RANGE_REQUIRED | ARGUMENT_OPTIONAL, Command.FLAG_MOT_EXCLUSIVE);
super(RANGE_REQUIRED | ARGUMENT_OPTIONAL, Command.FLAG_MOT_EXCLUSIVE, true, CaretOrder.DECREASING_OFFSET);
}
/**
* Moves the cursor to the line entered by the user
*
* @param editor The editor to perform the action in.
* @param editor The editor to perform the action in
* @param caret The caret to perform the action on
* @param context The data context
* @param cmd The complete Ex command including range, command, and arguments
* @return True if able to perform the command, false if not
*/
@Override
public boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull ExCommand cmd)
throws ExException {
final int lineCount = EditorHelper.getLineCount(editor);
final int line = Math.min(lineCount - 1, cmd.getLine(editor, context));
public boolean execute(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context,
@NotNull ExCommand cmd) throws ExException {
final int line = Math.min(cmd.getLine(editor, caret, context), EditorHelper.getLineCount(editor) - 1);
if (line >= 0) {
final int offset = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, line);
for (Caret caret : editor.getCaretModel().getAllCarets()) {
MotionGroup.moveCaret(editor, caret, offset);
}
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, line));
return true;
}
for (Caret caret : editor.getCaretModel().getAllCarets()) {
MotionGroup.moveCaret(editor, caret, 0);
}
MotionGroup.moveCaret(editor, caret, 0);
return false;
}
}

View File

@ -19,6 +19,7 @@
package com.maddyhome.idea.vim.ex.range;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.ex.Range;
import org.jetbrains.annotations.NotNull;
@ -124,6 +125,12 @@ public abstract class AbstractRange implements Range {
return line + offset;
}
public int getLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context, boolean lastZero) {
if (offset == 0) return getRangeLine(editor, context, lastZero);
return getRangeLine(editor, caret, context, lastZero) + offset;
}
@NotNull
public String toString() {
return "AbstractRange" + "{offset=" + offset + ", move=" + move + '}';
@ -139,6 +146,9 @@ public abstract class AbstractRange implements Range {
*/
protected abstract int getRangeLine(Editor editor, DataContext context, boolean lastZero);
protected abstract int getRangeLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context,
boolean lastZero);
protected final int offset;
protected final boolean move;
}

View File

@ -19,6 +19,7 @@
package com.maddyhome.idea.vim.ex.range;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.helper.EditorHelper;
import org.jetbrains.annotations.NotNull;
@ -73,6 +74,14 @@ public class LineNumberRange extends AbstractRange {
return line;
}
protected int getRangeLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context,
boolean lastZero) {
if (line == LAST_LINE) line = EditorHelper.getLineCount(editor) - 1;
else line = caret.getLogicalPosition().line;
return line;
}
@NotNull
public String toString() {

View File

@ -19,6 +19,7 @@
package com.maddyhome.idea.vim.ex.range;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.common.Mark;
@ -60,6 +61,13 @@ public class MarkRange extends AbstractRange {
}
}
@Override
protected int getRangeLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context,
boolean lastZero) {
//TODO: add multicaret support
return getRangeLine(editor, context, lastZero);
}
@NotNull
public String toString() {

View File

@ -20,6 +20,7 @@ package com.maddyhome.idea.vim.ex.range;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.command.Command;
@ -58,31 +59,33 @@ public class SearchRange extends AbstractRange {
StringTokenizer tok = new StringTokenizer(pattern, "\u0000");
while (tok.hasMoreTokens()) {
String pat = tok.nextToken();
if (pat.equals("\\/")) {
patterns.add(VimPlugin.getSearch().getLastSearch());
flags.add(Command.FLAG_SEARCH_FWD);
}
else if (pat.equals("\\?")) {
patterns.add(VimPlugin.getSearch().getLastSearch());
flags.add(Command.FLAG_SEARCH_REV);
}
else if (pat.equals("\\&")) {
patterns.add(VimPlugin.getSearch().getLastPattern());
flags.add(Command.FLAG_SEARCH_FWD);
}
else {
if (pat.charAt(0) == '/') {
switch (pat) {
case "\\/":
patterns.add(VimPlugin.getSearch().getLastSearch());
flags.add(Command.FLAG_SEARCH_FWD);
}
else {
break;
case "\\?":
patterns.add(VimPlugin.getSearch().getLastSearch());
flags.add(Command.FLAG_SEARCH_REV);
}
break;
case "\\&":
patterns.add(VimPlugin.getSearch().getLastPattern());
flags.add(Command.FLAG_SEARCH_FWD);
break;
default:
if (pat.charAt(0) == '/') {
flags.add(Command.FLAG_SEARCH_FWD);
}
else {
flags.add(Command.FLAG_SEARCH_REV);
}
pat = pat.substring(1);
if (pat.charAt(pat.length() - 1) == pat.charAt(0)) {
pat = pat.substring(0, pat.length() - 1);
}
patterns.add(pat);
pat = pat.substring(1);
if (pat.charAt(pat.length() - 1) == pat.charAt(0)) {
pat = pat.substring(0, pat.length() - 1);
}
patterns.add(pat);
break;
}
}
}
@ -126,14 +129,23 @@ public class SearchRange extends AbstractRange {
}
}
@Override
protected int getRangeLine(@NotNull Editor editor, @NotNull Caret caret, @NotNull DataContext context,
boolean lastZero) {
//TODO: add multicaret support
return getRangeLine(editor, context, lastZero);
}
@NotNull
public String toString() {
return "SearchRange[" + "patterns=" + patterns + ", " + super.toString() + "]";
}
@NotNull private final List<String> patterns = new ArrayList<String>();
@NotNull private final List<Integer> flags = new ArrayList<Integer>();
@NotNull
private final List<String> patterns = new ArrayList<>();
@NotNull
private final List<Integer> flags = new ArrayList<>();
private static final Logger logger = Logger.getInstance(SearchRange.class.getName());
}

View File

@ -10,4 +10,20 @@ class MultipleCaretsTest : VimTestCase() {
val after = "qwe <caret>rty asd\n fgh zxc vbn"
myFixture.checkResult(after)
}
fun testGotoLine() {
val before = "qwe\n" + "rty\n" + "asd\n" + "f<caret>gh\n" + "zxc\n" + "v<caret>bn\n"
configureByText(before)
typeText(commandToKeys("2"))
val after = "qwe\n" + "<caret>rty\n" + "asd\n" + "fgh\n" + "zxc\n" + "vbn\n"
myFixture.checkResult(after)
}
fun testGotoLineInc() {
val before = "qwe\n" + "rt<caret>y\n" + "asd\n" + "fgh\n" + "zxc\n" + "v<caret>bn\n"
configureByText(before)
typeText(commandToKeys("+2"))
val after = "qwe\n" + "rty\n" + "asd\n" + "<caret>fgh\n" + "zxc\n" + "<caret>vbn\n"
myFixture.checkResult(after)
}
}