diff --git a/app/src/processing/app/syntax/KeywordMap.java b/app/src/processing/app/syntax/KeywordMap.java index 21e3a5fed..31a63768d 100644 --- a/app/src/processing/app/syntax/KeywordMap.java +++ b/app/src/processing/app/syntax/KeywordMap.java @@ -22,119 +22,116 @@ import javax.swing.text.Segment; * @author Slava Pestov, Mike Dillon * @version $Id$ */ -public class KeywordMap -{ - /** - * Creates a new KeywordMap. - * @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 KeywordMap. - * @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 KeywordMap. + * @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 KeywordMap. + * @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; + } + } } diff --git a/app/src/processing/app/syntax/PdeKeywords.java b/app/src/processing/app/syntax/PdeKeywords.java index 2f7ce32cc..e8a62907b 100644 --- a/app/src/processing/app/syntax/PdeKeywords.java +++ b/app/src/processing/app/syntax/PdeKeywords.java @@ -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; } diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index a59467017..92bcf43f4 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -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: diff --git a/todo.txt b/todo.txt index 74d8d3184..29f7a3f51 100644 --- a/todo.txt +++ b/todo.txt @@ -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