}
prefix_ unsigned senf::term::BaseEditor::width()
+ const
{
return terminal_->width();
}
prefix_ unsigned senf::term::BaseEditor::height()
+ const
{
return terminal_->height();
}
///////////////////////////////////////////////////////////////////////////
prefix_ senf::term::LineEditor::LineEditor(AbstractTerminal & terminal, AcceptCallback cb)
- : BaseEditor(terminal), enabled_ (true), prompt_ ("$"), promptWidth_ (1u), editWidth_ (0u),
+ : BaseEditor(terminal), enabled_ (false), prompt_ ("$"), promptWidth_ (1u), editWidth_ (0u),
text_ (""), point_ (0u), displayPos_ (0u), lastKey_ (0u), callback_ (cb), historyPoint_ (0u)
{
defineKey(KeyParser::Return, &bindings::accept);
if (enabled_)
return;
enabled_ = true;
+ for (unsigned n (0); n < auxDisplay_.size(); ++n) {
+ toLine(n+1);
+ put(auxDisplay_[n]);
+ }
+ toLine(0);
forceRedisplay();
}
{
if (! enabled_)
return;
+ reset();
clearLine();
enabled_ = false;
}
if (enabled_)
newline();
hide();
- pushHistory(text_);
+ pushHistory(text_, true);
callback_(text_);
clear();
}
redisplay();
}
-prefix_ void senf::term::LineEditor::pushHistory(std::string const & text)
+prefix_ void senf::term::LineEditor::pushHistory(std::string const & text, bool accept)
{
if (! text.empty()
- && (historyPoint_ == history_.size() || history_[historyPoint_] != text)
+ && (accept || historyPoint_ == history_.size() || history_[historyPoint_] != text)
&& (history_.empty() || history_.back() != text)) {
history_.push_back(text);
while (history_.size() > MAX_HISTORY_SIZE)
history_.erase(history_.begin());
- historyPoint_ = history_.size() - 1;
+ if (accept)
+ historyPoint_ = history_.size() - 1;
}
}
}
}
-prefix_ void senf::term::LineEditor::auxDisplay(int line, std::string const & text)
+prefix_ void senf::term::LineEditor::auxDisplay(unsigned line, std::string const & text)
{
toLine(line+1);
clearLine();
put(text);
+ while (auxDisplay_.size() < line+1)
+ auxDisplay_.push_back("");
+ auxDisplay_[line] = text;
}
prefix_ unsigned senf::term::LineEditor::maxAuxDisplayHeight()
prefix_ void senf::term::LineEditor::clearAuxDisplay()
{
reset();
+ auxDisplay_.clear();
}
prefix_ std::string const & senf::term::LineEditor::text()
if (!BaseEditor::cb_init())
return false;
prompt(prompt_);
- forceRedisplay();
+ show();
return true;
}
editor.accept();
}
+prefix_ void senf::term::bindings::acceptWithRepeat(LineEditor & editor)
+{
+ if (editor.text().empty()) {
+ editor.prevHistory();
+ editor.forceRedisplay();
+ }
+ editor.accept();
+}
+
prefix_ void senf::term::bindings::backwardDeleteChar(LineEditor & editor)
{
unsigned p (editor.point());
{
typedef std::vector<std::string> Completions;
+ std::string text (editor.text());
Completions completions;
- completer(editor, 0, editor.point(), completions);
+ unsigned b (0);
+ unsigned e (editor.point());
+ std::string prefix;
+ completer(editor, b, e, prefix, completions);
if (completions.empty())
return;
+ if (e > text.size())
+ e = text.size();
+ if (b > e)
+ b = e;
// Find common start string of all completions
unsigned commonStart (completions[0].size());
}
// Replace to-be-completed string with the common start string shared by all completions
- std::string text (editor.text());
- std::string completion (completions[0].substr(0, commonStart));
+ std::string completion (prefix+completions[0].substr(0, commonStart));
bool didComplete (false);
- if (text.substr(0, editor.point()) != completion) {
- text.erase(0, editor.point());
- text.insert(0, completion);
+ if (text.substr(b, e) != completion) {
+ text.erase(b, e);
+ text.insert(b, completion);
didComplete = true;
}
- // If completion is already unique, make sure completion is followed by a space and place cursor
- // after that space
- if (completions.size() == 1u) {
- if (text.size() <= commonStart || text[commonStart] != ' ')
- text.insert(commonStart, " ");
- editor.set(text, commonStart + 1);
- return;
- }
-
- // Otherwise place cursor directly after the partial completion
- editor.set(text, commonStart);
- if (didComplete)
+ // Otherwise place cursor directly after the (possibly partial) completion
+ editor.set(text, b+prefix.size()+commonStart);
+ if (didComplete || completions.size() == 1)
return;
// Text was not changed, show list of possible completions
Completions::iterator i (completions.begin());
for (unsigned row (0); row < nRows; ++row) {
std::string line;
- for (unsigned column (0); column < nColumns && i != completions.end(); ++column) {
+ for (unsigned column (0); column < nColumns && i != completions.end(); ++column, ++i) {
std::string entry (colWidth, ' ');
- if (i->size() > colWidth-2)
- std::copy(i->begin(), i->begin()+colWidth-2, entry.begin());
- else
- std::copy(i->begin(), i->end(), entry.begin());
+ std::copy(i->begin(),
+ i->size() > colWidth-2 ? i->begin()+colWidth-2 : i->end(),
+ entry.begin());
line += entry;
- ++i;
}
editor.auxDisplay(row, line);
}