1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSim Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Reflection;
- using System.Text;
- using System.Threading;
- using log4net;
- namespace OpenSim.Framework.Console
- {
- public delegate void CommandDelegate(string module, string[] cmd);
- public class Commands
- {
- /// <summary>
- /// Encapsulates a command that can be invoked from the console
- /// </summary>
- private class CommandInfo
- {
- /// <value>
- /// The module from which this command comes
- /// </value>
- public string module;
-
- /// <value>
- /// Whether the module is shared
- /// </value>
- public bool shared;
-
- /// <value>
- /// Very short BNF description
- /// </value>
- public string help_text;
-
- /// <value>
- /// Longer one line help text
- /// </value>
- public string long_help;
-
- /// <value>
- /// Full descriptive help for this command
- /// </value>
- public string descriptive_help;
-
- /// <value>
- /// The method to invoke for this command
- /// </value>
- public List<CommandDelegate> fn;
- }
- /// <value>
- /// Commands organized by keyword in a tree
- /// </value>
- private Dictionary<string, object> tree =
- new Dictionary<string, object>();
- /// <summary>
- /// Get help for the given help string
- /// </summary>
- /// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param>
- /// <returns></returns>
- public List<string> GetHelp(string[] cmd)
- {
- List<string> help = new List<string>();
- List<string> helpParts = new List<string>(cmd);
-
- // Remove initial help keyword
- helpParts.RemoveAt(0);
- // General help
- if (helpParts.Count == 0)
- {
- help.AddRange(CollectHelp(tree));
- help.Sort();
- }
- else
- {
- help.AddRange(CollectHelp(helpParts));
- }
- return help;
- }
-
- /// <summary>
- /// See if we can find the requested command in order to display longer help
- /// </summary>
- /// <param name="helpParts"></param>
- /// <returns></returns>
- private List<string> CollectHelp(List<string> helpParts)
- {
- string originalHelpRequest = string.Join(" ", helpParts.ToArray());
- List<string> help = new List<string>();
-
- Dictionary<string, object> dict = tree;
- while (helpParts.Count > 0)
- {
- string helpPart = helpParts[0];
-
- if (!dict.ContainsKey(helpPart))
- break;
-
- //m_log.Debug("Found {0}", helpParts[0]);
-
- if (dict[helpPart] is Dictionary<string, Object>)
- dict = (Dictionary<string, object>)dict[helpPart];
-
- helpParts.RemoveAt(0);
- }
-
- // There was a command for the given help string
- if (dict.ContainsKey(String.Empty))
- {
- CommandInfo commandInfo = (CommandInfo)dict[String.Empty];
- help.Add(commandInfo.help_text);
- help.Add(commandInfo.long_help);
- help.Add(commandInfo.descriptive_help);
- }
- else
- {
- help.Add(string.Format("No help is available for {0}", originalHelpRequest));
- }
-
- return help;
- }
- private List<string> CollectHelp(Dictionary<string, object> dict)
- {
- List<string> result = new List<string>();
- foreach (KeyValuePair<string, object> kvp in dict)
- {
- if (kvp.Value is Dictionary<string, Object>)
- {
- result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
- }
- else
- {
- if (((CommandInfo)kvp.Value).long_help != String.Empty)
- result.Add(((CommandInfo)kvp.Value).help_text+" - "+
- ((CommandInfo)kvp.Value).long_help);
- }
- }
- return result;
- }
-
- /// <summary>
- /// Add a command to those which can be invoked from the console.
- /// </summary>
- /// <param name="module"></param>
- /// <param name="command"></param>
- /// <param name="help"></param>
- /// <param name="longhelp"></param>
- /// <param name="fn"></param>
- public void AddCommand(string module, bool shared, string command,
- string help, string longhelp, CommandDelegate fn)
- {
- AddCommand(module, shared, command, help, longhelp,
- String.Empty, fn);
- }
- /// <summary>
- /// Add a command to those which can be invoked from the console.
- /// </summary>
- /// <param name="module"></param>
- /// <param name="command"></param>
- /// <param name="help"></param>
- /// <param name="longhelp"></param>
- /// <param name="descriptivehelp"></param>
- /// <param name="fn"></param>
- public void AddCommand(string module, bool shared, string command,
- string help, string longhelp, string descriptivehelp,
- CommandDelegate fn)
- {
- string[] parts = Parser.Parse(command);
- Dictionary<string, Object> current = tree;
-
- foreach (string s in parts)
- {
- if (current.ContainsKey(s))
- {
- if (current[s] is Dictionary<string, Object>)
- {
- current = (Dictionary<string, Object>)current[s];
- }
- else
- return;
- }
- else
- {
- current[s] = new Dictionary<string, Object>();
- current = (Dictionary<string, Object>)current[s];
- }
- }
- CommandInfo info;
- if (current.ContainsKey(String.Empty))
- {
- info = (CommandInfo)current[String.Empty];
- if (!info.shared && !info.fn.Contains(fn))
- info.fn.Add(fn);
- return;
- }
-
- info = new CommandInfo();
- info.module = module;
- info.shared = shared;
- info.help_text = help;
- info.long_help = longhelp;
- info.descriptive_help = descriptivehelp;
- info.fn = new List<CommandDelegate>();
- info.fn.Add(fn);
- current[String.Empty] = info;
- }
- public string[] FindNextOption(string[] cmd, bool term)
- {
- Dictionary<string, object> current = tree;
- int remaining = cmd.Length;
- foreach (string s in cmd)
- {
- remaining--;
- List<string> found = new List<string>();
- foreach (string opt in current.Keys)
- {
- if (remaining > 0 && opt == s)
- {
- found.Clear();
- found.Add(opt);
- break;
- }
- if (opt.StartsWith(s))
- {
- found.Add(opt);
- }
- }
- if (found.Count == 1 && (remaining != 0 || term))
- {
- current = (Dictionary<string, object>)current[found[0]];
- }
- else if (found.Count > 0)
- {
- return found.ToArray();
- }
- else
- {
- break;
- // return new string[] {"<cr>"};
- }
- }
- if (current.Count > 1)
- {
- List<string> choices = new List<string>();
- bool addcr = false;
- foreach (string s in current.Keys)
- {
- if (s == String.Empty)
- {
- CommandInfo ci = (CommandInfo)current[String.Empty];
- if (ci.fn.Count != 0)
- addcr = true;
- }
- else
- choices.Add(s);
- }
- if (addcr)
- choices.Add("<cr>");
- return choices.ToArray();
- }
- if (current.ContainsKey(String.Empty))
- return new string[] { "Command help: "+((CommandInfo)current[String.Empty]).help_text};
- return new string[] { new List<string>(current.Keys)[0] };
- }
- public string[] Resolve(string[] cmd)
- {
- string[] result = cmd;
- int index = -1;
- Dictionary<string, object> current = tree;
- foreach (string s in cmd)
- {
- index++;
- List<string> found = new List<string>();
- foreach (string opt in current.Keys)
- {
- if (opt == s)
- {
- found.Clear();
- found.Add(opt);
- break;
- }
- if (opt.StartsWith(s))
- {
- found.Add(opt);
- }
- }
- if (found.Count == 1)
- {
- result[index] = found[0];
- current = (Dictionary<string, object>)current[found[0]];
- }
- else if (found.Count > 0)
- {
- return new string[0];
- }
- else
- {
- break;
- }
- }
- if (current.ContainsKey(String.Empty))
- {
- CommandInfo ci = (CommandInfo)current[String.Empty];
- if (ci.fn.Count == 0)
- return new string[0];
- foreach (CommandDelegate fn in ci.fn)
- {
- if (fn != null)
- fn(ci.module, result);
- else
- return new string[0];
- }
- return result;
- }
-
- return new string[0];
- }
- }
- public class Parser
- {
- public static string[] Parse(string text)
- {
- List<string> result = new List<string>();
- int index;
- string[] unquoted = text.Split(new char[] {'"'});
- for (index = 0 ; index < unquoted.Length ; index++)
- {
- if (index % 2 == 0)
- {
- string[] words = unquoted[index].Split(new char[] {' '});
- foreach (string w in words)
- {
- if (w != String.Empty)
- result.Add(w);
- }
- }
- else
- {
- result.Add(unquoted[index]);
- }
- }
- return result.ToArray();
- }
- }
- public class ConsoleBase
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private readonly object m_syncRoot = new object();
- private int y = -1;
- private int cp = 0;
- private int h = 1;
- private string prompt = "# ";
- private StringBuilder cmdline = new StringBuilder();
- public Commands Commands = new Commands();
- private bool echo = true;
- private List<string> history = new List<string>();
- private bool gui = false;
- public object ConsoleScene = null;
- /// <summary>
- /// The default prompt text.
- /// </summary>
- public string DefaultPrompt
- {
- set { m_defaultPrompt = value + "# "; }
- get { return m_defaultPrompt; }
- }
- protected string m_defaultPrompt;
- public ConsoleBase(string defaultPrompt)
- {
- DefaultPrompt = defaultPrompt;
- Commands.AddCommand("console", false, "help", "help [<command>]",
- "Get general command list or more detailed help on a specific command", Help);
- }
- public void SetGuiMode(bool mode)
- {
- gui = mode;
- }
- private void AddToHistory(string text)
- {
- while (history.Count >= 100)
- history.RemoveAt(0);
- history.Add(text);
- }
- /// <summary>
- /// derive an ansi color from a string, ignoring the darker colors.
- /// This is used to help automatically bin component tags with colors
- /// in various print functions.
- /// </summary>
- /// <param name="input">arbitrary string for input</param>
- /// <returns>an ansii color</returns>
- private static ConsoleColor DeriveColor(string input)
- {
- int colIdx = (input.ToUpper().GetHashCode() % 6) + 9;
- return (ConsoleColor) colIdx;
- }
- /// <summary>
- /// Sends a warning to the current console output
- /// </summary>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Warn(string format, params object[] args)
- {
- WriteNewLine(ConsoleColor.Yellow, format, args);
- }
- /// <summary>
- /// Sends a warning to the current console output
- /// </summary>
- /// <param name="sender">The module that sent this message</param>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Warn(string sender, string format, params object[] args)
- {
- WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Yellow, format, args);
- }
- /// <summary>
- /// Sends a notice to the current console output
- /// </summary>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Notice(string format, params object[] args)
- {
- WriteNewLine(ConsoleColor.White, format, args);
- }
- /// <summary>
- /// Sends a notice to the current console output
- /// </summary>
- /// <param name="sender">The module that sent this message</param>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Notice(string sender, string format, params object[] args)
- {
- WriteNewLine(DeriveColor(sender), sender, ConsoleColor.White, format, args);
- }
- /// <summary>
- /// Sends an error to the current console output
- /// </summary>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Error(string format, params object[] args)
- {
- WriteNewLine(ConsoleColor.Red, format, args);
- }
- /// <summary>
- /// Sends an error to the current console output
- /// </summary>
- /// <param name="sender">The module that sent this message</param>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Error(string sender, string format, params object[] args)
- {
- WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Red, format, args);
- }
- /// <summary>
- /// Sends a status message to the current console output
- /// </summary>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Status(string format, params object[] args)
- {
- WriteNewLine(ConsoleColor.Blue, format, args);
- }
- /// <summary>
- /// Sends a status message to the current console output
- /// </summary>
- /// <param name="sender">The module that sent this message</param>
- /// <param name="format">The message to send</param>
- /// <param name="args">WriteLine-style message arguments</param>
- public void Status(string sender, string format, params object[] args)
- {
- WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Blue, format, args);
- }
- [Conditional("DEBUG")]
- public void Debug(string format, params object[] args)
- {
- WriteNewLine(ConsoleColor.Gray, format, args);
- }
- [Conditional("DEBUG")]
- public void Debug(string sender, string format, params object[] args)
- {
- WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Gray, format, args);
- }
- private int SetCursorTop(int top)
- {
- if (top >= 0 && top < System.Console.BufferHeight)
- {
- System.Console.CursorTop = top;
- return top;
- }
- else
- {
- return System.Console.CursorTop;
- }
- }
- private int SetCursorLeft(int left)
- {
- if (left >= 0 && left < System.Console.BufferWidth)
- {
- System.Console.CursorLeft = left;
- return left;
- }
- else
- {
- return System.Console.CursorLeft;
- }
- }
- private void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
- {
- lock (cmdline)
- {
- if (y != -1)
- {
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- int count = cmdline.Length;
- System.Console.Write(" ");
- while (count-- > 0)
- System.Console.Write(" ");
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- }
- WritePrefixLine(senderColor, sender);
- WriteConsoleLine(color, format, args);
- if (y != -1)
- y = System.Console.CursorTop;
- }
- }
- private void WriteNewLine(ConsoleColor color, string format, params object[] args)
- {
- lock (cmdline)
- {
- if (y != -1)
- {
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- int count = cmdline.Length;
- System.Console.Write(" ");
- while (count-- > 0)
- System.Console.Write(" ");
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- }
- WriteConsoleLine(color, format, args);
- if (y != -1)
- y = System.Console.CursorTop;
- }
- }
- private void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
- {
- try
- {
- lock (m_syncRoot)
- {
- try
- {
- if (color != ConsoleColor.White)
- System.Console.ForegroundColor = color;
- System.Console.WriteLine(format, args);
- System.Console.ResetColor();
- }
- catch (ArgumentNullException)
- {
- // Some older systems dont support coloured text.
- System.Console.WriteLine(format, args);
- }
- catch (FormatException)
- {
- System.Console.WriteLine(args);
- }
- }
- }
- catch (ObjectDisposedException)
- {
- }
- }
- private void WritePrefixLine(ConsoleColor color, string sender)
- {
- try
- {
- lock (m_syncRoot)
- {
- sender = sender.ToUpper();
- System.Console.WriteLine("[" + sender + "] ");
- System.Console.Write("[");
- try
- {
- System.Console.ForegroundColor = color;
- System.Console.Write(sender);
- System.Console.ResetColor();
- }
- catch (ArgumentNullException)
- {
- // Some older systems dont support coloured text.
- System.Console.WriteLine(sender);
- }
- System.Console.Write("] \t");
- }
- }
- catch (ObjectDisposedException)
- {
- }
- }
- private void Help(string module, string[] cmd)
- {
- List<string> help = Commands.GetHelp(cmd);
- foreach (string s in help)
- Output(s);
- }
- private void Show()
- {
- lock (cmdline)
- {
- if (y == -1 || System.Console.BufferWidth == 0)
- return;
- int xc = prompt.Length + cp;
- int new_x = xc % System.Console.BufferWidth;
- int new_y = y + xc / System.Console.BufferWidth;
- int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
- if (end_y / System.Console.BufferWidth >= h)
- h++;
- if (end_y >= System.Console.BufferHeight) // wrap
- {
- y--;
- new_y--;
- System.Console.CursorLeft = 0;
- System.Console.CursorTop = System.Console.BufferHeight-1;
- System.Console.WriteLine(" ");
- }
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- if (echo)
- System.Console.Write("{0}{1}", prompt, cmdline);
- else
- System.Console.Write("{0}", prompt);
- SetCursorLeft(new_x);
- SetCursorTop(new_y);
- }
- }
- public void LockOutput()
- {
- Monitor.Enter(cmdline);
- try
- {
- if (y != -1)
- {
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
- int count = cmdline.Length + prompt.Length;
- while (count-- > 0)
- System.Console.Write(" ");
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
- }
- }
- catch (Exception)
- {
- }
- }
- public void UnlockOutput()
- {
- if (y != -1)
- {
- y = System.Console.CursorTop;
- Show();
- }
- Monitor.Exit(cmdline);
- }
- public void Output(string text)
- {
- lock (cmdline)
- {
- if (y == -1)
- {
- System.Console.WriteLine(text);
- return;
- }
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
- int count = cmdline.Length + prompt.Length;
- while (count-- > 0)
- System.Console.Write(" ");
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
- System.Console.WriteLine(text);
- y = System.Console.CursorTop;
- Show();
- }
- }
- private bool ContextHelp()
- {
- string[] words = Parser.Parse(cmdline.ToString());
- bool trailingSpace = cmdline.ToString().EndsWith(" ");
- // Allow ? through while typing a URI
- //
- if (words.Length > 0 && words[words.Length-1].StartsWith("http") && !trailingSpace)
- return false;
- string[] opts = Commands.FindNextOption(words, trailingSpace);
- if (opts[0].StartsWith("Command help:"))
- Output(opts[0]);
- else
- Output(String.Format("Options: {0}", String.Join(" ", opts)));
- return true;
- }
- public void Prompt()
- {
- string line = ReadLine(m_defaultPrompt, true, true);
- if (line != String.Empty)
- {
- m_log.Info("Invalid command");
- }
- }
- public string CmdPrompt(string p)
- {
- return ReadLine(String.Format("{0}: ", p), false, true);
- }
- public string CmdPrompt(string p, string def)
- {
- string ret = ReadLine(String.Format("{0} [{1}]: ", p, def), false, true);
- if (ret == String.Empty)
- ret = def;
- return ret;
- }
- // Displays a command prompt and returns a default value, user may only enter 1 of 2 options
- public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB)
- {
- bool itisdone = false;
- string temp = CmdPrompt(prompt, defaultresponse);
- while (itisdone == false)
- {
- if ((temp == OptionA) || (temp == OptionB))
- {
- itisdone = true;
- }
- else
- {
- System.Console.WriteLine("Valid options are " + OptionA + " or " + OptionB);
- temp = CmdPrompt(prompt, defaultresponse);
- }
- }
- return temp;
- }
- // Displays a prompt and waits for the user to enter a string, then returns that string
- // (Done with no echo and suitable for passwords)
- public string PasswdPrompt(string p)
- {
- return ReadLine(p, false, false);
- }
- public void RunCommand(string cmd)
- {
- string[] parts = Parser.Parse(cmd);
- Commands.Resolve(parts);
- }
- public string ReadLine(string p, bool isCommand, bool e)
- {
- h = 1;
- cp = 0;
- prompt = p;
- echo = e;
- int historyLine = history.Count;
- if (gui)
- {
- System.Console.Write("{0}", prompt);
- string cmdinput = System.Console.ReadLine();
- if (isCommand)
- {
- string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
- if (cmd.Length != 0)
- {
- int i;
- for (i=0 ; i < cmd.Length ; i++)
- {
- if (cmd[i].Contains(" "))
- cmd[i] = "\"" + cmd[i] + "\"";
- }
- return String.Empty;
- }
- }
- return cmdinput;
- }
- System.Console.CursorLeft = 0; // Needed for mono
- System.Console.Write(" "); // Needed for mono
- lock (cmdline)
- {
- y = System.Console.CursorTop;
- cmdline.Remove(0, cmdline.Length);
- }
- while (true)
- {
- Show();
- ConsoleKeyInfo key = System.Console.ReadKey(true);
- char c = key.KeyChar;
- if (!Char.IsControl(c))
- {
- if (cp >= 318)
- continue;
- if (c == '?' && isCommand)
- {
- if (ContextHelp())
- continue;
- }
- cmdline.Insert(cp, c);
- cp++;
- }
- else
- {
- switch (key.Key)
- {
- case ConsoleKey.Backspace:
- if (cp == 0)
- break;
- cmdline.Remove(cp-1, 1);
- cp--;
- System.Console.CursorLeft = 0;
- y = SetCursorTop(y);
- System.Console.Write("{0}{1} ", prompt, cmdline);
- break;
- case ConsoleKey.End:
- cp = cmdline.Length;
- break;
- case ConsoleKey.Home:
- cp = 0;
- break;
- case ConsoleKey.UpArrow:
- if (historyLine < 1)
- break;
- historyLine--;
- LockOutput();
- cmdline.Remove(0, cmdline.Length);
- cmdline.Append(history[historyLine]);
- cp = cmdline.Length;
- UnlockOutput();
- break;
- case ConsoleKey.DownArrow:
- if (historyLine >= history.Count)
- break;
- historyLine++;
- LockOutput();
- if (historyLine == history.Count)
- {
- cmdline.Remove(0, cmdline.Length);
- }
- else
- {
- cmdline.Remove(0, cmdline.Length);
- cmdline.Append(history[historyLine]);
- }
- cp = cmdline.Length;
- UnlockOutput();
- break;
- case ConsoleKey.LeftArrow:
- if (cp > 0)
- cp--;
- break;
- case ConsoleKey.RightArrow:
- if (cp < cmdline.Length)
- cp++;
- break;
- case ConsoleKey.Enter:
- System.Console.CursorLeft = 0;
- y = SetCursorTop(y);
- System.Console.WriteLine("{0}{1}", prompt, cmdline);
- lock (cmdline)
- {
- y = -1;
- }
- if (isCommand)
- {
- string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
- if (cmd.Length != 0)
- {
- int i;
- for (i=0 ; i < cmd.Length ; i++)
- {
- if (cmd[i].Contains(" "))
- cmd[i] = "\"" + cmd[i] + "\"";
- }
- AddToHistory(String.Join(" ", cmd));
- return String.Empty;
- }
- }
- AddToHistory(cmdline.ToString());
- return cmdline.ToString();
- default:
- break;
- }
- }
- }
- }
- }
- }
|