/**
* 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.jface.text.TextSelection;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Implements: transpose-characters
*
* Interchange characters around point, moving forward one character.
* With prefix ARG, effect is to take character before point
* and drag it forward past ARG other characters (backward if ARG negative).
* If no argument and at end of line, the previous two chars are exchanged.
*
* @author Mark Feber - initial API and implementation
*/
public class TransposeCharHandler extends EmacsPlusCmdHandler {
/**
* @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 {
IRegion reg = document.getLineInformationOfOffset(currentSelection.getOffset());
int coff = currentSelection.getOffset();
int lineNo = document.getLineOfOffset(coff);
int firstLen = 1;
int secondLen = 1;
ITextSelection xelection;
int uarg = getUniversalCount();
int eolLen = getLineDelimiter().length();
// take character before point and drag it backward past ARG other characters if ARG negative).
if (uarg < 0) {
if (coff == reg.getOffset()) {
// back up over eol
coff -= eolLen;
lineNo = document.getLineOfOffset(coff);
} else {
// back up one character
--coff;
}
}
if (coff == reg.getOffset()) { // handle beginning of a line
// if at the beginning of a line, make sure we're not at the beginning of the file
if (lineNo == 0){
return currentSelection.getOffset();
}
// back over line delimiter
firstLen = eolLen;
}
if (coff == reg.getOffset()+reg.getLength()){ // handle end of a line
if (isUniversalPresent() || reg.getLength() < 2) {
// if at the end of a line move across line delimiter
String eol = document.getLineDelimiter(lineNo);
// unless at end of file
if (eol == null) {
return currentSelection.getOffset();
}
secondLen = eol.length();
} else {
// If no argument and at end of line, the previous two chars are exchanged.
--coff;
}
}
xelection = new TextSelection(document,coff-firstLen,firstLen+secondLen);
updateText(document,xelection,xelection.getText().substring(firstLen)+xelection.getText().substring(0,firstLen));
int result = xelection.getOffset() + xelection.getLength();
if (uarg < 0 && result != 0) {
// adjust position of result when backing up
IRegion line = document.getLineInformationOfOffset(result);
if (result == line.getOffset() || line.getLength() == 0) {
result -= eolLen;
} else {
--result;
}
}
return result;
}
}