Package ideah.editor

Source Code of ideah.editor.HaskellStringCopyPasteProcessor

package ideah.editor;

import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RawText;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import ideah.lexer.HaskellTokenTypes;
import ideah.lexer.Unescaper;
import ideah.util.LineCol;

// todo: for IDEA 11 override StringLiteralCopyPasteProcessor
public final class HaskellStringCopyPasteProcessor implements CopyPastePreProcessor {

    public String preprocessOnCopy(PsiFile file, int[] startOffsets, int[] endOffsets, String text) {
        boolean isLiteral = true;
        for (int i = 0; i < startOffsets.length; i++) {
            if (findLiteralTokenType(file, startOffsets[i], endOffsets[i]) == null) {
                isLiteral = false;
                break;
            }
        }
        return isLiteral ? Unescaper.unescape(text) : null;
    }

    public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) {
        Document document = editor.getDocument();
        PsiDocumentManager.getInstance(project).commitDocument(document);
        SelectionModel selectionModel = editor.getSelectionModel();

        // pastes in block selection mode (column mode) are not handled by a CopyPasteProcessor
        int selectionStart = selectionModel.getSelectionStart();
        int selectionEnd = selectionModel.getSelectionEnd();
        IElementType tokenType = findLiteralTokenType(file, selectionStart, selectionEnd);

        if (tokenType == HaskellTokenTypes.STRING) {
            if (rawText != null && rawText.rawText != null)
                return rawText.rawText; // Copied from the string literal. Copy as is.

            StringBuilder buffer = new StringBuilder(text.length());
            LineCol lineCol = LineCol.fromOffset(file, selectionStart);
            String indent;
            if (lineCol != null) {
                int column = lineCol.column - 1;
                indent = StringUtil.repeat(" ", column > 0 ? column - 1 : 0);
            } else {
                indent = "";
            }
            String breaker = "\\n\\\n" + indent + "\\";
            String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
            for (int i = 0; i < lines.length; i++) {
                if (i > 0) {
                    buffer.append(breaker);
                }
                String line = lines[i];
                buffer.append(escape(line));
            }
            text = buffer.toString();
        }
        return text;
    }

    private static IElementType findLiteralTokenType(PsiFile file, int selectionStart, int selectionEnd) {
        PsiElement elementAtSelection = file.findElementAt(selectionStart);
        if (elementAtSelection == null)
            return null;
        IElementType tokenType = elementAtSelection.getNode().getElementType();
        if (tokenType != HaskellTokenTypes.STRING)
            return null;
        TextRange textRange = elementAtSelection.getTextRange();
        if (selectionStart <= textRange.getStartOffset() || selectionEnd >= textRange.getEndOffset()) {
            return null;
        }
        return tokenType;
    }

    private static String escape(String str) {
        StringBuilder buf = new StringBuilder(str.length());
        boolean prevHex = false;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            boolean nextPrevHex = false;
            if (ch == '\'') {
                buf.append(ch);
            } else {
                char escaped = Unescaper.escape(ch);
                if (escaped != 0) {
                    buf.append('\\').append(escaped);
                } else {
                    if (Character.isISOControl(ch)) {
                        String hexCode = Integer.toHexString(ch).toUpperCase();
                        buf.append("\\x");
                        int paddingCount = 4 - hexCode.length();
                        while (paddingCount-- > 0) {
                            buf.append('0');
                        }
                        buf.append(hexCode);
                        nextPrevHex = true;
                    } else {
                        if (prevHex && (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f')) {
                            buf.append('\\').append('&');
                        }
                        buf.append(ch);
                    }
                }
            }
            prevHex = nextPrevHex;
        }
        return buf.toString();
    }
}
TOP

Related Classes of ideah.editor.HaskellStringCopyPasteProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.