From ac4fa6a570f9f97c96e9cef6c9ae3ec307bd4943 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sat, 2 Sep 2017 07:23:20 +0200 Subject: [PATCH] trigger file loading through filePath instead of full Text source, comments --- src/CodeBuffer.cs | 43 +++++++++++++++++++++++------- src/CrowEdit.cs | 17 ++++-------- src/Parser.cs | 65 +++++++++++++++++++++++++++++++++++++++++---- src/SourceEditor.cs | 40 +++++++++++++++++----------- src/XMLParser.cs | 19 ------------- ui/main.crow | 2 +- 6 files changed, 124 insertions(+), 62 deletions(-) diff --git a/src/CodeBuffer.cs b/src/CodeBuffer.cs index 3c82d12..5eb4316 100644 --- a/src/CodeBuffer.cs +++ b/src/CodeBuffer.cs @@ -25,8 +25,13 @@ using System.Text.RegularExpressions; namespace Crow.Coding { + /// + /// Code buffer, lines are arranged in a List, new line chars are removed during string.split on '\n...', + /// public class CodeBuffer { + //those events are handled in SourceEditor to help keeping sync between textbuffer and parser. + //modified lines are marked for reparse #region Events public event EventHandler LineUpadateEvent; public event EventHandler LineRemoveEvent; @@ -158,36 +163,45 @@ namespace Crow.Coding /// /// convert buffer postition to visual position /// - Point getVisualPos (Point buffPos) { + Point getTabulatedPos (Point buffPos) { int vCol = this[buffPos.Y].Substring(0, buffPos.X).Replace("\t", new String(' ', Interface.TabSize)).Length; return new Point (vCol, buffPos.Y); } /// /// Gets visual position computed from actual buffer position /// - public Point VisualPosition { - get { return getVisualPos (new Point (_currentCol, _currentLine)); } + public Point TabulatedPosition { + get { return getTabulatedPos (new Point (_currentCol, _currentLine)); } } /// /// set buffer current position from visual position /// - public void SetBufferPos(Point visualPosition) { - CurrentPosition = getBuffPos(visualPosition); + public void SetBufferPos(Point tabulatedPosition) { + CurrentPosition = getBuffPos(tabulatedPosition); } #region Editing and moving cursor Point selectionStart = -1; Point selectionEnd = -1; - public void SetSelection (Point visualStart, Point visualEnd) { - selectionStart = getBuffPos (visualStart); - selectionEnd = getBuffPos (visualEnd); + /// + /// Set selection in buffer coords from tabulated coords + /// + public void SetSelection (Point tabulatedStart, Point tabulatedEnd) { + selectionStart = getBuffPos (tabulatedStart); + selectionEnd = getBuffPos (tabulatedEnd); } + /// + /// Set selection in buffer to -1, empty selection + /// public void ResetSelection () { selectionStart = selectionEnd = -1; } bool selectionIsEmpty { get { return selectionStart == selectionEnd; } } + /// + /// Current column in buffer coordinate, tabulation = 1 char + /// public int CurrentColumn{ get { return _currentCol; } set { @@ -201,6 +215,9 @@ namespace Crow.Coding _currentCol = value; } } + /// + /// Current row in buffer coordinate, tabulation = 1 char + /// public int CurrentLine{ get { return _currentLine; } set { @@ -218,6 +235,9 @@ namespace Crow.Coding CurrentColumn = cc; } } + /// + /// Current position in buffer coordinate, tabulation = 1 char + /// public Point CurrentPosition { get { return new Point(CurrentColumn, CurrentLine); } set { @@ -225,10 +245,13 @@ namespace Crow.Coding _currentLine = value.Y; } } + /// + /// get char at current position in buffer + /// protected Char CurrentChar { get { return lines [CurrentLine] [CurrentColumn]; } } /// - /// Moves cursor one char to the left. + /// Moves cursor one char to the left, move up if cursor reaches start of line /// /// true if move succeed public bool MoveLeft(){ @@ -243,7 +266,7 @@ namespace Crow.Coding return true; } /// - /// Moves cursor one char to the right. + /// Moves cursor one char to the right, move down if cursor reaches end of line /// /// true if move succeed public bool MoveRight(){ diff --git a/src/CrowEdit.cs b/src/CrowEdit.cs index d23541b..32b1d0e 100644 --- a/src/CrowEdit.cs +++ b/src/CrowEdit.cs @@ -138,18 +138,11 @@ namespace CrowEdit CurFilePath = fd.SelectedFile; CurrentDir = fd.SelectedDirectory; - using (StreamReader sr = new StreamReader (CurFileFullPath)) { - _origText = sr.ReadToEnd (); - } - _text = _origText; - - NotifyValueChanged ("Text", _text); - NotifyValueChanged ("IsDirty", false); - redoStack.Clear (); - undoStack.Clear (); - CMDRedo.CanExecute = false; - CMDUndo.CanExecute = false; - +// redoStack.Clear (); +// undoStack.Clear (); +// CMDRedo.CanExecute = false; +// CMDUndo.CanExecute = false; +// NotifyValueChanged ("CurFileFullPath", CurFileFullPath); } void saveFileDialog_OkClicked (object sender, EventArgs e) diff --git a/src/Parser.cs b/src/Parser.cs index 90caa30..f3f2206 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -6,8 +6,15 @@ using System.Diagnostics; namespace Crow.Coding { + /// + /// base class for tokenizing sources + /// public abstract class Parser { + /// + /// Default tokens, this enum may be overriden in derived parser with the new keyword, + /// see XMLParser for example. + /// public enum TokenType { Unknown, WhiteSpace, @@ -60,32 +67,64 @@ namespace Crow.Coding } #region low level parsing + /// + /// Read one char from current position in buffer and store it into the current token + /// + /// if true, set the Start position of the current token to the current position protected void readToCurrTok(bool startOfTok = false){ if (startOfTok) currentTok.Start = CurrentPosition; currentTok += Read(); } + /// + /// read n char from the buffer and store it into the current token + /// protected void readToCurrTok(int length) { for (int i = 0; i < length; i++) currentTok += Read (); } + /// + /// Save current token into current TokensLine and raz current token + /// + protected void saveAndResetCurrentTok() { + currentTok.End = CurrentPosition; + TokensLine.Add (currentTok); + currentTok = default(Token); + } + /// + /// read one char and add current token to current TokensLine, current token is reset + /// + /// Type of the token + /// set start of token to current position protected void readAndResetCurrentTok(System.Enum type, bool startToc = false) { readToCurrTok (); saveAndResetCurrentTok (type); } - protected void saveAndResetCurrentTok() { this.saveAndResetCurrentTok (currentTok.Type); } + /// + /// Save current tok + /// + /// set the type of the tok protected void saveAndResetCurrentTok(System.Enum type) { currentTok.Type = (TokenType)type; - currentTok.End = CurrentPosition; - TokensLine.Add (currentTok); - currentTok = default(Token); + saveAndResetCurrentTok (); } + /// + /// Peek next char, emit '\n' if current column > buffer's line length + /// Throw error if eof is true + /// protected virtual char Peek() { if (eof) throw new ParsingException (this, "Unexpected End of File"); return currentColumn < buffer [currentLine].Length ? buffer [currentLine] [currentColumn] : '\n'; } + /// + /// Peek n char from buffer or less if remaining char in buffer's line is less than requested + /// if end of line is reached, no '\n' will be emitted, instead, empty string is returned. '\n' should be checked only + /// with single char Peek(). + /// Throw error is eof is true + /// + /// Length. protected virtual string Peek(int length) { if (eof) throw new ParsingException (this, "Unexpected End of File"); @@ -94,9 +133,13 @@ namespace Crow.Coding return ""; return buffer [currentLine].Substring (currentColumn, lg); } + /// + /// read one char from buffer at current position, if '\n' is read, current line is incremented + /// and column is reset to 0 + /// protected virtual char Read() { char c = Peek (); - + //TODO: the parsing is done line by line, we should be able to remove the next line handling from read if (c == '\n') { currentLine++; if (currentLine >= buffer.Length) @@ -106,6 +149,10 @@ namespace Crow.Coding currentColumn++; return c; } + /// + /// read until end of line is reached + /// + /// string read protected virtual string ReadLine () { string tmp = ""; while (!eof) { @@ -115,6 +162,11 @@ namespace Crow.Coding } return tmp; } + /// + /// read until end expression is reached or end of line. + /// + /// string read minus the ending expression that has to be read after + /// Expression to search for protected virtual string ReadLineUntil (string endExp){ string tmp = ""; @@ -129,6 +181,9 @@ namespace Crow.Coding } return tmp; } + /// + /// skip white spaces, but not line break. Save spaces in a WhiteSpace token. + /// protected void SkipWhiteSpaces () { if (currentTok.Type != TokenType.Unknown) throw new ParsingException (this, "current token should be reset to unknown (0) before skiping white spaces"); diff --git a/src/SourceEditor.cs b/src/SourceEditor.cs index 1f6ae63..1cd7e1e 100644 --- a/src/SourceEditor.cs +++ b/src/SourceEditor.cs @@ -35,6 +35,7 @@ using System.Text.RegularExpressions; using System.Linq; using System.Diagnostics; using CrowEdit; +using System.IO; namespace Crow.Coding { @@ -78,6 +79,8 @@ namespace Crow.Coding } #region private and protected fields + string filePath = "unamed.txt"; + int leftMargin = 0; //margin used to display line numbers, folding errors,etc... int visibleLines = 1; int visibleColumns = 1; CodeBuffer buffer; @@ -111,6 +114,7 @@ namespace Crow.Coding } RegisterForGraphicUpdate (); } + #region Buffer events handlers void Buffer_BufferCleared (object sender, EventArgs e) { @@ -145,23 +149,31 @@ namespace Crow.Coding #endregion #region Public Crow Properties - [XmlAttributeAttribute][DefaultValue("label")] - public string Text + [XmlAttributeAttribute] + public string FilePath { get { return buffer == null ? "" : buffer.FullText; } set { - if (string.Equals (value, buffer?.FullText, StringComparison.Ordinal)) + if (filePath == value) + return; + + filePath = value; + NotifyValueChanged ("FilePath", filePath); + + if (!File.Exists (filePath)) return; - buffer.Load (value); + using (StreamReader sr = new StreamReader (filePath)) { + string txt = sr.ReadToEnd (); + buffer.Load (txt); + } MaxScrollY = Math.Max (0, buffer.Length - visibleLines); MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns); - OnTextChanged (this, null); RegisterForGraphicUpdate (); } } @@ -332,7 +344,7 @@ namespace Crow.Coding /// true if move succeed public bool MoveLeft(){ bool res = buffer.MoveLeft(); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; return res; } /// @@ -341,23 +353,23 @@ namespace Crow.Coding /// true if move succeed public bool MoveRight(){ bool res = buffer.MoveRight(); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; return res; } public void GotoWordStart(){ buffer.GotoWordStart(); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; } public void GotoWordEnd(){ buffer.GotoWordEnd(); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; } public void DeleteChar() { if (!selectionIsEmpty) buffer.SetSelection (selectionStart, selectionEnd); buffer.DeleteChar (); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; SelBegin = -1; SelRelease = -1; OnTextChanged (this, null); @@ -372,7 +384,7 @@ namespace Crow.Coding DeleteChar (); buffer.Insert (str); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; OnTextChanged (this, null); RegisterForGraphicUpdate(); @@ -383,7 +395,7 @@ namespace Crow.Coding protected void InsertLineBreak() { buffer.InsertLineBreak (); - CurrentPosition = buffer.VisualPosition; + CurrentPosition = buffer.TabulatedPosition; OnTextChanged (this, null); } #endregion @@ -625,7 +637,7 @@ namespace Crow.Coding else CurrentLine = ScrollY + (int)Math.Floor (mouseLocalPos.Y / fe.Height); - CurrentPosition = buffer.VisualPosition; //for rounding if in middle of tabs + CurrentPosition = buffer.TabulatedPosition; //for rounding if in middle of tabs } public override void onMouseEnter (object sender, MouseMoveEventArgs e) { @@ -731,8 +743,6 @@ namespace Crow.Coding this.InsertLineBreak (); break; case Key.Escape: - Text = ""; - CurrentColumn = 0; SelRelease = -1; break; case Key.Home: diff --git a/src/XMLParser.cs b/src/XMLParser.cs index 36a96e7..7383618 100644 --- a/src/XMLParser.cs +++ b/src/XMLParser.cs @@ -77,25 +77,6 @@ namespace Crow.Coding { get { return rxNameChar.IsMatch(new string(new char[]{Peek()})); } } -// public bool NameIsValid(string name) -// { -// if (!rxNameStartChar.IsMatch(char.ConvertFromUtf32(((string)name)[0]))) -// return false; -// -// return rxNameChar.IsMatch(name); -// } -// private bool NextCharIsValidPubidChar -// { -// get { return rxPubidChar.IsMatch(char.ConvertFromUtf32(Peek())); } -// } -// private bool AttributeValueIsValid(string name) -// { -// return string.IsNullOrEmpty(name) ? true : rxAttributeValue.IsMatch(name); -// } -// private bool NextCharIsValidEntityValue -// { -// get { return rxEntityValue.IsMatch(char.ConvertFromUtf32(Peek())); } -// } #endregion public override void SetLineInError (ParsingException ex) diff --git a/ui/main.crow b/ui/main.crow index 8e81eb2..f01a611 100755 --- a/ui/main.crow +++ b/ui/main.crow @@ -24,7 +24,7 @@ + FilePath="{CurFileFullPath}" KeyDown="textView_KeyDown"/> -- 2.47.3