aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Console/ConsoleBase.cs
diff options
context:
space:
mode:
authorMelanie Thielker2009-05-04 12:15:55 +0000
committerMelanie Thielker2009-05-04 12:15:55 +0000
commit1b877234dada9f14cebc486cc426db892beae152 (patch)
tree762ee7172c66a78b643f4cef0eed946314816403 /OpenSim/Framework/Console/ConsoleBase.cs
parentThanks BlueWall for Mantis #3578 - adding Hypergrid connection to JSON Stats (diff)
downloadopensim-SC-1b877234dada9f14cebc486cc426db892beae152.zip
opensim-SC-1b877234dada9f14cebc486cc426db892beae152.tar.gz
opensim-SC-1b877234dada9f14cebc486cc426db892beae152.tar.bz2
opensim-SC-1b877234dada9f14cebc486cc426db892beae152.tar.xz
Refactor. Make ConsoleBase a true base class. Create CommandConsole as a simple
console capable of processing commands. Create LocalConsole as a console that uses cursor control and context help. Precursor to a distributed console system for the new grid services. No functional change intended :)
Diffstat (limited to 'OpenSim/Framework/Console/ConsoleBase.cs')
-rw-r--r--OpenSim/Framework/Console/ConsoleBase.cs829
1 files changed, 31 insertions, 798 deletions
diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs
index fda2037..30493fc 100644
--- a/OpenSim/Framework/Console/ConsoleBase.cs
+++ b/OpenSim/Framework/Console/ConsoleBase.cs
@@ -35,388 +35,11 @@ using log4net;
35 35
36namespace OpenSim.Framework.Console 36namespace OpenSim.Framework.Console
37{ 37{
38 public delegate void CommandDelegate(string module, string[] cmd);
39
40 public class Commands
41 {
42 /// <summary>
43 /// Encapsulates a command that can be invoked from the console
44 /// </summary>
45 private class CommandInfo
46 {
47 /// <value>
48 /// The module from which this command comes
49 /// </value>
50 public string module;
51
52 /// <value>
53 /// Whether the module is shared
54 /// </value>
55 public bool shared;
56
57 /// <value>
58 /// Very short BNF description
59 /// </value>
60 public string help_text;
61
62 /// <value>
63 /// Longer one line help text
64 /// </value>
65 public string long_help;
66
67 /// <value>
68 /// Full descriptive help for this command
69 /// </value>
70 public string descriptive_help;
71
72 /// <value>
73 /// The method to invoke for this command
74 /// </value>
75 public List<CommandDelegate> fn;
76 }
77
78 /// <value>
79 /// Commands organized by keyword in a tree
80 /// </value>
81 private Dictionary<string, object> tree =
82 new Dictionary<string, object>();
83
84 /// <summary>
85 /// Get help for the given help string
86 /// </summary>
87 /// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param>
88 /// <returns></returns>
89 public List<string> GetHelp(string[] cmd)
90 {
91 List<string> help = new List<string>();
92 List<string> helpParts = new List<string>(cmd);
93
94 // Remove initial help keyword
95 helpParts.RemoveAt(0);
96
97 // General help
98 if (helpParts.Count == 0)
99 {
100 help.AddRange(CollectHelp(tree));
101 help.Sort();
102 }
103 else
104 {
105 help.AddRange(CollectHelp(helpParts));
106 }
107
108 return help;
109 }
110
111 /// <summary>
112 /// See if we can find the requested command in order to display longer help
113 /// </summary>
114 /// <param name="helpParts"></param>
115 /// <returns></returns>
116 private List<string> CollectHelp(List<string> helpParts)
117 {
118 string originalHelpRequest = string.Join(" ", helpParts.ToArray());
119 List<string> help = new List<string>();
120
121 Dictionary<string, object> dict = tree;
122 while (helpParts.Count > 0)
123 {
124 string helpPart = helpParts[0];
125
126 if (!dict.ContainsKey(helpPart))
127 break;
128
129 //m_log.Debug("Found {0}", helpParts[0]);
130
131 if (dict[helpPart] is Dictionary<string, Object>)
132 dict = (Dictionary<string, object>)dict[helpPart];
133
134 helpParts.RemoveAt(0);
135 }
136
137 // There was a command for the given help string
138 if (dict.ContainsKey(String.Empty))
139 {
140 CommandInfo commandInfo = (CommandInfo)dict[String.Empty];
141 help.Add(commandInfo.help_text);
142 help.Add(commandInfo.long_help);
143 help.Add(commandInfo.descriptive_help);
144 }
145 else
146 {
147 help.Add(string.Format("No help is available for {0}", originalHelpRequest));
148 }
149
150 return help;
151 }
152
153 private List<string> CollectHelp(Dictionary<string, object> dict)
154 {
155 List<string> result = new List<string>();
156
157 foreach (KeyValuePair<string, object> kvp in dict)
158 {
159 if (kvp.Value is Dictionary<string, Object>)
160 {
161 result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
162 }
163 else
164 {
165 if (((CommandInfo)kvp.Value).long_help != String.Empty)
166 result.Add(((CommandInfo)kvp.Value).help_text+" - "+
167 ((CommandInfo)kvp.Value).long_help);
168 }
169 }
170 return result;
171 }
172
173 /// <summary>
174 /// Add a command to those which can be invoked from the console.
175 /// </summary>
176 /// <param name="module"></param>
177 /// <param name="command"></param>
178 /// <param name="help"></param>
179 /// <param name="longhelp"></param>
180 /// <param name="fn"></param>
181 public void AddCommand(string module, bool shared, string command,
182 string help, string longhelp, CommandDelegate fn)
183 {
184 AddCommand(module, shared, command, help, longhelp,
185 String.Empty, fn);
186 }
187
188 /// <summary>
189 /// Add a command to those which can be invoked from the console.
190 /// </summary>
191 /// <param name="module"></param>
192 /// <param name="command"></param>
193 /// <param name="help"></param>
194 /// <param name="longhelp"></param>
195 /// <param name="descriptivehelp"></param>
196 /// <param name="fn"></param>
197 public void AddCommand(string module, bool shared, string command,
198 string help, string longhelp, string descriptivehelp,
199 CommandDelegate fn)
200 {
201 string[] parts = Parser.Parse(command);
202
203 Dictionary<string, Object> current = tree;
204
205 foreach (string s in parts)
206 {
207 if (current.ContainsKey(s))
208 {
209 if (current[s] is Dictionary<string, Object>)
210 {
211 current = (Dictionary<string, Object>)current[s];
212 }
213 else
214 return;
215 }
216 else
217 {
218 current[s] = new Dictionary<string, Object>();
219 current = (Dictionary<string, Object>)current[s];
220 }
221 }
222
223 CommandInfo info;
224
225 if (current.ContainsKey(String.Empty))
226 {
227 info = (CommandInfo)current[String.Empty];
228 if (!info.shared && !info.fn.Contains(fn))
229 info.fn.Add(fn);
230
231 return;
232 }
233
234 info = new CommandInfo();
235 info.module = module;
236 info.shared = shared;
237 info.help_text = help;
238 info.long_help = longhelp;
239 info.descriptive_help = descriptivehelp;
240 info.fn = new List<CommandDelegate>();
241 info.fn.Add(fn);
242 current[String.Empty] = info;
243 }
244
245 public string[] FindNextOption(string[] cmd, bool term)
246 {
247 Dictionary<string, object> current = tree;
248
249 int remaining = cmd.Length;
250
251 foreach (string s in cmd)
252 {
253 remaining--;
254
255 List<string> found = new List<string>();
256
257 foreach (string opt in current.Keys)
258 {
259 if (remaining > 0 && opt == s)
260 {
261 found.Clear();
262 found.Add(opt);
263 break;
264 }
265 if (opt.StartsWith(s))
266 {
267 found.Add(opt);
268 }
269 }
270
271 if (found.Count == 1 && (remaining != 0 || term))
272 {
273 current = (Dictionary<string, object>)current[found[0]];
274 }
275 else if (found.Count > 0)
276 {
277 return found.ToArray();
278 }
279 else
280 {
281 break;
282// return new string[] {"<cr>"};
283 }
284 }
285
286 if (current.Count > 1)
287 {
288 List<string> choices = new List<string>();
289
290 bool addcr = false;
291 foreach (string s in current.Keys)
292 {
293 if (s == String.Empty)
294 {
295 CommandInfo ci = (CommandInfo)current[String.Empty];
296 if (ci.fn.Count != 0)
297 addcr = true;
298 }
299 else
300 choices.Add(s);
301 }
302 if (addcr)
303 choices.Add("<cr>");
304 return choices.ToArray();
305 }
306
307 if (current.ContainsKey(String.Empty))
308 return new string[] { "Command help: "+((CommandInfo)current[String.Empty]).help_text};
309
310 return new string[] { new List<string>(current.Keys)[0] };
311 }
312
313 public string[] Resolve(string[] cmd)
314 {
315 string[] result = cmd;
316 int index = -1;
317
318 Dictionary<string, object> current = tree;
319
320 foreach (string s in cmd)
321 {
322 index++;
323
324 List<string> found = new List<string>();
325
326 foreach (string opt in current.Keys)
327 {
328 if (opt == s)
329 {
330 found.Clear();
331 found.Add(opt);
332 break;
333 }
334 if (opt.StartsWith(s))
335 {
336 found.Add(opt);
337 }
338 }
339
340 if (found.Count == 1)
341 {
342 result[index] = found[0];
343 current = (Dictionary<string, object>)current[found[0]];
344 }
345 else if (found.Count > 0)
346 {
347 return new string[0];
348 }
349 else
350 {
351 break;
352 }
353 }
354
355 if (current.ContainsKey(String.Empty))
356 {
357 CommandInfo ci = (CommandInfo)current[String.Empty];
358 if (ci.fn.Count == 0)
359 return new string[0];
360 foreach (CommandDelegate fn in ci.fn)
361 {
362 if (fn != null)
363 fn(ci.module, result);
364 else
365 return new string[0];
366 }
367 return result;
368 }
369
370 return new string[0];
371 }
372 }
373
374 public class Parser
375 {
376 public static string[] Parse(string text)
377 {
378 List<string> result = new List<string>();
379
380 int index;
381
382 string[] unquoted = text.Split(new char[] {'"'});
383
384 for (index = 0 ; index < unquoted.Length ; index++)
385 {
386 if (index % 2 == 0)
387 {
388 string[] words = unquoted[index].Split(new char[] {' '});
389 foreach (string w in words)
390 {
391 if (w != String.Empty)
392 result.Add(w);
393 }
394 }
395 else
396 {
397 result.Add(unquoted[index]);
398 }
399 }
400
401 return result.ToArray();
402 }
403 }
404
405 public class ConsoleBase 38 public class ConsoleBase
406 { 39 {
407 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
408 41
409 private readonly object m_syncRoot = new object(); 42 protected string prompt = "# ";
410
411 private int y = -1;
412 private int cp = 0;
413 private int h = 1;
414 private string prompt = "# ";
415 private StringBuilder cmdline = new StringBuilder();
416 public Commands Commands = new Commands();
417 private bool echo = true;
418 private List<string> history = new List<string>();
419 private bool gui = false;
420 43
421 public object ConsoleScene = null; 44 public object ConsoleScene = null;
422 45
@@ -433,22 +56,6 @@ namespace OpenSim.Framework.Console
433 public ConsoleBase(string defaultPrompt) 56 public ConsoleBase(string defaultPrompt)
434 { 57 {
435 DefaultPrompt = defaultPrompt; 58 DefaultPrompt = defaultPrompt;
436
437 Commands.AddCommand("console", false, "help", "help [<command>]",
438 "Get general command list or more detailed help on a specific command", Help);
439 }
440
441 public void SetGuiMode(bool mode)
442 {
443 gui = mode;
444 }
445
446 private void AddToHistory(string text)
447 {
448 while (history.Count >= 100)
449 history.RemoveAt(0);
450
451 history.Add(text);
452 } 59 }
453 60
454 /// <summary> 61 /// <summary>
@@ -458,10 +65,9 @@ namespace OpenSim.Framework.Console
458 /// </summary> 65 /// </summary>
459 /// <param name="input">arbitrary string for input</param> 66 /// <param name="input">arbitrary string for input</param>
460 /// <returns>an ansii color</returns> 67 /// <returns>an ansii color</returns>
461 private static ConsoleColor DeriveColor(string input) 68 protected virtual ConsoleColor DeriveColor(string input)
462 { 69 {
463 int colIdx = (input.ToUpper().GetHashCode() % 6) + 9; 70 return ConsoleColor.White;
464 return (ConsoleColor) colIdx;
465 } 71 }
466 72
467 /// <summary> 73 /// <summary>
@@ -559,280 +165,58 @@ namespace OpenSim.Framework.Console
559 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Gray, format, args); 165 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Gray, format, args);
560 } 166 }
561 167
562 private int SetCursorTop(int top) 168 protected virtual void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
563 { 169 {
564 if (top >= 0 && top < System.Console.BufferHeight) 170 WritePrefixLine(senderColor, sender);
565 { 171 WriteConsoleLine(color, format, args);
566 System.Console.CursorTop = top;
567 return top;
568 }
569 else
570 {
571 return System.Console.CursorTop;
572 }
573 } 172 }
574 173
575 private int SetCursorLeft(int left) 174 protected virtual void WriteNewLine(ConsoleColor color, string format, params object[] args)
576 { 175 {
577 if (left >= 0 && left < System.Console.BufferWidth) 176 WriteConsoleLine(color, format, args);
578 {
579 System.Console.CursorLeft = left;
580 return left;
581 }
582 else
583 {
584 return System.Console.CursorLeft;
585 }
586 } 177 }
587 178
588 private void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args) 179 protected virtual void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
589 {
590 lock (cmdline)
591 {
592 if (y != -1)
593 {
594 y=SetCursorTop(y);
595 System.Console.CursorLeft = 0;
596
597 int count = cmdline.Length;
598
599 System.Console.Write(" ");
600 while (count-- > 0)
601 System.Console.Write(" ");
602
603 y=SetCursorTop(y);
604 System.Console.CursorLeft = 0;
605 }
606 WritePrefixLine(senderColor, sender);
607 WriteConsoleLine(color, format, args);
608 if (y != -1)
609 y = System.Console.CursorTop;
610 }
611 }
612
613 private void WriteNewLine(ConsoleColor color, string format, params object[] args)
614 {
615 lock (cmdline)
616 {
617 if (y != -1)
618 {
619 y=SetCursorTop(y);
620 System.Console.CursorLeft = 0;
621
622 int count = cmdline.Length;
623
624 System.Console.Write(" ");
625 while (count-- > 0)
626 System.Console.Write(" ");
627
628 y=SetCursorTop(y);
629 System.Console.CursorLeft = 0;
630 }
631 WriteConsoleLine(color, format, args);
632 if (y != -1)
633 y = System.Console.CursorTop;
634 }
635 }
636
637 private void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
638 { 180 {
639 try 181 try
640 { 182 {
641 lock (m_syncRoot) 183 System.Console.WriteLine(format, args);
642 {
643 try
644 {
645 if (color != ConsoleColor.White)
646 System.Console.ForegroundColor = color;
647
648 System.Console.WriteLine(format, args);
649 System.Console.ResetColor();
650 }
651 catch (ArgumentNullException)
652 {
653 // Some older systems dont support coloured text.
654 System.Console.WriteLine(format, args);
655 }
656 catch (FormatException)
657 {
658 System.Console.WriteLine(args);
659 }
660 }
661 } 184 }
662 catch (ObjectDisposedException) 185 catch (ObjectDisposedException)
663 { 186 {
664 } 187 }
665 } 188 }
666 189
667 private void WritePrefixLine(ConsoleColor color, string sender) 190 protected virtual void WritePrefixLine(ConsoleColor color, string sender)
668 { 191 {
669 try 192 try
670 { 193 {
671 lock (m_syncRoot) 194 sender = sender.ToUpper();
672 {
673 sender = sender.ToUpper();
674 195
675 System.Console.WriteLine("[" + sender + "] "); 196 System.Console.WriteLine("[" + sender + "] ");
676 197
677 System.Console.Write("["); 198 System.Console.Write("[");
678 199
679 try 200 System.Console.Write(sender);
680 {
681 System.Console.ForegroundColor = color;
682 System.Console.Write(sender);
683 System.Console.ResetColor();
684 }
685 catch (ArgumentNullException)
686 {
687 // Some older systems dont support coloured text.
688 System.Console.WriteLine(sender);
689 }
690 201
691 System.Console.Write("] \t"); 202 System.Console.Write("] \t");
692 }
693 } 203 }
694 catch (ObjectDisposedException) 204 catch (ObjectDisposedException)
695 { 205 {
696 } 206 }
697 } 207 }
698 208
699 private void Help(string module, string[] cmd) 209 public virtual void LockOutput()
700 {
701 List<string> help = Commands.GetHelp(cmd);
702
703 foreach (string s in help)
704 Output(s);
705 }
706
707 private void Show()
708 {
709 lock (cmdline)
710 {
711 if (y == -1 || System.Console.BufferWidth == 0)
712 return;
713
714 int xc = prompt.Length + cp;
715 int new_x = xc % System.Console.BufferWidth;
716 int new_y = y + xc / System.Console.BufferWidth;
717 int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
718 if (end_y / System.Console.BufferWidth >= h)
719 h++;
720 if (end_y >= System.Console.BufferHeight) // wrap
721 {
722 y--;
723 new_y--;
724 System.Console.CursorLeft = 0;
725 System.Console.CursorTop = System.Console.BufferHeight-1;
726 System.Console.WriteLine(" ");
727 }
728
729 y=SetCursorTop(y);
730 System.Console.CursorLeft = 0;
731
732 if (echo)
733 System.Console.Write("{0}{1}", prompt, cmdline);
734 else
735 System.Console.Write("{0}", prompt);
736
737 SetCursorLeft(new_x);
738 SetCursorTop(new_y);
739 }
740 }
741
742 public void LockOutput()
743 {
744 Monitor.Enter(cmdline);
745 try
746 {
747 if (y != -1)
748 {
749 y = SetCursorTop(y);
750 System.Console.CursorLeft = 0;
751
752 int count = cmdline.Length + prompt.Length;
753
754 while (count-- > 0)
755 System.Console.Write(" ");
756
757 y = SetCursorTop(y);
758 System.Console.CursorLeft = 0;
759
760 }
761 }
762 catch (Exception)
763 {
764 }
765 }
766
767 public void UnlockOutput()
768 { 210 {
769 if (y != -1)
770 {
771 y = System.Console.CursorTop;
772 Show();
773 }
774 Monitor.Exit(cmdline);
775 } 211 }
776 212
777 public void Output(string text) 213 public virtual void UnlockOutput()
778 { 214 {
779 lock (cmdline)
780 {
781 if (y == -1)
782 {
783 System.Console.WriteLine(text);
784
785 return;
786 }
787
788 y = SetCursorTop(y);
789 System.Console.CursorLeft = 0;
790
791 int count = cmdline.Length + prompt.Length;
792
793 while (count-- > 0)
794 System.Console.Write(" ");
795
796 y = SetCursorTop(y);
797 System.Console.CursorLeft = 0;
798
799 System.Console.WriteLine(text);
800
801 y = System.Console.CursorTop;
802
803 Show();
804 }
805 }
806
807 private bool ContextHelp()
808 {
809 string[] words = Parser.Parse(cmdline.ToString());
810
811 bool trailingSpace = cmdline.ToString().EndsWith(" ");
812
813 // Allow ? through while typing a URI
814 //
815 if (words.Length > 0 && words[words.Length-1].StartsWith("http") && !trailingSpace)
816 return false;
817
818 string[] opts = Commands.FindNextOption(words, trailingSpace);
819
820 if (opts[0].StartsWith("Command help:"))
821 Output(opts[0]);
822 else
823 Output(String.Format("Options: {0}", String.Join(" ", opts)));
824
825 return true;
826 } 215 }
827 216
828 public void Prompt() 217 public virtual void Output(string text)
829 { 218 {
830 string line = ReadLine(m_defaultPrompt, true, true); 219 System.Console.WriteLine(text);
831
832 if (line != String.Empty)
833 {
834 m_log.Info("Invalid command");
835 }
836 } 220 }
837 221
838 public string CmdPrompt(string p) 222 public string CmdPrompt(string p)
@@ -850,19 +234,23 @@ namespace OpenSim.Framework.Console
850 } 234 }
851 235
852 // Displays a command prompt and returns a default value, user may only enter 1 of 2 options 236 // Displays a command prompt and returns a default value, user may only enter 1 of 2 options
853 public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB) 237 public string CmdPrompt(string prompt, string defaultresponse, List<string> options)
854 { 238 {
855 bool itisdone = false; 239 bool itisdone = false;
240 string optstr = String.Empty;
241 foreach (string s in options)
242 optstr += " " + s;
243
856 string temp = CmdPrompt(prompt, defaultresponse); 244 string temp = CmdPrompt(prompt, defaultresponse);
857 while (itisdone == false) 245 while (itisdone == false)
858 { 246 {
859 if ((temp == OptionA) || (temp == OptionB)) 247 if (options.Contains(temp))
860 { 248 {
861 itisdone = true; 249 itisdone = true;
862 } 250 }
863 else 251 else
864 { 252 {
865 System.Console.WriteLine("Valid options are " + OptionA + " or " + OptionB); 253 System.Console.WriteLine("Valid options are" + optstr);
866 temp = CmdPrompt(prompt, defaultresponse); 254 temp = CmdPrompt(prompt, defaultresponse);
867 } 255 }
868 } 256 }
@@ -876,167 +264,12 @@ namespace OpenSim.Framework.Console
876 return ReadLine(p, false, false); 264 return ReadLine(p, false, false);
877 } 265 }
878 266
879 public void RunCommand(string cmd) 267 public virtual string ReadLine(string p, bool isCommand, bool e)
880 {
881 string[] parts = Parser.Parse(cmd);
882 Commands.Resolve(parts);
883 }
884
885 public string ReadLine(string p, bool isCommand, bool e)
886 { 268 {
887 h = 1; 269 System.Console.Write("{0}", prompt);
888 cp = 0; 270 string cmdinput = System.Console.ReadLine();
889 prompt = p;
890 echo = e;
891 int historyLine = history.Count;
892 271
893 if (gui) 272 return cmdinput;
894 {
895 System.Console.Write("{0}", prompt);
896 string cmdinput = System.Console.ReadLine();
897
898 if (isCommand)
899 {
900 string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
901
902 if (cmd.Length != 0)
903 {
904 int i;
905
906 for (i=0 ; i < cmd.Length ; i++)
907 {
908 if (cmd[i].Contains(" "))
909 cmd[i] = "\"" + cmd[i] + "\"";
910 }
911 return String.Empty;
912 }
913 }
914 return cmdinput;
915 }
916
917 System.Console.CursorLeft = 0; // Needed for mono
918 System.Console.Write(" "); // Needed for mono
919
920 lock (cmdline)
921 {
922 y = System.Console.CursorTop;
923 cmdline.Remove(0, cmdline.Length);
924 }
925
926 while (true)
927 {
928 Show();
929
930 ConsoleKeyInfo key = System.Console.ReadKey(true);
931 char c = key.KeyChar;
932
933 if (!Char.IsControl(c))
934 {
935 if (cp >= 318)
936 continue;
937
938 if (c == '?' && isCommand)
939 {
940 if (ContextHelp())
941 continue;
942 }
943
944 cmdline.Insert(cp, c);
945 cp++;
946 }
947 else
948 {
949 switch (key.Key)
950 {
951 case ConsoleKey.Backspace:
952 if (cp == 0)
953 break;
954 cmdline.Remove(cp-1, 1);
955 cp--;
956
957 System.Console.CursorLeft = 0;
958 y = SetCursorTop(y);
959
960 System.Console.Write("{0}{1} ", prompt, cmdline);
961
962 break;
963 case ConsoleKey.End:
964 cp = cmdline.Length;
965 break;
966 case ConsoleKey.Home:
967 cp = 0;
968 break;
969 case ConsoleKey.UpArrow:
970 if (historyLine < 1)
971 break;
972 historyLine--;
973 LockOutput();
974 cmdline.Remove(0, cmdline.Length);
975 cmdline.Append(history[historyLine]);
976 cp = cmdline.Length;
977 UnlockOutput();
978 break;
979 case ConsoleKey.DownArrow:
980 if (historyLine >= history.Count)
981 break;
982 historyLine++;
983 LockOutput();
984 if (historyLine == history.Count)
985 {
986 cmdline.Remove(0, cmdline.Length);
987 }
988 else
989 {
990 cmdline.Remove(0, cmdline.Length);
991 cmdline.Append(history[historyLine]);
992 }
993 cp = cmdline.Length;
994 UnlockOutput();
995 break;
996 case ConsoleKey.LeftArrow:
997 if (cp > 0)
998 cp--;
999 break;
1000 case ConsoleKey.RightArrow:
1001 if (cp < cmdline.Length)
1002 cp++;
1003 break;
1004 case ConsoleKey.Enter:
1005 System.Console.CursorLeft = 0;
1006 y = SetCursorTop(y);
1007
1008 System.Console.WriteLine("{0}{1}", prompt, cmdline);
1009
1010 lock (cmdline)
1011 {
1012 y = -1;
1013 }
1014
1015 if (isCommand)
1016 {
1017 string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
1018
1019 if (cmd.Length != 0)
1020 {
1021 int i;
1022
1023 for (i=0 ; i < cmd.Length ; i++)
1024 {
1025 if (cmd[i].Contains(" "))
1026 cmd[i] = "\"" + cmd[i] + "\"";
1027 }
1028 AddToHistory(String.Join(" ", cmd));
1029 return String.Empty;
1030 }
1031 }
1032
1033 AddToHistory(cmdline.ToString());
1034 return cmdline.ToString();
1035 default:
1036 break;
1037 }
1038 }
1039 }
1040 } 273 }
1041 } 274 }
1042} 275}