45 , chunks(1, make_pair(rgb, 0))
51 chunks.push_back(make_pair(rgb, line.size()));
52 line.append(text.
data(), text.
size());
67 return unsigned(chunks.size());
72 assert(i < chunks.size());
73 return chunks[i].first;
78 assert(i < chunks.size());
79 auto pos = chunks[i].second;
80 auto len = ((i + 1) == chunks.size())
82 : chunks[i + 1].second - pos;
95 auto begin = line.begin();
98 while (len-- && (end != line.end())) {
101 result.line.assign(begin, end);
103 unsigned bpos = begin - line.begin();
104 unsigned bend = end - line.begin();
106 while ((i < chunks.size()) && (chunks[i].second <= bpos)) {
109 result.chunks.push_back(make_pair(chunks[i - 1].first, 0));
110 while ((i < chunks.size()) && (chunks[i].second < bend)) {
111 result.chunks.push_back(make_pair(chunks[i].first,
112 chunks[i].second - bpos));
120 static const char*
const PROMPT_NEW =
"> ";
121 static const char*
const PROMPT_CONT =
"| ";
122 static const char*
const PROMPT_BUSY =
"*busy*";
128 : commandController(commandController_)
129 , eventDistributor(eventDistributor_)
132 commandController,
"console",
133 "turns console display on/off", false,
Setting::DONT_SAVE))
135 commandController,
"console_history_size",
136 "amount of commands kept in console history", 100, 0, 10000))
138 commandController,
"console_remove_doubles",
139 "don't add the command to history if it's the same as the previous one",
141 , executingCommand(false)
145 newLineConsole(prompt);
152 print(
string(fullVersion.size(),
'-'));
154 "General information about openMSX is available at "
155 "http://www.openmsx.org.\n"
157 "Type 'help' to see a list of available commands "
158 "(use <PgUp>/<PgDn> to scroll).\n"
159 "Or read the Console Command Reference in the manual.\n"
178 void CommandConsole::saveHistory()
182 std::ofstream outputfile;
184 context.resolveCreate(
"history.txt"));
187 "Error while saving the console history.");
189 for (
auto& s : history) {
192 }
catch (FileException& e) {
197 void CommandConsole::loadHistory()
200 UserFileContext context(
"console");
201 std::ifstream inputfile(
202 context.resolveCreate(
"history.txt").c_str());
205 "Error while loading the console history.");
209 getline(inputfile, line);
211 putCommandHistory(prompt + line);
214 }
catch (FileException& e) {
222 return *consoleSetting.get();
228 unsigned num = lines[0].numChars() /
getColumns();
229 yPosition = num - (cursorPosition /
getColumns());
234 return consoleScrollBack;
241 count += (lines[buf].numChars() /
getColumns()) + 1;
243 return lines[buf].substr(
251 int CommandConsole::signalEvent(
const std::shared_ptr<const Event>& event)
253 auto& keyEvent = checked_cast<
const KeyEvent&>(*event);
254 if (!consoleSetting->getValue()) {
264 if (!executingCommand) {
265 if (handleEvent(keyEvent)) {
284 bool CommandConsole::handleEvent(
const KeyEvent& keyEvent)
286 auto keyCode = keyEvent.getKeyCode();
289 word chr = keyEvent.getUnicode();
299 cursorPosition = unsigned(prompt.size());
302 cursorPosition = lines[0].numChars();
315 scroll(max<int>(
getRows() - 1, 1));
318 scroll(-max<int>(
getRows() - 1, 1));
359 cursorPosition = unsigned(prompt.size());
362 if (cursorPosition > prompt.size()) {
367 if (cursorPosition < lines[0].numChars()) {
372 cursorPosition = unsigned(prompt.size());
375 cursorPosition = lines[0].numChars();
417 unsigned CommandConsole::getOutputColumns()
const
422 void CommandConsole::print(
string_ref text,
unsigned rgb)
425 auto pos = text.
find(
'\n');
426 newLineConsole(ConsoleLine(text.
substr(0, pos), rgb));
428 text = text.
substr(pos + 1);
429 if (text.
empty())
return;
433 void CommandConsole::newLineConsole(
string_ref line)
435 newLineConsole(ConsoleLine(line));
438 void CommandConsole::newLineConsole(ConsoleLine line)
443 ConsoleLine tmp = lines[0];
448 void CommandConsole::putCommandHistory(
const string& command)
451 if (command == prompt) {
454 if (removeDoublesSetting->getValue() && !history.empty()
455 && (history.back() == command)) {
459 history.push_back(command);
462 while (history.size() > unsigned(historySizeSetting->getValue())) {
467 void CommandConsole::commandExecute()
470 putCommandHistory(lines[0].str());
473 commandBuffer += lines[0].str().substr(prompt.size()) +
'\n';
474 newLineConsole(lines[0]);
475 if (commandController.
isComplete(commandBuffer)) {
480 prompt = PROMPT_BUSY;
487 if (!result.empty()) {
490 }
catch (CommandException& e) {
491 print(e.getMessage(), 0xff0000);
493 commandBuffer.clear();
496 prompt = PROMPT_CONT;
501 ConsoleLine CommandConsole::highLight(
string_ref line)
506 result.addChunk(prompt, 0xffffff);
510 assert(colors.size() == command.size());
513 while (pos != colors.size()) {
514 char col = colors[pos];
515 unsigned pos2 = pos++;
516 while ((pos != colors.size()) && (colors[pos] == col)) {
522 case 'E': rgb = 0xff0000;
break;
523 case 'c': rgb = 0x5c5cff;
break;
524 case 'v': rgb = 0x00ffff;
break;
525 case 'l': rgb = 0xff00ff;
break;
526 case 'p': rgb = 0xcdcd00;
break;
527 case 'o': rgb = 0x00cdcd;
break;
528 default: rgb = 0xffffff;
break;
530 result.addChunk(command.substr(pos2, pos - pos2), rgb);
535 void CommandConsole::putPrompt()
537 commandScrollBack = history.end();
538 currentLine = prompt;
539 lines[0] = highLight(currentLine);
540 cursorPosition = unsigned(prompt.size());
543 void CommandConsole::tabCompletion()
546 unsigned pl = unsigned(prompt.size());
551 currentLine = prompt + newFront + back;
552 lines[0] = highLight(currentLine);
555 void CommandConsole::scroll(
int delta)
557 consoleScrollBack = min(max(consoleScrollBack + delta, 0),
561 void CommandConsole::prevCommand()
564 if (history.empty()) {
568 auto tempScrollBack = commandScrollBack;
569 while ((tempScrollBack != history.begin()) && !match) {
574 commandScrollBack = tempScrollBack;
575 lines[0] = highLight(*commandScrollBack);
576 cursorPosition = lines[0].numChars();
580 void CommandConsole::nextCommand()
583 if (commandScrollBack == history.end()) {
587 auto tempScrollBack = commandScrollBack;
588 while ((++tempScrollBack != history.end()) && !match) {
593 commandScrollBack = tempScrollBack;
594 lines[0] = highLight(*commandScrollBack);
596 commandScrollBack = history.end();
597 lines[0] = highLight(currentLine);
599 cursorPosition = lines[0].numChars();
602 void CommandConsole::clearCommand()
605 commandBuffer.clear();
607 currentLine = prompt;
608 lines[0] = highLight(currentLine);
609 cursorPosition = unsigned(prompt.size());
612 void CommandConsole::backspace()
615 if (cursorPosition > prompt.size()) {
616 currentLine = lines[0].str();
617 auto begin = currentLine.begin();
621 currentLine.erase(begin, end);
622 lines[0] = highLight(currentLine);
627 void CommandConsole::delete_key()
630 if (lines[0].numChars() > cursorPosition) {
631 currentLine = lines[0].str();
632 auto begin = currentLine.begin();
636 currentLine.erase(begin, end);
637 lines[0] = highLight(currentLine);
641 void CommandConsole::normalKey(
word chr)
645 currentLine = lines[0].str();
646 auto pos = currentLine.begin();
649 lines[0] = highLight(currentLine);
653 void CommandConsole::resetScrollBack()
655 consoleScrollBack = 0;