00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef HH_SENF_Utils_Termlib_Editor_
00027 #define HH_SENF_Utils_Termlib_Editor_ 1
00028
00029
00030 #include <map>
00031 #include <vector>
00032 #include <string>
00033 #include <senf/Scheduler/ClockService.hh>
00034 #include <senf/Scheduler/TimerEvent.hh>
00035 #include "AbstractTerminal.hh"
00036 #include "Terminfo.hh"
00037
00038
00039
00040
00041 namespace senf {
00042 namespace term {
00043
00060 class BaseEditor
00061 : public AbstractTerminal::Callbacks
00062 {
00063 public:
00064 typedef KeyParser::keycode_t keycode_t;
00065
00066 static unsigned const DEFAULT_KEY_TIMEOUT_MS = 500u;
00067
00068 explicit BaseEditor(AbstractTerminal & terminal);
00069
00070 void newline();
00071 void toColumn(unsigned c);
00072 void put(char ch);
00073 void put(std::string const & text);
00074 void clearLine();
00075 void setBold();
00076 void setNormal();
00077 void maybeClrScr();
00078
00079 void toLine(unsigned l);
00080 void reset();
00081
00082 unsigned currentColumn() const;
00083 unsigned currentLine() const;
00084 unsigned width() const;
00085 unsigned height() const;
00086
00087 protected:
00088 virtual bool cb_init();
00089 virtual void cb_windowSizeChanged();
00091
00092 #ifndef DOXYGEN
00093 private:
00094 #endif
00095 virtual void v_keyReceived(keycode_t key) = 0;
00096
00097 private:
00098 virtual void cb_charReceived(char c);
00099
00100 void keySequenceTimeout();
00101 void processKeys();
00102
00103 void write(char ch);
00104 void write(std::string const & s);
00105
00106 AbstractTerminal * terminal_;
00107 Terminfo tifo_;
00108 KeyParser keyParser_;
00109 std::string inputBuffer_;
00110 ClockService::clock_type keyTimeout_;
00111 scheduler::TimerEvent timer_;
00112 unsigned column_;
00113 unsigned displayHeight_;
00114 unsigned line_;
00115 };
00116
00211 class LineEditor
00212 : public BaseEditor
00213 {
00214 public:
00215
00216
00217
00218 typedef boost::function<void (LineEditor&)> KeyBinding;
00219 typedef boost::function<void (std::string const &)> AcceptCallback;
00221
00222 static unsigned const MAX_HISTORY_SIZE = 1024u;
00223
00224
00225
00226 LineEditor(AbstractTerminal & terminal, AcceptCallback cb);
00228
00232
00233
00235
00236
00237 void show();
00238 void hide();
00239 void accept();
00240 void clear();
00241 void redisplay();
00242 void forceRedisplay();
00243 void prompt(std::string const & text);
00244
00245
00246
00248
00249
00250 void gotoChar(unsigned n);
00251 void scrollTo(unsigned n);
00252
00253
00254
00256
00257
00258 void deleteChar(unsigned n=1);
00259 void insert(char ch);
00260 void insert(std::string const & text);
00261 void set(std::string const & text, unsigned pos = 0u);
00263
00267
00268
00270
00271
00272 void pushHistory(std::string const & text, bool accept = false);
00274 void prevHistory();
00275 void nextHistory();
00276
00277
00278
00280
00281
00282 void auxDisplay(unsigned line, std::string const & text);
00284 unsigned maxAuxDisplayHeight();
00285 void clearAuxDisplay();
00286
00287
00288
00290
00291
00292 std::string const & text();
00293 unsigned point();
00294 unsigned displayPos();
00295 keycode_t lastKey();
00296
00297
00298
00300
00301
00302 void defineKey(keycode_t key, KeyBinding binding);
00304 void unsetKey(keycode_t key);
00305
00306
00307
00308 private:
00309 virtual bool cb_init();
00310 virtual void cb_windowSizeChanged();
00311 virtual void v_keyReceived(keycode_t key);
00312
00313 typedef std::map<keycode_t, KeyBinding> KeyMap;
00314 typedef std::vector<std::string> History;
00315 typedef std::vector<std::string> AuxDisplay;
00316
00317 bool enabled_;
00318 bool redisplayNeeded_;
00319 std::string prompt_;
00320 unsigned promptWidth_;
00321 unsigned editWidth_;
00322 std::string text_;
00323 unsigned point_;
00324 unsigned displayPos_;
00325 keycode_t lastKey_;
00326 AcceptCallback callback_;
00327 KeyMap bindings_;
00328 History history_;
00329 unsigned historyPoint_;
00330 AuxDisplay auxDisplay_;
00331 };
00332
00335 namespace bindings {
00336
00337 void selfInsertCommand (LineEditor & editor);
00338 void forwardChar (LineEditor & editor);
00339 void backwardChar (LineEditor & editor);
00340 void accept (LineEditor & editor);
00341 void acceptWithRepeat (LineEditor & editor);
00342 void backwardDeleteChar (LineEditor & editor);
00343 void deleteChar (LineEditor & editor);
00344 void beginningOfLine (LineEditor & editor);
00345 void endOfLine (LineEditor & editor);
00346 void deleteToEndOfLine (LineEditor & editor);
00347 void restartEdit (LineEditor & editor);
00348 void prevHistory (LineEditor & editor);
00349 void nextHistory (LineEditor & editor);
00350 void clearScreen (LineEditor & editor);
00351
00352 typedef boost::function<void (LineEditor &, unsigned & b, unsigned & e,
00353 std::string & prefix, std::vector<std::string> &)> Completer;
00354 void complete (LineEditor & editor, Completer completer);
00356
00363 }
00364
00365 }}
00366
00367
00368
00369
00370
00371 #endif
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382