diff --git a/editor/org.processing.editor/.classpath b/editor/org.processing.editor/.classpath
new file mode 100644
index 000000000..ad32c83a7
--- /dev/null
+++ b/editor/org.processing.editor/.classpath
@@ -0,0 +1,7 @@
+
+
+ * Requires the "org.eclipse.core.filebuffers.documentSetup" extension point.
+ *
+ * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant
+ */
+public class ProcessingDocumentSetupParticipant implements IDocumentSetupParticipant {
+
+ /**
+ */
+ public ProcessingDocumentSetupParticipant() {
+ }
+
+ /*
+ * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument)
+ */
+ public void setup(IDocument document) {
+ if (document instanceof IDocumentExtension3) {
+ IDocumentExtension3 extension3= (IDocumentExtension3) document;
+ IDocumentPartitioner partitioner= new FastPartitioner(ProcessingEditorPlugin.getDefault().getProcessingPartitionScanner(), ProcessingPartitionScanner.JAVA_PARTITION_TYPES);
+ extension3.setDocumentPartitioner(ProcessingEditorPlugin.PROCESSING_PARTITIONING, partitioner);
+ partitioner.connect(document);
+ }
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingEditor.java b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditor.java
new file mode 100644
index 000000000..adcacf695
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditor.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor;
+
+
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.swt.widgets.Composite;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+//import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionSupport;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.editors.text.TextEditor;
+//import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.TextEditorAction;
+import org.eclipse.ui.texteditor.TextOperationAction;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+//import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; // error checking annotations
+
+/**
+ * Sets up a Processing specific text editor.
+ *
+ * @see org.eclipse.ui.editors.text.TextEditor
+ */
+public class ProcessingEditor extends TextEditor {
+
+
+ private class DefineFoldingRegionAction extends TextEditorAction {
+
+ public DefineFoldingRegionAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
+ super(bundle, prefix, editor);
+ }
+
+ private IAnnotationModel getAnnotationModel(ITextEditor editor) {
+ return (IAnnotationModel) editor.getAdapter(ProjectionAnnotationModel.class);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ ITextEditor editor= getTextEditor();
+ ISelection selection= editor.getSelectionProvider().getSelection();
+ if (selection instanceof ITextSelection) {
+ ITextSelection textSelection= (ITextSelection) selection;
+ if (!textSelection.isEmpty()) {
+ IAnnotationModel model= getAnnotationModel(editor);
+ if (model != null) {
+
+ int start= textSelection.getStartLine();
+ int end= textSelection.getEndLine();
+
+ try {
+ IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ int offset= document.getLineOffset(start);
+ int endOffset= document.getLineOffset(end + 1);
+ Position position= new Position(offset, endOffset - offset);
+ model.addAnnotation(new ProjectionAnnotation(), position);
+ } catch (BadLocationException x) {
+ // ignore
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /** The outline page */
+ private ProcessingContentOutlinePage fOutlinePage;
+ /** The projection support */
+ private ProjectionSupport fProjectionSupport;
+
+ /**
+ * Default constructor.
+ */
+ public ProcessingEditor() {
+ super();
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method extend the
+ * actions to add those specific to the receiver
+ */
+ protected void createActions() {
+ super.createActions();
+ // accessing the ResourceBundle was causing an ExceptionInInitializerError, not sure what I changed to fix it [lonnen] June 10 2010
+ IAction a= new TextOperationAction(ProcessingEditorMessages.getResourceBundle(), "ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); //$NON-NLS-1$
+ a.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+ setAction("ContentAssistProposal", a); //$NON-NLS-1$
+
+ a= new TextOperationAction(ProcessingEditorMessages.getResourceBundle(), "ContentAssistTip.", this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); //$NON-NLS-1$
+ a.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
+ setAction("ContentAssistTip", a); //$NON-NLS-1$
+
+ a= new DefineFoldingRegionAction(ProcessingEditorMessages.getResourceBundle(), "DefineFoldingRegion.", this); //$NON-NLS-1$
+ setAction("DefineFoldingRegion", a); //$NON-NLS-1$
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method performs any extra
+ * disposal actions required by the java editor.
+ */
+ public void dispose() {
+ if (fOutlinePage != null)
+ fOutlinePage.setInput(null);
+ super.dispose();
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method performs any extra
+ * revert behavior required by the java editor.
+ */
+ public void doRevertToSaved() {
+ super.doRevertToSaved();
+ if (fOutlinePage != null)
+ fOutlinePage.update();
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method performs any extra
+ * save behavior required by the java editor.
+ *
+ * @param monitor the progress monitor
+ */
+ public void doSave(IProgressMonitor monitor) {
+ super.doSave(monitor);
+ if (fOutlinePage != null)
+ fOutlinePage.update();
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method performs any extra
+ * save as behavior required by the java editor.
+ */
+ public void doSaveAs() {
+ super.doSaveAs();
+ if (fOutlinePage != null)
+ fOutlinePage.update();
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method performs sets the
+ * input of the outline page after AbstractTextEditor has set input.
+ *
+ * @param input the editor input
+ * @throws CoreException in case the input can not be set
+ */
+ public void doSetInput(IEditorInput input) throws CoreException {
+ super.doSetInput(input);
+ if (fOutlinePage != null)
+ fOutlinePage.setInput(input);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.ExtendedTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
+ */
+ protected void editorContextMenuAboutToShow(IMenuManager menu) {
+ super.editorContextMenuAboutToShow(menu);
+ addAction(menu, "ContentAssistProposal"); //$NON-NLS-1$
+ addAction(menu, "ContentAssistTip"); //$NON-NLS-1$
+ addAction(menu, "DefineFoldingRegion"); //$NON-NLS-1$
+ }
+
+ /** The ProcessingEditor implementation of this
+ * AbstractTextEditor method performs gets
+ * the java content outline page if request is for a an
+ * outline page.
+ *
+ * @param required the required type
+ * @return an adapter for the required type or null
+ */
+ public Object getAdapter(Class required) {
+
+ if (IContentOutlinePage.class.equals(required)) {
+ if (fOutlinePage == null) {
+ fOutlinePage= new ProcessingContentOutlinePage(getDocumentProvider(), this);
+ if (getEditorInput() != null)
+ fOutlinePage.setInput(getEditorInput());
+ }
+ return fOutlinePage;
+ }
+
+ if (fProjectionSupport != null) {
+ Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), required);
+ if (adapter != null)
+ return adapter;
+ }
+
+ return super.getAdapter(required);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on AbstractTextEditor
+ */
+ protected void initializeEditor() {
+ super.initializeEditor();
+ setSourceViewerConfiguration(new ProcessingSourceViewerConfiguration());
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.ExtendedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
+ */
+ protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+
+ fAnnotationAccess= createAnnotationAccess();
+ fOverviewRuler= createOverviewRuler(getSharedColors());
+
+ ISourceViewer viewer= new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
+
+ // ensure decoration support has been created and configured.
+ // preferred over SourceViewerDecorationSupport due to impending API changes [lonnen] june 11, 2010
+ fSourceViewerDecorationSupport = getSourceViewerDecorationSupport(viewer);
+
+ return viewer;
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.ExtendedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ ProjectionViewer viewer= (ProjectionViewer) getSourceViewer();
+ fProjectionSupport= new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
+ fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
+ fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
+ fProjectionSupport.install();
+ viewer.doOperation(ProjectionViewer.TOGGLE);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#adjustHighlightRange(int, int)
+ */
+ protected void adjustHighlightRange(int offset, int length) {
+ ISourceViewer viewer= getSourceViewer();
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
+ extension.exposeModelRange(new Region(offset, length));
+ }
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorMessages.java b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorMessages.java
new file mode 100644
index 000000000..a2ff97029
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorMessages.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Processing Editor Messages object handles localization stuff
+ * using the ProcessingEditorMessages.preferences file. This class
+ * is never instantiated, and all of its variables and methods are
+ * static.
+ *
+ * @author lonnen
+ */
+public class ProcessingEditorMessages {
+
+ private static final String RESOURCE_BUNDLE= "org.processing.editor.ProcessingEditorMessages";//$NON-NLS-1$
+
+ private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+ private ProcessingEditorMessages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+
+ public static ResourceBundle getResourceBundle() {
+ return fgResourceBundle;
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorMessages.properties b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorMessages.properties
new file mode 100644
index 000000000..840497670
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorMessages.properties
@@ -0,0 +1,46 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# 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
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+# Essentially the same as JavaEditorMessage.properties from the Java example [lonnen] June 10 2010
+
+## Actions ##
+
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
+
+ContentAssistTip.label=Content Tip@Ctrl+SHIFT+SPACE
+ContentAssistTip.tooltip=Content Tip
+ContentAssistTip.image=
+ContentAssistTip.description=Content Tip
+
+DefineFoldingRegion.label=Define Folding Region
+DefineFoldingRegion.tooltip=Define Folding Region
+DefineFoldingRegion.image=
+DefineFoldingRegion.description=Define Folding Region
+
+TogglePresentation.label=Change Presentation
+TogglePresentation.tooltip=Enable/Disable Segmented Source Viewer
+TogglePresentation.image=togglepresentation.gif
+TogglePresentation.description=Enable/Disable Segmented Source Viewer
+
+OutlinePage.segment.title_pattern=position {0}
+
+AutoIndent.error.bad_location_1=JavaAutoIndentStrategy.getAutoIndentString: BadLocationException
+AutoIndent.error.bad_location_2=JavaAutoIndentStrategy.calcShiftBackReplace: BadLocationException
+
+CompletionProcessor.ContextInfo.display.pattern=proposal {0} at position {1}
+CompletionProcessor.ContextInfo.value.pattern=proposal {0} valid from {1} to {2}
+CompletionProcessor.Proposal.ContextInfo.pattern={0} valid 5 characters around insertion point
+CompletionProcessor.Proposal.hoverinfo.pattern=Java keyword: {0}
+
+JavaTextHover.emptySelection=empty selection
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorPlugin.java b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorPlugin.java
new file mode 100644
index 000000000..8bacdddbc
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingEditorPlugin.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor;
+
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.processing.editor.javadoc.JavaDocScanner;
+import org.processing.editor.language.ProcessingCodeScanner;
+import org.processing.editor.util.ProcessingColorProvider;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Processing editor plug-in class.
+ * Uses a singleton pattern to controls access to a few objects that need to be shared
+ * across the plugin. Access these options with ProcessingEditorPlugin.getDefault().method()
+ * @since 3.0
+ */
+public class ProcessingEditorPlugin extends AbstractUIPlugin {
+
+ public static final String PLUGIN_ID = "org.processing.ProcessingEditor";
+ //public static final String JAVA_PARTITIONING= "__java_example_partitioning"; //$NON-NLS-1$
+ public static final String PROCESSING_PARTITIONING= "__processing_partitioning"; //$NON-NLS-1$
+
+ // The shared instance
+ private static ProcessingEditorPlugin fgInstance;
+
+ // Supporting objects that are managed by the singleton
+ private ProcessingPartitionScanner fPartitionScanner;
+ private ProcessingColorProvider fColorProvider;
+ private ProcessingCodeScanner fCodeScanner;
+ private JavaDocScanner fDocScanner;
+
+ /**
+ * Creates a new plug-in instance.
+ *
+ */
+ public ProcessingEditorPlugin() {
+// [lonnen]
+// Java editor example has "fgInstance= this;"
+// while the editor template uses the start method to handle
+// that and leaves this empty. Since I've been chasing down
+// this null pointer error for going on 12 hours, I'm going
+// to try it the template's way and see if it works.
+//
+// That did the trick! On to debugging other problems. [lonnen] June 10 2010
+ }
+
+ /* added from the editor template, not present in the java editor code
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ fgInstance = this;
+ //System.out.println("fgInstance initialized!");
+ }
+
+ /* added from the editor template, not present in the java editor code
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ fgInstance = null;
+ super.stop(context);
+ }
+
+
+ /**
+ * Returns the default plug-in instance.
+ *
+ * @return the default plug-in instance
+ */
+ public static ProcessingEditorPlugin getDefault() { return fgInstance; }
+
+ /**
+ * Return a scanner for creating Processing partitions.
+ * Processing uses Java's commenting scheme, so our partitioner is almost identical. Unlike
+ * the Java partitioner, however, this Processing one currently treats the JavaDoc style
+ * comments as simple multiline comments.
+ *
+ * @return a scanner for creating Processing partitions
+ */
+ public ProcessingPartitionScanner getProcessingPartitionScanner() {
+ if (fPartitionScanner == null)
+ fPartitionScanner= new ProcessingPartitionScanner();
+ return fPartitionScanner;
+ }
+
+ /**
+ * Returns the singleton Processing code scanner.
+ *
+ * @return the singleton Processing code scanner
+ */
+ public RuleBasedScanner getProcessingCodeScanner() {
+ if (fCodeScanner == null)
+ fCodeScanner= new ProcessingCodeScanner(getProcessingColorProvider());
+ return fCodeScanner;
+ }
+
+ /**
+ * Returns the singleton Processing color provider.
+ *
+ * @return the singleton Processing color provider
+ */
+ public ProcessingColorProvider getProcessingColorProvider() {
+ if (fColorProvider == null)
+ fColorProvider= new ProcessingColorProvider();
+ return fColorProvider;
+ }
+
+ /**
+ * Returns the singleton Processingdoc scanner.
+ *
+ * @return the singleton Processingdoc scanner
+ */
+ public RuleBasedScanner getProcessingDocScanner() {
+ if (fDocScanner == null)
+ fDocScanner= new JavaDocScanner(fColorProvider);
+ return fDocScanner;
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingPartitionScanner.java b/editor/org.processing.editor/src/org/processing/editor/ProcessingPartitionScanner.java
new file mode 100644
index 000000000..70e88efdc
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingPartitionScanner.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.rules.*;
+
+/**
+ * Processing uses Java comments, so we use the same scanner. The class name is
+ * changed for consistency.
+ *
+ * This scanner recognizes the JavaDoc comments and Java multi line comments.
+ */
+public class ProcessingPartitionScanner extends RuleBasedPartitionScanner {
+
+ public final static String JAVA_MULTILINE_COMMENT= "__java_multiline_comment"; //$NON-NLS-1$
+ //Removing JavaDoc support from sketches, but leave in code
+// public final static String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$
+// public final static String[] JAVA_PARTITION_TYPES= new String[] { JAVA_MULTILINE_COMMENT, JAVA_DOC };
+ public final static String[] JAVA_PARTITION_TYPES= new String[] { JAVA_MULTILINE_COMMENT };
+
+ /**
+ * Detector for empty comments.
+ */
+ static class EmptyCommentDetector implements IWordDetector {
+
+ /* (non-Javadoc)
+ * Method declared on IWordDetector
+ */
+ public boolean isWordStart(char c) {
+ return (c == '/');
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IWordDetector
+ */
+ public boolean isWordPart(char c) {
+ return (c == '*' || c == '/');
+ }
+ }
+
+ /**
+ *
+ */
+ static class WordPredicateRule extends WordRule implements IPredicateRule {
+
+ private IToken fSuccessToken;
+
+ public WordPredicateRule(IToken successToken) {
+ super(new EmptyCommentDetector());
+ fSuccessToken= successToken;
+ addWord("/**/", fSuccessToken); //$NON-NLS-1$
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IPredicateRule#evaluate(ICharacterScanner, boolean)
+ */
+ public IToken evaluate(ICharacterScanner scanner, boolean resume) {
+ return super.evaluate(scanner);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IPredicateRule#getSuccessToken()
+ */
+ public IToken getSuccessToken() {
+ return fSuccessToken;
+ }
+ }
+
+ /**
+ * Creates the partitioner and sets up the appropriate rules.
+ */
+ public ProcessingPartitionScanner() {
+ super();
+ //Removing JavaDoc support from sketches, but leave in code
+// IToken javaDoc= new Token(JAVA_DOC);
+ IToken comment= new Token(JAVA_MULTILINE_COMMENT);
+
+ List rules= new ArrayList();
+
+ // Add rule for single line comments.
+ rules.add(new EndOfLineRule("//", Token.UNDEFINED)); //$NON-NLS-1$
+
+ // Add rule for strings and character constants.
+ rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+ rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+ // Add special case word rule.
+ rules.add(new WordPredicateRule(comment));
+
+ // Add rules for multi-line comments and javadoc.
+ //Removing JavaDoc support from sketches, but leave in code
+// rules.add(new MultiLineRule("/**", "*/", javaDoc, (char) 0, true)); //$NON-NLS-1$ //$NON-NLS-2$
+ rules.add(new MultiLineRule("/*", "*/", comment, (char) 0, true)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ IPredicateRule[] result= new IPredicateRule[rules.size()];
+ rules.toArray(result);
+ setPredicateRules(result);
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingSourceViewerConfiguration.java b/editor/org.processing.editor/src/org/processing/editor/ProcessingSourceViewerConfiguration.java
new file mode 100644
index 000000000..7c0d3ae6a
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingSourceViewerConfiguration.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor;
+
+import org.eclipse.swt.graphics.RGB;
+
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+//TODO implement completion properly for Processing
+//Removing JavaDoc support from sketches, but leave in code
+//import org.processing.editor.javadoc.JavaDocCompletionProcessor;
+import org.processing.editor.language.ProcessingAutoIndentStrategy;
+import org.processing.editor.language.ProcessingCompletionProcessor;
+import org.processing.editor.language.ProcessingDoubleClickSelector;
+import org.processing.editor.util.ProcessingColorProvider;
+
+/**
+ * Configuration for the ProcessingSourceViewer.
+ */
+public class ProcessingSourceViewerConfiguration extends SourceViewerConfiguration {
+
+
+ /**
+ * Single token scanner.
+ */
+ static class SingleTokenScanner extends BufferedRuleBasedScanner {
+ public SingleTokenScanner(TextAttribute attribute) {
+ setDefaultReturnToken(new Token(attribute));
+ }
+ }
+
+
+ /**
+ * Default constructor.
+ */
+ public ProcessingSourceViewerConfiguration() {
+ }
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+ return new ProcessingAnnotationHover();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+ */
+ public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
+ IAutoEditStrategy strategy= (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? new ProcessingAutoIndentStrategy() : new DefaultIndentLineAutoEditStrategy());
+ return new IAutoEditStrategy[] { strategy };
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+ return ProcessingEditorPlugin.PROCESSING_PARTITIONING;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+ //Removing JavaDoc support from sketches, but leave in code
+ //return new String[] { IDocument.DEFAULT_CONTENT_TYPE, ProcessingPartitionScanner.JAVA_DOC, ProcessingPartitionScanner.JAVA_MULTILINE_COMMENT };
+ return new String[] { IDocument.DEFAULT_CONTENT_TYPE, ProcessingPartitionScanner.JAVA_MULTILINE_COMMENT };
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+
+ ContentAssistant assistant= new ContentAssistant();
+ assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+ assistant.setContentAssistProcessor(new ProcessingCompletionProcessor(), IDocument.DEFAULT_CONTENT_TYPE);
+ // Disabling JavaDoc support [lonnen] june 12 2010
+ //assistant.setContentAssistProcessor(new JavaDocCompletionProcessor(), ProcessingPartitionScanner.JAVA_DOC);
+
+ assistant.enableAutoActivation(true);
+ assistant.setAutoActivationDelay(500);
+ assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
+ assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
+ assistant.setContextInformationPopupBackground(ProcessingEditorPlugin.getDefault().getProcessingColorProvider().getColor(new RGB(150, 150, 0)));
+
+ return assistant;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public String getDefaultPrefix(ISourceViewer sourceViewer, String contentType) {
+ return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? "//" : null); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
+ return new ProcessingDoubleClickSelector();
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
+ return new String[] { "\t", " " }; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+
+ ProcessingColorProvider provider= ProcessingEditorPlugin.getDefault().getProcessingColorProvider();
+
+ PresentationReconciler reconciler= new PresentationReconciler();
+ reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(ProcessingEditorPlugin.getDefault().getProcessingCodeScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+ //Removing JavaDoc support from sketches, but leave in code
+// dr= new DefaultDamagerRepairer(ProcessingEditorPlugin.getDefault().getProcessingDocScanner());
+// reconciler.setDamager(dr, ProcessingPartitionScanner.JAVA_DOC);
+// reconciler.setRepairer(dr, ProcessingPartitionScanner.JAVA_DOC);
+
+ dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(ProcessingColorProvider.COMMENT1))));
+ reconciler.setDamager(dr, ProcessingPartitionScanner.JAVA_MULTILINE_COMMENT);
+ reconciler.setRepairer(dr, ProcessingPartitionScanner.JAVA_MULTILINE_COMMENT);
+
+ return reconciler;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public int getTabWidth(ISourceViewer sourceViewer) {
+ return 4;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on SourceViewerConfiguration
+ */
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+ return new ProcessingTextHover();
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/ProcessingTextHover.java b/editor/org.processing.editor/src/org/processing/editor/ProcessingTextHover.java
new file mode 100644
index 000000000..1be66a9e3
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/ProcessingTextHover.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor;
+
+
+import org.eclipse.jface.text.*;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Example implementation for an ITextHover which hovers over Java code.
+ */
+public class ProcessingTextHover implements ITextHover {
+
+ /* (non-Javadoc)
+ * Method declared on ITextHover
+ */
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+ if (hoverRegion != null) {
+ try {
+ if (hoverRegion.getLength() > -1)
+ //TODO Implement a hover that returns something useful
+ return textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
+ } catch (BadLocationException x) {
+ }
+ }
+ return ProcessingEditorMessages.getString("ProcessingTextHover.emptySelection"); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * Method declared on ITextHover
+ */
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ Point selection= textViewer.getSelectedRange();
+ if (selection.x <= offset && offset < selection.x + selection.y)
+ return new Region(selection.x, selection.y);
+ return new Region(offset, 0);
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/javadoc/JavaDocCompletionProcessor.java b/editor/org.processing.editor/src/org/processing/editor/javadoc/JavaDocCompletionProcessor.java
new file mode 100644
index 000000000..94ff44d32
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/javadoc/JavaDocCompletionProcessor.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.javadoc;
+
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.*;
+
+/**
+ * Example Java doc completion processor. Should work for Processing unmodified. Do we even use Javadoc?
+ */
+public class JavaDocCompletionProcessor implements IContentAssistProcessor {
+
+ protected final static String[] fgProposals= { "@author", "@deprecated", "@exception", "@param", "@return", "@see", "@serial", "@serialData", "@serialField", "@since", "@throws", "@version" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
+ ICompletionProposal[] result= new ICompletionProposal[fgProposals.length];
+ for (int i= 0; i < fgProposals.length; i++)
+ result[i]= new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public char[] getContextInformationAutoActivationCharacters() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public String getErrorMessage() {
+ return null;
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/javadoc/JavaDocScanner.java b/editor/org.processing.editor/src/org/processing/editor/javadoc/JavaDocScanner.java
new file mode 100644
index 000000000..3bd97f7b1
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/javadoc/JavaDocScanner.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.javadoc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.*;
+import org.processing.editor.util.ProcessingColorProvider;
+import org.processing.editor.util.ProcessingWhitespaceDetector;
+
+
+/**
+ * A rule based JavaDoc scanner.
+ */
+public class JavaDocScanner extends RuleBasedScanner {
+
+ /**
+ * A key word detector.
+ */
+ static class JavaDocWordDetector implements IWordDetector {
+
+ /* (non-Javadoc)
+ * Method declared on IWordDetector
+ */
+ public boolean isWordStart(char c) {
+ return (c == '@');
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IWordDetector
+ */
+ public boolean isWordPart(char c) {
+ return Character.isLetter(c);
+ }
+ }
+
+ private static String[] fgKeywords= { "@author", "@deprecated", "@exception", "@param", "@return", "@see", "@serial", "@serialData", "@serialField", "@since", "@throws", "@version" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+ /**
+ * Create a new javadoc scanner for the given color provider.
+ *
+ * @param provider the color provider
+ */
+ public JavaDocScanner(ProcessingColorProvider provider) {
+ super();
+
+ IToken keyword= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.JAVADOC_KEYWORD)));
+ IToken tag= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.JAVADOC_TAG)));
+ IToken link= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.JAVADOC_LINK)));
+
+ List list= new ArrayList();
+
+ // Add rule for tags.
+ list.add(new SingleLineRule("<", ">", tag)); //$NON-NLS-2$ //$NON-NLS-1$
+
+ // Add rule for links.
+ list.add(new SingleLineRule("{", "}", link)); //$NON-NLS-2$ //$NON-NLS-1$
+
+ // Add generic whitespace rule.
+ list.add(new WhitespaceRule(new ProcessingWhitespaceDetector()));
+
+ // Add word rule for keywords.
+ WordRule wordRule= new WordRule(new JavaDocWordDetector());
+ for (int i= 0; i < fgKeywords.length; i++)
+ wordRule.addWord(fgKeywords[i], keyword);
+ list.add(wordRule);
+
+ IRule[] result= new IRule[list.size()];
+ list.toArray(result);
+ setRules(result);
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/language/ProcessingAutoIndentStrategy.java b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingAutoIndentStrategy.java
new file mode 100644
index 000000000..449cef152
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingAutoIndentStrategy.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.language;
+
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextUtilities;
+
+/**
+ * Auto indent line strategy sensitive to brackets. Should work for Processing unmodified.
+ */
+public class ProcessingAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
+
+ public ProcessingAutoIndentStrategy() {
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IAutoIndentStrategy
+ */
+ public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+ if (c.length == 0 && c.text != null && endsWithDelimiter(d, c.text))
+ smartIndentAfterNewLine(d, c);
+ else if ("}".equals(c.text)) { //$NON-NLS-1$
+ smartInsertAfterBracket(d, c);
+ }
+ }
+
+ /**
+ * Returns whether or not the given text ends with one of the documents legal line delimiters.
+ *
+ * @param d the document
+ * @param txt the text
+ * @return true if txt ends with one of the document's line delimiters, false otherwise
+ */
+ private boolean endsWithDelimiter(IDocument d, String txt) {
+ String[] delimiters= d.getLegalLineDelimiters();
+ if (delimiters != null)
+ return TextUtilities.endsWith(delimiters, txt) > -1;
+ return false;
+ }
+
+ /**
+ * Returns the line number of the next bracket after end.
+ *
+ * @param document - the document being parsed
+ * @param line - the line to start searching back from
+ * @param end - the end position to search back from
+ * @param closingBracketIncrease - the number of brackets to skip
+ * @return the line number of the next matching bracket after end
+ * @throws BadLocationException in case the line numbers are invalid in the document
+ */
+ protected int findMatchingOpenBracket(IDocument document, int line, int end, int closingBracketIncrease) throws BadLocationException {
+
+ int start= document.getLineOffset(line);
+ int brackcount= getBracketCount(document, start, end, false) - closingBracketIncrease;
+
+ // sum up the brackets counts of each line (closing brackets count negative,
+ // opening positive) until we find a line the brings the count to zero
+ while (brackcount < 0) {
+ line--;
+ if (line < 0) {
+ return -1;
+ }
+ start= document.getLineOffset(line);
+ end= start + document.getLineLength(line) - 1;
+ brackcount += getBracketCount(document, start, end, false);
+ }
+ return line;
+ }
+
+ /**
+ * Returns the bracket value of a section of text. Closing brackets have a value of -1 and
+ * open brackets have a value of 1.
+ *
+ * @param document - the document being parsed
+ * @param start - the start position for the search
+ * @param end - the end position for the search
+ * @param ignoreCloseBrackets - whether or not to ignore closing brackets in the count
+ * @return the bracket value of a section of text
+ * @throws BadLocationException in case the positions are invalid in the document
+ */
+ private int getBracketCount(IDocument document, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
+
+ int begin = start;
+ int bracketcount= 0;
+ while (begin < end) {
+ char curr= document.getChar(begin);
+ begin++;
+ switch (curr) {
+ case '/' :
+ if (begin < end) {
+ char next= document.getChar(begin);
+ if (next == '*') {
+ // a comment starts, advance to the comment end
+ begin= getCommentEnd(document, begin + 1, end);
+ } else if (next == '/') {
+ // '//'-comment: nothing to do anymore on this line
+ begin= end;
+ }
+ }
+ break;
+ case '*' :
+ if (begin < end) {
+ char next= document.getChar(begin);
+ if (next == '/') {
+ // we have been in a comment: forget what we read before
+ bracketcount= 0;
+ begin++;
+ }
+ }
+ break;
+ case '{' :
+ bracketcount++;
+ ignoreCloseBrackets= false;
+ break;
+ case '}' :
+ if (!ignoreCloseBrackets) {
+ bracketcount--;
+ }
+ break;
+ case '"' :
+ case '\'' :
+ begin= getStringEnd(document, begin, end, curr);
+ break;
+ default :
+ }
+ }
+ return bracketcount;
+ }
+
+ /**
+ * Returns the end position of a comment starting at the given position.
+ *
+ * @param document - the document being parsed
+ * @param position - the start position for the search
+ * @param end - the end position for the search
+ * @return the end position of a comment starting at the given position
+ * @throws BadLocationException in case position and end are invalid in the document
+ */
+ private int getCommentEnd(IDocument document, int position, int end) throws BadLocationException {
+ int currentPosition = position;
+ while (currentPosition < end) {
+ char curr= document.getChar(currentPosition);
+ currentPosition++;
+ if (curr == '*') {
+ if (currentPosition < end && document.getChar(currentPosition) == '/') {
+ return currentPosition + 1;
+ }
+ }
+ }
+ return end;
+ }
+
+ /**
+ * Returns the content of the given line without the leading whitespace.
+ *
+ * @param document - the document being parsed
+ * @param line - the line being searched
+ * @return the content of the given line without the leading whitespace
+ * @throws BadLocationException in case line is invalid in the document
+ */
+ protected String getIndentOfLine(IDocument document, int line) throws BadLocationException {
+ if (line > -1) {
+ int start= document.getLineOffset(line);
+ int end= start + document.getLineLength(line) - 1;
+ int whiteend= findEndOfWhiteSpace(document, start, end);
+ return document.get(start, whiteend - start);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the position of the character in the document after position.
+ *
+ * @param document - the document being parsed
+ * @param position - the position to start searching from
+ * @param end - the end of the document
+ * @param character - the character you are trying to match
+ * @return the next location of character
+ * @throws BadLocationException in case position is invalid in the document
+ */
+ private int getStringEnd(IDocument document, int position, int end, char character) throws BadLocationException {
+ int currentPosition = position;
+ while (currentPosition < end) {
+ char currentCharacter= document.getChar(currentPosition);
+ currentPosition++;
+ if (currentCharacter == '\\') {
+ // ignore escaped characters
+ currentPosition++;
+ } else if (currentCharacter == character) {
+ return currentPosition;
+ }
+ }
+ return end;
+ }
+
+ /**
+ * Set the indent of a new line based on the command provided in the supplied document.
+ * @param document - the document being parsed
+ * @param command - the command being performed
+ */
+ protected void smartIndentAfterNewLine(IDocument document, DocumentCommand command) {
+
+ int docLength= document.getLength();
+ if (command.offset == -1 || docLength == 0)
+ return;
+
+ try {
+ int p= (command.offset == docLength ? command.offset - 1 : command.offset);
+ int line= document.getLineOfOffset(p);
+
+ StringBuffer buf= new StringBuffer(command.text);
+ if (command.offset < docLength && document.getChar(command.offset) == '}') {
+ int indLine= findMatchingOpenBracket(document, line, command.offset, 0);
+ if (indLine == -1) {
+ indLine= line;
+ }
+ buf.append(getIndentOfLine(document, indLine));
+ } else {
+ int start= document.getLineOffset(line);
+ int whiteend= findEndOfWhiteSpace(document, start, command.offset);
+ buf.append(document.get(start, whiteend - start));
+ if (getBracketCount(document, start, command.offset, true) > 0) {
+ buf.append('\t');
+ }
+ }
+ command.text= buf.toString();
+
+ } catch (BadLocationException excp) {
+ System.out.println(ProcessingEditorMessages.getString("AutoIndent.error.bad_location_1")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Set the indent of a bracket based on the command provided in the supplied document.
+ * @param document - the document being parsed
+ * @param command - the command being performed
+ */
+ protected void smartInsertAfterBracket(IDocument document, DocumentCommand command) {
+ if (command.offset == -1 || document.getLength() == 0)
+ return;
+
+ try {
+ int p= (command.offset == document.getLength() ? command.offset - 1 : command.offset);
+ int line= document.getLineOfOffset(p);
+ int start= document.getLineOffset(line);
+ int whiteend= findEndOfWhiteSpace(document, start, command.offset);
+
+ // shift only when line does not contain any text up to the closing bracket
+ if (whiteend == command.offset) {
+ // evaluate the line with the opening bracket that matches out closing bracket
+ int indLine= findMatchingOpenBracket(document, line, command.offset, 1);
+ if (indLine != -1 && indLine != line) {
+ // take the indent of the found line
+ StringBuffer replaceText= new StringBuffer(getIndentOfLine(document, indLine));
+ // add the rest of the current line including the just added close bracket
+ replaceText.append(document.get(whiteend, command.offset - whiteend));
+ replaceText.append(command.text);
+ // modify document command
+ command.length= command.offset - start;
+ command.offset= start;
+ command.text= replaceText.toString();
+ }
+ }
+ } catch (BadLocationException excp) {
+ System.out.println(ProcessingEditorMessages.getString("AutoIndent.error.bad_location_2")); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/language/ProcessingCodeScanner.java b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingCodeScanner.java
new file mode 100644
index 000000000..7399c78ad
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingCodeScanner.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.language;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.*;
+import org.processing.editor.util.*;
+
+/**
+ * A Processing code scanner.
+ */
+public class ProcessingCodeScanner extends RuleBasedScanner {
+
+ private static String[] fgKeywords1= { "abstract", "break", "case", "catch", "class", "continue", "default", "do", "else", "extends", "final", "finally", "for", "if", "implements", "import", "instanceof", "interface", "native", "new", "package", "private", "protected", "public", "return", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while" }; //$NON-NLS-36$ //$NON-NLS-35$ //$NON-NLS-34$ //$NON-NLS-33$ //$NON-NLS-32$ //$NON-NLS-31$ //$NON-NLS-30$ //$NON-NLS-29$ //$NON-NLS-28$ //$NON-NLS-27$ //$NON-NLS-26$ //$NON-NLS-25$ //$NON-NLS-24$ //$NON-NLS-23$ //$NON-NLS-22$ //$NON-NLS-21$ //$NON-NLS-20$ //$NON-NLS-19$ //$NON-NLS-18$ //$NON-NLS-17$ //$NON-NLS-16$ //$NON-NLS-15$ //$NON-NLS-14$ //$NON-NLS-13$ //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ //TODO populate rule based scanner [lonnen] June 8 2010
+ // at the moment we'll use a few examples, the whole thing will need to be
+ // loaded with a helper class from keywords.txt
+ private static String[] fgKeywords2= {"setup","random","size","for"}; // methods
+ private static String[] fgKeywords3= {"byte","short","color","char","int","float"}; // byte short color char
+ private static String[] fgLiterals1= {"null", "true", "this", "false", "P2D"}; //
+ private static String[] fgLiterals2= {"mouseX","width","pixels","frameRate","height"};
+ private static String[] fgLabels = {}; //unused?
+ private static String[] fgOperators = {"+", "-", "=", "/", "*"};
+// private static String[] fgInvalids = {}; // ?? commented out until I figure out what this does
+ // Deleted the java 'types' and 'constants'
+
+ /**
+ * Creates a Processing code scanner with the given color provider.
+ *
+ * @param provider the color provider
+ */
+ public ProcessingCodeScanner(ProcessingColorProvider provider) {
+
+ IToken keyword1= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.KEYWORD1)));
+ IToken keyword2= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.KEYWORD2)));
+ IToken keyword3= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.KEYWORD3)));
+ IToken literal1= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.LITERAL1)));
+ IToken literal2= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.LITERAL2)));
+ IToken label= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.LABEL)));
+ IToken operator= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.OPERATOR)));
+// IToken invalid= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.INVALID)));
+ // leave the rest for now
+ IToken string= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.STRING)));
+ IToken comment= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.COMMENT2)));
+ IToken other= new Token(new TextAttribute(provider.getColor(ProcessingColorProvider.DEFAULT)));
+
+ List rules= new ArrayList();
+
+ // Add rule for single line comments.
+ rules.add(new EndOfLineRule("//", comment)); //$NON-NLS-1$
+
+ // Add rule for strings and character constants.
+ rules.add(new SingleLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+ rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+ // Add generic whitespace rule.
+ rules.add(new WhitespaceRule(new ProcessingWhitespaceDetector()));
+
+ // Add word rule for keywords
+ WordRule wordRule= new WordRule(new ProcessingWordDetector(), other);
+ for (int i= 0; i < fgKeywords1.length; i++)
+ wordRule.addWord(fgKeywords1[i], keyword1);
+ for (int i= 0; i < fgKeywords2.length; i++)
+ wordRule.addWord(fgKeywords2[i], keyword2);
+ for (int i= 0; i < fgKeywords3.length; i++)
+ wordRule.addWord(fgKeywords3[i], keyword3);
+ // literals
+ for (int i= 0; i < fgLiterals1.length; i++)
+ wordRule.addWord(fgLiterals1[i], literal1);
+ for (int i= 0; i < fgLiterals2.length; i++)
+ wordRule.addWord(fgLiterals2[i], literal2);
+ // label
+ for (int i= 0; i < fgLabels.length; i++)
+ wordRule.addWord(fgLabels[i], label);
+ // operator
+ for (int i= 0; i < fgOperators.length; i++)
+ wordRule.addWord(fgOperators[i], operator);
+
+ rules.add(wordRule);
+
+ IRule[] result= new IRule[rules.size()];
+ rules.toArray(result);
+ setRules(result);
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/language/ProcessingCompletionProcessor.java b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingCompletionProcessor.java
new file mode 100644
index 000000000..44d66352d
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingCompletionProcessor.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.language;
+
+
+import java.text.MessageFormat;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.contentassist.*;
+
+/**
+ * Example Java completion processor. Should work unmodified for Processing.
+ */
+public class ProcessingCompletionProcessor implements IContentAssistProcessor {
+
+ /**
+ * Simple content assist tip closer. The tip is valid in a range
+ * of 5 characters around its popup location.
+ */
+ protected static class Validator implements IContextInformationValidator, IContextInformationPresenter {
+
+ protected int fInstallOffset;
+
+ /*
+ * @see IContextInformationValidator#isContextInformationValid(int)
+ */
+ public boolean isContextInformationValid(int offset) {
+ return Math.abs(fInstallOffset - offset) < 5;
+ }
+
+ /*
+ * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
+ */
+ public void install(IContextInformation info, ITextViewer viewer, int offset) {
+ fInstallOffset= offset;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int, TextPresentation)
+ */
+ public boolean updatePresentation(int documentPosition, TextPresentation presentation) {
+ return false;
+ }
+ }
+
+ protected final static String[] fgProposals=
+ { "abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "continue", "default", "do", "double", "else", "extends", "false", "final", "finally", "float", "for", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while" }; //$NON-NLS-48$ //$NON-NLS-47$ //$NON-NLS-46$ //$NON-NLS-45$ //$NON-NLS-44$ //$NON-NLS-43$ //$NON-NLS-42$ //$NON-NLS-41$ //$NON-NLS-40$ //$NON-NLS-39$ //$NON-NLS-38$ //$NON-NLS-37$ //$NON-NLS-36$ //$NON-NLS-35$ //$NON-NLS-34$ //$NON-NLS-33$ //$NON-NLS-32$ //$NON-NLS-31$ //$NON-NLS-30$ //$NON-NLS-29$ //$NON-NLS-28$ //$NON-NLS-27$ //$NON-NLS-26$ //$NON-NLS-25$ //$NON-NLS-24$ //$NON-NLS-23$ //$NON-NLS-22$ //$NON-NLS-21$ //$NON-NLS-20$ //$NON-NLS-19$ //$NON-NLS-18$ //$NON-NLS-17$ //$NON-NLS-16$ //$NON-NLS-15$ //$NON-NLS-14$ //$NON-NLS-13$ //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+ protected IContextInformationValidator fValidator= new Validator();
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
+ ICompletionProposal[] result= new ICompletionProposal[fgProposals.length];
+ for (int i= 0; i < fgProposals.length; i++) {
+ IContextInformation info= new ContextInformation(fgProposals[i], MessageFormat.format(ProcessingEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
+ result[i]= new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(ProcessingEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i]})); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
+ IContextInformation[] result= new IContextInformation[5];
+ for (int i= 0; i < result.length; i++)
+ result[i]= new ContextInformation(
+ MessageFormat.format(ProcessingEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset) }), //$NON-NLS-1$
+ MessageFormat.format(ProcessingEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); //$NON-NLS-1$
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return new char[] { '.', '(' };
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public char[] getContextInformationAutoActivationCharacters() {
+ return new char[] { '#' };
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public IContextInformationValidator getContextInformationValidator() {
+ return fValidator;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentAssistProcessor
+ */
+ public String getErrorMessage() {
+ return null;
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/language/ProcessingDoubleClickSelector.java b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingDoubleClickSelector.java
new file mode 100644
index 000000000..653a7dee4
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingDoubleClickSelector.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.language;
+
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+/**
+ * Double click strategy aware of Java identifier syntax rules. These should work
+ * for Processing without modification.
+ */
+public class ProcessingDoubleClickSelector implements ITextDoubleClickStrategy {
+
+ protected ITextViewer fText;
+ protected int fPos;
+ protected int fStartPos;
+ protected int fEndPos;
+
+ protected static char[] fgBrackets= { '{', '}', '(', ')', '[', ']', '"', '"' };
+
+ /*
+ * Create a JavaDoubleClickSelector.
+ */
+ public ProcessingDoubleClickSelector() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * Method declared on ITextDoubleClickStrategy
+ */
+ public void doubleClicked(ITextViewer text) {
+
+ fPos= text.getSelectedRange().x;
+
+ if (fPos < 0)
+ return;
+
+ fText= text;
+
+ if (!selectBracketBlock())
+ selectWord();
+ }
+
+ /**
+ * Match the brackets at the current selection. Return true if successful,
+ * false otherwise.
+ *
+ * @return true if brackets match, false otherwise
+ */
+ protected boolean matchBracketsAt() {
+
+ char prevChar, nextChar;
+
+ int i;
+ int bracketIndex1= fgBrackets.length;
+ int bracketIndex2= fgBrackets.length;
+
+ fStartPos= -1;
+ fEndPos= -1;
+
+ // get the chars preceding and following the start position
+ try {
+
+ IDocument doc= fText.getDocument();
+
+ prevChar= doc.getChar(fPos - 1);
+ nextChar= doc.getChar(fPos);
+
+ // is the char either an open or close bracket?
+ for (i= 0; i < fgBrackets.length; i= i + 2) {
+ if (prevChar == fgBrackets[i]) {
+ fStartPos= fPos - 1;
+ bracketIndex1= i;
+ }
+ }
+ for (i= 1; i < fgBrackets.length; i= i + 2) {
+ if (nextChar == fgBrackets[i]) {
+ fEndPos= fPos;
+ bracketIndex2= i;
+ }
+ }
+
+ if (fStartPos > -1 && bracketIndex1 < bracketIndex2) {
+ fEndPos= searchForClosingBracket(fStartPos, prevChar, fgBrackets[bracketIndex1 + 1], doc);
+ if (fEndPos > -1)
+ return true;
+ fStartPos= -1;
+ } else if (fEndPos > -1) {
+ fStartPos= searchForOpenBracket(fEndPos, fgBrackets[bracketIndex2 - 1], nextChar, doc);
+ if (fStartPos > -1)
+ return true;
+ fEndPos= -1;
+ }
+
+ } catch (BadLocationException x) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Select the word at the current selection location. Return true if successful,
+ * false otherwise.
+ *
+ * @return true if a word can be found at the current selection location, false otherwise
+ */
+ protected boolean matchWord() {
+
+ IDocument doc= fText.getDocument();
+
+ try {
+
+ int pos= fPos;
+ char c;
+
+ while (pos >= 0) {
+ c= doc.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ --pos;
+ }
+
+ fStartPos= pos;
+
+ pos= fPos;
+ int length= doc.getLength();
+
+ while (pos < length) {
+ c= doc.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ ++pos;
+ }
+
+ fEndPos= pos;
+
+ return true;
+
+ } catch (BadLocationException x) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the position of the closing bracket after startPosition.
+ *
+ * @param startPosition - the beginning position
+ * @param openBracket - the character that represents the open bracket
+ * @param closeBracket - the character that represents the close bracket
+ * @param document - the document being searched
+ * @return the location of the closing bracket.
+ * @throws BadLocationException in case startPosition is invalid in the document
+ */
+ protected int searchForClosingBracket(int startPosition, char openBracket, char closeBracket, IDocument document) throws BadLocationException {
+ int stack= 1;
+ int closePosition= startPosition + 1;
+ int length= document.getLength();
+ char nextChar;
+
+ while (closePosition < length && stack > 0) {
+ nextChar= document.getChar(closePosition);
+ if (nextChar == openBracket && nextChar != closeBracket)
+ stack++;
+ else if (nextChar == closeBracket)
+ stack--;
+ closePosition++;
+ }
+
+ if (stack == 0)
+ return closePosition - 1;
+ return -1;
+
+ }
+
+ /**
+ * Returns the position of the open bracket before startPosition.
+ *
+ * @param startPosition - the beginning position
+ * @param openBracket - the character that represents the open bracket
+ * @param closeBracket - the character that represents the close bracket
+ * @param document - the document being searched
+ * @return the location of the starting bracket.
+ * @throws BadLocationException in case startPosition is invalid in the document
+ */
+ protected int searchForOpenBracket(int startPosition, char openBracket, char closeBracket, IDocument document) throws BadLocationException {
+ int stack= 1;
+ int openPos= startPosition - 1;
+ char nextChar;
+
+ while (openPos >= 0 && stack > 0) {
+ nextChar= document.getChar(openPos);
+ if (nextChar == closeBracket && nextChar != openBracket)
+ stack++;
+ else if (nextChar == openBracket)
+ stack--;
+ openPos--;
+ }
+
+ if (stack == 0)
+ return openPos + 1;
+ return -1;
+ }
+
+ /**
+ * Select the area between the selected bracket and the closing bracket.
+ *
+ * @return true if selection was successful, false otherwise
+ */
+ protected boolean selectBracketBlock() {
+ if (matchBracketsAt()) {
+
+ if (fStartPos == fEndPos)
+ fText.setSelectedRange(fStartPos, 0);
+ else
+ fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Select the word at the current selection.
+ */
+ protected void selectWord() {
+ if (matchWord()) {
+
+ if (fStartPos == fEndPos)
+ fText.setSelectedRange(fStartPos, 0);
+ else
+ fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
+ }
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/language/ProcessingEditorMessages.java b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingEditorMessages.java
new file mode 100644
index 000000000..79f7f86b4
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/language/ProcessingEditorMessages.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.language;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class ProcessingEditorMessages {
+
+ private static final String RESOURCE_BUNDLE= "org.processing.editor.ProcessingEditorMessages";//$NON-NLS-1$
+
+ private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+ private ProcessingEditorMessages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/util/ProcessingColorProvider.java b/editor/org.processing.editor/src/org/processing/editor/util/ProcessingColorProvider.java
new file mode 100644
index 000000000..ff3df759e
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/util/ProcessingColorProvider.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.util;
+
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Manager for colors used in the Java editor
+ */
+public class ProcessingColorProvider {
+
+ public static final RGB COMMENT1= new RGB(126, 126, 126); //comment 1
+ public static final RGB COMMENT2= new RGB(126, 126, 126); //comment 2
+ public static final RGB KEYWORD1= new RGB(204, 102, 0);
+ public static final RGB KEYWORD2= new RGB(204, 102, 0);
+ public static final RGB KEYWORD3= new RGB(204, 102, 0);
+ public static final RGB LITERAL1= new RGB(0, 102, 153);
+ public static final RGB LITERAL2= new RGB(0, 102, 153);
+ public static final RGB LABEL= new RGB(0, 0, 128); // use listed as '?' in p5 doc
+ public static final RGB OPERATOR= new RGB(0, 0, 0);
+ public static final RGB INVALID= new RGB(126, 126, 126);
+ // for the moment we'll leave these
+ public static final RGB STRING= new RGB(0, 0, 128);
+ public static final RGB DEFAULT= new RGB(0, 0, 0);
+ // used to color JavaDoc by org.processing.editor.javadoc.JavaDocScanner, do we still want this?
+ public static final RGB JAVADOC_KEYWORD= new RGB(126, 126, 126);
+ public static final RGB JAVADOC_TAG= new RGB(126, 126, 126);
+ public static final RGB JAVADOC_LINK= new RGB(126, 126, 126);
+ public static final RGB JAVADOC_DEFAULT= new RGB(126, 126, 126);
+
+ protected Map fColorTable= new HashMap(17);
+
+ /**
+ * Release all of the color resources held onto by the receiver.
+ */
+ public void dispose() {
+ Iterator e= fColorTable.values().iterator();
+ while (e.hasNext())
+ ((Color) e.next()).dispose();
+ }
+
+ /**
+ * Return the color that is stored in the color table under the given RGB
+ * value.
+ *
+ * @param rgb the RGB value
+ * @return the color stored in the color table for the given RGB value
+ */
+ public Color getColor(RGB rgb) {
+ Color color= (Color) fColorTable.get(rgb);
+ if (color == null) {
+ color= new Color(Display.getCurrent(), rgb);
+ fColorTable.put(rgb, color);
+ }
+ return color;
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/util/ProcessingWhitespaceDetector.java b/editor/org.processing.editor/src/org/processing/editor/util/ProcessingWhitespaceDetector.java
new file mode 100644
index 000000000..93c328433
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/util/ProcessingWhitespaceDetector.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.util;
+
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * A Processing aware white space detector, same as a java aware white space detector.
+ */
+public class ProcessingWhitespaceDetector implements IWhitespaceDetector {
+
+ /* (non-Javadoc)
+ * Method declared on IWhitespaceDetector
+ */
+ public boolean isWhitespace(char character) {
+ return Character.isWhitespace(character);
+ }
+}
diff --git a/editor/org.processing.editor/src/org/processing/editor/util/ProcessingWordDetector.java b/editor/org.processing.editor/src/org/processing/editor/util/ProcessingWordDetector.java
new file mode 100644
index 000000000..3b42dadea
--- /dev/null
+++ b/editor/org.processing.editor/src/org/processing/editor/util/ProcessingWordDetector.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.processing.editor.util;
+
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A Processing aware word detector. Same as a java aware word detector.
+ */
+public class ProcessingWordDetector implements IWordDetector {
+
+ /* (non-Javadoc)
+ * Method declared on IWordDetector.
+ */
+ public boolean isWordPart(char character) {
+ return Character.isJavaIdentifierPart(character);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IWordDetector.
+ */
+ public boolean isWordStart(char character) {
+ return Character.isJavaIdentifierStart(character);
+ }
+}