| /* |
| * 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(); |
| } |
| } |