1 /* 2 SPDX-FileCopyrightText: 2008-2009 Erlend Hamberg <ehamberg@gmail.com> 3 SPDX-FileCopyrightText: 2009 Paul Gideon Dann <pdgiddie@gmail.com> 4 SPDX-FileCopyrightText: 2011 Svyatoslav Kuzmich <svatoslav1@gmail.com> 5 SPDX-FileCopyrightText: 2012-2013 Simon St James <kdedevel@etotheipiplusone.com> 6 7 SPDX-License-Identifier: LGPL-2.0-or-later 8 */ 9 10 #ifndef KATEVI_NORMAL_VI_MODE_H 11 #define KATEVI_NORMAL_VI_MODE_H 12 13 #include <vimode/command.h> 14 #include <vimode/modes/modebase.h> 15 #include <vimode/motion.h> 16 #include <vimode/range.h> 17 18 #include <QHash> 19 #include <QRegularExpression> 20 #include <QStack> 21 #include <QVector> 22 23 #include <vector> 24 25 #include <ktexteditor/range.h> 26 #include <ktexteditor_export.h> 27 28 class QKeyEvent; 29 class KateViInputMode; 30 31 namespace KateVi 32 { 33 class KeyParser; 34 class InputModeManager; 35 36 /** 37 * Commands for the vi normal mode 38 */ 39 class KTEXTEDITOR_EXPORT NormalViMode : public ModeBase 40 { 41 Q_OBJECT 42 43 friend KateViInputMode; 44 45 public: 46 explicit NormalViMode(InputModeManager *viInputModeManager, KTextEditor::ViewPrivate *view, KateViewInternal *viewInternal); 47 ~NormalViMode() override; 48 49 bool handleKeypress(const QKeyEvent *e) override; 50 51 bool commandEnterInsertMode(); 52 bool commandEnterInsertModeAppend(); 53 bool commandEnterInsertModeAppendEOL(); 54 bool commandEnterInsertModeBeforeFirstNonBlankInLine(); 55 bool commandEnterInsertModeLast(); 56 57 bool commandEnterVisualMode(); 58 bool commandEnterVisualLineMode(); 59 bool commandEnterVisualBlockMode(); 60 bool commandReselectVisual(); 61 bool commandToOtherEnd(); 62 63 bool commandEnterReplaceMode(); 64 65 bool commandDelete(); 66 bool commandDeleteToEOL(); 67 bool commandDeleteLine(); 68 69 bool commandMakeLowercase(); 70 bool commandMakeLowercaseLine(); 71 bool commandMakeUppercase(); 72 bool commandMakeUppercaseLine(); 73 bool commandChangeCase(); 74 bool commandChangeCaseRange(); 75 bool commandChangeCaseLine(); 76 77 bool commandOpenNewLineUnder(); 78 bool commandOpenNewLineOver(); 79 80 bool commandJoinLines(); 81 82 bool commandChange(); 83 bool commandChangeLine(); 84 bool commandChangeToEOL(); 85 bool commandSubstituteChar(); 86 bool commandSubstituteLine(); 87 88 bool commandYank(); 89 bool commandYankLine(); 90 bool commandYankToEOL(); 91 92 bool commandPaste(); 93 bool commandPasteBefore(); 94 95 bool commandgPaste(); 96 bool commandgPasteBefore(); 97 98 bool commandIndentedPaste(); 99 bool commandIndentedPasteBefore(); 100 101 bool commandDeleteChar(); 102 bool commandDeleteCharBackward(); 103 104 bool commandReplaceCharacter(); 105 106 bool commandSwitchToCmdLine(); 107 bool commandSearchBackward(); 108 bool commandSearchForward(); 109 bool commandUndo(); 110 bool commandRedo(); 111 112 bool commandSetMark(); 113 114 bool commandIndentLine(); 115 bool commandUnindentLine(); 116 bool commandIndentLines(); 117 bool commandUnindentLines(); 118 119 bool commandScrollPageDown(); 120 bool commandScrollPageUp(); 121 bool commandScrollHalfPageUp(); 122 bool commandScrollHalfPageDown(); 123 124 bool commandCenterView(bool onFirst); 125 bool commandCenterViewOnNonBlank(); 126 bool commandCenterViewOnCursor(); 127 bool commandTopView(bool onFirst); 128 bool commandTopViewOnNonBlank(); 129 bool commandTopViewOnCursor(); 130 bool commandBottomView(bool onFirst); 131 bool commandBottomViewOnNonBlank(); 132 bool commandBottomViewOnCursor(); 133 134 bool commandAbort(); 135 136 bool commandPrintCharacterCode(); 137 138 bool commandRepeatLastChange(); 139 140 bool commandAlignLine(); 141 bool commandAlignLines(); 142 143 bool commandAddToNumber(); 144 bool commandSubtractFromNumber(); 145 146 bool commandPrependToBlock(); 147 bool commandAppendToBlock(); 148 149 bool commandGoToNextJump(); 150 bool commandGoToPrevJump(); 151 152 bool commandSwitchToLeftView(); 153 bool commandSwitchToUpView(); 154 bool commandSwitchToDownView(); 155 bool commandSwitchToRightView(); 156 bool commandSwitchToNextView(); 157 158 bool commandSplitHoriz(); 159 bool commandSplitVert(); 160 bool commandCloseView(); 161 162 bool commandSwitchToNextTab(); 163 bool commandSwitchToPrevTab(); 164 165 bool commandFormatLine(); 166 bool commandFormatLines(); 167 168 bool commandCollapseToplevelNodes(); 169 bool commandCollapseLocal(); 170 bool commandExpandAll(); 171 bool commandExpandLocal(); 172 bool commandToggleRegionVisibility(); 173 174 bool commandStartRecordingMacro(); 175 bool commandReplayMacro(); 176 177 bool commandCloseWrite(); 178 bool commandCloseNocheck(); 179 180 // MOTIONS 181 182 Range motionLeft(); 183 Range motionRight(); 184 Range motionDown(); 185 Range motionUp(); 186 187 Range motionPageDown(); 188 Range motionPageUp(); 189 Range motionHalfPageDown(); 190 Range motionHalfPageUp(); 191 192 Range motionUpToFirstNonBlank(); 193 Range motionDownToFirstNonBlank(); 194 195 Range motionWordForward(); 196 Range motionWordBackward(); 197 Range motionWORDForward(); 198 Range motionWORDBackward(); 199 200 Range motionToEndOfWord(); 201 Range motionToEndOfWORD(); 202 Range motionToEndOfPrevWord(); 203 Range motionToEndOfPrevWORD(); 204 205 Range motionFindChar(); 206 Range motionFindCharBackward(); 207 Range motionToChar(); 208 Range motionToCharBackward(); 209 Range motionRepeatlastTF(); 210 Range motionRepeatlastTFBackward(); 211 212 Range motionToEOL(); 213 Range motionToColumn0(); 214 Range motionToFirstCharacterOfLine(); 215 216 Range motionToLineFirst(); 217 Range motionToLineLast(); 218 219 Range motionToScreenColumn(); 220 221 Range motionToMark(); 222 Range motionToMarkLine(); 223 224 Range motionToMatchingItem(); 225 226 Range motionToPreviousBraceBlockStart(); 227 Range motionToNextBraceBlockStart(); 228 Range motionToPreviousBraceBlockEnd(); 229 Range motionToNextBraceBlockEnd(); 230 231 Range motionToNextOccurrence(); 232 Range motionToPrevOccurrence(); 233 234 Range motionToFirstLineOfWindow(); 235 Range motionToMiddleLineOfWindow(); 236 Range motionToLastLineOfWindow(); 237 238 Range motionToNextVisualLine(); 239 Range motionToPrevVisualLine(); 240 241 Range motionToPreviousSentence(); 242 Range motionToNextSentence(); 243 244 Range motionToBeforeParagraph(); 245 Range motionToAfterParagraph(); 246 247 Range motionToIncrementalSearchMatch(); 248 249 // TEXT OBJECTS 250 251 Range textObjectAWord(); 252 Range textObjectInnerWord(); 253 Range textObjectAWORD(); 254 Range textObjectInnerWORD(); 255 256 Range textObjectInnerSentence(); 257 Range textObjectASentence(); 258 259 Range textObjectInnerParagraph(); 260 Range textObjectAParagraph(); 261 262 Range textObjectAQuoteDouble(); 263 Range textObjectInnerQuoteDouble(); 264 265 Range textObjectAQuoteSingle(); 266 Range textObjectInnerQuoteSingle(); 267 268 Range textObjectABackQuote(); 269 Range textObjectInnerBackQuote(); 270 271 Range textObjectAParen(); 272 Range textObjectInnerParen(); 273 274 Range textObjectABracket(); 275 Range textObjectInnerBracket(); 276 277 Range textObjectACurlyBracket(); 278 Range textObjectInnerCurlyBracket(); 279 280 Range textObjectAInequalitySign(); 281 Range textObjectInnerInequalitySign(); 282 283 Range textObjectAComma(); 284 Range textObjectInnerComma(); 285 286 virtual void reset(); 287 288 void beginMonitoringDocumentChanges(); 289 290 protected: 291 void resetParser(); 292 void initializeCommands(); 293 QRegularExpression generateMatchingItemRegex() const; 294 void executeCommand(const Command *cmd); 295 OperationMode getOperationMode() const; 296 297 void highlightYank(const Range &range, const OperationMode mode = CharWise); 298 void addHighlightYank(const KTextEditor::Range &range); 299 motionWillBeUsedWithCommand()300 bool motionWillBeUsedWithCommand() const 301 { 302 return !m_awaitingMotionOrTextObject.isEmpty(); 303 }; 304 305 void joinLines(unsigned int from, unsigned int to) const; 306 void reformatLines(unsigned int from, unsigned int to) const; 307 bool executeKateCommand(const QString &command); 308 309 /** 310 * Get the index of the first non-blank character from the given line. 311 * 312 * @param line The line to be picked. The current line will picked instead 313 * if this parameter is set to a negative value. 314 * @returns the index of the first non-blank character from the given line. 315 * If a non-space character cannot be found, the 0 is returned. 316 */ 317 int getFirstNonBlank(int line = -1) const; 318 319 Range textObjectComma(bool inner) const; 320 void shrinkRangeAroundCursor(Range &toShrink, const Range &rangeToShrinkTo) const; 321 KTextEditor::Cursor findSentenceStart(); 322 KTextEditor::Cursor findSentenceEnd(); 323 KTextEditor::Cursor findParagraphStart(); 324 KTextEditor::Cursor findParagraphEnd(); 325 326 protected: 327 // The 'current position' is the current cursor position for non-linewise pastes, and the current 328 // line for linewise. 329 enum PasteLocation { AtCurrentPosition, AfterCurrentPosition }; 330 bool paste(NormalViMode::PasteLocation pasteLocation, bool isgPaste, bool isIndentedPaste); 331 KTextEditor::Cursor cursorPosAtEndOfPaste(const KTextEditor::Cursor pasteLocation, const QString &pastedText) const; 332 333 protected: 334 QString m_keys; 335 QString m_lastTFcommand; // holds the last t/T/f/F command so that it can be repeated with ;/, 336 337 unsigned int m_countTemp; 338 int m_motionOperatorIndex; 339 int m_scroll_count_limit; 340 341 std::vector<Command> m_commands; 342 std::vector<Motion> m_motions; 343 QVector<int> m_matchingCommands; 344 QVector<int> m_matchingMotions; 345 QStack<int> m_awaitingMotionOrTextObject; 346 347 bool m_findWaitingForChar; 348 bool m_isRepeatedTFcommand; 349 bool m_linewiseCommand; 350 bool m_commandWithMotion; 351 bool m_lastMotionWasLinewiseInnerBlock; 352 bool m_motionCanChangeWholeVisualModeSelection; 353 bool m_commandShouldKeepSelection; 354 bool m_deleteCommand; 355 // Ctrl-c or ESC have been pressed, leading to a call to reset(). 356 bool m_pendingResetIsDueToExit; 357 bool m_isUndo; 358 bool waitingForRegisterOrCharToSearch(); 359 360 // item matching ('%' motion) 361 QHash<QString, QString> m_matchingItems; 362 QRegularExpression m_matchItemRegex; 363 364 KeyParser *m_keyParser; 365 366 KTextEditor::Attribute::Ptr m_highlightYankAttribute; 367 QSet<KTextEditor::MovingRange *> m_highlightedYanks; 368 QSet<KTextEditor::MovingRange *> &highlightedYankForDocument(); 369 370 KTextEditor::Cursor m_currentChangeEndMarker; 371 KTextEditor::Cursor m_positionWhenIncrementalSearchBegan; 372 373 private Q_SLOTS: 374 void textInserted(KTextEditor::Document *document, KTextEditor::Range range); 375 void textRemoved(KTextEditor::Document *, KTextEditor::Range); 376 void undoBeginning(); 377 void undoEnded(); 378 379 void updateYankHighlightAttrib(); 380 void clearYankHighlight(); 381 void aboutToDeleteMovingInterfaceContent(); 382 }; 383 384 } 385 386 #endif /* KATEVI_NORMAL_VI_MODE_H */ 387