diff --git a/README.md b/README.md index 5a5f718..04d2bfe 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ # Praktikum 1 -https://wiki.itcollege.ee/index.php/Praktikum:_XML_failide_loomine(VR2.1) \ No newline at end of file +https://wiki.itcollege.ee/index.php/Praktikum:_XML_failide_loomine(VR2.1) + +# Run + + dotnet restore + dotnet run diff --git a/vr21/Program.cs b/vr21/Program.cs index 7b0b8f2..c146af1 100644 --- a/vr21/Program.cs +++ b/vr21/Program.cs @@ -3,17 +3,19 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using System.Xml.Serialization; +using System.IO; +using System.Xml; namespace vr21 { - public class Receipe + public class Recipe { public string Name; public string Description; public List Ingredients; public List Steps; - public Receipe() + public Recipe() { Ingredients = new List(); Steps = new List(); @@ -23,31 +25,40 @@ namespace vr21 public class Ingredient { public string Name; - public int Count; + public int Amount; public string Unit; } class Program { - private static string _xmllocation = @"..\..\..\XMLRecipe.xml"; + // private static string _xmllocation = @"..\..\..\XMLRecipe.xml"; + private static string _xmllocation = @"XMLRecipe.xml"; + + public static List Recipes = new List(); static void Main(string[] args) { - Ingredient kartul = new Ingredient() {Name = "Kartul", Count = 500, Unit = "g"}; - Receipe r = new Receipe() {Name="Supp"}; + Ingredient kartul = new Ingredient() {Name = "Kartul", Amount = 500, Unit = "g"}; + Recipe r = new Recipe() {Name="Supp"}; r.Ingredients.Add(kartul); r.Ingredients.Add(kartul); r.Steps.Add("Koori"); r.Steps.Add("Keeda"); - List l = new List(); + var l = Recipes; l.Add(r); l.Add(r); - XmlSerializer x = new XmlSerializer(l.GetType()); - // x.Serialize(Console.Out, l); - //writeReceipesInformation(); + r = new Recipe() {Name="kala"}; + l.Add(r); + + XmlSerializer x = new XmlSerializer(l.GetType()); + using (var fs = new FileStream(_xmllocation, FileMode.Create)) { + x.Serialize(fs, l); + } + //writeReceipesInformation(); + readRecipesInformation(); + System.Environment.Exit(1); - LineEditor le = new LineEditor("foo") {HeuristicsMode = "csharp"}; string s; - while ((s = le.Edit("shell> ", "")) != null) + while ((s = Console.ReadLine()) != null) { var arguments = s.Split(' '); var command = arguments[0].Trim(); @@ -63,10 +74,22 @@ namespace vr21 } } + static void readRecipesInformation() { + var x = new XmlSerializer(typeof(List)); + FileStream fs = new FileStream(_xmllocation, FileMode.Open); + XmlReader reader = XmlReader.Create(fs); + var l = (List)x.Deserialize(reader); + foreach (var r in l) { + Console.WriteLine(r.Name); + } + + } + static void writeReceipesInformation() { XDocument xdoc = XDocument.Load(_xmllocation); var allReceipes = xdoc.Descendants("Recipe"); + Console.WriteLine(allReceipes.Count()); foreach (var receipe in allReceipes) { Console.WriteLine(receipe.Element("Name").Value); diff --git a/vr21/XMLRecipe.xml b/vr21/XMLRecipe.xml new file mode 100644 index 0000000..dc19571 --- /dev/null +++ b/vr21/XMLRecipe.xml @@ -0,0 +1,46 @@ + + + + Supp + + + Kartul + 500 + g + + + Kartul + 500 + g + + + + Koori + Keeda + + + + Supp + + + Kartul + 500 + g + + + Kartul + 500 + g + + + + Koori + Keeda + + + + kala + + + + \ No newline at end of file diff --git a/vr21/getline.cs b/vr21/getline.cs deleted file mode 100644 index 4a7f3b5..0000000 --- a/vr21/getline.cs +++ /dev/null @@ -1,1439 +0,0 @@ -// -// getline.cs: A command line editor -// -// Authors: -// Miguel de Icaza (miguel@novell.com) -// -// Copyright 2008 Novell, Inc. -// Copyright 2016 Xamarin Inc -// -// Completion wanted: -// -// * Enable bash-like completion window the window as an option for non-GUI people? -// -// * Continue completing when Backspace is used? -// -// * Should we keep the auto-complete on "."? -// -// * Completion produces an error if the value is not resolvable, we should hide those errors -// -// Dual-licensed under the terms of the MIT X11 license or the -// Apache License 2.0 -// -// USE -define:DEMO to build this as a standalone file and test it -// -// TODO: -// Enter an error (a = 1); Notice how the prompt is in the wrong line -// This is caused by Stderr not being tracked by System.Console. -// Completion support -// Why is Thread.Interrupt not working? Currently I resort to Abort which is too much. -// -// Limitations in System.Console: -// Console needs SIGWINCH support of some sort -// Console needs a way of updating its position after things have been written -// behind its back (P/Invoke puts for example). -// System.Console needs to get the DELETE character, and report accordingly. -// -// Bug: -// About 8 lines missing, type "Con" and not enough lines are inserted at the bottom. -// -// -using System; -using System.Text; -using System.IO; -using System.Threading; -using System.Reflection; - -namespace vr21 { - - public class LineEditor { - - public class Completion { - public string [] Result; - public string Prefix; - - public Completion (string prefix, string [] result) - { - Prefix = prefix; - Result = result; - } - } - - public delegate Completion AutoCompleteHandler (string text, int pos); - - // null does nothing, "csharp" uses some heuristics that make sense for C# - public string HeuristicsMode; - - //static StreamWriter log; - - // The text being edited. - StringBuilder text; - - // The text as it is rendered (replaces (char)1 with ^A on display for example). - StringBuilder rendered_text; - - // The prompt specified, and the prompt shown to the user. - string prompt; - string shown_prompt; - - // The current cursor position, indexes into "text", for an index - // into rendered_text, use TextToRenderPos - int cursor; - - // The row where we started displaying data. - int home_row; - - // The maximum length that has been displayed on the screen - int max_rendered; - - // If we are done editing, this breaks the interactive loop - bool done = false; - - // The thread where the Editing started taking place - Thread edit_thread; - - // Our object that tracks history - History history; - - // The contents of the kill buffer (cut/paste in Emacs parlance) - string kill_buffer = ""; - - // The string being searched for - string search; - string last_search; - - // whether we are searching (-1= reverse; 0 = no; 1 = forward) - int searching; - - // The position where we found the match. - int match_at; - - // Used to implement the Kill semantics (multiple Alt-Ds accumulate) - KeyHandler last_handler; - - // If we have a popup completion, this is not null and holds the state. - CompletionState current_completion; - - // If this is set, it contains an escape sequence to reset the Unix colors to the ones that were used on startup - static byte [] unix_reset_colors; - - // This contains a raw stream pointing to stdout, used to bypass the TermInfoDriver - static Stream unix_raw_output; - - delegate void KeyHandler (); - - struct Handler { - public ConsoleKeyInfo CKI; - public KeyHandler KeyHandler; - public bool ResetCompletion; - - public Handler (ConsoleKey key, KeyHandler h, bool resetCompletion = true) - { - CKI = new ConsoleKeyInfo ((char) 0, key, false, false, false); - KeyHandler = h; - ResetCompletion = resetCompletion; - } - - public Handler (char c, KeyHandler h, bool resetCompletion = true) - { - KeyHandler = h; - // Use the "Zoom" as a flag that we only have a character. - CKI = new ConsoleKeyInfo (c, ConsoleKey.Zoom, false, false, false); - ResetCompletion = resetCompletion; - } - - public Handler (ConsoleKeyInfo cki, KeyHandler h, bool resetCompletion = true) - { - CKI = cki; - KeyHandler = h; - ResetCompletion = resetCompletion; - } - - public static Handler Control (char c, KeyHandler h, bool resetCompletion = true) - { - return new Handler ((char) (c - 'A' + 1), h, resetCompletion); - } - - public static Handler Alt (char c, ConsoleKey k, KeyHandler h) - { - ConsoleKeyInfo cki = new ConsoleKeyInfo ((char) c, k, false, true, false); - return new Handler (cki, h); - } - } - - /// - /// Invoked when the user requests auto-completion using the tab character - /// - /// - /// The result is null for no values found, an array with a single - /// string, in that case the string should be the text to be inserted - /// for example if the word at pos is "T", the result for a completion - /// of "ToString" should be "oString", not "ToString". - /// - /// When there are multiple results, the result should be the full - /// text - /// - public AutoCompleteHandler AutoCompleteEvent; - - static Handler [] handlers; - - public LineEditor (string name) : this (name, 10) { } - - public LineEditor (string name, int histsize) - { - handlers = new Handler [] { - new Handler (ConsoleKey.Home, CmdHome), - new Handler (ConsoleKey.End, CmdEnd), - new Handler (ConsoleKey.LeftArrow, CmdLeft), - new Handler (ConsoleKey.RightArrow, CmdRight), - new Handler (ConsoleKey.UpArrow, CmdUp, resetCompletion: false), - new Handler (ConsoleKey.DownArrow, CmdDown, resetCompletion: false), - new Handler (ConsoleKey.Enter, CmdDone, resetCompletion: false), - new Handler (ConsoleKey.Backspace, CmdBackspace, resetCompletion: false), - new Handler (ConsoleKey.Delete, CmdDeleteChar), - new Handler (ConsoleKey.Tab, CmdTabOrComplete, resetCompletion: false), - - // Emacs keys - Handler.Control ('A', CmdHome), - Handler.Control ('E', CmdEnd), - Handler.Control ('B', CmdLeft), - Handler.Control ('F', CmdRight), - Handler.Control ('P', CmdUp, resetCompletion: false), - Handler.Control ('N', CmdDown, resetCompletion: false), - Handler.Control ('K', CmdKillToEOF), - Handler.Control ('Y', CmdYank), - Handler.Control ('D', CmdDeleteChar), - Handler.Control ('L', CmdRefresh), - Handler.Control ('R', CmdReverseSearch), - Handler.Control ('G', delegate {} ), - Handler.Alt ('B', ConsoleKey.B, CmdBackwardWord), - Handler.Alt ('F', ConsoleKey.F, CmdForwardWord), - - Handler.Alt ('D', ConsoleKey.D, CmdDeleteWord), - Handler.Alt ((char) 8, ConsoleKey.Backspace, CmdDeleteBackword), - - // DEBUG - //Handler.Control ('T', CmdDebug), - - // quote - Handler.Control ('Q', delegate { HandleChar (Console.ReadKey (true).KeyChar); }) - }; - - rendered_text = new StringBuilder (); - text = new StringBuilder (); - - history = new History (name, histsize); - - GetUnixConsoleReset (); - //if (File.Exists ("log"))File.Delete ("log"); - //log = File.CreateText ("log"); - } - - // On Unix, there is a "default" color which is not represented by any colors in - // ConsoleColor and it is not possible to set is by setting the ForegroundColor or - // BackgroundColor properties, so we have to use the terminfo driver in Mono to - // fetch these values - - void GetUnixConsoleReset () - { - // - // On Unix, we want to be able to reset the color for the pop-up completion - // - int p = (int) Environment.OSVersion.Platform; - var is_unix = (p == 4) || (p == 128); - if (!is_unix) - return; - - // Sole purpose of this call is to initialize the Terminfo driver - var x = Console.CursorLeft; - - try { - var terminfo_driver = Type.GetType ("System.ConsoleDriver")?.GetField ("driver", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue (null); - if (terminfo_driver == null) - return; - - var unix_reset_colors_str = (terminfo_driver?.GetType ()?.GetField ("origPair", BindingFlags.Instance | BindingFlags.NonPublic))?.GetValue (terminfo_driver) as string; - - if (unix_reset_colors_str != null) - unix_reset_colors = Encoding.UTF8.GetBytes ((string)unix_reset_colors_str); - unix_raw_output = Console.OpenStandardOutput (); - } catch (Exception e){ - Console.WriteLine ("Error: " + e); - } - } - - - void CmdDebug () - { - history.Dump (); - Console.WriteLine (); - Render (); - } - - void Render () - { - Console.Write (shown_prompt); - Console.Write (rendered_text); - - int max = System.Math.Max (rendered_text.Length + shown_prompt.Length, max_rendered); - - for (int i = rendered_text.Length + shown_prompt.Length; i < max_rendered; i++) - Console.Write (' '); - max_rendered = shown_prompt.Length + rendered_text.Length; - - // Write one more to ensure that we always wrap around properly if we are at the - // end of a line. - Console.Write (' '); - - UpdateHomeRow (max); - } - - void UpdateHomeRow (int screenpos) - { - int lines = 1 + (screenpos / Console.WindowWidth); - - home_row = Console.CursorTop - (lines - 1); - if (home_row < 0) - home_row = 0; - } - - - void RenderFrom (int pos) - { - int rpos = TextToRenderPos (pos); - int i; - - for (i = rpos; i < rendered_text.Length; i++) - Console.Write (rendered_text [i]); - - if ((shown_prompt.Length + rendered_text.Length) > max_rendered) - max_rendered = shown_prompt.Length + rendered_text.Length; - else { - int max_extra = max_rendered - shown_prompt.Length; - for (; i < max_extra; i++) - Console.Write (' '); - } - } - - void ComputeRendered () - { - rendered_text.Length = 0; - - for (int i = 0; i < text.Length; i++){ - int c = (int) text [i]; - if (c < 26){ - if (c == '\t') - rendered_text.Append (" "); - else { - rendered_text.Append ('^'); - rendered_text.Append ((char) (c + (int) 'A' - 1)); - } - } else - rendered_text.Append ((char)c); - } - } - - int TextToRenderPos (int pos) - { - int p = 0; - - for (int i = 0; i < pos; i++){ - int c; - - c = (int) text [i]; - - if (c < 26){ - if (c == 9) - p += 4; - else - p += 2; - } else - p++; - } - - return p; - } - - int TextToScreenPos (int pos) - { - return shown_prompt.Length + TextToRenderPos (pos); - } - - string Prompt { - get { return prompt; } - set { prompt = value; } - } - - int LineCount { - get { - return (shown_prompt.Length + rendered_text.Length)/Console.WindowWidth; - } - } - - void ForceCursor (int newpos) - { - cursor = newpos; - - int actual_pos = shown_prompt.Length + TextToRenderPos (cursor); - int row = home_row + (actual_pos/Console.WindowWidth); - int col = actual_pos % Console.WindowWidth; - - if (row >= Console.BufferHeight) - row = Console.BufferHeight-1; - Console.SetCursorPosition (col, row); - - //log.WriteLine ("Going to cursor={0} row={1} col={2} actual={3} prompt={4} ttr={5} old={6}", newpos, row, col, actual_pos, prompt.Length, TextToRenderPos (cursor), cursor); - //log.Flush (); - } - - void UpdateCursor (int newpos) - { - if (cursor == newpos) - return; - - ForceCursor (newpos); - } - - void InsertChar (char c) - { - int prev_lines = LineCount; - text = text.Insert (cursor, c); - ComputeRendered (); - if (prev_lines != LineCount){ - - Console.SetCursorPosition (0, home_row); - Render (); - ForceCursor (++cursor); - } else { - RenderFrom (cursor); - ForceCursor (++cursor); - UpdateHomeRow (TextToScreenPos (cursor)); - } - } - - static void SaveExcursion (Action code) - { - var saved_col = Console.CursorLeft; - var saved_row = Console.CursorTop; - var saved_fore = Console.ForegroundColor; - var saved_back = Console.BackgroundColor; - - code (); - - Console.CursorLeft = saved_col; - Console.CursorTop = saved_row; - if (unix_reset_colors != null){ - unix_raw_output.Write (unix_reset_colors, 0, unix_reset_colors.Length); - } else { - Console.ForegroundColor = saved_fore; - Console.BackgroundColor = saved_back; - } - } - - class CompletionState { - public string Prefix; - public string [] Completions; - public int Col, Row, Width, Height; - int selected_item, top_item; - - public CompletionState (int col, int row, int width, int height) - { - Col = col; - Row = row; - Width = width; - Height = height; - - if (Col < 0) - throw new ArgumentException ("Cannot be less than zero" + Col, "Col"); - if (Row < 0) - throw new ArgumentException ("Cannot be less than zero", "Row"); - if (Width < 1) - throw new ArgumentException ("Cannot be less than one", "Width"); - if (Height < 1) - throw new ArgumentException ("Cannot be less than one", "Height"); - - } - - void DrawSelection () - { - for (int r = 0; r < Height; r++){ - int item_idx = top_item + r; - bool selected = (item_idx == selected_item); - - Console.ForegroundColor = selected ? ConsoleColor.Black : ConsoleColor.Gray; - Console.BackgroundColor = selected ? ConsoleColor.Cyan : ConsoleColor.Blue; - - var item = Prefix + Completions [item_idx]; - if (item.Length > Width) - item = item.Substring (0, Width); - - Console.CursorLeft = Col; - Console.CursorTop = Row + r; - Console.Write (item); - for (int space = item.Length; space <= Width; space++) - Console.Write (" "); - } - } - - public string Current { - get { - return Completions [selected_item]; - } - } - - public void Show () - { - SaveExcursion (DrawSelection); - } - - public void SelectNext () - { - if (selected_item+1 < Completions.Length){ - selected_item++; - if (selected_item - top_item >= Height) - top_item++; - SaveExcursion (DrawSelection); - } - } - - public void SelectPrevious () - { - if (selected_item > 0){ - selected_item--; - if (selected_item < top_item) - top_item = selected_item; - SaveExcursion (DrawSelection); - } - } - - void Clear () - { - for (int r = 0; r < Height; r++){ - Console.CursorLeft = Col; - Console.CursorTop = Row + r; - for (int space = 0; space <= Width; space++) - Console.Write (" "); - } - } - - public void Remove () - { - SaveExcursion (Clear); - } - } - - void ShowCompletions (string prefix, string [] completions) - { - // Ensure we have space, determine window size - int window_height = System.Math.Min (completions.Length, Console.WindowHeight/5); - int target_line = Console.WindowHeight-window_height-1; - if (Console.CursorTop > target_line){ - var saved_left = Console.CursorLeft; - var delta = Console.CursorTop-target_line; - Console.CursorLeft = 0; - Console.CursorTop = Console.WindowHeight-1; - for (int i = 0; i < delta+1; i++){ - for (int c = Console.WindowWidth; c > 0; c--) - Console.Write (" "); // To debug use ("{0}", i%10); - } - Console.CursorTop = target_line; - Console.CursorLeft = 0; - Render (); - } - - const int MaxWidth = 50; - int window_width = 12; - int plen = prefix.Length; - foreach (var s in completions) - window_width = System.Math.Max (plen + s.Length, window_width); - window_width = System.Math.Min (window_width, MaxWidth); - - if (current_completion == null){ - int left = Console.CursorLeft-prefix.Length; - - if (left + window_width + 1 >= Console.WindowWidth) - left = Console.WindowWidth-window_width-1; - - current_completion = new CompletionState (left, Console.CursorTop+1, window_width, window_height) { - Prefix = prefix, - Completions = completions, - }; - } else { - current_completion.Prefix = prefix; - current_completion.Completions = completions; - } - current_completion.Show (); - Console.CursorLeft = 0; - } - - void HideCompletions () - { - if (current_completion == null) - return; - current_completion.Remove (); - current_completion = null; - } - - // - // Triggers the completion engine, if insertBestMatch is true, then this will - // insert the best match found, this behaves like the shell "tab" which will - // complete as much as possible given the options. - // - void Complete () - { - Completion completion = AutoCompleteEvent (text.ToString (), cursor); - string [] completions = completion.Result; - if (completions == null){ - HideCompletions (); - return; - } - - int ncompletions = completions.Length; - if (ncompletions == 0){ - HideCompletions (); - return; - } - - if (completions.Length == 1){ - InsertTextAtCursor (completions [0]); - HideCompletions (); - } else { - int last = -1; - - for (int p = 0; p < completions [0].Length; p++){ - char c = completions [0][p]; - - - for (int i = 1; i < ncompletions; i++){ - if (completions [i].Length < p) - goto mismatch; - - if (completions [i][p] != c){ - goto mismatch; - } - } - last = p; - } - mismatch: - var prefix = completion.Prefix; - if (last != -1){ - InsertTextAtCursor (completions [0].Substring (0, last+1)); - - // Adjust the completions to skip the common prefix - prefix += completions [0].Substring (0, last+1); - for (int i = 0; i < completions.Length; i++) - completions [i] = completions [i].Substring (last+1); - } - ShowCompletions (prefix, completions); - Render (); - ForceCursor (cursor); - } - } - - // - // When the user has triggered a completion window, this will try to update - // the contents of it. The completion window is assumed to be hidden at this - // point - // - void UpdateCompletionWindow () - { - if (current_completion != null) - throw new Exception ("This method should only be called if the window has been hidden"); - - Completion completion = AutoCompleteEvent (text.ToString (), cursor); - string [] completions = completion.Result; - if (completions == null) - return; - - int ncompletions = completions.Length; - if (ncompletions == 0) - return; - - ShowCompletions (completion.Prefix, completion.Result); - Render (); - ForceCursor (cursor); - } - - - // - // Commands - // - void CmdDone () - { - if (current_completion != null){ - InsertTextAtCursor (current_completion.Current); - HideCompletions (); - return; - } - done = true; - } - - void CmdTabOrComplete () - { - bool complete = false; - - if (AutoCompleteEvent != null){ - if (TabAtStartCompletes) - complete = true; - else { - for (int i = 0; i < cursor; i++){ - if (!Char.IsWhiteSpace (text [i])){ - complete = true; - break; - } - } - } - - if (complete) - Complete (); - else - HandleChar ('\t'); - } else - HandleChar ('t'); - } - - void CmdHome () - { - UpdateCursor (0); - } - - void CmdEnd () - { - UpdateCursor (text.Length); - } - - void CmdLeft () - { - if (cursor == 0) - return; - - UpdateCursor (cursor-1); - } - - void CmdBackwardWord () - { - int p = WordBackward (cursor); - if (p == -1) - return; - UpdateCursor (p); - } - - void CmdForwardWord () - { - int p = WordForward (cursor); - if (p == -1) - return; - UpdateCursor (p); - } - - void CmdRight () - { - if (cursor == text.Length) - return; - - UpdateCursor (cursor+1); - } - - void RenderAfter (int p) - { - ForceCursor (p); - RenderFrom (p); - ForceCursor (cursor); - } - - void CmdBackspace () - { - if (cursor == 0) - return; - - bool completing = current_completion != null; - HideCompletions (); - - text.Remove (--cursor, 1); - ComputeRendered (); - RenderAfter (cursor); - if (completing) - UpdateCompletionWindow (); - } - - void CmdDeleteChar () - { - // If there is no input, this behaves like EOF - if (text.Length == 0){ - done = true; - text = null; - Console.WriteLine (); - return; - } - - if (cursor == text.Length) - return; - text.Remove (cursor, 1); - ComputeRendered (); - RenderAfter (cursor); - } - - int WordForward (int p) - { - if (p >= text.Length) - return -1; - - int i = p; - if (Char.IsPunctuation (text [p]) || Char.IsSymbol (text [p]) || Char.IsWhiteSpace (text[p])){ - for (; i < text.Length; i++){ - if (Char.IsLetterOrDigit (text [i])) - break; - } - for (; i < text.Length; i++){ - if (!Char.IsLetterOrDigit (text [i])) - break; - } - } else { - for (; i < text.Length; i++){ - if (!Char.IsLetterOrDigit (text [i])) - break; - } - } - if (i != p) - return i; - return -1; - } - - int WordBackward (int p) - { - if (p == 0) - return -1; - - int i = p-1; - if (i == 0) - return 0; - - if (Char.IsPunctuation (text [i]) || Char.IsSymbol (text [i]) || Char.IsWhiteSpace (text[i])){ - for (; i >= 0; i--){ - if (Char.IsLetterOrDigit (text [i])) - break; - } - for (; i >= 0; i--){ - if (!Char.IsLetterOrDigit (text[i])) - break; - } - } else { - for (; i >= 0; i--){ - if (!Char.IsLetterOrDigit (text [i])) - break; - } - } - i++; - - if (i != p) - return i; - - return -1; - } - - void CmdDeleteWord () - { - int pos = WordForward (cursor); - - if (pos == -1) - return; - - string k = text.ToString (cursor, pos-cursor); - - if (last_handler == CmdDeleteWord) - kill_buffer = kill_buffer + k; - else - kill_buffer = k; - - text.Remove (cursor, pos-cursor); - ComputeRendered (); - RenderAfter (cursor); - } - - void CmdDeleteBackword () - { - int pos = WordBackward (cursor); - if (pos == -1) - return; - - string k = text.ToString (pos, cursor-pos); - - if (last_handler == CmdDeleteBackword) - kill_buffer = k + kill_buffer; - else - kill_buffer = k; - - text.Remove (pos, cursor-pos); - ComputeRendered (); - RenderAfter (pos); - } - - // - // Adds the current line to the history if needed - // - void HistoryUpdateLine () - { - history.Update (text.ToString ()); - } - - void CmdHistoryPrev () - { - if (!history.PreviousAvailable ()) - return; - - HistoryUpdateLine (); - - SetText (history.Previous ()); - } - - void CmdHistoryNext () - { - if (!history.NextAvailable()) - return; - - history.Update (text.ToString ()); - SetText (history.Next ()); - - } - - void CmdUp () - { - if (current_completion == null) - CmdHistoryPrev (); - else - current_completion.SelectPrevious (); - } - - void CmdDown () - { - if (current_completion == null) - CmdHistoryNext (); - else - current_completion.SelectNext (); - } - - void CmdKillToEOF () - { - kill_buffer = text.ToString (cursor, text.Length-cursor); - text.Length = cursor; - ComputeRendered (); - RenderAfter (cursor); - } - - void CmdYank () - { - InsertTextAtCursor (kill_buffer); - } - - void InsertTextAtCursor (string str) - { - int prev_lines = LineCount; - text.Insert (cursor, str); - ComputeRendered (); - if (prev_lines != LineCount){ - Console.SetCursorPosition (0, home_row); - Render (); - cursor += str.Length; - ForceCursor (cursor); - } else { - RenderFrom (cursor); - cursor += str.Length; - ForceCursor (cursor); - UpdateHomeRow (TextToScreenPos (cursor)); - } - } - - void SetSearchPrompt (string s) - { - SetPrompt ("(reverse-i-search)`" + s + "': "); - } - - void ReverseSearch () - { - int p; - - if (cursor == text.Length){ - // The cursor is at the end of the string - - p = text.ToString ().LastIndexOf (search); - if (p != -1){ - match_at = p; - cursor = p; - ForceCursor (cursor); - return; - } - } else { - // The cursor is somewhere in the middle of the string - int start = (cursor == match_at) ? cursor - 1 : cursor; - if (start != -1){ - p = text.ToString ().LastIndexOf (search, start); - if (p != -1){ - match_at = p; - cursor = p; - ForceCursor (cursor); - return; - } - } - } - - // Need to search backwards in history - HistoryUpdateLine (); - string s = history.SearchBackward (search); - if (s != null){ - match_at = -1; - SetText (s); - ReverseSearch (); - } - } - - void CmdReverseSearch () - { - if (searching == 0){ - match_at = -1; - last_search = search; - searching = -1; - search = ""; - SetSearchPrompt (""); - } else { - if (search == ""){ - if (last_search != "" && last_search != null){ - search = last_search; - SetSearchPrompt (search); - - ReverseSearch (); - } - return; - } - ReverseSearch (); - } - } - - void SearchAppend (char c) - { - search = search + c; - SetSearchPrompt (search); - - // - // If the new typed data still matches the current text, stay here - // - if (cursor < text.Length){ - string r = text.ToString (cursor, text.Length - cursor); - if (r.StartsWith (search)) - return; - } - - ReverseSearch (); - } - - void CmdRefresh () - { - Console.Clear (); - max_rendered = 0; - Render (); - ForceCursor (cursor); - } - - void InterruptEdit (object sender, ConsoleCancelEventArgs a) - { - // Do not abort our program: - a.Cancel = true; - - // Interrupt the editor - edit_thread.Abort(); - } - - // - // Implements heuristics to show the completion window based on the mode - // - bool HeuristicAutoComplete (bool wasCompleting, char insertedChar) - { - if (HeuristicsMode == "csharp"){ - // csharp heuristics - if (wasCompleting){ - if (insertedChar == ' '){ - return false; - } - return true; - } - // If we were not completing, determine if we want to now - if (insertedChar == '.'){ - // Avoid completing for numbers "1.2" for example - if (cursor > 1 && Char.IsDigit (text[cursor-2])){ - for (int p = cursor-3; p >= 0; p--){ - char c = text[p]; - if (Char.IsDigit (c)) - continue; - if (c == '_') - return true; - if (Char.IsLetter (c) || Char.IsPunctuation (c) || Char.IsSymbol (c) || Char.IsControl (c)) - return true; - } - return false; - } - return true; - } - } - return false; - } - - void HandleChar (char c) - { - if (searching != 0) - SearchAppend (c); - else { - bool completing = current_completion != null; - HideCompletions (); - - InsertChar (c); - if (HeuristicAutoComplete (completing, c)) - UpdateCompletionWindow (); - } - } - - void EditLoop () - { - ConsoleKeyInfo cki; - - while (!done){ - ConsoleModifiers mod; - - cki = Console.ReadKey (true); - if (cki.Key == ConsoleKey.Escape){ - if (current_completion != null){ - HideCompletions (); - continue; - } else { - cki = Console.ReadKey (true); - - mod = ConsoleModifiers.Alt; - } - } else - mod = cki.Modifiers; - - bool handled = false; - - foreach (Handler handler in handlers){ - ConsoleKeyInfo t = handler.CKI; - - if (t.Key == cki.Key && t.Modifiers == mod){ - handled = true; - if (handler.ResetCompletion) - HideCompletions (); - handler.KeyHandler (); - last_handler = handler.KeyHandler; - break; - } else if (t.KeyChar == cki.KeyChar && t.Key == ConsoleKey.Zoom){ - handled = true; - if (handler.ResetCompletion) - HideCompletions (); - - handler.KeyHandler (); - last_handler = handler.KeyHandler; - break; - } - } - if (handled){ - if (searching != 0){ - if (last_handler != CmdReverseSearch){ - searching = 0; - SetPrompt (prompt); - } - } - continue; - } - - if (cki.KeyChar != (char) 0){ - HandleChar (cki.KeyChar); - } - } - } - - void InitText (string initial) - { - text = new StringBuilder (initial); - ComputeRendered (); - cursor = text.Length; - Render (); - ForceCursor (cursor); - } - - void SetText (string newtext) - { - Console.SetCursorPosition (0, home_row); - InitText (newtext); - } - - void SetPrompt (string newprompt) - { - shown_prompt = newprompt; - Console.SetCursorPosition (0, home_row); - Render (); - ForceCursor (cursor); - } - - public string Edit (string prompt, string initial) - { - edit_thread = Thread.CurrentThread; - searching = 0; - Console.CancelKeyPress += InterruptEdit; - - done = false; - history.CursorToEnd (); - max_rendered = 0; - - Prompt = prompt; - shown_prompt = prompt; - InitText (initial); - history.Append (initial); - - do { - try { - EditLoop (); - } catch (ThreadAbortException){ - searching = 0; - Thread.ResetAbort (); - Console.WriteLine (); - SetPrompt (prompt); - SetText (""); - } - } while (!done); - Console.WriteLine (); - - Console.CancelKeyPress -= InterruptEdit; - - if (text == null){ - history.Close (); - return null; - } - - string result = text.ToString (); - if (result != "") - history.Accept (result); - else - history.RemoveLast (); - - return result; - } - - public void SaveHistory () - { - if (history != null) { - history.Close (); - } - } - - public bool TabAtStartCompletes { get; set; } - - // - // Emulates the bash-like behavior, where edits done to the - // history are recorded - // - class History { - string [] history; - int head, tail; - int cursor, count; - string histfile; - - public History (string app, int size) - { - if (size < 1) - throw new ArgumentException ("size"); - - if (app != null){ - string dir = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData); - //Console.WriteLine (dir); - if (!Directory.Exists (dir)){ - try { - Directory.CreateDirectory (dir); - } catch { - app = null; - } - } - if (app != null) - histfile = Path.Combine (dir, app) + ".history"; - } - - history = new string [size]; - head = tail = cursor = 0; - - if (File.Exists (histfile)){ - using (StreamReader sr = File.OpenText (histfile)){ - string line; - - while ((line = sr.ReadLine ()) != null){ - if (line != "") - Append (line); - } - } - } - } - - public void Close () - { - if (histfile == null) - return; - - try { - using (StreamWriter sw = File.CreateText (histfile)){ - int start = (count == history.Length) ? head : tail; - for (int i = start; i < start+count; i++){ - int p = i % history.Length; - sw.WriteLine (history [p]); - } - } - } catch { - // ignore - } - } - - // - // Appends a value to the history - // - public void Append (string s) - { - //Console.WriteLine ("APPENDING {0} head={1} tail={2}", s, head, tail); - history [head] = s; - head = (head+1) % history.Length; - if (head == tail) - tail = (tail+1 % history.Length); - if (count != history.Length) - count++; - //Console.WriteLine ("DONE: head={1} tail={2}", s, head, tail); - } - - // - // Updates the current cursor location with the string, - // to support editing of history items. For the current - // line to participate, an Append must be done before. - // - public void Update (string s) - { - history [cursor] = s; - } - - public void RemoveLast () - { - head = head-1; - if (head < 0) - head = history.Length-1; - } - - public void Accept (string s) - { - int t = head-1; - if (t < 0) - t = history.Length-1; - - history [t] = s; - } - - public bool PreviousAvailable () - { - //Console.WriteLine ("h={0} t={1} cursor={2}", head, tail, cursor); - if (count == 0) - return false; - int next = cursor-1; - if (next < 0) - next = count-1; - - if (next == head) - return false; - - return true; - } - - public bool NextAvailable () - { - if (count == 0) - return false; - int next = (cursor + 1) % history.Length; - if (next == head) - return false; - return true; - } - - - // - // Returns: a string with the previous line contents, or - // nul if there is no data in the history to move to. - // - public string Previous () - { - if (!PreviousAvailable ()) - return null; - - cursor--; - if (cursor < 0) - cursor = history.Length - 1; - - return history [cursor]; - } - - public string Next () - { - if (!NextAvailable ()) - return null; - - cursor = (cursor + 1) % history.Length; - return history [cursor]; - } - - public void CursorToEnd () - { - if (head == tail) - return; - - cursor = head; - } - - public void Dump () - { - Console.WriteLine ("Head={0} Tail={1} Cursor={2} count={3}", head, tail, cursor, count); - for (int i = 0; i < history.Length;i++){ - Console.WriteLine (" {0} {1}: {2}", i == cursor ? "==>" : " ", i, history[i]); - } - //log.Flush (); - } - - public string SearchBackward (string term) - { - for (int i = 0; i < count; i++){ - int slot = cursor-i-1; - if (slot < 0) - slot = history.Length+slot; - if (slot >= history.Length) - slot = 0; - if (history [slot] != null && history [slot].IndexOf (term) != -1){ - cursor = slot; - return history [slot]; - } - } - - return null; - } - - } - } - -#if DEMO - class Demo { - static void Main () - { - LineEditor le = new LineEditor ("foo") { - HeuristicsMode = "csharp" - }; - le.AutoCompleteEvent += delegate (string a, int pos){ - string prefix = ""; - var completions = new string [] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" }; - return new Mono.Terminal.LineEditor.Completion (prefix, completions); - }; - - string s; - - while ((s = le.Edit ("shell> ", "")) != null){ - Console.WriteLine ("----> [{0}]", s); - } - } - } -#endif -} diff --git a/vr21/project.json b/vr21/project.json new file mode 100755 index 0000000..eb23553 --- /dev/null +++ b/vr21/project.json @@ -0,0 +1,23 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + "emitEntryPoint": true + }, + "dependencies": {}, + "frameworks": { + "netcoreapp1.1": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.1.0-preview1-001100-00" + }, + "System.Xml.XmlSerializer":{ + "version":"*" + }, + "System.IO.FileSystem": {"version":"*"} + }, + "imports": "dnxcore50" + } + } +}