Warning, file /frameworks/ktexteditor/src/inputmode/kateviinputmode.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: KDE Developers
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "kateviinputmode.h"
0008 #include "kateconfig.h"
0009 #include "katedocument.h"
0010 #include "kateviewinternal.h"
0011 #include <vimode/emulatedcommandbar/emulatedcommandbar.h>
0012 #include <vimode/macrorecorder.h>
0013 #include <vimode/marks.h>
0014 #include <vimode/modes/replacevimode.h>
0015 #include <vimode/modes/visualvimode.h>
0016 #include <vimode/searcher.h>
0017 
0018 #include <KLocalizedString>
0019 
0020 #include <QCoreApplication>
0021 
0022 namespace
0023 {
0024 QString viModeToString(KateVi::ViMode mode)
0025 {
0026     QString modeStr;
0027     switch (mode) {
0028     case KateVi::InsertMode:
0029         modeStr = i18n("VI: INSERT MODE");
0030         break;
0031     case KateVi::NormalMode:
0032         modeStr = i18n("VI: NORMAL MODE");
0033         break;
0034     case KateVi::VisualMode:
0035         modeStr = i18n("VI: VISUAL");
0036         break;
0037     case KateVi::VisualBlockMode:
0038         modeStr = i18n("VI: VISUAL BLOCK");
0039         break;
0040     case KateVi::VisualLineMode:
0041         modeStr = i18n("VI: VISUAL LINE");
0042         break;
0043     case KateVi::ReplaceMode:
0044         modeStr = i18n("VI: REPLACE");
0045         break;
0046     }
0047 
0048     return modeStr;
0049 }
0050 }
0051 
0052 KateViInputMode::KateViInputMode(KateViewInternal *viewInternal, KateVi::GlobalState *global)
0053     : KateAbstractInputMode(viewInternal)
0054     , m_viModeEmulatedCommandBar(nullptr)
0055     , m_viGlobal(global)
0056     , m_caret(KateRenderer::Block)
0057     , m_nextKeypressIsOverriddenShortCut(false)
0058     , m_relLineNumbers(KateViewConfig::global()->viRelativeLineNumbers())
0059     , m_activated(false)
0060     , m_viModeManager(new KateVi::InputModeManager(this, view(), viewInternal))
0061 {
0062 }
0063 
0064 void KateViInputMode::activate()
0065 {
0066     m_activated = true;
0067     setCaretStyle(KateRenderer::Block); // TODO: can we end up in insert mode?
0068     reset(); // TODO: is this necessary? (well, not anymore I guess)
0069 
0070     if (view()->selection()) {
0071         m_viModeManager->changeViMode(KateVi::VisualMode);
0072         view()->setCursorPosition(KTextEditor::Cursor(view()->selectionRange().end().line(), view()->selectionRange().end().column() - 1));
0073         m_viModeManager->m_viVisualMode->updateSelection();
0074     }
0075     viewInternal()->iconBorder()->setRelLineNumbersOn(m_relLineNumbers);
0076 }
0077 
0078 void KateViInputMode::deactivate()
0079 {
0080     if (m_viModeEmulatedCommandBar) {
0081         m_viModeEmulatedCommandBar->hideMe();
0082     }
0083 
0084     // make sure to turn off edits merging when leaving vi input mode
0085     view()->doc()->setUndoMergeAllEdits(false);
0086     m_activated = false;
0087     viewInternal()->iconBorder()->setRelLineNumbersOn(false);
0088     m_viModeManager->searcher()->enableHighlightSearch(false);
0089 }
0090 
0091 void KateViInputMode::reset()
0092 {
0093     if (m_viModeEmulatedCommandBar) {
0094         m_viModeEmulatedCommandBar->hideMe();
0095     }
0096 
0097     // ensure first the old stuff is deleted and then the new manager is constructed
0098     m_viModeManager.reset();
0099     m_viModeManager.reset(new KateVi::InputModeManager(this, view(), viewInternal()));
0100 
0101     if (m_viModeEmulatedCommandBar) {
0102         m_viModeEmulatedCommandBar->setViInputModeManager(m_viModeManager.get());
0103     }
0104 }
0105 
0106 bool KateViInputMode::overwrite() const
0107 {
0108     return m_viModeManager->getCurrentViMode() == KateVi::ViMode::ReplaceMode;
0109 }
0110 
0111 void KateViInputMode::overwrittenChar(const QChar &c)
0112 {
0113     m_viModeManager->getViReplaceMode()->overwrittenChar(c);
0114 }
0115 
0116 void KateViInputMode::clearSelection()
0117 {
0118     // do nothing, handled elsewhere
0119 }
0120 
0121 bool KateViInputMode::stealKey(QKeyEvent *k)
0122 {
0123     if (!KateViewConfig::global()->viInputModeStealKeys()) {
0124         return false;
0125     }
0126 
0127     // Actually see if we can make use of this key - if so, we've stolen it; if not,
0128     // let Qt's shortcut handling system deal with it.
0129     const bool stolen = keyPress(k);
0130     if (stolen) {
0131         // Qt will replay this QKeyEvent, next time as an ordinary KeyPress.
0132         m_nextKeypressIsOverriddenShortCut = true;
0133     }
0134     return stolen;
0135 }
0136 
0137 KTextEditor::View::InputMode KateViInputMode::viewInputMode() const
0138 {
0139     return KTextEditor::View::ViInputMode;
0140 }
0141 
0142 QString KateViInputMode::viewInputModeHuman() const
0143 {
0144     return i18n("vi-mode");
0145 }
0146 
0147 KTextEditor::View::ViewMode KateViInputMode::viewMode() const
0148 {
0149     return m_viModeManager->getCurrentViewMode();
0150 }
0151 
0152 QString KateViInputMode::viewModeHuman() const
0153 {
0154     QString currentMode = viModeToString(m_viModeManager->getCurrentViMode());
0155 
0156     if (m_viModeManager->macroRecorder()->isRecording()) {
0157         currentMode.prepend(QLatin1Char('(') + i18n("recording") + QLatin1String(") "));
0158     }
0159 
0160     QString cmd = m_viModeManager->getVerbatimKeys();
0161     if (!cmd.isEmpty()) {
0162         currentMode.prepend(QStringLiteral("%1 ").arg(cmd));
0163     }
0164 
0165     return currentMode;
0166 }
0167 
0168 void KateViInputMode::gotFocus()
0169 {
0170     // nothing to do
0171 }
0172 
0173 void KateViInputMode::lostFocus()
0174 {
0175     // nothing to do
0176 }
0177 
0178 void KateViInputMode::readSessionConfig(const KConfigGroup &config)
0179 {
0180     // restore vi registers and jump list
0181     m_viModeManager->readSessionConfig(config);
0182 }
0183 
0184 void KateViInputMode::writeSessionConfig(KConfigGroup &config)
0185 {
0186     // save vi registers and jump list
0187     m_viModeManager->writeSessionConfig(config);
0188 }
0189 
0190 void KateViInputMode::updateConfig()
0191 {
0192     KateViewConfig *cfg = view()->config();
0193 
0194     // whether relative line numbers should be used or not.
0195     m_relLineNumbers = cfg->viRelativeLineNumbers();
0196 
0197     if (m_activated) {
0198         viewInternal()->iconBorder()->setRelLineNumbersOn(m_relLineNumbers);
0199     }
0200 }
0201 
0202 void KateViInputMode::readWriteChanged(bool)
0203 {
0204     // nothing todo
0205 }
0206 
0207 void KateViInputMode::find()
0208 {
0209     showViModeEmulatedCommandBar();
0210     viModeEmulatedCommandBar()->init(KateVi::EmulatedCommandBar::SearchForward);
0211 }
0212 
0213 void KateViInputMode::findSelectedForwards()
0214 {
0215     m_viModeManager->searcher()->findNext();
0216 }
0217 
0218 void KateViInputMode::findSelectedBackwards()
0219 {
0220     m_viModeManager->searcher()->findPrevious();
0221 }
0222 
0223 void KateViInputMode::findReplace()
0224 {
0225     showViModeEmulatedCommandBar();
0226     viModeEmulatedCommandBar()->init(KateVi::EmulatedCommandBar::SearchForward);
0227 }
0228 
0229 void KateViInputMode::findNext()
0230 {
0231     m_viModeManager->searcher()->findNext();
0232 }
0233 
0234 void KateViInputMode::findPrevious()
0235 {
0236     m_viModeManager->searcher()->findPrevious();
0237 }
0238 
0239 void KateViInputMode::activateCommandLine()
0240 {
0241     showViModeEmulatedCommandBar();
0242     viModeEmulatedCommandBar()->init(KateVi::EmulatedCommandBar::Command);
0243 }
0244 
0245 void KateViInputMode::showViModeEmulatedCommandBar()
0246 {
0247     view()->bottomViewBar()->addBarWidget(viModeEmulatedCommandBar());
0248     view()->bottomViewBar()->showBarWidget(viModeEmulatedCommandBar());
0249 }
0250 
0251 KateVi::EmulatedCommandBar *KateViInputMode::viModeEmulatedCommandBar()
0252 {
0253     if (!m_viModeEmulatedCommandBar) {
0254         m_viModeEmulatedCommandBar = new KateVi::EmulatedCommandBar(this, m_viModeManager.get(), view());
0255         m_viModeEmulatedCommandBar->hide();
0256     }
0257 
0258     return m_viModeEmulatedCommandBar;
0259 }
0260 
0261 void KateViInputMode::updateRendererConfig()
0262 {
0263     m_viModeManager->searcher()->updateHighlightColors();
0264 }
0265 
0266 bool KateViInputMode::keyPress(QKeyEvent *e)
0267 {
0268     if (m_nextKeypressIsOverriddenShortCut) {
0269         // This is just the replay of a shortcut that we stole, this time as a QKeyEvent.
0270         // Ignore it, as we'll have already handled it via stealKey()!
0271         m_nextKeypressIsOverriddenShortCut = false;
0272         return true;
0273     }
0274 
0275     if (m_viModeManager->handleKeypress(e)) {
0276         Q_EMIT view()->viewModeChanged(view(), viewMode());
0277         return true;
0278     }
0279 
0280     return false;
0281 }
0282 
0283 bool KateViInputMode::blinkCaret() const
0284 {
0285     return false;
0286 }
0287 
0288 KateRenderer::caretStyles KateViInputMode::caretStyle() const
0289 {
0290     return m_caret;
0291 }
0292 
0293 void KateViInputMode::toggleInsert()
0294 {
0295     // do nothing
0296 }
0297 
0298 void KateViInputMode::launchInteractiveCommand(const QString &)
0299 {
0300     // do nothing so far
0301 }
0302 
0303 QString KateViInputMode::bookmarkLabel(int line) const
0304 {
0305     return m_viModeManager->marks()->getMarksOnTheLine(line);
0306 }
0307 
0308 void KateViInputMode::setCaretStyle(const KateRenderer::caretStyles caret)
0309 {
0310     if (m_caret != caret) {
0311         m_caret = caret;
0312 
0313         view()->renderer()->setCaretStyle(m_caret);
0314         view()->renderer()->setDrawCaret(true);
0315         viewInternal()->paintCursor();
0316     }
0317 }