1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 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 *******************************************************************************/
12 package net.sourceforge.phpdt.internal.ui.text.phpdoc;
14 import java.text.BreakIterator;
16 import net.sourceforge.phpdt.core.ICompilationUnit;
17 import net.sourceforge.phpdt.core.IJavaElement;
18 import net.sourceforge.phpdt.core.IMethod;
19 import net.sourceforge.phpdt.core.ISourceRange;
20 import net.sourceforge.phpdt.core.IType;
21 import net.sourceforge.phpdt.internal.corext.util.Strings;
22 import net.sourceforge.phpdt.ui.CodeGeneration;
23 import net.sourceforge.phpdt.ui.IWorkingCopyManager;
24 import net.sourceforge.phpdt.ui.PreferenceConstants;
25 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
26 import net.sourceforge.phpeclipse.ui.WebUI;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.core.runtime.Preferences;
30 import org.eclipse.jface.preference.IPreferenceStore;
31 import org.eclipse.jface.text.BadLocationException;
32 import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
33 import org.eclipse.jface.text.DocumentCommand;
34 import org.eclipse.jface.text.IDocument;
35 import org.eclipse.jface.text.IRegion;
36 import org.eclipse.jface.text.ITypedRegion;
37 import org.eclipse.jface.text.TextUtilities;
38 import org.eclipse.ui.IEditorPart;
39 import org.eclipse.ui.IWorkbenchPage;
40 import org.eclipse.ui.IWorkbenchWindow;
41 import org.eclipse.ui.PlatformUI;
42 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
43 import org.eclipse.ui.texteditor.ITextEditorExtension3;
46 * Auto indent strategy for java doc comments
48 public class JavaDocAutoIndentStrategy extends
49 DefaultIndentLineAutoEditStrategy {
51 private String fPartitioning;
54 * Creates a new Javadoc auto indent strategy for the given document
58 * the document partitioning
60 public JavaDocAutoIndentStrategy(String partitioning) {
61 fPartitioning = partitioning;
64 private static String getLineDelimiter(IDocument document) {
66 if (document.getNumberOfLines() > 1)
67 return document.getLineDelimiter(0);
68 } catch (BadLocationException e) {
72 return System.getProperty("line.separator"); //$NON-NLS-1$
76 * Copies the indentation of the previous line and add a star. If the
77 * javadoc just started on this line add standard method tags and close the
81 * the document to work on
83 * the command to deal with
85 private void jdocIndentAfterNewLine(IDocument d, DocumentCommand c) {
87 if (c.offset == -1 || d.getLength() == 0)
92 int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
93 IRegion info = d.getLineInformationOfOffset(p);
94 int start = info.getOffset();
97 int end = findEndOfWhiteSpace(d, start, c.offset);
99 StringBuffer buf = new StringBuffer(c.text);
100 if (end >= start) { // 1GEYL1R: ITPJUI:ALL - java doc edit smartness
101 // not work for class comments
103 String indentation = jdocExtractLinePrefix(d, d
104 .getLineOfOffset(c.offset));
105 buf.append(indentation);
106 if (end < c.offset) {
107 if (d.getChar(end) == '/') {
108 // javadoc started on this line
109 buf.append(" * "); //$NON-NLS-1$
113 .getPreferenceStore()
115 PreferenceConstants.EDITOR_CLOSE_JAVADOCS)
116 && isNewComment(d, c.offset, fPartitioning)) {
117 String lineDelimiter = getLineDelimiter(d);
119 String endTag = lineDelimiter + indentation + " */"; //$NON-NLS-1$
120 d.replace(c.offset, 0, endTag); //$NON-NLS-1$
121 // evaluate method signature
122 ICompilationUnit unit = getCompilationUnit();
125 // (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS)
130 // JavaModelUtil.reconcile(unit);
131 // String string= createJavaDocTags(d, c,
132 // indentation, lineDelimiter, unit);
133 // if (string != null) {
134 // d.replace(c.offset, 0, string);
136 // } catch (CoreException e) {
146 c.text = buf.toString();
148 } catch (BadLocationException excp) {
153 private String createJavaDocTags(IDocument document,
154 DocumentCommand command, String indentation, String lineDelimiter,
155 ICompilationUnit unit) throws CoreException, BadLocationException {
156 IJavaElement element = unit.getElementAt(command.offset);
160 switch (element.getElementType()) {
161 case IJavaElement.TYPE:
162 return createTypeTags(document, command, indentation,
163 lineDelimiter, (IType) element);
165 case IJavaElement.METHOD:
166 return createMethodTags(document, command, indentation,
167 lineDelimiter, (IMethod) element);
175 * Removes start and end of a comment and corrects indentation and line
178 private String prepareTemplateComment(String comment, String indentation,
179 String lineDelimiter) {
180 // trim comment start and end if any
181 if (comment.endsWith("*/")) //$NON-NLS-1$
182 comment = comment.substring(0, comment.length() - 2);
183 comment = comment.trim();
184 if (comment.startsWith("/*")) { //$NON-NLS-1$
185 if (comment.length() > 2 && comment.charAt(2) == '*') {
186 comment = comment.substring(3); // remove '/**'
188 comment = comment.substring(2); // remove '/*'
191 // return Strings.changeIndent(comment, 0,
192 // CodeFormatterUtil.getTabWidth(), indentation, lineDelimiter);
193 return Strings.changeIndent(comment, 0, getTabWidth(), indentation,
197 public static int getTabWidth() {
198 Preferences preferences = WebUI.getDefault()
199 .getPluginPreferences();
201 .getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
204 private String createTypeTags(IDocument document, DocumentCommand command,
205 String indentation, String lineDelimiter, IType type)
206 throws CoreException {
207 String comment = CodeGeneration.getTypeComment(type
208 .getCompilationUnit(), type.getTypeQualifiedName('.'),
210 if (comment != null) {
211 return prepareTemplateComment(comment.trim(), indentation,
217 private String createMethodTags(IDocument document,
218 DocumentCommand command, String indentation, String lineDelimiter,
219 IMethod method) throws CoreException, BadLocationException {
220 IRegion partition = TextUtilities.getPartition(document, fPartitioning,
221 command.offset, false);
222 ISourceRange sourceRange = method.getSourceRange();
223 if (sourceRange == null
224 || sourceRange.getOffset() != partition.getOffset())
227 // IMethod inheritedMethod= getInheritedMethod(method);
228 // String comment= CodeGeneration.getMethodComment(method,
229 // inheritedMethod, lineDelimiter);
230 // if (comment != null) {
231 // comment= comment.trim();
232 // boolean javadocComment= comment.startsWith("/**"); //$NON-NLS-1$
233 // boolean isJavaDoc= partition.getLength() >= 3 &&
234 // document.get(partition.getOffset(), 3).equals("/**"); //$NON-NLS-1$
235 // if (javadocComment == isJavaDoc) {
236 // return prepareTemplateComment(comment, indentation, lineDelimiter);
243 * Returns the method inherited from, <code>null</code> if method is newly
246 // private static IMethod getInheritedMethod(IMethod method) throws
247 // JavaModelException {
248 // IType declaringType= method.getDeclaringType();
249 // ITypeHierarchy typeHierarchy=
250 // SuperTypeHierarchyCache.getTypeHierarchy(declaringType);
251 // return JavaModelUtil.findMethodDeclarationInHierarchy(typeHierarchy,
253 // method.getElementName(), method.getParameterTypes(),
254 // method.isConstructor());
256 protected void jdocIndentForCommentEnd(IDocument d, DocumentCommand c) {
257 if (c.offset < 2 || d.getLength() == 0) {
261 if ("* ".equals(d.get(c.offset - 2, 2))) { //$NON-NLS-1$
262 // modify document command
266 } catch (BadLocationException excp) {
272 * Guesses if the command operates within a newly created javadoc comment or
273 * not. If in doubt, it will assume that the javadoc is new.
275 private static boolean isNewComment(IDocument document, int commandOffset,
276 String partitioning) {
279 int lineIndex = document.getLineOfOffset(commandOffset) + 1;
280 if (lineIndex >= document.getNumberOfLines())
283 IRegion line = document.getLineInformation(lineIndex);
284 ITypedRegion partition = TextUtilities.getPartition(document,
285 partitioning, commandOffset, false);
286 int partitionEnd = partition.getOffset() + partition.getLength();
287 if (line.getOffset() >= partitionEnd)
290 if (document.getLength() == partitionEnd)
291 return true; // partition goes to end of document - probably
294 String comment = document.get(partition.getOffset(), partition
296 if (comment.indexOf("/*", 2) != -1) //$NON-NLS-1$
297 return true; // enclosed another comment -> probably a new
302 } catch (BadLocationException e) {
307 private boolean isSmartMode() {
308 IWorkbenchPage page = WebUI.getActivePage();
310 IEditorPart part = page.getActiveEditor();
311 if (part instanceof ITextEditorExtension3) {
312 ITextEditorExtension3 extension = (ITextEditorExtension3) part;
313 return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
320 * @see IAutoIndentStrategy#customizeDocumentCommand
322 public void customizeDocumentCommand(IDocument document,
323 DocumentCommand command) {
330 if (command.text != null && command.length == 0) {
331 String[] lineDelimiters = document.getLegalLineDelimiters();
332 int index = TextUtilities
333 .endsWith(lineDelimiters, command.text);
335 // ends with line delimiter
336 if (lineDelimiters[index].equals(command.text))
337 // just the line delimiter
338 jdocIndentAfterNewLine(document, command);
343 if (command.text != null && command.text.equals("/")) { //$NON-NLS-1$
344 jdocIndentForCommentEnd(document, command);
348 ITypedRegion partition = TextUtilities.getPartition(document,
349 fPartitioning, command.offset, true);
350 int partitionStart = partition.getOffset();
351 int partitionEnd = partition.getLength() + partitionStart;
353 String text = command.text;
354 int offset = command.offset;
355 int length = command.length;
358 final int PREFIX_LENGTH = "/*".length(); //$NON-NLS-1$
359 final int POSTFIX_LENGTH = "*/".length(); //$NON-NLS-1$
360 if ((offset < partitionStart + PREFIX_LENGTH || offset + length > partitionEnd
363 && text.length() >= 2
364 && ((text.indexOf("*/") != -1) || (document.getChar(offset) == '*' && text.startsWith("/")))) //$NON-NLS-1$ //$NON-NLS-2$
367 if (command.text == null || command.text.length() == 0)
368 jdocHandleBackspaceDelete(document, command);
370 else if (command.text != null && command.length == 0
371 && command.text.length() > 0)
372 jdocWrapParagraphOnInsert(document, command);
374 } catch (BadLocationException e) {
379 private void flushCommand(IDocument document, DocumentCommand command)
380 throws BadLocationException {
385 document.replace(command.offset, command.length, command.text);
387 command.doit = false;
388 if (command.text != null)
389 command.offset += command.text.length();
394 protected void jdocWrapParagraphOnInsert(IDocument document,
395 DocumentCommand command) throws BadLocationException {
397 // Assert.isTrue(command.length == 0);
398 // Assert.isTrue(command.text != null && command.text.length() == 1);
400 if (!getPreferenceStore().getBoolean(
401 PreferenceConstants.EDITOR_FORMAT_JAVADOCS))
404 int line = document.getLineOfOffset(command.offset);
405 IRegion region = document.getLineInformation(line);
406 int lineOffset = region.getOffset();
407 int lineLength = region.getLength();
409 String lineContents = document.get(lineOffset, lineLength);
410 StringBuffer buffer = new StringBuffer(lineContents);
411 int start = command.offset - lineOffset;
412 int end = command.length + start;
413 buffer.replace(start, end, command.text);
416 if (command.text != null && command.text.length() != 0
417 && command.text.trim().length() == 0) {
419 String endOfLine = document.get(command.offset, lineOffset
420 + lineLength - command.offset);
423 if (endOfLine.length() == 0) {
424 // move caret to next line
425 flushCommand(document, command);
427 if (isLineTooShort(document, line)) {
428 int[] caretOffset = { command.offset };
429 jdocWrapParagraphFromLine(document, line, caretOffset,
431 command.offset = caretOffset[0];
435 // move caret to next line if possible
436 if (line < document.getNumberOfLines() - 1
437 && isJavaDocLine(document, line + 1)) {
438 String lineDelimiter = document.getLineDelimiter(line);
439 String nextLinePrefix = jdocExtractLinePrefix(document,
441 command.offset += lineDelimiter.length()
442 + nextLinePrefix.length();
446 // inside whitespace at end of line
447 } else if (endOfLine.trim().length() == 0) {
448 // simply insert space
453 // change in prefix region
454 String prefix = jdocExtractLinePrefix(document, line);
455 boolean wrapAlways = command.offset >= lineOffset
456 && command.offset <= lineOffset + prefix.length();
458 // must insert the text now because it may include whitepace
459 flushCommand(document, command);
462 || calculateDisplayedWidth(buffer.toString()) > getMargin()
463 || isLineTooShort(document, line)) {
464 int[] caretOffset = { command.offset };
465 jdocWrapParagraphFromLine(document, line, caretOffset, wrapAlways);
468 command.offset = caretOffset[0];
473 * Method jdocWrapParagraphFromLine.
479 private void jdocWrapParagraphFromLine(IDocument document, int line,
480 int[] caretOffset, boolean always) throws BadLocationException {
482 String indent = jdocExtractLinePrefix(document, line);
484 if (!indent.trim().startsWith("*")) //$NON-NLS-1$
487 if (indent.trim().startsWith("*/")) //$NON-NLS-1$
490 if (!isLineTooLong(document, line)
491 && !isLineTooShort(document, line))
495 boolean caretRelativeToParagraphOffset = false;
496 int caret = caretOffset[0];
498 int caretLine = document.getLineOfOffset(caret);
499 int lineOffset = document.getLineOffset(line);
500 int paragraphOffset = lineOffset + indent.length();
501 if (paragraphOffset < caret) {
502 caret -= paragraphOffset;
503 caretRelativeToParagraphOffset = true;
508 StringBuffer buffer = new StringBuffer();
509 int currentLine = line;
510 while (line == currentLine || isJavaDocLine(document, currentLine)) {
512 if (buffer.length() != 0
513 && !Character.isWhitespace(buffer
514 .charAt(buffer.length() - 1))) {
516 if (currentLine <= caretLine) {
517 // in this case caretRelativeToParagraphOffset is always
523 String string = getLineContents(document, currentLine);
524 buffer.append(string);
527 String paragraph = buffer.toString();
529 if (paragraph.trim().length() == 0)
532 caretOffset[0] = caretRelativeToParagraphOffset ? caret : 0;
533 String delimiter = document.getLineDelimiter(0);
534 String wrapped = formatParagraph(paragraph, caretOffset, indent,
535 delimiter, getMargin());
537 int beginning = document.getLineOffset(line);
538 int end = document.getLineOffset(currentLine);
539 document.replace(beginning, end - beginning, wrapped.toString());
541 caretOffset[0] = caretRelativeToParagraphOffset ? caretOffset[0]
542 + beginning : caret + beginning;
546 * Line break iterator to handle whitespaces as first class citizens.
548 private static class LineBreakIterator {
550 private final String fString;
552 private final BreakIterator fIterator = BreakIterator.getLineInstance();
558 private int fBufferedEnd;
560 public LineBreakIterator(String string) {
562 fIterator.setText(string);
567 fStart = fIterator.first();
573 if (fBufferedEnd != -1) {
581 fEnd = fIterator.next();
583 if (fEnd == BreakIterator.DONE)
586 final String string = fString.substring(fStart, fEnd);
589 if (string.trim().length() == 0)
592 final String word = string.trim();
593 if (word.length() == string.length())
596 // suspected whitespace
598 return fStart + word.length();
603 * Formats a paragraph, using break iterator.
606 * an offset within the paragraph, which will be updated with
607 * respect to formatting.
609 private static String formatParagraph(String paragraph, int[] offset,
610 String prefix, String lineDelimiter, int margin) {
612 LineBreakIterator iterator = new LineBreakIterator(paragraph);
614 StringBuffer paragraphBuffer = new StringBuffer();
615 StringBuffer lineBuffer = new StringBuffer();
616 StringBuffer whiteSpaceBuffer = new StringBuffer();
618 int index = offset[0];
619 int indexBuffer = -1;
621 // line delimiter could be null
622 if (lineDelimiter == null)
623 lineDelimiter = ""; //$NON-NLS-1$
625 for (int start = iterator.first(), end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
628 String word = paragraph.substring(start, end);
630 // word is whitespace
631 if (word.trim().length() == 0) {
632 whiteSpaceBuffer.append(word);
634 // first word of line is always appended
635 } else if (lineBuffer.length() == 0) {
636 lineBuffer.append(prefix);
637 lineBuffer.append(whiteSpaceBuffer.toString());
638 lineBuffer.append(word);
641 String line = lineBuffer.toString()
642 + whiteSpaceBuffer.toString() + word.toString();
645 if (calculateDisplayedWidth(line) > margin) {
646 // flush line buffer and wrap paragraph
647 paragraphBuffer.append(lineBuffer.toString());
648 paragraphBuffer.append(lineDelimiter);
649 lineBuffer.setLength(0);
650 lineBuffer.append(prefix);
651 lineBuffer.append(word);
653 // flush index buffer
654 if (indexBuffer != -1) {
655 offset[0] = indexBuffer;
656 // correct for caret in whitespace at the end of line
657 if (whiteSpaceBuffer.length() != 0 && index < start
658 && index >= start - whiteSpaceBuffer.length())
659 offset[0] -= (index - (start - whiteSpaceBuffer
664 whiteSpaceBuffer.setLength(0);
666 // margin not exceeded
668 lineBuffer.append(whiteSpaceBuffer.toString());
669 lineBuffer.append(word);
670 whiteSpaceBuffer.setLength(0);
674 if (index >= start && index < end) {
675 indexBuffer = paragraphBuffer.length() + lineBuffer.length()
677 if (word.trim().length() != 0)
678 indexBuffer -= word.length();
683 paragraphBuffer.append(lineBuffer.toString());
684 paragraphBuffer.append(lineDelimiter);
686 // flush index buffer
687 if (indexBuffer != -1)
688 offset[0] = indexBuffer;
690 // last position is not returned by break iterator
691 else if (offset[0] == paragraph.length())
692 offset[0] = paragraphBuffer.length() - lineDelimiter.length();
694 return paragraphBuffer.toString();
697 private static IPreferenceStore getPreferenceStore() {
698 return WebUI.getDefault().getPreferenceStore();
702 * Returns the displayed width of a string, taking in account the displayed
703 * tab width. The result can be compared against the print margin.
705 private static int calculateDisplayedWidth(String string) {
707 int tabWidth = getPreferenceStore()
709 AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
714 for (int i = 0; i < string.length(); i++)
715 if ('\t' == string.charAt(i))
716 column += tabWidth - (column % tabWidth);
723 private String jdocExtractLinePrefix(IDocument d, int line)
724 throws BadLocationException {
726 IRegion region = d.getLineInformation(line);
727 int lineOffset = region.getOffset();
728 int index = findEndOfWhiteSpace(d, lineOffset, lineOffset
729 + d.getLineLength(line));
730 if (d.getChar(index) == '*') {
732 if (index != lineOffset + region.getLength()
733 && d.getChar(index) == ' ')
736 return d.get(lineOffset, index - lineOffset);
739 private String getLineContents(IDocument d, int line)
740 throws BadLocationException {
741 int offset = d.getLineOffset(line);
742 int length = d.getLineLength(line);
743 String lineDelimiter = d.getLineDelimiter(line);
744 if (lineDelimiter != null)
745 length = length - lineDelimiter.length();
746 String lineContents = d.get(offset, length);
747 int trim = jdocExtractLinePrefix(d, line).length();
748 return lineContents.substring(trim);
751 private static String getLine(IDocument document, int line)
752 throws BadLocationException {
753 IRegion region = document.getLineInformation(line);
754 return document.get(region.getOffset(), region.getLength());
758 * Returns <code>true</code> if the javadoc line is too short,
759 * <code>false</code> otherwise.
761 private boolean isLineTooShort(IDocument document, int line)
762 throws BadLocationException {
764 if (!isJavaDocLine(document, line + 1))
767 String nextLine = getLineContents(document, line + 1);
768 if (nextLine.trim().length() == 0)
775 * Returns <code>true</code> if the line is too long, <code>false</code>
778 private boolean isLineTooLong(IDocument document, int line)
779 throws BadLocationException {
780 String lineContents = getLine(document, line);
781 return calculateDisplayedWidth(lineContents) > getMargin();
784 private static int getMargin() {
785 return getPreferenceStore()
787 AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN);
790 private static final String[] fgInlineTags = {
791 "<b>", "<i>", "<em>", "<strong>", "<code>" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
794 private boolean isInlineTag(String string) {
795 for (int i = 0; i < fgInlineTags.length; i++)
796 if (string.startsWith(fgInlineTags[i]))
802 * returns true if the specified line is part of a paragraph and should be
803 * merged with the previous line.
805 private boolean isJavaDocLine(IDocument document, int line)
806 throws BadLocationException {
808 if (document.getNumberOfLines() < line)
811 int offset = document.getLineOffset(line);
812 int length = document.getLineLength(line);
813 int firstChar = findEndOfWhiteSpace(document, offset, offset + length);
814 length -= firstChar - offset;
815 String lineContents = document.get(firstChar, length);
817 String prefix = lineContents.trim();
818 if (!prefix.startsWith("*") || prefix.startsWith("*/")) //$NON-NLS-1$ //$NON-NLS-2$
821 lineContents = lineContents.substring(1).trim().toLowerCase();
823 // preserve empty lines
824 if (lineContents.length() == 0)
828 if (lineContents.startsWith("@")) //$NON-NLS-1$
831 // preserve HTML tags which are not inline
832 if (lineContents.startsWith("<") && !isInlineTag(lineContents)) //$NON-NLS-1$
838 protected void jdocHandleBackspaceDelete(IDocument document,
841 if (!getPreferenceStore().getBoolean(
842 PreferenceConstants.EDITOR_FORMAT_JAVADOCS))
846 String text = document.get(c.offset, c.length);
847 int line = document.getLineOfOffset(c.offset);
848 int lineOffset = document.getLineOffset(line);
850 // erase line delimiter
851 String lineDelimiter = document.getLineDelimiter(line);
852 if (lineDelimiter != null && lineDelimiter.equals(text)) {
854 String prefix = jdocExtractLinePrefix(document, line + 1);
856 // strip prefix if any
857 if (prefix.length() > 0) {
858 int length = document.getLineDelimiter(line).length()
860 document.replace(c.offset, length, null);
867 // backspace: beginning of a javadoc line
868 } else if (document.getChar(c.offset - 1) == '*'
869 && jdocExtractLinePrefix(document, line).length() - 1 >= c.offset
872 lineDelimiter = document.getLineDelimiter(line - 1);
873 String prefix = jdocExtractLinePrefix(document, line);
874 int length = (lineDelimiter != null ? lineDelimiter.length()
877 document.replace(c.offset - length + 1, length, null);
880 c.offset -= length - 1;
885 document.replace(c.offset, c.length, null);
890 } catch (BadLocationException e) {
895 int line = document.getLineOfOffset(c.offset);
896 int lineOffset = document.getLineOffset(line);
897 String prefix = jdocExtractLinePrefix(document, line);
898 boolean always = c.offset > lineOffset
899 && c.offset <= lineOffset + prefix.length();
900 int[] caretOffset = { c.offset };
901 jdocWrapParagraphFromLine(document, document
902 .getLineOfOffset(c.offset), caretOffset, always);
903 c.offset = caretOffset[0];
905 } catch (BadLocationException e) {
911 * Returns the compilation unit of the CompilationUnitEditor invoking the
912 * AutoIndentStrategy, might return <code>null</code> on error.
914 private static ICompilationUnit getCompilationUnit() {
916 IWorkbenchWindow window = PlatformUI.getWorkbench()
917 .getActiveWorkbenchWindow();
921 IWorkbenchPage page = window.getActivePage();
925 IEditorPart editor = page.getActiveEditor();
929 IWorkingCopyManager manager = WebUI.getDefault()
930 .getWorkingCopyManager();
931 ICompilationUnit unit = manager.getWorkingCopy(editor.getEditorInput());