/** * Copyright (c) 2015-2016 Angelo ZERR. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Angelo Zerr <[email protected]> - initial API and implementation * Lorenzo Dalla Vecchia <[email protected]> - made toTextEdit public */ package ts.eclipse.jface.text; import java.util.List; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; import org.eclipse.text.undo.DocumentUndoManagerRegistry; import org.eclipse.text.undo.IDocumentUndoManager; import ts.TypeScriptException; import ts.client.CodeEdit; import ts.client.Location; public class DocumentUtils { public static int getPosition(IDocument document, Location location) throws TypeScriptException { return getPosition(document, location.getLine(), location.getOffset()); } public static int getPosition(IDocument document, int line, int offset) throws TypeScriptException { if (document == null) { throw new TypeScriptException("document cannot be null"); } try { return document.getLineOffset(line - 1) + offset - 1; } catch (BadLocationException e) { throw new TypeScriptException(e); } } /** * Method will apply all edits to document as single modification. Needs to * be executed in UI thread. * * @param document * document to modify * @param edits * list of TypeScript {@link CodeEdit}. * @throws TypeScriptException * @throws BadLocationException * @throws MalformedTreeException */ public static void applyEdits(IDocument document, List<CodeEdit> codeEdits) throws TypeScriptException, MalformedTreeException, BadLocationException { if (document == null || codeEdits.isEmpty()) { return; } IDocumentUndoManager manager = DocumentUndoManagerRegistry.getDocumentUndoManager(document); if (manager != null) { manager.beginCompoundChange(); } try { TextEdit edit = toTextEdit(codeEdits, document); // RewriteSessionEditProcessor editProcessor = new // RewriteSessionEditProcessor(document, edit, // org.eclipse.text.edits.TextEdit.NONE); // editProcessor.performEdits(); edit.apply(document); } finally { if (manager != null) { manager.endCompoundChange(); } } } /** * Transforms a list of documents edits into a standard {@link TextEdit} * object that can be used for more complex operations, such as with the * refactoring API. * * @param codeEdits * list of TypeScript {@link CodeEdit}. * @param document * document to use as context for validating edit positions. * @return a {@link TextEdit} object. * @throws TypeScriptException */ public static TextEdit toTextEdit(List<CodeEdit> codeEdits, IDocument document) throws TypeScriptException { MultiTextEdit textEdit = new MultiTextEdit(); for (CodeEdit codeEdit : codeEdits) { toTextEdit(codeEdit, document, textEdit); } return textEdit; } private static void toTextEdit(CodeEdit codeEdit, IDocument document, MultiTextEdit textEdit) throws TypeScriptException { String newText = codeEdit.getNewText(); int startLine = codeEdit.getStart().getLine(); int startOffset = codeEdit.getStart().getOffset(); int endLine = codeEdit.getEnd().getLine(); int endOffset = codeEdit.getEnd().getOffset(); int start = DocumentUtils.getPosition(document, startLine, startOffset); int end = DocumentUtils.getPosition(document, endLine, endOffset); int length = end - start; if (newText.isEmpty()) { if (length > 0) { textEdit.addChild(new DeleteEdit(start, length)); } } else { if (length > 0) { textEdit.addChild(new ReplaceEdit(start, length, newText)); } else if (length == 0) { textEdit.addChild(new InsertEdit(start, newText)); } } } }