diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2017-03-07 19:23:25 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2017-03-07 19:23:25 +0100 |
commit | 892248991babb55366860488678632ab4ccdb0ba (patch) | |
tree | e2ed43f63c21dd7e70a62ff7cd6149cc150d54cc /src/parser.h | |
parent | a2e52ca49c6a5495f134648e91647008dca4a742 (diff) | |
download | sciteco-892248991babb55366860488678632ab4ccdb0ba.tar.gz |
refactored commandline key processing: rewritten Cmdline::process_edit_cmd() as State::process_edit_cmd() virtual methods
* Cmdline::process_edit_cmd() was much too long and deeply nested.
It used RTTI excessively to implement the state-specific behaviour.
It became apparent that the behaviour is largely state-specific and could be
modelled much more elegantly as virtual methods of State.
* Basically, a state can now implement a method to customize its
commandline behaviour.
In the case that the state does not define custom behaviour for
the key pressed, it can "chain" to the parent class' process_edit_cmd().
This can be optimized to tail calls by the compiler.
* The State::process_edit_cmd() implementations are still isolated in
cmdline.cpp. This is not strictly necessary but allows us keep the
already large compilations units like parser.cpp small.
Also, the edit command processing has little to do with the rest of
a state's functionality and is only used in interactive mode.
* As a result, we have many small functions now which are much easier to
maintain.
This makes adding new and more complex context sensitive editing behaviour
easier.
* State-specific function key masking has been refactored by introducing
State::get_fnmacro_mask().
* This allowed us to remove the States::is_*() functions which have
always been a crutch to support context-sensitive key handling.
* RTTI is almost completely eradicated, except for exception handling
and StdError(). Both remaining cases can probably be avoided in the
future, allowing us to compile smaller binaries.
Diffstat (limited to 'src/parser.h')
-rw-r--r-- | src/parser.h | 106 |
1 files changed, 65 insertions, 41 deletions
diff --git a/src/parser.h b/src/parser.h index 9aa13ad..700d25f 100644 --- a/src/parser.h +++ b/src/parser.h @@ -87,6 +87,41 @@ protected: throw SyntaxError(chr); return NULL; } + +public: + /** + * Process editing command (or key press). + * + * This is part of command line handling in interactive + * mode and allows the definition of state-specific + * editing commands (behaviour on key press). + * + * By implementing this method, sub-states can either + * handle a key and return or chain to the + * parent's process_edit_cmd() implementation. + * + * All implementations of this method are defined in + * cmdline.cpp. + */ + virtual void process_edit_cmd(gchar key); + + enum fnmacroMask { + FNMACRO_MASK_START = (1 << 0), + FNMACRO_MASK_STRING = (1 << 1), + FNMACRO_MASK_DEFAULT = ~((1 << 2)-1) + }; + + /** + * Get the function key macro mask this + * state refers to. + * + * Could also be modelled as a State member. + */ + virtual fnmacroMask + get_fnmacro_mask(void) const + { + return FNMACRO_MASK_DEFAULT; + } }; template <typename Type> @@ -166,14 +201,9 @@ class StateExpectString : public State { bool string_building; bool last; -public: - /* - * FIXME: Only public as long as cmdline.cpp - * needs to access it. - * Can be avoided one process_edit_cmd() is in State. - */ StringBuildingMachine machine; +public: StateExpectString(bool _building = true, bool _last = true) : insert_len(0), nesting(1), string_building(_building), last(_last) {} @@ -182,10 +212,19 @@ private: State *custom(gchar chr); void refresh(void); + virtual fnmacroMask + get_fnmacro_mask(void) const + { + return FNMACRO_MASK_STRING; + } + protected: virtual void initial(void) {} virtual void process(const gchar *str, gint new_chars) {} virtual State *done(const gchar *str) = 0; + + /* in cmdline.cpp */ + void process_edit_cmd(gchar key); }; class StateExpectFile : public StateExpectString { @@ -198,12 +237,19 @@ private: protected: virtual State *got_file(const gchar *filename) = 0; + + /* in cmdline.cpp */ + void process_edit_cmd(gchar key); }; class StateExpectDir : public StateExpectFile { public: StateExpectDir(bool _building = true, bool _last = true) : StateExpectFile(_building, _last) {} + +protected: + /* in cmdline.cpp */ + void process_edit_cmd(gchar key); }; class StateStart : public State { @@ -222,6 +268,12 @@ private: State *custom(gchar chr); void end_of_macro(void) {} + + fnmacroMask + get_fnmacro_mask(void) const + { + return FNMACRO_MASK_START; + } }; class StateControl : public State { @@ -304,6 +356,10 @@ public: private: State *done(const gchar *str); + +protected: + /* in cmdline.cpp */ + void process_edit_cmd(gchar key); }; class StateScintilla_lParam : public StateExpectString { @@ -323,6 +379,9 @@ protected: void initial(void); void process(const gchar *str, gint new_chars); State *done(const gchar *str); + + /* in cmdline.cpp */ + void process_edit_cmd(gchar key); }; class StateInsertIndent : public StateInsert { @@ -346,41 +405,6 @@ namespace States { extern StateInsertIndent insert_indent; extern State *current; - - static inline bool - is_start() - { - /* - * The "escape" state exists only as a hack, - * to support $$. Otherwise it should behave - * like the start state. - */ - return current == &start || current == &escape; - } - - static inline bool - is_string() - { - return dynamic_cast<StateExpectString *>(current); - } - - static inline bool - is_insertion() - { - return dynamic_cast<StateInsert *>(current); - } - - static inline bool - is_file() - { - return dynamic_cast<StateExpectFile *>(current); - } - - static inline bool - is_dir() - { - return dynamic_cast<StateExpectDir *>(current); - } } extern enum Mode { |