--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.phpdoc;
+
+
+import java.text.BreakIterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.ui.CodeGeneration;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultAutoIndentStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+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.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+
+
+/**
+ * Auto indent strategy for java doc comments
+ */
+public class JavaDocAutoIndentStrategy extends DefaultAutoIndentStrategy {
+
+ private String fPartitioning;
+
+ /**
+ * Creates a new Javadoc auto indent strategy for the given document partitioning.
+ *
+ * @param partitioning the document partitioning
+ */
+ public JavaDocAutoIndentStrategy(String partitioning) {
+ fPartitioning= partitioning;
+ }
+
+ private static String getLineDelimiter(IDocument document) {
+ try {
+ if (document.getNumberOfLines() > 1)
+ return document.getLineDelimiter(0);
+ } catch (BadLocationException e) {
+ PHPeclipsePlugin.log(e);
+ }
+
+ return System.getProperty("line.separator"); //$NON-NLS-1$
+ }
+
+ /**
+ * Copies the indentation of the previous line and add a star.
+ * If the javadoc just started on this line add standard method tags
+ * and close the javadoc.
+ *
+ * @param d the document to work on
+ * @param c the command to deal with
+ */
+ private void jdocIndentAfterNewLine(IDocument d, DocumentCommand c) {
+
+ if (c.offset == -1 || d.getLength() == 0)
+ return;
+
+ try {
+ // find start of line
+ int p= (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+ IRegion info= d.getLineInformationOfOffset(p);
+ int start= info.getOffset();
+
+ // find white spaces
+ int end= findEndOfWhiteSpace(d, start, c.offset);
+
+ StringBuffer buf= new StringBuffer(c.text);
+ if (end >= start) { // 1GEYL1R: ITPJUI:ALL - java doc edit smartness not work for class comments
+ // append to input
+ String indentation= jdocExtractLinePrefix(d, d.getLineOfOffset(c.offset));
+ buf.append(indentation);
+ if (end < c.offset) {
+ if (d.getChar(end) == '/') {
+ // javadoc started on this line
+ buf.append(" * "); //$NON-NLS-1$
+
+ if (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CLOSE_JAVADOCS) && isNewComment(d, c.offset, fPartitioning)) {
+ String lineDelimiter= getLineDelimiter(d);
+
+ String endTag= lineDelimiter + indentation + " */"; //$NON-NLS-1$
+ d.replace(c.offset, 0, endTag); //$NON-NLS-1$
+ // evaluate method signature
+ ICompilationUnit unit= getCompilationUnit();
+
+// if (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS) &&
+// unit != null)
+// {
+// try {
+// JavaModelUtil.reconcile(unit);
+// String string= createJavaDocTags(d, c, indentation, lineDelimiter, unit);
+// if (string != null) {
+// d.replace(c.offset, 0, string);
+// }
+// } catch (CoreException e) {
+// // ignore
+// }
+// }
+ }
+
+ }
+ }
+ }
+
+ c.text= buf.toString();
+
+ } catch (BadLocationException excp) {
+ // stop work
+ }
+ }
+
+ private String createJavaDocTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, ICompilationUnit unit)
+ throws CoreException, BadLocationException
+ {
+ IJavaElement element= unit.getElementAt(command.offset);
+ if (element == null)
+ return null;
+
+ switch (element.getElementType()) {
+ case IJavaElement.TYPE:
+ return createTypeTags(document, command, indentation, lineDelimiter, (IType) element);
+
+ case IJavaElement.METHOD:
+ return createMethodTags(document, command, indentation, lineDelimiter, (IMethod) element);
+
+ default:
+ return null;
+ }
+ }
+
+ /*
+ * Removes start and end of a comment and corrects indentation and line delimiters.
+ */
+ private String prepareTemplateComment(String comment, String indentation, String lineDelimiter) {
+ // trim comment start and end if any
+ if (comment.endsWith("*/")) //$NON-NLS-1$
+ comment= comment.substring(0, comment.length() - 2);
+ comment= comment.trim();
+ if (comment.startsWith("/*")) { //$NON-NLS-1$
+ if (comment.length() > 2 && comment.charAt(2) == '*') {
+ comment= comment.substring(3); // remove '/**'
+ } else {
+ comment= comment.substring(2); // remove '/*'
+ }
+ }
+// return Strings.changeIndent(comment, 0, CodeFormatterUtil.getTabWidth(), indentation, lineDelimiter);
+ return Strings.changeIndent(comment, 0, getTabWidth(), indentation, lineDelimiter);
+ }
+
+ public static int getTabWidth() {
+ Preferences preferences= PHPeclipsePlugin.getDefault().getPluginPreferences();
+ return preferences.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+ }
+
+ private String createTypeTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, IType type)
+ throws CoreException
+ {
+ String comment= CodeGeneration.getTypeComment(type.getCompilationUnit(), type.getTypeQualifiedName('.'), lineDelimiter);
+ if (comment != null) {
+ return prepareTemplateComment(comment.trim(), indentation, lineDelimiter);
+ }
+ return null;
+ }
+
+ private String createMethodTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, IMethod method)
+ throws CoreException, BadLocationException
+ {
+ IRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset, false);
+ ISourceRange sourceRange= method.getSourceRange();
+ if (sourceRange == null || sourceRange.getOffset() != partition.getOffset())
+ return null;
+
+// IMethod inheritedMethod= getInheritedMethod(method);
+// String comment= CodeGeneration.getMethodComment(method, inheritedMethod, lineDelimiter);
+// if (comment != null) {
+// comment= comment.trim();
+// boolean javadocComment= comment.startsWith("/**"); //$NON-NLS-1$
+// boolean isJavaDoc= partition.getLength() >= 3 && document.get(partition.getOffset(), 3).equals("/**"); //$NON-NLS-1$
+// if (javadocComment == isJavaDoc) {
+// return prepareTemplateComment(comment, indentation, lineDelimiter);
+// }
+// }
+ return null;
+ }
+
+ /**
+ * Returns the method inherited from, <code>null</code> if method is newly defined.
+ */
+// private static IMethod getInheritedMethod(IMethod method) throws JavaModelException {
+// IType declaringType= method.getDeclaringType();
+// ITypeHierarchy typeHierarchy= SuperTypeHierarchyCache.getTypeHierarchy(declaringType);
+// return JavaModelUtil.findMethodDeclarationInHierarchy(typeHierarchy, declaringType,
+// method.getElementName(), method.getParameterTypes(), method.isConstructor());
+// }
+
+ protected void jdocIndentForCommentEnd(IDocument d, DocumentCommand c) {
+ if (c.offset < 2 || d.getLength() == 0) {
+ return;
+ }
+ try {
+ if ("* ".equals(d.get(c.offset - 2, 2))) { //$NON-NLS-1$
+ // modify document command
+ c.length++;
+ c.offset--;
+ }
+ } catch (BadLocationException excp) {
+ // stop work
+ }
+ }
+
+ /**
+ * Guesses if the command operates within a newly created javadoc comment or not.
+ * If in doubt, it will assume that the javadoc is new.
+ */
+ private static boolean isNewComment(IDocument document, int commandOffset, String partitioning) {
+
+ try {
+ int lineIndex= document.getLineOfOffset(commandOffset) + 1;
+ if (lineIndex >= document.getNumberOfLines())
+ return true;
+
+ IRegion line= document.getLineInformation(lineIndex);
+ ITypedRegion partition= TextUtilities.getPartition(document, partitioning, commandOffset, false);
+ int partitionEnd= partition.getOffset() + partition.getLength();
+ if (line.getOffset() >= partitionEnd)
+ return false;
+
+ if (document.getLength() == partitionEnd)
+ return true; // partition goes to end of document - probably a new comment
+
+ String comment= document.get(partition.getOffset(), partition.getLength());
+ if (comment.indexOf("/*", 2) != -1) //$NON-NLS-1$
+ return true; // enclosed another comment -> probably a new comment
+
+ return false;
+
+ } catch (BadLocationException e) {
+ return false;
+ }
+ }
+
+ private boolean isSmartMode() {
+ IWorkbenchPage page= PHPeclipsePlugin.getActivePage();
+ if (page != null) {
+ IEditorPart part= page.getActiveEditor();
+ if (part instanceof ITextEditorExtension3) {
+ ITextEditorExtension3 extension= (ITextEditorExtension3) part;
+ return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * @see IAutoIndentStrategy#customizeDocumentCommand
+ */
+ public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
+
+ if (!isSmartMode())
+ return;
+
+ try {
+
+ if (command.text != null && command.length == 0) {
+ String[] lineDelimiters= document.getLegalLineDelimiters();
+ int index= TextUtilities.endsWith(lineDelimiters, command.text);
+ if (index > -1) {
+ // ends with line delimiter
+ if (lineDelimiters[index].equals(command.text))
+ // just the line delimiter
+ jdocIndentAfterNewLine(document, command);
+ return;
+ }
+ }
+
+ if (command.text != null && command.text.equals("/")) { //$NON-NLS-1$
+ jdocIndentForCommentEnd(document, command);
+ return;
+ }
+
+ ITypedRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset, true);
+ int partitionStart= partition.getOffset();
+ int partitionEnd= partition.getLength() + partitionStart;
+
+ String text= command.text;
+ int offset= command.offset;
+ int length= command.length;
+
+ // partition change
+ final int PREFIX_LENGTH= "/*".length(); //$NON-NLS-1$
+ final int POSTFIX_LENGTH= "*/".length(); //$NON-NLS-1$
+ if ((offset < partitionStart + PREFIX_LENGTH || offset + length > partitionEnd - POSTFIX_LENGTH) ||
+ text != null && text.length() >= 2 && ((text.indexOf("*/") != -1) || (document.getChar(offset) == '*' && text.startsWith("/")))) //$NON-NLS-1$ //$NON-NLS-2$
+ return;
+
+ if (command.text == null || command.text.length() == 0)
+ jdocHandleBackspaceDelete(document, command);
+
+ else if (command.text != null && command.length == 0 && command.text.length() > 0)
+ jdocWrapParagraphOnInsert(document, command);
+
+ } catch (BadLocationException e) {
+ PHPeclipsePlugin.log(e);
+ }
+ }
+
+ private void flushCommand(IDocument document, DocumentCommand command) throws BadLocationException {
+
+ if (!command.doit)
+ return;
+
+ document.replace(command.offset, command.length, command.text);
+
+ command.doit= false;
+ if (command.text != null)
+ command.offset += command.text.length();
+ command.length= 0;
+ command.text= null;
+ }
+
+ protected void jdocWrapParagraphOnInsert(IDocument document, DocumentCommand command) throws BadLocationException {
+
+// Assert.isTrue(command.length == 0);
+// Assert.isTrue(command.text != null && command.text.length() == 1);
+
+ if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FORMAT_JAVADOCS))
+ return;
+
+ int line= document.getLineOfOffset(command.offset);
+ IRegion region= document.getLineInformation(line);
+ int lineOffset= region.getOffset();
+ int lineLength= region.getLength();
+
+ String lineContents= document.get(lineOffset, lineLength);
+ StringBuffer buffer= new StringBuffer(lineContents);
+ int start= command.offset - lineOffset;
+ int end= command.length + start;
+ buffer.replace(start, end, command.text);
+
+ // handle whitespace
+ if (command.text != null && command.text.length() != 0 && command.text.trim().length() == 0) {
+
+ String endOfLine= document.get(command.offset, lineOffset + lineLength - command.offset);
+
+ // end of line
+ if (endOfLine.length() == 0) {
+ // move caret to next line
+ flushCommand(document, command);
+
+ if (isLineTooShort(document, line)) {
+ int[] caretOffset= {command.offset};
+ jdocWrapParagraphFromLine(document, line, caretOffset, false);
+ command.offset= caretOffset[0];
+ return;
+ }
+
+ // move caret to next line if possible
+ if (line < document.getNumberOfLines() - 1 && isJavaDocLine(document, line + 1)) {
+ String lineDelimiter= document.getLineDelimiter(line);
+ String nextLinePrefix= jdocExtractLinePrefix(document, line + 1);
+ command.offset += lineDelimiter.length() + nextLinePrefix.length();
+ }
+ return;
+
+ // inside whitespace at end of line
+ } else if (endOfLine.trim().length() == 0) {
+ // simply insert space
+ return;
+ }
+ }
+
+ // change in prefix region
+ String prefix= jdocExtractLinePrefix(document, line);
+ boolean wrapAlways= command.offset >= lineOffset && command.offset <= lineOffset + prefix.length();
+
+ // must insert the text now because it may include whitepace
+ flushCommand(document, command);
+
+ if (wrapAlways || calculateDisplayedWidth(buffer.toString()) > getMargin() || isLineTooShort(document, line)) {
+ int[] caretOffset= {command.offset};
+ jdocWrapParagraphFromLine(document, line, caretOffset, wrapAlways);
+
+ if (!wrapAlways)
+ command.offset= caretOffset[0];
+ }
+ }
+
+ /**
+ * Method jdocWrapParagraphFromLine.
+ *
+ * @param document
+ * @param line
+ * @param always
+ */
+ private void jdocWrapParagraphFromLine(IDocument document, int line, int[] caretOffset, boolean always) throws BadLocationException {
+
+ String indent= jdocExtractLinePrefix(document, line);
+ if (!always) {
+ if (!indent.trim().startsWith("*")) //$NON-NLS-1$
+ return;
+
+ if (indent.trim().startsWith("*/")) //$NON-NLS-1$
+ return;
+
+ if (!isLineTooLong(document, line) && !isLineTooShort(document, line))
+ return;
+ }
+
+ boolean caretRelativeToParagraphOffset= false;
+ int caret= caretOffset[0];
+
+ int caretLine= document.getLineOfOffset(caret);
+ int lineOffset= document.getLineOffset(line);
+ int paragraphOffset= lineOffset + indent.length();
+ if (paragraphOffset < caret) {
+ caret -= paragraphOffset;
+ caretRelativeToParagraphOffset= true;
+ } else {
+ caret -= lineOffset;
+ }
+
+ StringBuffer buffer= new StringBuffer();
+ int currentLine= line;
+ while (line == currentLine || isJavaDocLine(document, currentLine)) {
+
+ if (buffer.length() != 0 && !Character.isWhitespace(buffer.charAt(buffer.length() - 1))) {
+ buffer.append(' ');
+ if (currentLine <= caretLine) {
+ // in this case caretRelativeToParagraphOffset is always true
+ ++caret;
+ }
+ }
+
+ String string= getLineContents(document, currentLine);
+ buffer.append(string);
+ currentLine++;
+ }
+ String paragraph= buffer.toString();
+
+ if (paragraph.trim().length() == 0)
+ return;
+
+ caretOffset[0]= caretRelativeToParagraphOffset ? caret : 0;
+ String delimiter= document.getLineDelimiter(0);
+ String wrapped= formatParagraph(paragraph, caretOffset, indent, delimiter, getMargin());
+
+ int beginning= document.getLineOffset(line);
+ int end= document.getLineOffset(currentLine);
+ document.replace(beginning, end - beginning, wrapped.toString());
+
+ caretOffset[0]= caretRelativeToParagraphOffset ? caretOffset[0] + beginning : caret + beginning;
+ }
+
+ /**
+ * Line break iterator to handle whitespaces as first class citizens.
+ */
+ private static class LineBreakIterator {
+
+ private final String fString;
+ private final BreakIterator fIterator= BreakIterator.getLineInstance();
+
+ private int fStart;
+ private int fEnd;
+ private int fBufferedEnd;
+
+ public LineBreakIterator(String string) {
+ fString= string;
+ fIterator.setText(string);
+ }
+
+ public int first() {
+ fBufferedEnd= -1;
+ fStart= fIterator.first();
+ return fStart;
+ }
+
+ public int next() {
+
+ if (fBufferedEnd != -1) {
+ fStart= fEnd;
+ fEnd= fBufferedEnd;
+ fBufferedEnd= -1;
+ return fEnd;
+ }
+
+ fStart= fEnd;
+ fEnd= fIterator.next();
+
+ if (fEnd == BreakIterator.DONE)
+ return fEnd;
+
+ final String string= fString.substring(fStart, fEnd);
+
+ // whitespace
+ if (string.trim().length() == 0)
+ return fEnd;
+
+ final String word= string.trim();
+ if (word.length() == string.length())
+ return fEnd;
+
+ // suspected whitespace
+ fBufferedEnd= fEnd;
+ return fStart + word.length();
+ }
+ }
+
+ /**
+ * Formats a paragraph, using break iterator.
+ *
+ * @param offset an offset within the paragraph, which will be updated with respect to formatting.
+ */
+ private static String formatParagraph(String paragraph, int[] offset, String prefix, String lineDelimiter, int margin) {
+
+ LineBreakIterator iterator= new LineBreakIterator(paragraph);
+
+ StringBuffer paragraphBuffer= new StringBuffer();
+ StringBuffer lineBuffer= new StringBuffer();
+ StringBuffer whiteSpaceBuffer= new StringBuffer();
+
+ int index= offset[0];
+ int indexBuffer= -1;
+
+ // line delimiter could be null
+ if (lineDelimiter == null)
+ lineDelimiter= ""; //$NON-NLS-1$
+
+ for (int start= iterator.first(), end= iterator.next(); end != BreakIterator.DONE; start= end, end= iterator.next()) {
+
+ String word= paragraph.substring(start, end);
+
+ // word is whitespace
+ if (word.trim().length() == 0) {
+ whiteSpaceBuffer.append(word);
+
+ // first word of line is always appended
+ } else if (lineBuffer.length() == 0) {
+ lineBuffer.append(prefix);
+ lineBuffer.append(whiteSpaceBuffer.toString());
+ lineBuffer.append(word);
+
+ } else {
+ String line= lineBuffer.toString() + whiteSpaceBuffer.toString() + word.toString();
+
+ // margin exceeded
+ if (calculateDisplayedWidth(line) > margin) {
+ // flush line buffer and wrap paragraph
+ paragraphBuffer.append(lineBuffer.toString());
+ paragraphBuffer.append(lineDelimiter);
+ lineBuffer.setLength(0);
+ lineBuffer.append(prefix);
+ lineBuffer.append(word);
+
+ // flush index buffer
+ if (indexBuffer != -1) {
+ offset[0]= indexBuffer;
+ // correct for caret in whitespace at the end of line
+ if (whiteSpaceBuffer.length() != 0 && index < start && index >= start - whiteSpaceBuffer.length())
+ offset[0] -= (index - (start - whiteSpaceBuffer.length()));
+ indexBuffer= -1;
+ }
+
+ whiteSpaceBuffer.setLength(0);
+
+ // margin not exceeded
+ } else {
+ lineBuffer.append(whiteSpaceBuffer.toString());
+ lineBuffer.append(word);
+ whiteSpaceBuffer.setLength(0);
+ }
+ }
+
+ if (index >= start && index < end) {
+ indexBuffer= paragraphBuffer.length() + lineBuffer.length() + (index - start);
+ if (word.trim().length() != 0)
+ indexBuffer -= word.length();
+ }
+ }
+
+ // flush line buffer
+ paragraphBuffer.append(lineBuffer.toString());
+ paragraphBuffer.append(lineDelimiter);
+
+ // flush index buffer
+ if (indexBuffer != -1)
+ offset[0]= indexBuffer;
+
+ // last position is not returned by break iterator
+ else if (offset[0] == paragraph.length())
+ offset[0]= paragraphBuffer.length() - lineDelimiter.length();
+
+ return paragraphBuffer.toString();
+ }
+
+ private static IPreferenceStore getPreferenceStore() {
+ return PHPeclipsePlugin.getDefault().getPreferenceStore();
+ }
+
+ /**
+ * Returns the displayed width of a string, taking in account the displayed tab width.
+ * The result can be compared against the print margin.
+ */
+ private static int calculateDisplayedWidth(String string) {
+
+ int tabWidth= getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+ if (tabWidth<=0) {
+ tabWidth = 2;
+ }
+ int column= 0;
+ for (int i= 0; i < string.length(); i++)
+ if ('\t' == string.charAt(i))
+ column += tabWidth - (column % tabWidth);
+ else
+ column++;
+
+ return column;
+ }
+
+ private String jdocExtractLinePrefix(IDocument d, int line) throws BadLocationException {
+
+ IRegion region= d.getLineInformation(line);
+ int lineOffset= region.getOffset();
+ int index= findEndOfWhiteSpace(d, lineOffset, lineOffset + d.getLineLength(line));
+ if (d.getChar(index) == '*') {
+ index++;
+ if (index != lineOffset + region.getLength() &&d.getChar(index) == ' ')
+ index++;
+ }
+ return d.get(lineOffset, index - lineOffset);
+ }
+
+ private String getLineContents(IDocument d, int line) throws BadLocationException {
+ int offset = d.getLineOffset(line);
+ int length = d.getLineLength(line);
+ String lineDelimiter= d.getLineDelimiter(line);
+ if (lineDelimiter != null)
+ length= length - lineDelimiter.length();
+ String lineContents = d.get(offset, length);
+ int trim = jdocExtractLinePrefix(d, line).length();
+ return lineContents.substring(trim);
+ }
+
+ private static String getLine(IDocument document, int line) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ return document.get(region.getOffset(), region.getLength());
+ }
+
+ /**
+ * Returns <code>true</code> if the javadoc line is too short, <code>false</code> otherwise.
+ */
+ private boolean isLineTooShort(IDocument document, int line) throws BadLocationException {
+
+ if (!isJavaDocLine(document, line + 1))
+ return false;
+
+ String nextLine= getLineContents(document, line + 1);
+ if (nextLine.trim().length() == 0)
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Returns <code>true</code> if the line is too long, <code>false</code> otherwise.
+ */
+ private boolean isLineTooLong(IDocument document, int line) throws BadLocationException {
+ String lineContents= getLine(document, line);
+ return calculateDisplayedWidth(lineContents) > getMargin();
+ }
+
+ private static int getMargin() {
+ return getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN);
+ }
+
+ private static final String[] fgInlineTags= {
+ "<b>", "<i>", "<em>", "<strong>", "<code>" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ };
+
+ private boolean isInlineTag(String string) {
+ for (int i= 0; i < fgInlineTags.length; i++)
+ if (string.startsWith(fgInlineTags[i]))
+ return true;
+ return false;
+ }
+
+ /**
+ * returns true if the specified line is part of a paragraph and should be merged with
+ * the previous line.
+ */
+ private boolean isJavaDocLine(IDocument document, int line) throws BadLocationException {
+
+ if (document.getNumberOfLines() < line)
+ return false;
+
+ int offset= document.getLineOffset(line);
+ int length= document.getLineLength(line);
+ int firstChar= findEndOfWhiteSpace(document, offset, offset + length);
+ length -= firstChar - offset;
+ String lineContents= document.get(firstChar, length);
+
+ String prefix= lineContents.trim();
+ if (!prefix.startsWith("*") || prefix.startsWith("*/")) //$NON-NLS-1$ //$NON-NLS-2$
+ return false;
+
+ lineContents= lineContents.substring(1).trim().toLowerCase();
+
+ // preserve empty lines
+ if (lineContents.length() == 0)
+ return false;
+
+ // preserve @TAGS
+ if (lineContents.startsWith("@")) //$NON-NLS-1$
+ return false;
+
+ // preserve HTML tags which are not inline
+ if (lineContents.startsWith("<") && !isInlineTag(lineContents)) //$NON-NLS-1$
+ return false;
+
+ return true;
+ }
+
+ protected void jdocHandleBackspaceDelete(IDocument document, DocumentCommand c) {
+
+ if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FORMAT_JAVADOCS))
+ return;
+
+ try {
+ String text= document.get(c.offset, c.length);
+ int line= document.getLineOfOffset(c.offset);
+ int lineOffset= document.getLineOffset(line);
+
+ // erase line delimiter
+ String lineDelimiter= document.getLineDelimiter(line);
+ if (lineDelimiter != null && lineDelimiter.equals(text)) {
+
+ String prefix= jdocExtractLinePrefix(document, line + 1);
+
+ // strip prefix if any
+ if (prefix.length() > 0) {
+ int length= document.getLineDelimiter(line).length() + prefix.length();
+ document.replace(c.offset, length, null);
+
+ c.doit= false;
+ c.length= 0;
+ return;
+ }
+
+ // backspace: beginning of a javadoc line
+ } else if (document.getChar(c.offset - 1) == '*' && jdocExtractLinePrefix(document, line).length() - 1 >= c.offset - lineOffset) {
+
+ lineDelimiter= document.getLineDelimiter(line - 1);
+ String prefix= jdocExtractLinePrefix(document, line);
+ int length= (lineDelimiter != null ? lineDelimiter.length() : 0) + prefix.length();
+ document.replace(c.offset - length + 1, length, null);
+
+ c.doit= false;
+ c.offset -= length - 1;
+ c.length= 0;
+ return;
+
+ } else {
+ document.replace(c.offset, c.length, null);
+ c.doit= false;
+ c.length= 0;
+ }
+
+ } catch (BadLocationException e) {
+ PHPeclipsePlugin.log(e);
+ }
+
+ try {
+ int line= document.getLineOfOffset(c.offset);
+ int lineOffset= document.getLineOffset(line);
+ String prefix= jdocExtractLinePrefix(document, line);
+ boolean always= c.offset > lineOffset && c.offset <= lineOffset + prefix.length();
+ int[] caretOffset= {c.offset};
+ jdocWrapParagraphFromLine(document, document.getLineOfOffset(c.offset), caretOffset, always);
+ c.offset= caretOffset[0];
+
+ } catch (BadLocationException e) {
+ PHPeclipsePlugin.log(e);
+ }
+ }
+
+ /**
+ * Returns the compilation unit of the CompilationUnitEditor invoking the AutoIndentStrategy,
+ * might return <code>null</code> on error.
+ */
+ private static ICompilationUnit getCompilationUnit() {
+
+ IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null)
+ return null;
+
+ IWorkbenchPage page= window.getActivePage();
+ if (page == null)
+ return null;
+
+ IEditorPart editor= page.getActiveEditor();
+ if (editor == null)
+ return null;
+
+ IWorkingCopyManager manager= PHPeclipsePlugin.getDefault().getWorkingCopyManager();
+ ICompilationUnit unit= manager.getWorkingCopy(editor.getEditorInput());
+ if (unit == null)
+ return null;
+
+ return unit;
+ }
+
+}
import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy;
import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaInformationProvider;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.JavaDocAutoIndentStrategy;
import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor;
import net.sourceforge.phpdt.ui.PreferenceConstants;
fPreferenceStore = preferenceStore;
fTextEditor = editor;
fDocumentPartitioning = partitioning;
-// fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
+ // fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools();
xmlConfiguration = new XMLConfiguration(fXMLTextTools);
- fColorManager= colorManager;
- fPreferenceStore= preferenceStore;
- fTextEditor= editor;
- fDocumentPartitioning= partitioning;
-
+ fColorManager = colorManager;
+ fPreferenceStore = preferenceStore;
+ fTextEditor = editor;
+ fDocumentPartitioning = partitioning;
+
initializeScanners();
}
/**
- * Creates a new Java source viewer configuration for viewers in the given editor
- * using the given Java tools.
- *
- * @param tools the Java text tools to be used
- * @param editor the editor in which the configured viewer(s) will reside
- * @see JavaTextTools
- * @deprecated As of 3.0, replaced by {@link JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager, IPreferenceStore, ITextEditor, String)}
- */
-// public PHPSourceViewerConfiguration(JavaTextTools tools, PHPEditor editor, String partitioning) {
-// fJavaTextTools = tools;
-// fColorManager = tools.getColorManager();
-// fPreferenceStore = createPreferenceStore();
-// fDocumentPartitioning = partitioning;
-// fCodeScanner = (AbstractJavaScanner) fJavaTextTools.getCodeScanner();
-// fMultilineCommentScanner = (AbstractJavaScanner) fJavaTextTools.getMultilineCommentScanner();
-// fSinglelineCommentScanner = (AbstractJavaScanner) fJavaTextTools.getSinglelineCommentScanner();
-// fStringScanner = (AbstractJavaScanner) fJavaTextTools.getStringScanner();
-// fJavaDocScanner = (AbstractJavaScanner) fJavaTextTools.getJavaDocScanner();
-// fTextEditor = editor;
-// fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools();
-// xmlConfiguration = new XMLConfiguration(fXMLTextTools);
-// }
-
+ * Creates a new Java source viewer configuration for viewers in the given editor using the given Java tools.
+ *
+ * @param tools
+ * the Java text tools to be used
+ * @param editor
+ * the editor in which the configured viewer(s) will reside
+ * @see JavaTextTools
+ * @deprecated As of 3.0, replaced by
+ * {@link JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager, IPreferenceStore, ITextEditor, String)}
+ */
+ // public PHPSourceViewerConfiguration(JavaTextTools tools, PHPEditor editor, String partitioning) {
+ // fJavaTextTools = tools;
+ // fColorManager = tools.getColorManager();
+ // fPreferenceStore = createPreferenceStore();
+ // fDocumentPartitioning = partitioning;
+ // fCodeScanner = (AbstractJavaScanner) fJavaTextTools.getCodeScanner();
+ // fMultilineCommentScanner = (AbstractJavaScanner) fJavaTextTools.getMultilineCommentScanner();
+ // fSinglelineCommentScanner = (AbstractJavaScanner) fJavaTextTools.getSinglelineCommentScanner();
+ // fStringScanner = (AbstractJavaScanner) fJavaTextTools.getStringScanner();
+ // fJavaDocScanner = (AbstractJavaScanner) fJavaTextTools.getJavaDocScanner();
+ // fTextEditor = editor;
+ // fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools();
+ // xmlConfiguration = new XMLConfiguration(fXMLTextTools);
+ // }
/**
* Returns the color manager for this configuration.
*
* (non-Javadoc) Method declared on SourceViewerConfiguration
*/
public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer, String contentType) {
+ if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(contentType)
+ || IPHPPartitions.PHP_MULTILINE_COMMENT.equals(contentType))
+ return new JavaDocAutoIndentStrategy(getConfiguredDocumentPartitioning(sourceViewer));
if (IPHPPartitions.PHP_STRING_DQ.equals(contentType))
return new JavaStringAutoIndentStrategyDQ(getConfiguredDocumentPartitioning(sourceViewer));
if (IPHPPartitions.PHP_STRING_SQ.equals(contentType))
protected RuleBasedScanner getCodeScanner() {
return fCodeScanner; //fJavaTextTools.getCodeScanner();
}
- /**
- * Returns the Java multi-line comment scanner for this configuration.
- *
- * @return the Java multi-line comment scanner
- * @since 2.0
- */
- protected RuleBasedScanner getMultilineCommentScanner() {
- return fMultilineCommentScanner;
- }
-
- /**
- * Returns the Java single-line comment scanner for this configuration.
- *
- * @return the Java single-line comment scanner
- * @since 2.0
- */
- protected RuleBasedScanner getSinglelineCommentScanner() {
- return fSinglelineCommentScanner;
- }
-
- /**
- * Returns the Java string scanner for this configuration.
- *
- * @return the Java string scanner
- * @since 2.0
- */
- protected RuleBasedScanner getStringScanner() {
- return fStringScanner;
- }
+
+ /**
+ * Returns the Java multi-line comment scanner for this configuration.
+ *
+ * @return the Java multi-line comment scanner
+ * @since 2.0
+ */
+ protected RuleBasedScanner getMultilineCommentScanner() {
+ return fMultilineCommentScanner;
+ }
+
+ /**
+ * Returns the Java single-line comment scanner for this configuration.
+ *
+ * @return the Java single-line comment scanner
+ * @since 2.0
+ */
+ protected RuleBasedScanner getSinglelineCommentScanner() {
+ return fSinglelineCommentScanner;
+ }
+
+ /**
+ * Returns the Java string scanner for this configuration.
+ *
+ * @return the Java string scanner
+ * @since 2.0
+ */
+ protected RuleBasedScanner getStringScanner() {
+ return fStringScanner;
+ }
+
/**
* Returns the HTML source code scanner for this configuration.
*
*
* @return the Smarty source code scanner
*/
-// protected RuleBasedScanner getSmartyScanner() {
-// return fJavaTextTools.getSmartyScanner();
-// }
-
+ // protected RuleBasedScanner getSmartyScanner() {
+ // return fJavaTextTools.getSmartyScanner();
+ // }
/*
* @see SourceViewerConfiguration#getReconciler(ISourceViewer)
*/
*
* @return the SmartyDoc source code scanner
*/
-// protected RuleBasedScanner getSmartyDocScanner() {
-// return fJavaTextTools.getSmartyDocScanner();
-// }
-
+ // protected RuleBasedScanner getSmartyDocScanner() {
+ // return fJavaTextTools.getSmartyDocScanner();
+ // }
/**
* Returns the PHPDoc source code scanner for this configuration.
*
// dr = new DefaultDamagerRepairer(getHTMLScanner());
// reconciler.setDamager(dr, IPHPPartitions.JS_MULTILINE_COMMENT);
// reconciler.setRepairer(dr, IPHPPartitions.JS_MULTILINE_COMMENT);
-// DefaultDamagerRepairer phpDR = new DefaultDamagerRepairer(getSmartyScanner());
-// phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY);
-// phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY);
-// phpDR = new DefaultDamagerRepairer(getSmartyDocScanner());
-// phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
-// phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+ // DefaultDamagerRepairer phpDR = new DefaultDamagerRepairer(getSmartyScanner());
+ // phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY);
+ // phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY);
+ // phpDR = new DefaultDamagerRepairer(getSmartyDocScanner());
+ // phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+ // phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
// dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
// PHPColorProvider.MULTI_LINE_COMMENT))));
// reconciler.setDamager(dr, IPHPPartitions.HTML_MULTILINE_COMMENT);