* merge with HEAD
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/docs/RiHelper.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/docs/RiHelper.java
index f515e71..489e3d6 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/docs/RiHelper.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/docs/RiHelper.java
@@ -69,7 +69,7 @@
.append("dltkri.rb").toFile();
riProcess = ScriptLaunchUtil.runScriptWithInterpreter(install
.getInstallLocation().getAbsolutePath(), script, null, null,
- null);
+ null, install.getEnvironmentVariables());
writer = new OutputStreamWriter(riProcess.getOutputStream());
reader = new BufferedReader(new InputStreamReader(riProcess
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java
index a554a7d..008c2ad 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/documentation/RubyDocumentationProvider.java
@@ -52,6 +52,7 @@
*/
private static void installStuff(Document document) {
String[] types = new String[] { IRubyPartitions.RUBY_STRING,
+ IRubyPartitions.RUBY_SINGLE_QUOTE_STRING,
IRubyPartitions.RUBY_COMMENT, IRubyPartitions.RUBY_DOC,
IDocument.DEFAULT_CONTENT_TYPE };
FastPartitioner partitioner = new FastPartitioner(
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/editor/RubyEditor.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/editor/RubyEditor.java
index 57ade30..308b7e4 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/editor/RubyEditor.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/editor/RubyEditor.java
@@ -30,8 +30,11 @@
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.widgets.Composite;
@@ -205,4 +208,70 @@
super.configureSourceViewerDecorationSupport(support);
}
+ /**
+ * Jumps to the matching bracket.
+ */
+ public void gotoMatchingBracket() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ IDocument document = sourceViewer.getDocument();
+ if (document == null)
+ return;
+
+ IRegion selection = getSignedSelection(sourceViewer);
+
+ int selectionLength = Math.abs(selection.getLength());
+ if (selectionLength > 1) {
+ setStatusLineErrorMessage("No bracket selected");
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ // #26314
+ int sourceCaretOffset = selection.getOffset() + selection.getLength();
+ if (isSurroundedByBrackets(document, sourceCaretOffset))
+ sourceCaretOffset -= selection.getLength();
+
+ IRegion region = bracketMatcher.match(document, sourceCaretOffset);
+ if (region == null) {
+ setStatusLineErrorMessage("No matching bracket found");
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ int offset = region.getOffset();
+ int length = region.getLength();
+
+ if (length < 1)
+ return;
+
+ int anchor = bracketMatcher.getAnchor();
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
+ int targetOffset = (ICharacterPairMatcher.RIGHT == anchor) ? offset + 1
+ : offset + length;
+
+ boolean visible = false;
+ if (sourceViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
+ visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
+ } else {
+ IRegion visibleRegion = sourceViewer.getVisibleRegion();
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
+ visible = (targetOffset >= visibleRegion.getOffset() && targetOffset <= visibleRegion
+ .getOffset()
+ + visibleRegion.getLength());
+ }
+
+ if (!visible) {
+ setStatusLineErrorMessage("Matching bracket is outside selected element");
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ if (selection.getLength() < 0)
+ targetOffset -= selection.getLength();
+
+ sourceViewer.setSelectedRange(targetOffset, selection.getLength());
+ sourceViewer.revealRange(targetOffset, selection.getLength());
+ }
+
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/IRubyPartitions.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/IRubyPartitions.java
index e56613b..7f2d153 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/IRubyPartitions.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/IRubyPartitions.java
@@ -8,9 +8,11 @@
public static final String RUBY_COMMENT = "__ruby_comment";
public static final String RUBY_STRING = "__ruby_string";
+ public static final String RUBY_SINGLE_QUOTE_STRING = "__ruby_single_quote_string";
public static final String RUBY_DOC = "__ruby_doc";
public final static String[] RUBY_PARTITION_TYPES = new String[] {
IDocument.DEFAULT_CONTENT_TYPE, IRubyPartitions.RUBY_DOC,
- IRubyPartitions.RUBY_COMMENT, IRubyPartitions.RUBY_STRING };
+ IRubyPartitions.RUBY_COMMENT, IRubyPartitions.RUBY_STRING,
+ IRubyPartitions.RUBY_SINGLE_QUOTE_STRING };
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyAutoEditStrategy.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyAutoEditStrategy.java
index 4329e22..6c480d6 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyAutoEditStrategy.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyAutoEditStrategy.java
@@ -2,13 +2,6 @@
import java.util.Arrays;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.dltk.ast.parser.ISourceParser;
-import org.eclipse.dltk.compiler.problem.IProblem;
-import org.eclipse.dltk.compiler.problem.IProblemReporter;
-import org.eclipse.dltk.core.DLTKLanguageManager;
-import org.eclipse.dltk.ruby.core.RubyNature;
import org.eclipse.dltk.ruby.internal.ui.RubyUI;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.text.util.AutoEditUtils;
@@ -73,7 +66,7 @@
private String getApropriateBlockEnding(IDocument d,
RubyHeuristicScanner scanner, int offset)
throws BadLocationException {
- int beginning = scanner.findBlockBeginningOffset(offset);
+ int beginning = scanner.findBlockBeginningOffset(offset) - 1;
IRegion line = d.getLineInformationOfOffset(beginning);
int ending = Math.min(line.getOffset() + line.getLength(), offset);
int token = scanner.previousToken(ending, beginning);
@@ -128,7 +121,7 @@
if (Arrays.binarySearch(INDENT_TO_BLOCK_TOKENS, token) >= 0) {
String indent = "";
try {
- indent = getBlockIndent(d, c, scanner);
+ indent = getBlockIndent(d, info.getOffset(), scanner);
} catch (BadLocationException e) {
// there is no enclosing block
}
@@ -150,13 +143,34 @@
c.text = d.get(start, c.offset - start) + c.text;
c.length = c.offset - info.getOffset();
c.offset = info.getOffset();
+ } else {
+ // if previous was indented to block, restore original indentation
+ int wsPos = scanner.findNonIdentifierBackward(c.offset, info
+ .getOffset());
+ int previosToken = scanner.previousToken(c.offset, wsPos);
+ if (Arrays.binarySearch(INDENT_TO_BLOCK_TOKENS, previosToken) >= 0
+ && Character.isJavaIdentifierPart(c.text.charAt(0))) {
+ String indent = getPreviousLineIndent(d, info.getOffset() - 1,
+ scanner);
+
+ int pos = scanner.findNonWhitespaceForwardInAnyPartition(info
+ .getOffset(), c.offset);
+ String line = "";
+ if (pos != RubyHeuristicScanner.NOT_FOUND) {
+ line = d.get(pos, c.offset - pos);
+ }
+
+ c.text = indent + line + c.text;
+ c.length = c.offset - info.getOffset();
+ c.offset = info.getOffset();
+ }
}
}
- private String getBlockIndent(IDocument d, DocumentCommand c,
+ private String getBlockIndent(IDocument d, int offset,
RubyHeuristicScanner scanner) throws BadLocationException {
- int blockOffset = scanner.findBlockBeginningOffset(c.offset);
+ int blockOffset = scanner.findBlockBeginningOffset(offset);
if (blockOffset == RubyHeuristicScanner.NOT_FOUND)
throw new BadLocationException("Block not found");
@@ -182,7 +196,7 @@
// beginning
if (nextIsIdentToBlockToken(scanner, c.offset, lineEnd)) {
try {
- c.text += getBlockIndent(d, c, scanner);
+ c.text += getBlockIndent(d, c.offset, scanner);
} catch (BadLocationException e) {
// there is no enclosing block
}
@@ -190,7 +204,7 @@
}
// else
- String indent = getPreviousLineIndent(d, c, scanner);
+ String indent = getPreviousLineIndent(d, c.offset, scanner);
c.text += indent;
if (previousIsBlockBeginning(d, scanner, c.offset)) {
@@ -279,7 +293,8 @@
RubyHeuristicScanner scanner = new RubyHeuristicScanner(d);
String indent = "";
try {
- indent = getBlockIndent(d, c, scanner) + fPreferences.getIndent();
+ indent = getBlockIndent(d, c.offset, scanner)
+ + fPreferences.getIndent();
} catch (BadLocationException e) {
// there is no enclosing block
}
@@ -368,15 +383,15 @@
* determined
* @throws BadLocationException
*/
- private String getPreviousLineIndent(IDocument d, DocumentCommand c,
+ private String getPreviousLineIndent(IDocument d, int offset,
RubyHeuristicScanner scanner) throws BadLocationException {
StringBuffer result = new StringBuffer();
- if (c.offset == -1 || d.getLength() == 0)
+ if (offset < 0 || d.getLength() == 0)
return result.toString();
// find start of line
- int start = scanner.findPrecedingNotEmptyLine(c.offset);
+ int start = scanner.findPrecedingNotEmptyLine(offset);
IRegion info = d.getLineInformationOfOffset(start);
int end = scanner.findNonWhitespaceForwardInAnyPartition(start, start
+ info.getLength());
@@ -390,44 +405,85 @@
private boolean isBlockClosed(IDocument document, int offset)
throws BadLocationException {
+ // TODO: Remove this comment when Ruby parser become able to report
+ // unclosed blocks
+ //
+ // RubyHeuristicScanner scanner = new RubyHeuristicScanner(document);
+ // IRegion sourceRange = scanner.findSurroundingBlock(offset);
+ // if (sourceRange != null) {
+ // String source = document.get(sourceRange.getOffset(), sourceRange
+ // .getLength());
+ // char[] buffer = source.toCharArray();
+ //
+ // SyntaxErrorListener listener = new SyntaxErrorListener();
+ // ISourceParser parser;
+ // try {
+ // parser = DLTKLanguageManager
+ // .getSourceParser(RubyNature.NATURE_ID);
+ // parser.parse(null, buffer, listener);
+ // if (listener.errorOccured())
+ // return false;
+ // } catch (CoreException e) {
+ // DLTKUIPlugin.log(e);
+ // }
+ // }
+ return getBlockBalance(document, offset) <= 0;
+ }
+
+ /**
+ * Returns the block balance, i.e. zero if the blocks are balanced at
+ * <code>offset</code>, a negative number if there are more closing than
+ * opening braces, and a positive number if there are more opening than
+ * closing braces.
+ *
+ * @param document
+ * @param offset
+ * @param partitioning
+ * @return the block balance
+ */
+ private static int getBlockBalance(IDocument document, int offset) {
+ if (offset < 1)
+ return -1;
+ if (offset >= document.getLength())
+ return 1;
+
+ int begin = offset;
+ int end = offset - 1;
+
RubyHeuristicScanner scanner = new RubyHeuristicScanner(document);
- IRegion sourceRange = scanner.findSurroundingBlock(offset);
- if (sourceRange != null) {
- String source = document.get(sourceRange.getOffset(), sourceRange
- .getLength());
- char[] buffer = source.toCharArray();
- SyntaxErrorListener listener = new SyntaxErrorListener();
- ISourceParser parser;
- try {
- parser = DLTKLanguageManager
- .getSourceParser(RubyNature.NATURE_ID);
- parser.parse(null, buffer, listener);
- if (listener.errorOccured())
- return false;
- } catch (CoreException e) {
- DLTKUIPlugin.log(e);
- }
- }
- return true;
- }
-
- private static class SyntaxErrorListener implements IProblemReporter {
- private boolean fError = false;
-
- public void clearMarkers() {
- }
-
- public IMarker reportProblem(IProblem problem) throws CoreException {
- int id = problem.getID();
- if ((id & IProblem.Syntax) != 0 || id == IProblem.Unclassified) {
- fError = true;
- }
- return null;
- }
-
- public boolean errorOccured() {
- return fError;
+ while (true) {
+ begin = scanner.findBlockBeginningOffset(begin);
+ end = scanner.findBlockEndingOffset(end + 1);
+ if (begin == RubyHeuristicScanner.NOT_FOUND
+ && end == RubyHeuristicScanner.NOT_FOUND)
+ return 0;
+ if (begin == RubyHeuristicScanner.NOT_FOUND)
+ return -1;
+ if (end == RubyHeuristicScanner.NOT_FOUND)
+ return 1;
}
}
+
+ // TODO: Remove this comment when Ruby parser become able to report
+ // unclosed blocks
+ //
+ // private static class SyntaxErrorListener implements IProblemReporter {
+ // private boolean fError = false;
+ //
+ // public void clearMarkers() {
+ // }
+ //
+ // public IMarker reportProblem(IProblem problem) throws CoreException {
+ // int id = problem.getID();
+ // if ((id & IProblem.Syntax) != 0 || id == IProblem.Unclassified) {
+ // fError = true;
+ // }
+ // return null;
+ // }
+ //
+ // public boolean errorOccured() {
+ // return fError;
+ // }
+ // }
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyCodeScanner.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyCodeScanner.java
index 9c8b9a8..4cb59e5 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyCodeScanner.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyCodeScanner.java
@@ -12,6 +12,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.dltk.ruby.internal.ui.text.rules.RubyFloatNumberRule;
import org.eclipse.dltk.ruby.internal.ui.text.rules.StartWithRule;
import org.eclipse.dltk.ui.text.AbstractScriptScanner;
import org.eclipse.dltk.ui.text.IColorManager;
@@ -61,7 +62,7 @@
IToken keywordReturn = getToken(IRubyColorConstants.RUBY_KEYWORD_RETURN);
IToken comment = getToken(IRubyColorConstants.RUBY_SINGLE_LINE_COMMENT);
IToken other = getToken(IRubyColorConstants.RUBY_DEFAULT);
-// IToken number = getToken(RubyColorConstants.RUBY_NUMBER);
+ IToken number = getToken(IRubyColorConstants.RUBY_NUMBER);
IToken classVariable = getToken(IRubyColorConstants.RUBY_CLASS_VARIABLE);
IToken instanceVariable = getToken(IRubyColorConstants.RUBY_INSTANCE_VARIABLE);
@@ -72,8 +73,9 @@
// Add rule for single line comments.
rules.add(new EndOfLineRule("#", comment));
// Add generic whitespace rule.
- rules.add(new WhitespaceRule(new RubyWhitespaceDetector()));
- // rules.add(new FloatNumberRule(number));
+ rules.add(new WhitespaceRule(new RubyWhitespaceDetector()));
+ // Add rule for numbers
+ rules.add(new RubyFloatNumberRule(number));
// Global Variables
rules.add(new StartWithRule(globalVariable, '$') {
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyHeuristicScanner.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyHeuristicScanner.java
index 10560b6..71fa272 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyHeuristicScanner.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyHeuristicScanner.java
@@ -5,17 +5,18 @@
import org.eclipse.core.runtime.Assert;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
public class RubyHeuristicScanner extends ScriptHeuristicScanner implements
IRubySymbols {
- private static final int[] BLOCK_BEGINNINGS_STARTS = { TokenIF, TokenFOR,
+ private static final int[] BLOCK_BEGINNING_KEYWORDS = { TokenIF, TokenFOR,
TokenDEF, TokenCASE, TokenCATCH, TokenCLASS, TokenWHILE,
TokenBEGIN, TokenUNTIL, TokenUNLESS, TokenMODULE, TokenDO };
- private static final int[] BLOCK_BEGINNINGS_ENDS = { TokenDO, TokenLBRACE };
+ private static final int[] BLOCK_BEGINNING_SYMBOLS = { TokenLBRACE };
private static final int[] BLOCK_MIDDLES = { TokenELSE, TokenELSIF,
TokenENSURE, TokenRESCUE, TokenWHEN };
@@ -23,8 +24,8 @@
private static final int[] BLOCK_ENDINGS = { TokenEND, TokenRBRACE };
static {
- Arrays.sort(BLOCK_BEGINNINGS_STARTS);
- Arrays.sort(BLOCK_BEGINNINGS_ENDS);
+ Arrays.sort(BLOCK_BEGINNING_KEYWORDS);
+ Arrays.sort(BLOCK_BEGINNING_SYMBOLS);
Arrays.sort(BLOCK_MIDDLES);
Arrays.sort(BLOCK_ENDINGS);
}
@@ -152,27 +153,32 @@
int start = findBlockBeginningOffset(offset);
if (start == NOT_FOUND)
start = 0;
-
+
int end = findBlockEndingOffset(offset);
if (end == NOT_FOUND)
end = getDocument().getLength();
-
+
return new Region(start, end - start);
}
public boolean isBlockBeginning(int offset, int bound) {
- if (Arrays.binarySearch(BLOCK_BEGINNINGS_STARTS, nextToken(offset,
- bound)) >= 0) {
- // setting the position to start of the block keyword
- findNonIdentifierBackward(getPosition(), UNBOUND);
- setPosition(getPosition() + 1);
- return true;
- } else if (Arrays.binarySearch(BLOCK_BEGINNINGS_ENDS, previousToken(
- bound, offset)) >= 0) {
- // setting the position to start of the block keyword
- setPosition(getPosition() + 1);
- return true;
+ int token = previousToken(bound, offset);
+ while (token != NOT_FOUND) {
+ if (Arrays.binarySearch(BLOCK_BEGINNING_SYMBOLS, token) >= 0)
+ return true;
+
+ if (Arrays.binarySearch(BLOCK_BEGINNING_KEYWORDS, token) >= 0) {
+ int pos = getPosition();
+ token = previousToken(getPosition(), offset);
+ if (token == NOT_FOUND || token == TokenEQUAL) {
+ setPosition(pos + 1);
+ return true;
+ }
+ }
+
+ token = previousToken(getPosition(), offset);
}
+
return false;
}
@@ -188,7 +194,14 @@
}
public boolean isBlockEnding(int offset, int bound) {
- return Arrays.binarySearch(BLOCK_ENDINGS, nextToken(offset, bound)) >= 0;
+ int token = nextToken(offset, bound);
+ while (token != NOT_FOUND) {
+ if (Arrays.binarySearch(BLOCK_ENDINGS, token) >= 0)
+ return true;
+ token = nextToken(getPosition(), bound);
+ }
+
+ return false;
}
public int findBlockBeginningOffset(int offset) {
@@ -243,4 +256,25 @@
}
return NOT_FOUND;
}
+
+ public int previousTokenAfterInput(int offset, String appended) {
+ try {
+ if (appended.length() == 1) {
+ int token = getGenericToken(appended.charAt(0));
+ if (token != TokenOTHER)
+ return token;
+ }
+
+ IRegion line = getDocument().getLineInformationOfOffset(offset);
+ String content = getDocument().get(line.getOffset(),
+ offset - line.getOffset())
+ + appended;
+ IDocument newDoc = new Document(content);
+ RubyHeuristicScanner scanner = new RubyHeuristicScanner(newDoc);
+ return scanner.previousToken(content.length(), UNBOUND);
+ } catch (BadLocationException e) {
+ DLTKUIPlugin.log(e);
+ }
+ return NOT_FOUND;
+ }
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPartitionScanner.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPartitionScanner.java
index c9fbdf6..50d42db 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPartitionScanner.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPartitionScanner.java
@@ -12,6 +12,9 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.dltk.ruby.internal.ui.text.rules.RubyGlobalVarRule;
+import org.eclipse.dltk.ruby.internal.ui.text.rules.RubyPercentStringRule;
+import org.eclipse.dltk.ruby.internal.ui.text.rules.RubySlashRegexpRule;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.EndOfLineRule;
import org.eclipse.jface.text.rules.IPredicateRule;
@@ -25,17 +28,20 @@
private Token comment;
private Token rubyDoc;
private Token defaultToken;
-
+ private Token singleQuoteString;
+
/**
* Creates the partitioner and sets up the appropriate rules.
*/
public RubyPartitionScanner() {
super();
-
+
defaultToken = new Token(IDocument.DEFAULT_CONTENT_TYPE);
string = new Token(IRubyPartitions.RUBY_STRING);
+ singleQuoteString = new Token(IRubyPartitions.RUBY_SINGLE_QUOTE_STRING);
+
comment = new Token(IRubyPartitions.RUBY_COMMENT);
rubyDoc = new Token(IRubyPartitions.RUBY_DOC);
@@ -46,14 +52,14 @@
rules.add(new EndOfLineRule("#", comment));
- rules.add(new MultiLineRule("'", "'", string, '\\', true));
-
rules.add(new MultiLineRule("\"", "\"", string, '\\', true));
+
+ rules.add(new MultiLineRule("'", "'", singleQuoteString, '\\', true));
rules.add(new RubyPercentStringRule(string, false));
rules.add(new RubySlashRegexpRule(string));
-
+
rules.add(new RubyGlobalVarRule(defaultToken));
IPredicateRule[] result = new IPredicateRule[rules.size()];
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySingleQuoteStringScanner.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySingleQuoteStringScanner.java
new file mode 100644
index 0000000..6ebecc8
--- /dev/null
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySingleQuoteStringScanner.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ *
+
+ *******************************************************************************/
+package org.eclipse.dltk.ruby.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.dltk.ruby.internal.ui.text.IRubyColorConstants;
+import org.eclipse.dltk.ui.text.AbstractScriptScanner;
+import org.eclipse.dltk.ui.text.IColorManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class RubySingleQuoteStringScanner extends AbstractScriptScanner {
+
+ private static final String[] fgTokenProperties = new String[] { IRubyColorConstants.RUBY_STRING };
+
+ public RubySingleQuoteStringScanner(IColorManager manager,
+ IPreferenceStore store) {
+ super(manager, store);
+
+ initialize();
+ }
+
+ protected String[] getTokenProperties() {
+ return fgTokenProperties;
+ }
+
+ protected List createRules() {
+ List rules = new ArrayList();
+
+ // Add generic whitespace rule.
+ rules.add(new WhitespaceRule(new RubyWhitespaceDetector()));
+ setDefaultReturnToken(getToken(IRubyColorConstants.RUBY_STRING));
+
+ return rules;
+ }
+
+}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySourceViewerConfiguration.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySourceViewerConfiguration.java
index 385ca8b..86cd40c 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySourceViewerConfiguration.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySourceViewerConfiguration.java
@@ -58,6 +58,8 @@
private AbstractScriptScanner fStringScanner;
+ private AbstractScriptScanner fSingleQuoteStringScanner;
+
private AbstractScriptScanner fCommentScanner;
private AbstractScriptScanner fDocScanner;
@@ -74,7 +76,8 @@
public String[] getIndentPrefixes(ISourceViewer sourceViewer,
String contentType) {
- RubyPreferenceInterpreter prefs = new RubyPreferenceInterpreter(fPreferenceStore);
+ RubyPreferenceInterpreter prefs = new RubyPreferenceInterpreter(
+ fPreferenceStore);
if (prefs.getTabStyle() == TabStyle.SPACES)
return new String[] { AutoEditUtils.getNSpaces(prefs
.getIndentSize()) };
@@ -94,6 +97,8 @@
fCodeScanner = new RubyCodeScanner(getColorManager(), fPreferenceStore);
fStringScanner = new RubyStringScanner(getColorManager(),
fPreferenceStore);
+ fSingleQuoteStringScanner = new RubySingleQuoteStringScanner(
+ getColorManager(), fPreferenceStore);
fCommentScanner = new SingleTokenScriptScanner(getColorManager(),
fPreferenceStore, IRubyColorConstants.RUBY_SINGLE_LINE_COMMENT);
@@ -130,6 +135,10 @@
reconciler.setDamager(dr, IRubyPartitions.RUBY_STRING);
reconciler.setRepairer(dr, IRubyPartitions.RUBY_STRING);
+ dr = new DefaultDamagerRepairer(getSingleQuoteStringScanner());
+ reconciler.setDamager(dr, IRubyPartitions.RUBY_SINGLE_QUOTE_STRING);
+ reconciler.setRepairer(dr, IRubyPartitions.RUBY_SINGLE_QUOTE_STRING);
+
dr = new DefaultDamagerRepairer(getDocScanner());
reconciler.setDamager(dr, IRubyPartitions.RUBY_DOC);
reconciler.setRepairer(dr, IRubyPartitions.RUBY_DOC);
@@ -141,6 +150,10 @@
return reconciler;
}
+ private ITokenScanner getSingleQuoteStringScanner() {
+ return fSingleQuoteStringScanner;
+ }
+
private ITokenScanner getDocScanner() {
return fDocScanner;
}
@@ -164,6 +177,8 @@
fCodeScanner.adaptToPreferenceChange(event);
if (fStringScanner.affectsBehavior(event))
fStringScanner.adaptToPreferenceChange(event);
+ if (fSingleQuoteStringScanner.affectsBehavior(event))
+ fSingleQuoteStringScanner.adaptToPreferenceChange(event);
if (fDocScanner.affectsBehavior(event))
fDocScanner.adaptToPreferenceChange(event);
}
@@ -180,6 +195,7 @@
public boolean affectsTextPresentation(PropertyChangeEvent event) {
return fCodeScanner.affectsBehavior(event)
|| fStringScanner.affectsBehavior(event)
+ || fSingleQuoteStringScanner.affectsBehavior(event)
|| fDocScanner.affectsBehavior(event);
}
@@ -292,5 +308,7 @@
.setInformationProvider(provider, IRubyPartitions.RUBY_COMMENT);
presenter.setInformationProvider(provider, IRubyPartitions.RUBY_DOC);
presenter.setInformationProvider(provider, IRubyPartitions.RUBY_STRING);
+ presenter.setInformationProvider(provider,
+ IRubyPartitions.RUBY_SINGLE_QUOTE_STRING);
}
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyStringScanner.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyStringScanner.java
index b88b5a3..8f5f0d1 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyStringScanner.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyStringScanner.java
@@ -12,17 +12,19 @@
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.dltk.ruby.internal.ui.text.IRubyColorConstants;
import org.eclipse.dltk.ui.text.AbstractScriptScanner;
import org.eclipse.dltk.ui.text.IColorManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordPatternRule;
public class RubyStringScanner extends AbstractScriptScanner {
private static final String[] fgTokenProperties = new String[] {
- IRubyColorConstants.RUBY_STRING
- };
+ IRubyColorConstants.RUBY_STRING, IRubyColorConstants.RUBY_DEFAULT,
+ IRubyColorConstants.RUBY_CLASS_VARIABLE,
+ IRubyColorConstants.RUBY_GLOBAL_VARIABLE,
+ IRubyColorConstants.RUBY_INSTANCE_VARIABLE };
public RubyStringScanner(IColorManager manager, IPreferenceStore store) {
super(manager, store);
@@ -30,23 +32,26 @@
initialize();
}
-
protected String[] getTokenProperties() {
return fgTokenProperties;
}
-
protected List createRules() {
- List/*<IRule>*/ rules = new ArrayList/*<IRule>*/();
+ List rules = new ArrayList/* <IRule> */();
// Add generic whitespace rule.
rules.add(new WhitespaceRule(new RubyWhitespaceDetector()));
-
- //TODO: Add here % and %{name} variables handling.
-
+ rules.add(new WordPatternRule(new RubyWordDetector(), "#$", "",
+ getToken(IRubyColorConstants.RUBY_GLOBAL_VARIABLE)));
+ rules.add(new WordPatternRule(new RubyWordDetector(), "#@@", "",
+ getToken(IRubyColorConstants.RUBY_CLASS_VARIABLE)));
+ rules.add(new WordPatternRule(new RubyWordDetector(), "#@", "",
+ getToken(IRubyColorConstants.RUBY_INSTANCE_VARIABLE)));
+// rules.add(new MultiLineRule("#{", "}",
+// getToken(IRubyColorConstants.RUBY_DEFAULT)));
+
setDefaultReturnToken(getToken(IRubyColorConstants.RUBY_STRING));
return rules;
}
-
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyTextTools.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyTextTools.java
index 86d9541..9106b8c 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyTextTools.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyTextTools.java
@@ -23,8 +23,9 @@
private IPartitionTokenScanner fPartitionScanner;
private final static String[] LEGAL_CONTENT_TYPES = new String[] {
- IRubyPartitions.RUBY_STRING, IRubyPartitions.RUBY_COMMENT,
- IRubyPartitions.RUBY_DOC };
+ IRubyPartitions.RUBY_STRING,
+ IRubyPartitions.RUBY_SINGLE_QUOTE_STRING,
+ IRubyPartitions.RUBY_COMMENT, IRubyPartitions.RUBY_DOC };
public RubyTextTools(boolean autoDisposeOnDisplayDispose) {
super(IRubyPartitions.RUBY_PARTITIONING, LEGAL_CONTENT_TYPES,
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/ScriptHeuristicScanner.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/ScriptHeuristicScanner.java
index bfee352..1d53d1e 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/ScriptHeuristicScanner.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/ScriptHeuristicScanner.java
@@ -503,7 +503,7 @@
return scanBackward(position, bound, fNonWS);
}
- private int getGenericToken(char ch) {
+ protected int getGenericToken(char ch) {
switch (ch) {
case LBRACE:
return TokenLBRACE;
@@ -617,7 +617,7 @@
int from, to = pos + 1;
pos = findNonIdentifierBackward(pos, bound);
if (pos == NOT_FOUND)
- from = bound == UNBOUND ? 0 : bound + 1;
+ from = bound == UNBOUND ? 0 : bound;
else
from = pos + 1;
@@ -659,34 +659,6 @@
}
return 0;
}
-
- public int previousTokenAfterInput(int offset, String appended) {
- try {
- if (appended.length() == 1) {
- int token = getGenericToken(appended.charAt(0));
- if (token != TokenOTHER)
- return token;
- }
-
- int lineOffset = fDocument.getLineInformationOfOffset(offset)
- .getOffset();
- int token = previousToken(offset, lineOffset);
- if (token != TokenIDENTIFIER)
- return token;
-
- // else
- int start = getPosition() + 1;
- int end = findNonIdentifierForward(start, offset);
- if (end == NOT_FOUND) {
- end = offset;
- }
- String identifier = fDocument.get(start, end - start);
- return getToken(start, identifier + appended);
- } catch (BadLocationException e) {
- DLTKUIPlugin.log(e);
- }
- return NOT_FOUND;
- }
/**
* Returns the position of the closing peer character (forward search). Any scopes introduced by opening peers
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposal.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposal.java
index cd0d1c0..3ca659b 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposal.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/completion/RubyCompletionProposal.java
@@ -9,7 +9,10 @@
*******************************************************************************/
package org.eclipse.dltk.ruby.internal.ui.text.completion;
+import org.eclipse.dltk.ruby.internal.ui.RubyUI;
+import org.eclipse.dltk.ui.PreferenceConstants;
import org.eclipse.dltk.ui.text.completion.ScriptCompletionProposal;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.Image;
public class RubyCompletionProposal extends ScriptCompletionProposal {
@@ -36,6 +39,10 @@
return false;
}
-
+ protected boolean insertCompletion() {
+ IPreferenceStore preference = RubyUI.getDefault().getPreferenceStore();
+ return preference
+ .getBoolean(PreferenceConstants.CODEASSIST_INSERT_COMPLETION);
+ }
}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyFloatNumberRule.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyFloatNumberRule.java
new file mode 100644
index 0000000..155ce9e
--- /dev/null
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyFloatNumberRule.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ *
+
+ *******************************************************************************/
+package org.eclipse.dltk.ruby.internal.ui.text.rules;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * An implementation of <code>IRule</code> detecting a numerical value.
+ */
+public class RubyFloatNumberRule implements IRule {
+ protected static final int UNDEFINED = -1;
+ protected IToken fToken;
+ protected int fColumn = UNDEFINED;
+
+ public RubyFloatNumberRule(IToken token) {
+ Assert.isNotNull(token);
+ fToken = token;
+ }
+
+ public void setColumnConstraint(int column) {
+ if (column < 0)
+ column = UNDEFINED;
+ fColumn = column;
+ }
+
+ public IToken evaluate(ICharacterScanner scanner) {
+ int c = scanner.read();
+ int p = c;
+ if (Character.isDigit((char) c) || c == '.') {
+ if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+ do {
+ p = c;
+ c = scanner.read();
+ } while (Character.isDigit((char) c));
+ if ((c != 'e' && c != 'E')) {
+ scanner.unread();
+ }
+ if (p == '.') {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ return fToken;
+ }
+ }
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+}
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyGlobalVarRule.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyGlobalVarRule.java
similarity index 95%
rename from plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyGlobalVarRule.java
rename to plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyGlobalVarRule.java
index edb301f..ea3cd80 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyGlobalVarRule.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyGlobalVarRule.java
@@ -7,7 +7,7 @@
*
*******************************************************************************/
-package org.eclipse.dltk.ruby.internal.ui.text;
+package org.eclipse.dltk.ruby.internal.ui.text.rules;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IPredicateRule;
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPercentStringRule.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyPercentStringRule.java
similarity index 99%
rename from plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPercentStringRule.java
rename to plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyPercentStringRule.java
index ed19c3d..92c6d9a 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubyPercentStringRule.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubyPercentStringRule.java
@@ -7,7 +7,7 @@
*
*******************************************************************************/
-package org.eclipse.dltk.ruby.internal.ui.text;
+package org.eclipse.dltk.ruby.internal.ui.text.rules;
import java.util.Arrays;
import java.util.Comparator;
diff --git a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySlashRegexpRule.java b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubySlashRegexpRule.java
similarity index 95%
rename from plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySlashRegexpRule.java
rename to plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubySlashRegexpRule.java
index 474129e..ab66dfc 100644
--- a/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/RubySlashRegexpRule.java
+++ b/plugins/org.eclipse.dltk.ruby.ui/src/org/eclipse/dltk/ruby/internal/ui/text/rules/RubySlashRegexpRule.java
@@ -7,7 +7,7 @@
*
*******************************************************************************/
-package org.eclipse.dltk.ruby.internal.ui.text;
+package org.eclipse.dltk.ruby.internal.ui.text.rules;
import org.eclipse.dltk.ruby.core.utils.RubySyntaxUtils;
import org.eclipse.jface.text.rules.ICharacterScanner;