blob: d0fdd9eeb0c09a1572e12d5f65d4d403b744cb66 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.editor.selectWord;
import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.psi.*;
import java.util.Collections;
import java.util.List;
/**
* User: catherine
*
* Handler to select commas around a selection before widening the selection to few words
*/
public class PyCommaSelectionHandler extends ExtendWordSelectionHandlerBase {
public boolean canSelect(final PsiElement e) {
return e instanceof PyReferenceExpression || e instanceof PyKeyValueExpression || e instanceof PyKeywordArgument
|| e instanceof PyNumericLiteralExpression || e instanceof PyStringLiteralExpression || e instanceof PyNamedParameter
|| e instanceof PyStarArgument;
}
@Override
public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
if (e != null) {
List<TextRange> textRange = addNextComma(e, cursorOffset);
if (textRange.equals(Collections.emptyList())) return addPreviousComma(e, cursorOffset);
else return textRange;
}
return Collections.emptyList();
}
/**
* adds previous comma and whitespace to result text range
* @param e is current element
* @param cursorOffset is current cursor offset
* @return result selection textRange
*/
private static List<TextRange> addPreviousComma(PsiElement e, int cursorOffset) {
PsiElement prevSibling = e.getPrevSibling();
TextRange textRange = e.getTextRange();
TextRange offsetRange = null;
if (prevSibling != null) {
if (prevSibling instanceof PsiWhiteSpace) {
PsiElement prevCommaSibling = prevSibling.getPrevSibling();
if (prevCommaSibling != null) {
ASTNode node = prevCommaSibling.getNode();
if (node != null) {
IElementType commaType = node.getElementType();
if (commaType == PyTokenTypes.COMMA) {
offsetRange = new TextRange(textRange.getStartOffset() - 2, textRange.getEndOffset());
if (offsetRange.contains(cursorOffset) && offsetRange.getLength() > 1) {
return Collections.singletonList(offsetRange);
}
}
}
}
}
else {
ASTNode node = prevSibling.getNode();
if (node != null) {
IElementType commaType = node.getElementType();
if (commaType == PyTokenTypes.COMMA) {
offsetRange = new TextRange(textRange.getStartOffset() - 1, textRange.getEndOffset());
}
}
}
if (offsetRange != null) {
if (offsetRange.contains(cursorOffset) && offsetRange.getLength() > 1) {
return Collections.singletonList(offsetRange);
}
}
}
return Collections.emptyList();
}
/**
* add next comma and whitespace to selection
* @param e is crrent element
* @param cursorOffset is current cursor offset
* @return result selection TextRange
*/
private static List<TextRange> addNextComma(PsiElement e, int cursorOffset) {
PsiElement nextCommaSibling = e.getNextSibling();
if (nextCommaSibling != null) {
ASTNode node = nextCommaSibling.getNode();
if (node != null) {
IElementType commaType = node.getElementType();
if (commaType == PyTokenTypes.COMMA) {
PsiElement nextSpaceSibling = nextCommaSibling.getNextSibling();
if (nextSpaceSibling != null) {
TextRange textRange = e.getTextRange();
TextRange offsetRange;
if (nextSpaceSibling instanceof PsiWhiteSpace) {
offsetRange = new TextRange(textRange.getStartOffset(), textRange.getEndOffset() + 2);
}
else {
offsetRange = new TextRange(textRange.getStartOffset(), textRange.getEndOffset() + 1);
}
if (offsetRange.contains(cursorOffset) && offsetRange.getLength() > 1) {
return Collections.singletonList(offsetRange);
}
}
}
}
}
return Collections.emptyList();
}
}