forked from qt-creator/qt-creator
Display parent functions in the Find Usages menu
To display the parent function, first we find it in displayResults and store the information to SearchResultItem, then SearchResultTreeItemDelegate gets the information and renders it. Similar approach is applied to ClangdClient, in addSearchResultsForFile. This change also adds default style for containing function highlight in the search. Default foreground and background colors are same as usual text colors. Task-number: QTCREATORBUG-27550 Change-Id: Id1251afa192f8d1232524742b7c211770bcb83fb Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
<style name="SearchResult" background="#8a7f2c"/>
|
||||
<style name="SearchResultAlt1" foreground="#aaaaff" background="#363655"/>
|
||||
<style name="SearchResultAlt2" foreground="#ffaaaa" background="#553636"/>
|
||||
<style name="SearchResultContainingFunction" foreground="#d6cf9a" background="#2e2f30"/>
|
||||
<style name="SearchScope" background="#8a602c"/>
|
||||
<style name="Parentheses" foreground="#bec0c2" background="#1d545c"/>
|
||||
<style name="ParenthesesMismatch" background="#ff6aad"/>
|
||||
|
@@ -36,6 +36,7 @@
|
||||
<style name="SearchResult" background="#555500"/>
|
||||
<style name="SearchResultAlt1" foreground="#aaaaff" background="#363655"/>
|
||||
<style name="SearchResultAlt2" foreground="#ffaaaa" background="#553636"/>
|
||||
<style name="SearchResultContainingFunction" foreground="#aaaaaa" background="#000000"/>
|
||||
<style name="SearchScope" background="#222200"/>
|
||||
<style name="Selection" foreground="#000000" background="#aaaaaa"/>
|
||||
<style name="Static" foreground="#55ff55" italic="true"/>
|
||||
|
@@ -43,6 +43,7 @@
|
||||
<style name="SearchResult" foreground="#000000" background="#ffef0b"/>
|
||||
<style name="SearchResultAlt1" foreground="#000000" background="#6464ff"/>
|
||||
<style name="SearchResultAlt2" foreground="#000000" background="#ff6464"/>
|
||||
<style name="SearchResultContainingFunction" foreground="#cfbfad" background="#1e1e27"/>
|
||||
<style name="SearchScope" foreground="#000000" background="#f8fafc"/>
|
||||
<style name="Selection" foreground="#ffffff" background="#4e4e8f"/>
|
||||
<style name="Static" foreground="#cb6ecb"/>
|
||||
|
@@ -16,6 +16,7 @@
|
||||
<style name="SearchResult" background="#555500"/>
|
||||
<style name="SearchResultAlt1" foreground="#aaaaff" background="#363655"/>
|
||||
<style name="SearchResultAlt2" foreground="#ffaaaa" background="#553636"/>
|
||||
<style name="SearchResultContainingFunction" foreground="#ffffff" background="#000000"/>
|
||||
<style name="SearchScope" background="#222200"/>
|
||||
<style name="Parentheses" foreground="#ffffff" background="#11404c"/>
|
||||
<style name="CurrentLine" background="#373737"/>
|
||||
|
@@ -13,6 +13,7 @@
|
||||
<style name="SearchResult" background="#073642"/>
|
||||
<style name="SearchResultAlt1" foreground="#aaaaff" background="#363655"/>
|
||||
<style name="SearchResultAlt2" foreground="#ffaaaa" background="#553636"/>
|
||||
<style name="SearchResultContainingFunction" foreground="#839496" background="#002b36"/>
|
||||
<style name="SearchScope" background="#073642"/>
|
||||
<style name="Parentheses" foreground="#dc322f" background="#586e75" bold="true"/>
|
||||
<style name="ParenthesesMismatch" foreground="#fdff2c" background="#d33682" bold="true"/>
|
||||
|
@@ -13,6 +13,7 @@
|
||||
<style name="SearchResult" background="#eee8d5"/>
|
||||
<style name="SearchResultAlt1" background="#93a1a1"/>
|
||||
<style name="SearchResultAlt2" background="#e0dbcb"/>
|
||||
<style name="SearchResultContainingFunction" foreground="#657b83" background="#fdf6e3"/>
|
||||
<style name="SearchScope" background="#073642"/>
|
||||
<style name="Parentheses" foreground="#dc322f" background="#93a1a1" bold="true"/>
|
||||
<style name="ParenthesesMismatch" foreground="#ffff00" background="#ff00ff" bold="true"/>
|
||||
|
@@ -96,6 +96,86 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class ContainingFunctionAt: protected SymbolVisitor
|
||||
{
|
||||
TranslationUnit *translationUnit;
|
||||
Symbol *root;
|
||||
int line;
|
||||
int column;
|
||||
Symbol *functionSymbol;
|
||||
bool foundFunction;
|
||||
bool foundBlock;
|
||||
|
||||
bool scopeContains(Scope* scope, int line, int column){
|
||||
if (!scope)
|
||||
return false;
|
||||
|
||||
int scopeStartLine{-1}, scopeStartColumn{-1}, scopeEndLine{-1}, scopeEndColumn{-1};
|
||||
translationUnit->getPosition(scope->startOffset(), &scopeStartLine, &scopeStartColumn);
|
||||
translationUnit->getPosition(scope->endOffset(), &scopeEndLine, &scopeEndColumn);
|
||||
|
||||
if (line < scopeStartLine || line > scopeEndLine)
|
||||
return false;
|
||||
|
||||
if (line > scopeStartLine && line < scopeEndLine)
|
||||
return true;
|
||||
|
||||
if (scopeStartLine == line && column >= scopeStartColumn)
|
||||
return true;
|
||||
|
||||
if (scopeEndLine == line && column <= scopeEndColumn)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
ContainingFunctionAt(TranslationUnit *unit, Symbol *root)
|
||||
: translationUnit(unit), root(root), line(0), column(0), functionSymbol(nullptr)
|
||||
, foundFunction(false), foundBlock(false) {}
|
||||
|
||||
Symbol *operator()(int line, int column)
|
||||
{
|
||||
this->line = line;
|
||||
this->column = column;
|
||||
this->functionSymbol = nullptr;
|
||||
accept(root);
|
||||
|
||||
return foundBlock ? functionSymbol : nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool preVisit(Symbol *s) final
|
||||
{
|
||||
if (foundBlock)
|
||||
return false;
|
||||
|
||||
if (foundFunction) {
|
||||
auto block = s->asBlock();
|
||||
if (!block)
|
||||
return true;
|
||||
|
||||
if (scopeContains(block->asScope(), line, column)) {
|
||||
foundBlock = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
auto asFunction = s->asFunction();
|
||||
if (asFunction) {
|
||||
if (s->line() < line || (s->line() == line && s->column() <= column)) {
|
||||
foundFunction = scopeContains(s->asScope(), line, column);
|
||||
if (foundFunction)
|
||||
functionSymbol = asFunction;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FindScopeAt: protected SymbolVisitor
|
||||
{
|
||||
TranslationUnit *_unit;
|
||||
@@ -512,19 +592,11 @@ QString Document::functionAt(int line, int column, int *lineOpeningDeclaratorPar
|
||||
if (line < 1 || column < 1)
|
||||
return QString();
|
||||
|
||||
Symbol *symbol = lastVisibleSymbolAt(line, column);
|
||||
Symbol *symbol = ContainingFunctionAt{translationUnit(), globalNamespace()}(line, column);
|
||||
if (!symbol)
|
||||
return QString();
|
||||
|
||||
// Find the enclosing function scope (which might be several levels up, or we might be standing
|
||||
// on it)
|
||||
Scope *scope = symbol->asScope();
|
||||
if (!scope)
|
||||
scope = symbol->enclosingScope();
|
||||
|
||||
while (scope && !scope->isFunction() )
|
||||
scope = scope->enclosingScope();
|
||||
|
||||
if (!scope)
|
||||
return QString();
|
||||
|
||||
|
@@ -62,6 +62,12 @@ bool ClangdAstNode::arcanaContains(const QString &s) const
|
||||
return arcanaString && arcanaString->contains(s);
|
||||
}
|
||||
|
||||
bool ClangdAstNode::isFunction() const
|
||||
{
|
||||
return role() == "declaration"
|
||||
&& (kind() == "Function" || kind() == "FunctionProto" || kind() == "CXXMethod");
|
||||
}
|
||||
|
||||
bool ClangdAstNode::isMemberFunctionCall() const
|
||||
{
|
||||
return role() == "expression" && (kind() == "CXXMemberCall"
|
||||
|
@@ -79,6 +79,7 @@ public:
|
||||
bool hasRange() const;
|
||||
bool arcanaContains(const QString &s) const;
|
||||
bool detailIs(const QString &s) const { return detail() && *detail() == s; }
|
||||
bool isFunction() const;
|
||||
bool isMemberFunctionCall() const;
|
||||
bool isPureVirtualDeclaration() const;
|
||||
bool isPureVirtualDefinition() const;
|
||||
|
@@ -907,6 +907,8 @@ public:
|
||||
|
||||
void handleDeclDefSwitchReplies();
|
||||
|
||||
Utils::optional<QString> getContainingFunctionName(const ClangdAstPath &astPath, const Range& range);
|
||||
|
||||
static CppEditor::CppEditorWidget *widgetFromDocument(const TextDocument *doc);
|
||||
QString searchTermFromCursor(const QTextCursor &cursor) const;
|
||||
QTextCursor adjustedCursor(const QTextCursor &cursor, const TextDocument *doc);
|
||||
@@ -1762,9 +1764,10 @@ void ClangdClient::Private::addSearchResultsForFile(ReferencesData &refData,
|
||||
qCDebug(clangdLog) << file << "has valid AST:" << fileData.ast.isValid();
|
||||
for (const auto &rangeWithText : fileData.rangesAndLineText) {
|
||||
const Range &range = rangeWithText.first;
|
||||
const Usage::Type usageType = fileData.ast.isValid()
|
||||
? getUsageType(getAstPath(fileData.ast, qAsConst(range)))
|
||||
: Usage::Type::Other;
|
||||
const ClangdAstPath astPath = getAstPath(fileData.ast, range);
|
||||
const Usage::Type usageType = fileData.ast.isValid() ? getUsageType(astPath)
|
||||
: Usage::Type::Other;
|
||||
|
||||
SearchResultItem item;
|
||||
item.setUserData(int(usageType));
|
||||
item.setStyle(CppEditor::colorStyleForUsageType(usageType));
|
||||
@@ -1772,6 +1775,8 @@ void ClangdClient::Private::addSearchResultsForFile(ReferencesData &refData,
|
||||
item.setMainRange(SymbolSupport::convertRange(range));
|
||||
item.setUseTextEditorFont(true);
|
||||
item.setLineText(rangeWithText.second);
|
||||
item.setContainingFunctionName(getContainingFunctionName(astPath, range));
|
||||
|
||||
if (refData.search->supportsReplace()) {
|
||||
const bool fileInSession = SessionManager::projectForFile(file);
|
||||
item.setSelectForReplacement(fileInSession);
|
||||
@@ -2418,6 +2423,31 @@ void ClangdClient::Private::handleDeclDefSwitchReplies()
|
||||
switchDeclDefData.reset();
|
||||
}
|
||||
|
||||
Utils::optional<QString> ClangdClient::Private::getContainingFunctionName(
|
||||
const ClangdAstPath &astPath, const Range& range)
|
||||
{
|
||||
const ClangdAstNode* containingFuncNode{nullptr};
|
||||
const ClangdAstNode* lastCompoundStmtNode{nullptr};
|
||||
|
||||
for (auto it = astPath.crbegin(); it != astPath.crend(); ++it) {
|
||||
if (it->arcanaContains("CompoundStmt"))
|
||||
lastCompoundStmtNode = &*it;
|
||||
|
||||
if (it->isFunction()) {
|
||||
if (lastCompoundStmtNode && lastCompoundStmtNode->hasRange()
|
||||
&& lastCompoundStmtNode->range().contains(range)) {
|
||||
containingFuncNode = &*it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!containingFuncNode || !containingFuncNode->isValid())
|
||||
return Utils::nullopt;
|
||||
|
||||
return containingFuncNode->detail();
|
||||
}
|
||||
|
||||
CppEditor::CppEditorWidget *ClangdClient::Private::widgetFromDocument(const TextDocument *doc)
|
||||
{
|
||||
IEditor * const editor = Utils::findOrDefault(EditorManager::visibleEditors(),
|
||||
|
@@ -39,14 +39,21 @@ public:
|
||||
|
||||
SearchResultColor() = default;
|
||||
SearchResultColor(const QColor &textBg, const QColor &textFg,
|
||||
const QColor &highlightBg, const QColor &highlightFg)
|
||||
const QColor &highlightBg, const QColor &highlightFg,
|
||||
const QColor &functionBg, const QColor &functionFg
|
||||
)
|
||||
: textBackground(textBg), textForeground(textFg),
|
||||
highlightBackground(highlightBg), highlightForeground(highlightFg)
|
||||
highlightBackground(highlightBg), highlightForeground(highlightFg),
|
||||
containingFunctionBackground(functionBg),containingFunctionForeground(functionFg)
|
||||
{
|
||||
if (!highlightBackground.isValid())
|
||||
highlightBackground = textBackground;
|
||||
if (!highlightForeground.isValid())
|
||||
highlightForeground = textForeground;
|
||||
if (!containingFunctionBackground.isValid())
|
||||
containingFunctionBackground = textBackground;
|
||||
if (!containingFunctionForeground.isValid())
|
||||
containingFunctionForeground = textForeground;
|
||||
}
|
||||
|
||||
friend auto qHash(SearchResultColor::Style style)
|
||||
@@ -58,6 +65,8 @@ public:
|
||||
QColor textForeground;
|
||||
QColor highlightBackground;
|
||||
QColor highlightForeground;
|
||||
QColor containingFunctionBackground;
|
||||
QColor containingFunctionForeground;
|
||||
};
|
||||
|
||||
using SearchResultColors = QHash<SearchResultColor::Style, SearchResultColor>;
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QStringList>
|
||||
@@ -127,6 +128,13 @@ public:
|
||||
bool selectForReplacement() const { return m_selectForReplacement; }
|
||||
void setSelectForReplacement(bool select) { m_selectForReplacement = select; }
|
||||
|
||||
Utils::optional<QString> containingFunctionName() const { return m_containingFunctionName; }
|
||||
|
||||
void setContainingFunctionName(Utils::optional<QString> containingFunctionName)
|
||||
{
|
||||
m_containingFunctionName = std::move(containingFunctionName);
|
||||
}
|
||||
|
||||
private:
|
||||
QStringList m_path; // hierarchy to the parent item of this item
|
||||
QString m_lineText; // text to show for the item itself
|
||||
@@ -136,6 +144,7 @@ private:
|
||||
bool m_useTextEditorFont = false;
|
||||
bool m_selectForReplacement = true;
|
||||
SearchResultColor::Style m_style = SearchResultColor::Style::Default;
|
||||
Utils::optional<QString> m_containingFunctionName;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
@@ -58,15 +58,33 @@ static std::pair<int, QString> lineNumberInfo(const QStyleOptionViewItem &option
|
||||
lineNumberText};
|
||||
}
|
||||
|
||||
static QString itemText(const QModelIndex &index)
|
||||
// Aligns text by appending spaces
|
||||
static QPair<QString, QString> align(QString text, const QString& containingFunction) {
|
||||
constexpr int minimumTextSize = 80;
|
||||
constexpr int textSizeIncrement = 20;
|
||||
|
||||
int textSize = ((text.size() / textSizeIncrement) + 1) * textSizeIncrement;
|
||||
textSize = std::max(minimumTextSize, textSize);
|
||||
text.resize(textSize, ' ');
|
||||
return QPair<QString, QString>{std::move(text), containingFunction};
|
||||
}
|
||||
|
||||
static QPair<QString, QString> itemText(const QModelIndex &index)
|
||||
{
|
||||
const QString text = index.data(Qt::DisplayRole).toString();
|
||||
QString text = index.data(Qt::DisplayRole).toString();
|
||||
// show number of subresults in displayString
|
||||
QString containingFunction;
|
||||
const auto contFnName = index.data(ItemDataRoles::ContainingFunctionNameRole).toString();
|
||||
if (contFnName.length())
|
||||
containingFunction = QLatin1String("[in ") + contFnName + QLatin1String("]");
|
||||
|
||||
if (index.model()->hasChildren(index)) {
|
||||
return text + QLatin1String(" (") + QString::number(index.model()->rowCount(index))
|
||||
+ QLatin1Char(')');
|
||||
QString textAndCount{text + QLatin1String(" (")
|
||||
+ QString::number(index.model()->rowCount(index)) + QLatin1Char(')')};
|
||||
|
||||
return align(std::move(textAndCount), containingFunction);
|
||||
}
|
||||
return text;
|
||||
return align(std::move(text), containingFunction);
|
||||
}
|
||||
|
||||
LayoutInfo SearchResultTreeItemDelegate::getLayoutInfo(const QStyleOptionViewItem &option,
|
||||
@@ -150,7 +168,9 @@ QSize SearchResultTreeItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const LayoutInfo info = getLayoutInfo(option, index);
|
||||
const int height = index.data(Qt::SizeHintRole).value<QSize>().height();
|
||||
// get text width, see QItemDelegatePrivate::displayRect
|
||||
const QString text = itemText(index).replace('\t', m_tabString);
|
||||
auto texts = itemText(index);
|
||||
const QString text = texts.first.replace('\t', m_tabString)
|
||||
+ texts.second.replace('\t', m_tabString);
|
||||
const QRect textMaxRect(0, 0, INT_MAX / 256, height);
|
||||
const QRect textLayoutRect = textRectangle(nullptr, textMaxRect, info.option.font, text);
|
||||
const QRect textRect(info.textRect.x(), info.textRect.y(), textLayoutRect.width(), height);
|
||||
@@ -198,7 +218,8 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
|
||||
const QRect &rect,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
const QString text = itemText(index);
|
||||
const auto texts = itemText(index);
|
||||
const QString text = texts.first;
|
||||
|
||||
const int searchTermStart = index.model()->data(index, ItemDataRoles::ResultBeginColumnNumberRole).toInt();
|
||||
int searchTermLength = index.model()->data(index, ItemDataRoles::SearchTermLengthRole).toInt();
|
||||
@@ -218,6 +239,8 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
|
||||
const QString textAfter = text.mid(searchTermStart + searchTermLength).replace(QLatin1Char('\t'), m_tabString);
|
||||
int searchTermStartPixels = option.fontMetrics.horizontalAdvance(textBefore);
|
||||
int searchTermLengthPixels = option.fontMetrics.horizontalAdvance(textHighlight);
|
||||
int textAfterLengthPixels = option.fontMetrics.horizontalAdvance(textAfter);
|
||||
int containingFunctionLengthPixels = option.fontMetrics.horizontalAdvance(texts.second);
|
||||
|
||||
// rects
|
||||
QRect beforeHighlightRect(rect);
|
||||
@@ -229,6 +252,11 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
|
||||
|
||||
QRect afterHighlightRect(rect);
|
||||
afterHighlightRect.setLeft(resultHighlightRect.right());
|
||||
afterHighlightRect.setRight(afterHighlightRect.left() + textAfterLengthPixels);
|
||||
|
||||
QRect containingFunctionRect(rect);
|
||||
containingFunctionRect.setLeft(afterHighlightRect.right());
|
||||
containingFunctionRect.setRight(afterHighlightRect.right() + containingFunctionLengthPixels);
|
||||
|
||||
// paint all highlight backgrounds
|
||||
// qitemdelegate has problems with painting background when highlighted
|
||||
@@ -249,7 +277,14 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
|
||||
}
|
||||
const QColor highlightBackground =
|
||||
index.model()->data(index, ItemDataRoles::ResultHighlightBackgroundColor).value<QColor>();
|
||||
painter->fillRect(resultHighlightRect.adjusted(textMargin, 0, textMargin - 1, 0), QBrush(highlightBackground));
|
||||
painter->fillRect(resultHighlightRect.adjusted(textMargin, 0, textMargin - 1, 0),
|
||||
QBrush(highlightBackground));
|
||||
|
||||
// Background of containing function
|
||||
const QColor funcHighlightBackground
|
||||
= index.model()->data(index, ItemDataRoles::FunctionHighlightBackgroundColor).value<QColor>();
|
||||
painter->fillRect(containingFunctionRect.adjusted(textMargin, 0, textMargin - 1, 0),
|
||||
QBrush(funcHighlightBackground));
|
||||
|
||||
// Text before the highlighting
|
||||
QStyleOptionViewItem noHighlightOpt = baseOption;
|
||||
@@ -261,12 +296,19 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
|
||||
|
||||
// Highlight text
|
||||
QStyleOptionViewItem highlightOpt = noHighlightOpt;
|
||||
const QColor highlightForeground =
|
||||
index.model()->data(index, ItemDataRoles::ResultHighlightForegroundColor).value<QColor>();
|
||||
const QColor highlightForeground
|
||||
= index.model()->data(index, ItemDataRoles::ResultHighlightForegroundColor).value<QColor>();
|
||||
highlightOpt.palette.setColor(QPalette::Text, highlightForeground);
|
||||
QItemDelegate::drawDisplay(painter, highlightOpt, resultHighlightRect, textHighlight);
|
||||
|
||||
// Text after the Highlight
|
||||
noHighlightOpt.rect = afterHighlightRect;
|
||||
QItemDelegate::drawDisplay(painter, noHighlightOpt, afterHighlightRect, textAfter);
|
||||
|
||||
// Containing function
|
||||
const QColor funcHighlightForeground
|
||||
= index.model()->data(index, ItemDataRoles::FunctionHighlightForegroundColor).value<QColor>();
|
||||
highlightOpt.palette.setColor(QPalette::Text, funcHighlightForeground);
|
||||
highlightOpt.rect = containingFunctionRect;
|
||||
QItemDelegate::drawDisplay(painter, highlightOpt, containingFunctionRect, texts.second);
|
||||
}
|
||||
|
@@ -31,16 +31,18 @@ namespace Core {
|
||||
namespace Internal {
|
||||
namespace ItemDataRoles {
|
||||
|
||||
enum Roles
|
||||
{
|
||||
enum Roles {
|
||||
ResultItemRole = Qt::UserRole,
|
||||
ResultLineRole,
|
||||
ResultBeginLineNumberRole,
|
||||
ResultIconRole,
|
||||
ResultHighlightBackgroundColor,
|
||||
ResultHighlightForegroundColor,
|
||||
FunctionHighlightBackgroundColor,
|
||||
FunctionHighlightForegroundColor,
|
||||
ResultBeginColumnNumberRole,
|
||||
SearchTermLengthRole,
|
||||
ContainingFunctionNameRole,
|
||||
IsGeneratedRole
|
||||
};
|
||||
|
||||
|
@@ -332,12 +332,21 @@ QVariant SearchResultTreeModel::data(const SearchResultTreeItem *row, int role)
|
||||
case ItemDataRoles::ResultHighlightForegroundColor:
|
||||
result = m_colors.value(row->item.style()).highlightForeground;
|
||||
break;
|
||||
case ItemDataRoles::FunctionHighlightBackgroundColor:
|
||||
result = m_colors.value(row->item.style()).containingFunctionBackground;
|
||||
break;
|
||||
case ItemDataRoles::FunctionHighlightForegroundColor:
|
||||
result = m_colors.value(row->item.style()).containingFunctionForeground;
|
||||
break;
|
||||
case ItemDataRoles::ResultBeginColumnNumberRole:
|
||||
result = row->item.mainRange().begin.column;
|
||||
break;
|
||||
case ItemDataRoles::SearchTermLengthRole:
|
||||
result = row->item.mainRange().length(row->item.lineText());
|
||||
break;
|
||||
case ItemDataRoles::ContainingFunctionNameRole:
|
||||
result = row->item.containingFunctionName().value_or(QString{});
|
||||
break;
|
||||
case ItemDataRoles::IsGeneratedRole:
|
||||
result = row->isGenerated();
|
||||
break;
|
||||
|
@@ -632,8 +632,29 @@ CPlusPlus::Symbol *CppFindReferences::findSymbol(const CppFindReferencesParamete
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void displayResults(SearchResult *search, QFutureWatcher<CPlusPlus::Usage> *watcher,
|
||||
int first, int last)
|
||||
Utils::optional<QString> getContainingFunctionName(const Utils::FilePath &fileName,
|
||||
int line,
|
||||
int column)
|
||||
{
|
||||
const CPlusPlus::Snapshot snapshot = CppModelManager::instance()->snapshot();
|
||||
auto document = snapshot.document(fileName);
|
||||
|
||||
// context properties need lookup inside function scope, and thus require a full check
|
||||
CPlusPlus::Document::Ptr localDoc = document;
|
||||
if (document->checkMode() != CPlusPlus::Document::FullCheck) {
|
||||
localDoc = snapshot.documentFromSource(document->utf8Source(), document->fileName());
|
||||
localDoc->check();
|
||||
}
|
||||
|
||||
auto funcName = localDoc->functionAt(line, column);
|
||||
|
||||
return funcName.size() ? Utils::make_optional(funcName) : Utils::nullopt;
|
||||
}
|
||||
|
||||
static void displayResults(SearchResult *search,
|
||||
QFutureWatcher<CPlusPlus::Usage> *watcher,
|
||||
int first,
|
||||
int last)
|
||||
{
|
||||
CppFindReferencesParameters parameters = search->userData().value<CppFindReferencesParameters>();
|
||||
|
||||
@@ -648,6 +669,20 @@ static void displayResults(SearchResult *search, QFutureWatcher<CPlusPlus::Usage
|
||||
item.setUseTextEditorFont(true);
|
||||
if (search->supportsReplace())
|
||||
item.setSelectForReplacement(SessionManager::projectForFile(result.path));
|
||||
|
||||
// In case we're looking for a function, we need to look at the symbol near the end. This
|
||||
// is needed to avoid following corner-cases:
|
||||
// 1) if we're looking at the beginning of the function declaration, we can get the
|
||||
// declaration of the previous function
|
||||
// 2) if we're looking somewhere at the middle of the function declaration, we can still
|
||||
// get the declaration of the previous function if the cursor is located at the
|
||||
// namespace declaration, i.e. CppReference>|<s::findUsages
|
||||
|
||||
const auto containingFunctionName = getContainingFunctionName(result.path,
|
||||
result.line,
|
||||
(result.col + result.len) - 1);
|
||||
|
||||
item.setContainingFunctionName(containingFunctionName);
|
||||
search->addResult(item);
|
||||
|
||||
if (parameters.prettySymbolName.isEmpty())
|
||||
|
@@ -306,6 +306,8 @@ QColor FormatDescription::defaultForeground(TextStyle id)
|
||||
return QColor(0x00, 0x00, 0x33);
|
||||
} else if (id == C_SEARCH_RESULT_ALT2) {
|
||||
return QColor(0x33, 0x00, 0x00);
|
||||
} else if (id == C_SEARCH_RESULT_CONTAINING_FUNCTION) {
|
||||
return Qt::black;
|
||||
}
|
||||
return QColor();
|
||||
}
|
||||
@@ -322,6 +324,8 @@ QColor FormatDescription::defaultBackground(TextStyle id)
|
||||
return QColor(0xb6, 0xcc, 0xff);
|
||||
} else if (id == C_SEARCH_RESULT_ALT2) {
|
||||
return QColor(0xff, 0xb6, 0xcc);
|
||||
} else if (id == C_SEARCH_RESULT_CONTAINING_FUNCTION) {
|
||||
return Qt::white;
|
||||
} else if (id == C_PARENTHESES) {
|
||||
return QColor(0xb4, 0xee, 0xb4);
|
||||
} else if (id == C_PARENTHESES_MISMATCH) {
|
||||
|
@@ -53,6 +53,7 @@ public:
|
||||
enum ShowControls {
|
||||
ShowForegroundControl = 0x1,
|
||||
ShowBackgroundControl = 0x2,
|
||||
ShowForeAndBackgroundControl = ShowForegroundControl | ShowBackgroundControl,
|
||||
ShowFontControls = 0x4,
|
||||
ShowUnderlineControl = 0x8,
|
||||
ShowRelativeForegroundControl = 0x10,
|
||||
|
@@ -41,6 +41,7 @@ const char *nameForStyle(TextStyle style)
|
||||
case C_SEARCH_RESULT: return "SearchResult";
|
||||
case C_SEARCH_RESULT_ALT1: return "SearchResultAlt1";
|
||||
case C_SEARCH_RESULT_ALT2: return "SearchResultAlt2";
|
||||
case C_SEARCH_RESULT_CONTAINING_FUNCTION: return "SearchResultContainingFunction";
|
||||
case C_SEARCH_SCOPE: return "SearchScope";
|
||||
case C_PARENTHESES: return "Parentheses";
|
||||
case C_PARENTHESES_MISMATCH:return "ParenthesesMismatch";
|
||||
|
@@ -41,6 +41,7 @@ enum TextStyle : quint8 {
|
||||
C_SEARCH_RESULT,
|
||||
C_SEARCH_RESULT_ALT1,
|
||||
C_SEARCH_RESULT_ALT2,
|
||||
C_SEARCH_RESULT_CONTAINING_FUNCTION,
|
||||
C_SEARCH_SCOPE,
|
||||
C_PARENTHESES,
|
||||
C_PARENTHESES_MISMATCH,
|
||||
@@ -85,7 +86,6 @@ enum TextStyle : quint8 {
|
||||
C_QML_STATE_NAME,
|
||||
C_BINDING,
|
||||
|
||||
|
||||
C_DISABLED_CODE,
|
||||
|
||||
C_ADDED_LINE,
|
||||
|
@@ -280,16 +280,23 @@ void TextEditorPluginPrivate::updateSearchResultsFont(const FontSettings &settin
|
||||
const Format defaultResultFormat = settings.formatFor(C_SEARCH_RESULT);
|
||||
const Format alt1ResultFormat = settings.formatFor(C_SEARCH_RESULT_ALT1);
|
||||
const Format alt2ResultFormat = settings.formatFor(C_SEARCH_RESULT_ALT2);
|
||||
const Format containingFunctionResultFormat =
|
||||
settings.formatFor(C_SEARCH_RESULT_CONTAINING_FUNCTION);
|
||||
window->setTextEditorFont(QFont(settings.family(), settings.fontSize() * settings.fontZoom() / 100),
|
||||
{std::make_pair(SearchResultColor::Style::Default,
|
||||
SearchResultColor(textFormat.background(), textFormat.foreground(),
|
||||
defaultResultFormat.background(), defaultResultFormat.foreground())),
|
||||
defaultResultFormat.background(), defaultResultFormat.foreground(),
|
||||
containingFunctionResultFormat.background(), containingFunctionResultFormat.foreground())),
|
||||
std::make_pair(SearchResultColor::Style::Alt1,
|
||||
SearchResultColor(textFormat.background(), textFormat.foreground(),
|
||||
alt1ResultFormat.background(), alt1ResultFormat.foreground())),
|
||||
alt1ResultFormat.background(), alt1ResultFormat.foreground(),
|
||||
containingFunctionResultFormat.background(),
|
||||
containingFunctionResultFormat.foreground())),
|
||||
std::make_pair(SearchResultColor::Style::Alt2,
|
||||
SearchResultColor(textFormat.background(), textFormat.foreground(),
|
||||
alt2ResultFormat.background(), alt2ResultFormat.foreground()))});
|
||||
alt2ResultFormat.background(), alt2ResultFormat.foreground(),
|
||||
containingFunctionResultFormat.background(),
|
||||
containingFunctionResultFormat.foreground()))});
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -112,6 +112,11 @@ FormatDescriptions TextEditorSettingsPrivate::initialFormats()
|
||||
tr("Highlighted search results inside the editor.\n"
|
||||
"Used to mark write accesses to C++ symbols."),
|
||||
FormatDescription::ShowBackgroundControl);
|
||||
formatDescr.emplace_back(C_SEARCH_RESULT_CONTAINING_FUNCTION,
|
||||
tr("Search Result Containing function"),
|
||||
tr("Highlighted search results inside the editor.\n"
|
||||
"Used to mark containing function of the symbol usage."),
|
||||
FormatDescription::ShowForeAndBackgroundControl);
|
||||
formatDescr.emplace_back(C_SEARCH_SCOPE, tr("Search Scope"),
|
||||
tr("Section where the pattern is searched in."),
|
||||
FormatDescription::ShowBackgroundControl);
|
||||
|
Reference in New Issue
Block a user