1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-04-16 02:15:43 +02:00

Rewritten to properly handle a sequence of ranges

This commit is contained in:
rmaddy 2003-04-29 05:20:21 +00:00
parent ad2b4faf09
commit 335b80f419

View File

@ -23,20 +23,28 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.maddyhome.idea.vim.ex.range.AbstractRange;
import com.maddyhome.idea.vim.ex.range.LineNumberRange;
import com.maddyhome.idea.vim.group.CommandGroups;
import com.maddyhome.idea.vim.group.MotionGroup;
import com.maddyhome.idea.vim.helper.EditorHelper;
import java.util.ArrayList;
/**
*
* Handles the set of range values entered as part of an Ex command.
*/
public class Ranges
{
/**
* Create the empty range list
*/
public Ranges()
{
ranges = new ArrayList();
}
/**
* Adds a range to the list
* @param range The list of ranges to append to the current list
*/
public void addRange(Range[] range)
{
for (int i = 0; i < range.length; i++)
@ -45,39 +53,49 @@ public class Ranges
}
}
/**
* Gets the number of ranges in the list
* @return The range count
*/
public int size()
{
return ranges.size();
return count;
}
/**
* Gets the line of the last range specified in the range list
* @param editor The editor to get the line for
* @param context The data context
* @return The line number represented by the range
*/
public int getLine(Editor editor, DataContext context)
{
if (size() > 0)
{
Range last = (Range)ranges.get(size() - 1);
processRange(editor, context);
return last.getLine(editor, context);
}
else
{
return (new LineNumberRange(0, false)).getLine(editor, context);
}
return endLine;
}
/**
* Gets the start line number the range represents
* @param editor The editor to get the line number for
* @param context The data context
* @return The starting line number
*/
public int getFirstLine(Editor editor, DataContext context)
{
if (size() > 0)
{
Range first = (Range)ranges.get(0);
processRange(editor, context);
return first.getLine(editor, context);
}
else
{
return (new LineNumberRange(0, false)).getLine(editor, context);
}
return startLine;
}
/**
* Gets the count for an Ex command. This is either an explicit count enter at the end of the command or the
* end of the specified range.
* @param editor The editor to get the count for
* @param context The data context
* @param count The count given at the end of the command or -1 if no such count (use end line)
* @return count if count != -1, else return end line of range
*/
public int getCount(Editor editor, DataContext context, int count)
{
if (count == -1)
@ -90,45 +108,42 @@ public class Ranges
}
}
/**
* Gets the line range represented by this range. If a count is given, the range is the range end line through
* count-1 lines. If no count is given (-1), the range is the range given by the user.
* @param editor The editor to get the range for
* @param context The data context
* @param count The count given at the end of the command or -1 if no such count
* @return The line range
*/
public LineRange getLineRange(Editor editor, DataContext context, int count)
{
Range end = null;
Range start = null;
processRange(editor, context);
int end = -1;
int start = -1;
if (count == -1)
{
if (size() >= 2)
{
end = (Range)ranges.get(size() - 1);
start = (Range)ranges.get(size() - 2);
}
else if (size() == 1)
{
end = (Range)ranges.get(size() - 1);
start = end;
}
else
{
end = new LineNumberRange(0, false);
start = end;
}
end = endLine;
start = startLine;
}
else
{
if (size() >= 1)
{
start = (Range)ranges.get(size() - 1);
}
else
{
start = new LineNumberRange(0, false);
}
end = new LineNumberRange(start.getLine(editor, context), count - 1, false);
start = endLine;
end = start + count - 1;
}
return new LineRange(start.getLine(editor, context), end.getLine(editor, context));
return new LineRange(start, end);
}
/**
* Gets the text range represented by this range. If a count is given, the range is the range end line through
* count-1 lines. If no count is given (-1), the range is the range given by the user. The text range is based
* on the line range but this is character based from the start of the first line to the end of the last line.
* @param editor The editor to get the range for
* @param context The data context
* @param count The count given at the end of the command or -1 if no such count
* @return The text range
*/
public TextRange getTextRange(Editor editor, DataContext context, int count)
{
LineRange lr = getLineRange(editor, context, count);
@ -138,6 +153,12 @@ public class Ranges
return new TextRange(start, Math.min(end, EditorHelper.getFileSize(editor)));
}
/**
* Helper method to get the text range for the current cursor line
* @param editor The editor to get the range for
* @param context The data context
* @return The range of the current line
*/
public static TextRange getCurrentLineRange(Editor editor, DataContext context)
{
Ranges ranges = new Ranges();
@ -145,6 +166,12 @@ public class Ranges
return ranges.getTextRange(editor, context, -1);
}
/**
* Helper method to get the text range for the current file
* @param editor The editor to get the range for
* @param context The data context
* @return The range of the current file
*/
public static TextRange getFileTextRange(Editor editor, DataContext context)
{
Ranges ranges = new Ranges();
@ -153,6 +180,45 @@ public class Ranges
return ranges.getTextRange(editor, context, -1);
}
/**
* Processes the list of ranges and calculates the start and end lines of the range
* @param editor The editor to get the lines for
* @param context The data context
*/
private void processRange(Editor editor, DataContext context)
{
// Already done
if (done) return;
// Start with the range being the current line
startLine = editor.getCaretModel().getLogicalPosition().line;
endLine = startLine;
boolean lastZero = false;
// Now process each range, moving the cursor if appropriate
for (int i = 0; i < ranges.size(); i++)
{
startLine = endLine;
Range range = (Range)ranges.get(i);
endLine = range.getLine(editor, context, lastZero);
if (range.isMove())
{
MotionGroup.moveCaret(editor, context,
CommandGroups.getInstance().getMotion().moveCaretToLine(editor, context, endLine));
}
// Did that last range represent the start of the file?
lastZero = (endLine < 0);
count++;
}
// If only one range given, make the start and end the same
if (count == 1)
{
startLine = endLine;
}
done = true;
}
public String toString()
{
StringBuffer res = new StringBuffer();
@ -162,5 +228,9 @@ public class Ranges
return res.toString();
}
private int startLine = 0;
private int endLine = 0;
private int count = 0;
private boolean done = false;
private ArrayList ranges;
}