[b/9260695] Added a preference to enable/disable the smart semicolon. While the feature is very handy, it causes delays while typing and can be extremely annoying for some users. The same auto-id functionality is available through content assist independent of the new preference. Change-Id: Ic166b7b42d93037a108da073c2b004057d28179e
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java index 5c21247..47c6389 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java
@@ -57,10 +57,6 @@ public class SmartSemicolonHandler extends SmartInsertHandler { private static final Pattern NUMBERS_PATTERN = compile("[\\d]+"); - private static final IUnitOfWork.Void<XtextResource> NULL_UNIT_OF_WORK = new IUnitOfWork.Void<XtextResource>() { - @Override public void process(XtextResource resource) {} - }; - private static Logger logger = Logger.getLogger(SmartSemicolonHandler.class); @Inject private CommentNodesFinder commentNodesFinder; @@ -71,13 +67,15 @@ @Inject private Protobufs protobufs; @Inject private Resources resources; @Inject private IPreferenceStoreAccess storeAccess; + private NumericTagPreferences preferences; private static final String SEMICOLON = CommonKeyword.SEMICOLON.toString(); @Override protected void insertContent(XtextEditor editor, StyledText styledText) { + preferences = new NumericTagPreferences(storeAccess); StyledTextAccess styledTextAccess = new StyledTextAccess(styledText); String line = styledTextAccess.lineAtCaretOffset(); - if (line.endsWith(SEMICOLON)) { + if (!preferences.isSmartSemicolonEnabled() || line.endsWith(SEMICOLON)) { styledTextAccess.insert(SEMICOLON); return; } @@ -89,15 +87,11 @@ final AtomicBoolean shouldInsertSemicolon = new AtomicBoolean(true); final IXtextDocument document = editor.getDocument(); final List<Pair<EObject, Long>> commentsToUpdate = Lists.newLinkedList(); + final List<Pair<Literal, Long>> indexesToUpdate1 = Lists.newLinkedList(); + final List<Pair<MessageField, Long>> indexesToUpdate2 = Lists.newLinkedList(); - document.readOnly(NULL_UNIT_OF_WORK); // wait for reconciler to finish its work. try { - /* - * Textual and semantic updates cannot be done in the same IUnitOfWork (throws an - * IllegalStateException), so index updates (semantic) are done first and tracked in the - * commentsToUpdate list, then a 2nd IUnitOfWork processes the comment updates (textual). - */ - document.modify(new IUnitOfWork.Void<XtextResource>() { + document.readOnly(new IUnitOfWork.Void<XtextResource>() { @Override public void process(XtextResource resource) { Protobuf root = resources.rootOf(resource); if (!protobufs.isProto2(root) /*|| !resource.getErrors().isEmpty()*/) { @@ -118,7 +112,7 @@ Literal literal = (Literal) model; if (shouldCalculateIndex(literal, LITERAL__INDEX)) { long index = literals.calculateNewIndexOf(literal); - literal.setIndex(index); + indexesToUpdate1.add(Tuples.create(literal, index)); commentsToUpdate.add(Tuples.create(model, index)); shouldInsertSemicolon.set(false); } @@ -127,7 +121,7 @@ MessageField field = (MessageField) model; if (shouldCalculateIndex(field)) { long index = indexedElements.calculateNewIndexFor(field); - field.setIndex(index); + indexesToUpdate2.add(Tuples.create(field, index)); commentsToUpdate.add(Tuples.create(model, index)); shouldInsertSemicolon.set(false); } @@ -136,14 +130,34 @@ } }); + /* + * Textual and semantic updates cannot be done in the same IUnitOfWork (throws an + * IllegalStateException), so index updates (semantic) are done first and tracked in the + * commentsToUpdate list, then a 2nd IUnitOfWork processes the comment updates (textual). + */ + if (!indexesToUpdate1.isEmpty() || !indexesToUpdate2.isEmpty()) { + document.modify(new IUnitOfWork.Void<XtextResource>() { + @Override public void process(XtextResource resource) { + for (Pair<Literal, Long> indexUpdate : indexesToUpdate1) { + indexUpdate.getFirst().setIndex(indexUpdate.getSecond()); + } + + for (Pair<MessageField, Long> indexUpdate : indexesToUpdate2) { + indexUpdate.getFirst().setIndex(indexUpdate.getSecond()); + } + } + }); + } + if (!commentsToUpdate.isEmpty()) { document.modify(new IUnitOfWork.Void<XtextResource>() { - @Override public void process(XtextResource resource) { - for (Pair<EObject, Long> updateInfo : commentsToUpdate) { - updateIndexInCommentOfParent(updateInfo.getFirst(), updateInfo.getSecond(), document); + @Override + public void process(XtextResource resource) { + for (Pair<EObject, Long> updateInfo : commentsToUpdate) { + updateIndexInCommentOfParent(updateInfo.getFirst(), updateInfo.getSecond(), document); + } } - } - }); + }); } } catch (Throwable t) { shouldInsertSemicolon.set(true); @@ -158,7 +172,7 @@ INode node = nodes.firstNodeForFeature(target, indexAttribute); return node == null || isEmpty(node.getText()); } - + private boolean shouldCalculateIndex(IndexedElement target) { return indexedElements.indexOf(target) <= 0; } @@ -174,7 +188,7 @@ if (parent == null) { return; } - NumericTagPreferences preferences = new NumericTagPreferences(storeAccess); + for (String pattern : preferences.patterns()) { Pair<INode, Matcher> match = commentNodesFinder.matchingCommentNode(parent, pattern); if (match == null) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java index 4e7c8fa..1b9a06c 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java
@@ -24,6 +24,7 @@ public static String pattern; public static String remove; public static String testPattern; + public static String enableSmartSemicolon; static { Class<Messages> type = Messages.class;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.properties index 47f2798..a97daff 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.properties +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.properties
@@ -1,3 +1,4 @@ +enableSmartSemicolon=Enable Smart Semicolon add=&Add addNewPattern=Add New Pattern edit=&Edit
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java index 18413ec..e0d7e28 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java
@@ -8,16 +8,23 @@ */ package com.google.eclipse.protobuf.ui.preferences.editor.numerictag; -import static org.eclipse.jface.window.Window.OK; - import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.AddOrEditPatternDialog.addPattern; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.AddOrEditPatternDialog.editPattern; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.Messages.add; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.Messages.edit; +import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.Messages.enableSmartSemicolon; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.Messages.pageDescription; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.Messages.remove; +import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.PreferenceNames.ENABLE_SMART_SEMICOLON; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.PreferenceNames.NUMERIC_TAG_PATTERNS; +import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf; import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems.bindItemsOf; +import static org.eclipse.jface.window.Window.OK; + +import com.google.eclipse.protobuf.ui.preferences.StringSplitter; +import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage; +import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder; +import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceFactory; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.swt.SWT; @@ -30,11 +37,6 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; -import com.google.eclipse.protobuf.ui.preferences.StringSplitter; -import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage; -import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder; -import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceFactory; - /** * Preference page where users can specify the patterns to use to match comments where "the next id" is being tracked. * @@ -43,12 +45,18 @@ public class NumericTagPreferencePage extends PreferenceAndPropertyPage { private static final String PREFERENCE_PAGE_ID = NumericTagPreferencePage.class.getName(); + private Button btnEnableSmartSemicolon; private List lstPatterns; private Button btnAdd; private Button btnEdit; private Button btnRemove; @Override protected void doCreateContents(Composite parent) { + btnEnableSmartSemicolon = new Button(parent, SWT.CHECK); + btnEnableSmartSemicolon.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); + btnEnableSmartSemicolon.setText(enableSmartSemicolon); + new Label(parent, SWT.NONE); + Label lblDescription = new Label(parent, SWT.WRAP); GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1); gridData.widthHint = 150; // only expand further if anyone else requires it @@ -132,6 +140,7 @@ @Override protected void setupBinding(PreferenceBinder binder, PreferenceFactory factory) { StringSplitter splitter = NumericTagPatternSplitter.instance(); binder.add(bindItemsOf(lstPatterns).to(factory.newStringListPreference(NUMERIC_TAG_PATTERNS, splitter))); + binder.add(bindSelectionOf(btnEnableSmartSemicolon).to(factory.newBooleanPreference(ENABLE_SMART_SEMICOLON))); } @Override protected void onProjectSettingsActivation(boolean projectSettingsActive) {}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java index 418b3e5..dd3edb2 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java
@@ -8,6 +8,7 @@ */ package com.google.eclipse.protobuf.ui.preferences.editor.numerictag; +import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.PreferenceNames.ENABLE_SMART_SEMICOLON; import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.PreferenceNames.NUMERIC_TAG_PATTERNS; import java.util.List; @@ -31,10 +32,15 @@ return NumericTagPatternSplitter.instance().splitIntoList(value); } + public boolean isSmartSemicolonEnabled() { + return store.getBoolean(ENABLE_SMART_SEMICOLON); + } + public static class Initializer implements IPreferenceStoreInitializer { @Override public void initialize(IPreferenceStoreAccess storeAccess) { IPreferenceStore store = storeAccess.getWritablePreferenceStore(); store.setDefault(NUMERIC_TAG_PATTERNS, "Next[\\s]+Id:[\\s]+[\\d]+"); + store.setDefault(ENABLE_SMART_SEMICOLON, true); } } }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java index 43ebd1b..67eecd7 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java
@@ -13,6 +13,7 @@ */ final class PreferenceNames { static final String NUMERIC_TAG_PATTERNS = "numericTag.patterns"; + static final String ENABLE_SMART_SEMICOLON = "numericTag.enableSmartSemicolon"; private PreferenceNames() {} }