1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-08 15:34:07 +02:00

Lots of little fixes to avoid errors running commands on empty files

This commit is contained in:
rmaddy 2003-04-21 05:13:39 +00:00
parent cb5a3d495c
commit e4386f52f7
8 changed files with 122 additions and 35 deletions

View File

@ -132,8 +132,8 @@ public class Ranges
public TextRange getTextRange(Editor editor, DataContext context, int count)
{
LineRange lr = getLineRange(editor, context, count);
int start = editor.getDocument().getLineStartOffset(lr.getStartLine());
int end = editor.getDocument().getLineEndOffset(lr.getEndLine()) + 1;
int start = EditorHelper.getLineStartOffset(editor, lr.getStartLine());
int end = EditorHelper.getLineEndOffset(editor, lr.getEndLine()) + 1;
return new TextRange(start, Math.min(end, EditorHelper.getFileSize(editor)));
}

View File

@ -26,6 +26,7 @@ import com.maddyhome.idea.vim.ex.CommandName;
import com.maddyhome.idea.vim.ex.ExCommand;
import com.maddyhome.idea.vim.ex.ExException;
import com.maddyhome.idea.vim.group.CommandGroups;
import com.maddyhome.idea.vim.helper.EditorHelper;
/**
*
@ -44,7 +45,7 @@ public class MarkHandler extends CommandHandler
{
char mark = cmd.getArgument().charAt(0);
int line = cmd.getLine(editor, context);
int offset = editor.getDocument().getLineStartOffset(line);
int offset = EditorHelper.getLineStartOffset(editor, line);
return CommandGroups.getInstance().getMark().setMark(editor, context, mark, offset);
}

View File

@ -28,6 +28,7 @@ import com.maddyhome.idea.vim.ex.ExException;
import com.maddyhome.idea.vim.group.CommandGroups;
import com.maddyhome.idea.vim.group.MotionGroup;
import com.maddyhome.idea.vim.group.RegisterGroup;
import com.maddyhome.idea.vim.helper.EditorHelper;
/**
*
@ -60,7 +61,7 @@ public class PutLinesHandler extends CommandHandler
CommandGroups.getInstance().getRegister().selectRegister(RegisterGroup.REGISTER_DEFAULT);
}
MotionGroup.moveCaret(editor, context, editor.getDocument().getLineStartOffset(line));
MotionGroup.moveCaret(editor, context, EditorHelper.getLineStartOffset(editor, line));
if (before)
{
return CommandGroups.getInstance().getCopy().putTextBeforeCursor(editor, context, 1);

View File

@ -650,6 +650,10 @@ public class ChangeGroup extends AbstractActionGroup
public boolean deleteMotion(Editor editor, DataContext context, int count, int rawCount, Argument argument)
{
TextRange range = MotionGroup.getMotionRange(editor, context, count, rawCount, argument, false);
if (range == null && EditorHelper.getFileSize(editor) == 0)
{
return true;
}
return deleteRange(editor, context, range, argument.getMotion().getFlags());
}
@ -737,7 +741,7 @@ public class ChangeGroup extends AbstractActionGroup
char[] chars = editor.getDocument().getChars();
for (int i = range.getStartOffset(); i < range.getEndOffset(); i++)
{
if ('\n' != chars[i])
if (i < chars.length && '\n' != chars[i])
{
replaceText(editor, context, i, i + 1, Character.toString(ch));
}
@ -819,7 +823,8 @@ public class ChangeGroup extends AbstractActionGroup
String id = ActionManager.getInstance().getId(argument.getMotion().getAction());
if (id.equals("VimMotionWordRight"))
{
if (!Character.isWhitespace(editor.getDocument().getChars()[editor.getCaretModel().getOffset()]))
if (EditorHelper.getFileSize(editor) > 0 &&
!Character.isWhitespace(editor.getDocument().getChars()[editor.getCaretModel().getOffset()]))
{
argument.getMotion().setAction(ActionManager.getInstance().getAction("VimMotionWordEndRight"));
argument.getMotion().setFlags(MotionGroup.INCLUSIVE);
@ -827,7 +832,8 @@ public class ChangeGroup extends AbstractActionGroup
}
else if (id.equals("VimMotionWORDRight"))
{
if (!Character.isWhitespace(editor.getDocument().getChars()[editor.getCaretModel().getOffset()]))
if (EditorHelper.getFileSize(editor) > 0 &&
!Character.isWhitespace(editor.getDocument().getChars()[editor.getCaretModel().getOffset()]))
{
argument.getMotion().setAction(ActionManager.getInstance().getAction("VimMotionWORDEndRight"));
argument.getMotion().setFlags(MotionGroup.INCLUSIVE);
@ -962,6 +968,11 @@ public class ChangeGroup extends AbstractActionGroup
char[] chars = editor.getDocument().getChars();
for (int i = start; i < end; i++)
{
if (i >= chars.length)
{
break;
}
char ch = CharacterHelper.changeCase(chars[i], type);
if (ch != chars[i])
{
@ -1022,7 +1033,7 @@ public class ChangeGroup extends AbstractActionGroup
for (int l = sline; l <= eline; l++)
{
int soff = editor.getDocument().getLineStartOffset(l);
int soff = EditorHelper.getLineStartOffset(editor, l);
int woff = CommandGroups.getInstance().getMotion().moveCaretToLineStartSkipLeading(editor, l);
int col = editor.offsetToVisualPosition(woff).column;
int newCol = Math.max(0, col + dir * tabSize * count);

View File

@ -32,6 +32,7 @@ import com.intellij.openapi.editor.event.EditorFactoryEvent;
import com.intellij.openapi.vfs.VirtualFile;
import com.maddyhome.idea.vim.common.Mark;
import com.maddyhome.idea.vim.helper.EditorData;
import com.maddyhome.idea.vim.helper.EditorHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -410,8 +411,8 @@ public class MarkGroup extends AbstractActionGroup
// If the deleted text begins before the mark and ends after the mark then it may be shifted or deleted
else if (delStart.line <= mark.getLogicalLine() && delEnd.line >= mark.getLogicalLine())
{
int markLineStartOff = editor.getDocument().getLineStartOffset(mark.getLogicalLine());
int markLineEndOff = editor.getDocument().getLineEndOffset(mark.getLogicalLine());
int markLineStartOff = EditorHelper.getLineStartOffset(editor, mark.getLogicalLine());
int markLineEndOff = EditorHelper.getLineEndOffset(editor, mark.getLogicalLine());
// If the marked line is completely within the deleted text, remove the mark
if (delStartOff <= markLineStartOff && delEndOff >= markLineEndOff)
{

View File

@ -393,6 +393,12 @@ public class MotionGroup extends AbstractActionGroup
*/
public int moveCaretToNextWordEnd(Editor editor, int count, boolean skipPunc)
{
if ((editor.getCaretModel().getOffset() == 0 && count < 0) ||
(editor.getCaretModel().getOffset() >= EditorHelper.getFileSize(editor) - 1 && count > 0))
{
return -1;
}
int pos = SearchHelper.findNextWordEnd(editor, count, skipPunc);
if (pos == -1)
{
@ -707,12 +713,17 @@ public class MotionGroup extends AbstractActionGroup
public int moveCaretToLineStartSkipLeading(Editor editor, int lline)
{
int start = editor.getDocument().getLineStartOffset(lline);
int end = editor.getDocument().getLineEndOffset(lline);
int start = EditorHelper.getLineStartOffset(editor, lline);
int end = EditorHelper.getLineEndOffset(editor, lline);
char[] chars = editor.getDocument().getChars();
int pos = end;
for (int offset = start; offset < end; offset++)
{
if (offset >= chars.length)
{
break;
}
if (!Character.isWhitespace(chars[offset]))
{
pos = offset;
@ -731,12 +742,17 @@ public class MotionGroup extends AbstractActionGroup
public int moveCaretToLineEndSkipLeading(Editor editor, int lline)
{
int start = editor.getDocument().getLineStartOffset(lline);
int end = editor.getDocument().getLineEndOffset(lline);
int start = EditorHelper.getLineStartOffset(editor, lline);
int end = EditorHelper.getLineEndOffset(editor, lline);
char[] chars = editor.getDocument().getChars();
int pos = start;
for (int offset = end; offset > start; offset--)
{
if (offset >= chars.length)
{
break;
}
if (!Character.isWhitespace(chars[offset]))
{
pos = offset;
@ -749,7 +765,7 @@ public class MotionGroup extends AbstractActionGroup
public int moveCaretToLineEnd(Editor editor, int lline)
{
int offset = EditorHelper.normalizeOffset(editor, lline, editor.getDocument().getLineEndOffset(lline) - 1,
int offset = EditorHelper.normalizeOffset(editor, lline, EditorHelper.getLineEndOffset(editor, lline) - 1,
false);
return offset;
@ -757,7 +773,7 @@ public class MotionGroup extends AbstractActionGroup
public int moveCaretToLineEndAppend(Editor editor, int lline)
{
return editor.getDocument().getLineEndOffset(lline);
return EditorHelper.getLineEndOffset(editor, lline);
}
public int moveCaretToLineEndAppend(Editor editor)
@ -768,7 +784,7 @@ public class MotionGroup extends AbstractActionGroup
public int moveCaretToLineEndAppendOffset(Editor editor, int cntForward)
{
int line = EditorHelper.normalizeVisualLine(editor, EditorHelper.getCurrentVisualLine(editor) + cntForward);
return editor.getDocument().getLineEndOffset(EditorHelper.visualLineToLogicalLine(editor, line));
return EditorHelper.getLineEndOffset(editor, EditorHelper.visualLineToLogicalLine(editor, line));
}
public int moveCaretToLineEndOffset(Editor editor, int cntForward)
@ -790,7 +806,7 @@ public class MotionGroup extends AbstractActionGroup
return EditorHelper.getFileSize(editor);
}
int start = editor.getDocument().getLineStartOffset(lline);
int start = EditorHelper.getLineStartOffset(editor, lline);
return start;
}
@ -873,25 +889,28 @@ public class MotionGroup extends AbstractActionGroup
saveJumpLocation(editor, context);
return moveCaretToLineStartSkipLeading(editor, EditorHelper.normalizeLine(
editor, (EditorHelper.getLineCount(editor) * count + 99) / 100) - 1);
editor, (EditorHelper.getLineCount(editor) * count + 99) / 100 - 1));
}
public int moveCaretGotoLineLast(Editor editor, DataContext context, int rawCount, int lline)
{
saveJumpLocation(editor, context);
return moveCaretToLineStartSkipLeading(editor, rawCount == 0 ? EditorHelper.getLineCount(editor) - 1 : lline);
return moveCaretToLineStartSkipLeading(editor, rawCount == 0 ?
EditorHelper.normalizeLine(editor, EditorHelper.getLineCount(editor) - 1) : lline);
}
public int moveCaretGotoLineLastEnd(Editor editor, DataContext context, int rawCount, int lline)
{
saveJumpLocation(editor, context);
return moveCaretToLineEnd(editor, rawCount == 0 ? EditorHelper.getLineCount(editor) - 1 : lline);
return moveCaretToLineEnd(editor, rawCount == 0 ?
EditorHelper.normalizeLine(editor, EditorHelper.getLineCount(editor) - 1) : lline);
}
public int moveCaretGotoLineLastEndAppend(Editor editor, DataContext context, int rawCount, int lline)
{
saveJumpLocation(editor, context);
return moveCaretToLineEndAppend(editor, rawCount == 0 ? EditorHelper.getLineCount(editor) - 1 : lline);
return moveCaretToLineEndAppend(editor, rawCount == 0 ?
EditorHelper.normalizeLine(editor, EditorHelper.getLineCount(editor) - 1) : lline);
}
public int moveCaretGotoLineFirst(Editor editor, DataContext context, int lline)
@ -902,7 +921,7 @@ public class MotionGroup extends AbstractActionGroup
public static void moveCaret(Editor editor, DataContext context, int offset)
{
if (offset >= 0)
if (offset >= 0 && offset < editor.getDocument().getTextLength())
{
editor.getCaretModel().moveToOffset(offset);
EditorData.setLastColumn(editor, editor.getCaretModel().getVisualPosition().column);
@ -973,8 +992,8 @@ public class MotionGroup extends AbstractActionGroup
if (start != end)
{
int line = editor.offsetToLogicalPosition(start).line;
int lstart = editor.getDocument().getLineStartOffset(line);
int lend = editor.getDocument().getLineEndOffset(line);
int lstart = EditorHelper.getLineStartOffset(editor, line);
int lend = EditorHelper.getLineEndOffset(editor, line);
logger.debug("start=" + start + ", end=" + end + ", lstart=" + lstart + ", lend=" + lend);
if (lstart == start && lend + 1 == end)
{

View File

@ -111,14 +111,15 @@ public class EditorHelper
}
/**
* Gets the number of visible lines in the editor. This will less then the actuall number of lines in the file
* Gets the number of visible lines in the editor. This will less then the actual number of lines in the file
* if there are any collapsed folds.
* @param editor The editor
* @return The number of visible lines in the file
*/
public static int getVisualLineCount(Editor editor)
{
return logicalLineToVisualLine(editor, getLineCount(editor));
int count = getLineCount(editor);
return count == 0 ? 0 : logicalLineToVisualLine(editor, count - 1) + 1;
}
/**
@ -201,6 +202,50 @@ public class EditorHelper
return editor.logicalToVisualPosition(new LogicalPosition(lline, 0)).line;
}
/**
* Returns the offset of the start of the requested line.
* @param editor The editor
* @param lline The logical line to get the start offset for.
* @return 0 if line is &lt 0, file size of line is bigger than file, else the start offset for the line
*/
public static int getLineStartOffset(Editor editor, int lline)
{
if (lline < 0)
{
return 0;
}
else if (lline >= getLineCount(editor))
{
return getFileSize(editor);
}
else
{
return editor.getDocument().getLineStartOffset(lline);
}
}
/**
* Returns the offset of the end of the requested line.
* @param editor The editor
* @param lline The logical line to get the end offset for.
* @return 0 if line is &lt 0, file size of line is bigger than file, else the end offset for the line
*/
public static int getLineEndOffset(Editor editor, int lline)
{
if (lline < 0)
{
return 0;
}
else if (lline >= getLineCount(editor))
{
return getFileSize(editor);
}
else
{
return editor.getDocument().getLineEndOffset(lline);
}
}
/**
* Ensures that the supplied visual line is within the range 0 (incl) and the number of visual lines in the file
* (excl).
@ -224,7 +269,7 @@ public class EditorHelper
*/
public static int normalizeLine(Editor editor, int lline)
{
lline = Math.min(Math.max(0, lline), getLineCount(editor) - 1);
lline = Math.max(0, Math.min(lline, getLineCount(editor) - 1));
return lline;
}
@ -270,13 +315,13 @@ public class EditorHelper
*/
public static int normalizeOffset(Editor editor, int lline, int offset, boolean allowEnd)
{
if (lline == 0 && getFileSize(editor) == 0)
if (getFileSize(editor) == 0)
{
return 0;
}
int min = editor.getDocument().getLineStartOffset(lline);
int max = editor.getDocument().getLineEndOffset(lline) - (allowEnd ? 0 : 1);
int min = getLineStartOffset(editor, lline);
int max = getLineEndOffset(editor, lline) - (allowEnd ? 0 : 1);
offset = Math.max(Math.min(offset, max), min);
return offset;

View File

@ -38,7 +38,7 @@ public class SearchHelper
{
int res = -1;
int line = EditorHelper.getCurrentLogicalLine(editor);
int end = editor.getDocument().getLineEndOffset(line);
int end = EditorHelper.getLineEndOffset(editor, line);
char[] chars = editor.getDocument().getChars();
int pos = editor.getCaretModel().getOffset();
int loc = -1;
@ -142,6 +142,11 @@ public class SearchHelper
pos = skipSpace(chars, pos, step, size);
}
int res = pos;
if (pos < 0 || pos >= size)
{
return pos;
}
int type = CharacterHelper.charType(chars[pos], skipPunc);
pos += step;
while (pos >= 0 && pos < size && found < Math.abs(count))
@ -212,6 +217,10 @@ public class SearchHelper
pos = skipSpace(chars, pos, step, size);
}
int res = pos;
if (pos < 0 || pos >= size)
{
return pos;
}
int type = CharacterHelper.charType(chars[pos], skipPunc);
pos += step;
while (pos >= 0 && pos < size && found < Math.abs(count))
@ -288,13 +297,13 @@ public class SearchHelper
public static int findNextCharacterOnLine(Editor editor, int count, char ch)
{
int line = EditorHelper.getCurrentLogicalLine(editor);
int start = editor.getDocument().getLineStartOffset(line);
int end = editor.getDocument().getLineEndOffset(line);
int start = EditorHelper.getLineStartOffset(editor, line);
int end = EditorHelper.getLineEndOffset(editor, line);
char[] chars = editor.getDocument().getChars();
int found = 0;
int step = count >= 0 ? 1 : -1;
int pos = editor.getCaretModel().getOffset() + step;
while (pos >= start && pos < end)
while (pos >= start && pos < end && pos >= 0 && pos < chars.length)
{
if (chars[pos] == ch)
{