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

source code of ktexteditor/src/vimode/modes/normalvimode.h