29 using System.Collections.Generic;
30 using System.Diagnostics;
31 using System.Reflection;
33 using System.Text.RegularExpressions;
34 using System.Threading;
39 namespace OpenSim.Framework.Console
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 private string m_historyPath;
48 private bool m_historyEnable;
51 private const string LOGLEVEL_NONE =
"(none)";
54 private Regex m_categoryRegex
56 @"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)", RegexOptions.Singleline | RegexOptions.Compiled);
58 private int m_cursorYPosition = -1;
59 private int m_cursorXPosition = 0;
60 private StringBuilder m_commandLine =
new StringBuilder();
61 private bool m_echo =
true;
62 private List<string> m_history =
new List<string>();
64 private static readonly ConsoleColor[] Colors = {
80 private static ConsoleColor DeriveColor(
string input)
83 return Colors[(Math.Abs(input.ToUpper().GetHashCode()) % Colors.Length)];
86 public LocalConsole(
string defaultPrompt, IConfig startupConfig = null) : base(defaultPrompt)
89 if (startupConfig == null)
return;
91 m_historyEnable = startupConfig.GetBoolean(
"ConsoleHistoryFileEnabled",
false);
94 m_log.Info(
"[LOCAL CONSOLE]: Persistent command line history from file is Disabled");
98 string m_historyFile = startupConfig.GetString(
"ConsoleHistoryFile",
"OpenSimConsoleHistory.txt");
99 int m_historySize = startupConfig.GetInt(
"ConsoleHistoryFileLines", 100);
100 m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile));
101 m_log.InfoFormat(
"[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath);
103 if (
File.Exists(m_historyPath))
105 using (StreamReader history_file =
new StreamReader(m_historyPath))
108 while ((line = history_file.ReadLine()) != null)
114 if (m_history.Count > m_historySize)
116 while (m_history.Count > m_historySize)
117 m_history.RemoveAt(0);
119 using (StreamWriter history_file =
new StreamWriter(m_historyPath))
121 foreach (
string line
in m_history)
123 history_file.WriteLine(line);
127 m_log.InfoFormat(
"[LOCAL CONSOLE]: Read {0} lines of command line history from file {1}", m_history.Count, m_historyPath);
131 m_log.InfoFormat(
"[LOCAL CONSOLE]: Creating new empty command line history file {0}", m_historyPath);
132 File.Create(m_historyPath).Dispose();
136 private void AddToHistory(
string text)
138 while (m_history.Count >= 100)
139 m_history.RemoveAt(0);
144 File.AppendAllText(m_historyPath, text + Environment.NewLine);
159 private int SetCursorTop(
int top)
164 int left = System.Console.CursorLeft;
168 System.Console.CursorLeft = 0;
172 int bufferWidth = System.Console.BufferWidth;
175 if (bufferWidth > 0 && left >= bufferWidth)
176 System.Console.CursorLeft = bufferWidth - 1;
185 int bufferHeight = System.Console.BufferHeight;
188 if (bufferHeight > 0 && top >= bufferHeight)
189 top = bufferHeight - 1;
192 System.Console.CursorTop = top;
208 private int SetCursorLeft(
int left)
213 int top = System.Console.CursorTop;
217 System.Console.CursorTop = 0;
221 int bufferHeight = System.Console.BufferHeight;
223 if (bufferHeight > 0 && top >= bufferHeight)
224 System.Console.CursorTop = bufferHeight - 1;
233 int bufferWidth = System.Console.BufferWidth;
236 if (bufferWidth > 0 && left >= bufferWidth)
237 left = bufferWidth - 1;
240 System.Console.CursorLeft = left;
249 if (m_cursorYPosition == -1 || System.Console.BufferWidth == 0)
252 int xc = prompt.Length + m_cursorXPosition;
253 int new_x = xc % System.Console.BufferWidth;
254 int new_y = m_cursorYPosition + xc / System.Console.BufferWidth;
255 int end_y = m_cursorYPosition + (m_commandLine.Length + prompt.Length) / System.Console.BufferWidth;
257 if (end_y >= System.Console.BufferHeight)
262 SetCursorTop(System.Console.BufferHeight - 1);
263 System.Console.WriteLine(
" ");
266 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
270 System.Console.Write(
"{0}{1}", prompt, m_commandLine);
272 System.Console.Write(
"{0}", prompt);
275 SetCursorLeft(new_x);
281 Monitor.Enter(m_commandLine);
284 if (m_cursorYPosition != -1)
286 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
287 System.Console.CursorLeft = 0;
289 int count = m_commandLine.Length + prompt.Length;
292 System.Console.Write(
" ");
294 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
305 if (m_cursorYPosition != -1)
307 m_cursorYPosition = System.Console.CursorTop;
310 Monitor.Exit(m_commandLine);
313 private void WriteColorText(ConsoleColor color,
string sender)
321 System.Console.ForegroundColor = color;
322 System.Console.Write(sender);
323 System.Console.ResetColor();
325 catch (ArgumentNullException)
328 System.Console.WriteLine(sender);
332 catch (ObjectDisposedException)
337 private void WriteLocalText(
string text,
string level)
339 string outText = text;
341 if (level != LOGLEVEL_NONE)
343 MatchCollection matches = m_categoryRegex.Matches(text);
345 if (matches.Count == 1)
347 outText = matches[0].Groups[
"End"].Value;
348 System.Console.Write(matches[0].Groups[
"Front"].Value);
350 System.Console.Write(
"[");
351 WriteColorText(DeriveColor(matches[0].Groups[
"Category"].Value),
352 matches[0].Groups[
"Category"].Value);
353 System.Console.Write(
"]:");
357 outText = outText.Trim();
361 if (level ==
"error")
362 WriteColorText(ConsoleColor.Red, outText);
363 else if (level ==
"warn")
364 WriteColorText(ConsoleColor.Yellow, outText);
366 System.Console.Write(outText);
368 System.Console.WriteLine();
373 Output(text, LOGLEVEL_NONE);
376 public override void Output(
string text,
string level)
382 if (m_cursorYPosition == -1)
384 WriteLocalText(text, level);
389 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
392 int count = m_commandLine.Length + prompt.Length;
395 System.Console.Write(
" ");
397 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
400 WriteLocalText(text, level);
402 m_cursorYPosition = System.Console.CursorTop;
408 private bool ContextHelp()
410 string[] words = Parser.Parse(m_commandLine.ToString());
412 bool trailingSpace = m_commandLine.ToString().EndsWith(
" ");
416 if (words.Length > 0 && words[words.Length-1].StartsWith(
"http") && !trailingSpace)
419 string[] opts = Commands.FindNextOption(words, trailingSpace);
421 if (opts[0].StartsWith(
"Command help:"))
424 Output(String.Format(
"Options: {0}", String.Join(
" ", opts)));
429 public override string ReadLine(
string p,
bool isCommand,
bool e)
431 m_cursorXPosition = 0;
434 int historyLine = m_history.Count;
437 System.Console.Write(
" ");
441 m_cursorYPosition = System.Console.CursorTop;
442 m_commandLine.Remove(0, m_commandLine.Length);
449 ConsoleKeyInfo
key = System.Console.ReadKey(
true);
450 char enteredChar = key.KeyChar;
452 if (!Char.IsControl(enteredChar))
454 if (m_cursorXPosition >= 318)
457 if (enteredChar ==
'?' && isCommand)
463 m_commandLine.Insert(m_cursorXPosition, enteredChar);
470 case ConsoleKey.Backspace:
471 if (m_cursorXPosition == 0)
473 m_commandLine.Remove(m_cursorXPosition-1, 1);
477 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
480 System.Console.Write(
"{0}{1} ", prompt, m_commandLine);
482 System.Console.Write(
"{0}", prompt);
485 case ConsoleKey.Delete:
486 if (m_cursorXPosition == m_commandLine.Length)
489 m_commandLine.Remove(m_cursorXPosition, 1);
492 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
495 System.Console.Write(
"{0}{1} ", prompt, m_commandLine);
497 System.Console.Write(
"{0}", prompt);
501 m_cursorXPosition = m_commandLine.Length;
503 case ConsoleKey.Home:
504 m_cursorXPosition = 0;
506 case ConsoleKey.UpArrow:
511 m_commandLine.Remove(0, m_commandLine.Length);
512 m_commandLine.Append(m_history[historyLine]);
513 m_cursorXPosition = m_commandLine.Length;
516 case ConsoleKey.DownArrow:
517 if (historyLine >= m_history.Count)
521 if (historyLine == m_history.Count)
523 m_commandLine.Remove(0, m_commandLine.Length);
527 m_commandLine.Remove(0, m_commandLine.Length);
528 m_commandLine.Append(m_history[historyLine]);
530 m_cursorXPosition = m_commandLine.Length;
533 case ConsoleKey.LeftArrow:
534 if (m_cursorXPosition > 0)
537 case ConsoleKey.RightArrow:
538 if (m_cursorXPosition < m_commandLine.Length)
541 case ConsoleKey.Enter:
543 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
545 System.Console.WriteLine();
550 m_cursorYPosition = -1;
553 string commandLine = m_commandLine.ToString();
557 string[] cmd = Commands.Resolve(Parser.Parse(commandLine));
563 for (index=0 ; index < cmd.Length ; index++)
565 if (cmd[index].Contains(
" "))
566 cmd[index] =
"\"" + cmd[index] +
"\"";
568 AddToHistory(String.Join(
" ", cmd));
574 if (m_echo && commandLine !=
"")
575 AddToHistory(commandLine);
override void Output(string text, string level)
override void Output(string text)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
override void LockOutput()
override void UnlockOutput()
A console that uses cursor control and color
LocalConsole(string defaultPrompt, IConfig startupConfig=null)
override string ReadLine(string p, bool isCommand, bool e)
A console that processes commands internally