56d3d754f24205565d128b950d974b065aad5cc3
[phpeclipse.git] /
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text.java;
12
13 import net.sourceforge.phpdt.ui.PreferenceConstants;
14 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
15
16 import org.eclipse.jface.preference.IPreferenceStore;
17 import org.eclipse.jface.text.BadLocationException;
18 import org.eclipse.jface.text.DefaultAutoIndentStrategy;
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;
27
28
29 /**
30  * Auto indent strategy for java strings
31  */
32 public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy {
33         
34         private String fPartitioning;
35         
36         /**
37          * The input string doesn't contain any line delimiter.
38          * 
39          * @param inputString the given input string
40          * @return the displayable string.
41          */
42         private String displayString(String inputString, String indentation, String delimiter) {
43                 
44                 int length = inputString.length();
45                 StringBuffer buffer = new StringBuffer(length);
46                 java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(inputString, "\n\r", true); //$NON-NLS-1$
47                 while (tokenizer.hasMoreTokens()){
48         
49                         String token = tokenizer.nextToken();
50                         if (token.equals("\r")) { //$NON-NLS-1$
51                                 buffer.append("\\r"); //$NON-NLS-1$
52                                 if (tokenizer.hasMoreTokens()) {
53                                         token = tokenizer.nextToken();
54                                         if (token.equals("\n")) { //$NON-NLS-1$
55                                                 buffer.append("\\n"); //$NON-NLS-1$
56                                                 buffer.append("\" + " + delimiter); //$NON-NLS-1$
57                                                 buffer.append(indentation);
58                                                 buffer.append("\""); //$NON-NLS-1$
59                                                 continue;
60                                         } else {
61                                                 buffer.append("\" + " + delimiter); //$NON-NLS-1$
62                                                 buffer.append(indentation);
63                                                 buffer.append("\""); //$NON-NLS-1$
64                                         }
65                                 } else {
66                                         continue;
67                                 }
68                         } else if (token.equals("\n")) { //$NON-NLS-1$
69                                 buffer.append("\\n"); //$NON-NLS-1$
70                                 buffer.append("\" + " + delimiter); //$NON-NLS-1$
71                                 buffer.append(indentation);
72                                 buffer.append("\""); //$NON-NLS-1$
73                                 continue;
74                         }       
75         
76                         StringBuffer tokenBuffer = new StringBuffer();
77                         for (int i = 0; i < token.length(); i++){ 
78                                 char c = token.charAt(i);
79                                 switch (c) {
80                                         case '\r' :
81                                                 tokenBuffer.append("\\r"); //$NON-NLS-1$
82                                                 break;
83                                         case '\n' :
84                                                 tokenBuffer.append("\\n"); //$NON-NLS-1$
85                                                 break;
86                                         case '\b' :
87                                                 tokenBuffer.append("\\b"); //$NON-NLS-1$
88                                                 break;
89                                         case '\t' :
90                                                 // keep tabs verbatim
91                                                 tokenBuffer.append("\t"); //$NON-NLS-1$
92                                                 break;
93                                         case '\f' :
94                                                 tokenBuffer.append("\\f"); //$NON-NLS-1$
95                                                 break;
96                                         case '\"' :
97                                                 tokenBuffer.append("\\\""); //$NON-NLS-1$
98                                                 break;
99                                         case '\'' :
100                                                 tokenBuffer.append("\\'"); //$NON-NLS-1$
101                                                 break;
102                                         case '\\' :
103                                                 tokenBuffer.append("\\\\"); //$NON-NLS-1$
104                                                 break;
105                                         default :
106                                                 tokenBuffer.append(c);
107                                 }
108                         }
109                         buffer.append(tokenBuffer);
110                 }
111                 return buffer.toString();
112         }
113
114         /**
115          * Creates a new Java string auto indent strategy for the given document partitioning.
116          * 
117          * @param partitioning the document partitioning
118          */
119         public JavaStringAutoIndentStrategy(String partitioning) {
120                 super();
121                 fPartitioning= partitioning;
122         }
123         
124         private boolean isLineDelimiter(IDocument document, String text) {
125                 String[] delimiters= document.getLegalLineDelimiters();
126                 if (delimiters != null)
127                         return TextUtilities.equals(delimiters, text) > -1;
128                 return false;
129         }
130         
131         private String getLineIndentation(IDocument document, int offset) throws BadLocationException {
132
133                 // find start of line
134                 int adjustedOffset= (offset == document.getLength() ? offset  - 1 : offset);
135                 IRegion line= document.getLineInformationOfOffset(adjustedOffset);
136                 int start= line.getOffset();
137                                         
138                 // find white spaces
139                 int end= findEndOfWhiteSpace(document, start, offset);
140                 
141                 return document.get(start, end - start);
142         }
143
144         private String getModifiedText(String string, String indentation, String delimiter) throws BadLocationException {               
145                 return displayString(string, indentation, delimiter);
146         }
147
148         private void javaStringIndentAfterNewLine(IDocument document, DocumentCommand command) throws BadLocationException {
149
150                 ITypedRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset, false);
151                 int offset= partition.getOffset();
152                 int length= partition.getLength();
153
154                 if (command.offset == offset) {
155                         // we are really just before the string partition -> feet the event through the java indenter
156         //              new JavaAutoIndentStrategy(fPartitioning).customizeDocumentCommand(document, command);
157                         return;
158                 }
159                 
160                 if (command.offset == offset + length && document.getChar(offset + length - 1) == '\"')
161                         return;
162
163                 String indentation= getLineIndentation(document, command.offset);
164                 String delimiter= TextUtilities.getDefaultLineDelimiter(document);
165
166                 IRegion line= document.getLineInformationOfOffset(offset);
167                 String string= document.get(line.getOffset(), offset - line.getOffset());
168                 if (string.trim().length() != 0)
169                         indentation += String.valueOf("\t\t"); //$NON-NLS-1$
170                 
171                 IPreferenceStore preferenceStore= PHPeclipsePlugin.getDefault().getPreferenceStore();
172                 if (isLineDelimiter(document, command.text))
173                         command.text= "\" +" + command.text + indentation + "\"";  //$NON-NLS-1$//$NON-NLS-2$
174                 else if (command.text.length() > 1 && preferenceStore.getBoolean(PreferenceConstants.EDITOR_ESCAPE_STRINGS))
175                         command.text= getModifiedText(command.text, indentation, delimiter);            
176         }
177         
178         private boolean isSmartMode() {
179                 IWorkbenchPage page= PHPeclipsePlugin.getActivePage();
180                 if (page != null)  {
181                         IEditorPart part= page.getActiveEditor(); 
182                         if (part instanceof ITextEditorExtension3) {
183                                 ITextEditorExtension3 extension= (ITextEditorExtension3) part;
184                                 return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
185                         }
186                 }
187                 return false;
188         }
189
190         /*
191          * @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
192          */
193         public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
194                 try {
195                         if (command.length != 0 || command.text == null)
196                                 return;
197
198                         IPreferenceStore preferenceStore= PHPeclipsePlugin.getDefault().getPreferenceStore();
199                                 
200                         if (preferenceStore.getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS) && isSmartMode())
201                                 javaStringIndentAfterNewLine(document, command);
202                                 
203                 } catch (BadLocationException e) {
204                 }
205         }
206 }