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 commandToggleComment();
80
81 bool commandChange();
82 bool commandChangeLine();
83 bool commandChangeToEOL();
84 bool commandSubstituteChar();
85 bool commandSubstituteLine();
86
87 bool commandYank();
88 bool commandYankLine();
89 bool commandYankToEOL();
90
91 bool commandPaste();
92 bool commandPasteBefore();
93
94 bool commandgPaste();
95 bool commandgPasteBefore();
96
97 bool commandIndentedPaste();
98 bool commandIndentedPasteBefore();
99
100 bool commandDeleteChar();
101 bool commandDeleteCharBackward();
102
103 bool commandReplaceCharacter();
104
105 bool commandSwitchToCmdLine();
106 bool commandSearchBackward();
107 bool commandSearchForward();
108 bool commandUndo();
109 bool commandRedo();
110
111 bool commandSetMark();
112
113 bool commandIndentLine();
114 bool commandUnindentLine();
115 bool commandIndentLines();
116 bool commandUnindentLines();
117
118 bool commandScrollPageDown();
119 bool commandScrollPageUp();
120 bool commandScrollHalfPageUp();
121 bool commandScrollHalfPageDown();
122
123 bool commandCenterView(bool onFirst);
124 bool commandCenterViewOnNonBlank();
125 bool commandCenterViewOnCursor();
126 bool commandTopView(bool onFirst);
127 bool commandTopViewOnNonBlank();
128 bool commandTopViewOnCursor();
129 bool commandBottomView(bool onFirst);
130 bool commandBottomViewOnNonBlank();
131 bool commandBottomViewOnCursor();
132
133 bool commandAbort();
134
135 bool commandPrintCharacterCode();
136
137 bool commandRepeatLastChange();
138
139 bool commandAlignLine();
140 bool commandAlignLines();
141
142 bool commandAddToNumber();
143 bool commandSubtractFromNumber();
144
145 bool commandPrependToBlock();
146 bool commandAppendToBlock();
147
148 bool commandGoToNextJump();
149 bool commandGoToPrevJump();
150
151 bool commandSwitchToLeftView();
152 bool commandSwitchToUpView();
153 bool commandSwitchToDownView();
154 bool commandSwitchToRightView();
155 bool commandSwitchToNextView();
156
157 bool commandSplitHoriz();
158 bool commandSplitVert();
159 bool commandCloseView();
160
161 bool commandSwitchToNextTab();
162 bool commandSwitchToPrevTab();
163
164 bool commandFormatLine();
165 bool commandFormatLines();
166
167 bool commandCollapseToplevelNodes();
168 bool commandCollapseLocal();
169 bool commandExpandAll();
170 bool commandExpandLocal();
171 bool commandToggleRegionVisibility();
172
173 bool commandStartRecordingMacro();
174 bool commandReplayMacro();
175
176 bool commandCloseWrite();
177 bool commandCloseNocheck();
178
179 // MOTIONS
180
181 Range motionLeft();
182 Range motionRight();
183 Range motionDown();
184 Range motionUp();
185
186 Range motionPageDown();
187 Range motionPageUp();
188 Range motionHalfPageDown();
189 Range motionHalfPageUp();
190
191 Range motionUpToFirstNonBlank();
192 Range motionDownToFirstNonBlank();
193
194 Range motionWordForward();
195 Range motionWordBackward();
196 Range motionWORDForward();
197 Range motionWORDBackward();
198
199 Range motionToEndOfWord();
200 Range motionToEndOfWORD();
201 Range motionToEndOfPrevWord();
202 Range motionToEndOfPrevWORD();
203
204 Range motionFindChar();
205 Range motionFindCharBackward();
206 Range motionToChar();
207 Range motionToCharBackward();
208 Range motionRepeatlastTF();
209 Range motionRepeatlastTFBackward();
210
211 Range motionToEOL();
212 Range motionToLastNonBlank();
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
290protected:
291 void resetParser();
292 QRegularExpression generateMatchingItemRegex() const;
293 void executeCommand(const Command *cmd);
294 OperationMode getOperationMode() const;
295
296 void highlightYank(const Range &range, const OperationMode mode = CharWise);
297 void addHighlightYank(KTextEditor::Range range);
298
299 bool motionWillBeUsedWithCommand() const
300 {
301 return !m_awaitingMotionOrTextObject.isEmpty();
302 };
303
304 void joinLines(unsigned int from, unsigned int to) const;
305 void reformatLines(unsigned int from, unsigned int to) const;
306 bool executeKateCommand(const QString &command);
307
308 /**
309 * Get the index of the first non-blank character from the given line.
310 *
311 * @param line The line to be picked. The current line will picked instead
312 * if this parameter is set to a negative value.
313 * @returns the index of the first non-blank character from the given line.
314 * If a non-space character cannot be found, the 0 is returned.
315 */
316 int getFirstNonBlank(int line = -1) const;
317
318 Range textObjectComma(bool inner) const;
319 void shrinkRangeAroundCursor(Range &toShrink, const Range &rangeToShrinkTo) const;
320 KTextEditor::Cursor findSentenceStart();
321 KTextEditor::Cursor findSentenceEnd();
322 KTextEditor::Cursor findParagraphStart();
323 KTextEditor::Cursor findParagraphEnd();
324
325 /**
326 * Return commands available for this mode.
327 * Overwritten in sub classes to replace them, must be a stable reference!
328 */
329 virtual const std::vector<Command> &commands();
330
331 /**
332 * Return motions available for this mode.
333 * Overwritten in sub classes to replace them, must be a stable reference!
334 */
335 virtual const std::vector<Motion> &motions();
336
337protected:
338 // The 'current position' is the current cursor position for non-linewise pastes, and the current
339 // line for linewise.
340 enum PasteLocation {
341 AtCurrentPosition,
342 AfterCurrentPosition
343 };
344 bool paste(NormalViMode::PasteLocation pasteLocation, bool isgPaste, bool isIndentedPaste);
345 static KTextEditor::Cursor cursorPosAtEndOfPaste(const KTextEditor::Cursor pasteLocation, const QString &pastedText);
346
347 // set sticky column to a ridiculously high value so that the cursor will stick to EOL,
348 // but only if it's a regular motion
349 void stickStickyColumnToEOL();
350
351protected:
352 QString m_keys;
353 QString m_lastTFcommand; // holds the last t/T/f/F command so that it can be repeated with ;/,
354
355 unsigned int m_countTemp;
356 int m_motionOperatorIndex;
357 int m_scroll_count_limit;
358
359 QList<int> m_matchingCommands;
360 QList<int> m_matchingMotions;
361 QStack<int> m_awaitingMotionOrTextObject;
362
363 bool m_findWaitingForChar;
364 bool m_isRepeatedTFcommand;
365 bool m_linewiseCommand;
366 bool m_commandWithMotion;
367 bool m_lastMotionWasLinewiseInnerBlock;
368 bool m_motionCanChangeWholeVisualModeSelection;
369 bool m_commandShouldKeepSelection;
370 bool m_deleteCommand;
371 // Ctrl-c or ESC have been pressed, leading to a call to reset().
372 bool m_pendingResetIsDueToExit;
373 bool m_isUndo;
374 bool waitingForRegisterOrCharToSearch();
375
376 // item matching ('%' motion)
377 QHash<QString, QString> m_matchingItems;
378 QRegularExpression m_matchItemRegex;
379
380 KeyParser *m_keyParser;
381
382 KTextEditor::Attribute::Ptr m_highlightYankAttribute;
383 QSet<KTextEditor::MovingRange *> m_highlightedYanks;
384 QSet<KTextEditor::MovingRange *> &highlightedYankForDocument();
385
386 KTextEditor::Cursor m_currentChangeEndMarker;
387 KTextEditor::Cursor m_positionWhenIncrementalSearchBegan;
388
389private:
390 void textInserted(KTextEditor::Document *document, KTextEditor::Range range);
391 void textRemoved(KTextEditor::Document *, KTextEditor::Range);
392 void undoBeginning();
393 void undoEnded();
394
395 void updateYankHighlightAttrib();
396 void clearYankHighlight();
397};
398}
399
400#endif /* KATEVI_NORMAL_VI_MODE_H */
401

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