Git commit cbaa10dd605e33726335a04eea93f900b401f7ac by Simon St James. Committed on 17/06/2016 at 08:14. Pushed by sstjames into branch 'master'. Move ActiveMode and Completer into their own source files - couldn't do thi= s piecemeal, alas, so it took a while to disentangle it. M +1 -0 src/CMakeLists.txt A +49 -0 src/vimode/emulatedcommandbar/activemode.cpp [License: U= NKNOWN] * A +53 -0 src/vimode/emulatedcommandbar/activemode.h [License: UNK= NOWN] * M +236 -0 src/vimode/emulatedcommandbar/completer.cpp M +49 -0 src/vimode/emulatedcommandbar/completer.h M +4 -264 src/vimode/emulatedcommandbar/emulatedcommandbar.cpp M +3 -73 src/vimode/emulatedcommandbar/emulatedcommandbar.h The files marked with a * at the end have a non valid license. Please read:= http://techbase.kde.org/Policies/Licensing_Policy and use the headers whic= h are listed at that page. http://commits.kde.org/ktexteditor/cbaa10dd605e33726335a04eea93f900b401f7ac diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 49900cd..b50de81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -278,6 +278,7 @@ if (BUILD_VIMODE) vimode/emulatedcommandbar/emulatedcommandbar.cpp vimode/emulatedcommandbar/matchhighlighter.cpp vimode/emulatedcommandbar/completer.cpp + vimode/emulatedcommandbar/activemode.cpp vimode/commandrangeexpressionparser.cpp vimode/keymapper.cpp vimode/marks.cpp diff --git a/src/vimode/emulatedcommandbar/activemode.cpp b/src/vimode/emul= atedcommandbar/activemode.cpp new file mode 100644 index 0000000..3f2a11e --- /dev/null +++ b/src/vimode/emulatedcommandbar/activemode.cpp @@ -0,0 +1,49 @@ +#include "activemode.h" +#include "completer.h" +#include "emulatedcommandbar.h" +#include "matchhighlighter.h" + +using namespace KateVi; + +CompletionStartParams ActiveMode::completionInvoked(Completer::CompletionI= nvocation invocationType) +{ + Q_UNUSED(invocationType); + return CompletionStartParams(); +}; + +ActiveMode::~ActiveMode() +{ + +} + +void ActiveMode::hideAllWidgetsExcept(QWidget* widgetToKeepVisible) +{ + m_emulatedCommandBar->hideAllWidgetsExcept(widgetToKeepVisible); +} + +void ActiveMode::moveCursorTo(const KTextEditor::Cursor &cursorPos) +{ + m_emulatedCommandBar->moveCursorTo(cursorPos); +} + +void ActiveMode::updateMatchHighlight(const KTextEditor::Range& matchRange) +{ + m_matchHighligher->updateMatchHighlight(matchRange); +} + +void ActiveMode::close( bool wasAborted ) +{ + m_emulatedCommandBar->m_wasAborted =3D wasAborted; + m_emulatedCommandBar->hideMe(); +} + +void ActiveMode::closeWithStatusMessage(const QString& exitStatusMessage) +{ + m_emulatedCommandBar->closeWithStatusMessage(exitStatusMessage); +} + +void ActiveMode::startCompletion ( const CompletionStartParams& completion= StartParams ) +{ + m_emulatedCommandBar->m_completer->startCompletion(completionStartPara= ms); +} + diff --git a/src/vimode/emulatedcommandbar/activemode.h b/src/vimode/emulat= edcommandbar/activemode.h new file mode 100644 index 0000000..8e32959 --- /dev/null +++ b/src/vimode/emulatedcommandbar/activemode.h @@ -0,0 +1,53 @@ +#ifndef KATEVI_EMULATED_COMMAND_BAR_ACTIVEMODE_H +#define KATEVI_EMULATED_COMMAND_BAR_ACTIVEMODE_H + +#include "completer.h" + +class QKeyEvent; +class QString; + +namespace KTextEditor +{ + class Cursor; + class Range; +} + +namespace KateVi +{ +class EmulatedCommandBar; +class CompletionStartParams; +class MatchHighlighter; + +class ActiveMode +{ +public: + ActiveMode(EmulatedCommandBar* emulatedCommandBar, MatchHighlighter* m= atchHighlighter) + : m_emulatedCommandBar(emulatedCommandBar), + m_matchHighligher(matchHighlighter) + { + } + virtual ~ActiveMode() =3D 0; + virtual bool handleKeyPress(const QKeyEvent *keyEvent) =3D 0; + virtual void editTextChanged(const QString &newText) + { + Q_UNUSED(newText); + } + virtual KateVi::CompletionStartParams completionInvoked(Completer::Com= pletionInvocation invocationType); + virtual void completionChosen() + { + } + virtual void deactivate(bool wasAborted) =3D 0; +protected: + // Helper methods. + void hideAllWidgetsExcept(QWidget* widgetToKeepVisible); + void moveCursorTo(const KTextEditor::Cursor &cursorPos); + void updateMatchHighlight(const KTextEditor::Range &matchRange); + void close(bool wasAborted); + void closeWithStatusMessage(const QString& exitStatusMessage); + void startCompletion(const CompletionStartParams& completionStartParam= s); + EmulatedCommandBar *m_emulatedCommandBar; +private: + MatchHighlighter *m_matchHighligher; +}; +} +#endif diff --git a/src/vimode/emulatedcommandbar/completer.cpp b/src/vimode/emula= tedcommandbar/completer.cpp index e69de29..b95c6c9 100644 --- a/src/vimode/emulatedcommandbar/completer.cpp +++ b/src/vimode/emulatedcommandbar/completer.cpp @@ -0,0 +1,236 @@ +#include "completer.h" +#include "emulatedcommandbar.h" + +using namespace KateVi; + +#include "kateview.h" + +#include +#include +#include +#include + +namespace +{ +bool caseInsensitiveLessThan(const QString &s1, const QString &s2) +{ + return s1.toLower() < s2.toLower(); +} +} + +Completer::Completer ( EmulatedCommandBar* emulatedCommandBar, KTextEditor= ::ViewPrivate* view, QLineEdit* edit ) + : m_edit(edit), + m_view(view) +{ + m_completer =3D new QCompleter(QStringList(), edit); + // Can't find a way to stop the QCompleter from auto-completing when a= ttached to a QLineEdit, + // so don't actually set it as the QLineEdit's completer. + m_completer->setWidget(edit); + m_completer->setObjectName(QStringLiteral("completer")); + m_completionModel =3D new QStringListModel(emulatedCommandBar); + m_completer->setModel(m_completionModel); + m_completer->setCaseSensitivity(Qt::CaseInsensitive); + m_completer->popup()->installEventFilter(emulatedCommandBar); +} + +void Completer::startCompletion ( const CompletionStartParams& completionS= tartParams ) +{ + if (completionStartParams.completionType !=3D CompletionStartParams::N= one) + { + m_completionModel->setStringList(completionStartParams.completions= ); + const QString completionPrefix =3D m_edit->text().mid(completionSt= artParams.wordStartPos, m_edit->cursorPosition() - completionStartParams.wo= rdStartPos); + m_completer->setCompletionPrefix(completionPrefix); + m_completer->complete(); + m_currentCompletionStartParams =3D completionStartParams; + m_currentCompletionType =3D completionStartParams.completionType; + } +} + +void Completer::deactivateCompletion() +{ + m_completer->popup()->hide(); + m_currentCompletionType =3D CompletionStartParams::None; +} + +bool Completer::isCompletionActive() const +{ + return m_currentCompletionType !=3D CompletionStartParams::None; +} + +bool Completer::isNextTextChangeDueToCompletionChange() const +{ + return m_isNextTextChangeDueToCompletionChange; +} + +bool Completer::completerHandledKeypress ( const QKeyEvent* keyEvent ) +{ + if (!m_edit->isVisible()) + return false; + + if (keyEvent->modifiers() =3D=3D Qt::ControlModifier && (keyEvent->key= () =3D=3D Qt::Key_C || keyEvent->key() =3D=3D Qt::Key_BracketLeft)) + { + if (m_currentCompletionType !=3D CompletionStartParams::None && m_= completer->popup()->isVisible()) + { + abortCompletionAndResetToPreCompletion(); + return true; + } + } + if (keyEvent->modifiers() =3D=3D Qt::ControlModifier && keyEvent->key(= ) =3D=3D Qt::Key_Space) { + CompletionStartParams completionStartParams =3D activateWordFromDo= cumentCompletion(); + startCompletion(completionStartParams); + return true; + } + if ((keyEvent->modifiers() =3D=3D Qt::ControlModifier && keyEvent->key= () =3D=3D Qt::Key_P) || keyEvent->key() =3D=3D Qt::Key_Down) { + if (!m_completer->popup()->isVisible()) { + const CompletionStartParams completionStartParams =3D m_curren= tMode->completionInvoked(CompletionInvocation::ExtraContext); + startCompletion(completionStartParams); + if (m_currentCompletionType !=3D CompletionStartParams::None) { + setCompletionIndex(0); + } + } else { + // Descend to next row, wrapping around if necessary. + if (m_completer->currentRow() + 1 =3D=3D m_completer->completi= onCount()) { + setCompletionIndex(0); + } else { + setCompletionIndex(m_completer->currentRow() + 1); + } + } + return true; + } + if ((keyEvent->modifiers() =3D=3D Qt::ControlModifier && keyEvent->key= () =3D=3D Qt::Key_N) || keyEvent->key() =3D=3D Qt::Key_Up) { + if (!m_completer->popup()->isVisible()) { + const CompletionStartParams completionStartParams =3D m_curren= tMode->completionInvoked(CompletionInvocation::NormalContext); + startCompletion(completionStartParams); + setCompletionIndex(m_completer->completionCount() - 1); + } else { + // Ascend to previous row, wrapping around if necessary. + if (m_completer->currentRow() =3D=3D 0) { + setCompletionIndex(m_completer->completionCount() - 1); + } else { + setCompletionIndex(m_completer->currentRow() - 1); + } + } + return true; + } + if (keyEvent->key() =3D=3D Qt::Key_Enter || keyEvent->key() =3D=3D Qt:= :Key_Return) { + if (!m_completer->popup()->isVisible() || m_currentCompletionType = !=3D CompletionStartParams::WordFromDocument) { + m_currentMode->completionChosen(); + } + deactivateCompletion(); + return true; + } + return false; + +} + +void Completer::editTextChanged ( const QString& newText ) +{ + if (!m_isNextTextChangeDueToCompletionChange) { + m_textToRevertToIfCompletionAborted =3D newText; + m_cursorPosToRevertToIfCompletionAborted =3D m_edit->cursorPositio= n(); + } + // If we edit the text after having selected a completion, this means = we implicitly accept it, + // and so we should dismiss it. + if (!m_isNextTextChangeDueToCompletionChange && m_completer->popup()->= currentIndex().row() !=3D -1) { + deactivateCompletion(); + } + + if (m_currentCompletionType !=3D CompletionStartParams::None && !m_isN= extTextChangeDueToCompletionChange) { + updateCompletionPrefix(); + } +} + +void Completer::setCurrentMode ( ActiveMode* currentMode ) +{ + m_currentMode =3D currentMode; +} + +void Completer::setCompletionIndex ( int index ) +{ + const QModelIndex modelIndex =3D m_completer->popup()->model()->index(= index, 0); + // Need to set both of these, for some reason. + m_completer->popup()->setCurrentIndex(modelIndex); + m_completer->setCurrentRow(index); + + m_completer->popup()->scrollTo(modelIndex); + + currentCompletionChanged(); +} + +void Completer::currentCompletionChanged() +{ + const QString newCompletion =3D m_completer->currentCompletion(); + if (newCompletion.isEmpty()) { + return; + } + QString transformedCompletion =3D newCompletion; + if (m_currentCompletionStartParams.completionTransform) + { + transformedCompletion =3D m_currentCompletionStartParams.completio= nTransform(newCompletion); + } + + m_isNextTextChangeDueToCompletionChange =3D true; + m_edit->setSelection(m_currentCompletionStartParams.wordStartPos, m_ed= it->cursorPosition() - m_currentCompletionStartParams.wordStartPos); + m_edit->insert(transformedCompletion); + m_isNextTextChangeDueToCompletionChange =3D false; + +} + + +void Completer::updateCompletionPrefix() +{ + const QString completionPrefix =3D m_edit->text().mid(m_currentComplet= ionStartParams.wordStartPos, m_edit->cursorPosition() - m_currentCompletion= StartParams.wordStartPos); + m_completer->setCompletionPrefix(completionPrefix); + // Seem to need a call to complete() else the size of the popup box is= not altered appropriately. + m_completer->complete(); +} + +CompletionStartParams Completer::activateWordFromDocumentCompletion() +{ + QRegExp wordRegEx(QLatin1String("\\w{1,}")); + QStringList foundWords; + // Narrow the range of lines we search around the cursor so that we do= n't die on huge files. + const int startLine =3D qMax(0, m_view->cursorPosition().line() - 4096= ); + const int endLine =3D qMin(m_view->document()->lines(), m_view->cursor= Position().line() + 4096); + for (int lineNum =3D startLine; lineNum < endLine; lineNum++) { + const QString line =3D m_view->document()->line(lineNum); int word= SearchBeginPos =3D 0; + while (wordRegEx.indexIn(line, wordSearchBeginPos) !=3D -1) { + const QString foundWord =3D wordRegEx.cap(0); + foundWords << foundWord; + wordSearchBeginPos =3D wordRegEx.indexIn(line, wordSearchBegin= Pos) + wordRegEx.matchedLength(); + } + } + foundWords =3D QSet::fromList(foundWords).toList(); + qSort(foundWords.begin(), foundWords.end(), caseInsensitiveLessThan); + CompletionStartParams completionStartParams; + completionStartParams.completionType =3D CompletionStartParams::WordFr= omDocument; + completionStartParams.completions =3D foundWords; + completionStartParams.wordStartPos =3D wordBeforeCursorBegin(); + return completionStartParams; +} + +QString Completer::wordBeforeCursor() +{ + const int wordBeforeCursorBegin =3D this->wordBeforeCursorBegin(); + return m_edit->text().mid(wordBeforeCursorBegin, m_edit->cursorPositio= n() - wordBeforeCursorBegin); +} + +int Completer::wordBeforeCursorBegin() +{ + int wordBeforeCursorBegin =3D m_edit->cursorPosition() - 1; + while (wordBeforeCursorBegin >=3D 0 && (m_edit->text()[wordBeforeCurso= rBegin].isLetterOrNumber() || m_edit->text()[wordBeforeCursorBegin] =3D=3D = QLatin1Char('_'))) { + wordBeforeCursorBegin--; + } + wordBeforeCursorBegin++; + return wordBeforeCursorBegin; +} + +void Completer::abortCompletionAndResetToPreCompletion() +{ + deactivateCompletion(); + m_isNextTextChangeDueToCompletionChange =3D true; + m_edit->setText(m_textToRevertToIfCompletionAborted); + m_edit->setCursorPosition(m_cursorPosToRevertToIfCompletionAborted); + m_isNextTextChangeDueToCompletionChange =3D false; +} + diff --git a/src/vimode/emulatedcommandbar/completer.h b/src/vimode/emulate= dcommandbar/completer.h index aed09ea..0fb5d3d 100644 --- a/src/vimode/emulatedcommandbar/completer.h +++ b/src/vimode/emulatedcommandbar/completer.h @@ -3,8 +3,23 @@ = #include = +#include + +namespace KTextEditor +{ + class ViewPrivate; +} + +class QLineEdit; +class QCompleter; +class QStringListModel; +class QKeyEvent; + namespace KateVi { + class ActiveMode; + class EmulatedCommandBar; + struct CompletionStartParams { static CompletionStartParams createModeSpecific(const QStringList&= completions, int wordStartPos, std::function comp= letionTransform =3D std::function()) @@ -28,6 +43,40 @@ namespace KateVi QStringList completions; std::function completionTransform; }; + + class Completer + { + public: + enum class CompletionInvocation { ExtraContext, NormalContext }; + Completer(EmulatedCommandBar* emulatedCommandBar, KTextEditor::Vie= wPrivate* view, QLineEdit* edit); + void startCompletion(const CompletionStartParams& completionStartP= arams); + void deactivateCompletion(); + bool isCompletionActive() const; + bool isNextTextChangeDueToCompletionChange() const; + bool completerHandledKeypress(const QKeyEvent* keyEvent); + void editTextChanged(const QString &newText); + void setCurrentMode(ActiveMode* currentMode); + private: + QLineEdit *m_edit; + KTextEditor::ViewPrivate *m_view; + ActiveMode *m_currentMode =3D nullptr; + + void setCompletionIndex(int index); + void currentCompletionChanged(); + void updateCompletionPrefix(); + CompletionStartParams activateWordFromDocumentCompletion(); + QString wordBeforeCursor(); + int wordBeforeCursorBegin(); + void abortCompletionAndResetToPreCompletion(); + + QCompleter *m_completer; + QStringListModel *m_completionModel; + QString m_textToRevertToIfCompletionAborted; + int m_cursorPosToRevertToIfCompletionAborted; + bool m_isNextTextChangeDueToCompletionChange =3D false; + CompletionStartParams m_currentCompletionStartParams; + CompletionStartParams::CompletionType m_currentCompletionType =3D = CompletionStartParams::None; + }; } #endif = diff --git a/src/vimode/emulatedcommandbar/emulatedcommandbar.cpp b/src/vim= ode/emulatedcommandbar/emulatedcommandbar.cpp index 952160f..3075796 100644 --- a/src/vimode/emulatedcommandbar/emulatedcommandbar.cpp +++ b/src/vimode/emulatedcommandbar/emulatedcommandbar.cpp @@ -46,11 +46,8 @@ #include #include #include -#include #include -#include #include -#include = #include = @@ -58,11 +55,6 @@ using namespace KateVi; = namespace { -bool caseInsensitiveLessThan(const QString &s1, const QString &s2) -{ - return s1.toLower() < s2.toLower(); -} - bool isCharEscaped(const QString &string, int charPos) { if (charPos =3D=3D 0) { @@ -411,7 +403,7 @@ void EmulatedCommandBar::closed() m_currentMode =3D nullptr; } = -void EmulatedCommandBar::switchToMode ( EmulatedCommandBar::ActiveMode* ne= wMode ) +void EmulatedCommandBar::switchToMode ( ActiveMode* newMode ) { if (m_currentMode) m_currentMode->deactivate(false); @@ -656,42 +648,6 @@ void EmulatedCommandBar::hideAllWidgetsExcept(QWidget*= widgetToKeepVisible) = } = -EmulatedCommandBar::ActiveMode::~ActiveMode() -{ - -} - -void EmulatedCommandBar::ActiveMode::hideAllWidgetsExcept(QWidget* widgetT= oKeepVisible) -{ - m_emulatedCommandBar->hideAllWidgetsExcept(widgetToKeepVisible); -} - -void EmulatedCommandBar::ActiveMode::moveCursorTo(const KTextEditor::Curso= r &cursorPos) -{ - m_emulatedCommandBar->moveCursorTo(cursorPos); -} - -void EmulatedCommandBar::ActiveMode::updateMatchHighlight(const KTextEdito= r::Range& matchRange) -{ - m_matchHighligher->updateMatchHighlight(matchRange); -} - -void EmulatedCommandBar::ActiveMode::close( bool wasAborted ) -{ - m_emulatedCommandBar->m_wasAborted =3D wasAborted; - m_emulatedCommandBar->hideMe(); -} - -void EmulatedCommandBar::ActiveMode::closeWithStatusMessage(const QString&= exitStatusMessage) -{ - m_emulatedCommandBar->closeWithStatusMessage(exitStatusMessage); -} - -void EmulatedCommandBar::ActiveMode::startCompletion ( const CompletionSta= rtParams& completionStartParams ) -{ - m_emulatedCommandBar->m_completer->startCompletion(completionStartPara= ms); -} - EmulatedCommandBar::InteractiveSedReplaceMode::InteractiveSedReplaceMode(E= mulatedCommandBar* emulatedCommandBar, MatchHighlighter* matchHighlighter) : ActiveMode(emulatedCommandBar, matchHighlighter), m_isActive(false) @@ -700,222 +656,6 @@ EmulatedCommandBar::InteractiveSedReplaceMode::Intera= ctiveSedReplaceMode(Emulate m_interactiveSedReplaceLabel->setObjectName(QStringLiteral("interactiv= esedreplace")); } = -EmulatedCommandBar::Completer::Completer ( EmulatedCommandBar* emulatedCom= mandBar, KTextEditor::ViewPrivate* view, QLineEdit* edit ) - : m_edit(edit), - m_view(view) -{ - m_completer =3D new QCompleter(QStringList(), edit); - // Can't find a way to stop the QCompleter from auto-completing when a= ttached to a QLineEdit, - // so don't actually set it as the QLineEdit's completer. - m_completer->setWidget(edit); - m_completer->setObjectName(QStringLiteral("completer")); - m_completionModel =3D new QStringListModel(emulatedCommandBar); - m_completer->setModel(m_completionModel); - m_completer->setCaseSensitivity(Qt::CaseInsensitive); - m_completer->popup()->installEventFilter(emulatedCommandBar); -} - -void EmulatedCommandBar::Completer::startCompletion ( const CompletionStar= tParams& completionStartParams ) -{ - if (completionStartParams.completionType !=3D CompletionStartParams::N= one) - { - m_completionModel->setStringList(completionStartParams.completions= ); - const QString completionPrefix =3D m_edit->text().mid(completionSt= artParams.wordStartPos, m_edit->cursorPosition() - completionStartParams.wo= rdStartPos); - m_completer->setCompletionPrefix(completionPrefix); - m_completer->complete(); - m_currentCompletionStartParams =3D completionStartParams; - m_currentCompletionType =3D completionStartParams.completionType; - } -} - -void EmulatedCommandBar::Completer::deactivateCompletion() -{ - m_completer->popup()->hide(); - m_currentCompletionType =3D CompletionStartParams::None; -} - -bool EmulatedCommandBar::Completer::isCompletionActive() const -{ - return m_currentCompletionType !=3D CompletionStartParams::None; -} - -bool EmulatedCommandBar::Completer::isNextTextChangeDueToCompletionChange(= ) const -{ - return m_isNextTextChangeDueToCompletionChange; -} - -bool EmulatedCommandBar::Completer::completerHandledKeypress ( const QKeyE= vent* keyEvent ) -{ - if (!m_edit->isVisible()) - return false; - - if (keyEvent->modifiers() =3D=3D Qt::ControlModifier && (keyEvent->key= () =3D=3D Qt::Key_C || keyEvent->key() =3D=3D Qt::Key_BracketLeft)) - { - if (m_currentCompletionType !=3D CompletionStartParams::None && m_= completer->popup()->isVisible()) - { - abortCompletionAndResetToPreCompletion(); - return true; - } - } - if (keyEvent->modifiers() =3D=3D Qt::ControlModifier && keyEvent->key(= ) =3D=3D Qt::Key_Space) { - CompletionStartParams completionStartParams =3D activateWordFromDo= cumentCompletion(); - startCompletion(completionStartParams); - return true; - } - if ((keyEvent->modifiers() =3D=3D Qt::ControlModifier && keyEvent->key= () =3D=3D Qt::Key_P) || keyEvent->key() =3D=3D Qt::Key_Down) { - if (!m_completer->popup()->isVisible()) { - const CompletionStartParams completionStartParams =3D m_curren= tMode->completionInvoked(CompletionInvocation::ExtraContext); - startCompletion(completionStartParams); - if (m_currentCompletionType !=3D CompletionStartParams::None) { - setCompletionIndex(0); - } - } else { - // Descend to next row, wrapping around if necessary. - if (m_completer->currentRow() + 1 =3D=3D m_completer->completi= onCount()) { - setCompletionIndex(0); - } else { - setCompletionIndex(m_completer->currentRow() + 1); - } - } - return true; - } - if ((keyEvent->modifiers() =3D=3D Qt::ControlModifier && keyEvent->key= () =3D=3D Qt::Key_N) || keyEvent->key() =3D=3D Qt::Key_Up) { - if (!m_completer->popup()->isVisible()) { - const CompletionStartParams completionStartParams =3D m_curren= tMode->completionInvoked(CompletionInvocation::NormalContext); - startCompletion(completionStartParams); - setCompletionIndex(m_completer->completionCount() - 1); - } else { - // Ascend to previous row, wrapping around if necessary. - if (m_completer->currentRow() =3D=3D 0) { - setCompletionIndex(m_completer->completionCount() - 1); - } else { - setCompletionIndex(m_completer->currentRow() - 1); - } - } - return true; - } - if (keyEvent->key() =3D=3D Qt::Key_Enter || keyEvent->key() =3D=3D Qt:= :Key_Return) { - if (!m_completer->popup()->isVisible() || m_currentCompletionType = !=3D CompletionStartParams::WordFromDocument) { - m_currentMode->completionChosen(); - } - deactivateCompletion(); - return true; - } - return false; - -} - -void EmulatedCommandBar::Completer::editTextChanged ( const QString& newTe= xt ) -{ - if (!m_isNextTextChangeDueToCompletionChange) { - m_textToRevertToIfCompletionAborted =3D newText; - m_cursorPosToRevertToIfCompletionAborted =3D m_edit->cursorPositio= n(); - } - // If we edit the text after having selected a completion, this means = we implicitly accept it, - // and so we should dismiss it. - if (!m_isNextTextChangeDueToCompletionChange && m_completer->popup()->= currentIndex().row() !=3D -1) { - deactivateCompletion(); - } - - if (m_currentCompletionType !=3D CompletionStartParams::None && !m_isN= extTextChangeDueToCompletionChange) { - updateCompletionPrefix(); - } -} - -void EmulatedCommandBar::Completer::setCurrentMode ( EmulatedCommandBar::A= ctiveMode* currentMode ) -{ - m_currentMode =3D currentMode; -} - -void EmulatedCommandBar::Completer::setCompletionIndex ( int index ) -{ - const QModelIndex modelIndex =3D m_completer->popup()->model()->index(= index, 0); - // Need to set both of these, for some reason. - m_completer->popup()->setCurrentIndex(modelIndex); - m_completer->setCurrentRow(index); - - m_completer->popup()->scrollTo(modelIndex); - - currentCompletionChanged(); -} - -void EmulatedCommandBar::Completer::currentCompletionChanged() -{ - const QString newCompletion =3D m_completer->currentCompletion(); - if (newCompletion.isEmpty()) { - return; - } - QString transformedCompletion =3D newCompletion; - if (m_currentCompletionStartParams.completionTransform) - { - transformedCompletion =3D m_currentCompletionStartParams.completio= nTransform(newCompletion); - } - - m_isNextTextChangeDueToCompletionChange =3D true; - m_edit->setSelection(m_currentCompletionStartParams.wordStartPos, m_ed= it->cursorPosition() - m_currentCompletionStartParams.wordStartPos); - m_edit->insert(transformedCompletion); - m_isNextTextChangeDueToCompletionChange =3D false; - -} - - -void EmulatedCommandBar::Completer::updateCompletionPrefix() -{ - const QString completionPrefix =3D m_edit->text().mid(m_currentComplet= ionStartParams.wordStartPos, m_edit->cursorPosition() - m_currentCompletion= StartParams.wordStartPos); - m_completer->setCompletionPrefix(completionPrefix); - // Seem to need a call to complete() else the size of the popup box is= not altered appropriately. - m_completer->complete(); -} - -CompletionStartParams EmulatedCommandBar::Completer::activateWordFromDocum= entCompletion() -{ - QRegExp wordRegEx(QLatin1String("\\w{1,}")); - QStringList foundWords; - // Narrow the range of lines we search around the cursor so that we do= n't die on huge files. - const int startLine =3D qMax(0, m_view->cursorPosition().line() - 4096= ); - const int endLine =3D qMin(m_view->document()->lines(), m_view->cursor= Position().line() + 4096); - for (int lineNum =3D startLine; lineNum < endLine; lineNum++) { - const QString line =3D m_view->document()->line(lineNum); int word= SearchBeginPos =3D 0; - while (wordRegEx.indexIn(line, wordSearchBeginPos) !=3D -1) { - const QString foundWord =3D wordRegEx.cap(0); - foundWords << foundWord; - wordSearchBeginPos =3D wordRegEx.indexIn(line, wordSearchBegin= Pos) + wordRegEx.matchedLength(); - } - } - foundWords =3D QSet::fromList(foundWords).toList(); - qSort(foundWords.begin(), foundWords.end(), caseInsensitiveLessThan); - CompletionStartParams completionStartParams; - completionStartParams.completionType =3D CompletionStartParams::WordFr= omDocument; - completionStartParams.completions =3D foundWords; - completionStartParams.wordStartPos =3D wordBeforeCursorBegin(); - return completionStartParams; -} - -QString EmulatedCommandBar::Completer::wordBeforeCursor() -{ - const int wordBeforeCursorBegin =3D this->wordBeforeCursorBegin(); - return m_edit->text().mid(wordBeforeCursorBegin, m_edit->cursorPositio= n() - wordBeforeCursorBegin); -} - -int EmulatedCommandBar::Completer::wordBeforeCursorBegin() -{ - int wordBeforeCursorBegin =3D m_edit->cursorPosition() - 1; - while (wordBeforeCursorBegin >=3D 0 && (m_edit->text()[wordBeforeCurso= rBegin].isLetterOrNumber() || m_edit->text()[wordBeforeCursorBegin] =3D=3D = QLatin1Char('_'))) { - wordBeforeCursorBegin--; - } - wordBeforeCursorBegin++; - return wordBeforeCursorBegin; -} - -void EmulatedCommandBar::Completer::abortCompletionAndResetToPreCompletion= () -{ - deactivateCompletion(); - m_isNextTextChangeDueToCompletionChange =3D true; - m_edit->setText(m_textToRevertToIfCompletionAborted); - m_edit->setCursorPosition(m_cursorPosToRevertToIfCompletionAborted); - m_isNextTextChangeDueToCompletionChange =3D false; -} - void EmulatedCommandBar::InteractiveSedReplaceMode::activate(QSharedPointe= r interactiveSedReplace) { Q_ASSERT_X(interactiveSedReplace->currentMatch().isValid(), "startInte= ractiveSearchAndReplace", "KateCommands shouldn't initiate an interactive s= ed replace with no initial match"); @@ -1095,7 +835,7 @@ void EmulatedCommandBar::SearchMode::deactivate(bool w= asAborted) m_viInputModeManager->globalState()->searchHistory()->append(m_edit->t= ext()); } = -CompletionStartParams EmulatedCommandBar::SearchMode::completionInvoked ( = EmulatedCommandBar::Completer::CompletionInvocation invocationType ) +CompletionStartParams EmulatedCommandBar::SearchMode::completionInvoked ( = Completer::CompletionInvocation invocationType ) { Q_UNUSED(invocationType); return activateSearchHistoryCompletion(); @@ -1217,10 +957,10 @@ void EmulatedCommandBar::CommandMode::deactivate ( b= ool wasAborted ) = } = -CompletionStartParams EmulatedCommandBar::CommandMode::completionInvoked(E= mulatedCommandBar::Completer::CompletionInvocation invocationType) +CompletionStartParams EmulatedCommandBar::CommandMode::completionInvoked(C= ompleter::CompletionInvocation invocationType) { CompletionStartParams completionStartParams; - if (invocationType =3D=3D EmulatedCommandBar::Completer::CompletionInv= ocation::ExtraContext) + if (invocationType =3D=3D Completer::CompletionInvocation::ExtraContex= t) { if (isCursorInFindTermOfSed()) { completionStartParams =3D activateSedFindHistoryCompletion(); diff --git a/src/vimode/emulatedcommandbar/emulatedcommandbar.h b/src/vimod= e/emulatedcommandbar/emulatedcommandbar.h index 720bb9b..0e2f708 100644 --- a/src/vimode/emulatedcommandbar/emulatedcommandbar.h +++ b/src/vimode/emulatedcommandbar/emulatedcommandbar.h @@ -27,7 +27,7 @@ #include #include #include "../searcher.h" -#include "completer.h" +#include "activemode.h" = namespace KTextEditor { class ViewPrivate; @@ -35,8 +35,6 @@ namespace KTextEditor { } = class QLabel; -class QCompleter; -class QStringListModel; = namespace KateVi { @@ -86,78 +84,10 @@ private: = QScopedPointer m_matchHighligher; = - class ActiveMode; - class Completer - { - public: - enum class CompletionInvocation { ExtraContext, NormalContext }; - Completer(EmulatedCommandBar* emulatedCommandBar, KTextEditor::Vie= wPrivate* view, QLineEdit* edit); - void startCompletion(const CompletionStartParams& completionStartP= arams); - void deactivateCompletion(); - bool isCompletionActive() const; - bool isNextTextChangeDueToCompletionChange() const; - bool completerHandledKeypress(const QKeyEvent* keyEvent); - void editTextChanged(const QString &newText); - void setCurrentMode(ActiveMode* currentMode); - private: - QLineEdit *m_edit; - KTextEditor::ViewPrivate *m_view; - ActiveMode *m_currentMode =3D nullptr; - - void setCompletionIndex(int index); - void currentCompletionChanged(); - void updateCompletionPrefix(); - CompletionStartParams activateWordFromDocumentCompletion(); - QString wordBeforeCursor(); - int wordBeforeCursorBegin(); - void abortCompletionAndResetToPreCompletion(); - - QCompleter *m_completer; - QStringListModel *m_completionModel; - QString m_textToRevertToIfCompletionAborted; - int m_cursorPosToRevertToIfCompletionAborted; - bool m_isNextTextChangeDueToCompletionChange =3D false; - CompletionStartParams m_currentCompletionStartParams; - CompletionStartParams::CompletionType m_currentCompletionType =3D = CompletionStartParams::None; - }; + friend class ActiveMode; QScopedPointer m_completer; = - class ActiveMode - { - public: - ActiveMode(EmulatedCommandBar* emulatedCommandBar, MatchHighlighte= r* matchHighlighter) - : m_emulatedCommandBar(emulatedCommandBar), - m_matchHighligher(matchHighlighter) - { - } - virtual ~ActiveMode() =3D 0; - virtual bool handleKeyPress(const QKeyEvent *keyEvent) =3D 0; - virtual void editTextChanged(const QString &newText) - { - Q_UNUSED(newText); - } - virtual CompletionStartParams completionInvoked(Completer::Complet= ionInvocation invocationType) - { - Q_UNUSED(invocationType); - return CompletionStartParams(); - }; - virtual void completionChosen() - { - } - virtual void deactivate(bool wasAborted) =3D 0; - protected: - // Helper methods. - void hideAllWidgetsExcept(QWidget* widgetToKeepVisible); - void moveCursorTo(const KTextEditor::Cursor &cursorPos); - void updateMatchHighlight(const KTextEditor::Range &matchRange); - void close(bool wasAborted); - void closeWithStatusMessage(const QString& exitStatusMessage); - void startCompletion(const CompletionStartParams& completionStartP= arams); - EmulatedCommandBar *m_emulatedCommandBar; - private: - MatchHighlighter *m_matchHighligher; - }; - friend ActiveMode; + friend class ActiveMode; = class InteractiveSedReplaceMode : public ActiveMode {