1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text.java;
13 import net.sourceforge.phpdt.ui.PreferenceConstants;
14 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
16 import org.eclipse.jface.preference.IPreferenceStore;
17 import org.eclipse.jface.text.BadLocationException;
18 import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
19 import org.eclipse.jface.text.DocumentCommand;
20 import org.eclipse.jface.text.IDocument;
21 import org.eclipse.jface.text.IRegion;
22 import org.eclipse.jface.text.ITypedRegion;
23 import org.eclipse.jface.text.TextUtilities;
24 import org.eclipse.ui.IEditorPart;
25 import org.eclipse.ui.IWorkbenchPage;
26 import org.eclipse.ui.texteditor.ITextEditorExtension3;
29 * Auto indent strategy for double quoted PHP strings
31 public class JavaStringAutoIndentStrategyDQ extends
32 DefaultIndentLineAutoEditStrategy {
34 private String fPartitioning;
37 * The input string doesn't contain any line delimiter.
40 * the given input string
41 * @return the displayable string.
43 private String displayString (String inputString, String indentation, String delimiter) {
44 int length = inputString.length();
45 StringBuffer buffer = new StringBuffer(length);
46 java.util.StringTokenizer tokenizer =
47 new java.util.StringTokenizer (inputString, "\n\r", true); //$NON-NLS-1$
49 while (tokenizer.hasMoreTokens ()) {
50 String token = tokenizer.nextToken ();
52 if (token.equals ("\r")) { //$NON-NLS-1$
53 buffer.append ("\\r"); //$NON-NLS-1$
54 if (tokenizer.hasMoreTokens ()) {
55 token = tokenizer.nextToken();
57 if (token.equals("\n")) { //$NON-NLS-1$
58 buffer.append("\\n"); //$NON-NLS-1$
59 buffer.append("\" . " + delimiter); //$NON-NLS-1$
60 buffer.append(indentation);
61 buffer.append("\""); //$NON-NLS-1$
64 buffer.append("\" . " + delimiter); //$NON-NLS-1$
65 buffer.append(indentation);
66 buffer.append("\""); //$NON-NLS-1$
71 } else if (token.equals("\n")) { //$NON-NLS-1$
72 buffer.append("\\n"); //$NON-NLS-1$
73 buffer.append("\" . " + delimiter); //$NON-NLS-1$
74 buffer.append(indentation);
75 buffer.append("\""); //$NON-NLS-1$
79 StringBuffer tokenBuffer = new StringBuffer();
81 for (int i = 0; i < token.length(); i++) {
82 char c = token.charAt(i);
85 tokenBuffer.append("\\r"); //$NON-NLS-1$
88 tokenBuffer.append("\\n"); //$NON-NLS-1$
91 tokenBuffer.append("\\b"); //$NON-NLS-1$
95 tokenBuffer.append("\t"); //$NON-NLS-1$
98 tokenBuffer.append("\\f"); //$NON-NLS-1$
101 tokenBuffer.append("\\\""); //$NON-NLS-1$
104 tokenBuffer.append("\\'"); //$NON-NLS-1$
107 tokenBuffer.append("\\\\"); //$NON-NLS-1$
110 tokenBuffer.append(c);
113 buffer.append(tokenBuffer);
116 return buffer.toString();
120 * Creates a new Java string auto indent strategy for the given document
123 * @param partitioning
124 * the document partitioning
126 public JavaStringAutoIndentStrategyDQ (String partitioning) {
128 fPartitioning = partitioning;
132 * Check whether the 'text' is one of the allowed line delimiters (e.g. \n \r)
134 * @param document The document object for which we do the check
135 * @param text The text with the possible delimiter
137 * - true if 'text' is a valid delimiter
138 * - false if 'text' is not a valid delimiter
140 private boolean isLineDelimiter (IDocument document, String text) {
141 String[] delimiters = document.getLegalLineDelimiters();
143 if (delimiters != null) {
144 return TextUtilities.equals (delimiters, text) > -1;
151 * Get back the indentation of the line to which the offset belongs.
153 * It searches the first occurrence of a white space (non space/non tab)
158 * @throws BadLocationException
160 private String getLineIndentation (IDocument document, int offset)
161 throws BadLocationException {
162 String indentation = "";
167 // find start of line
168 int adjustedOffset = (offset == document.getLength() ? offset - 1 : offset);// Check whether the offset is not at the end of file
169 IRegion line = document.getLineInformationOfOffset (adjustedOffset); // Get the start and the length of the line
171 start = line.getOffset (); // Get the start of the line
172 end = findStringStart (document, start, offset);
174 IPreferenceStore preferenceStore = PHPeclipsePlugin.getDefault().getPreferenceStore();
176 int tabWidth = preferenceStore.getInt (PreferenceConstants.EDITOR_TAB_WIDTH);
178 for (int pos = start; pos < end; pos++) {
179 if (document.getChar (pos) == '\t') { // If the character is a tab
180 length += tabWidth; // take the tab width for calculating the indentation length
182 else { // If it's just a space
183 length++; // add one character to the indentation length
187 if (preferenceStore.getBoolean (PreferenceConstants.EDITOR_SPACES_FOR_TABS)) { // Indentation with spaces only
189 indentation = String.format ("%" + length + "s", "");
192 else { // Indentation with tabs
196 tabs = length / tabWidth;
197 spaces = length % tabWidth;
199 indentation = new String (new char[tabs]).replace('\0', '\t');
202 indentation += String.format ("%" + spaces + "s", "");
211 * Return the position of the string start (first occurrence of a quote or double quote)
218 private int findStringStart(IDocument document, int offset, int end) throws BadLocationException {
219 while (offset < end) {
220 char c = document.getChar (offset);
222 if ((c == '\'') || (c == '\"')) {
238 * @throws BadLocationException
240 private String getModifiedText (String string, String indentation, String delimiter)
241 throws BadLocationException {
242 return displayString (string, indentation, delimiter);
249 * @throws BadLocationException
251 private void javaStringIndentAfterNewLine (IDocument document, DocumentCommand command) throws BadLocationException {
252 ITypedRegion partition = TextUtilities.getPartition (document, fPartitioning, command.offset, false);
253 int offset = partition.getOffset();
254 int length = partition.getLength();
256 if (command.offset == offset) {
257 // we are really just before the string partition -> feet the event
258 // through the java indenter
260 // JavaAutoIndentStrategy(fPartitioning).customizeDocumentCommand(document,
265 if ((command.offset == offset + length) &&
266 (document.getChar (offset + length - 1) == '\"')) {
270 String indentation = getLineIndentation (document, command.offset);
271 String delimiter = TextUtilities.getDefaultLineDelimiter (document);
273 IRegion line = document.getLineInformationOfOffset (offset);
274 String string = document.get (line.getOffset(),
275 offset - line.getOffset()); // Get the current line as string
277 if (string.trim().length() != 0) {
278 indentation += String.valueOf ("\t\t"); //$NON-NLS-1$
281 IPreferenceStore preferenceStore = PHPeclipsePlugin.getDefault ().getPreferenceStore();
283 if (isLineDelimiter (document, command.text)) {
284 command.text = "\" ." + command.text + indentation + "\""; //$NON-NLS-1$//$NON-NLS-2$
286 else if ((command.text.length() > 1) &&
287 preferenceStore.getBoolean (PreferenceConstants.EDITOR_ESCAPE_STRINGS_DQ)) {
288 command.text = getModifiedText(command.text, indentation, delimiter);
296 private boolean isSmartMode () {
297 IWorkbenchPage page = PHPeclipsePlugin.getActivePage();
300 IEditorPart part = page.getActiveEditor ();
302 if (part instanceof ITextEditorExtension3) {
303 ITextEditorExtension3 extension = (ITextEditorExtension3) part;
304 return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
312 * @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(IDocument,
315 public void customizeDocumentCommand (IDocument document, DocumentCommand command) {
317 if ((command.length != 0) ||
318 (command.text == null)) {
322 IPreferenceStore preferenceStore = PHPeclipsePlugin.getDefault().getPreferenceStore();
324 if (preferenceStore.getBoolean (PreferenceConstants.EDITOR_WRAP_STRINGS_DQ) && isSmartMode ()) {
325 javaStringIndentAfterNewLine (document, command);
328 } catch (BadLocationException e) {