syntax highlight support, continue

This commit is contained in:
Vadim Lopatin 2015-01-19 21:11:04 +03:00
parent 2d1c6601e3
commit 3d87406f78
1 changed files with 57 additions and 7 deletions

View File

@ -391,8 +391,6 @@ class EditOperation {
} }
} }
alias TokenPropString = ubyte[];
/// Undo/Redo buffer /// Undo/Redo buffer
class UndoBuffer { class UndoBuffer {
protected Collection!EditOperation _undoList; protected Collection!EditOperation _undoList;
@ -449,6 +447,14 @@ interface EditableContentListener {
void onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source); void onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source);
} }
alias TokenPropString = ubyte[];
/// interface for custom syntax highlight
interface SyntaxHighlighter {
/// categorize characters in content by token types
void updateHighlight(dstring[] lines, TokenPropString[] props, int changeStartLine, int changeEndLine);
}
/// editable plain text (singleline/multiline) /// editable plain text (singleline/multiline)
class EditableContent { class EditableContent {
@ -460,6 +466,22 @@ class EditableContent {
protected UndoBuffer _undoBuffer; protected UndoBuffer _undoBuffer;
protected SyntaxHighlighter _syntaxHighlighter;
@property SyntaxHighlighter syntaxHighlighter() {
return _syntaxHighlighter;
}
@property EditableContent syntaxHighlighter(SyntaxHighlighter syntaxHighlighter) {
_syntaxHighlighter = syntaxHighlighter;
updateTokenProps(0, _lines.length);
}
/// returns true if content has syntax highlight handler set
@property bool hasSyntaxHighlight() {
return _syntaxHighlighter !is null;
}
protected bool _readOnly; protected bool _readOnly;
@property bool readOnly() { @property bool readOnly() {
@ -501,19 +523,28 @@ class EditableContent {
TextRange rangeBefore; TextRange rangeBefore;
TextRange rangeAfter; TextRange rangeAfter;
handleContentChange(new EditOperation(EditAction.ReplaceContent), rangeBefore, rangeAfter, this); handleContentChange(new EditOperation(EditAction.ReplaceContent), rangeBefore, rangeAfter, this);
// update highlight if necessary
updateTokenProps(0, _lines.length);
} }
protected void updateTokenProps(int startLine, int endLine) { protected void updateTokenProps(int startLine, int endLine) {
clearTokenProps(startLine, endLine); clearTokenProps(startLine, endLine);
if (_syntaxHighlighter) {
_syntaxHighlighter.updateHighlight(_lines, _tokenProps, startLine, endLine);
}
} }
/// set props arrays size equal to text line sizes, bit fill with unknown token /// set props arrays size equal to text line sizes, bit fill with unknown token
protected void clearTokenProps(int startLine, int endLine) { protected void clearTokenProps(int startLine, int endLine) {
for (int i = startLine; i < endLine; i++) { for (int i = startLine; i < endLine; i++) {
if (hasSyntaxHighlight) {
int len = cast(int)_lines[i].length; int len = cast(int)_lines[i].length;
_tokenProps[i].length = len; _tokenProps[i].length = len;
for (int j = 0; j < len; j++) for (int j = 0; j < len; j++)
_tokenProps[i][j] = TOKEN_UNKNOWN; _tokenProps[i][j] = TOKEN_UNKNOWN;
} else {
_tokenProps[i] = null; // no token props
}
} }
} }
@ -948,6 +979,7 @@ class EditableContent {
if (s is null) if (s is null)
break; break;
int pos = cast(int)(_lines.length++); int pos = cast(int)(_lines.length++);
_tokenProps.length = _lines.length;
_lines[pos] = s.dup; _lines[pos] = s.dup;
clearTokenProps(pos, pos + 1); clearTokenProps(pos, pos + 1);
} }
@ -2740,14 +2772,32 @@ class EditBox : EditWidgetBase {
protected CustomCharProps[ubyte] _tokenHighlightColors; protected CustomCharProps[ubyte] _tokenHighlightColors;
void setTokenHightlightColor(ubyte tokenCategory, uint color, bool underline, bool strikeThrough) { void setTokenHightlightColor(ubyte tokenCategory, uint color, bool underline, bool strikeThrough) {
_tokenHighlightColors[tokenCategory] = CustomCharProps(color, underline, strikeThrough); _tokenHighlightColors[tokenCategory] = CustomCharProps(color, underline, strikeThrough);
} }
void clearTokenHightlightColors() {
destroy(_tokenHighlightColors);
}
/// custom text color and style highlight (using text highlight) support /**
Custom text color and style highlight (using text highlight) support.
Return null if no syntax highlight required for line.
*/
protected CustomCharProps[] handleCustomLineHighlight(int line, dstring txt) { protected CustomCharProps[] handleCustomLineHighlight(int line, dstring txt) {
if (!_tokenHighlightColors)
return null; // no highlight colors set
TokenPropString tokenProps = _content.lineTokenProps(line); TokenPropString tokenProps = _content.lineTokenProps(line);
if (tokenProps.length > 0) { if (tokenProps.length > 0) {
bool hasNonzeroTokens = false;
foreach(t; tokenProps)
if (t) {
hasNonzeroTokens = true;
break;
}
if (!hasNonzeroTokens)
return null; // all characters are of unknown token type (or white space)
CustomCharProps[] colors = new CustomCharProps[tokenProps.length]; CustomCharProps[] colors = new CustomCharProps[tokenProps.length];
for (int i = 0; i < tokenProps.length; i++) { for (int i = 0; i < tokenProps.length; i++) {
ubyte p = tokenProps[i]; ubyte p = tokenProps[i];