mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 16:59:35 +01:00
Merge branch 'main' into toplevel-improvement
This commit is contained in:
@@ -1333,17 +1333,46 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
void ColorNormal ()
|
||||
/// <summary>
|
||||
/// Sets the driver to the default color for the control where no text is being rendered. Defaults to <see cref="ColorScheme.Normal"/>.
|
||||
/// </summary>
|
||||
protected virtual void ColorNormal ()
|
||||
{
|
||||
Driver.SetAttribute (ColorScheme.Normal);
|
||||
}
|
||||
|
||||
void ColorSelection ()
|
||||
/// <summary>
|
||||
/// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idx"/> of the
|
||||
/// current <paramref name="line"/>. Override to provide custom coloring by calling <see cref="ConsoleDriver.SetAttribute(Attribute)"/>
|
||||
/// Defaults to <see cref="ColorScheme.Normal"/>.
|
||||
/// </summary>
|
||||
/// <param name="line"></param>
|
||||
/// <param name="idx"></param>
|
||||
protected virtual void ColorNormal (List<Rune> line, int idx)
|
||||
{
|
||||
Driver.SetAttribute (ColorScheme.Normal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idx"/> of the
|
||||
/// current <paramref name="line"/>. Override to provide custom coloring by calling <see cref="ConsoleDriver.SetAttribute(Attribute)"/>
|
||||
/// Defaults to <see cref="ColorScheme.Focus"/>.
|
||||
/// </summary>
|
||||
/// <param name="line"></param>
|
||||
/// <param name="idx"></param>
|
||||
protected virtual void ColorSelection (List<Rune> line, int idx)
|
||||
{
|
||||
Driver.SetAttribute (ColorScheme.Focus);
|
||||
}
|
||||
|
||||
void ColorUsed ()
|
||||
/// <summary>
|
||||
/// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idx"/> of the
|
||||
/// current <paramref name="line"/>. Override to provide custom coloring by calling <see cref="ConsoleDriver.SetAttribute(Attribute)"/>
|
||||
/// Defaults to <see cref="ColorScheme.HotFocus"/>.
|
||||
/// </summary>
|
||||
/// <param name="line"></param>
|
||||
/// <param name="idx"></param>
|
||||
protected virtual void ColorUsed (List<Rune> line, int idx)
|
||||
{
|
||||
Driver.SetAttribute (ColorScheme.HotFocus);
|
||||
}
|
||||
@@ -1667,12 +1696,12 @@ namespace Terminal.Gui {
|
||||
var rune = idxCol >= lineRuneCount ? ' ' : line [idxCol];
|
||||
var cols = Rune.ColumnWidth (rune);
|
||||
if (idxCol < line.Count && selecting && PointInSelection (idxCol, idxRow)) {
|
||||
ColorSelection ();
|
||||
ColorSelection (line, idxCol);
|
||||
} else if (idxCol == currentColumn && idxRow == currentRow && !selecting && !Used
|
||||
&& HasFocus && idxCol < lineRuneCount) {
|
||||
ColorUsed ();
|
||||
ColorUsed (line, idxCol);
|
||||
} else {
|
||||
ColorNormal ();
|
||||
ColorNormal (line,idxCol);
|
||||
}
|
||||
|
||||
if (rune == '\t' && TabWidth > 0) {
|
||||
|
||||
180
UICatalog/Scenarios/SyntaxHighlighting.cs
Normal file
180
UICatalog/Scenarios/SyntaxHighlighting.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Terminal.Gui;
|
||||
using static UICatalog.Scenario;
|
||||
using Attribute = Terminal.Gui.Attribute;
|
||||
|
||||
namespace UICatalog.Scenarios {
|
||||
[ScenarioMetadata (Name: "Syntax Highlighting", Description: "Text editor with keyword highlighting")]
|
||||
[ScenarioCategory ("Controls")]
|
||||
class SyntaxHighlighting : Scenario {
|
||||
|
||||
public override void Setup ()
|
||||
{
|
||||
Win.Title = this.GetName ();
|
||||
Win.Y = 1; // menu
|
||||
Win.Height = Dim.Fill (1); // status bar
|
||||
Top.LayoutSubviews ();
|
||||
|
||||
var menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("_File", new MenuItem [] {
|
||||
new MenuItem ("_Quit", "", () => Quit()),
|
||||
})
|
||||
});
|
||||
Top.Add (menu);
|
||||
|
||||
var textView = new SqlTextView () {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (1),
|
||||
};
|
||||
|
||||
textView.Init();
|
||||
|
||||
textView.Text = "SELECT TOP 100 * \nfrom\n MyDb.dbo.Biochemistry;";
|
||||
|
||||
Win.Add (textView);
|
||||
|
||||
var statusBar = new StatusBar (new StatusItem [] {
|
||||
new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => Quit()),
|
||||
|
||||
});
|
||||
|
||||
|
||||
Top.Add (statusBar);
|
||||
}
|
||||
|
||||
|
||||
private void Quit ()
|
||||
{
|
||||
Application.RequestStop ();
|
||||
}
|
||||
|
||||
private class SqlTextView : TextView{
|
||||
|
||||
private HashSet<string> keywords = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
|
||||
private Attribute blue;
|
||||
private Attribute white;
|
||||
private Attribute magenta;
|
||||
|
||||
|
||||
public void Init()
|
||||
{
|
||||
keywords.Add("select");
|
||||
keywords.Add("distinct");
|
||||
keywords.Add("top");
|
||||
keywords.Add("from");
|
||||
keywords.Add ("create");
|
||||
keywords.Add ("primary");
|
||||
keywords.Add ("key");
|
||||
keywords.Add ("insert");
|
||||
keywords.Add ("alter");
|
||||
keywords.Add ("add");
|
||||
keywords.Add ("update");
|
||||
keywords.Add ("set");
|
||||
keywords.Add ("delete");
|
||||
keywords.Add ("truncate");
|
||||
keywords.Add ("as");
|
||||
keywords.Add ("order");
|
||||
keywords.Add ("by");
|
||||
keywords.Add ("asc");
|
||||
keywords.Add ("desc");
|
||||
keywords.Add ("between");
|
||||
keywords.Add ("where");
|
||||
keywords.Add ("and");
|
||||
keywords.Add ("or");
|
||||
keywords.Add ("not");
|
||||
keywords.Add ("limit");
|
||||
keywords.Add ("null");
|
||||
keywords.Add ("is");
|
||||
keywords.Add ("drop");
|
||||
keywords.Add ("database");
|
||||
keywords.Add ("column");
|
||||
keywords.Add ("table");
|
||||
keywords.Add ("having");
|
||||
keywords.Add ("in");
|
||||
keywords.Add ("join");
|
||||
keywords.Add ("on");
|
||||
keywords.Add ("union");
|
||||
keywords.Add ("exists");
|
||||
|
||||
magenta = Driver.MakeAttribute (Color.Magenta, Color.Black);
|
||||
blue = Driver.MakeAttribute (Color.Cyan, Color.Black);
|
||||
white = Driver.MakeAttribute (Color.White, Color.Black);
|
||||
}
|
||||
|
||||
protected override void ColorNormal ()
|
||||
{
|
||||
Driver.SetAttribute (white);
|
||||
}
|
||||
|
||||
protected override void ColorNormal (List<System.Rune> line, int idx)
|
||||
{
|
||||
if(IsInStringLiteral(line,idx)) {
|
||||
Driver.SetAttribute (magenta);
|
||||
}
|
||||
else
|
||||
if(IsKeyword(line,idx))
|
||||
{
|
||||
Driver.SetAttribute (blue);
|
||||
}
|
||||
else{
|
||||
Driver.SetAttribute (white);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInStringLiteral (List<System.Rune> line, int idx)
|
||||
{
|
||||
string strLine = new string (line.Select (r => (char)r).ToArray ());
|
||||
|
||||
foreach(Match m in Regex.Matches(strLine, "'[^']*'")) {
|
||||
if(idx >= m.Index && idx < m.Index+m.Length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsKeyword(List<System.Rune> line, int idx)
|
||||
{
|
||||
var word = IdxToWord(line,idx);
|
||||
|
||||
if(string.IsNullOrWhiteSpace(word)){
|
||||
return false;
|
||||
}
|
||||
|
||||
return keywords.Contains(word,StringComparer.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
private string IdxToWord(List<System.Rune> line, int idx)
|
||||
{
|
||||
var words = Regex.Split(
|
||||
new string(line.Select(r=>(char)r).ToArray()),
|
||||
"\\b");
|
||||
|
||||
|
||||
int count = 0;
|
||||
string current = null;
|
||||
|
||||
foreach(var word in words)
|
||||
{
|
||||
current = word;
|
||||
count+= word.Length;
|
||||
if(count > idx){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return current?.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user