/**
* Copyright (c) 2009, 2014 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 java.util.Iterator;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.ui.texteditor.ITextEditor;
import com.mulgasoft.emacsplus.MarkUtils;
/**
* Implement Reposition Window (approximately)
* Make the current definition visible by revealing as much as possible in the viewer
* If called with uArg, move point to beginning of defun as well.
*
* NB: This is a noop if the buffer has been narrowed
* NB: No effort is made to determine the semantic contents of the projection
*
* @author mfeber - Initial API and implementation
*/
public class RepositionHandler extends EmacsPlusNoEditHandler {
/**
* A semi-hack... This uses stuff that may change at any time in Eclipse.
* In the java editor, the projection annotation model contains the collapsible regions which correspond to methods (and other areas
* such as import groups).
*
* This may work in other editor types as well... TBD
*/
protected int transform(ITextEditor editor, IDocument document, ITextSelection currentSelection,
ExecutionEvent event) throws BadLocationException {
ITextViewerExtension viewer = MarkUtils.getITextViewer(editor);
if (viewer instanceof ProjectionViewer) {
ProjectionAnnotationModel projection = ((ProjectionViewer)viewer).getProjectionAnnotationModel();
@SuppressWarnings("unchecked") // the method name says it all
Iterator<Annotation> pit = projection.getAnnotationIterator();
while (pit.hasNext()) {
Position p = projection.getPosition(pit.next());
if (p.includes(currentSelection.getOffset())) {
if (isUniversalPresent()) {
// Do this here to prevent subsequent scrolling once range is revealed
MarkUtils.setSelection(editor, new TextSelection(document, p.offset, 0));
}
// the viewer is pretty much guaranteed to be a TextViewer
if (viewer instanceof TextViewer) {
((TextViewer)viewer).revealRange(p.offset, p.length);
}
break;
}
}
}
return NO_OFFSET;
}
@Override
protected boolean isLooping() {
return false;
}
}