Commit 3b1d3658 authored by Alexander Dietsch's avatar Alexander Dietsch

New:

-Added working parser for LW-grammar (possibly needs some testing)
-Added syntax highlighting (also possibly needs some testing)
-Added first version of working text editor

General:
-disabled running program
-added temporary button to check for correct syntax
parent 4df67d8e
using System;
using System.Drawing;
using System.Drawing.Printing;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Item of autocomplete menu
/// </summary>
public class AutocompleteItem
{
public string Text;
public int ImageIndex = -1;
public object Tag;
string toolTipTitle;
string toolTipText;
string menuText;
public AutocompleteMenu Parent { get; internal set; }
public AutocompleteItem()
{
}
public AutocompleteItem(string text)
{
Text = text;
}
public AutocompleteItem(string text, int imageIndex)
: this(text)
{
this.ImageIndex = imageIndex;
}
public AutocompleteItem(string text, int imageIndex, string menuText)
: this(text, imageIndex)
{
this.menuText = menuText;
}
public AutocompleteItem(string text, int imageIndex, string menuText, string toolTipTitle, string toolTipText)
: this(text, imageIndex, menuText)
{
this.toolTipTitle = toolTipTitle;
this.toolTipText = toolTipText;
}
/// <summary>
/// Returns text for inserting into Textbox
/// </summary>
public virtual string GetTextForReplace()
{
return Text;
}
/// <summary>
/// Compares fragment text with this item
/// </summary>
public virtual CompareResult Compare(string fragmentText)
{
if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase) &&
Text != fragmentText)
return CompareResult.VisibleAndSelected;
return CompareResult.Hidden;
}
/// <summary>
/// Returns text for display into popup menu
/// </summary>
public override string ToString()
{
return menuText ?? Text;
}
/// <summary>
/// This method is called after item inserted into text
/// </summary>
public virtual void OnSelected(AutocompleteMenu popupMenu, SelectedEventArgs e)
{
;
}
/// <summary>
/// Title for tooltip.
/// </summary>
/// <remarks>Return null for disable tooltip for this item</remarks>
public virtual string ToolTipTitle
{
get { return toolTipTitle; }
set { toolTipTitle = value; }
}
/// <summary>
/// Tooltip text.
/// </summary>
/// <remarks>For display tooltip text, ToolTipTitle must be not null</remarks>
public virtual string ToolTipText
{
get{ return toolTipText; }
set { toolTipText = value; }
}
/// <summary>
/// Menu text. This text is displayed in the drop-down menu.
/// </summary>
public virtual string MenuText
{
get { return menuText; }
set { menuText = value; }
}
/// <summary>
/// Fore color of text of item
/// </summary>
public virtual Color ForeColor
{
get { return Color.Transparent; }
set { throw new NotImplementedException("Override this property to change color"); }
}
/// <summary>
/// Back color of item
/// </summary>
public virtual Color BackColor
{
get { return Color.Transparent; }
set { throw new NotImplementedException("Override this property to change color"); }
}
}
public enum CompareResult
{
/// <summary>
/// Item do not appears
/// </summary>
Hidden,
/// <summary>
/// Item appears
/// </summary>
Visible,
/// <summary>
/// Item appears and will selected
/// </summary>
VisibleAndSelected
}
/// <summary>
/// Autocomplete item for code snippets
/// </summary>
/// <remarks>Snippet can contain special char ^ for caret position.</remarks>
public class SnippetAutocompleteItem : AutocompleteItem
{
public SnippetAutocompleteItem(string snippet)
{
Text = snippet.Replace("\r", "");
ToolTipTitle = "Code snippet:";
ToolTipText = Text;
}
public override string ToString()
{
return MenuText ?? Text.Replace("\n", " ").Replace("^", "");
}
public override string GetTextForReplace()
{
return Text;
}
public override void OnSelected(AutocompleteMenu popupMenu, SelectedEventArgs e)
{
e.Tb.BeginUpdate();
e.Tb.Selection.BeginUpdate();
//remember places
var p1 = popupMenu.Fragment.Start;
var p2 = e.Tb.Selection.Start;
//do auto indent
if (e.Tb.AutoIndent)
{
for (int iLine = p1.iLine + 1; iLine <= p2.iLine; iLine++)
{
e.Tb.Selection.Start = new Place(0, iLine);
e.Tb.DoAutoIndent(iLine);
}
}
e.Tb.Selection.Start = p1;
//move caret position right and find char ^
while (e.Tb.Selection.CharBeforeStart != '^')
if (!e.Tb.Selection.GoRightThroughFolded())
break;
//remove char ^
e.Tb.Selection.GoLeft(true);
e.Tb.InsertText("");
//
e.Tb.Selection.EndUpdate();
e.Tb.EndUpdate();
}
/// <summary>
/// Compares fragment text with this item
/// </summary>
public override CompareResult Compare(string fragmentText)
{
if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase) &&
Text != fragmentText)
return CompareResult.Visible;
return CompareResult.Hidden;
}
}
/// <summary>
/// This autocomplete item appears after dot
/// </summary>
public class MethodAutocompleteItem : AutocompleteItem
{
string firstPart;
string lowercaseText;
public MethodAutocompleteItem(string text)
: base(text)
{
lowercaseText = Text.ToLower();
}
public override CompareResult Compare(string fragmentText)
{
int i = fragmentText.LastIndexOf('.');
if (i < 0)
return CompareResult.Hidden;
string lastPart = fragmentText.Substring(i + 1);
firstPart = fragmentText.Substring(0, i);
if(lastPart=="") return CompareResult.Visible;
if(Text.StartsWith(lastPart, StringComparison.InvariantCultureIgnoreCase))
return CompareResult.VisibleAndSelected;
if(lowercaseText.Contains(lastPart.ToLower()))
return CompareResult.Visible;
return CompareResult.Hidden;
}
public override string GetTextForReplace()
{
return firstPart + "." + Text;
}
}
/// <summary>
/// This Item does not check correspondence to current text fragment.
/// SuggestItem is intended for dynamic menus.
/// </summary>
public class SuggestItem : AutocompleteItem
{
public SuggestItem(string text, int imageIndex):base(text, imageIndex)
{
}
public override CompareResult Compare(string fragmentText)
{
return CompareResult.Visible;
}
}
}
This diff is collapsed.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Base class for bookmark collection
/// </summary>
public abstract class BaseBookmarks : ICollection<Bookmark>, IDisposable
{
#region ICollection
public abstract void Add(Bookmark item);
public abstract void Clear();
public abstract bool Contains(Bookmark item);
public abstract void CopyTo(Bookmark[] array, int arrayIndex);
public abstract int Count { get; }
public abstract bool IsReadOnly { get; }
public abstract bool Remove(Bookmark item);
public abstract IEnumerator<Bookmark> GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region IDisposable
public abstract void Dispose();
#endregion
#region Additional properties
public abstract void Add(int lineIndex, string bookmarkName);
public abstract void Add(int lineIndex);
public abstract bool Contains(int lineIndex);
public abstract bool Remove(int lineIndex);
public abstract Bookmark GetBookmark(int i);
#endregion
}
/// <summary>
/// Collection of bookmarks
/// </summary>
public class Bookmarks : BaseBookmarks
{
protected FastColoredTextBox tb;
protected List<Bookmark> items = new List<Bookmark>();
protected int counter;
public Bookmarks(FastColoredTextBox tb)
{
this.tb = tb;
tb.LineInserted += tb_LineInserted;
tb.LineRemoved += tb_LineRemoved;
}
protected virtual void tb_LineRemoved(object sender, LineRemovedEventArgs e)
{
for(int i=0; i<Count; i++)
if (items[i].LineIndex >= e.Index)
{
if (items[i].LineIndex >= e.Index + e.Count)
{
items[i].LineIndex = items[i].LineIndex - e.Count;
continue;
}
var was = e.Index <= 0;
foreach (var b in items)
if (b.LineIndex == e.Index - 1)
was = true;
if(was)
{
items.RemoveAt(i);
i--;
}else
items[i].LineIndex = e.Index - 1;
//if (items[i].LineIndex == e.Index + e.Count - 1)
//{
// items[i].LineIndex = items[i].LineIndex - e.Count;
// continue;
//}
//
//items.RemoveAt(i);
//i--;
}
}
protected virtual void tb_LineInserted(object sender, LineInsertedEventArgs e)
{
for (int i = 0; i < Count; i++)
if (items[i].LineIndex >= e.Index)
{
items[i].LineIndex = items[i].LineIndex + e.Count;
}else
if (items[i].LineIndex == e.Index - 1 && e.Count == 1)
{
if(tb[e.Index - 1].StartSpacesCount == tb[e.Index - 1].Count)
items[i].LineIndex = items[i].LineIndex + e.Count;
}
}
public override void Dispose()
{
tb.LineInserted -= tb_LineInserted;
tb.LineRemoved -= tb_LineRemoved;
}
public override IEnumerator<Bookmark> GetEnumerator()
{
foreach (var item in items)
yield return item;
}
public override void Add(int lineIndex, string bookmarkName)
{
Add(new Bookmark(tb, bookmarkName ?? "Bookmark " + counter, lineIndex));
}
public override void Add(int lineIndex)
{
Add(new Bookmark(tb, "Bookmark " + counter, lineIndex));
}
public override void Clear()
{
items.Clear();
counter = 0;
}
public override void Add(Bookmark bookmark)
{
foreach (var bm in items)
if (bm.LineIndex == bookmark.LineIndex)
return;
items.Add(bookmark);
counter++;
tb.Invalidate();
}
public override bool Contains(Bookmark item)
{
return items.Contains(item);
}
public override bool Contains(int lineIndex)
{
foreach (var item in items)
if (item.LineIndex == lineIndex)
return true;
return false;
}
public override void CopyTo(Bookmark[] array, int arrayIndex)
{
items.CopyTo(array, arrayIndex);
}
public override int Count
{
get { return items.Count; }
}
public override bool IsReadOnly
{
get { return false; }
}
public override bool Remove(Bookmark item)
{
tb.Invalidate();
return items.Remove(item);
}
/// <summary>
/// Removes bookmark by line index
/// </summary>
public override bool Remove(int lineIndex)
{
bool was = false;
for (int i = 0; i < Count; i++)
if (items[i].LineIndex == lineIndex)
{
items.RemoveAt(i);
i--;
was = true;
}
tb.Invalidate();
return was;
}
/// <summary>
/// Returns Bookmark by index.
/// </summary>
public override Bookmark GetBookmark(int i)
{
return items[i];
}
}
/// <summary>
/// Bookmark of FastColoredTextbox
/// </summary>
public class Bookmark
{
public FastColoredTextBox TB { get; private set; }
/// <summary>
/// Name of bookmark
/// </summary>
public string Name { get; set; }
/// <summary>
/// Line index
/// </summary>
public int LineIndex {get; set; }
/// <summary>
/// Color of bookmark sign
/// </summary>
public Color Color { get; set; }
/// <summary>
/// Scroll textbox to the bookmark
/// </summary>
public virtual void DoVisible()
{
TB.Selection.Start = new Place(0, LineIndex);
TB.DoRangeVisible(TB.Selection, true);
TB.Invalidate();
}
public Bookmark(FastColoredTextBox tb, string name, int lineIndex)
{
this.TB = tb;
this.Name = name;
this.LineIndex = lineIndex;
Color = tb.BookmarkColor;
}
public virtual void Paint(Graphics gr, Rectangle lineRect)
{
var size = TB.CharHeight - 1;
using (var brush = new LinearGradientBrush(new Rectangle(0, lineRect.Top, size, size), Color.White, Color, 45))
gr.FillEllipse(brush, 0, lineRect.Top, size, size);
using (var pen = new Pen(Color))
gr.DrawEllipse(pen, 0, lineRect.Top, size, size);
}
}
}
using System;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Char and style
/// </summary>
public struct Char
{
/// <summary>
/// Unicode character
/// </summary>
public char c;
/// <summary>
/// Style bit mask
/// </summary>
/// <remarks>Bit 1 in position n means that this char will rendering by FastColoredTextBox.Styles[n]</remarks>
public StyleIndex style;
public Char(char c)
{
this.c = c;
style = StyleIndex.None;
}
}
}
using System.Collections.Generic;
using System;
namespace FastColoredTextBoxNS
{
public class CommandManager
{
readonly int maxHistoryLength = 200;
LimitedStack<UndoableCommand> history;
Stack<UndoableCommand> redoStack = new Stack<UndoableCommand>();
public TextSource TextSource{ get; private set; }
public bool UndoRedoStackIsEnabled { get; set; }
public CommandManager(TextSource ts)
{
history = new LimitedStack<UndoableCommand>(maxHistoryLength);
TextSource = ts;
UndoRedoStackIsEnabled = true;
}
public virtual void ExecuteCommand(Command cmd)
{
if (disabledCommands > 0)
return;
//multirange ?
if (cmd.ts.CurrentTB.Selection.ColumnSelectionMode)
if (cmd is UndoableCommand)
//make wrapper
cmd = new MultiRangeCommand((UndoableCommand)cmd);
if (cmd is UndoableCommand)
{
//if range is ColumnRange, then create wrapper
(cmd as UndoableCommand).autoUndo = autoUndoCommands > 0;
history.Push(cmd as UndoableCommand);
}
try
{
cmd.Execute();
}
catch (ArgumentOutOfRangeException)
{
//OnTextChanging cancels enter of the text
if (cmd is UndoableCommand)
history.Pop();
}
//
if (!UndoRedoStackIsEnabled)
ClearHistory();
//
redoStack.Clear();
//
TextSource.CurrentTB.OnUndoRedoStateChanged();
}
public void Undo()
{
if (history.Count > 0)