Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Editor.cc

Go to the documentation of this file.
00001 // $Id: Editor.cc 1772 2011-03-10 12:45:21Z tho $
00002 //
00003 // Copyright (C) 2009
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #include "Editor.hh"
00027 //#include "Editor.ih"
00028 
00029 // Custom includes
00030 #include <senf/Utils/membind.hh>
00031 #include <senf/Scheduler/Scheduler.hh>
00032 
00033 //#include "Editor.mpp"
00034 #define prefix_
00035 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00036 
00037 prefix_ senf::term::BaseEditor::BaseEditor(AbstractTerminal & terminal)
00038     : terminal_ (&terminal),
00039       keyTimeout_ (ClockService::milliseconds(DEFAULT_KEY_TIMEOUT_MS)),
00040       timer_ ("senf::term::BaseEditor::keySequenceTimeout",
00041               membind(&BaseEditor::keySequenceTimeout, this)),
00042       column_ (0u), displayHeight_ (1u), line_ (0u)
00043 {
00044     terminal_->setCallbacks(*this);
00045 }
00046 
00047 prefix_ void senf::term::BaseEditor::newline()
00048 {
00049     reset();
00050     write("\n");
00051     write(tifo_.getString(Terminfo::properties::ClrEol));
00052     column_ = 0;
00053 }
00054 
00055 prefix_ void senf::term::BaseEditor::toColumn(unsigned c)
00056 {
00057     if (c >= width())
00058         c = width();
00059     if (c > column_) {
00060         if (tifo_.hasProperty(Terminfo::properties::ParmRightCursor)) {
00061             write(tifo_.formatString(Terminfo::properties::ParmRightCursor, c - column_));
00062             column_ = c;
00063         }
00064         else {
00065             char const * cuf1 (tifo_.getString(Terminfo::properties::CursorRight));
00066             while (c > column_) {
00067                 write(cuf1);
00068                 ++column_;
00069             }
00070         }
00071     }
00072     else if (c < column_) {
00073         if (tifo_.hasProperty(Terminfo::properties::ParmLeftCursor)) {
00074             write(tifo_.formatString(Terminfo::properties::ParmLeftCursor, column_ - c));
00075             column_ = c;
00076         }
00077         else {
00078             char const * cub1 (tifo_.getString(Terminfo::properties::CursorLeft));
00079             while (c < column_) {
00080                 write(cub1);
00081                 --column_;
00082             }
00083         }
00084     }
00085 }
00086 
00087 prefix_ void senf::term::BaseEditor::put(char ch)
00088 {
00089     if (column_ >= width()-1)
00090         return;
00091     write(ch);
00092     ++ column_;
00093 }
00094 
00095 prefix_ void senf::term::BaseEditor::put(std::string const & text)
00096 {
00097     if (text.size() > width()-column_-1) {
00098         write(text.substr(0,width()-column_-1));
00099         column_ = width() - 1;
00100     }
00101     else {
00102         write(text);
00103         column_ += text.size();
00104     }
00105 }
00106 
00107 prefix_ void senf::term::BaseEditor::clearLine()
00108 {
00109     write("\r");
00110     write(tifo_.getString(Terminfo::properties::ClrEol));
00111     column_ = 0;
00112 }
00113 
00114 prefix_ void senf::term::BaseEditor::setBold()
00115 {
00116     if (tifo_.hasProperty(Terminfo::properties::EnterBoldMode) &&
00117         tifo_.hasProperty(Terminfo::properties::ExitAttributeMode))
00118         write(tifo_.getString(Terminfo::properties::EnterBoldMode));
00119 }
00120 
00121 prefix_ void senf::term::BaseEditor::setNormal()
00122 {
00123     if (tifo_.hasProperty(Terminfo::properties::EnterBoldMode) &&
00124         tifo_.hasProperty(Terminfo::properties::ExitAttributeMode))
00125         write(tifo_.getString(Terminfo::properties::ExitAttributeMode));
00126 }
00127 
00128 prefix_ void senf::term::BaseEditor::maybeClrScr()
00129 {
00130     if (tifo_.hasProperty(Terminfo::properties::ClearScreen))
00131         write(tifo_.getString(Terminfo::properties::ClearScreen));
00132 }
00133 
00134 prefix_ void senf::term::BaseEditor::toLine(unsigned l)
00135 {
00136     if (l >= height())
00137         l = height() - 1;
00138     unsigned ll (l);
00139     if (ll >= displayHeight_)
00140         ll = displayHeight_-1;
00141     if (ll > line_) {
00142         if (tifo_.hasProperty(Terminfo::properties::ParmDownCursor)) {
00143             write(tifo_.formatString(Terminfo::properties::ParmDownCursor, ll - line_));
00144             line_ = ll;
00145         }
00146         else {
00147             char const * cud1 (tifo_.getString(Terminfo::properties::CursorDown));
00148             while (ll > line_) {
00149                 write(cud1);
00150                 ++line_;
00151             }
00152         }
00153     }
00154     else if (ll < line_) {
00155         if (tifo_.hasProperty(Terminfo::properties::ParmUpCursor)) {
00156             write(tifo_.formatString(Terminfo::properties::ParmUpCursor, line_ - ll));
00157             line_ = ll;
00158         }
00159         else {
00160             char const * cuu1 (tifo_.getString(Terminfo::properties::CursorUp));
00161             while (ll < line_) {
00162                 write(cuu1);
00163                 --line_;
00164             }
00165         }
00166     }
00167     while (line_ < l) {
00168         write("\n");
00169         write(tifo_.getString(Terminfo::properties::ClrEol));
00170         ++displayHeight_;
00171         ++line_;
00172     }
00173     write('\r');
00174     column_ = 0;
00175 }
00176 
00177 prefix_ void senf::term::BaseEditor::reset()
00178 {
00179     for (unsigned i (1); i < displayHeight_; ++i) {
00180         toLine(i);
00181         clearLine();
00182     }
00183     toLine(0);
00184     displayHeight_ = 1;
00185 }
00186 
00187 prefix_ unsigned senf::term::BaseEditor::currentColumn()
00188    const
00189 {
00190     return column_;
00191 }
00192 
00193 prefix_ unsigned senf::term::BaseEditor::currentLine()
00194     const
00195 {
00196     return line_;
00197 }
00198 
00199 prefix_ bool senf::term::BaseEditor::cb_init()
00200 {
00201     try {
00202         tifo_.load(terminal_->terminalType());
00203         keyParser_.load(tifo_);
00204     }
00205     catch (Terminfo::InvalidTerminfoException & ex) {
00206         return false;
00207     }
00208 
00209     typedef Terminfo::properties p;
00210     if (! (tifo_.hasProperty(p::ClrEol) &&
00211            (tifo_.hasProperty(p::ParmRightCursor) || tifo_.hasProperty(p::CursorRight)) &&
00212            (tifo_.hasProperty(p::ParmLeftCursor) || tifo_.hasProperty(p::CursorLeft))))
00213         return false;
00214 
00215     if (tifo_.hasProperty(Terminfo::properties::KeypadXmit))
00216         write(tifo_.getString(Terminfo::properties::KeypadXmit));
00217     return true;
00218 }
00219 
00220 prefix_ void senf::term::BaseEditor::cb_charReceived(char c)
00221 {
00222     inputBuffer_ += c;
00223     timer_.timeout(scheduler::eventTime() + keyTimeout_);
00224     processKeys();
00225 }
00226 
00227 prefix_ void senf::term::BaseEditor::cb_windowSizeChanged()
00228 {
00229     if (column_ >= width())
00230         column_ = width()-1;
00231 }
00232 
00233 prefix_ void senf::term::BaseEditor::keySequenceTimeout()
00234 {
00235     while (!inputBuffer_.empty()) {
00236         processKeys();
00237         v_keyReceived(keycode_t(inputBuffer_[0]));
00238         inputBuffer_.erase(0, 1);
00239     }
00240 }
00241 
00242 prefix_ void senf::term::BaseEditor::processKeys()
00243 {
00244     do {
00245         std::pair<KeyParser::keycode_t, std::string::size_type> result
00246             (keyParser_.lookup(inputBuffer_));
00247         if (result.first == KeyParser::Incomplete)
00248             return;
00249         v_keyReceived(result.first);
00250         inputBuffer_.erase(0, result.second);
00251     } while (! inputBuffer_.empty());
00252     timer_.disable();
00253 }
00254 
00255 prefix_ unsigned senf::term::BaseEditor::width()
00256     const
00257 {
00258     return terminal_->width();
00259 }
00260 
00261 prefix_ unsigned senf::term::BaseEditor::height()
00262     const
00263 {
00264     return terminal_->height();
00265 }
00266 
00267 prefix_ void senf::term::BaseEditor::write(char ch)
00268 {
00269     terminal_->write(ch);
00270 }
00271 
00272 prefix_ void senf::term::BaseEditor::write(std::string const & s)
00273 {
00274     for (std::string::const_iterator i (s.begin()); i != s.end(); ++i)
00275         write(*i);
00276 }
00277 
00278 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00279 
00280 prefix_ senf::term::LineEditor::LineEditor(AbstractTerminal & terminal, AcceptCallback cb)
00281     : BaseEditor(terminal), enabled_ (false), prompt_ ("$"), promptWidth_ (1u), editWidth_ (0u),
00282       text_ (""), point_ (0u), displayPos_ (0u), lastKey_ (0u), callback_ (cb), historyPoint_ (0u)
00283 {
00284     defineKey(KeyParser::Return,    &bindings::accept);
00285     defineKey(KeyParser::Right,     &bindings::forwardChar);
00286     defineKey(KeyParser::Left,      &bindings::backwardChar);
00287     defineKey(KeyParser::Up,        &bindings::prevHistory);
00288     defineKey(KeyParser::Down,      &bindings::nextHistory);
00289     defineKey(KeyParser::Backspace, &bindings::backwardDeleteChar);
00290     defineKey(KeyParser::Delete,    &bindings::deleteChar);
00291     defineKey(KeyParser::Home,      &bindings::beginningOfLine);
00292     defineKey(KeyParser::End,       &bindings::endOfLine);
00293     defineKey(KeyParser::Ctrl('K'), &bindings::deleteToEndOfLine);
00294     defineKey(KeyParser::Ctrl('A'), &bindings::beginningOfLine);
00295     defineKey(KeyParser::Ctrl('E'), &bindings::endOfLine);
00296     defineKey(KeyParser::Ctrl('D'), &bindings::deleteChar);
00297     defineKey(KeyParser::Ctrl('C'), &bindings::restartEdit);
00298     defineKey(KeyParser::Ctrl('L'), &bindings::clearScreen);
00299 }
00300 
00301 prefix_ void senf::term::LineEditor::prompt(std::string const & text)
00302 {
00303     prompt_ = text;
00304     promptWidth_ = prompt_.size();
00305     if (promptWidth_ > width() - 4 && width() > 4)
00306         promptWidth_ = width() - 4;
00307     editWidth_ = width() - promptWidth_ - 3;
00308     if (enabled_)
00309         redisplay();
00310 }
00311 
00312 prefix_ void senf::term::LineEditor::set(std::string const & text, unsigned pos)
00313 {
00314     text_ = text;
00315     point_ = pos;
00316     if (point_ > text.size())
00317         point_ = text.size();
00318     displayPos_ = 0u;
00319     if (point_ > editWidth_)
00320         displayPos_ = point_ - editWidth_;
00321     redisplay();
00322 }
00323 
00324 prefix_ void senf::term::LineEditor::show()
00325 {
00326     if (enabled_)
00327         return;
00328     enabled_ = true;
00329     for (unsigned n (0); n < auxDisplay_.size(); ++n) {
00330         toLine(n+1);
00331         put(auxDisplay_[n]);
00332     }
00333     toLine(0);
00334     forceRedisplay();
00335 }
00336 
00337 prefix_ void senf::term::LineEditor::hide()
00338 {
00339     if (! enabled_)
00340         return;
00341     reset();
00342     clearLine();
00343     enabled_ = false;
00344 }
00345 
00346 prefix_ void senf::term::LineEditor::accept()
00347 {
00348     if (enabled_)
00349         newline();
00350     hide();
00351     pushHistory(text_, true);
00352     callback_(text_);
00353     clear();
00354 }
00355 
00356 prefix_ void senf::term::LineEditor::clear()
00357 {
00358     set("");
00359     historyPoint_ = history_.size();
00360 }
00361 
00362 prefix_ void senf::term::LineEditor::redisplay()
00363 {
00364     redisplayNeeded_ = true;
00365 }
00366 
00367 prefix_ void senf::term::LineEditor::forceRedisplay()
00368 {
00369     if (! enabled_)
00370         return;
00371     clearLine();
00372     setBold();
00373     if (prompt_.size() > promptWidth_)
00374         put(prompt_.substr(prompt_.size()-promptWidth_));
00375     else
00376         put(prompt_);
00377     put( displayPos_ > 0 ? '<' : ' ' );
00378     if (text_.size() > displayPos_ + editWidth_) {
00379         toColumn(editWidth_ + promptWidth_ + 1);
00380         put('>');
00381         toColumn(promptWidth_ + 1);
00382     }
00383     setNormal();
00384     put(text_.substr(displayPos_, editWidth_));
00385     toColumn(point_ - displayPos_ + promptWidth_ + 1);
00386     redisplayNeeded_ = false;
00387 }
00388 
00389 prefix_ void senf::term::LineEditor::gotoChar(unsigned n)
00390 {
00391     point_ = n;
00392     if (point_ > text_.size())
00393         point_ = text_.size();
00394     if (point_ < displayPos_)
00395         displayPos_ = point_;
00396     if (point_ > displayPos_+editWidth_)
00397         displayPos_ = point_-editWidth_;
00398     redisplay();
00399 }
00400 
00401 prefix_ void senf::term::LineEditor::scrollTo(unsigned n)
00402 {
00403     displayPos_ = n;
00404     if (displayPos_ > text_.size())
00405         displayPos_ = text_.size();
00406     if (point_ < displayPos_)
00407         point_ = displayPos_;
00408     if (point_ > displayPos_+editWidth_)
00409         point_ = displayPos_+editWidth_;
00410     redisplay();
00411 }
00412 
00413 prefix_ void senf::term::LineEditor::deleteChar(unsigned n)
00414 {
00415     if (point_ >= text_.size())
00416         return;
00417     text_.erase(point_, n);
00418     redisplay();
00419 }
00420 
00421 prefix_ void senf::term::LineEditor::insert(char ch)
00422 {
00423     text_.insert(point_, std::string(1, ch));
00424     gotoChar(point_+1);
00425     redisplay();
00426 }
00427 
00428 prefix_ void senf::term::LineEditor::insert(std::string const & text)
00429 {
00430     text_.insert(point_, text);
00431     gotoChar(point_+text.size());
00432     redisplay();
00433 }
00434 
00435 prefix_ void senf::term::LineEditor::pushHistory(std::string const & text, bool accept)
00436 {
00437     if (! text.empty()
00438         && (accept || historyPoint_ == history_.size() || history_[historyPoint_] != text)
00439         && (history_.empty() || history_.back() != text)) {
00440         history_.push_back(text);
00441         while (history_.size() > MAX_HISTORY_SIZE)
00442             history_.erase(history_.begin());
00443         if (accept)
00444             historyPoint_ = history_.size() - 1;
00445     }
00446 }
00447 
00448 prefix_ void senf::term::LineEditor::prevHistory()
00449 {
00450     if (historyPoint_ <= 0)
00451         return;
00452     pushHistory(text_);
00453     std::string entry (history_[--historyPoint_]);
00454     set(entry, entry.size());
00455 }
00456 
00457 prefix_ void senf::term::LineEditor::nextHistory()
00458 {
00459     if (historyPoint_ >= history_.size())
00460         return;
00461     pushHistory(text_);
00462     ++ historyPoint_;
00463     if (historyPoint_ >= history_.size())
00464         set("");
00465     else {
00466         std::string entry (history_[historyPoint_]);
00467         set(entry, entry.size());
00468     }
00469 }
00470 
00471 prefix_ void senf::term::LineEditor::auxDisplay(unsigned line, std::string const & text)
00472 {
00473     toLine(line+1);
00474     clearLine();
00475     put(text);
00476     while (auxDisplay_.size() < line+1)
00477         auxDisplay_.push_back("");
00478     auxDisplay_[line] = text;
00479 }
00480 
00481 prefix_ unsigned senf::term::LineEditor::maxAuxDisplayHeight()
00482 {
00483     return height()-1;
00484 }
00485 
00486 prefix_ void senf::term::LineEditor::clearAuxDisplay()
00487 {
00488     reset();
00489     auxDisplay_.clear();
00490 }
00491 
00492 prefix_ std::string const & senf::term::LineEditor::text()
00493 {
00494     return text_;
00495 }
00496 
00497 prefix_ unsigned senf::term::LineEditor::point()
00498 {
00499     return point_;
00500 }
00501 
00502 prefix_ unsigned senf::term::LineEditor::displayPos()
00503 {
00504     return displayPos_;
00505 }
00506 
00507 prefix_ senf::term::LineEditor::keycode_t senf::term::LineEditor::lastKey()
00508 {
00509     return lastKey_;
00510 }
00511 
00512 prefix_ void senf::term::LineEditor::defineKey(keycode_t key, KeyBinding binding)
00513 {
00514     bindings_[key] = binding;
00515 }
00516 
00517 prefix_ void senf::term::LineEditor::unsetKey(keycode_t key)
00518 {
00519     bindings_.erase(key);
00520 }
00521 
00522 prefix_ bool senf::term::LineEditor::cb_init()
00523 {
00524     if (!BaseEditor::cb_init())
00525         return false;
00526     prompt(prompt_);
00527     show();
00528     return true;
00529 }
00530 
00531 prefix_ void senf::term::LineEditor::cb_windowSizeChanged()
00532 {
00533     BaseEditor::cb_windowSizeChanged();
00534     clearAuxDisplay();
00535     prompt(prompt_);
00536     gotoChar(point_);
00537     forceRedisplay();
00538 }
00539 
00540 prefix_ void senf::term::LineEditor::v_keyReceived(keycode_t key)
00541 {
00542     if (! enabled_)
00543         return;
00544     clearAuxDisplay();
00545     lastKey_ = key;
00546     KeyMap::iterator i (bindings_.find(key));
00547     if (i != bindings_.end())
00548         i->second(*this);
00549     else if (key >= ' ' && key < 256)
00550         insert(char(key));
00551     if (currentLine() != 0)
00552         toLine(0);
00553     if (redisplayNeeded_)
00554         forceRedisplay();
00555     else
00556         toColumn(point_ - displayPos_ + promptWidth_ + 1);
00557 }
00558 
00559 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00560 
00561 prefix_ void senf::term::bindings::selfInsertCommand(LineEditor & editor)
00562 {
00563     LineEditor::keycode_t key (editor.lastKey());
00564     if (key >= ' ' && key < 256)
00565         editor.insert(key);
00566 }
00567 
00568 prefix_ void senf::term::bindings::forwardChar(LineEditor & editor)
00569 {
00570     editor.gotoChar(editor.point()+1);
00571 }
00572 
00573 prefix_ void senf::term::bindings::backwardChar(LineEditor & editor)
00574 {
00575     unsigned p (editor.point());
00576     if (p>0)
00577         editor.gotoChar(p-1);
00578 }
00579 
00580 prefix_ void senf::term::bindings::accept(LineEditor & editor)
00581 {
00582     editor.accept();
00583 }
00584 
00585 prefix_ void senf::term::bindings::acceptWithRepeat(LineEditor & editor)
00586 {
00587     if (editor.text().empty()) {
00588         editor.prevHistory();
00589         editor.forceRedisplay();
00590     }
00591     editor.accept();
00592 }
00593 
00594 prefix_ void senf::term::bindings::backwardDeleteChar(LineEditor & editor)
00595 {
00596     unsigned p (editor.point());
00597     if (p>0) {
00598         editor.gotoChar(p-1);
00599         editor.deleteChar();
00600     }
00601 }
00602 
00603 prefix_ void senf::term::bindings::deleteChar(LineEditor & editor)
00604 {
00605     editor.deleteChar();
00606 }
00607 
00608 prefix_ void senf::term::bindings::beginningOfLine(LineEditor & editor)
00609 {
00610     editor.gotoChar(0u);
00611 }
00612 
00613 prefix_ void senf::term::bindings::endOfLine(LineEditor & editor)
00614 {
00615     editor.gotoChar(editor.text().size());
00616 }
00617 
00618 prefix_ void senf::term::bindings::deleteToEndOfLine(LineEditor & editor)
00619 {
00620     editor.deleteChar(editor.text().size()-editor.point());
00621 }
00622 
00623 prefix_ void senf::term::bindings::restartEdit(LineEditor & editor)
00624 {
00625     editor.newline();
00626     editor.clear();
00627     editor.redisplay();
00628 }
00629 
00630 prefix_ void senf::term::bindings::prevHistory(LineEditor & editor)
00631 {
00632     editor.prevHistory();
00633 }
00634 
00635 prefix_ void senf::term::bindings::nextHistory(LineEditor & editor)
00636 {
00637     editor.nextHistory();
00638 }
00639 
00640 prefix_ void senf::term::bindings::clearScreen(LineEditor & editor)
00641 {
00642     editor.maybeClrScr();
00643     editor.clearLine();
00644     editor.forceRedisplay();
00645 }
00646 
00647 prefix_ void senf::term::bindings::complete(LineEditor & editor, Completer completer)
00648 {
00649     typedef std::vector<std::string> Completions;
00650 
00651     std::string text (editor.text());
00652     Completions completions;
00653     unsigned b (0);
00654     unsigned e (editor.point());
00655     std::string prefix;
00656     completer(editor, b, e, prefix, completions);
00657     if (completions.empty())
00658         return;
00659     if (e > text.size())
00660         e = text.size();
00661     if (b > e)
00662         b = e;
00663 
00664     // Find common start string of all completions
00665     unsigned commonStart (completions[0].size());
00666     unsigned maxLen (commonStart);
00667     for (Completions::const_iterator i (boost::next(completions.begin()));
00668          i != completions.end(); ++i) {
00669         if (i->size() > maxLen)
00670             maxLen = i->size();
00671         unsigned n (0u);
00672         for (; n < commonStart && n < i->size() && completions[0][n] == (*i)[n]; ++n) ;
00673         commonStart = n;
00674     }
00675 
00676     // Replace to-be-completed string with the common start string shared by all completions
00677     std::string completion (prefix+completions[0].substr(0, commonStart));
00678     bool didComplete (false);
00679     if (text.substr(b, e) != completion) {
00680         text.erase(b, e);
00681         text.insert(b, completion);
00682         didComplete = true;
00683     }
00684 
00685     // Otherwise place cursor directly after the (possibly partial) completion
00686     editor.set(text, b+prefix.size()+commonStart);
00687     if (didComplete || completions.size() == 1)
00688         return;
00689 
00690     // Text was not changed, show list of possible completions
00691     unsigned colWidth (maxLen+2);
00692     unsigned nColumns ((editor.width()-1) / colWidth);
00693     if (nColumns < 1) nColumns = 1;
00694     unsigned nRows ((completions.size()+nColumns-1) / nColumns);
00695     if (nRows > editor.maxAuxDisplayHeight()) {
00696         editor.auxDisplay(0, "(too many completions)");
00697         return;
00698     }
00699     Completions::iterator i (completions.begin());
00700     for (unsigned row (0); row < nRows; ++row) {
00701         std::string line;
00702         for (unsigned column (0); column < nColumns && i != completions.end(); ++column, ++i) {
00703             std::string entry (colWidth, ' ');
00704             std::copy(i->begin(),
00705                       i->size() > colWidth-2 ? i->begin()+colWidth-2 : i->end(),
00706                       entry.begin());
00707             line += entry;
00708         }
00709         editor.auxDisplay(row, line);
00710     }
00711 }
00712 
00713 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00714 #undef prefix_
00715 //#include "Editor.mpp"
00716 
00717 
00718 // Local Variables:
00719 // mode: c++
00720 // fill-column: 100
00721 // comment-column: 40
00722 // c-file-style: "senf"
00723 // indent-tabs-mode: nil
00724 // ispell-local-dictionary: "american"
00725 // compile-command: "scons -u test"
00726 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research