From: Jean-Philippe Bruyère Date: Sat, 4 Nov 2017 12:06:16 +0000 (+0100) Subject: * CrowEdit.csproj: ok X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=2a57843f38d279c23cc690b675db1cdeef18836c;p=jp%2Fcrowedit.git * CrowEdit.csproj: ok * packages.config: update to crow 0.5.6 * main.crow: * Parser.cs: * TokenList.cs: * CodeBuffer.cs: * SourceEditor.cs: wip --- diff --git a/CrowEdit.csproj b/CrowEdit.csproj index 01825e2..0cad08b 100644 --- a/CrowEdit.csproj +++ b/CrowEdit.csproj @@ -55,26 +55,20 @@ - - packages\OpenTK.2.0.0\lib\net20\OpenTK.dll - + + packages\OpenTK.2.0.0\lib\net20\OpenTK.dll + - packages\Crow.OpenTK.0.5.5\lib\net45\Crow.dll + packages\Crow.OpenTK.0.5.6\lib\net45\Crow.dll - - - - - - @@ -85,6 +79,12 @@ + + + + + + diff --git a/packages.config b/packages.config index c3ffa7c..9e8d256 100644 --- a/packages.config +++ b/packages.config @@ -1,5 +1,5 @@  - + - + \ No newline at end of file diff --git a/src/CodeBuffer.cs b/src/CodeBuffer.cs index c063c18..424aa4a 100644 --- a/src/CodeBuffer.cs +++ b/src/CodeBuffer.cs @@ -172,17 +172,13 @@ namespace Crow.Coding return new Point (buffCol, visualPos.Y); } /// - /// convert buffer postition to visual position - /// - 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 TabulatedPosition { - get { return getTabulatedPos (new Point (_currentCol, _currentLine)); } + get { return new Point (TabulatedColumn, _currentLine); } + } + public int TabulatedColumn { + get { return this [_currentLine].Substring (0, _currentCol).Replace ("\t", new String (' ', Interface.TabSize)).Length; } } /// /// set buffer current position from visual position diff --git a/src/Parser.cs b/src/Parser.cs index 942454f..dcb2c62 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -43,7 +43,7 @@ namespace Crow.Coding buffer = _buffer; buffer.LineUpadateEvent += Buffer_LineUpadateEvent; - buffer.LineAdditionEvent += Buffer_LineAdditionEvent;; + //buffer.LineAdditionEvent += Buffer_LineAdditionEvent;; buffer.LineRemoveEvent += Buffer_LineRemoveEvent; buffer.BufferCleared += Buffer_BufferCleared; @@ -61,12 +61,7 @@ namespace Crow.Coding } void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e) { - for (int i = 0; i < e.LineCount; i++) { - int lptr = e.LineStart + i; - Tokens.Insert (lptr, new TokenList ()); - tryParseBufferLine (e.LineStart + i); - } - reparseSource (); + } void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e) { @@ -121,25 +116,28 @@ namespace Crow.Coding // } // } } - void reparseSource () { + public void reparseSource () { for (int i = 0; i < Tokens.Count; i++) { if (Tokens[i].Dirty) tryParseBufferLine (i); } try { SyntaxAnalysis (); - } catch (ParsingException ex) { + } catch (Exception ex) { Debug.WriteLine ("Syntax Error: " + ex.ToString ()); - SetLineInError (ex); + if (ex is ParsingException) + SetLineInError (ex as ParsingException); } } - void tryParseBufferLine(int lPtr) { + public void tryParseBufferLine(int lPtr) { try { Parse (lPtr); - } catch (ParsingException ex) { + } catch (Exception ex) { Debug.WriteLine (ex.ToString ()); - SetLineInError (ex); + if (ex is ParsingException) + SetLineInError (ex as ParsingException); } + } CodeBuffer buffer; @@ -161,13 +159,35 @@ namespace Crow.Coding currentColumn = value.X; } } + public int LineCount { + get { return Tokens.Count; } + } + /// + /// unfolded and not in folds line count + /// + public int VisibleLines { + get { + int i = 0, vl = 0; + while (i + /// Updates visible line in widget, adapt max scroll y and updatePrintedLines + /// void updateVisibleLines(){ visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / fe.Height); - MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines); - + updateMaxScrollY (); + updatePrintedLines (); System.Diagnostics.Debug.WriteLine ("update visible lines: " + visibleLines); System.Diagnostics.Debug.WriteLine ("update MaxScrollY: " + MaxScrollY); } @@ -125,6 +128,57 @@ namespace Crow.Coding System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin); System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX); } + void updateMaxScrollY () { + if (parser == null || !foldingEnabled) + MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines); + else + MaxScrollY = Math.Max (0, parser.VisibleLines - visibleLines); + } + + int firstPrintedLine = -1; + /// + /// list of lines visible in the Editor depending on scrolling and folding + /// + List PrintedLines; + + void updatePrintedLines () { + if (parser == null) + return; + PrintedLines = new List (); + int curL = 0; + int i = 0; + + while (curL < parser.LineCount && i < ScrollY) { + if (parser.Tokens [curL].folded && parser.Tokens [curL].SyntacticNode != null) + curL = parser.Tokens [curL].SyntacticNode.EndLine; + curL++; + i++; + } + + firstPrintedLine = curL; + i = 0; + while (i < visibleLines && curL < parser.LineCount) { + PrintedLines.Add (parser.Tokens [curL]); + + if (parser.Tokens [curL].folded && parser.Tokens [curL].SyntacticNode != null) + curL = parser.Tokens [curL].SyntacticNode.EndLine; + + curL++; + i++; + } + RegisterForGraphicUpdate (); + } + void toogleFolding (int line) { + if (parser == null || !foldingEnabled) + return; + if (parser.Tokens [line].SyntacticNode == null) + return; + parser.Tokens [line].folded = !parser.Tokens [line].folded; + updatePrintedLines (); + updateMaxScrollY (); + + RegisterForGraphicUpdate (); + } #region Buffer events handlers void Buffer_BufferCleared (object sender, EventArgs e) @@ -145,8 +199,20 @@ namespace Crow.Coding buffer.longestLineCharCount = charCount; }else if (lptr <= buffer.longestLineIdx) buffer.longestLineIdx++; + if (parser == null) + continue; + parser.Tokens.Insert (lptr, new TokenList ()); + parser.tryParseBufferLine (e.LineStart + i); } measureLeftMargin (); + + if (parser != null) + parser.reparseSource (); + + + updatePrintedLines (); + updateOnScreenPosFromBuffPos (); + RegisterForGraphicUpdate (); } @@ -161,6 +227,7 @@ namespace Crow.Coding if (trigFindLongestLine) findLongestLineAndUpdateMaxScrollX (); measureLeftMargin (); + updatePrintedLines (); RegisterForGraphicUpdate (); } @@ -227,13 +294,18 @@ namespace Crow.Coding parser = getParserFromExt (System.IO.Path.GetExtension (filePath)); - using (StreamReader sr = new StreamReader (filePath)) { - string txt = sr.ReadToEnd (); - buffer.Load (txt); + try { + using (StreamReader sr = new StreamReader (filePath)) { + string txt = sr.ReadToEnd (); + buffer.Load (txt); + } + } catch (Exception ex) { + Debug.WriteLine (ex.ToString ()); } - MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines); + updateMaxScrollY (); MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns); + updatePrintedLines (); RegisterForGraphicUpdate (); } @@ -295,19 +367,17 @@ namespace Crow.Coding _currentLine = 0; else _currentLine = value; - //force recheck of currentCol for bounding - int cc = _currentCol; - _currentCol = 0; - CurrentColumn = cc; - buffer.SetBufferPos (CurrentPosition); - - //System.Diagnostics.Debug.WriteLine ("Scroll:{0} visibleLines:{1} CurLine:{2}", ScrollY, visibleLines, CurrentLine); + if (_currentCol > buffer.GetPrintableLine(_currentLine).Length) + CurrentColumn = buffer.GetPrintableLine(_currentLine).Length;//buffer.setBufferPos is called inside + else + buffer.SetBufferPos (CurrentPosition); - if (_currentLine < ScrollY) - ScrollY = _currentLine; - else if (_currentLine >= ScrollY + visibleLines) - ScrollY = _currentLine - visibleLines + 1; +// if (_currentLine < ScrollY) +// ScrollY = _currentLine; +// else if (_currentLine >= ScrollY + visibleLines) +// ScrollY = _currentLine - visibleLines + 1; + NotifyValueChanged ("CurrentLine", _currentLine); } } @@ -326,11 +396,11 @@ namespace Crow.Coding ScrollX = _currentCol; else if (_currentCol >= ScrollX + visibleColumns) ScrollX = _currentCol - visibleColumns + 1; - - if (_currentLine < ScrollY) - ScrollY = _currentLine; - else if (_currentLine >= ScrollY + visibleLines) - ScrollY = _currentLine - visibleLines + 1; +// +// if (_currentLine < ScrollY) +// ScrollY = _currentLine; +// else if (_currentLine >= ScrollY + visibleLines) +// ScrollY = _currentLine - visibleLines + 1; NotifyValueChanged ("CurrentColumn", _currentCol); NotifyValueChanged ("CurrentLine", _currentLine); @@ -370,15 +440,6 @@ namespace Crow.Coding } } /// - /// return char at CurrentLine, CurrentColumn - /// - [XmlIgnore]protected Char CurrentChar - { - get { - return buffer [CurrentLine] [CurrentColumn]; - } - } - /// /// ordered selection start and end positions in char units /// [XmlIgnore]protected Point selectionStart @@ -414,27 +475,45 @@ namespace Crow.Coding /// Moves cursor one char to the left. /// /// true if move succeed - public bool MoveLeft(){ - bool res = buffer.MoveLeft(); - CurrentPosition = buffer.TabulatedPosition; - return res; + public void MoveLeft(){ + if (CurrentPosition == 0) + return; + if (_currentCol == 0) { + PrintedCurrentLine--; + CurrentColumn = int.MaxValue; + } else { + //do move in the buffer so that tabulations are treated as single char + buffer.CurrentColumn --; + CurrentPosition = buffer.TabulatedPosition; + } } /// /// Moves cursor one char to the right. /// /// true if move succeed - public bool MoveRight(){ - bool res = buffer.MoveRight(); - CurrentPosition = buffer.TabulatedPosition; - return res; + public void MoveRight(){ + if (_currentCol == buffer.GetPrintableLine(CurrentLine).Length && _currentLine < buffer.LineCount - 1) { + PrintedCurrentLine++; + CurrentColumn = 0; + } else { + //do move in the buffer so that tabulations are treated as single char + buffer.CurrentColumn ++; + CurrentPosition = buffer.TabulatedPosition; + } + } + public void MoveUp (){ + PrintedCurrentLine--; + } + public void MoveDown (){ + PrintedCurrentLine++; } public void GotoWordStart(){ buffer.GotoWordStart(); - CurrentPosition = buffer.TabulatedPosition; + updateOnScreenPosFromBuffPos (); } public void GotoWordEnd(){ buffer.GotoWordEnd(); - CurrentPosition = buffer.TabulatedPosition; + updateOnScreenPosFromBuffPos (); } public void DeleteChar() @@ -442,7 +521,7 @@ namespace Crow.Coding if (!selectionIsEmpty) buffer.SetSelection (selectionStart, selectionEnd); buffer.DeleteChar (); - CurrentPosition = buffer.TabulatedPosition; + updateOnScreenPosFromBuffPos (); SelBegin = -1; SelRelease = -1; } @@ -460,21 +539,60 @@ namespace Crow.Coding RegisterForGraphicUpdate(); } - /// - /// Insert a line break. - /// - protected void InsertLineBreak() - { - buffer.InsertLineBreak (); + #endregion - if (_currentLine == buffer.longestLineIdx) - findLongestLineAndUpdateMaxScrollX (); + void updateOnScreenPosFromBuffPos(){ + if (parser.Tokens.Count == 0 || PrintedLines.Count == 0) + return; + if (!PrintedLines.Contains (parser.Tokens [buffer.CurrentLine])) + return; + printedCurrentLine = PrintedLines.IndexOf (parser.Tokens [buffer.CurrentLine]); + setCurrentLineFromBuffer (); + CurrentColumn = buffer.TabulatedColumn; + } - CurrentPosition = buffer.TabulatedPosition; + void setCurrentLineFromBuffer () { + _currentLine = buffer.CurrentLine; + NotifyValueChanged ("CurrentLine", _currentLine); + } - RegisterForGraphicUpdate(); + public override int ScrollY { + get { + return base.ScrollY; + } + set { + if (value == base.ScrollY) + return; + base.ScrollY = value; + updatePrintedLines (); + } } - #endregion + + + /// + /// Index of the currentline in the PrintedLines array + /// + int printedCurrentLine = 0; + + int PrintedCurrentLine { + get { return printedCurrentLine;} + set { + if (value < 0) { + ScrollY += value; + printedCurrentLine = 0; + } else if (PrintedLines.Count < visibleLines && value >= PrintedLines.Count) { + printedCurrentLine = PrintedLines.Count - 1; + }else if (value >= visibleLines) { + ScrollY += value - visibleLines + 1; + printedCurrentLine = visibleLines - 1; + }else + printedCurrentLine = value; + + //update position in buffer + CurrentLine = parser.Tokens.IndexOf (PrintedLines[printedCurrentLine]); + } + } + #region Drawing /// @@ -548,6 +666,9 @@ namespace Crow.Coding } } void drawParsed(Context gr){ + if (PrintedLines == null) + return; + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); gr.SetFontSize (Font.Size); gr.FontOptions = Interface.FontRenderingOptions; @@ -568,23 +689,21 @@ namespace Crow.Coding else if (HasFocus){ gr.LineWidth = 1.0; double cursorX = + leftMargin + cb.X + (CurrentColumn - ScrollX) * fe.MaxXAdvance; - gr.MoveTo (0.5 + cursorX, cb.Y + (CurrentLine - ScrollY) * fe.Height); - gr.LineTo (0.5 + cursorX, cb.Y + (CurrentLine + 1 - ScrollY) * fe.Height); + gr.MoveTo (0.5 + cursorX, cb.Y + printedCurrentLine * fe.Height); + gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * fe.Height); gr.Stroke(); } #endregion - for (int i = 0; i < visibleLines; i++) { - if (i + ScrollY >= parser.Tokens.Count) - break; + for (int i = 0; i < PrintedLines.Count; i++) drawTokenLine (gr, i, selectionInProgress, cb); - } gr.Restore (); } void drawTokenLine(Context gr, int i, bool selectionInProgress, Rectangle cb) { - int curL = i + ScrollY; - TokenList tokens = parser.Tokens[curL]; + TokenList tokens = PrintedLines[i]; + int lineIndex = parser.Tokens.IndexOf(tokens); + int lPtr = 0; double y = cb.Y + fe.Height * i; @@ -595,14 +714,14 @@ namespace Crow.Coding Rectangle mgR = new Rectangle (cb.X, (int)y, leftMargin - leftMarginGap, (int)Math.Ceiling(fe.Height)); if (tokens.exception != null) { mgBg = Color.Red; - if (CurrentLine == curL) + if (CurrentLine == lineIndex) mgFg = Color.White; else mgFg = Color.LightGray; - }else if (CurrentLine == curL) { + }else if (CurrentLine == lineIndex) { mgFg = Color.Black; } - string strLN = curL.ToString (); + string strLN = lineIndex.ToString (); gr.SetSourceColor (mgBg); gr.Rectangle (mgR); gr.Fill(); @@ -666,19 +785,19 @@ namespace Crow.Coding gr.ShowText (lstr); gr.Fill (); - if (selectionInProgress && curL >= selectionStart.Y && curL <= selectionEnd.Y && - !(curL == selectionStart.Y && lPtr + lstr.Length <= selectionStart.X) && - !(curL == selectionEnd.Y && selectionEnd.X <= lPtr)) { + if (selectionInProgress && lineIndex >= selectionStart.Y && lineIndex <= selectionEnd.Y && + !(lineIndex == selectionStart.Y && lPtr + lstr.Length <= selectionStart.X) && + !(lineIndex == selectionEnd.Y && selectionEnd.X <= lPtr)) { double rLineX = x, rLineY = cb.Y + i * fe.Height, rLineW = lstr.Length * fe.MaxXAdvance; double startAdjust = 0.0; - if ((curL == selectionStart.Y) && (selectionStart.X < lPtr + lstr.Length) && (selectionStart.X > lPtr)) + if ((lineIndex == selectionStart.Y) && (selectionStart.X < lPtr + lstr.Length) && (selectionStart.X > lPtr)) startAdjust = (selectionStart.X - lPtr) * fe.MaxXAdvance; rLineX += startAdjust; - if ((curL == selectionEnd.Y) && (selectionEnd.X < lPtr + lstr.Length)) + if ((lineIndex == selectionEnd.Y) && (selectionEnd.X < lPtr + lstr.Length)) rLineW = (selectionEnd.X - lPtr) * fe.MaxXAdvance; rLineW -= startAdjust; @@ -749,18 +868,18 @@ namespace Crow.Coding #endregion #region Mouse handling - void updatemouseLocalPos(Point mpos){ - Point mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft; + Point mouseLocalPos; + void updateCurrentPos(){ if (mouseLocalPos.X < 0) CurrentColumn--; else CurrentColumn = ScrollX + (int)Math.Round ((mouseLocalPos.X - leftMargin) / fe.MaxXAdvance); + PrintedCurrentLine = (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / fe.Height)); + if (mouseLocalPos.Y < 0) - CurrentLine--; - else - CurrentLine = ScrollY + (int)Math.Floor (mouseLocalPos.Y / fe.Height); + ScrollY--; CurrentPosition = buffer.TabulatedPosition; //for rounding if in middle of tabs } @@ -781,29 +900,29 @@ namespace Crow.Coding { base.onMouseMove (sender, e); - if (e.X - ScreenCoordinates(Slot).X < leftMargin + ClientRectangle.X) - currentInterface.MouseCursor = XCursor.Default; - else - currentInterface.MouseCursor = XCursor.Text; + mouseLocalPos = e.Position - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft; - if (!e.Mouse.IsButtonDown (MouseButton.Left)) + if (!e.Mouse.IsButtonDown (MouseButton.Left)) { + if (mouseLocalPos.X < leftMargin) + currentInterface.MouseCursor = XCursor.Default; + else + currentInterface.MouseCursor = XCursor.Text; return; + } + if (!HasFocus || SelBegin < 0) return; - updatemouseLocalPos (e.Position); + //mouse is down + updateCurrentPos (); SelRelease = CurrentPosition; RegisterForRedraw(); } public override void onMouseDown (object sender, MouseButtonEventArgs e) { - //initialize cursor position if not yet focused - if (!this.HasFocus & this.Focusable){ - updatemouseLocalPos (e.Position); - SelBegin = SelRelease = CurrentPosition; - RegisterForRedraw(); - } + if (!this.Focusable) + return; base.onMouseDown (sender, e); @@ -811,11 +930,11 @@ namespace Crow.Coding doubleClicked = false; return; } - if (this.HasFocus){ - updatemouseLocalPos (e.Position); - SelBegin = SelRelease = CurrentPosition; - RegisterForRedraw(); - } + + updateCurrentPos (); + SelBegin = SelRelease = CurrentPosition; + + RegisterForRedraw(); } public override void onMouseUp (object sender, MouseButtonEventArgs e) { @@ -825,7 +944,7 @@ namespace Crow.Coding if (SelBegin == SelRelease) SelBegin = SelRelease = -1; - updatemouseLocalPos (e.Position); + updateCurrentPos (); RegisterForRedraw (); } bool doubleClicked = false; @@ -861,8 +980,7 @@ namespace Crow.Coding break; case Key.Delete: if (selectionIsEmpty) { - if (!MoveRight ()) - return; + MoveRight (); }else if (e.Shift) currentInterface.Clipboard = this.SelectedText; this.DeleteChar (); @@ -871,7 +989,7 @@ namespace Crow.Coding case Key.KeypadEnter: if (!selectionIsEmpty) this.DeleteChar (); - this.InsertLineBreak (); + buffer.InsertLineBreak (); break; case Key.Escape: SelRelease = SelBegin = -1; @@ -918,8 +1036,8 @@ namespace Crow.Coding SelBegin = CurrentPosition; if (e.Control) GotoWordStart (); - else if (!MoveLeft ()) - return; + else + MoveLeft (); SelRelease = CurrentPosition; break; } @@ -935,8 +1053,8 @@ namespace Crow.Coding SelBegin = CurrentPosition; if (e.Control) GotoWordEnd (); - else if (!MoveRight ()) - return; + else + MoveRight (); SelRelease = CurrentPosition; break; } @@ -950,23 +1068,23 @@ namespace Crow.Coding if (e.Shift) { if (selectionIsEmpty) SelBegin = CurrentPosition; - CurrentLine--; + MoveUp (); SelRelease = CurrentPosition; break; } SelRelease = SelBegin = -1; - CurrentLine--; + MoveUp (); break; case Key.Down: if (e.Shift) { if (selectionIsEmpty) SelBegin = CurrentPosition; - CurrentLine++; + MoveDown (); SelRelease = CurrentPosition; break; } SelRelease = SelBegin = -1; - CurrentLine++; + MoveDown (); break; case Key.Menu: break; @@ -999,6 +1117,7 @@ namespace Crow.Coding this.Insert ("\t"); break; case Key.F8: + toogleFolding (CurrentLine); // if (parser != null) // reparseSource (); break; diff --git a/src/TokenList.cs b/src/TokenList.cs index 3160c09..f4d03c7 100644 --- a/src/TokenList.cs +++ b/src/TokenList.cs @@ -46,7 +46,6 @@ namespace Crow.Coding //override list.clear to clear additional states of tokenList public new void Clear() { EndingState = 0; - folded = false; SyntacticNode = null; exception = null; Dirty = true; diff --git a/ui/main.crow b/ui/main.crow index f01a611..04ecc85 100755 --- a/ui/main.crow +++ b/ui/main.crow @@ -22,8 +22,8 @@ -