File indexing completed on 2024-05-12 15:46:28
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 */