- enhancement: prefer local headers over system headers when complete #include header path
This commit is contained in:
parent
8c99d28307
commit
9d401cce42
1
NEWS.md
1
NEWS.md
|
@ -7,6 +7,7 @@ Red Panda C++ Version 1.0.4
|
|||
- enhancement: if a project's unit encoding is the same with project's encoding, don't save its encoding
|
||||
- fix: files will be saved to default encoding inspite of its original encoding
|
||||
- fix: parenthesis skip doesn't work when editing non-c/c++ files
|
||||
- enhancement: prefer local headers over system headers when complete #include header path
|
||||
|
||||
Red Panda C++ Version 1.0.3
|
||||
- fix: when oj problem grabbed by competitive companion received,
|
||||
|
|
|
@ -3120,7 +3120,7 @@ void Editor::completionInsert(bool appendFunc)
|
|||
|
||||
void Editor::headerCompletionInsert()
|
||||
{
|
||||
QString headerName = mHeaderCompletionPopup->selectedFilename();
|
||||
QString headerName = mHeaderCompletionPopup->selectedFilename(true);
|
||||
if (headerName.isEmpty())
|
||||
return;
|
||||
|
||||
|
|
|
@ -570,9 +570,13 @@ void MainWindow::updateEditorColorSchemes()
|
|||
QColor baseColor = palette().color(QPalette::Base);
|
||||
item = pColorManager->getItem(schemeName, SYNS_AttrPreprocessor);
|
||||
if (item) {
|
||||
mHeaderCompletionPopup->setSuggestionColor(item->foreground());
|
||||
mHeaderCompletionPopup->setSuggestionColor(item->foreground(),
|
||||
item->foreground(),
|
||||
item->foreground());
|
||||
} else {
|
||||
mHeaderCompletionPopup->setSuggestionColor(palette().color(QPalette::Text));
|
||||
mHeaderCompletionPopup->setSuggestionColor(palette().color(QPalette::Text),
|
||||
palette().color(QPalette::Text),
|
||||
palette().color(QPalette::Text));
|
||||
}
|
||||
item = pColorManager->getItem(schemeName, COLOR_SCHEME_ERROR);
|
||||
if (item && haveGoodContrast(item->foreground(), baseColor)) {
|
||||
|
|
|
@ -2763,7 +2763,7 @@ void Settings::CompilerSets::deleteSet(int index)
|
|||
saveSets();
|
||||
}
|
||||
|
||||
int Settings::CompilerSets::size() const
|
||||
size_t Settings::CompilerSets::size() const
|
||||
{
|
||||
return mList.size();
|
||||
}
|
||||
|
|
|
@ -1334,7 +1334,7 @@ public:
|
|||
void saveDefaultIndex();
|
||||
void deleteSet(int index);
|
||||
void saveSet(int index);
|
||||
int size() const;
|
||||
size_t size() const;
|
||||
int defaultIndex() const;
|
||||
void setDefaultIndex(int value);
|
||||
PCompilerSet defaultSet();
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
#include "headercompletionpopup.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
HeaderCompletionPopup::HeaderCompletionPopup(QWidget* parent):QWidget(parent)
|
||||
{
|
||||
|
@ -86,7 +86,7 @@ bool HeaderCompletionPopup::search(const QString &phrase, bool autoHideOnSingleR
|
|||
if (autoHideOnSingleResult)
|
||||
return true;
|
||||
// if only one suggestion, and is exactly the symbol to search, hide the frame (the search is over)
|
||||
if (symbol == mCompletionList.front())
|
||||
if (symbol == mCompletionList[0]->filename)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -100,43 +100,66 @@ void HeaderCompletionPopup::setKeypressedCallback(const KeyPressedCallback &newK
|
|||
mListView->setKeypressedCallback(newKeypressedCallback);
|
||||
}
|
||||
|
||||
void HeaderCompletionPopup::setSuggestionColor(const QColor &color)
|
||||
void HeaderCompletionPopup::setSuggestionColor(const QColor& localColor,
|
||||
const QColor& projectColor,
|
||||
const QColor& systemColor)
|
||||
{
|
||||
mModel->setColor(color);
|
||||
mModel->setLocalColor(localColor);
|
||||
mModel->setProjectColor(projectColor);
|
||||
mModel->setSystemColor(systemColor);
|
||||
}
|
||||
|
||||
QString HeaderCompletionPopup::selectedFilename()
|
||||
QString HeaderCompletionPopup::selectedFilename(bool updateUsageCount)
|
||||
{
|
||||
if (!isEnabled())
|
||||
return "";
|
||||
int index = mListView->currentIndex().row();
|
||||
PHeaderCompletionListItem item;
|
||||
if (index>=0 && index<mCompletionList.count())
|
||||
return mCompletionList[index];
|
||||
item=mCompletionList[index];
|
||||
else if (mCompletionList.count()>0) {
|
||||
return mCompletionList.front();
|
||||
item=mCompletionList.front();
|
||||
}
|
||||
return "";
|
||||
if (item) {
|
||||
if (updateUsageCount) {
|
||||
item->usageCount++;
|
||||
mHeaderUsageCounts.insert(item->fullpath,item->usageCount);
|
||||
}
|
||||
return item->filename;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool sortByUsage(const PHeaderCompletionListItem& item1,const PHeaderCompletionListItem& item2){
|
||||
if (item1->usageCount != item2->usageCount)
|
||||
return item1->usageCount > item2->usageCount;
|
||||
|
||||
if (item1->itemType != item2->itemType)
|
||||
return item1->itemType<item2->itemType;
|
||||
|
||||
return item1->filename < item2->filename;
|
||||
}
|
||||
|
||||
|
||||
void HeaderCompletionPopup::filterList(const QString &member)
|
||||
{
|
||||
Qt::CaseSensitivity caseSensitivity=mIgnoreCase?Qt::CaseInsensitive:Qt::CaseSensitive;
|
||||
mCompletionList.clear();
|
||||
if (member.isEmpty()) {
|
||||
foreach (const QString& s,mFullCompletionList) {
|
||||
mCompletionList.append(s);
|
||||
foreach (const PHeaderCompletionListItem& item,mFullCompletionList.values()) {
|
||||
mCompletionList.append(item);
|
||||
}
|
||||
} else {
|
||||
foreach (const QString& s,mFullCompletionList) {
|
||||
if (mIgnoreCase && s.startsWith(member, Qt::CaseInsensitive)) {
|
||||
mCompletionList.append(s);
|
||||
} else if (s.startsWith(member, Qt::CaseSensitive)){
|
||||
mCompletionList.append(s);
|
||||
foreach (const PHeaderCompletionListItem& item,mFullCompletionList.values()) {
|
||||
if (item->filename.startsWith(member, caseSensitivity)) {
|
||||
mCompletionList.append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(mCompletionList.begin(),mCompletionList.end());
|
||||
std::sort(mCompletionList.begin(),mCompletionList.end(), sortByUsage);
|
||||
}
|
||||
|
||||
|
||||
void HeaderCompletionPopup::getCompletionFor(const QString &phrase)
|
||||
{
|
||||
int idx = phrase.lastIndexOf('\\');
|
||||
|
@ -147,33 +170,33 @@ void HeaderCompletionPopup::getCompletionFor(const QString &phrase)
|
|||
if (idx < 0) { // dont have basedir
|
||||
if (mSearchLocal) {
|
||||
QFileInfo fileInfo(mCurrentFile);
|
||||
addFilesInPath(fileInfo.absolutePath());
|
||||
addFilesInPath(fileInfo.absolutePath(), HeaderCompletionListItemType::LocalHeader);
|
||||
};
|
||||
|
||||
for (const QString& path: mParser->includePaths()) {
|
||||
addFilesInPath(path);
|
||||
addFilesInPath(path, HeaderCompletionListItemType::ProjectHeader);
|
||||
}
|
||||
|
||||
for (const QString& path: mParser->projectIncludePaths()) {
|
||||
addFilesInPath(path);
|
||||
addFilesInPath(path, HeaderCompletionListItemType::SystemHeader);
|
||||
}
|
||||
} else {
|
||||
QString current = phrase.mid(0,idx);
|
||||
if (mSearchLocal) {
|
||||
QFileInfo fileInfo(mCurrentFile);
|
||||
addFilesInSubDir(fileInfo.absolutePath(),current);
|
||||
addFilesInSubDir(fileInfo.absolutePath(),current, HeaderCompletionListItemType::LocalHeader);
|
||||
}
|
||||
for (const QString& path: mParser->includePaths()) {
|
||||
addFilesInSubDir(path,current);
|
||||
addFilesInSubDir(path,current, HeaderCompletionListItemType::ProjectHeader);
|
||||
}
|
||||
|
||||
for (const QString& path: mParser->projectIncludePaths()) {
|
||||
addFilesInSubDir(path,current);
|
||||
addFilesInSubDir(path,current, HeaderCompletionListItemType::SystemHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HeaderCompletionPopup::addFilesInPath(const QString &path)
|
||||
void HeaderCompletionPopup::addFilesInPath(const QString &path, HeaderCompletionListItemType type)
|
||||
{
|
||||
QDir dir(path);
|
||||
if (!dir.exists())
|
||||
|
@ -183,25 +206,30 @@ void HeaderCompletionPopup::addFilesInPath(const QString &path)
|
|||
continue;
|
||||
QString suffix = fileInfo.suffix().toLower();
|
||||
if (suffix == "h" || suffix == "hpp" || suffix == "") {
|
||||
addFile(fileInfo.fileName());
|
||||
addFile(dir, fileInfo.fileName(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HeaderCompletionPopup::addFile(const QString &fileName)
|
||||
void HeaderCompletionPopup::addFile(const QDir& dir, const QString &fileName, HeaderCompletionListItemType type)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
if (fileName.startsWith('.'))
|
||||
return;
|
||||
mFullCompletionList.insert(fileName);
|
||||
PHeaderCompletionListItem item = std::make_shared<HeaderCompletionListItem>();
|
||||
item->filename = fileName;
|
||||
item->itemType = type;
|
||||
item->fullpath = dir.absoluteFilePath(fileName);
|
||||
item->usageCount = mHeaderUsageCounts.value(item->fullpath,0);
|
||||
mFullCompletionList.insert(fileName,item);
|
||||
}
|
||||
|
||||
void HeaderCompletionPopup::addFilesInSubDir(const QString &baseDirPath, const QString &subDirName)
|
||||
void HeaderCompletionPopup::addFilesInSubDir(const QString &baseDirPath, const QString &subDirName, HeaderCompletionListItemType type)
|
||||
{
|
||||
QDir baseDir(baseDirPath);
|
||||
QString subDirPath = baseDir.filePath(subDirName);
|
||||
addFilesInPath(subDirPath);
|
||||
addFilesInPath(subDirPath, type);
|
||||
}
|
||||
|
||||
bool HeaderCompletionPopup::searchLocal() const
|
||||
|
@ -259,7 +287,7 @@ bool HeaderCompletionPopup::event(QEvent *event)
|
|||
return result;
|
||||
}
|
||||
|
||||
HeaderCompletionListModel::HeaderCompletionListModel(const QStringList *files, QObject *parent):
|
||||
HeaderCompletionListModel::HeaderCompletionListModel(const QList<PHeaderCompletionListItem> *files, QObject *parent):
|
||||
QAbstractListModel(parent),
|
||||
mFiles(files)
|
||||
{
|
||||
|
@ -280,10 +308,18 @@ QVariant HeaderCompletionListModel::data(const QModelIndex &index, int role) con
|
|||
|
||||
switch(role) {
|
||||
case Qt::DisplayRole: {
|
||||
return mFiles->at(index.row());
|
||||
return mFiles->at(index.row())->filename;
|
||||
}
|
||||
case Qt::ForegroundRole:
|
||||
return mColor;
|
||||
switch(mFiles->at(index.row())->itemType) {
|
||||
case HeaderCompletionListItemType::LocalHeader:
|
||||
return mLocalColor;
|
||||
case HeaderCompletionListItemType::ProjectHeader:
|
||||
return mProjectColor;
|
||||
case HeaderCompletionListItemType::SystemHeader:
|
||||
return mSystemColor;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return QVariant();
|
||||
|
@ -295,7 +331,17 @@ void HeaderCompletionListModel::notifyUpdated()
|
|||
endResetModel();
|
||||
}
|
||||
|
||||
void HeaderCompletionListModel::setColor(const QColor &newColor)
|
||||
void HeaderCompletionListModel::setSystemColor(const QColor &newColor)
|
||||
{
|
||||
mColor = newColor;
|
||||
mSystemColor = newColor;
|
||||
}
|
||||
|
||||
void HeaderCompletionListModel::setProjectColor(const QColor &newColor)
|
||||
{
|
||||
mProjectColor = newColor;
|
||||
}
|
||||
|
||||
void HeaderCompletionListModel::setLocalColor(const QColor &newColor)
|
||||
{
|
||||
mLocalColor = newColor;
|
||||
}
|
||||
|
|
|
@ -17,22 +17,42 @@
|
|||
#ifndef HEADERCOMPLETIONPOPUP_H
|
||||
#define HEADERCOMPLETIONPOPUP_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QWidget>
|
||||
#include "codecompletionlistview.h"
|
||||
#include "../parser/cppparser.h"
|
||||
|
||||
enum class HeaderCompletionListItemType {
|
||||
LocalHeader,
|
||||
ProjectHeader,
|
||||
SystemHeader
|
||||
};
|
||||
|
||||
struct HeaderCompletionListItem {
|
||||
QString filename;
|
||||
QString fullpath;
|
||||
int usageCount;
|
||||
HeaderCompletionListItemType itemType;
|
||||
};
|
||||
|
||||
using PHeaderCompletionListItem=std::shared_ptr<HeaderCompletionListItem>;
|
||||
|
||||
class HeaderCompletionListModel: public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HeaderCompletionListModel(const QStringList* files,QObject *parent = nullptr);
|
||||
explicit HeaderCompletionListModel(const QList<PHeaderCompletionListItem>* files,QObject *parent = nullptr);
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
void notifyUpdated();
|
||||
void setColor(const QColor &newColor);
|
||||
void setLocalColor(const QColor &newColor);
|
||||
void setSystemColor(const QColor &newColor);
|
||||
void setProjectColor(const QColor &newColor);
|
||||
|
||||
private:
|
||||
const QStringList* mFiles;
|
||||
QColor mColor;
|
||||
const QList<PHeaderCompletionListItem>* mFiles;
|
||||
QColor mLocalColor;
|
||||
QColor mSystemColor;
|
||||
QColor mProjectColor;
|
||||
};
|
||||
|
||||
class HeaderCompletionPopup : public QWidget
|
||||
|
@ -44,21 +64,24 @@ public:
|
|||
void prepareSearch(const QString& phrase, const QString& fileName);
|
||||
bool search(const QString& phrase, bool autoHideOnSingleResult);
|
||||
void setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback);
|
||||
void setSuggestionColor(const QColor& color);
|
||||
QString selectedFilename();
|
||||
void setSuggestionColor(const QColor& localColor,
|
||||
const QColor& projectColor,
|
||||
const QColor& systemColor);
|
||||
QString selectedFilename(bool updateUsageCount);
|
||||
|
||||
private:
|
||||
void filterList(const QString& member);
|
||||
void getCompletionFor(const QString& phrase);
|
||||
void addFilesInPath(const QString& path);
|
||||
void addFile(const QString& fileName);
|
||||
void addFilesInSubDir(const QString& baseDirPath, const QString& subDirName);
|
||||
void addFilesInPath(const QString& path, HeaderCompletionListItemType type);
|
||||
void addFile(const QDir& dir, const QString& fileName, HeaderCompletionListItemType type);
|
||||
void addFilesInSubDir(const QString& baseDirPath, const QString& subDirName, HeaderCompletionListItemType type);
|
||||
private:
|
||||
|
||||
CodeCompletionListView* mListView;
|
||||
HeaderCompletionListModel* mModel;
|
||||
QSet<QString> mFullCompletionList;
|
||||
QStringList mCompletionList;
|
||||
QHash<QString, PHeaderCompletionListItem> mFullCompletionList;
|
||||
QList<PHeaderCompletionListItem> mCompletionList;
|
||||
QHash<QString,int> mHeaderUsageCounts;
|
||||
int mShowCount;
|
||||
QSet<QString> mAddedFileNames;
|
||||
|
||||
|
|
Loading…
Reference in New Issue