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 */