/* * Copyright 2015 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.robotframework.ide.eclipse.main.plugin.tableeditor.source.handler; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import javax.inject.Named; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.ui.ISources; import org.robotframework.ide.eclipse.main.plugin.tableeditor.RobotFormEditor; import org.robotframework.ide.eclipse.main.plugin.tableeditor.source.handler.ToggleCommentHandler.E4ToggleCommentHandler; import org.robotframework.red.commands.DIParameterizedHandler; import com.google.common.annotations.VisibleForTesting; /** * @author Michal Anglart */ public class ToggleCommentHandler extends DIParameterizedHandler<E4ToggleCommentHandler> { public ToggleCommentHandler() { super(E4ToggleCommentHandler.class); } public static class E4ToggleCommentHandler { @Execute public void toggleComment(final @Named(ISources.ACTIVE_EDITOR_NAME) RobotFormEditor editor) { final SourceViewer viewer = editor.getSourceEditor().getViewer(); final IDocument document = viewer.getDocument(); final ITextSelection selection = (ITextSelection) viewer.getSelection(); toggleComment(document, selection); } @VisibleForTesting void toggleComment(final IDocument document, final ITextSelection selection) { final int selectionStartLine = selection.getStartLine(); final int selectionEndLine = selection.getEndLine(); try { final IRegion startLineInfo = document.getLineInformation(selectionStartLine); final IRegion endLineInfo = document.getLineInformation(selectionEndLine); final int affectedRegionOffset = startLineInfo.getOffset(); final int affectedRegionLength = endLineInfo.getOffset() + endLineInfo.getLength() - affectedRegionOffset; final String affectedRegionContent = document.get(affectedRegionOffset, affectedRegionLength); final boolean shouldAddMarks = shouldAddCommentMarks(affectedRegionContent); final String newContent = shouldAddMarks ? addCommentMarks(affectedRegionContent) : removeCommentMarks(affectedRegionContent); document.replace(affectedRegionOffset, affectedRegionLength, newContent); } catch (final BadLocationException e) { // we'll do nothing then } } private boolean shouldAddCommentMarks(final String affectedRegionContent) { try (BufferedReader reader = new BufferedReader(new StringReader(affectedRegionContent))) { String line = reader.readLine(); while (line != null) { if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { return true; } line = reader.readLine(); } } catch (final IOException e) { return true; } return false; } private String addCommentMarks(final String oldContent) { final StringBuilder newContent = new StringBuilder(); boolean addedInCurrentLine = false; for (int i = 0; i < oldContent.length(); i++) { final char ch = oldContent.charAt(i); if (ch == '\n' || ch == '\r') { addedInCurrentLine = false; } else if (ch != ' ' && ch != '\t' && !addedInCurrentLine) { newContent.append("# "); addedInCurrentLine = true; } newContent.append(ch); } return newContent.toString(); } private String removeCommentMarks(final String oldContent) { final StringBuilder newContent = new StringBuilder(); boolean removedInCurrentLine = false; for (int i = 0; i < oldContent.length(); i++) { final char ch = oldContent.charAt(i); if (ch == '\n' || ch == '\r') { newContent.append(ch); removedInCurrentLine = false; } else if (ch == '#' && !removedInCurrentLine) { if (i + 1 < oldContent.length() && oldContent.charAt(i + 1) == ' ') { i++; } removedInCurrentLine = true; } else { newContent.append(ch); } } return newContent.toString(); } } }