fix mousePressed/mousePressed() syntax coloring (issue #41)

This commit is contained in:
benfry
2012-11-27 00:42:09 +00:00
parent c2d84d77ef
commit f735a976d6
4 changed files with 189 additions and 115 deletions

View File

@@ -22,119 +22,116 @@ import javax.swing.text.Segment;
* @author Slava Pestov, Mike Dillon
* @version $Id$
*/
public class KeywordMap
{
/**
* Creates a new <code>KeywordMap</code>.
* @param ignoreCase True if keys are case insensitive
*/
public KeywordMap(boolean ignoreCase)
{
this(ignoreCase, 52);
this.ignoreCase = ignoreCase;
}
public class KeywordMap {
private Keyword[] map;
private boolean ignoreCase;
/**
* Creates a new <code>KeywordMap</code>.
* @param ignoreCase True if the keys are case insensitive
* @param mapLength The number of `buckets' to create.
* A value of 52 will give good performance for most maps.
*/
public KeywordMap(boolean ignoreCase, int mapLength)
{
this.mapLength = mapLength;
this.ignoreCase = ignoreCase;
map = new Keyword[mapLength];
}
/**
* Creates a new <code>KeywordMap</code>.
* @param ignoreCase True if keys are case insensitive
*/
public KeywordMap(boolean ignoreCase) {
this(ignoreCase, 52);
this.ignoreCase = ignoreCase;
}
/**
* Looks up a key.
* @param text The text segment
* @param offset The offset of the substring within the text segment
* @param length The length of the substring
*/
public byte lookup(Segment text, int offset, int length)
{
if(length == 0)
return Token.NULL;
Keyword k = map[getSegmentMapKey(text, offset, length)];
while(k != null)
{
if(length != k.keyword.length)
{
k = k.next;
continue;
}
if(SyntaxUtilities.regionMatches(ignoreCase,text,offset,
k.keyword))
return k.id;
k = k.next;
}
return Token.NULL;
}
/**
* Adds a key-value mapping.
* @param keyword The key
* @param id The value
*/
public void add(String keyword, byte id)
{
int key = getStringMapKey(keyword);
map[key] = new Keyword(keyword.toCharArray(),id,map[key]);
}
/**
* Creates a new <code>KeywordMap</code>.
* @param ignoreCase True if the keys are case insensitive
* @param mapLength The number of `buckets' to create.
* A value of 52 will give good performance for most maps.
*/
public KeywordMap(boolean ignoreCase, int mapLength) {
this.mapLength = mapLength;
this.ignoreCase = ignoreCase;
map = new Keyword[mapLength];
}
/**
* Returns true if the keyword map is set to be case insensitive,
* false otherwise.
*/
public boolean getIgnoreCase()
{
return ignoreCase;
}
/**
* Sets if the keyword map should be case insensitive.
* @param ignoreCase True if the keyword map should be case
* insensitive, false otherwise
*/
public void setIgnoreCase(boolean ignoreCase)
{
this.ignoreCase = ignoreCase;
}
/**
* Looks up a key.
* @param text The text segment
* @param offset The offset of the substring within the text segment
* @param length The length of the substring
*/
public byte lookup(Segment text, int offset, int length) {
if (length == 0) {
return Token.NULL;
}
Keyword k = map[getSegmentMapKey(text, offset, length)];
while(k != null) {
if (length != k.keyword.length) {
k = k.next;
continue;
}
if (SyntaxUtilities.regionMatches(ignoreCase,text,offset, k.keyword)) {
return k.id;
}
k = k.next;
}
return Token.NULL;
}
// protected members
protected int mapLength;
protected int getStringMapKey(String s)
{
return (Character.toUpperCase(s.charAt(0)) +
Character.toUpperCase(s.charAt(s.length()-1)))
% mapLength;
}
/**
* Adds a key-value mapping.
* @param keyword The key
* @param id The value
*/
public void add(String keyword, byte id) {
int key = getStringMapKey(keyword);
map[key] = new Keyword(keyword.toCharArray(),id,map[key]);
}
protected int getSegmentMapKey(Segment s, int off, int len)
{
return (Character.toUpperCase(s.array[off]) +
Character.toUpperCase(s.array[off + len - 1]))
% mapLength;
}
/**
* Returns true if the keyword map is set to be case insensitive,
* false otherwise.
*/
public boolean getIgnoreCase() {
return ignoreCase;
}
// private members
private static class Keyword
{
public Keyword(char[] keyword, byte id, Keyword next)
{
this.keyword = keyword;
this.id = id;
this.next = next;
}
/**
* Sets if the keyword map should be case insensitive.
* @param ignoreCase True if the keyword map should be case
* insensitive, false otherwise
*/
public void setIgnoreCase(boolean ignoreCase) {
this.ignoreCase = ignoreCase;
}
public final char[] keyword;
public final byte id;
public final Keyword next;
}
// protected members
protected int mapLength;
private Keyword[] map;
private boolean ignoreCase;
protected int getStringMapKey(String s) {
return (Character.toUpperCase(s.charAt(0)) +
Character.toUpperCase(s.charAt(s.length()-1)))
% mapLength;
}
protected int getSegmentMapKey(Segment s, int off, int len) {
return (Character.toUpperCase(s.array[off]) +
Character.toUpperCase(s.array[off + len - 1]))
% mapLength;
}
// private members
private static class Keyword {
public final char[] keyword;
public final byte id;
public final Keyword next;
public Keyword(char[] keyword, byte id, Keyword next) {
this.keyword = keyword;
this.id = id;
this.next = next;
}
}
}

View File

@@ -4,7 +4,7 @@
PdeKeywords - handles text coloring and links to html reference
Part of the Processing project - http://processing.org
Copyright (c) 2004-10 Ben Fry and Casey Reas
Copyright (c) 2004-12 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
@@ -118,7 +118,7 @@ public class PdeKeywords extends TokenMarker {
int offset = line.offset;
lastOffset = offset;
lastKeyword = offset;
int mlength = line.count + offset;
int mlength = offset + line.count;
boolean backslash = false;
loop: for (int i = offset; i < mlength; i++) {
@@ -186,13 +186,25 @@ public class PdeKeywords extends TokenMarker {
lastOffset = lastKeyword = mlength;
break loop;
}
i++; // jdf- fix http://dev.processing.org/bugs/show_bug.cgi?id=609
i++; // http://processing.org/bugs/bugzilla/609.html [jdf]
}
break;
default:
backslash = false;
if (!Character.isLetterOrDigit(c) && c != '_')
if (!Character.isLetterOrDigit(c) && c != '_') {
// if (i1 < mlength && array[i1]
// boolean paren = false;
// int stepper = i + 1;
// while (stepper < mlength) {
// if (array[stepper] == '(') {
// paren = true;
// break;
// }
// stepper++;
// }
doKeyword(line, i, c);
// doKeyword(line, i, checkParen(array, i1, mlength));
}
break;
}
break;
@@ -231,8 +243,9 @@ public class PdeKeywords extends TokenMarker {
}
}
if (token == Token.NULL)
if (token == Token.NULL) {
doKeyword(line, mlength, '\0');
}
switch (token) {
case Token.LITERAL1:
@@ -252,16 +265,75 @@ public class PdeKeywords extends TokenMarker {
}
return token;
}
private boolean checkParen(char[] array, int index, int stop) {
// boolean paren = false;
// int stepper = i + 1;
// while (stepper < mlength) {
// if (array[stepper] == '(') {
// paren = true;
// break;
// }
// stepper++;
// }
while (index < stop) {
// if (array[index] == '(') {
// return true;
// } else if (!Character.isWhitespace(array[index])) {
// return false;
// }
switch (array[index]) {
case '(':
return true;
case ' ':
case '\t':
case '\n':
case '\r':
index++;
break;
default:
// System.out.println("defaulting because " + array[index] + " " + PApplet.hex(array[index]));
return false;
}
}
// System.out.println("exiting " + new String(array, index, stop - index));
return false;
}
private boolean doKeyword(Segment line, int i, char c) {
// return doKeyword(line, i, false);
// }
//
//
// //private boolean doKeyword(Segment line, int i, char c) {
// private boolean doKeyword(Segment line, int i, boolean paren) {
int i1 = i + 1;
int len = i - lastKeyword;
boolean paren = checkParen(line.array, i, line.array.length);
// String s = new String(line.array, lastKeyword, len);
// if (s.equals("mousePressed")) {
// System.out.println("found mousePressed" + (paren ? "()" : ""));
// //new Exception().printStackTrace(System.out);
//// System.out.println(" " + i + " " + line.count + " " +
//// //new String(line.array, line.offset + i, line.offset + line.count - i));
//// new String(line.array, i, line.array.length - i));
// }
byte id = keywordColoring.lookup(line, lastKeyword, len);
if (id != Token.NULL) {
if (lastKeyword != lastOffset)
if (lastKeyword != lastOffset) {
addToken(lastKeyword - lastOffset, Token.NULL);
}
if (paren && id == Token.LITERAL2) {
id = Token.KEYWORD2;
} else if (!paren && id == Token.KEYWORD2) {
id = Token.LITERAL2;
}
addToken(len, id);
lastOffset = i;
}

View File

@@ -82,6 +82,10 @@ PROCESSING 2.0b7 (REV 0215) - 25 November 2012
+ mouseButton is 0 in mouseReleased() on OS X
http://code.google.com/p/processing/issues/detail?id=1373
+ mousePressed() coloring now different from mousePressed
http://code.google.com/p/processing/issues/detail?id=41
Still not necessarily perfect, but it's a big improvement.
+ Fix ugly results from resize() command on PImage:
http://code.google.com/p/processing/issues/detail?id=332
and similar on Android:

View File

@@ -43,12 +43,15 @@ X fix the debug stuff before shipping this out
X just remove for the release
X Reas added notes about command line support to the Wiki
X http://wiki.processing.org/w/Command_Line
X mousePressed() coloring now different from mousePressed
X i.e. mousePressed() is red but mouseMoved() is brown
X http://code.google.com/p/processing/issues/detail?id=41
X Token.KEYWORD / KEYWORD1/2 / LITERAL1/2/3
earlier
X The sketch name can't begin with '_' (underscore)
X http://code.google.com/p/processing/issues/detail?id=859
_ include debug mode as 'experimental'?
_ DebugMode throwing exception about breakpoints when trying to save
_ what to call it?
@@ -592,9 +595,6 @@ _ http://code.google.com/p/processing/issues/detail?id=11
_ or option to export all the code as colored html?
_ dim edit menus as appropriate during selection/no selection/etc
_ http://code.google.com/p/processing/issues/detail?id=14
_ code coloring is imperfect because it's not based on a parser
_ i.e. mousePressed() is red but mouseMoved() is brown
_ http://code.google.com/p/processing/issues/detail?id=41
_ implement better method of showing curly brace closure
_ http://code.google.com/p/processing/issues/detail?id=55
_ sketches should only write to the console of their editor window
@@ -1047,6 +1047,7 @@ _ indents and loops
_ or make the area light up gray as it's being worked on
_ Replace current editor with more advanced version
_ http://code.google.com/p/processing/issues/detail?id=1032
_ code coloring is imperfect because it's not based on a parser
_ better text editor / live debugging (integrate Eclipse JDT)
_ line numbers
_ it's too difficult for students to debug their code