blob: dcc205ee181b72c33cd2c44569ed840725a1e289 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 2020 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.editors;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.internal.r.ui.RUIMessages;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.model.core.ModelManager;
import org.eclipse.statet.ltk.model.core.element.SourceDocumentRunnable;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditorProgressHandler;
import org.eclipse.statet.r.core.rsource.ast.SourceComponent;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
public class RStripCommentsHandler extends SourceEditorProgressHandler {
public RStripCommentsHandler(final ISourceEditor editor) {
super(editor);
}
@Override
protected String getTaskLabel() {
return RUIMessages.StripComments_task_label;
}
@Override
protected boolean isEditTask() {
return true;
}
@Override
protected void doExecute(final ISourceEditor editor, final SourceUnit su,
final ITextSelection selection, final IProgressMonitor monitor) throws Exception {
final AbstractDocument document = su.getDocument(monitor);
final SourceUnitModelInfo model = su.getModelInfo(null, ModelManager.MODEL_FILE, monitor);
final RHeuristicTokenScanner scanner= RHeuristicTokenScanner.create(editor.getDocumentContentInfo());
if (model == null || scanner == null || monitor.isCanceled()) {
return;
}
monitor.subTask(getTaskLabel() + "..."); //$NON-NLS-1$
final List<? extends AstNode> comments = ((SourceComponent) model.getAst().getRoot()).getComments();
final IRegion region = TextUtil.getBlock(document,
selection.getOffset(), selection.getOffset()+selection.getLength() );
scanner.configure(document);
final MultiTextEdit edits = new MultiTextEdit();
final int startOffset = region.getOffset();
final int endOffset = region.getOffset() + region.getLength();
for (final AstNode comment : comments) {
if (comment.getStartOffset() >= startOffset) {
if (comment.getStartOffset() >= endOffset) {
break;
}
final int line = document.getLineOfOffset(comment.getStartOffset());
final int lineOffset = document.getLineOffset(line);
int offset = scanner.findNonBlankBackward(comment.getStartOffset(), lineOffset, false);
if (offset >= 0) {
offset++;
}
else {
offset = lineOffset;
}
if (offset == lineOffset) {
edits.addChild(new DeleteEdit(lineOffset, document.getLineLength(line)));
}
else {
edits.addChild(new DeleteEdit(offset, comment.getEndOffset() - offset));
}
}
}
if (edits.getChildrenSize() > 0) {
su.syncExec(new SourceDocumentRunnable(document, model.getStamp().getContentStamp(),
DocumentRewriteSessionType.SEQUENTIAL ) {
@Override
public void run() throws InvocationTargetException {
try {
edits.apply(getDocument(), TextEdit.NONE);
}
catch (final MalformedTreeException e) {
throw new InvocationTargetException(e);
}
catch (final BadLocationException e) {
throw new InvocationTargetException(e);
}
}
});
}
}
}