// Copyright 2012 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.collide.client.editor.selection; import com.google.collide.shared.document.DocumentMutator; import com.google.collide.shared.document.Line; import com.google.collide.shared.document.LineInfo; import com.google.collide.shared.document.Position; import com.google.common.base.Preconditions; import com.google.gwt.regexp.shared.RegExp; /** * Utility that comments / uncomments selected lines. * */ public class ToggleCommentsController { private final RegExp commentChecker; private final String commentHead; ToggleCommentsController(RegExp commentChecker, String commentHead) { this.commentChecker = commentChecker; this.commentHead = commentHead; } void processLines(DocumentMutator documentMutator, SelectionModel selection) { boolean moveDown = !selection.hasSelection(); Position[] selectionRange = selection.getSelectionRange(false); int initialColumn = selectionRange[0].getColumn(); Line terminator = selectionRange[1].getLine(); if (selectionRange[1].getColumn() != 0 || !selection.hasSelection()) { terminator = terminator.getNextLine(); } int lineNumber = selectionRange[0].getLineNumber(); Line current = selectionRange[0].getLine(); if (canUncommentAll(current, terminator)) { int headLength = commentHead.length(); while (current != terminator) { int pos = current.getText().indexOf(commentHead); documentMutator.deleteText(current, lineNumber, pos, headLength); lineNumber++; current = current.getNextLine(); } } else { while (current != terminator) { documentMutator.insertText(current, lineNumber, 0, commentHead, false); lineNumber++; current = current.getNextLine(); } } if (moveDown) { moveCursorDown(selection, initialColumn); } } /** * Check that all lines between begin (inclusive) and end (exclusive) are * commented. * * @param end {@code null} to check to document end */ private boolean canUncommentAll(Line begin, Line end) { Line current = begin; while (current != end) { Preconditions.checkNotNull(current, "hasn't met terminator before document end"); if (!commentChecker.test(current.getText())) { return false; } current = current.getNextLine(); } return true; } private void moveCursorDown(SelectionModel selection, int initialColumn) { Line line = selection.getCursorLine().getNextLine(); if (line == null) { return; } int lineNumber = selection.getCursorLineNumber() + 1; String text = line.getText(); int lineLength = text.length(); if (text.endsWith("\n")) { lineLength--; } int column = Math.min(initialColumn, lineLength); selection.setCursorPosition(new LineInfo(line, lineNumber), column); } }