package osmedile.intellij.stringmanip.styles; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiUtilBase; import osmedile.intellij.stringmanip.AbstractStringManipAction; import osmedile.intellij.stringmanip.utils.StringUtil; import java.util.Map; /** todo write some tests for this shit */ public abstract class AbstractCaseConvertingAction extends AbstractStringManipAction<Object> { public static final String FROM = "from"; private final Logger LOG = Logger.getInstance("#" + getClass().getCanonicalName()); public AbstractCaseConvertingAction() { } public AbstractCaseConvertingAction(boolean setupHandler) { super(setupHandler); } @Override protected boolean selectSomethingUnderCaret(Editor editor, DataContext dataContext, SelectionModel selectionModel) { try { PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(editor.getDocument()); if (psiFile == null) {// select whole line in plaintext return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } FileType fileType = psiFile.getFileType(); boolean handled = false; if (fileType.equals(StdFileTypes.JAVA) && isJavaInstalled()) { handled = javaHandling(editor, dataContext, selectionModel, psiFile); } if (!handled && fileType.equals(StdFileTypes.PROPERTIES)) { handled = propertiesHandling(editor, dataContext, selectionModel, psiFile); } if (!handled && fileType.equals(StdFileTypes.PLAIN_TEXT)) { handled = super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } if (!handled) { handled = genericHandling(editor, dataContext, selectionModel, psiFile); } return handled; } catch (Exception e) { LOG.error("please report this, so I can fix it :(", e); return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } } private boolean isJavaInstalled() { boolean javaInstalled; try { Class.forName("com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl"); javaInstalled = true; } catch (ClassNotFoundException e) { javaInstalled = false; } return javaInstalled; } private boolean propertiesHandling(Editor editor, DataContext dataContext, SelectionModel selectionModel, PsiFile psiFile) { PsiElement elementAtCaret = PsiUtilBase.getElementAtCaret(editor); if (elementAtCaret instanceof PsiWhiteSpace) { return false; } else if (elementAtCaret instanceof LeafPsiElement) { IElementType elementType = ((LeafPsiElement) elementAtCaret).getElementType(); if (elementType.toString().equals("Properties:VALUE_CHARACTERS") || elementType.toString().equals("Properties:KEY_CHARACTERS")) { TextRange textRange = elementAtCaret.getTextRange(); if (textRange.getLength() == 0) { return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } selectionModel.setSelection(textRange.getStartOffset(), textRange.getEndOffset()); return true; } } return false; } private boolean javaHandling(Editor editor, DataContext dataContext, SelectionModel selectionModel, PsiFile psiFile) { boolean steppedLeft = false; int caretOffset = editor.getCaretModel().getOffset(); PsiElement elementAtCaret = PsiUtilBase.getElementAtCaret(editor); if (elementAtCaret instanceof PsiWhiteSpace) { elementAtCaret = PsiUtilBase.getElementAtOffset(psiFile, caretOffset - 1); steppedLeft = true; } else if (elementAtCaret instanceof PsiJavaTokenImpl) { PsiJavaToken javaToken = (PsiJavaToken) elementAtCaret; if (javaToken.getTokenType() != JavaTokenType.STRING_LITERAL) { elementAtCaret = PsiUtilBase.getElementAtOffset(psiFile, caretOffset - 1); steppedLeft = true; } } if (steppedLeft && !(elementAtCaret instanceof PsiJavaToken)) { return false; } if (steppedLeft && elementAtCaret instanceof PsiJavaTokenImpl) { PsiJavaToken javaToken = (PsiJavaToken) elementAtCaret; if (javaToken.getTokenType() != JavaTokenType.STRING_LITERAL) { return false; } } if (elementAtCaret instanceof PsiJavaToken) { int offset = 0; PsiJavaToken javaToken = (PsiJavaToken) elementAtCaret; if (javaToken.getTokenType() == JavaTokenType.STRING_LITERAL) { offset = 1; } TextRange textRange = elementAtCaret.getTextRange(); if (textRange.getLength() == 0) { return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } selectionModel.setSelection(textRange.getStartOffset() + offset, textRange.getEndOffset() - offset); if (caretOffset < selectionModel.getSelectionStart()) { editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart()); } if (caretOffset > selectionModel.getSelectionEnd()) { editor.getCaretModel().moveToOffset(selectionModel.getSelectionEnd()); } return true; } else { return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } } private boolean genericHandling(Editor editor, DataContext dataContext, SelectionModel selectionModel, PsiFile psiFile) { int caretOffset = editor.getCaretModel().getOffset(); PsiElement elementAtCaret = PsiUtilBase.getElementAtCaret(editor); if (elementAtCaret instanceof PsiPlainText) { return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } else if (elementAtCaret instanceof PsiWhiteSpace) { elementAtCaret = PsiUtilBase.getElementAtOffset(psiFile, caretOffset - 1); } if (elementAtCaret == null || elementAtCaret instanceof PsiWhiteSpace) { return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } else { TextRange textRange = elementAtCaret.getTextRange(); if (textRange.getLength() == 0) { return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } selectionModel.setSelection(textRange.getStartOffset(), textRange.getEndOffset()); String selectedText = selectionModel.getSelectedText(); if (selectedText != null && selectedText.contains("\n")) { selectionModel.removeSelection(); return super.selectSomethingUnderCaret(editor, dataContext, selectionModel); } if (StringUtil.isQuoted(selectedText)) { selectionModel.setSelection(selectionModel.getSelectionStart() + 1, selectionModel.getSelectionEnd() - 1); } if (caretOffset < selectionModel.getSelectionStart()) { editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart()); } if (caretOffset > selectionModel.getSelectionEnd()) { editor.getCaretModel().moveToOffset(selectionModel.getSelectionEnd()); } return true; } } protected Style getStyle(Map<String, Object> actionContext, String s) { Style from = (Style) actionContext.get(FROM); if (from == null) { from = Style.from(s); actionContext.put(FROM, from); } return from; } }