diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/OSGI-INF/l10n/bundle.properties b/plugins/org.jkiss.dbeaver.ui.editors.sql/OSGI-INF/l10n/bundle.properties index 72df45920e3460b1d7456f1e520e34d39566ced0..2d5bd51ecb47614cbd9fedf0f3dcd7ab3e99b640 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/OSGI-INF/l10n/bundle.properties +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/OSGI-INF/l10n/bundle.properties @@ -64,6 +64,9 @@ command.org.jkiss.dbeaver.ui.editors.sql.query.next.name=Next query command.org.jkiss.dbeaver.ui.editors.sql.query.next.description=Switch to the next query command.org.jkiss.dbeaver.ui.editors.sql.query.prev.name=Previous query command.org.jkiss.dbeaver.ui.editors.sql.query.prev.description=Switch to the previous query +command.org.jkiss.dbeaver.ui.editors.sql.gotoMatchingBracket.name=Go to matching bracket +command.org.jkiss.dbeaver.ui.editors.sql.gotoMatchingBracket.description=Position cursor on the matching bracket + command.org.jkiss.dbeaver.ui.editors.sql.show.output.name=Show server output command.org.jkiss.dbeaver.ui.editors.sql.show.output.description=Show server output console command.org.jkiss.dbeaver.ui.editors.sql.show.log.name=Show execution log diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/plugin.xml b/plugins/org.jkiss.dbeaver.ui.editors.sql/plugin.xml index 4eaecf6bfd5b7a6b77072b47ad267abedf13ddf7..555c9f0cd97380be05f9cec0e8a3ce64384f3fc8 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/plugin.xml +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/plugin.xml @@ -256,6 +256,7 @@ + @@ -527,6 +528,9 @@ + + + @@ -551,7 +555,7 @@ - + @@ -572,6 +576,8 @@ + + diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java index 001a4419ebc3439bfe47e75fe940a7e2cf368763..8a40804e1f539882ad8b286d039501c766b103c9 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java @@ -32,6 +32,7 @@ import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.*; import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; @@ -86,6 +87,8 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext public static final String STATS_CATEGORY_SELECTION_STATE = "SelectionState"; + protected final static char[] BRACKETS = {'{', '}', '(', ')', '[', ']', '<', '>'}; + static { // SQL editor preferences. Do this here because it initializes display // (that's why we can't run it in prefs initializer classes which run before workbench creation) @@ -120,17 +123,17 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext private boolean markOccurrencesForSelection; private OccurrencesFinderJob occurrencesFinderJob; private OccurrencesFinderJobCanceler occurrencesFinderJobCanceler; + private ICharacterPairMatcher characterPairMatcher; - public SQLEditorBase() - { + public SQLEditorBase() { super(); syntaxManager = new SQLSyntaxManager(); ruleManager = new SQLRuleManager(syntaxManager); themeListener = new IPropertyChangeListener() { long lastUpdateTime = 0; + @Override - public void propertyChange(PropertyChangeEvent event) - { + public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals(IThemeManager.CHANGE_CURRENT_THEME) || event.getProperty().startsWith("org.jkiss.dbeaver.sql.editor")) { if (lastUpdateTime > 0 && System.currentTimeMillis() - lastUpdateTime < 500) { @@ -246,8 +249,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @NotNull - public SQLSyntaxManager getSyntaxManager() - { + public SQLSyntaxManager getSyntaxManager() { return syntaxManager; } @@ -256,19 +258,16 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext return ruleManager; } - public ProjectionAnnotationModel getAnnotationModel() - { + public ProjectionAnnotationModel getAnnotationModel() { return annotationModel; } - public SQLEditorSourceViewerConfiguration getViewerConfiguration() - { + public SQLEditorSourceViewerConfiguration getViewerConfiguration() { return (SQLEditorSourceViewerConfiguration) super.getSourceViewerConfiguration(); } @Override - public void createPartControl(Composite parent) - { + public void createPartControl(Composite parent) { setRangeIndicator(new DefaultRangeIndicator()); editorControl = new SQLEditorControl(parent, this); @@ -325,8 +324,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @Override - public void updatePartControl(IEditorInput input) - { + public void updatePartControl(IEditorInput input) { super.updatePartControl(input); } @@ -358,18 +356,15 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @Override - protected IVerticalRuler createVerticalRuler() - { + protected IVerticalRuler createVerticalRuler() { return hasVerticalRuler ? super.createVerticalRuler() : new VerticalRuler(0); } - public void setHasVerticalRuler(boolean hasVerticalRuler) - { + public void setHasVerticalRuler(boolean hasVerticalRuler) { this.hasVerticalRuler = hasVerticalRuler; } - protected ISharedTextColors getSharedColors() - { + protected ISharedTextColors getSharedColors() { return UIUtils.getSharedTextColors(); } @@ -387,10 +382,9 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @Override - protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) - { - fAnnotationAccess= getAnnotationAccess(); - fOverviewRuler= createOverviewRuler(getSharedColors()); + protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { + fAnnotationAccess = getAnnotationAccess(); + fOverviewRuler = createOverviewRuler(getSharedColors()); SQLEditorSourceViewer sourceViewer = createSourceViewer(parent, ruler, styles, fOverviewRuler); @@ -400,17 +394,16 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) { - char[] matchChars = {'(', ')', '[', ']', '{', '}'}; //which brackets to match - ICharacterPairMatcher matcher; + char[] matchChars = BRACKETS; //which brackets to match try { - matcher = new SQLCharacterPairMatcher(this, matchChars, + characterPairMatcher = new SQLCharacterPairMatcher(this, matchChars, SQLPartitionScanner.SQL_PARTITIONING, true); } catch (Throwable e) { // If we below Eclipse 4.2.1 - matcher = new SQLCharacterPairMatcher(this, matchChars, SQLPartitionScanner.SQL_PARTITIONING); + characterPairMatcher = new SQLCharacterPairMatcher(this, matchChars, SQLPartitionScanner.SQL_PARTITIONING); } - support.setCharacterPairMatcher(matcher); + support.setCharacterPairMatcher(characterPairMatcher); support.setMatchingCharacterPainterPreferenceKeys(SQLPreferenceConstants.MATCHING_BRACKETS, SQLPreferenceConstants.MATCHING_BRACKETS_COLOR); super.configureSourceViewerDecorationSupport(support); } @@ -418,11 +411,11 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext @NotNull protected SQLEditorSourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles, IOverviewRuler overviewRuler) { return new SQLEditorSourceViewer( - parent, - ruler, - overviewRuler, - true, - styles); + parent, + ruler, + overviewRuler, + true, + styles); } @Override @@ -439,7 +432,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } } */ - + @SuppressWarnings("unchecked") @Override public T getAdapter(Class required) { @@ -456,19 +449,17 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext return super.getAdapter(required); } - public SQLTemplatesPage getTemplatesPage() - { + public SQLTemplatesPage getTemplatesPage() { if (templatesPage == null) templatesPage = new SQLTemplatesPage(this); return templatesPage; } @Override - public void dispose() - { + public void dispose() { if (this.selectionChangedListener != null) { this.selectionChangedListener.uninstall(this.getSelectionProvider()); - this.selectionChangedListener= null; + this.selectionChangedListener = null; } /* if (this.activationListener != null) { @@ -489,8 +480,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @Override - protected void createActions() - { + protected void createActions() { super.createActions(); ResourceBundle bundle = ResourceBundle.getBundle(SQLEditorMessages.BUNDLE_NAME); @@ -545,8 +535,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @Override - public void editorContextMenuAboutToShow(IMenuManager menu) - { + public void editorContextMenuAboutToShow(IMenuManager menu) { super.editorContextMenuAboutToShow(menu); //menu.add(new Separator("content"));//$NON-NLS-1$ @@ -574,8 +563,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext //menu.remove(IWorkbenchActionConstants.MB_ADDITIONS); } - public void reloadSyntaxRules() - { + public void reloadSyntaxRules() { // Refresh syntax SQLDialect dialect = getSQLDialect(); syntaxManager.init(dialect, getActivePreferenceStore()); @@ -628,8 +616,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } } - public boolean hasActiveQuery() - { + public boolean hasActiveQuery() { Document document = getDocument(); if (document == null) { return false; @@ -654,8 +641,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } @Nullable - public SQLScriptElement extractActiveQuery() - { + public SQLScriptElement extractActiveQuery() { SQLScriptElement element; ITextSelection selection = (ITextSelection) getSelectionProvider().getSelection(); String selText = selection.getText(); @@ -684,13 +670,12 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext return null; } if (element instanceof SQLQuery && getActivePreferenceStore().getBoolean(ModelPreferences.SQL_PARAMETERS_ENABLED)) { - ((SQLQuery)element).setParameters(parseParameters(getDocument(), (SQLQuery)element)); + ((SQLQuery) element).setParameters(parseParameters(getDocument(), (SQLQuery) element)); } return element; } - public SQLScriptElement extractQueryAtPos(int currentPos) - { + public SQLScriptElement extractQueryAtPos(int currentPos) { Document document = getDocument(); if (document == null || document.getLength() == 0) { return null; @@ -839,8 +824,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext ruleManager.endEval(); } - public List extractScriptQueries(int startOffset, int length, boolean scriptMode, boolean keepDelimiters, boolean parseParameters) - { + public List extractScriptQueries(int startOffset, int length, boolean scriptMode, boolean keepDelimiters, boolean parseParameters) { List queryList = new ArrayList<>(); IDocument document = getDocument(); @@ -858,8 +842,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext queryList.add(query); queryOffset = query.getOffset() + query.getLength(); } - } - finally { + } finally { this.endScriptEvaluation(); } @@ -867,7 +850,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext // Parse parameters for (SQLScriptElement query : queryList) { if (query instanceof SQLQuery) { - ((SQLQuery)query).setParameters(parseParameters(getDocument(), (SQLQuery) query)); + ((SQLQuery) query).setParameters(parseParameters(getDocument(), (SQLQuery) query)); } } } @@ -896,7 +879,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext IToken token = ruleManager.nextToken(); int tokenOffset = ruleManager.getTokenOffset(); int tokenLength = ruleManager.getTokenLength(); - int tokenType = token instanceof SQLToken ? ((SQLToken)token).getType() : SQLToken.T_UNKNOWN; + int tokenType = token instanceof SQLToken ? ((SQLToken) token).getType() : SQLToken.T_UNKNOWN; if (tokenOffset < startPos) { // This may happen with EOF tokens (bug in jface?) return null; @@ -1014,17 +997,16 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext commandId = ((SQLControlToken) token).getCommandId(); } SQLControlCommand command = new SQLControlCommand( - getDataSource(), - syntaxManager, - controlText.trim(), - commandId, - tokenOffset, - tokenLength, - tokenType == SQLToken.T_SET_DELIMITER); + getDataSource(), + syntaxManager, + controlText.trim(), + commandId, + tokenOffset, + tokenLength, + tokenType == SQLToken.T_SET_DELIMITER); if (command.isEmptyCommand() || - (command.getCommandId() != null && - SQLCommandsRegistry.getInstance().getCommandHandler(command.getCommandId()) != null)) - { + (command.getCommandId() != null && + SQLCommandsRegistry.getInstance().getCommandHandler(command.getCommandId()) != null)) { return command; } // This is not a valid command @@ -1032,7 +1014,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } catch (BadLocationException e) { log.warn("Can't extract control statement", e); //$NON-NLS-1$ return null; - } + } } if (hasValuableTokens && (token.isEOF() || (isDelimiter && tokenOffset >= currentPos) || tokenOffset > endPos)) { if (tokenOffset > endPos) { @@ -1071,10 +1053,9 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext if (isDelimiter && (keepDelimiters || (hasBlocks ? dialect.isDelimiterAfterBlock() && firstKeyword != null && (SQLUtils.isBlockStartKeyword(dialect, firstKeyword) || - ArrayUtils.containsIgnoreCase(dialect.getDDLKeywords(), firstKeyword) || - ArrayUtils.containsIgnoreCase(dialect.getBlockHeaderStrings(), firstKeyword)) : - dialect.isDelimiterAfterQuery()))) - { + ArrayUtils.containsIgnoreCase(dialect.getDDLKeywords(), firstKeyword) || + ArrayUtils.containsIgnoreCase(dialect.getBlockHeaderStrings(), firstKeyword)) : + dialect.isDelimiterAfterQuery()))) { if (delimiterText != null && delimiterText.equals(SQLConstants.DEFAULT_STATEMENT_DELIMITER)) { // Add delimiter in the end of query. Do this only for semicolon delimiters. // For SQL server add it in the end of query. For Oracle only after END clause @@ -1092,7 +1073,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext getDataSource(), queryText, statementStart, - queryEndPos - statementStart); + queryEndPos - statementStart); } catch (BadLocationException ex) { log.warn("Can't extract query", ex); //$NON-NLS-1$ return null; @@ -1141,7 +1122,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext ruleManager.setRange(document, queryOffset, queryLength); boolean firstKeyword = true; - for (;;) { + for (; ; ) { IToken token = ruleManager.nextToken(); final int tokenOffset = ruleManager.getTokenOffset(); final int tokenLength = ruleManager.getTokenLength(); @@ -1259,8 +1240,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext return parseParameters(new Document(query), 0, query.length()); } - public boolean isDisposed() - { + public boolean isDisposed() { return getSourceViewer() == null || getSourceViewer().getTextWidget() == null || @@ -1269,8 +1249,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext @Nullable @Override - public ICommentsSupport getCommentsSupport() - { + public ICommentsSupport getCommentsSupport() { final SQLDialect dialect = getSQLDialect(); return new ICommentsSupport() { @Nullable @@ -1372,7 +1351,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext */ protected void updateStatusField(String category) { if (STATS_CATEGORY_SELECTION_STATE.equals(category)) { - IStatusField field= getStatusField(category); + IStatusField field = getStatusField(category); if (field != null) { StringBuilder txt = new StringBuilder("Sel: "); ISelection selection = getSelectionProvider().getSelection(); @@ -1456,7 +1435,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext if (documentProvider != null) { IAnnotationModel annotationModel = documentProvider.getAnnotationModel(this.getEditorInput()); if (annotationModel != null && this.occurrenceAnnotations != null) { - synchronized(LOCK_OBJECT) { + synchronized (LOCK_OBJECT) { this.updateAnnotationModelForRemoves(annotationModel); } @@ -1466,11 +1445,11 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext private void updateAnnotationModelForRemoves(IAnnotationModel annotationModel) { if (annotationModel instanceof IAnnotationModelExtension) { - ((IAnnotationModelExtension)annotationModel).replaceAnnotations(this.occurrenceAnnotations, null); + ((IAnnotationModelExtension) annotationModel).replaceAnnotations(this.occurrenceAnnotations, null); } else { int i = 0; - for(int length = this.occurrenceAnnotations.length; i < length; ++i) { + for (int length = this.occurrenceAnnotations.length; i < length; ++i) { annotationModel.removeAnnotation(this.occurrenceAnnotations[i]); } } @@ -1528,7 +1507,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext private class EditorSelectionChangedListener implements ISelectionChangedListener { public void install(ISelectionProvider selectionProvider) { if (selectionProvider instanceof IPostSelectionProvider) { - ((IPostSelectionProvider)selectionProvider).addPostSelectionChangedListener(this); + ((IPostSelectionProvider) selectionProvider).addPostSelectionChangedListener(this); } else if (selectionProvider != null) { selectionProvider.addSelectionChangedListener(this); } @@ -1536,7 +1515,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext public void uninstall(ISelectionProvider selectionProvider) { if (selectionProvider instanceof IPostSelectionProvider) { - ((IPostSelectionProvider)selectionProvider).removePostSelectionChangedListener(this); + ((IPostSelectionProvider) selectionProvider).removePostSelectionChangedListener(this); } else if (selectionProvider != null) { selectionProvider.removeSelectionChangedListener(this); } @@ -1545,7 +1524,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof ITextSelection) { - SQLEditorBase.this.updateOccurrenceAnnotations((ITextSelection)selection); + SQLEditorBase.this.updateOccurrenceAnnotations((ITextSelection) selection); } } } @@ -1602,7 +1581,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } if (!this.isCanceled()) { - synchronized(LOCK_OBJECT) { + synchronized (LOCK_OBJECT) { this.updateAnnotations(annotationModel, annotationMap); } return Status.OK_STATUS; @@ -1617,7 +1596,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext private void updateAnnotations(IAnnotationModel annotationModel, Map annotationMap) { if (annotationModel instanceof IAnnotationModelExtension) { - ((IAnnotationModelExtension)annotationModel).replaceAnnotations(SQLEditorBase.this.occurrenceAnnotations, annotationMap); + ((IAnnotationModelExtension) annotationModel).replaceAnnotations(SQLEditorBase.this.occurrenceAnnotations, annotationMap); } else { SQLEditorBase.this.removeOccurrenceAnnotations(); @@ -1733,7 +1712,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext private void findPositions(String searchFor, List positions, boolean forSelection) throws BadLocationException { FindReplaceDocumentAdapter findReplaceDocumentAdapter = new FindReplaceDocumentAdapter(fDocument); - for (int offset = 0;;) { + for (int offset = 0; ; ) { IRegion region = findReplaceDocumentAdapter.find(offset, searchFor, true, false, !forSelection, false); if (region == null) { break; @@ -1747,4 +1726,103 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } + //////////////////////////////////////////////////////// + // Brackets + + // copied from JDT code + public void gotoMatchingBracket() { + + ISourceViewer sourceViewer = getSourceViewer(); + IDocument document = sourceViewer.getDocument(); + if (document == null) + return; + + IRegion selection = getSignedSelection(sourceViewer); + + IRegion region = characterPairMatcher.match(document, selection.getOffset()); + if (region == null) { + return; + } + int offset = region.getOffset(); + int length = region.getLength(); + + if (length < 1) + return; + + int anchor = characterPairMatcher.getAnchor(); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195 + int targetOffset = (ICharacterPairMatcher.RIGHT == anchor) ? offset + 1 : offset + length - 1; + + 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) { + return; + } + + int adjustment = getOffsetAdjustment(document, selection.getOffset() + selection.getLength(), selection.getLength()); + targetOffset += adjustment; + int direction = Integer.compare(selection.getLength(), 0); + + sourceViewer.setSelectedRange(targetOffset, direction); + sourceViewer.revealRange(targetOffset, direction); + } + + // copied from JDT code + private static IRegion getSignedSelection(ISourceViewer sourceViewer) { + Point viewerSelection = sourceViewer.getSelectedRange(); + + StyledText text = sourceViewer.getTextWidget(); + Point selection = text.getSelectionRange(); + if (text.getCaretOffset() == selection.x) { + viewerSelection.x = viewerSelection.x + viewerSelection.y; + viewerSelection.y = -viewerSelection.y; + } + + return new Region(viewerSelection.x, viewerSelection.y); + } + + // copied from JDT code + private static int getOffsetAdjustment(IDocument document, int offset, int length) { + if (length == 0 || Math.abs(length) > 1) + return 0; + try { + if (length < 0) { + if (isOpeningBracket(document.getChar(offset))) { + return 1; + } + } else { + if (isClosingBracket(document.getChar(offset - 1))) { + return -1; + } + } + } catch (BadLocationException e) { + //do nothing + } + return 0; + } + + private static boolean isOpeningBracket(char character) { + for (int i = 0; i < BRACKETS.length; i += 2) { + if (character == BRACKETS[i]) + return true; + } + return false; + } + + private static boolean isClosingBracket(char character) { + for (int i = 1; i < BRACKETS.length; i += 2) { + if (character == BRACKETS[i]) + return true; + } + return false; + } + } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorCommands.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorCommands.java index eee4372d50fcc27216a6b658371e131132ca32db..653a72bf1e0eb80d2c2dcbdfcf8d85f76543d8bd 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorCommands.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorCommands.java @@ -34,6 +34,7 @@ public interface SQLEditorCommands String CMD_SQL_EDITOR_RECENT = "org.jkiss.dbeaver.core.sql.editor.recent"; String CMD_SQL_QUERY_NEXT = "org.jkiss.dbeaver.ui.editors.sql.query.next"; String CMD_SQL_QUERY_PREV = "org.jkiss.dbeaver.ui.editors.sql.query.prev"; + String CMD_SQL_GOTO_MATCHING_BRACKET = "org.jkiss.dbeaver.ui.editors.sql.gotoMatchingBracket"; String CMD_SQL_SWITCH_PANEL = "org.jkiss.dbeaver.ui.editors.sql.switch.panel"; String CMD_SQL_SHOW_OUTPUT = "org.jkiss.dbeaver.ui.editors.sql.show.output"; String CMD_SQL_SHOW_LOG = "org.jkiss.dbeaver.ui.editors.sql.show.log"; diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorContributor.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorContributor.java index dbccaf244342b4e73f8c654daabff1390108da7d..0bc89cb66e8bd769194221e744141c4e7a317833 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorContributor.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorContributor.java @@ -157,6 +157,7 @@ public class SQLEditorContributor extends TextEditorActionContributor navMenu.add(new Separator()); navMenu.add(ActionUtils.makeCommandContribution(window, SQLEditorCommands.CMD_SQL_QUERY_NEXT)); navMenu.add(ActionUtils.makeCommandContribution(window, SQLEditorCommands.CMD_SQL_QUERY_PREV)); + navMenu.add(ActionUtils.makeCommandContribution(window, SQLEditorCommands.CMD_SQL_GOTO_MATCHING_BRACKET)); } } } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/handlers/GoToMatchingBracketHandler.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/handlers/GoToMatchingBracketHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..fa76fc9edaae843d2b35b78d6cdf6a14da53ab70 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/handlers/GoToMatchingBracketHandler.java @@ -0,0 +1,38 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ui.editors.sql.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; +import org.jkiss.dbeaver.ui.editors.sql.SQLEditor; +import org.jkiss.dbeaver.ui.editors.sql.SQLEditorBase; +import org.jkiss.dbeaver.utils.RuntimeUtils; + +public class GoToMatchingBracketHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + SQLEditorBase editor = RuntimeUtils.getObjectAdapter(HandlerUtil.getActiveEditor(event), SQLEditorBase.class); + if (editor != null) { + editor.gotoMatchingBracket(); + } + return null; + } + +} \ No newline at end of file