blob: 62276632ee113bd4a47f6a79485395cfc7df3f00 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin, Google
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.texteditor.ITextEditorExtension3;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
/**
* Auto indent strategy for C strings
*/
public class CStringAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
private String fPartitioning;
private final ICProject fProject;
/**
* The input string doesn't contain any line delimiter.
*
* @param inputString the given input string
* @return the displayable string.
*/
private String displayString(String inputString, CharSequence indentation, String delimiter) {
int length = inputString.length();
StringBuilder buffer = new StringBuilder(length);
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(inputString, "\n\r", true); //$NON-NLS-1$
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (token.equals("\r")) { //$NON-NLS-1$
buffer.append("\\r"); //$NON-NLS-1$
if (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if (token.equals("\n")) { //$NON-NLS-1$
buffer.append("\\n"); //$NON-NLS-1$
buffer.append('"').append(delimiter);
buffer.append(indentation);
buffer.append('"');
continue;
}
buffer.append('"').append(delimiter);
buffer.append(indentation);
buffer.append('"');
} else {
continue;
}
} else if (token.equals("\n")) { //$NON-NLS-1$
buffer.append("\\n"); //$NON-NLS-1$
buffer.append('"').append(delimiter);
buffer.append(indentation);
buffer.append('"');
continue;
}
StringBuilder tokenBuffer = new StringBuilder();
for (int i = 0; i < token.length(); i++){
char c = token.charAt(i);
switch (c) {
case '\r' :
tokenBuffer.append("\\r"); //$NON-NLS-1$
break;
case '\n' :
tokenBuffer.append("\\n"); //$NON-NLS-1$
break;
case '\b' :
tokenBuffer.append("\\b"); //$NON-NLS-1$
break;
case '\t' :
// keep tabs verbatim
tokenBuffer.append("\t"); //$NON-NLS-1$
break;
case '\f' :
tokenBuffer.append("\\f"); //$NON-NLS-1$
break;
case '\"' :
tokenBuffer.append("\\\""); //$NON-NLS-1$
break;
case '\'' :
tokenBuffer.append("\\'"); //$NON-NLS-1$
break;
case '\\' :
tokenBuffer.append("\\\\"); //$NON-NLS-1$
break;
default :
tokenBuffer.append(c);
}
}
buffer.append(tokenBuffer);
}
return buffer.toString();
}
/**
* Creates a new C string auto indent strategy for the given document partitioning.
*
* @param partitioning the document partitioning
*/
public CStringAutoIndentStrategy(String partitioning, ICProject project) {
super();
fPartitioning = partitioning;
fProject = project;
}
private boolean isLineDelimiter(IDocument document, String text) {
String[] delimiters= document.getLegalLineDelimiters();
if (delimiters != null)
return TextUtilities.equals(delimiters, text) > -1;
return false;
}
private String getModifiedText(String string, CharSequence indentation, String delimiter) {
return displayString(string, indentation, delimiter);
}
private void indentStringAfterNewLine(IDocument document, DocumentCommand command) throws BadLocationException {
ITypedRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset, true);
int offset= partition.getOffset();
int length= partition.getLength();
if (command.offset == offset + length && document.getChar(offset + length - 1) == '\"')
return;
if (offset > 0 && document.getChar(offset - 1) == 'R') // raw string
return;
CHeuristicScanner scanner = new CHeuristicScanner(document);
CIndenter indenter = new CIndenter(document, scanner, fProject);
StringBuilder indentation = indenter.computeContinuationLineIndentation(offset);
if (indentation == null)
indentation = new StringBuilder();
String delimiter= TextUtilities.getDefaultLineDelimiter(document);
IPreferenceStore preferenceStore= CUIPlugin.getDefault().getPreferenceStore();
if (isLineDelimiter(document, command.text))
command.text= "\"" + command.text + indentation + "\""; //$NON-NLS-1$//$NON-NLS-2$
else if (command.text.length() > 1 && preferenceStore.getBoolean(PreferenceConstants.EDITOR_ESCAPE_STRINGS))
command.text= getModifiedText(command.text, indentation, delimiter);
}
private boolean isSmartMode() {
IWorkbenchPage page= CUIPlugin.getActivePage();
if (page != null) {
IEditorPart part= page.getActiveEditor();
if (part instanceof MultiPageEditorPart) {
part= (IEditorPart)part.getAdapter(ITextEditorExtension3.class);
}
if (part instanceof ITextEditorExtension3) {
ITextEditorExtension3 extension= (ITextEditorExtension3) part;
return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
}
}
return false;
}
/*
* @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
*/
@Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
try {
if (command.length != 0 || command.text == null)
return;
IPreferenceStore preferenceStore= CUIPlugin.getDefault().getPreferenceStore();
if (preferenceStore.getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS) && isSmartMode()) {
indentStringAfterNewLine(document, command);
}
} catch (BadLocationException e) {
}
}
}