forked from qt-creator/qt-creator
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 <tobias.hunger@qt.io>
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "fossilclient.h"
|
||||
#include "fossileditor.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <coreplugin/id.h>
|
||||
@@ -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<FossilEditorWidget *>(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<FossilEditorWidget *>(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<FossilEditorWidget *>(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,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <utils/synchronousprocess.h>
|
||||
#include <vcsbase/diffandloghighlighter.h>
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QRegExp>
|
||||
#include <QString>
|
||||
#include <QTextCursor>
|
||||
@@ -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<QString> FossilEditorWidget::annotationChanges() const
|
||||
{
|
||||
|
||||
@@ -77,12 +114,12 @@ QSet<QString> FossilEditorWidget::annotationChanges() const
|
||||
|
||||
QSet<QString> 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;
|
||||
}
|
||||
|
||||
@@ -27,26 +27,28 @@
|
||||
|
||||
#include <vcsbase/vcsbaseeditor.h>
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
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<QString> annotationChanges() const final;
|
||||
QString changeUnderCursor(const QTextCursor &cursor) const final;
|
||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes) const final;
|
||||
|
||||
const QRegularExpression m_exactChangesetId;
|
||||
const QRegularExpression m_firstChangesetId;
|
||||
const QRegularExpression m_nextChangesetId;
|
||||
FossilEditorWidgetPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user