parent
9b87d93b72
commit
b518304f56
3
NEWS.md
3
NEWS.md
|
@ -13,8 +13,9 @@ Version 0.2.2
|
|||
- fix: can't coorectly show code completion for array elements
|
||||
- enhancement: show caret when show code/header completions
|
||||
- fix: correctly display pointer info in watch console
|
||||
- enhancement: search in project
|
||||
- implement: search in project
|
||||
- enhancement: view memory when debugging
|
||||
- implement: symbol usage count
|
||||
|
||||
Version 0.2.1
|
||||
- fix: crash when load last opens
|
||||
|
|
|
@ -18,6 +18,7 @@ SOURCES += \
|
|||
autolinkmanager.cpp \
|
||||
caretlist.cpp \
|
||||
codeformatter.cpp \
|
||||
codesnippetsmanager.cpp \
|
||||
codetemplate.cpp \
|
||||
colorscheme.cpp \
|
||||
compiler/projectcompiler.cpp \
|
||||
|
@ -57,6 +58,7 @@ SOURCES += \
|
|||
settingsdialog/projectoutputwidget.cpp \
|
||||
settingsdialog/projectprecompilewidget.cpp \
|
||||
settingsdialog/projectversioninfowidget.cpp \
|
||||
symbolusagemanager.cpp \
|
||||
widgets/classbrowser.cpp \
|
||||
widgets/codecompletionlistview.cpp \
|
||||
widgets/codecompletionpopup.cpp \
|
||||
|
@ -117,6 +119,7 @@ HEADERS += \
|
|||
autolinkmanager.h \
|
||||
caretlist.h \
|
||||
codeformatter.h \
|
||||
codesnippetsmanager.h \
|
||||
codetemplate.h \
|
||||
colorscheme.h \
|
||||
compiler/compiler.h \
|
||||
|
@ -155,6 +158,7 @@ HEADERS += \
|
|||
settingsdialog/projectoutputwidget.h \
|
||||
settingsdialog/projectprecompilewidget.h \
|
||||
settingsdialog/projectversioninfowidget.h \
|
||||
symbolusagemanager.h \
|
||||
widgets/classbrowser.h \
|
||||
widgets/codecompletionlistview.h \
|
||||
widgets/codecompletionpopup.h \
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
#include "codesnippetsmanager.h"
|
||||
#include "settings.h"
|
||||
#include "systemconsts.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
CodeSnippetsManager::CodeSnippetsManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CodeSnippetsManager::load()
|
||||
{
|
||||
//if config file not exists, copy it from data
|
||||
//read config file
|
||||
}
|
||||
|
||||
void CodeSnippetsManager::save()
|
||||
{
|
||||
QString filename = pSettings->dirs().config() + DEV_CODESNIPPET_FILE;
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Save code snippets failed"),
|
||||
tr("Can't open code snippet file '%1' for write.")
|
||||
.arg(filename));
|
||||
}
|
||||
QJsonArray array;
|
||||
foreach (const PCodeSnippet& snippet,mSnippets) {
|
||||
QJsonObject object;
|
||||
object["caption"]=snippet->caption;
|
||||
object["prefix"]=snippet->prefix;
|
||||
object["code"]=snippet->code;
|
||||
object["description"]=snippet->desc;
|
||||
object["section"]=snippet->section;
|
||||
array.append(object);
|
||||
}
|
||||
QJsonDocument doc;
|
||||
doc.setArray(array);
|
||||
if (file.write(doc.toJson())<0) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Save code snippets failed"),
|
||||
tr("Write to code snippet file '%1' failed.")
|
||||
.arg(filename));
|
||||
}
|
||||
}
|
||||
|
||||
void CodeSnippetsManager::addSnippet(const QString &caption, const QString &prefix, const QString &code, const QString &description, int menuSection)
|
||||
{
|
||||
PCodeSnippet snippet = std::make_shared<CodeSnippet>();
|
||||
snippet->caption = caption;
|
||||
snippet->prefix = prefix;
|
||||
snippet->code = code;
|
||||
snippet->desc = description;
|
||||
snippet->section = menuSection;
|
||||
mSnippets.append(snippet);
|
||||
}
|
||||
|
||||
void CodeSnippetsManager::remove(int index)
|
||||
{
|
||||
Q_ASSERT(index>=0 && index<mSnippets.count());
|
||||
mSnippets.removeAt(index);
|
||||
}
|
||||
|
||||
void CodeSnippetsManager::clear()
|
||||
{
|
||||
mSnippets.clear();
|
||||
}
|
||||
|
||||
const QList<PCodeSnippet> &CodeSnippetsManager::snippets() const
|
||||
{
|
||||
return mSnippets;
|
||||
}
|
||||
|
||||
int CodeSnippetsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return mSnippets.count();
|
||||
}
|
||||
|
||||
int CodeSnippetsModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool CodeSnippetsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVariant CodeSnippetsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
switch(section) {
|
||||
case 0:
|
||||
return tr("Caption");
|
||||
case 1:
|
||||
return tr("Completion Prefix");
|
||||
case 2:
|
||||
return tr("Description");
|
||||
case 3:
|
||||
return tr("Menu Section");
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef CODESNIPPETSMANAGER_H
|
||||
#define CODESNIPPETSMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include "parser/parserutils.h"
|
||||
|
||||
class CodeSnippetsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CodeSnippetsManager(QObject *parent = nullptr);
|
||||
|
||||
void load();
|
||||
void save();
|
||||
void addSnippet(
|
||||
const QString& caption,
|
||||
const QString& prefix,
|
||||
const QString& code,
|
||||
const QString& description,
|
||||
int menuSection);
|
||||
void remove(int index);
|
||||
void clear();
|
||||
const QList<PCodeSnippet> &snippets() const;
|
||||
|
||||
signals:
|
||||
private:
|
||||
QList<PCodeSnippet> mSnippets;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // CODESNIPPETSMANAGER_H
|
|
@ -1900,17 +1900,13 @@ void Editor::completionInsert(bool appendFunc)
|
|||
PStatement statement = mCompletionPopup->selectedStatement();
|
||||
if (!statement)
|
||||
return;
|
||||
// if devCodeCompletion.RecordUsage and (Statement^._Kind <> skUserCodeIn) then begin
|
||||
// idx:=Utils.FastIndexOf(dmMain.SymbolUsage,Statement^._FullName);
|
||||
// if idx = -1 then begin
|
||||
// usageCount:=1;
|
||||
// dmMain.SymbolUsage.AddObject(Statement^._FullName, pointer(1))
|
||||
// end else begin
|
||||
// usageCount := 1 + integer(dmMain.SymbolUsage.Objects[idx]);
|
||||
// dmMain.SymbolUsage.Objects[idx] := pointer( usageCount );
|
||||
// end;
|
||||
// Statement^._UsageCount := usageCount;
|
||||
// end;
|
||||
|
||||
if (pSettings->codeCompletion().recordUsage()
|
||||
&& statement->kind != StatementKind::skUserCodeIn) {
|
||||
statement->usageCount+=1;
|
||||
pMainWindow->symbolUsageManager()->updateUsage(statement->fullName,
|
||||
statement->usageCount);
|
||||
}
|
||||
|
||||
QString funcAddOn = "";
|
||||
|
||||
|
|
|
@ -123,6 +123,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(ui->cbMemoryAddress->lineEdit(), &QLineEdit::returnPressed,
|
||||
this, &MainWindow::onDebugMemoryAddressInput);
|
||||
|
||||
mSymbolUsageManager = std::make_shared<SymbolUsageManager>();
|
||||
mSymbolUsageManager->load();
|
||||
mSearchResultTreeModel = std::make_shared<SearchResultTreeModel>(&mSearchResultModel);
|
||||
mSearchResultListModel = std::make_shared<SearchResultListModel>(&mSearchResultModel);
|
||||
mSearchViewDelegate = std::make_shared<SearchResultTreeViewDelegate>(mSearchResultTreeModel);
|
||||
|
@ -2391,7 +2393,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
|||
|
||||
mCompilerManager->stopCompile();
|
||||
mCompilerManager->stopRun();
|
||||
|
||||
mSymbolUsageManager->save();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
@ -3746,3 +3748,7 @@ void MainWindow::on_classBrowser_doubleClicked(const QModelIndex &index)
|
|||
}
|
||||
}
|
||||
|
||||
PSymbolUsageManager &MainWindow::symbolUsageManager()
|
||||
{
|
||||
return mSymbolUsageManager;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "widgets/headercompletionpopup.h"
|
||||
#include "widgets/functiontooltipwidget.h"
|
||||
#include "caretlist.h"
|
||||
#include "symbolusagemanager.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
|
@ -113,6 +114,8 @@ public:
|
|||
|
||||
const std::shared_ptr<QHash<StatementKind, QColor> > &statementColors() const;
|
||||
|
||||
PSymbolUsageManager &symbolUsageManager();
|
||||
|
||||
public slots:
|
||||
void onCompileLog(const QString& msg);
|
||||
void onCompileIssue(PCompileIssue issue);
|
||||
|
@ -379,6 +382,7 @@ private:
|
|||
PSearchResultTreeViewDelegate mSearchViewDelegate;
|
||||
ClassBrowserModel mClassBrowserModel;
|
||||
std::shared_ptr<QHash<StatementKind, QColor>> mStatementColors;
|
||||
PSymbolUsageManager mSymbolUsageManager;
|
||||
|
||||
bool mCheckSyntaxInBack;
|
||||
bool mOpenClosingBottomPanel;
|
||||
|
|
|
@ -1077,7 +1077,7 @@ PStatement CppParser::addStatement(const PStatement& parent,
|
|||
result->fullName = newCommand;
|
||||
else
|
||||
result->fullName = getFullStatementName(newCommand, parent);
|
||||
result->usageCount = 0;
|
||||
result->usageCount = -1;
|
||||
result->freqTop = 0;
|
||||
mStatementList.add(result);
|
||||
if (result->kind == StatementKind::skNamespace) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <QSet>
|
||||
#include <memory>
|
||||
|
||||
struct CodeIns {
|
||||
struct CodeSnippet {
|
||||
QString caption; //Name
|
||||
QString prefix; //Prefix used in code suggestion
|
||||
QString code; //Code body
|
||||
|
@ -13,7 +13,7 @@ struct CodeIns {
|
|||
int section; //Section in the menu
|
||||
};
|
||||
|
||||
using PCodeIns = std::shared_ptr<CodeIns>;
|
||||
using PCodeIns = std::shared_ptr<CodeSnippet>;
|
||||
|
||||
// preprocess/ macro define
|
||||
struct Define {
|
||||
|
|
|
@ -42,6 +42,7 @@ void EditorAutoSaveWidget::doLoad()
|
|||
break;
|
||||
case astAllOpennedFiles:
|
||||
ui->rbAllOpennedFiles->setChecked(true);
|
||||
break;
|
||||
default:
|
||||
ui->rbProjectFiles->setChecked(true);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "editorcodecompletionwidget.h"
|
||||
#include "ui_editorcodecompletionwidget.h"
|
||||
#include "../settings.h"
|
||||
#include "../mainwindow.h"
|
||||
#include "../symbolusagemanager.h"
|
||||
|
||||
EditorCodeCompletionWidget::EditorCodeCompletionWidget(const QString& name, const QString& group,
|
||||
QWidget *parent) :
|
||||
|
@ -56,3 +58,9 @@ void EditorCodeCompletionWidget::doSave()
|
|||
pSettings->codeCompletion().save();
|
||||
}
|
||||
|
||||
|
||||
void EditorCodeCompletionWidget::on_btnClearUsageData_clicked()
|
||||
{
|
||||
pMainWindow->symbolUsageManager()->reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ private:
|
|||
protected:
|
||||
void doLoad() override;
|
||||
void doSave() override;
|
||||
private slots:
|
||||
void on_btnClearUsageData_clicked();
|
||||
};
|
||||
|
||||
#endif // EDITORCODECOMPLETIONWIDGET_H
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
#include "symbolusagemanager.h"
|
||||
#include "settings.h"
|
||||
#include "systemconsts.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMessageBox>
|
||||
|
||||
SymbolUsageManager::SymbolUsageManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SymbolUsageManager::load()
|
||||
{
|
||||
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config())
|
||||
+ DEV_SYMBOLUSAGE_FILE;
|
||||
if (!fileExists(filename))
|
||||
return;
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Load symbol usage info failed"),
|
||||
tr("Can't open symbol usage file '%1' for read.")
|
||||
.arg(filename));
|
||||
}
|
||||
QByteArray contents = file.readAll();
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(contents,&error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Load symbol usage info failed"),
|
||||
tr("Can't parse symbol usage file '%1'.")
|
||||
.arg(filename));
|
||||
}
|
||||
|
||||
mUsages.clear();
|
||||
QJsonArray array = doc.array();
|
||||
foreach (const QJsonValue& val, array) {
|
||||
QJsonObject obj = val.toObject();
|
||||
QString fullname = obj["symbol"].toString();
|
||||
int count = obj["count"].toInt();
|
||||
PSymbolUsage usage = std::make_shared<SymbolUsage>();
|
||||
usage->fullName = fullname;
|
||||
usage->count = count;
|
||||
mUsages.insert(fullname,usage);
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolUsageManager::save()
|
||||
{
|
||||
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config())
|
||||
+ DEV_SYMBOLUSAGE_FILE;
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Save symbol usage info failed"),
|
||||
tr("Can't open symbol usage file '%1' for write.")
|
||||
.arg(filename));
|
||||
}
|
||||
QJsonArray array;
|
||||
foreach (const PSymbolUsage& usage,mUsages) {
|
||||
QJsonObject object;
|
||||
object["symbol"]=usage->fullName;
|
||||
object["count"]=usage->count;
|
||||
array.append(object);
|
||||
}
|
||||
QJsonDocument doc;
|
||||
doc.setArray(array);
|
||||
if (file.write(doc.toJson())<0) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Save symbol usage info failed"),
|
||||
tr("Write to symbol usage file '%1' failed.")
|
||||
.arg(filename));
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolUsageManager::reset()
|
||||
{
|
||||
mUsages.clear();
|
||||
save();
|
||||
}
|
||||
|
||||
PSymbolUsage SymbolUsageManager::findUsage(const QString &fullName) const
|
||||
{
|
||||
return mUsages.value(fullName,PSymbolUsage());
|
||||
}
|
||||
|
||||
void SymbolUsageManager::updateUsage(const QString &symbol, int count)
|
||||
{
|
||||
PSymbolUsage usage = mUsages.value(symbol,PSymbolUsage());
|
||||
if (usage) {
|
||||
usage->count = count;
|
||||
} else {
|
||||
usage = std::make_shared<SymbolUsage>();
|
||||
usage->fullName = symbol;
|
||||
usage->count = count;
|
||||
mUsages.insert(symbol,usage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef SYMBOLUSAGEMANAGER_H
|
||||
#define SYMBOLUSAGEMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
struct SymbolUsage {
|
||||
QString fullName;
|
||||
int count;
|
||||
};
|
||||
using PSymbolUsage = std::shared_ptr<SymbolUsage>;
|
||||
|
||||
class SymbolUsageManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SymbolUsageManager(QObject *parent = nullptr);
|
||||
void load();
|
||||
void save();
|
||||
void reset();
|
||||
PSymbolUsage findUsage(const QString& fullName) const;
|
||||
void updateUsage(const QString& symbol, int count);
|
||||
signals:
|
||||
private:
|
||||
QHash<QString, PSymbolUsage> mUsages;
|
||||
};
|
||||
|
||||
using PSymbolUsageManager = std::shared_ptr<SymbolUsageManager>;
|
||||
|
||||
#endif // SYMBOLUSAGEMANAGER_H
|
|
@ -32,7 +32,8 @@
|
|||
#define TEMPLATE_EXT "template"
|
||||
#define DEV_INTERNAL_OPEN "$__DEV_INTERNAL_OPEN"
|
||||
#define DEV_LASTOPENS_FILE "lastopens.ini"
|
||||
|
||||
#define DEV_SYMBOLUSAGE_FILE "symbolusage.json"
|
||||
#define DEV_CODESNIPPET_FILE "codesnippets.json"
|
||||
#ifdef Q_OS_WIN
|
||||
# define PATH_SENSITIVITY Qt::CaseInsensitive
|
||||
# define PATH_SEPARATOR ";"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "../mainwindow.h"
|
||||
#include "../editor.h"
|
||||
#include "../editorlist.h"
|
||||
#include "../symbolusagemanager.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
@ -360,10 +361,13 @@ void CodeCompletionPopup::filterList(const QString &member)
|
|||
int thirdCount = 0;
|
||||
int usageCount;
|
||||
foreach (const PStatement& statement,mCompletionStatementList) {
|
||||
if (statement->usageCount == 0) {
|
||||
usageCount = mSymbolUsage.value(statement->fullName,0);
|
||||
if (usageCount == 0)
|
||||
continue;
|
||||
if (statement->usageCount == -1) {
|
||||
PSymbolUsage usage = pMainWindow->symbolUsageManager()->findUsage(statement->fullName);
|
||||
if (usage) {
|
||||
usageCount = usage->count;
|
||||
} else {
|
||||
usageCount = 0;
|
||||
}
|
||||
statement->usageCount = usageCount;
|
||||
} else
|
||||
usageCount = statement->usageCount;
|
||||
|
|
|
@ -85,7 +85,6 @@ private:
|
|||
QSet<QString> mUsings;
|
||||
QSet<QString> mAddedStatements;
|
||||
QString mPhrase;
|
||||
QHash<QString,int> mSymbolUsage;
|
||||
QRecursiveMutex mMutex;
|
||||
std::shared_ptr<QHash<StatementKind, QColor>> mColors;
|
||||
|
||||
|
|
Loading…
Reference in New Issue