Copyright (c) 2011, 2016 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2011, 2016 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.jdt.internal.ui.text.correction.proposals; import org.eclipse.text.edits.CopyTargetEdit; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MoveSourceEdit; import org.eclipse.text.edits.MoveTargetEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; import org.eclipse.text.edits.TextEditVisitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jdt.internal.core.manipulation.util.Strings;
Class to annotate edits made by a quick fix/assist to be shown via the quick fix pop-up preview. E.g. the added changes are shown in bold.
Since:3.8
/** * Class to annotate edits made by a quick fix/assist to be shown via the quick fix pop-up preview. * E.g. the added changes are shown in bold. * * @since 3.8 */
public class EditAnnotator extends TextEditVisitor { private int fWrittenToPos= 0; private final StringBuffer fBuf; private final IDocument fPreviewDocument; public EditAnnotator(StringBuffer buffer, IDocument previewDoc) { fBuf= buffer; fPreviewDocument= previewDoc; } public void unchangedUntil(int pos) { if (pos > fWrittenToPos) { appendContent(fPreviewDocument, fWrittenToPos, pos, true); fWrittenToPos= pos; } } @Override public boolean visit(MoveTargetEdit edit) { return true; //rangeAdded(edit); } @Override public boolean visit(CopyTargetEdit edit) { return true; //return rangeAdded(edit); } @Override public boolean visit(InsertEdit edit) { return rangeAdded(edit); } @Override public boolean visit(ReplaceEdit edit) { if (edit.getLength() > 0) return rangeAdded(edit); return rangeRemoved(edit); } @Override public boolean visit(MoveSourceEdit edit) { return rangeRemoved(edit); } @Override public boolean visit(DeleteEdit edit) { return rangeRemoved(edit); } protected boolean rangeRemoved(TextEdit edit) { unchangedUntil(edit.getOffset()); return false; } private boolean rangeAdded(TextEdit edit) { return annotateEdit(edit, "<b>", "</b>"); //$NON-NLS-1$ //$NON-NLS-2$ } protected boolean annotateEdit(TextEdit edit, String startTag, String endTag) { unchangedUntil(edit.getOffset()); fBuf.append(startTag); appendContent(fPreviewDocument, edit.getOffset(), edit.getExclusiveEnd(), false); fBuf.append(endTag); fWrittenToPos= edit.getExclusiveEnd(); return false; } private void appendContent(IDocument text, int startOffset, int endOffset, boolean surroundLinesOnly) { final int surroundLines= 1; try { int startLine= text.getLineOfOffset(startOffset); int endLine= text.getLineOfOffset(endOffset); boolean dotsAdded= false; if (surroundLinesOnly && startOffset == 0) { // no surround lines for the top no-change range startLine= Math.max(endLine - surroundLines, 0); fBuf.append("...<br>"); //$NON-NLS-1$ dotsAdded= true; } for (int i= startLine; i <= endLine; i++) { if (surroundLinesOnly) { if ((i - startLine > surroundLines) && (endLine - i > surroundLines)) { if (!dotsAdded) { fBuf.append("...<br>"); //$NON-NLS-1$ dotsAdded= true; } else if (endOffset == text.getLength()) { return; // no surround lines for the bottom no-change range } continue; } } IRegion lineInfo= text.getLineInformation(i); int start= lineInfo.getOffset(); int end= start + lineInfo.getLength(); int from= Math.max(start, startOffset); int to= Math.min(end, endOffset); String content= text.get(from, to - from); if (surroundLinesOnly && (from == start) && Strings.containsOnlyWhitespaces(content)) { continue; // ignore empty lines except when range started in the middle of a line } for (int k= 0; k < content.length(); k++) { char ch= content.charAt(k); switch (ch) { case '<': fBuf.append("&lt;"); //$NON-NLS-1$ break; case '>': fBuf.append("&gt;"); //$NON-NLS-1$ break; default: fBuf.append(ch); break; } } if (to == end && to != endOffset) { // new line when at the end of the line, and not end of range fBuf.append("<br>"); //$NON-NLS-1$ } } } catch (BadLocationException e) { // ignore } } }