/** * 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.ITextSelection; import org.eclipse.jface.text.TextSelection; import org.eclipse.ui.texteditor.ITextEditor; import com.mulgasoft.emacsplus.MarkUtils; /** * Implements: mark-sexp. * Select one s-expression forward without moving point * If called with negative arg, mark-sexps backward * * @author Mark Feber - initial API and implementation */ public class SexpMarkHandler extends SexpForwardHandler { /** * @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 { markSexp(editor,document,currentSelection,false); return NO_OFFSET; } protected void markSexp(ITextEditor editor, IDocument document, ITextSelection currentSelection, boolean wordp) throws BadLocationException { boolean backp = getUniversalCount() < 0; // remember where we came from int begOffset = currentSelection.getOffset(); int cursorOffset = MarkUtils.getCursorOffset(editor); int mark; ITextSelection selection = currentSelection; if (selection.getLength() == 0) { // set the mark at the beginning of the first sexp mark = setMark(editor,cursorOffset); } else { mark = getMark(editor); } try { selection = new TextSelection(document,((mark < cursorOffset) ? mark : begOffset+selection.getLength()), 0); if (backp) { selection = new SexpBackwardHandler().getNextSexp(document, selection, wordp); } else { selection = getNextSexp(document, selection, wordp); } } catch (BadLocationException e) { } if (selection == null) { unbalanced(editor,true); throw new BadLocationException(); } // compute the entire region and select it int endOffset = (backp ? selection.getOffset() : selection.getOffset()+selection.getLength()); selection = new TextSelection(document, endOffset, (cursorOffset - endOffset)); // set new mark, but don't save previous mark to mark ring setMark(editor,selection.getOffset(),false); setSelection(editor,selection); // and make sure the end is visible MarkUtils.revealRange(editor, endOffset, 0); } }