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:
parent
f38bf65656
commit
2efb0dfb17
src/com/maddyhome/idea/vim/ex
test/org/jetbrains/plugins/ideavim/ex
@ -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) {
|
||||
|
@ -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?
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user