package org.jetbrains.plugins.clojure.editor.selection;
import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author ilyas
*/
public abstract class ClojureBasicSelectioner implements ExtendWordSelectionHandler {
public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
final TextRange originalRange = e.getTextRange();
List<TextRange> ranges = expandToWholeLine(editorText, originalRange, true);
if (ranges.size() == 1 && ranges.contains(originalRange)) {
ranges = expandToWholeLine(editorText, originalRange, false);
}
List<TextRange> result = new ArrayList<TextRange>();
result.addAll(ranges);
return result;
}
static List<TextRange> expandToWholeLine(CharSequence text, TextRange range, boolean isSymmetric) {
int textLength = text.length();
List<TextRange> result = new ArrayList<TextRange>();
if (range == null) {
return result;
}
boolean hasNewLines = false;
for (int i = range.getStartOffset(); i < range.getEndOffset(); i++) {
char c = text.charAt(i);
if (c == '\r' || c == '\n') {
hasNewLines = true;
break;
}
}
if (!hasNewLines) {
result.add(range);
}
int startOffset = range.getStartOffset();
int endOffset = range.getEndOffset();
int index1 = CharArrayUtil.shiftBackward(text, startOffset - 1, " \t");
if (endOffset > startOffset && text.charAt(endOffset - 1) == '\n' || text.charAt(endOffset - 1) == '\r') {
endOffset--;
}
int index2 = Math.min(textLength, CharArrayUtil.shiftForward(text, endOffset, " \t"));
if (index1 < 0
|| text.charAt(index1) == '\n'
|| text.charAt(index1) == '\r'
|| index2 == textLength
|| text.charAt(index2) == '\n'
|| text.charAt(index2) == '\r') {
if (!isSymmetric) {
if (index1 < 0 || text.charAt(index1) == '\n' || text.charAt(index1) == '\r') {
startOffset = index1 + 1;
}
if (index2 == textLength || text.charAt(index2) == '\n' || text.charAt(index2) == '\r') {
endOffset = index2;
if (endOffset < textLength) {
endOffset++;
if (endOffset < textLength && text.charAt(endOffset - 1) == '\r' && text.charAt(endOffset) == '\n') {
endOffset++;
}
}
}
result.add(new TextRange(startOffset, endOffset));
} else {
if ((index1 < 0 || text.charAt(index1) == '\n' || text.charAt(index1) == '\r') &&
(index2 == textLength || text.charAt(index2) == '\n' || text.charAt(index2) == '\r')) {
startOffset = index1 + 1;
endOffset = index2;
if (endOffset < textLength) {
endOffset++;
if (endOffset < textLength && text.charAt(endOffset - 1) == '\r' && text.charAt(endOffset) == '\n') {
endOffset++;
}
}
result.add(new TextRange(startOffset, endOffset));
} else {
result.add(range);
}
}
} else {
result.add(range);
}
return result;
}
public int getMinimalTextRangeLength(@NotNull PsiElement element, @NotNull CharSequence text, int cursorOffset) {
return element.getTextLength();
}
public int getMinimalTextRangeLength(@NotNull PsiElement element) {
return element.getTextLength();
}
}