Commit 84f2875f authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh
Browse files

Git: Support tree argument for Grep



Change-Id: Ic7dfcd8bad98223d68725f1a0c1f103ad8ea4e0f
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent fcdb286c
...@@ -27,21 +27,26 @@ ...@@ -27,21 +27,26 @@
#include "gitclient.h" #include "gitclient.h"
#include "gitplugin.h" #include "gitplugin.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/vcsmanager.h> #include <coreplugin/vcsmanager.h>
#include <texteditor/findinfiles.h> #include <texteditor/findinfiles.h>
#include <vcsbase/vcscommand.h> #include <vcsbase/vcscommand.h>
#include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseconstants.h>
#include <utils/fancylineedit.h>
#include <utils/filesearch.h> #include <utils/filesearch.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <utils/textfileformat.h>
#include <QCheckBox> #include <QCheckBox>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QHBoxLayout>
#include <QRegularExpressionValidator>
#include <QScopedPointer> #include <QScopedPointer>
#include <QSettings> #include <QSettings>
#include <QTextStream> #include <QTextStream>
...@@ -49,6 +54,13 @@ ...@@ -49,6 +54,13 @@
namespace Git { namespace Git {
namespace Internal { namespace Internal {
class GitGrepParameters
{
public:
QString ref;
bool isEnabled = false;
};
using namespace Core; using namespace Core;
using namespace Utils; using namespace Utils;
using VcsBase::VcsCommand; using VcsBase::VcsCommand;
...@@ -56,6 +68,7 @@ using VcsBase::VcsCommand; ...@@ -56,6 +68,7 @@ using VcsBase::VcsCommand;
namespace { namespace {
const char EnableGitGrep[] = "EnableGitGrep"; const char EnableGitGrep[] = "EnableGitGrep";
const char GitGrepRef[] = "GitGrepRef";
class GitGrepRunner : public QObject class GitGrepRunner : public QObject
{ {
...@@ -78,8 +91,10 @@ public: ...@@ -78,8 +91,10 @@ public:
static const QLatin1String resetColor("\x1b[m"); static const QLatin1String resetColor("\x1b[m");
FileSearchResult single; FileSearchResult single;
const int lineSeparator = line.indexOf(QChar::Null); const int lineSeparator = line.indexOf(QChar::Null);
single.fileName = m_directory + QLatin1Char('/') QString filePath = line.left(lineSeparator);
+ line.left(lineSeparator); if (!m_ref.isEmpty() && filePath.startsWith(m_ref))
filePath.remove(0, m_ref.length());
single.fileName = m_directory + QLatin1Char('/') + filePath;
const int textSeparator = line.indexOf(QChar::Null, lineSeparator + 1); const int textSeparator = line.indexOf(QChar::Null, lineSeparator + 1);
single.lineNumber = line.mid(lineSeparator + 1, textSeparator - lineSeparator - 1).toInt(); single.lineNumber = line.mid(lineSeparator + 1, textSeparator - lineSeparator - 1).toInt();
QString text = line.mid(textSeparator + 1); QString text = line.mid(textSeparator + 1);
...@@ -130,6 +145,11 @@ public: ...@@ -130,6 +145,11 @@ public:
else else
arguments << QLatin1String("-F"); arguments << QLatin1String("-F");
arguments << m_parameters.text; arguments << m_parameters.text;
GitGrepParameters params = m_parameters.extensionParameters.value<GitGrepParameters>();
if (!params.ref.isEmpty()) {
arguments << params.ref;
m_ref = params.ref + QLatin1Char(':');
}
arguments << QLatin1String("--") << m_parameters.nameFilters; arguments << QLatin1String("--") << m_parameters.nameFilters;
GitClient *client = GitPlugin::instance()->client(); GitClient *client = GitPlugin::instance()->client();
QScopedPointer<VcsCommand> command(client->createCommand(m_directory)); QScopedPointer<VcsCommand> command(client->createCommand(m_directory));
...@@ -166,6 +186,7 @@ public: ...@@ -166,6 +186,7 @@ public:
private: private:
FutureInterfaceType m_fi; FutureInterfaceType m_fi;
QString m_directory; QString m_directory;
QString m_ref;
const TextEditor::FileFindParameters &m_parameters; const TextEditor::FileFindParameters &m_parameters;
}; };
...@@ -180,9 +201,21 @@ static bool validateDirectory(const QString &path) ...@@ -180,9 +201,21 @@ static bool validateDirectory(const QString &path)
GitGrep::GitGrep() GitGrep::GitGrep()
{ {
m_widget = new QCheckBox(tr("&Use Git Grep")); m_widget = new QWidget;
m_widget->setToolTip(tr("Use Git Grep for searching. This includes only files " auto layout = new QHBoxLayout(m_widget);
"that are managed by source control.")); layout->setMargin(0);
m_enabledCheckBox = new QCheckBox(tr("&Use Git Grep"));
m_enabledCheckBox->setToolTip(tr("Use Git Grep for searching. This includes only files "
"that are managed by Git."));
layout->addWidget(m_enabledCheckBox);
m_treeLineEdit = new FancyLineEdit;
m_treeLineEdit->setPlaceholderText(
tr("Tree: add reference here or leave empty to search through the file system)"));
m_treeLineEdit->setToolTip(
tr("Reference can be HEAD, tag, local or remote branch, or a commit hash."));
const QRegularExpression refExpression(QLatin1String("[\\w/]*"));
m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this));
layout->addWidget(m_treeLineEdit);
TextEditor::FindInFiles *findInFiles = TextEditor::FindInFiles::instance(); TextEditor::FindInFiles *findInFiles = TextEditor::FindInFiles::instance();
QTC_ASSERT(findInFiles, return); QTC_ASSERT(findInFiles, return);
connect(findInFiles, &TextEditor::FindInFiles::pathChanged, connect(findInFiles, &TextEditor::FindInFiles::pathChanged,
...@@ -202,6 +235,14 @@ QString GitGrep::title() const ...@@ -202,6 +235,14 @@ QString GitGrep::title() const
return tr("Git Grep"); return tr("Git Grep");
} }
QString GitGrep::toolTip() const
{
const QString ref = m_treeLineEdit->text();
if (!ref.isEmpty())
return tr("Ref: %1\n%2").arg(ref);
return QLatin1String("%1");
}
QWidget *GitGrep::widget() const QWidget *GitGrep::widget() const
{ {
return m_widget; return m_widget;
...@@ -209,27 +250,32 @@ QWidget *GitGrep::widget() const ...@@ -209,27 +250,32 @@ QWidget *GitGrep::widget() const
bool GitGrep::isEnabled() const bool GitGrep::isEnabled() const
{ {
return m_widget->isEnabled() && m_widget->isChecked(); return m_widget->isEnabled() && m_enabledCheckBox->isChecked();
} }
bool GitGrep::isEnabled(const TextEditor::FileFindParameters &parameters) const bool GitGrep::isEnabled(const TextEditor::FileFindParameters &parameters) const
{ {
return parameters.extensionParameters.toBool(); return parameters.extensionParameters.value<GitGrepParameters>().isEnabled;
} }
QVariant GitGrep::parameters() const QVariant GitGrep::parameters() const
{ {
return isEnabled(); GitGrepParameters params;
params.isEnabled = isEnabled();
params.ref = m_treeLineEdit->text();
return qVariantFromValue(params);
} }
void GitGrep::readSettings(QSettings *settings) void GitGrep::readSettings(QSettings *settings)
{ {
m_widget->setChecked(settings->value(QLatin1String(EnableGitGrep), false).toBool()); m_enabledCheckBox->setChecked(settings->value(QLatin1String(EnableGitGrep), false).toBool());
m_treeLineEdit->setText(settings->value(QLatin1String(GitGrepRef)).toString());
} }
void GitGrep::writeSettings(QSettings *settings) const void GitGrep::writeSettings(QSettings *settings) const
{ {
settings->setValue(QLatin1String(EnableGitGrep), m_widget->isChecked()); settings->setValue(QLatin1String(EnableGitGrep), m_enabledCheckBox->isChecked());
settings->setValue(QLatin1String(GitGrepRef), m_treeLineEdit->text());
} }
QFuture<FileSearchResultList> GitGrep::executeSearch( QFuture<FileSearchResultList> GitGrep::executeSearch(
...@@ -238,5 +284,37 @@ QFuture<FileSearchResultList> GitGrep::executeSearch( ...@@ -238,5 +284,37 @@ QFuture<FileSearchResultList> GitGrep::executeSearch(
return Utils::runAsync(GitGrepRunner::run, parameters); return Utils::runAsync(GitGrepRunner::run, parameters);
} }
IEditor *GitGrep::openEditor(const SearchResultItem &item,
const TextEditor::FileFindParameters &parameters)
{
GitGrepParameters params = parameters.extensionParameters.value<GitGrepParameters>();
if (!params.isEnabled || params.ref.isEmpty() || item.path.isEmpty())
return nullptr;
const QString path = QDir::fromNativeSeparators(item.path.first());
QByteArray content;
GitClient *client = GitPlugin::instance()->client();
const QString topLevel = parameters.additionalParameters.toString();
const QString relativePath = QDir(topLevel).relativeFilePath(path);
if (!client->synchronousShow(topLevel, params.ref + QLatin1String(":./") + relativePath,
&content, nullptr)) {
return nullptr;
}
if (content.isEmpty())
return nullptr;
QByteArray fileContent;
if (TextFileFormat::readFileUTF8(path, 0, &fileContent, 0) == TextFileFormat::ReadSuccess) {
if (fileContent == content)
return nullptr; // open the file for read/write
}
QString title = tr("Git Show %1:%2").arg(params.ref).arg(relativePath);
IEditor *editor = EditorManager::openEditorWithContents(Id(), &title, content, title,
EditorManager::DoNotSwitchToDesignMode);
editor->gotoLine(item.lineNumber, item.textMarkPos);
editor->document()->setTemporary(true);
return editor;
}
} // Internal } // Internal
} // Git } // Git
Q_DECLARE_METATYPE(Git::Internal::GitGrepParameters)
...@@ -28,10 +28,12 @@ ...@@ -28,10 +28,12 @@
#include <texteditor/basefilefind.h> #include <texteditor/basefilefind.h>
#include <utils/fileutils.h> #include <QCoreApplication>
QT_FORWARD_DECLARE_CLASS(QCheckBox) QT_FORWARD_DECLARE_CLASS(QCheckBox)
namespace Utils { class FancyLineEdit; }
namespace Git { namespace Git {
namespace Internal { namespace Internal {
...@@ -43,6 +45,7 @@ public: ...@@ -43,6 +45,7 @@ public:
GitGrep(); GitGrep();
~GitGrep() override; ~GitGrep() override;
QString title() const override; QString title() const override;
QString toolTip() const override;
QWidget *widget() const override; QWidget *widget() const override;
bool isEnabled() const override; bool isEnabled() const override;
bool isEnabled(const TextEditor::FileFindParameters &parameters) const override; bool isEnabled(const TextEditor::FileFindParameters &parameters) const override;
...@@ -51,9 +54,13 @@ public: ...@@ -51,9 +54,13 @@ public:
void writeSettings(QSettings *settings) const override; void writeSettings(QSettings *settings) const override;
QFuture<Utils::FileSearchResultList> executeSearch( QFuture<Utils::FileSearchResultList> executeSearch(
const TextEditor::FileFindParameters &parameters) override; const TextEditor::FileFindParameters &parameters) override;
Core::IEditor *openEditor(const Core::SearchResultItem &item,
const TextEditor::FileFindParameters &parameters) override;
private: private:
QCheckBox *m_widget; QWidget *m_widget;
QCheckBox *m_enabledCheckBox;
Utils::FancyLineEdit *m_treeLineEdit;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -140,8 +140,11 @@ void BaseFileFind::runNewSearch(const QString &txt, FindFlags findFlags, ...@@ -140,8 +140,11 @@ void BaseFileFind::runNewSearch(const QString &txt, FindFlags findFlags,
d->m_currentFindSupport = 0; d->m_currentFindSupport = 0;
if (d->m_filterCombo) if (d->m_filterCombo)
updateComboEntries(d->m_filterCombo, true); updateComboEntries(d->m_filterCombo, true);
QString tooltip = toolTip();
if (d->m_extension)
tooltip = tooltip.arg(d->m_extension->toolTip());
SearchResult *search = SearchResultWindow::instance()->startNewSearch(label(), SearchResult *search = SearchResultWindow::instance()->startNewSearch(label(),
toolTip().arg(IFindFilter::descriptionForFindFlags(findFlags)), tooltip.arg(IFindFilter::descriptionForFindFlags(findFlags)),
txt, searchMode, SearchResultWindow::PreserveCaseEnabled, txt, searchMode, SearchResultWindow::PreserveCaseEnabled,
QString::fromLatin1("TextEditor")); QString::fromLatin1("TextEditor"));
search->setTextToReplace(txt); search->setTextToReplace(txt);
...@@ -320,14 +323,19 @@ void BaseFileFind::updateComboEntries(QComboBox *combo, bool onTop) ...@@ -320,14 +323,19 @@ void BaseFileFind::updateComboEntries(QComboBox *combo, bool onTop)
void BaseFileFind::openEditor(const SearchResultItem &item) void BaseFileFind::openEditor(const SearchResultItem &item)
{ {
SearchResult *result = qobject_cast<SearchResult *>(sender()); SearchResult *result = qobject_cast<SearchResult *>(sender());
FileFindParameters parameters = result->userData().value<FileFindParameters>();
IEditor *openedEditor = 0; IEditor *openedEditor = 0;
if (item.path.size() > 0) { if (d->m_extension)
openedEditor = EditorManager::openEditorAt(QDir::fromNativeSeparators(item.path.first()), openedEditor = d->m_extension->openEditor(item, parameters);
item.lineNumber, if (!openedEditor) {
item.textMarkPos, Id(), if (item.path.size() > 0) {
EditorManager::DoNotSwitchToDesignMode); openedEditor = EditorManager::openEditorAt(QDir::fromNativeSeparators(item.path.first()),
} else { item.lineNumber,
openedEditor = EditorManager::openEditor(QDir::fromNativeSeparators(item.text)); item.textMarkPos, Id(),
EditorManager::DoNotSwitchToDesignMode);
} else {
openedEditor = EditorManager::openEditor(QDir::fromNativeSeparators(item.text));
}
} }
if (d->m_currentFindSupport) if (d->m_currentFindSupport)
d->m_currentFindSupport->clearHighlights(); d->m_currentFindSupport->clearHighlights();
...@@ -336,11 +344,8 @@ void BaseFileFind::openEditor(const SearchResultItem &item) ...@@ -336,11 +344,8 @@ void BaseFileFind::openEditor(const SearchResultItem &item)
return; return;
// highlight results // highlight results
if (IFindSupport *findSupport = Aggregation::query<IFindSupport>(openedEditor->widget())) { if (IFindSupport *findSupport = Aggregation::query<IFindSupport>(openedEditor->widget())) {
if (result) { d->m_currentFindSupport = findSupport;
FileFindParameters parameters = result->userData().value<FileFindParameters>(); d->m_currentFindSupport->highlightAll(parameters.text, parameters.flags);
d->m_currentFindSupport = findSupport;
d->m_currentFindSupport->highlightAll(parameters.text, parameters.flags);
}
} }
} }
......
...@@ -41,9 +41,10 @@ QT_END_NAMESPACE ...@@ -41,9 +41,10 @@ QT_END_NAMESPACE
namespace Utils { class FileIterator; } namespace Utils { class FileIterator; }
namespace Core { namespace Core {
class IEditor;
class IFindSupport;
class SearchResult; class SearchResult;
class SearchResultItem; class SearchResultItem;
class IFindSupport;
} // namespace Core } // namespace Core
namespace TextEditor { namespace TextEditor {
...@@ -65,6 +66,7 @@ class TEXTEDITOR_EXPORT FileFindExtension : public QObject ...@@ -65,6 +66,7 @@ class TEXTEDITOR_EXPORT FileFindExtension : public QObject
public: public:
virtual ~FileFindExtension() {} virtual ~FileFindExtension() {}
virtual QString title() const = 0; virtual QString title() const = 0;
virtual QString toolTip() const = 0; // add %1 placeholder where the find flags should be put
virtual QWidget *widget() const = 0; virtual QWidget *widget() const = 0;
virtual bool isEnabled() const = 0; virtual bool isEnabled() const = 0;
virtual bool isEnabled(const FileFindParameters &parameters) const = 0; virtual bool isEnabled(const FileFindParameters &parameters) const = 0;
...@@ -73,6 +75,8 @@ public: ...@@ -73,6 +75,8 @@ public:
virtual void writeSettings(QSettings *settings) const = 0; virtual void writeSettings(QSettings *settings) const = 0;
virtual QFuture<Utils::FileSearchResultList> executeSearch( virtual QFuture<Utils::FileSearchResultList> executeSearch(
const FileFindParameters &parameters) = 0; const FileFindParameters &parameters) = 0;
virtual Core::IEditor *openEditor(const Core::SearchResultItem &item,
const FileFindParameters &parameters) = 0;
}; };
class TEXTEDITOR_EXPORT BaseFileFind : public Core::IFindFilter class TEXTEDITOR_EXPORT BaseFileFind : public Core::IFindFilter
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment