📄 defaulthighlightingstrategy.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Kr黦er" email="mike@icsharpcode.net"/>
// <version value="$version"/>
// </file>
using System;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public class DefaultHighlightingStrategy : IHighlightingStrategy
{
string name;
ArrayList rules = new ArrayList();
Hashtable environmentColors = new Hashtable();
Hashtable properties = new Hashtable();
string[] extensions;
HighlightColor digitColor;
HighlightRuleSet defaultRuleSet = null;
public HighlightColor DigitColor {
get {
return digitColor;
}
set {
digitColor = value;
}
}
public DefaultHighlightingStrategy() : this("Default")
{
}
public DefaultHighlightingStrategy(string name)
{
this.name = name;
digitColor = new HighlightBackground("WindowText", "Window", false, false);
// set small 'default color environment'
environmentColors["DefaultBackground"]= new HighlightBackground("WindowText", "Window", false, false);
environmentColors["Default"] = new HighlightColor(System.Drawing.SystemColors.WindowText, false, false);
environmentColors["Selection"] = new HighlightColor("HighlightText", "Highlight", false, false);
environmentColors["VRuler"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["InvalidLines"] = new HighlightColor(Color.Red, false, false);
environmentColors["CaretMarker"] = new HighlightColor(Color.Yellow, false, false);
environmentColors["LineNumbers"] = new HighlightBackground("ControlDark", "Window", false, false);
environmentColors["FoldLine"] = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.Black, false, false);
environmentColors["FoldMarker"] = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.White, false, false);
environmentColors["SelectedFoldLine"] = new HighlightColor(Color.Black, false, false);
environmentColors["EOLMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["SpaceMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["TabMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
}
public Hashtable Properties {
get {
return properties;
}
}
public string Name
{
get {
return name;
}
}
public string[] Extensions
{
set {
extensions = value;
}
get {
return extensions;
}
}
public ArrayList Rules
{
get {
return rules;
}
}
public HighlightRuleSet FindHighlightRuleSet(string name)
{
foreach(HighlightRuleSet ruleSet in rules) {
if (ruleSet.Name == name) {
return ruleSet;
}
}
return null;
}
public void AddRuleSet(HighlightRuleSet aRuleSet)
{
rules.Add(aRuleSet);
}
internal void ResolveReferences()
{
// Resolve references from Span definitions to RuleSets
ResolveRuleSetReferences();
// Resolve references from RuleSet defintitions to Highlighters defined in an external mode file
ResolveExternalReferences();
}
void ResolveRuleSetReferences()
{
foreach (HighlightRuleSet ruleSet in Rules) {
if (ruleSet.Name == null) {
defaultRuleSet = ruleSet;
}
foreach (Span aSpan in ruleSet.Spans) {
if (aSpan.Rule != null) {
bool found = false;
foreach (HighlightRuleSet refSet in Rules) {
if (refSet.Name == aSpan.Rule) {
found = true;
aSpan.RuleSet = refSet;
break;
}
}
if (!found) {
MessageBox.Show("The RuleSet " + aSpan.Rule + " could not be found in mode definition " + this.Name, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
aSpan.RuleSet = null;
}
} else {
aSpan.RuleSet = null;
}
}
}
if (defaultRuleSet == null) {
MessageBox.Show("No default RuleSet is defined for mode definition " + this.Name, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
}
}
void ResolveExternalReferences()
{
foreach (HighlightRuleSet ruleSet in Rules) {
if (ruleSet.Reference != null) {
IHighlightingStrategy highlighter = HighlightingManager.Manager.FindHighlighter (ruleSet.Reference);
if (highlighter != null) {
ruleSet.Highlighter = highlighter;
} else {
MessageBox.Show("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition could not be found", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
ruleSet.Highlighter = this;
}
} else {
ruleSet.Highlighter = this;
}
}
}
// internal void SetDefaultColor(HighlightBackground color)
// {
// return (HighlightColor)environmentColors[name];
// defaultColor = color;
// }
internal void SetColorFor(string name, HighlightColor color)
{
environmentColors[name] = color;
}
public HighlightColor GetColorFor(string name)
{
if (environmentColors[name] == null) {
throw new Exception("Color : " + name + " not found!");
}
return (HighlightColor)environmentColors[name];
}
public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
{
return GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength);
}
HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
{
if (ruleSet != null) {
if (ruleSet.Reference != null) {
return ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength);
} else {
return (HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength];
}
}
return null;
}
public HighlightRuleSet GetRuleSet(Span aSpan)
{
if (aSpan == null) {
return this.defaultRuleSet;
} else {
if (aSpan.RuleSet != null)
{
if (aSpan.RuleSet.Reference != null) {
return aSpan.RuleSet.Highlighter.GetRuleSet(null);
} else {
return aSpan.RuleSet;
}
} else {
return null;
}
}
}
// Line state variable
LineSegment currentLine;
// Span stack state variable
Stack currentSpanStack;
public void MarkTokens(IDocument document)
{
try
{
if (Rules.Count == 0) {
return;
}
int lineNumber = 0;
while (lineNumber < document.TotalNumberOfLines) {
LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
if (lineNumber >= document.LineSegmentCollection.Count) { // may be, if the last line ends with a delimiter
break; // then the last line is not in the collection :)
}
currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? ((Stack)(previousLine.HighlightSpanStack.Clone())) : null);
if (currentSpanStack != null) {
while (currentSpanStack.Count > 0 && ((Span)currentSpanStack.Peek()).StopEOL)
{
currentSpanStack.Pop();
}
if (currentSpanStack.Count == 0) currentSpanStack = null;
}
currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
if (currentLine.Length == -1) { // happens when buffer is empty !
return;
}
ArrayList words = ParseLine(document);
//// Alex: clear old words
if (currentLine.Words!=null) currentLine.Words.Clear();
currentLine.Words = words;
currentLine.HighlightSpanStack = (currentSpanStack==null || currentSpanStack.Count==0) ? null : currentSpanStack;
++lineNumber;
}
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
document.CommitUpdate();
}
finally
{
currentLine = null;
}
}
bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged)
{
bool processNextLine = false;
LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? ((Stack)(previousLine.HighlightSpanStack.Clone())) : null);
if (currentSpanStack != null) {
while (currentSpanStack.Count > 0 && ((Span)currentSpanStack.Peek()).StopEOL) {
currentSpanStack.Pop();
}
if (currentSpanStack.Count == 0) {
currentSpanStack = null;
}
}
currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
if (currentLine.Length == -1) { // happens when buffer is empty !
return false;
}
ArrayList words = ParseLine(document);
if (currentSpanStack != null && currentSpanStack.Count == 0) {
currentSpanStack = null;
}
// Check if the span state has changed, if so we must re-render the next line
// This check may seem utterly complicated but I didn't want to introduce any function calls
// or alllocations here for perf reasons.
if(currentLine.HighlightSpanStack != currentSpanStack) {
if (currentLine.HighlightSpanStack == null) {
processNextLine = false;
foreach (Span sp in currentSpanStack) {
if (!sp.StopEOL) {
spanChanged = true;
processNextLine = true;
break;
}
}
} else if (currentSpanStack == null) {
processNextLine = false;
foreach (Span sp in currentLine.HighlightSpanStack) {
if (!sp.StopEOL) {
spanChanged = true;
processNextLine = true;
break;
}
}
} else {
IEnumerator e1 = currentSpanStack.GetEnumerator();
IEnumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
bool done = false;
while (!done) {
bool blockSpanIn1 = false;
while (e1.MoveNext()) {
if (!((Span)e1.Current).StopEOL) {
blockSpanIn1 = true;
break;
}
}
bool blockSpanIn2 = false;
while (e2.MoveNext()) {
if (!((Span)e2.Current).StopEOL) {
blockSpanIn2 = true;
break;
}
}
if (blockSpanIn1 || blockSpanIn2) {
if (blockSpanIn1 && blockSpanIn2) {
if (e1.Current != e2.Current) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -