From 8cc9b5c57d453ea0de7fe9838b22824c7f9eec21 Mon Sep 17 00:00:00 2001 From: Artur Shepilko Date: Thu, 20 Apr 2017 02:21:51 -0500 Subject: Vcs: Jump to the current source line in Fossil Annotate editor * Keep track of the current source line number and pass it to Annotate action. * Add a 'List Versions' toggle in Annotate editor to prepend a list of commits that make up the annotated source. * By default do not show the version list so that annotated line number could be matched to the source line. NOTE: VcsBaseEditorWidget::configurationWidget() query is no longer available, yet Fossil client needs it in order to process the effective arguments. So we re-implement it in FossilEditorWidget sub-class. Change-Id: Idc4c21d074ccf4e1c6d041cce2abceb78665c8f2 Reviewed-by: Tobias Hunger --- plugins/fossil/fossilclient.cpp | 96 +++++++++++++++++++++++++++------------ plugins/fossil/fossileditor.cpp | 57 +++++++++++++++++++---- plugins/fossil/fossileditor.h | 12 +++-- plugins/fossil/fossilplugin.cpp | 3 +- plugins/fossil/fossilsettings.cpp | 2 + plugins/fossil/fossilsettings.h | 1 + 6 files changed, 127 insertions(+), 44 deletions(-) diff --git a/plugins/fossil/fossilclient.cpp b/plugins/fossil/fossilclient.cpp index bb8bcee..584fc81 100644 --- a/plugins/fossil/fossilclient.cpp +++ b/plugins/fossil/fossilclient.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "fossilclient.h" +#include "fossileditor.h" #include "constants.h" #include @@ -93,6 +94,13 @@ public: mapSetting(addToggleButton("|BLAME|", tr("Show Committers")), settings.boolPointer(FossilSettings::annotateShowCommittersKey)); } + + // Force listVersions setting to false by default. + // This way the annotated line number would not get offset by the version list. + settings.setValue(FossilSettings::annotateListVersionsKey, false); + + mapSetting(addToggleButton(QLatin1String("--log"), tr("List Versions")), + settings.boolPointer(FossilSettings::annotateListVersionsKey)); } }; @@ -725,19 +733,34 @@ VcsBase::VcsBaseEditorWidget *FossilClient::annotate( VcsBase::VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, VcsBase::VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); - QStringList effectiveArgs = extraOptions; - if (!editor->configurationAdded()) { - if (VcsBase::VcsBaseEditorConfig *editorConfig = createAnnotateEditor(editor)) { + + // We need to be able to re-query the configuration widget for the arguments + // each time the Annotate is requested from the main menu. This allows processing of + // the effective args controlled via configuration widget. + // However VcsBaseEditorWidget no longer stores the configuration widget and thus + // does not support configurationWidget() query. + // So we re-implement the configurationWidget() in FossilEditorWidget sub-class. + + auto *fossilEditor = qobject_cast(editor); + QTC_ASSERT(fossilEditor, return editor); + + if (!fossilEditor->configurationAdded()) { + if (VcsBase::VcsBaseEditorConfig *editorConfig = createAnnotateEditor(fossilEditor)) { + editorConfig->setBaseArguments(extraOptions); // editor has been just created, createVcsEditor() didn't set a configuration widget yet connect(editorConfig, &VcsBase::VcsBaseEditorConfig::commandExecutionRequested, - [=] { return this->annotate(workingDir, file, revision, lineNumber, extraOptions + editorConfig->arguments()); } ); - effectiveArgs += editorConfig->arguments(); - editor->setConfigurationAdded(); + [=]() { + const int line = VcsBase::VcsBaseEditor::lineNumberOfCurrentEditor(); + return this->annotate(workingDir, file, revision, line, editorConfig->arguments()); + } ); + fossilEditor->setConfigurationWidget(editorConfig); } } + QStringList effectiveArgs = extraOptions; + if (VcsBase::VcsBaseEditorConfig *editorConfig = fossilEditor->configurationWidget()) + effectiveArgs = editorConfig->arguments(); - VcsBase::VcsCommand *cmd = createCommand(workingDir, editor); - cmd->setCookie(lineNumber); + VcsBase::VcsCommand *cmd = createCommand(workingDir, fossilEditor); // here we introduce a "|BLAME|" meta-option to allow both annotate and blame modes int pos = effectiveArgs.indexOf("|BLAME|"); @@ -746,10 +769,15 @@ VcsBase::VcsBaseEditorWidget *FossilClient::annotate( effectiveArgs.removeAt(pos); } QStringList args(vcsCmdString); - args << revisionSpec(revision) << effectiveArgs << "--log" << file; + args << revisionSpec(revision) << effectiveArgs << file; + + // When version list requested, ignore the source line. + if (args.contains("--log")) + lineNumber = -1; + cmd->setCookie(lineNumber); enqueueJob(cmd, args); - return editor; + return fossilEditor; } bool FossilClient::isVcsFileOrDirectory(const Utils::FileName &fileName) const @@ -926,28 +954,34 @@ void FossilClient::log(const QString &workingDir, const QStringList &files, VcsBase::VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, VcsBase::VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); - editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); - QStringList effectiveArgs = extraOptions; - if (!editor->configurationAdded()) { - if (VcsBase::VcsBaseEditorConfig *editorConfig = createLogEditor(editor)) { + auto *fossilEditor = qobject_cast(editor); + QTC_ASSERT(fossilEditor, return); + + fossilEditor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); + + if (!fossilEditor->configurationAdded()) { + if (VcsBase::VcsBaseEditorConfig *editorConfig = createLogEditor(fossilEditor)) { + editorConfig->setBaseArguments(extraOptions); // editor has been just created, createVcsEditor() didn't set a configuration widget yet connect(editorConfig, &VcsBase::VcsBaseEditorConfig::commandExecutionRequested, - [=]() { this->log(workingDir, files, extraOptions + editorConfig->arguments(), enableAnnotationContextMenu); } ); - effectiveArgs += editorConfig->arguments(); - editor->setConfigurationAdded(); + [=]() { this->log(workingDir, files, editorConfig->arguments(), enableAnnotationContextMenu); } ); + fossilEditor->setConfigurationWidget(editorConfig); } } + QStringList effectiveArgs = extraOptions; + if (VcsBase::VcsBaseEditorConfig *editorConfig = fossilEditor->configurationWidget()) + effectiveArgs = editorConfig->arguments(); //@TODO: move highlighter and widgets to fossil editor sources. - new FossilLogHighlighter(editor->document()); + new FossilLogHighlighter(fossilEditor->document()); QStringList args(vcsCmdString); args << effectiveArgs; if (!files.isEmpty()) args << "--path" << files; - enqueueJob(createCommand(workingDir, editor), args); + enqueueJob(createCommand(workingDir, fossilEditor), args); } void FossilClient::logCurrentFile(const QString &workingDir, const QStringList &files, @@ -972,26 +1006,32 @@ void FossilClient::logCurrentFile(const QString &workingDir, const QStringList & VcsBase::VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, VcsBase::VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); - editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); - QStringList effectiveArgs = extraOptions; - if (!editor->configurationAdded()) { - if (VcsBase::VcsBaseEditorConfig *editorConfig = createLogEditor(editor)) { + auto *fossilEditor = qobject_cast(editor); + QTC_ASSERT(fossilEditor, return); + + fossilEditor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); + + if (!fossilEditor->configurationAdded()) { + if (VcsBase::VcsBaseEditorConfig *editorConfig = createLogEditor(fossilEditor)) { + editorConfig->setBaseArguments(extraOptions); // editor has been just created, createVcsEditor() didn't set a configuration widget yet connect(editorConfig, &VcsBase::VcsBaseEditorConfig::commandExecutionRequested, - [=]() { this->logCurrentFile(workingDir, files, extraOptions + editorConfig->arguments(), enableAnnotationContextMenu); } ); - effectiveArgs += editorConfig->arguments(); - editor->setConfigurationAdded(); + [=]() { this->logCurrentFile(workingDir, files, editorConfig->arguments(), enableAnnotationContextMenu); } ); + fossilEditor->setConfigurationWidget(editorConfig); } } + QStringList effectiveArgs = extraOptions; + if (VcsBase::VcsBaseEditorConfig *editorConfig = fossilEditor->configurationWidget()) + effectiveArgs = editorConfig->arguments(); //@TODO: move highlighter and widgets to fossil editor sources. - new FossilLogHighlighter(editor->document()); + new FossilLogHighlighter(fossilEditor->document()); QStringList args(vcsCmdString); args << effectiveArgs << files; - enqueueJob(createCommand(workingDir, editor), args); + enqueueJob(createCommand(workingDir, fossilEditor), args); } void FossilClient::revertFile(const QString &workingDir, diff --git a/plugins/fossil/fossileditor.cpp b/plugins/fossil/fossileditor.cpp index c379fd9..2c36f3b 100644 --- a/plugins/fossil/fossileditor.cpp +++ b/plugins/fossil/fossileditor.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -44,15 +45,31 @@ namespace Fossil { namespace Internal { -FossilEditorWidget::FossilEditorWidget() : - m_exactChangesetId(Constants::CHANGESET_ID_EXACT), - m_firstChangesetId(QString("\n") + Constants::CHANGESET_ID + " "), - m_nextChangesetId(m_firstChangesetId) +class FossilEditorWidgetPrivate { - QTC_ASSERT(m_exactChangesetId.isValid(), return); - QTC_ASSERT(m_firstChangesetId.isValid(), return); - QTC_ASSERT(m_nextChangesetId.isValid(), return); +public: + FossilEditorWidgetPrivate() : + m_exactChangesetId(Constants::CHANGESET_ID_EXACT), + m_firstChangesetId(QString("\n") + Constants::CHANGESET_ID + " "), + m_nextChangesetId(m_firstChangesetId), + m_configurationWidget(nullptr) + { + QTC_ASSERT(m_exactChangesetId.isValid(), return); + QTC_ASSERT(m_firstChangesetId.isValid(), return); + QTC_ASSERT(m_nextChangesetId.isValid(), return); + } + + + const QRegularExpression m_exactChangesetId; + const QRegularExpression m_firstChangesetId; + const QRegularExpression m_nextChangesetId; + + VcsBase::VcsBaseEditorConfig *m_configurationWidget; +}; +FossilEditorWidget::FossilEditorWidget() : + d(new FossilEditorWidgetPrivate) +{ setAnnotateRevisionTextFormat(tr("&Annotate %1")); setAnnotatePreviousRevisionTextFormat(tr("Annotate &Parent Revision %1")); @@ -65,6 +82,26 @@ FossilEditorWidget::FossilEditorWidget() : setLogEntryPattern(logChangePattern); } +FossilEditorWidget::~FossilEditorWidget() +{ + delete d; +} + +bool FossilEditorWidget::setConfigurationWidget(VcsBase::VcsBaseEditorConfig *w) +{ + if (configurationAdded()) + return false; + + d->m_configurationWidget = w; + setConfigurationAdded(); + return true; +} + +VcsBase::VcsBaseEditorConfig *FossilEditorWidget::configurationWidget() const +{ + return d->m_configurationWidget; +} + QSet FossilEditorWidget::annotationChanges() const { @@ -77,12 +114,12 @@ QSet FossilEditorWidget::annotationChanges() const QSet changes; - QRegularExpressionMatch firstChangesetIdMatch = m_firstChangesetId.match(txt); + QRegularExpressionMatch firstChangesetIdMatch = d->m_firstChangesetId.match(txt); if (firstChangesetIdMatch.hasMatch()) { QString changeId = firstChangesetIdMatch.captured(1); changes.insert(changeId); - QRegularExpressionMatchIterator i = m_nextChangesetId.globalMatch(txt); + QRegularExpressionMatchIterator i = d->m_nextChangesetId.globalMatch(txt); while (i.hasNext()) { const QRegularExpressionMatch nextChangesetIdMatch = i.next(); changeId = nextChangesetIdMatch.captured(1); @@ -98,7 +135,7 @@ QString FossilEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) const cursor.select(QTextCursor::WordUnderCursor); if (cursor.hasSelection()) { const QString change = cursor.selectedText(); - QRegularExpressionMatch exactChangesetIdMatch = m_exactChangesetId.match(change); + QRegularExpressionMatch exactChangesetIdMatch = d->m_exactChangesetId.match(change); if (exactChangesetIdMatch.hasMatch()) return change; } diff --git a/plugins/fossil/fossileditor.h b/plugins/fossil/fossileditor.h index e052b93..e9adc35 100644 --- a/plugins/fossil/fossileditor.h +++ b/plugins/fossil/fossileditor.h @@ -27,26 +27,28 @@ #include -#include - namespace Fossil { namespace Internal { +class FossilEditorWidgetPrivate; + class FossilEditorWidget : public VcsBase::VcsBaseEditorWidget { Q_OBJECT public: FossilEditorWidget(); + ~FossilEditorWidget() final; + + bool setConfigurationWidget(VcsBase::VcsBaseEditorConfig *w); + VcsBase::VcsBaseEditorConfig *configurationWidget() const; private: QSet annotationChanges() const final; QString changeUnderCursor(const QTextCursor &cursor) const final; VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet &changes) const final; - const QRegularExpression m_exactChangesetId; - const QRegularExpression m_firstChangesetId; - const QRegularExpression m_nextChangesetId; + FossilEditorWidgetPrivate *d; }; } // namespace Internal diff --git a/plugins/fossil/fossilplugin.cpp b/plugins/fossil/fossilplugin.cpp index f8da7a8..55034fa 100644 --- a/plugins/fossil/fossilplugin.cpp +++ b/plugins/fossil/fossilplugin.cpp @@ -265,7 +265,8 @@ void FossilPlugin::annotateCurrentFile() { const VcsBase::VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - m_client->annotate(state.currentFileTopLevel(), state.relativeCurrentFile()); + const int lineNumber = VcsBase::VcsBaseEditor::lineNumberOfCurrentEditor(state.currentFile()); + m_client->annotate(state.currentFileTopLevel(), state.relativeCurrentFile(), QString(), lineNumber); } void FossilPlugin::diffCurrentFile() diff --git a/plugins/fossil/fossilsettings.cpp b/plugins/fossil/fossilsettings.cpp index e6f4769..f946d7f 100644 --- a/plugins/fossil/fossilsettings.cpp +++ b/plugins/fossil/fossilsettings.cpp @@ -36,6 +36,7 @@ const QString FossilSettings::sslIdentityFileKey("sslIdentityFile"); const QString FossilSettings::diffIgnoreAllWhiteSpaceKey("diffIgnoreAllWhiteSpace"); const QString FossilSettings::diffStripTrailingCRKey("diffStripTrailingCR"); const QString FossilSettings::annotateShowCommittersKey("annotateShowCommitters"); +const QString FossilSettings::annotateListVersionsKey("annotateListVersions"); const QString FossilSettings::timelineWidthKey("timelineWidth"); const QString FossilSettings::timelineLineageFilterKey("timelineLineageFilter"); const QString FossilSettings::timelineVerboseKey("timelineVerbose"); @@ -52,6 +53,7 @@ FossilSettings::FossilSettings() declareKey(diffIgnoreAllWhiteSpaceKey, false); declareKey(diffStripTrailingCRKey, false); declareKey(annotateShowCommittersKey, false); + declareKey(annotateListVersionsKey, false); declareKey(timelineWidthKey, 0); declareKey(timelineLineageFilterKey, ""); declareKey(timelineVerboseKey, false); diff --git a/plugins/fossil/fossilsettings.h b/plugins/fossil/fossilsettings.h index 5a82e8d..3e58e77 100644 --- a/plugins/fossil/fossilsettings.h +++ b/plugins/fossil/fossilsettings.h @@ -38,6 +38,7 @@ public: static const QString diffIgnoreAllWhiteSpaceKey; static const QString diffStripTrailingCRKey; static const QString annotateShowCommittersKey; + static const QString annotateListVersionsKey; static const QString timelineWidthKey; static const QString timelineLineageFilterKey; static const QString timelineVerboseKey; -- cgit v1.2.3