|
From: Christopher W. <caw...@us...> - 2006-02-24 20:06:52
|
Update of /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1630/src/org/rubypeople/rdt/internal/ui/rubyeditor Modified Files: RubyEditor.java Log Message: hook in new go to matching bracket action Index: RubyEditor.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyEditor.java,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** RubyEditor.java 23 Feb 2006 21:52:05 -0000 1.38 --- RubyEditor.java 24 Feb 2006 20:06:47 -0000 1.39 *************** *** 30,35 **** --- 30,37 ---- import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewerExtension; + import org.eclipse.jface.text.ITextViewerExtension5; import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.Position; + import org.eclipse.jface.text.Region; import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.link.ILinkedModeListener; *************** *** 42,45 **** --- 44,48 ---- import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; + import org.eclipse.jface.text.source.ICharacterPairMatcher; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; *************** *** 83,86 **** --- 86,90 ---- import org.rubypeople.rdt.internal.ui.text.IRubyPartitions; import org.rubypeople.rdt.internal.ui.text.RubyHeuristicScanner; + import org.rubypeople.rdt.internal.ui.text.RubyPairMatcher; import org.rubypeople.rdt.internal.ui.text.Symbols; import org.rubypeople.rdt.ui.IWorkingCopyManager; *************** *** 94,97 **** --- 98,103 ---- public class RubyEditor extends RubyAbstractEditor { + protected final static char[] BRACKETS= { '{', '}', '(', ')', '[', ']' }; + protected RubyActionGroup actionGroup; private ProjectionSupport fProjectionSupport; *************** *** 126,129 **** --- 132,138 ---- */ private IMarker fLastMarkerTarget = null; + + /** The editor's bracket matcher */ + protected RubyPairMatcher fBracketMatcher= new RubyPairMatcher(BRACKETS); private BracketInserter fBracketInserter = new BracketInserter(); *************** *** 164,167 **** --- 173,180 ---- WorkbenchHelp.setHelp(action, IRubyHelpContextIds.TOGGLE_COMMENT_ACTION); configureToggleCommentAction(); + + action= new GotoMatchingBracketAction(this); + action.setActionDefinitionId(IRubyEditorActionDefinitionIds.GOTO_MATCHING_BRACKET); + setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action); action = new FormatAction(RubyUIMessages.getResourceBundle(), "Format.", this); *************** *** 176,180 **** beginRescueAction.update(selection); provider.addSelectionChangedListener(beginRescueAction); ! setAction("SurroundWithBeginRescue", beginRescueAction); //$NON-NLS-1$ actionGroup = new RubyActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); --- 189,193 ---- beginRescueAction.update(selection); provider.addSelectionChangedListener(beginRescueAction); ! setAction(SurroundWithBeginRescueAction.SURROUND_WTH_BEGIN_RESCUE, beginRescueAction); actionGroup = new RubyActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); *************** *** 1108,1110 **** --- 1121,1233 ---- return getElementAt(offset, true); } + + /** + * Jumps to the matching bracket. + */ + public void gotoMatchingBracket() { + + ISourceViewer sourceViewer= getSourceViewer(); + IDocument document= sourceViewer.getDocument(); + if (document == null) + return; + + IRegion selection= getSignedSelection(sourceViewer); + + int selectionLength= Math.abs(selection.getLength()); + if (selectionLength > 1) { + setStatusLineErrorMessage(RubyEditorMessages.GotoMatchingBracket_error_invalidSelection); + sourceViewer.getTextWidget().getDisplay().beep(); + return; + } + + // #26314 + int sourceCaretOffset= selection.getOffset() + selection.getLength(); + if (isSurroundedByBrackets(document, sourceCaretOffset)) + sourceCaretOffset -= selection.getLength(); + + IRegion region= fBracketMatcher.match(document, sourceCaretOffset); + if (region == null) { + setStatusLineErrorMessage(RubyEditorMessages.GotoMatchingBracket_error_noMatchingBracket); + sourceViewer.getTextWidget().getDisplay().beep(); + return; + } + + int offset= region.getOffset(); + int length= region.getLength(); + + if (length < 1) + return; + + int anchor= fBracketMatcher.getAnchor(); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195 + int targetOffset= (ICharacterPairMatcher.RIGHT == anchor) ? offset + 1: offset + length; + + boolean visible= false; + if (sourceViewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension= (ITextViewerExtension5) sourceViewer; + visible= (extension.modelOffset2WidgetOffset(targetOffset) > -1); + } else { + IRegion visibleRegion= sourceViewer.getVisibleRegion(); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195 + visible= (targetOffset >= visibleRegion.getOffset() && targetOffset <= visibleRegion.getOffset() + visibleRegion.getLength()); + } + + if (!visible) { + setStatusLineErrorMessage(RubyEditorMessages.GotoMatchingBracket_error_bracketOutsideSelectedElement); + sourceViewer.getTextWidget().getDisplay().beep(); + return; + } + + if (selection.getLength() < 0) + targetOffset -= selection.getLength(); + + sourceViewer.setSelectedRange(targetOffset, selection.getLength()); + sourceViewer.revealRange(targetOffset, selection.getLength()); + } + + /** + * Returns the signed current selection. + * The length will be negative if the resulting selection + * is right-to-left (RtoL). + * <p> + * The selection offset is model based. + * </p> + * + * @param sourceViewer the source viewer + * @return a region denoting the current signed selection, for a resulting RtoL selections length is < 0 + */ + protected IRegion getSignedSelection(ISourceViewer sourceViewer) { + StyledText text= sourceViewer.getTextWidget(); + Point selection= text.getSelectionRange(); + + if (text.getCaretOffset() == selection.x) { + selection.x= selection.x + selection.y; + selection.y= -selection.y; + } + + selection.x= widgetOffset2ModelOffset(sourceViewer, selection.x); + + return new Region(selection.x, selection.y); + } + + private static boolean isSurroundedByBrackets(IDocument document, int offset) { + if (offset == 0 || offset == document.getLength()) + return false; + + try { + return + isBracket(document.getChar(offset - 1)) && + isBracket(document.getChar(offset)); + + } catch (BadLocationException e) { + return false; + } + } + + private static boolean isBracket(char character) { + for (int i= 0; i != BRACKETS.length; ++i) + if (character == BRACKETS[i]) + return true; + return false; + } } \ No newline at end of file |