File indexing completed on 2024-04-28 03:58:09

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