File indexing completed on 2024-05-12 11:58:35

0001 /*
0002     SPDX-FileCopyrightText: 2008-2009 Erlend Hamberg <ehamberg@gmail.com>
0003     SPDX-FileCopyrightText: 2009 Paul Gideon Dann <pdgiddie@gmail.com>
0004     SPDX-FileCopyrightText: 2011 Svyatoslav Kuzmich <svatoslav1@gmail.com>
0005     SPDX-FileCopyrightText: 2012-2013 Simon St James <kdedevel@etotheipiplusone.com>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #ifndef KATEVI_NORMAL_VI_MODE_H
0011 #define KATEVI_NORMAL_VI_MODE_H
0012 
0013 #include <vimode/command.h>
0014 #include <vimode/modes/modebase.h>
0015 #include <vimode/motion.h>
0016 #include <vimode/range.h>
0017 
0018 #include <QHash>
0019 #include <QRegularExpression>
0020 #include <QStack>
0021 #include <QVector>
0022 
0023 #include <vector>
0024 
0025 #include <ktexteditor/range.h>
0026 #include <ktexteditor_export.h>
0027 
0028 class QKeyEvent;
0029 class KateViInputMode;
0030 
0031 namespace KateVi
0032 {
0033 class KeyParser;
0034 class InputModeManager;
0035 
0036 /**
0037  * Commands for the vi normal mode
0038  */
0039 class KTEXTEDITOR_EXPORT NormalViMode : public ModeBase
0040 {
0041     Q_OBJECT
0042 
0043     friend KateViInputMode;
0044 
0045 public:
0046     explicit NormalViMode(InputModeManager *viInputModeManager, KTextEditor::ViewPrivate *view, KateViewInternal *viewInternal);
0047     ~NormalViMode() override;
0048 
0049     bool handleKeypress(const QKeyEvent *e) override;
0050 
0051     bool commandEnterInsertMode();
0052     bool commandEnterInsertModeAppend();
0053     bool commandEnterInsertModeAppendEOL();
0054     bool commandEnterInsertModeBeforeFirstNonBlankInLine();
0055     bool commandEnterInsertModeLast();
0056 
0057     bool commandEnterVisualMode();
0058     bool commandEnterVisualLineMode();
0059     bool commandEnterVisualBlockMode();
0060     bool commandReselectVisual();
0061     bool commandToOtherEnd();
0062 
0063     bool commandEnterReplaceMode();
0064 
0065     bool commandDelete();
0066     bool commandDeleteToEOL();
0067     bool commandDeleteLine();
0068 
0069     bool commandMakeLowercase();
0070     bool commandMakeLowercaseLine();
0071     bool commandMakeUppercase();
0072     bool commandMakeUppercaseLine();
0073     bool commandChangeCase();
0074     bool commandChangeCaseRange();
0075     bool commandChangeCaseLine();
0076 
0077     bool commandOpenNewLineUnder();
0078     bool commandOpenNewLineOver();
0079 
0080     bool commandJoinLines();
0081 
0082     bool commandChange();
0083     bool commandChangeLine();
0084     bool commandChangeToEOL();
0085     bool commandSubstituteChar();
0086     bool commandSubstituteLine();
0087 
0088     bool commandYank();
0089     bool commandYankLine();
0090     bool commandYankToEOL();
0091 
0092     bool commandPaste();
0093     bool commandPasteBefore();
0094 
0095     bool commandgPaste();
0096     bool commandgPasteBefore();
0097 
0098     bool commandIndentedPaste();
0099     bool commandIndentedPasteBefore();
0100 
0101     bool commandDeleteChar();
0102     bool commandDeleteCharBackward();
0103 
0104     bool commandReplaceCharacter();
0105 
0106     bool commandSwitchToCmdLine();
0107     bool commandSearchBackward();
0108     bool commandSearchForward();
0109     bool commandUndo();
0110     bool commandRedo();
0111 
0112     bool commandSetMark();
0113 
0114     bool commandIndentLine();
0115     bool commandUnindentLine();
0116     bool commandIndentLines();
0117     bool commandUnindentLines();
0118 
0119     bool commandScrollPageDown();
0120     bool commandScrollPageUp();
0121     bool commandScrollHalfPageUp();
0122     bool commandScrollHalfPageDown();
0123 
0124     bool commandCenterView(bool onFirst);
0125     bool commandCenterViewOnNonBlank();
0126     bool commandCenterViewOnCursor();
0127     bool commandTopView(bool onFirst);
0128     bool commandTopViewOnNonBlank();
0129     bool commandTopViewOnCursor();
0130     bool commandBottomView(bool onFirst);
0131     bool commandBottomViewOnNonBlank();
0132     bool commandBottomViewOnCursor();
0133 
0134     bool commandAbort();
0135 
0136     bool commandPrintCharacterCode();
0137 
0138     bool commandRepeatLastChange();
0139 
0140     bool commandAlignLine();
0141     bool commandAlignLines();
0142 
0143     bool commandAddToNumber();
0144     bool commandSubtractFromNumber();
0145 
0146     bool commandPrependToBlock();
0147     bool commandAppendToBlock();
0148 
0149     bool commandGoToNextJump();
0150     bool commandGoToPrevJump();
0151 
0152     bool commandSwitchToLeftView();
0153     bool commandSwitchToUpView();
0154     bool commandSwitchToDownView();
0155     bool commandSwitchToRightView();
0156     bool commandSwitchToNextView();
0157 
0158     bool commandSplitHoriz();
0159     bool commandSplitVert();
0160     bool commandCloseView();
0161 
0162     bool commandSwitchToNextTab();
0163     bool commandSwitchToPrevTab();
0164 
0165     bool commandFormatLine();
0166     bool commandFormatLines();
0167 
0168     bool commandCollapseToplevelNodes();
0169     bool commandCollapseLocal();
0170     bool commandExpandAll();
0171     bool commandExpandLocal();
0172     bool commandToggleRegionVisibility();
0173 
0174     bool commandStartRecordingMacro();
0175     bool commandReplayMacro();
0176 
0177     bool commandCloseWrite();
0178     bool commandCloseNocheck();
0179 
0180     // MOTIONS
0181 
0182     Range motionLeft();
0183     Range motionRight();
0184     Range motionDown();
0185     Range motionUp();
0186 
0187     Range motionPageDown();
0188     Range motionPageUp();
0189     Range motionHalfPageDown();
0190     Range motionHalfPageUp();
0191 
0192     Range motionUpToFirstNonBlank();
0193     Range motionDownToFirstNonBlank();
0194 
0195     Range motionWordForward();
0196     Range motionWordBackward();
0197     Range motionWORDForward();
0198     Range motionWORDBackward();
0199 
0200     Range motionToEndOfWord();
0201     Range motionToEndOfWORD();
0202     Range motionToEndOfPrevWord();
0203     Range motionToEndOfPrevWORD();
0204 
0205     Range motionFindChar();
0206     Range motionFindCharBackward();
0207     Range motionToChar();
0208     Range motionToCharBackward();
0209     Range motionRepeatlastTF();
0210     Range motionRepeatlastTFBackward();
0211 
0212     Range motionToEOL();
0213     Range motionToColumn0();
0214     Range motionToFirstCharacterOfLine();
0215 
0216     Range motionToLineFirst();
0217     Range motionToLineLast();
0218 
0219     Range motionToScreenColumn();
0220 
0221     Range motionToMark();
0222     Range motionToMarkLine();
0223 
0224     Range motionToMatchingItem();
0225 
0226     Range motionToPreviousBraceBlockStart();
0227     Range motionToNextBraceBlockStart();
0228     Range motionToPreviousBraceBlockEnd();
0229     Range motionToNextBraceBlockEnd();
0230 
0231     Range motionToNextOccurrence();
0232     Range motionToPrevOccurrence();
0233 
0234     Range motionToFirstLineOfWindow();
0235     Range motionToMiddleLineOfWindow();
0236     Range motionToLastLineOfWindow();
0237 
0238     Range motionToNextVisualLine();
0239     Range motionToPrevVisualLine();
0240 
0241     Range motionToPreviousSentence();
0242     Range motionToNextSentence();
0243 
0244     Range motionToBeforeParagraph();
0245     Range motionToAfterParagraph();
0246 
0247     Range motionToIncrementalSearchMatch();
0248 
0249     // TEXT OBJECTS
0250 
0251     Range textObjectAWord();
0252     Range textObjectInnerWord();
0253     Range textObjectAWORD();
0254     Range textObjectInnerWORD();
0255 
0256     Range textObjectInnerSentence();
0257     Range textObjectASentence();
0258 
0259     Range textObjectInnerParagraph();
0260     Range textObjectAParagraph();
0261 
0262     Range textObjectAQuoteDouble();
0263     Range textObjectInnerQuoteDouble();
0264 
0265     Range textObjectAQuoteSingle();
0266     Range textObjectInnerQuoteSingle();
0267 
0268     Range textObjectABackQuote();
0269     Range textObjectInnerBackQuote();
0270 
0271     Range textObjectAParen();
0272     Range textObjectInnerParen();
0273 
0274     Range textObjectABracket();
0275     Range textObjectInnerBracket();
0276 
0277     Range textObjectACurlyBracket();
0278     Range textObjectInnerCurlyBracket();
0279 
0280     Range textObjectAInequalitySign();
0281     Range textObjectInnerInequalitySign();
0282 
0283     Range textObjectAComma();
0284     Range textObjectInnerComma();
0285 
0286     virtual void reset();
0287 
0288     void beginMonitoringDocumentChanges();
0289 
0290 protected:
0291     void resetParser();
0292     QRegularExpression generateMatchingItemRegex() const;
0293     void executeCommand(const Command *cmd);
0294     OperationMode getOperationMode() const;
0295 
0296     void highlightYank(const Range &range, const OperationMode mode = CharWise);
0297     void addHighlightYank(KTextEditor::Range range);
0298 
0299     bool motionWillBeUsedWithCommand() const
0300     {
0301         return !m_awaitingMotionOrTextObject.isEmpty();
0302     };
0303 
0304     void joinLines(unsigned int from, unsigned int to) const;
0305     void reformatLines(unsigned int from, unsigned int to) const;
0306     bool executeKateCommand(const QString &command);
0307 
0308     /**
0309      * Get the index of the first non-blank character from the given line.
0310      *
0311      * @param line The line to be picked. The current line will picked instead
0312      * if this parameter is set to a negative value.
0313      * @returns the index of the first non-blank character from the given line.
0314      * If a non-space character cannot be found, the 0 is returned.
0315      */
0316     int getFirstNonBlank(int line = -1) const;
0317 
0318     Range textObjectComma(bool inner) const;
0319     void shrinkRangeAroundCursor(Range &toShrink, const Range &rangeToShrinkTo) const;
0320     KTextEditor::Cursor findSentenceStart();
0321     KTextEditor::Cursor findSentenceEnd();
0322     KTextEditor::Cursor findParagraphStart();
0323     KTextEditor::Cursor findParagraphEnd();
0324 
0325     /**
0326      * Return commands available for this mode.
0327      * Overwritten in sub classes to replace them, must be a stable reference!
0328      */
0329     virtual const std::vector<Command> &commands();
0330 
0331     /**
0332      * Return motions available for this mode.
0333      * Overwritten in sub classes to replace them, must be a stable reference!
0334      */
0335     virtual const std::vector<Motion> &motions();
0336 
0337 protected:
0338     // The 'current position' is the current cursor position for non-linewise pastes, and the current
0339     // line for linewise.
0340     enum PasteLocation { AtCurrentPosition, AfterCurrentPosition };
0341     bool paste(NormalViMode::PasteLocation pasteLocation, bool isgPaste, bool isIndentedPaste);
0342     static KTextEditor::Cursor cursorPosAtEndOfPaste(const KTextEditor::Cursor pasteLocation, const QString &pastedText);
0343 
0344 protected:
0345     QString m_keys;
0346     QString m_lastTFcommand; // holds the last t/T/f/F command so that it can be repeated with ;/,
0347 
0348     unsigned int m_countTemp;
0349     int m_motionOperatorIndex;
0350     int m_scroll_count_limit;
0351 
0352     QVector<int> m_matchingCommands;
0353     QVector<int> m_matchingMotions;
0354     QStack<int> m_awaitingMotionOrTextObject;
0355 
0356     bool m_findWaitingForChar;
0357     bool m_isRepeatedTFcommand;
0358     bool m_linewiseCommand;
0359     bool m_commandWithMotion;
0360     bool m_lastMotionWasLinewiseInnerBlock;
0361     bool m_motionCanChangeWholeVisualModeSelection;
0362     bool m_commandShouldKeepSelection;
0363     bool m_deleteCommand;
0364     // Ctrl-c or ESC have been pressed, leading to a call to reset().
0365     bool m_pendingResetIsDueToExit;
0366     bool m_isUndo;
0367     bool waitingForRegisterOrCharToSearch();
0368 
0369     // item matching ('%' motion)
0370     QHash<QString, QString> m_matchingItems;
0371     QRegularExpression m_matchItemRegex;
0372 
0373     KeyParser *m_keyParser;
0374 
0375     KTextEditor::Attribute::Ptr m_highlightYankAttribute;
0376     QSet<KTextEditor::MovingRange *> m_highlightedYanks;
0377     QSet<KTextEditor::MovingRange *> &highlightedYankForDocument();
0378 
0379     KTextEditor::Cursor m_currentChangeEndMarker;
0380     KTextEditor::Cursor m_positionWhenIncrementalSearchBegan;
0381 
0382 private Q_SLOTS:
0383     void textInserted(KTextEditor::Document *document, KTextEditor::Range range);
0384     void textRemoved(KTextEditor::Document *, KTextEditor::Range);
0385     void undoBeginning();
0386     void undoEnded();
0387 
0388     void updateYankHighlightAttrib();
0389     void clearYankHighlight();
0390     void aboutToDeleteMovingInterfaceContent();
0391 };
0392 
0393 }
0394 
0395 #endif /* KATEVI_NORMAL_VI_MODE_H */