The next step is to customize ScintillaNET for R syntax highlighting, auto complete and so on. While earlier version of ScintillaNET does not have R Lexer, the current version downloaded (3.3.0) contains a very easy way for R syntax highlighting and auto-complete. Below is the Source codes (Assuming I put the code in a winform named FrmDummy, and my Scintilla editor component I put in the form is named "txtScript"):
public partial class FrmDummy : Form
{
private List<string> Keywords1 = null;
private List<string> Keywords2 = null;
private string AutoCompleteKeywords = null;
public FrmDummy()
{
InitializeComponent();
PrepareKeywords();
ConfigureRScriptSyntaxHighlight();
ConfigureRScriptAutoFolding();
ConifugreRScriptAutoComplete();
txtScript.Text=@"#Some dummy R codes
print('Hello World')
x <- c('Hello World', 'Hello World2')";
}
private void PrepareKeywords()
{
Keywords1 = @"commandArgs detach length dev.off stop lm library predict lmer
plot print display anova read.table read.csv complete.cases dim attach as.numeric seq max
min data.frame lines curve as.integer levels nlevels ceiling sqrt ranef order
AIC summary str head png tryCatch par mfrow interaction.plot qqnorm qqline".Split(new char[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).ToList();
Keywords2 = @"TRUE FALSE if else for while in break continue function".Split(new char[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).ToList();
List<string> keywords = Keywords1.ToList();
keywords.AddRange(Keywords2);
keywords.Sort();
AutoCompleteKeywords = string.Join(" ", keywords);
}
private void ConfigureRScriptSyntaxHighlight()
{
txtScript.StyleResetDefault();
txtScript.Styles[Style.Default].Font = "Consolas";
txtScript.Styles[Style.Default].Size = 10;
txtScript.StyleClearAll();
txtScript.Styles[Style.R.Default].ForeColor = Color.Brown;
txtScript.Styles[Style.R.Comment].ForeColor = Color.FromArgb(0, 128, 0); // Green
txtScript.Styles[Style.R.Number].ForeColor = Color.Olive;
txtScript.Styles[Style.R.BaseKWord].ForeColor = Color.Purple;
txtScript.Styles[Style.R.Identifier].ForeColor = Color.Black;
txtScript.Styles[Style.R.String].ForeColor = Color.FromArgb(163, 21, 21); // Red
txtScript.Styles[Style.R.KWord].ForeColor = Color.Blue;
txtScript.Styles[Style.R.OtherKWord].ForeColor = Color.Blue;
txtScript.Styles[Style.R.String2].ForeColor = Color.OrangeRed;
txtScript.Styles[Style.R.Operator].ForeColor = Color.Purple;
txtScript.Lexer = Lexer.R;
txtScript.SetKeywords(0, string.Join(" ", Keywords1));
txtScript.SetKeywords(1, string.Join(" ", Keywords2));
}
private void ConifugreRScriptAutoComplete()
{
txtScript.CharAdded += scintilla_CharAdded;
}
private void scintilla_CharAdded(object sender, CharAddedEventArgs e)
{
Scintilla scintilla = txtScript;
// Find the word start
var currentPos = scintilla.CurrentPosition;
var wordStartPos = scintilla.WordStartPosition(currentPos, true);
// Display the autocompletion list
var lenEntered = currentPos - wordStartPos;
if (lenEntered > 0)
{
scintilla.AutoCShow(lenEntered, AutoCompleteKeywords);
}
}
private void ConfigureRScriptAutoFolding()
{
Scintilla scintilla = txtScript;
// Instruct the lexer to calculate folding
scintilla.SetProperty("fold", "1");
scintilla.SetProperty("fold.compact", "1");
// Configure a margin to display folding symbols
scintilla.Margins[2].Type = MarginType.Symbol;
scintilla.Margins[2].Mask = Marker.MaskFolders;
scintilla.Margins[2].Sensitive = true;
scintilla.Margins[2].Width = 20;
// Set colors for all folding markers
for (int i = 25; i <= 31; i++)
{
scintilla.Markers[i].SetForeColor(SystemColors.ControlLightLight);
scintilla.Markers[i].SetBackColor(SystemColors.ControlDark);
}
// Configure folding markers with respective symbols
scintilla.Markers[Marker.Folder].Symbol = MarkerSymbol.BoxPlus;
scintilla.Markers[Marker.FolderOpen].Symbol = MarkerSymbol.BoxMinus;
scintilla.Markers[Marker.FolderEnd].Symbol = MarkerSymbol.BoxPlusConnected;
scintilla.Markers[Marker.FolderMidTail].Symbol = MarkerSymbol.TCorner;
scintilla.Markers[Marker.FolderOpenMid].Symbol = MarkerSymbol.BoxMinusConnected;
scintilla.Markers[Marker.FolderSub].Symbol = MarkerSymbol.VLine;
scintilla.Markers[Marker.FolderTail].Symbol = MarkerSymbol.LCorner;
// Enable automatic folding
scintilla.AutomaticFold = (AutomaticFold.Show | AutomaticFold.Click | AutomaticFold.Change);
}
}
To display the line number, one can set txtScript.Margins[0].Width=30
No comments:
Post a Comment