Closed Bug 605059 Opened 15 years ago Closed 7 years ago

Proposed patch to add syntax hilight in debugger

Categories

(Rhino Graveyard :: Core, enhancement)

head
x86
Windows XP
enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED INACTIVE

People

(Reporter: joel.hockey, Unassigned)

Details

Attachments

(1 file)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.13) Gecko/20100914 Firefox/3.5.13 (.NET CLR 3.5.30729) Build Identifier: 1.7R2 I have modified the org.mozilla.javascript.tools.debugger.SwingGui.java code a little to provide syntax hilighting by using a JTextPane rather than JTextArea and to show source code. I do some simple parsing to detect keywords, comments and string literals. Ideally, if the TokenStream.isKeyword method could be made visible (add a wrapper in ScriptRuntime?), the keyword detection code could use it rather than the list of strings in a HashSet implementation that I have done. Reproducible: Always Steps to Reproduce: n/a diff of latest org.mozilla.javascript.tools.SwingGui.java from CVS HEAD 70a71 > import java.util.HashSet; 80a82 > import java.util.Set; 496,497c498,499 < int start = w.getPosition(lineNumber-1); < int end = w.getPosition(lineNumber)-1; --- > int start = w.getLineStartOffset(lineNumber-1); > int end = w.getLineStartOffset(lineNumber)-1; 529,537c531 < try { < w.setPosition(w.textArea.getLineStartOffset(line-1)); < } catch (BadLocationException exc) { < try { < w.setPosition(w.textArea.getLineStartOffset(0)); < } catch (BadLocationException ee) { < w.setPosition(-1); < } < } --- > w.setPosition(w.getLineStartOffset(line-1)); 581,594c575,583 < JTextArea ta = w.textArea; < try { < if (line == -1) { < w.setPosition(-1); < if (currentWindow == w) { < currentWindow = null; < } < } else { < int loc = ta.getLineStartOffset(line-1); < if (currentWindow != null && currentWindow != w) { < currentWindow.setPosition(-1); < } < w.setPosition(loc); < currentWindow = w; --- > if (line == -1) { > w.setPosition(-1); > if (currentWindow == w) { > currentWindow = null; > } > } else { > int loc = w.getLineStartOffset(line-1); > if (currentWindow != null && currentWindow != w) { > currentWindow.setPosition(-1); 596,597c585,586 < } catch (BadLocationException exc) { < // fix me --- > w.setPosition(loc); > currentWindow = w; 1425c1414 < extends JTextArea --- > extends JTextPane 1461c1450 < int line = getLineOfOffset(pos); --- > int line = w.getLineOfOffset(pos); 1468c1457 < modelToView(getLineStartOffset(line + 1)); --- > modelToView(w.getLineStartOffset(line + 1)); 1570c1559 < line = getLineOfOffset(pos); --- > line = w.getLineOfOffset(pos); 1960c1949 < int lineCount = textArea.getLineCount() + 1; --- > int lineCount = fileWindow.getLineCount() + 1; 1987c1976 < int lineCount = textArea.getLineCount() + 1; --- > int lineCount = fileWindow.getLineCount() + 1; 1999,2002c1988 < try { < pos = textArea.getLineStartOffset(i); < } catch (BadLocationException ignored) { < } --- > pos = fileWindow.getLineStartOffset(i); 2046c2032 < --- > 2092a2079,2152 > private static Set<String> KEYWORDS = new HashSet<String>(Arrays.asList( > new String[] { > "abstract", > "boolean", > "break", > "byte", > "case", > "catch", > "char", > "class", > "const", > "continue", > "debugger", > "default", > "delete", > "do", > "double", > "else", > "enum", > "export", > "extends", > "false", > "final", > "finally", > "float", > "for", > "function", > "goto", > "if", > "implements", > "import", > "in", > "instanceof", > "int", > "interface", > "long", > "native", > "new", > "null", > "package", > "private", > "protected", > "public", > "return", > "short", > "static", > "super", > "switch", > "synchronized", > "this", > "throw", > "throws", > "transient", > "true", > "try", > "typeof", > "var", > "void", > "volatile", > "while", > "with" > })); > private static final SimpleAttributeSet KEYWORD = new SimpleAttributeSet(); > private static final SimpleAttributeSet JAVADOC = new SimpleAttributeSet(); > private static final SimpleAttributeSet COMMENT = new SimpleAttributeSet(); > private static final SimpleAttributeSet QUOTED = new SimpleAttributeSet(); > > static { > // use same color scheme as eclipse > StyleConstants.setForeground(KEYWORD, new Color(127, 0, 85)); > StyleConstants.setForeground(JAVADOC, new Color(63, 95, 191)); > StyleConstants.setForeground(COMMENT, new Color(63, 127, 125)); > StyleConstants.setForeground(QUOTED, new Color(42, 0, 255)); > } 2118c2178 < --- > 2129a2190,2199 > * Offsets for start of each line in {@link #textArea}. > */ > private int[] lineStartOffsets = new int[16]; > > /** > * Number of lines. > */ > private int lineCount = 0; > > /** 2145,2149c2215,2219 < public int getPosition(int line) { < int result = -1; < try { < result = textArea.getLineStartOffset(line); < } catch (javax.swing.text.BadLocationException exc) { --- > public int getLineStartOffset(int line) { > if (line >= 0 && line < lineStartOffsets.length) { > return lineStartOffsets[line]; > } else { > return -1; 2151c2221,2228 < return result; --- > } > public int getLineCount() { > return lineStartOffsets.length; > } > public int getLineOfOffset(int offset) { > int i = 0; > while (i < lineStartOffsets.length && offset < lineStartOffsets[i++]); > return i + 1; 2207,2208d2283 < textArea.setRows(24); < textArea.setColumns(80); 2257a2333,2355 > > // re-calculate lineOffsets (must normalize linesep) > lineCount = 1; > int offset = 0; > for (int i = 0; i < newText.length(); i++) { > char c = newText.charAt(i); > // treat CRLF as single char > if (c == '\n' && i > 1 && newText.charAt(i - 1) == '\r') { > continue; > } > offset++; > if (c == '\r' || c == '\n') { > // resize if needed > if (lineCount == lineStartOffsets.length) { > int[] tmp = new int[lineStartOffsets.length * 2]; > System.arraycopy(lineStartOffsets, 0, > tmp, 0, lineStartOffsets.length); > lineStartOffsets = tmp; > } > lineStartOffsets[lineCount++] = offset; > } > } > hilight(); 2261a2360,2419 > > /** > * Apply syntax higlight to @link {@link #textArea} > */ > private void hilight() { > StyledDocument doc = textArea.getStyledDocument(); > String text = ""; > try { > text = doc.getText(0, doc.getLength()); > } catch (BadLocationException e) {} > // parse JS and set colours > int pos = 0; > while (pos < text.length()) { > char c = text.charAt(pos); > SimpleAttributeSet style; > int start = pos; > if (Character.isJavaIdentifierStart(c)) { > // read rest of identifier > while (++pos < text.length() > && Character.isJavaIdentifierPart(text.charAt(pos))); > String word = text.substring(start, pos); > if (!KEYWORDS.contains(word)) { > continue; > } > style = KEYWORD; > > // block comment (or javadoc) > } else if (text.regionMatches(pos, "/*", 0, 2)) { > style = COMMENT; > if (pos < text.length() - 3 && text.charAt(pos + 2) == '*' > && text.charAt(pos + 3) != '/') { > style = JAVADOC; // '/**' but not '/**/' > } > // move to end of '*/' or end of string if comment not closed > pos = text.indexOf("*/", pos); > pos = pos == -1 ? text.length() : pos + 2; > > // line comment > } else if (text.regionMatches(pos, "//", 0, 2)) { > style = COMMENT; > // move to end of line or end of doc > while (++pos < text.length() && text.charAt(pos) != '\r' > && text.charAt(pos) != '\n'); > } else if (c == '\"' || c == '\'') { > style = QUOTED; > int q = c; // match either single or double quote > pos++; // skip first quote > while (pos < text.length() && (c = text.charAt(pos++)) != q) { > if (c == '\\') pos++; // skip any escaped quotes > } > } else { > pos++; > continue; > } > > // apply style > doc.setCharacterAttributes(start, pos - start, style, false); > } > } >
Version: other → head
I have made some small changes / fixes to this. Please email me (joel.hockey@gmail.com) to get latest version
Joel, do you have this in an OSS repo somewhere? I would very much like to use this feature.

Closing. Bug management is now done here:
https://github.com/mozilla/rhino

Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
Resolution: --- → INACTIVE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: