d654a3578ffd650214430436f84b7caff72278c7
[senf.git] / Utils / Termlib / Editor.hh
1 // $Id$
2 //
3 // Copyright (C) 2009 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Editor public header */
25
26 #ifndef HH_SENF_Utils_Termlib_Editor_
27 #define HH_SENF_Utils_Termlib_Editor_ 1
28
29 // Custom includes
30 #include <map>
31 #include <vector>
32 #include <string>
33 #include <senf/Scheduler/ClockService.hh>
34 #include <senf/Scheduler/TimerEvent.hh>
35 #include "AbstractTerminal.hh"
36 #include "Terminfo.hh"
37
38 //#include "Editor.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42 namespace term {
43
44     class BaseEditor
45         : public AbstractTerminal::Callbacks
46     {
47     public:
48         typedef KeyParser::keycode_t keycode_t;
49
50         static unsigned const DEFAULT_KEY_TIMEOUT_MS = 500u;
51
52         explicit BaseEditor(AbstractTerminal & terminal);
53
54         void newline();                 ///< Move to beginning of a new, empty line
55         void toColumn(unsigned c);      ///< Move cursor to column \p c
56         void put(char ch);              ///< Write \p ch at current column
57         void put(std::string const & text);
58         void clearLine();               ///< Clear current line and move cursor to first column
59         void setBold();                 ///< Set bold char display
60         void setNormal();               ///< Set normal char display
61         void maybeClrScr();             ///< Clear screen if possible
62
63         unsigned currentColumn() const; ///< Return number of current column
64         unsigned width();
65
66     protected:
67         virtual bool cb_init();
68         virtual void cb_windowSizeChanged();
69
70     private:
71         virtual void v_keyReceived(keycode_t key) = 0;
72
73         virtual void cb_charReceived(char c);
74
75         void keySequenceTimeout();
76         void processKeys();
77
78         void write(char ch);
79         void write(std::string const & s);
80         
81         AbstractTerminal * terminal_;
82         Terminfo tifo_;
83         KeyParser keyParser_;
84         std::string inputBuffer_;
85         ClockService::clock_type keyTimeout_;
86         scheduler::TimerEvent timer_;
87         unsigned column_;
88     };
89
90     class LineEditor
91         : public BaseEditor
92     {
93     public:
94         ///////////////////////////////////////////////////////////////////////////
95         // Types
96
97         typedef boost::function<void (LineEditor&)> KeyBinding;
98         typedef boost::function<void (std::string const &)> AcceptCallback;
99
100         static unsigned const MAX_HISTORY_SIZE = 1024u;
101
102         ///////////////////////////////////////////////////////////////////////////
103
104         LineEditor(AbstractTerminal & terminal, AcceptCallback cb);
105         
106         ///////////////////////////////////////////////////////////////////////////
107
108         void prompt(std::string const & text);
109         void set(std::string const & text, unsigned pos = 0u);
110
111         // Overall edit control
112         void show();
113         void hide();
114         void accept();
115         void clear();
116         void redisplay();
117         void forceRedisplay();
118         
119         // Cursor and display movement
120         void gotoChar(unsigned n);
121         void scrollTo(unsigned n);
122
123         // Text manipulation
124         void deleteChar(unsigned n=1);
125         void insert(char ch);
126         void insert(std::string const & text);
127
128         // History
129         void pushHistory(std::string const & text);
130         void prevHistory();
131         void nextHistory();
132
133         // Get information
134         std::string const & text();
135         unsigned point();
136         unsigned displayPos();
137         keycode_t lastKey();
138
139         // Key bindings
140         void defineKey(keycode_t key, KeyBinding binding);
141         void unsetKey(keycode_t key);
142         
143     private:
144         virtual bool cb_init();
145         virtual void cb_windowSizeChanged();
146         virtual void v_keyReceived(keycode_t key);
147
148         typedef std::map<keycode_t, KeyBinding> KeyMap;
149         typedef std::vector<std::string> History;
150
151         bool enabled_;
152         bool redisplayNeeded_;
153         std::string prompt_;
154         unsigned promptWidth_;
155         unsigned editWidth_;
156         std::string text_;
157         unsigned point_;
158         unsigned displayPos_;
159         keycode_t lastKey_;
160         AcceptCallback callback_;
161         KeyMap bindings_;
162         History history_;
163         unsigned historyPoint_;
164     };
165
166 namespace bindings {
167
168     void selfInsertCommand   (LineEditor & editor);
169     void forwardChar         (LineEditor & editor);
170     void backwardChar        (LineEditor & editor);
171     void accept              (LineEditor & editor);
172     void backwardDeleteChar  (LineEditor & editor);
173     void deleteChar          (LineEditor & editor);
174     void beginningOfLine     (LineEditor & editor);
175     void endOfLine           (LineEditor & editor);
176     void deleteToEndOfLine   (LineEditor & editor);
177     void restartEdit         (LineEditor & editor);
178     void prevHistory         (LineEditor & editor);
179     void nextHistory         (LineEditor & editor);
180     void clearScreen         (LineEditor & editor);
181
182 }
183
184 }}
185
186 ///////////////////////////////hh.e////////////////////////////////////////
187 //#include "Editor.cci"
188 //#include "Editor.ct"
189 //#include "Editor.cti"
190 #endif
191
192 \f
193 // Local Variables:
194 // mode: c++
195 // fill-column: 100
196 // comment-column: 40
197 // c-file-style: "senf"
198 // indent-tabs-mode: nil
199 // ispell-local-dictionary: "american"
200 // compile-command: "scons -u test"
201 // End: