10#include <vimode/inputmodemanager.h>
12#include <QApplication>
16#include <KConfigGroup>
17#include <KLocalizedString>
19#include "completionrecorder.h"
20#include "completionreplayer.h"
21#include "definitions.h"
22#include "globalstate.h"
24#include "kateconfig.h"
25#include "katedocument.h"
26#include "kateglobal.h"
27#include "katerenderer.h"
29#include "kateviewinternal.h"
30#include "kateviinputmode.h"
31#include "lastchangerecorder.h"
32#include "macrorecorder.h"
38#include <vimode/emulatedcommandbar/emulatedcommandbar.h>
39#include <vimode/keymapper.h>
40#include <vimode/keyparser.h>
41#include <vimode/modes/insertvimode.h>
42#include <vimode/modes/normalvimode.h>
43#include <vimode/modes/replacevimode.h>
44#include <vimode/modes/visualvimode.h>
46using namespace KateVi;
48InputModeManager::InputModeManager(KateViInputMode *inputAdapter, KTextEditor::ViewPrivate *view, KateViewInternal *viewInternal)
49 : m_inputAdapter(inputAdapter)
51 m_currentViMode = ViMode::NormalMode;
52 m_previousViMode = ViMode::NormalMode;
54 m_viNormalMode =
new NormalViMode(
this, view, viewInternal);
55 m_viInsertMode =
new InsertViMode(
this, view, viewInternal);
56 m_viVisualMode =
new VisualViMode(
this, view, viewInternal);
57 m_viReplaceMode =
new ReplaceViMode(
this, view, viewInternal);
60 m_viewInternal = viewInternal;
62 m_insideHandlingKeyPressCount = 0;
64 m_keyMapperStack.push(std::make_shared<KeyMapper>(
this, m_view->doc()));
66 m_temporaryNormalMode =
false;
68 m_jumps =
new Jumps();
69 m_marks =
new Marks(
this);
71 m_searcher =
new Searcher(
this);
72 m_completionRecorder =
new CompletionRecorder(
this);
73 m_completionReplayer =
new CompletionReplayer(
this);
75 m_macroRecorder =
new MacroRecorder(
this);
77 m_lastChangeRecorder =
new LastChangeRecorder(
this);
82 m_viNormalMode->beginMonitoringDocumentChanges();
85InputModeManager::~InputModeManager()
87 delete m_viNormalMode;
88 delete m_viInsertMode;
89 delete m_viVisualMode;
90 delete m_viReplaceMode;
94 delete m_macroRecorder;
95 delete m_completionRecorder;
96 delete m_completionReplayer;
97 delete m_lastChangeRecorder;
100bool InputModeManager::handleKeypress(
const QKeyEvent *e)
102 m_insideHandlingKeyPressCount++;
104 bool keyIsPartOfMapping =
false;
105 const bool isSyntheticSearchCompletedKeyPress = m_inputAdapter->viModeEmulatedCommandBar()->isSendingSyntheticSearchCompletedKeypress();
111 if (m_macroRecorder->isRecording() && !m_macroRecorder->isReplaying() && !isSyntheticSearchCompletedKeyPress && !keyMapper()->isExecutingMapping()
112 && !keyMapper()->isPlayingBackRejectedKeys() && !lastChangeRecorder()->isReplaying()) {
113 m_macroRecorder->record(*e);
116 if (!m_lastChangeRecorder->isReplaying() && !isSyntheticSearchCompletedKeyPress) {
123 const QChar key = KeyParser::self()->KeyEventToQChar(*e);
124 if (keyMapper()->handleKeypress(key)) {
125 keyIsPartOfMapping =
true;
131 if (!keyIsPartOfMapping) {
132 if (!m_lastChangeRecorder->isReplaying() && !isSyntheticSearchCompletedKeyPress) {
134 m_lastChangeRecorder->record(*e);
137 if (m_inputAdapter->viModeEmulatedCommandBar()->isActive()) {
138 res = m_inputAdapter->viModeEmulatedCommandBar()->handleKeyPress(e);
140 res = getCurrentViModeHandler()->handleKeypress(e);
144 m_insideHandlingKeyPressCount--;
145 Q_ASSERT(m_insideHandlingKeyPressCount >= 0);
150void InputModeManager::feedKeyPresses(
const QString &keyPresses)
const
156 for (
const QChar c : keyPresses) {
157 QString decoded = KeyParser::self()->decodeKeySequence(
QString(c));
162 if (decoded.
length() > 1) {
179 mods |= CONTROL_MODIFIER;
191 mods |= META_MODIFIER;
195 if (decoded.
length() > 1) {
196 key = KeyParser::self()->vi2qt(decoded);
197 }
else if (decoded.
length() == 1) {
198 key = int(decoded.
at(0).
toUpper().toLatin1());
199 text = decoded.
at(0);
202 key = KeyParser::self()->vi2qt(decoded);
206 text = decoded.
at(0);
233bool InputModeManager::isHandlingKeypress()
const
235 return m_insideHandlingKeyPressCount > 0;
238void InputModeManager::storeLastChangeCommand()
240 m_lastChange = m_lastChangeRecorder->encodedChanges();
241 m_lastChangeCompletionsLog = m_completionRecorder->currentChangeCompletionsLog();
244void InputModeManager::repeatLastChange()
246 m_lastChangeRecorder->replay(m_lastChange, m_lastChangeCompletionsLog);
249void InputModeManager::clearCurrentChangeLog()
251 m_lastChangeRecorder->clear();
252 m_completionRecorder->clearCurrentChangeCompletionsLog();
255void InputModeManager::doNotLogCurrentKeypress()
257 m_macroRecorder->dropLast();
258 m_lastChangeRecorder->dropLast();
261void InputModeManager::changeViMode(ViMode newMode)
263 m_previousViMode = m_currentViMode;
264 m_currentViMode = newMode;
267ViMode InputModeManager::getCurrentViMode()
const
269 return m_currentViMode;
274 switch (m_currentViMode) {
275 case ViMode::InsertMode:
276 return KTextEditor::View::ViModeInsert;
277 case ViMode::VisualMode:
278 return KTextEditor::View::ViModeVisual;
279 case ViMode::VisualLineMode:
280 return KTextEditor::View::ViModeVisualLine;
281 case ViMode::VisualBlockMode:
282 return KTextEditor::View::ViModeVisualBlock;
283 case ViMode::ReplaceMode:
284 return KTextEditor::View::ViModeReplace;
285 case ViMode::NormalMode:
287 return KTextEditor::View::ViModeNormal;
291ViMode InputModeManager::getPreviousViMode()
const
293 return m_previousViMode;
296bool InputModeManager::isAnyVisualMode()
const
298 return ((m_currentViMode == ViMode::VisualMode) || (m_currentViMode == ViMode::VisualLineMode) || (m_currentViMode == ViMode::VisualBlockMode));
301::ModeBase *InputModeManager::getCurrentViModeHandler()
const
303 switch (m_currentViMode) {
304 case ViMode::NormalMode:
305 return m_viNormalMode;
306 case ViMode::InsertMode:
307 return m_viInsertMode;
308 case ViMode::VisualMode:
309 case ViMode::VisualLineMode:
310 case ViMode::VisualBlockMode:
311 return m_viVisualMode;
312 case ViMode::ReplaceMode:
313 return m_viReplaceMode;
318void InputModeManager::viEnterNormalMode()
320 bool moveCursorLeft = (m_currentViMode == ViMode::InsertMode || m_currentViMode == ViMode::ReplaceMode) && m_viewInternal->cursorPosition().
column() > 0;
322 if (!m_lastChangeRecorder->isReplaying() && (m_currentViMode == ViMode::InsertMode || m_currentViMode == ViMode::ReplaceMode)) {
329 m_inputAdapter->globalState()->registers()->setInsertStopped(insertedText);
335 changeViMode(ViMode::NormalMode);
337 if (moveCursorLeft) {
338 m_viewInternal->cursorPrevChar();
340 m_inputAdapter->setCaretStyle(KTextEditor::caretStyles::Block);
344void InputModeManager::viEnterInsertMode()
346 changeViMode(ViMode::InsertMode);
348 if (getTemporaryNormalMode()) {
353 m_inputAdapter->setCaretStyle(KTextEditor::caretStyles::Line);
354 setTemporaryNormalMode(
false);
358void InputModeManager::viEnterVisualMode(ViMode mode)
364 m_inputAdapter->setCaretStyle(KTextEditor::caretStyles::Block);
366 getViVisualMode()->setVisualModeType(mode);
367 getViVisualMode()->init();
370void InputModeManager::viEnterReplaceMode()
372 changeViMode(ViMode::ReplaceMode);
374 m_inputAdapter->setCaretStyle(KTextEditor::caretStyles::Underline);
380 return m_viNormalMode;
383InsertViMode *InputModeManager::getViInsertMode()
385 return m_viInsertMode;
388VisualViMode *InputModeManager::getViVisualMode()
390 return m_viVisualMode;
395 return m_viReplaceMode;
398const QString InputModeManager::getVerbatimKeys()
const
402 switch (getCurrentViMode()) {
403 case ViMode::NormalMode:
404 cmd = m_viNormalMode->getVerbatimKeys();
406 case ViMode::InsertMode:
407 case ViMode::ReplaceMode:
410 case ViMode::VisualMode:
411 case ViMode::VisualLineMode:
412 case ViMode::VisualBlockMode:
413 cmd = m_viVisualMode->getVerbatimKeys();
420void InputModeManager::readSessionConfig(
const KConfigGroup &config)
422 m_jumps->readSessionConfig(config);
423 m_marks->readSessionConfig(config);
426void InputModeManager::writeSessionConfig(
KConfigGroup &config)
428 m_jumps->writeSessionConfig(config);
429 m_marks->writeSessionConfig(config);
432void InputModeManager::reset()
434 if (m_viVisualMode) {
435 m_viVisualMode->reset();
439KeyMapper *InputModeManager::keyMapper()
441 return m_keyMapperStack.
top().get();
446 m_inputAdapter->updateCursor(c);
449GlobalState *InputModeManager::globalState()
const
451 return m_inputAdapter->globalState();
454KTextEditor::ViewPrivate *InputModeManager::view()
const
459void InputModeManager::pushKeyMapper(std::shared_ptr<KeyMapper> mapper)
461 m_keyMapperStack.
push(mapper);
464void InputModeManager::popKeyMapper()
466 m_keyMapperStack.
pop();
The Cursor represents a position in a Document.
constexpr int column() const noexcept
Retrieve the column on which this cursor is situated.
QString text(KTextEditor::Range range, bool blockwise=false) const override
Get the document content within the given range.
An object representing a section of text, from one Cursor to another.
ViewMode
Possible view modes These correspond to various modes the text editor might be in.
Commands for the vi normal mode.
Commands for the vi replace mode.
char32_t toUpper(char32_t ucs4)
bool sendEvent(QObject *receiver, QEvent *event)
const QChar at(qsizetype position) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
typedef KeyboardModifiers