blob: 6b136920c85ada5beaf23c1816777decedfcb14d [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 2021 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 org.eclipse.jface.action.Action;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentRewriteSession;
import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.statet.ecommons.text.IndentUtil;
import org.eclipse.statet.ecommons.text.IndentUtil.IndentEditAction;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.r.core.RCoreAccess;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
/**
* Add '## '-prefix to the current selection.
*/
public class RDoubleCommentAction extends Action implements IUpdate {
public static final String ACTION_ID = "org.eclipse.statet.r.actions.AddDoubleComment"; //$NON-NLS-1$
private final ISourceEditor fEditor;
private final RCoreAccess fCore;
public RDoubleCommentAction(final ISourceEditor editor, final RCoreAccess core) {
fEditor = editor;
fCore = core;
setId(ACTION_ID);
setActionDefinitionId(LTKUI.ADD_DOC_COMMENT_COMMAND_ID);
update();
}
@Override
public void update() {
setEnabled(fEditor.isEditable(false));
}
@Override
public void run() {
if (!fEditor.isEditable(true)) {
return;
}
try {
addComment();
} catch (final BadLocationException e) {
RUIPlugin.logError(RUIPlugin.INTERNAL_ERROR, "An error occurred while running RDoubleClickAction.", e); //$NON-NLS-1$
}
}
private void addComment() throws BadLocationException {
final ISourceViewer sourceViewer = fEditor.getViewer();
final IDocument document = sourceViewer.getDocument();
final ITextSelection selection = (ITextSelection) sourceViewer.getSelectionProvider().getSelection();
final int offset = selection.getOffset();
final RHeuristicTokenScanner scanner= RHeuristicTokenScanner.create(
fEditor.getDocumentContentInfo() );
scanner.configure(document);
if (selection.getLength() == 0 && scanner.isBlankLine(selection.getOffset())) {
document.replace(offset, 0, "## "); //$NON-NLS-1$
sourceViewer.setSelectedRange(offset+3, 0);
sourceViewer.revealRange(offset+3, 0);
return;
}
final IRegion textBlock = TextUtil.getBlock(document, selection.getOffset(), selection.getOffset()+selection.getLength());
final IndentUtil util = new IndentUtil(document, fCore.getRCodeStyle());
IDocumentExtension4 doc4 = null;
DocumentRewriteSession rewriteSession = null;
try {
if (document instanceof IDocumentExtension4) {
doc4 = (IDocumentExtension4) document;
rewriteSession = doc4.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
}
final int firstLine = scanner.getFirstLineOfRegion(textBlock);
final int lastLine = scanner.getLastLineOfRegion(textBlock);
final int column = util.getMultilineIndentColumn(firstLine, lastLine);
final IndentEditAction action = new IndentEditAction(column) {
@Override
public void doEdit(final int line, final int offset, final int length, final StringBuilder text) throws BadLocationException {
if (text != null) {
document.replace(offset, length, text.toString());
}
document.replace(util.getIndentedOffsetAt(line, column), 0, "## "); //$NON-NLS-1$
}
};
util.editInIndent(firstLine, lastLine, action);
}
finally {
if (doc4 != null) {
doc4.stopRewriteSession(rewriteSession);
}
}
}
}