PageRenderTime 29ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/console/prompt.d

http://github.com/wilkie/djehuty
D | 298 lines | 191 code | 72 blank | 35 comment | 60 complexity | 187e8f6fb99c08bbf04a90531dc89caf MD5 | raw file
  1. module console.prompt;
  2. import djehuty;
  3. import io.console;
  4. import core.definitions;
  5. import data.queue;
  6. // Section: Console
  7. // Description: This class provides a line input field for a console application. This class can buffer the previous lines much like that of a modern shell.
  8. class Prompt {
  9. // TODO: Allow ANSI emulated prompt strings
  10. this() {
  11. _prompt = "";
  12. }
  13. // Description: This will set the prompt string that will precede the input.
  14. // prompt: A string representing the prompt.
  15. void prompt(string prompt) {
  16. _prompt = prompt.dup;
  17. }
  18. // Description: This function will return the current prompt.
  19. // Returns: The current prompt.
  20. string prompt() {
  21. return _prompt.dup;
  22. }
  23. void promptColor(Color fgClr) {
  24. _promptClr = fgClr;
  25. }
  26. void forecolor(Color fgClr) {
  27. _clr = fgClr;
  28. }
  29. // Description: This function will set the amount of lines the line buffer stores. The line buffer will scroll through the most recent lines inputted by the user. This function will also turn off the line buffer if the size is 0.
  30. // bufferSize: The number of lines to store. Setting this to zero will turn off the buffer. There is a maximum of 5000.
  31. void bufferSize(uint bufferSize) {
  32. if (bufferSize > 5000) {
  33. bufferSize = 5000;
  34. }
  35. if (bufferSize != 0) {
  36. _lineBuffer = new Queue!(string)();
  37. }
  38. else {
  39. _lineBuffer = null;
  40. }
  41. _bufferSize = bufferSize;
  42. }
  43. // Description: This will display the prompt and return the line typed by the user.
  44. // Returns: The line typed by the user.
  45. string line() {
  46. // the current displayed line
  47. string line;
  48. // the 'working' line being edited
  49. string workingLine;
  50. // Print out the prompt string
  51. Console.forecolor = _promptClr;
  52. Console.put(_prompt);
  53. // Go into a key loop, wait for a return
  54. // On any special key, fire the callback and expect a result (for instance, on TAB)
  55. // When we are allowed, up and down can signify the use of the line buffer
  56. dchar chr;
  57. uint code;
  58. line = "";
  59. workingLine = line;
  60. if (_lineBuffer !is null) {
  61. _bufferPos = -1;
  62. }
  63. Console.forecolor = _clr;
  64. for(;;) {
  65. Console.getChar(chr, code);
  66. if (code == Key.Return) {
  67. // enter
  68. _pos = 0;
  69. break;
  70. }
  71. else if (code == Key.Backspace) {
  72. // backspace
  73. if (line.length > 0 && _pos > 0) {
  74. Console.put(chr);
  75. Console.put(' ');
  76. Console.put(chr);
  77. if (_pos == line.length) {
  78. line = line.substring(0, line.length-1);
  79. }
  80. else {
  81. string newLine = line.substring(0, _pos-1);
  82. string restLine = line.substring(_pos);
  83. newLine ~= restLine;
  84. Console.put(restLine);
  85. Console.put(' ');
  86. for (uint i=0; i<=restLine.length; i++) {
  87. Console.put(cast(char)0x8);
  88. }
  89. line = newLine;
  90. }
  91. if (_lineBuffer !is null) {
  92. _bufferPos = -1;
  93. }
  94. workingLine = line;
  95. _pos--;
  96. }
  97. }
  98. else if (code == Key.Left) {
  99. if (_pos > 0) {
  100. Console.put(cast(char)0x8);
  101. _pos--;
  102. }
  103. }
  104. else if (code == Key.Right) {
  105. if (_pos < line.length) {
  106. Console.setRelative(1,0);
  107. _pos++;
  108. }
  109. }
  110. else if (code == Key.Up) {
  111. // The current line is still stored
  112. // And then the line buffer spits out
  113. // the previous line submitted
  114. if (_lineBuffer !is null) {
  115. if (_bufferPos+1 < cast(int)_lineBuffer.length && _lineBuffer.length > 0) {
  116. // grab the line from the line buffer
  117. _bufferPos++;
  118. line = _lineBuffer.peekAt(_bufferPos);
  119. uint i;
  120. if (line.length < _pos) {
  121. for (i=line.length; i<_pos; i++) {
  122. Console.put(cast(char)0x8);
  123. Console.put(' ');
  124. Console.put(cast(char)0x8);
  125. }
  126. _pos = line.length;
  127. }
  128. for (i=0; i<_pos; i++) {
  129. Console.put(cast(char)0x8);
  130. }
  131. // print the line
  132. Console.put(line);
  133. _pos = line.length;
  134. }
  135. }
  136. }
  137. else if (code == Key.Down) {
  138. // The current line is still stored
  139. // And then the line buffer spits out
  140. // the next line submitted
  141. if (_lineBuffer !is null) {
  142. if (_bufferPos > 0) {
  143. // grab the line from the line buffer
  144. _bufferPos--;
  145. line = _lineBuffer.peekAt(_bufferPos);
  146. }
  147. else {
  148. // redisplay the working line
  149. _bufferPos = -1;
  150. if (workingLine !is null) {
  151. line = workingLine;
  152. }
  153. }
  154. // goto the front of the current line, and erase the current line
  155. uint i;
  156. if (line.length < _pos) {
  157. for (i=line.length; i<_pos; i++) {
  158. Console.put(cast(char)0x8);
  159. Console.put(' ');
  160. Console.put(cast(char)0x8);
  161. }
  162. _pos = line.length;
  163. }
  164. for (i=0; i<_pos; i++) {
  165. Console.put(cast(char)0x8);
  166. }
  167. // print the line
  168. Console.put(line);
  169. // erase the rest of the previous line
  170. _pos = line.length;
  171. }
  172. }
  173. else if (chr != 0) {
  174. // written character
  175. if (_pos == line.length) {
  176. Console.put(chr);
  177. line ~= chr;
  178. }
  179. else if (_pos == 0) {
  180. string newLine = "" ~ Unicode.toUtf8([chr]) ~ line;
  181. Console.put(newLine);
  182. for (uint i=1; i<newLine.length; i++) {
  183. Console.put(cast(char)0x8);
  184. }
  185. line = newLine;
  186. }
  187. else {
  188. Console.put(chr);
  189. string leftLine = line.substring(0, _pos);
  190. leftLine ~= chr;
  191. string rightLine = line.substring(_pos);
  192. leftLine ~= rightLine;
  193. Console.put(rightLine);
  194. for (uint i=0; i<rightLine.length; i++) {
  195. Console.put(cast(char)0x8);
  196. }
  197. line = leftLine;
  198. }
  199. if (_lineBuffer !is null) {
  200. _bufferPos = -1;
  201. }
  202. workingLine = line;
  203. _pos++;
  204. }
  205. }
  206. Console.putln("");
  207. // Save line in line buffer
  208. if (_lineBuffer !is null) {
  209. if (_lineBuffer.length == _bufferSize) {
  210. _lineBuffer.remove();
  211. }
  212. _lineBuffer.add(line);
  213. _bufferPos = -1;
  214. }
  215. return line;
  216. }
  217. protected:
  218. // the prompt string, for instance "# " or "C:\>"
  219. string _prompt;
  220. Color _promptClr = Color.Gray;
  221. Color _clr = Color.Gray;
  222. Queue!(string) _lineBuffer;
  223. int _bufferSize;
  224. int _bufferPos;
  225. uint _pos;
  226. }