/** * Copyright (c) 2009, 2010 Mark Feber, MulgaSoft * * 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 */ package com.mulgasoft.emacsplus.commands; import org.eclipse.core.commands.ExecutionEvent; 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.ui.texteditor.ITextEditor; import org.eclipse.jface.text.Position; /** * Implement: delete-trailing-whitespace * * Delete all the trailing whitespace across the current buffer. * All whitespace after the last non-whitespace character in a line is deleted. * This respects narrowing, created by C-x n n and friends. * * This command differs from the Eclipse remove-trailing-whitespace by * operating on only one file and respecting the narrowed region of a buffer. * * @author Mark Feber - initial API and implementation */ public class DeleteWhitespaceHandler extends EmacsPlusCmdHandler { /** * Determine the correct set of lines and delete the whitespace at the end of each of them. * * @see com.mulgasoft.emacsplus.commands.EmacsPlusCmdHandler#transform(ITextEditor, IDocument, ITextSelection, ExecutionEvent) */ @Override protected int transform(ITextEditor editor, IDocument document, ITextSelection currentSelection, ExecutionEvent event) throws BadLocationException { int result = NO_OFFSET; int lastLine = 0; int firstLine = 0; int maxOffset = Integer.MAX_VALUE; if (editor.showsHighlightRangeOnly()) { // if the buffer is narrowed, then operate on precise region IRegion narrow = editor.getHighlightRange(); int lastOffset = narrow.getOffset() + narrow.getLength(); firstLine = document.getLineOfOffset(narrow.getOffset()); lastLine = document.getLineOfOffset(lastOffset); IRegion endInfo = document.getLineInformationOfOffset(lastOffset); if (endInfo.getOffset() != lastOffset) { // point maxOffset at the last character in the narrowed region maxOffset = lastOffset -1; } else { // back up if we're at the first offset of the last line lastLine--; } } else { lastLine = document.getNumberOfLines() -1; } if (firstLine <= lastLine) { Position coff = new Position(getCursorOffset(editor,currentSelection),0); try { // record the position so we can restore it after any whitespace deletions document.addPosition(coff); deleteWhitepace(lastLine,firstLine,maxOffset,document); } catch (BadLocationException e) { // shouldn't happen, but alert user if it does asyncShowMessage(editor,BAD_LOCATION_ERROR,true); } finally { result = coff.getOffset(); document.removePosition(coff); } } return result; } /** * Delete the whitespace at the end of each line from the bottom up * * @param lastLine last line in the region * @param firstLine first line in the region * @param maxOffset when narrowed, this is the last offset on the last line * @param document the model * @throws BadLocationException */ private void deleteWhitepace(int lastLine, int firstLine, int maxOffset, IDocument document) throws BadLocationException { // bottoms up for (int i= lastLine; i >= firstLine; i--) { IRegion line= document.getLineInformation(i); if (line.getLength() == 0) continue; int lineStart= line.getOffset(); int lineLen = line.getLength(); int lineEnd = lineStart + lineLen; if (lineEnd > maxOffset) { lineLen -= (lineEnd - maxOffset) - 1; lineEnd = maxOffset; } else { lineEnd--; } int j= lineEnd; // String t = document.get(lineStart,line.getLength()); while (j >= lineStart && Character.isWhitespace(document.getChar(j))) --j; if (j < lineEnd) { String newText = document.get(lineStart,(j - lineStart)+1); updateText(document,lineStart,lineLen ,newText); } } } /** * Force undo protect * @see com.mulgasoft.emacsplus.commands.EmacsPlusCmdHandler#undoProtect() */ protected boolean undoProtect() { return true; } }