File indexing completed on 2024-04-28 07:47:06

0001 /*
0002     SPDX-FileCopyrightText: 2008 Erlend Hamberg <ehamberg@gmail.com>
0003     SPDX-FileCopyrightText: 2011 Svyatoslav Kuzmich <svatoslav1@gmail.com>
0004     SPDX-FileCopyrightText: 2012-2013 Simon St James <kdedevel@etotheipiplusone.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef KATEVI_INPUT_MODE_MANAGER_H
0010 #define KATEVI_INPUT_MODE_MANAGER_H
0011 
0012 #include <QKeyEvent>
0013 #include <QStack>
0014 #include <ktexteditor/cursor.h>
0015 #include <ktexteditor/view.h>
0016 #include <ktexteditor_export.h>
0017 
0018 #include <vimode/completion.h>
0019 #include <vimode/definitions.h>
0020 
0021 class KConfigGroup;
0022 class KateViewInternal;
0023 class KateViInputMode;
0024 class QString;
0025 
0026 namespace KTextEditor
0027 {
0028 class ViewPrivate;
0029 class DocumentPrivate;
0030 class MovingCursor;
0031 class Mark;
0032 class MarkInterface;
0033 }
0034 
0035 namespace KateVi
0036 {
0037 class GlobalState;
0038 class Searcher;
0039 class CompletionRecorder;
0040 class CompletionReplayer;
0041 class Marks;
0042 class Jumps;
0043 class MacroRecorder;
0044 class LastChangeRecorder;
0045 class ModeBase;
0046 class NormalViMode;
0047 class InsertViMode;
0048 class VisualViMode;
0049 class ReplaceViMode;
0050 class KeyParser;
0051 class KeyMapper;
0052 
0053 class InputModeManager
0054 {
0055     friend KateViInputMode;
0056 
0057 public:
0058     InputModeManager(KateViInputMode *inputAdapter, KTextEditor::ViewPrivate *view, KateViewInternal *viewInternal);
0059     ~InputModeManager();
0060     InputModeManager(const InputModeManager &) = delete;
0061     InputModeManager &operator=(const InputModeManager &) = delete;
0062 
0063     /**
0064      * feed key the given key press to the command parser
0065      * @return true if keypress was is [part of a] command, false otherwise
0066      */
0067     bool handleKeypress(const QKeyEvent *e);
0068 
0069     /**
0070      * feed key the given list of key presses to the key handling code, one by one
0071      */
0072     void feedKeyPresses(const QString &keyPresses) const;
0073 
0074     /**
0075      * Determines whether we are currently processing a Vi keypress
0076      * @return true if we are still in a call to handleKeypress, false otherwise
0077      */
0078     bool isHandlingKeypress() const;
0079 
0080     /**
0081      * @return The current vi mode
0082      */
0083     KTEXTEDITOR_EXPORT ViMode getCurrentViMode() const;
0084 
0085     /**
0086      * @return The current vi mode string representation
0087      */
0088     KTextEditor::View::ViewMode getCurrentViewMode() const;
0089 
0090     /**
0091      * @return the previous vi mode
0092      */
0093     ViMode getPreviousViMode() const;
0094 
0095     /**
0096      * @return true if and only if the current mode is one of VisualMode, VisualBlockMode or VisualLineMode.
0097      */
0098     bool isAnyVisualMode() const;
0099 
0100     /**
0101      * @return one of getViNormalMode(), getViVisualMode(), etc, depending on getCurrentViMode().
0102      */
0103     ModeBase *getCurrentViModeHandler() const;
0104 
0105     const QString getVerbatimKeys() const;
0106 
0107     /**
0108      * changes the current vi mode to the given mode
0109      */
0110     void changeViMode(ViMode newMode);
0111 
0112     /**
0113      * set normal mode to be the active vi mode and perform the needed setup work
0114      */
0115     KTEXTEDITOR_EXPORT void viEnterNormalMode();
0116 
0117     /**
0118      * set insert mode to be the active vi mode and perform the needed setup work
0119      */
0120     void viEnterInsertMode();
0121 
0122     /**
0123      * set visual mode to be the active vi mode and make the needed setup work
0124      */
0125     void viEnterVisualMode(ViMode visualMode = ViMode::VisualMode);
0126 
0127     /**
0128      * set replace mode to be the active vi mode and make the needed setup work
0129      */
0130     void viEnterReplaceMode();
0131 
0132     /**
0133      * @return the NormalMode instance
0134      */
0135     NormalViMode *getViNormalMode();
0136 
0137     /**
0138      * @return the InsertMode instance
0139      */
0140     InsertViMode *getViInsertMode();
0141 
0142     /**
0143      * @return the VisualMode instance
0144      */
0145     VisualViMode *getViVisualMode();
0146 
0147     /**
0148      * @return the ReplaceMode instance
0149      */
0150     ReplaceViMode *getViReplaceMode();
0151 
0152     /**
0153      * clear the key event log
0154      */
0155     void clearCurrentChangeLog();
0156 
0157     /**
0158      * copy the contents of the key events log to m_lastChange so that it can be repeated
0159      */
0160     void storeLastChangeCommand();
0161 
0162     /**
0163      * repeat last change by feeding the contents of m_lastChange to feedKeys()
0164      */
0165     void repeatLastChange();
0166 
0167     void doNotLogCurrentKeypress();
0168 
0169     bool getTemporaryNormalMode()
0170     {
0171         return m_temporaryNormalMode;
0172     }
0173 
0174     void setTemporaryNormalMode(bool b)
0175     {
0176         m_temporaryNormalMode = b;
0177     }
0178 
0179     void reset();
0180 
0181     inline Marks *marks()
0182     {
0183         return m_marks;
0184     }
0185     inline Jumps *jumps()
0186     {
0187         return m_jumps;
0188     }
0189 
0190     inline Searcher *searcher()
0191     {
0192         return m_searcher;
0193     }
0194 
0195     CompletionRecorder *completionRecorder()
0196     {
0197         return m_completionRecorder;
0198     }
0199     CompletionReplayer *completionReplayer()
0200     {
0201         return m_completionReplayer;
0202     }
0203 
0204     MacroRecorder *macroRecorder()
0205     {
0206         return m_macroRecorder;
0207     }
0208 
0209     LastChangeRecorder *lastChangeRecorder()
0210     {
0211         return m_lastChangeRecorder;
0212     }
0213 
0214     // session stuff
0215     void readSessionConfig(const KConfigGroup &config);
0216     void writeSessionConfig(KConfigGroup &config);
0217 
0218     KTEXTEDITOR_EXPORT KeyMapper *keyMapper();
0219     GlobalState *globalState() const;
0220     KTextEditor::ViewPrivate *view() const;
0221 
0222     KateViInputMode *inputAdapter()
0223     {
0224         return m_inputAdapter;
0225     }
0226 
0227     void updateCursor(const KTextEditor::Cursor c);
0228 
0229     void pushKeyMapper(std::shared_ptr<KeyMapper> mapper);
0230     void popKeyMapper();
0231 
0232 private:
0233     NormalViMode *m_viNormalMode;
0234     InsertViMode *m_viInsertMode;
0235     VisualViMode *m_viVisualMode;
0236     ReplaceViMode *m_viReplaceMode;
0237 
0238     ViMode m_currentViMode;
0239     ViMode m_previousViMode;
0240 
0241     KateViInputMode *m_inputAdapter;
0242     KTextEditor::ViewPrivate *m_view;
0243     KateViewInternal *m_viewInternal;
0244     KeyParser *m_keyParser;
0245 
0246     // Create a new keymapper for each macro event, to simplify expansion of mappings in macros
0247     // where the macro itself was triggered by expanding a mapping!
0248     QStack<std::shared_ptr<KeyMapper>> m_keyMapperStack;
0249 
0250     int m_insideHandlingKeyPressCount;
0251 
0252     /**
0253      * a list of the (encoded) key events that was part of the last change.
0254      */
0255     QString m_lastChange;
0256 
0257     CompletionList m_lastChangeCompletionsLog;
0258 
0259     /**
0260      * true when normal mode was started by Ctrl-O command in insert mode.
0261      */
0262     bool m_temporaryNormalMode;
0263 
0264     Marks *m_marks;
0265     Jumps *m_jumps;
0266 
0267     Searcher *m_searcher;
0268     CompletionRecorder *m_completionRecorder;
0269     CompletionReplayer *m_completionReplayer;
0270 
0271     MacroRecorder *m_macroRecorder;
0272 
0273     LastChangeRecorder *m_lastChangeRecorder;
0274 };
0275 
0276 }
0277 
0278 #endif