mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-22 06:12:32 -06:00
Developing indexer
This commit is contained in:
parent
b16713e74c
commit
78dc90e9c2
34 changed files with 1059 additions and 219 deletions
|
|
@ -25,10 +25,10 @@ public:
|
|||
};
|
||||
|
||||
struct TimeStopper {
|
||||
const char *name;
|
||||
String name;
|
||||
TimeStop tm;
|
||||
|
||||
TimeStopper(const char *name) : name(name) {}
|
||||
TimeStopper(const String& name) : name(name) {}
|
||||
~TimeStopper() { RLOG(name << " " << tm); }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1068,8 +1068,10 @@ EditField& EditField::SetFont(Font _font)
|
|||
|
||||
EditField& EditField::SetColor(Color c)
|
||||
{
|
||||
SetColorAttr(ATTR_TEXTCOLOR, c);
|
||||
Refresh();
|
||||
if(GetColorAttr(ATTR_TEXTCOLOR) != c) {
|
||||
SetColorAttr(ATTR_TEXTCOLOR, c);
|
||||
Refresh();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ AssistEditor::AssistEditor()
|
|||
NoFindReplace();
|
||||
|
||||
WhenUpdate << [=] {
|
||||
annotate_trigger.KillSet(100, [=] { SyncCurrentFile(); });
|
||||
annotating = true;
|
||||
annotate_trigger.KillSet(500, [=] { SyncCurrentFile(); });
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -460,6 +461,10 @@ CurrentFileContext AssistEditor::CurrentContext(int& line_delta)
|
|||
cfx.content.Clear();
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
if(cfx.content.GetCount())
|
||||
SaveFile(ConfigFile("pseudo_header_src.cpp"), cfx.content);
|
||||
#endif
|
||||
return cfx;
|
||||
}
|
||||
|
||||
|
|
@ -478,6 +483,9 @@ void AssistEditor::SyncCurrentFile(CurrentFileContext& cfx, int line_delta)
|
|||
m.id);
|
||||
}
|
||||
}
|
||||
annotating = false;
|
||||
if(!navigator_global)
|
||||
Search();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -490,11 +498,11 @@ void AssistEditor::SyncCurrentFile()
|
|||
|
||||
void AssistEditor::NewFile()
|
||||
{
|
||||
SyncHeaders();
|
||||
int line_delta;
|
||||
CurrentFileContext cfx = CurrentContext(line_delta);
|
||||
SyncCurrentFile(cfx, line_delta);
|
||||
SetAutoCompleteFile(cfx);
|
||||
SyncHeaders();
|
||||
}
|
||||
|
||||
void AssistEditor::Assist(bool macros)
|
||||
|
|
@ -744,7 +752,7 @@ void AssistEditor::AssistInsert()
|
|||
else {
|
||||
String txt = f.name;
|
||||
int param_count;
|
||||
ParseSignature(f.name, f.signature, ¶m_count);
|
||||
ParsePretty(f.name, f.signature, ¶m_count);
|
||||
if(param_count >= 0)
|
||||
txt << "()";
|
||||
if(f.signature.EndsWith("::"))
|
||||
|
|
@ -803,21 +811,7 @@ bool AssistEditor::Key(dword key, int count)
|
|||
Exclamation("No annotation for this line.");
|
||||
}
|
||||
if(key == K_F11) {
|
||||
HdependTimeDirty();
|
||||
VectorMap<String, Vector<String>> deps;
|
||||
{
|
||||
TIMESTOP("Scan");
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
for(int i = 0; i < wspc.GetCount(); i++) {
|
||||
const Package& pk = wspc.GetPackage(i);
|
||||
String n = wspc[i];
|
||||
for(int i = 0; i < pk.file.GetCount(); i++) {
|
||||
String path = SourcePath(n, pk.file[i]);
|
||||
deps.GetAdd(path) = pick(HdependGetDependencies(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
DDUMPM(deps);
|
||||
StartIndexing(theide->GetCurrentIncludePath(), theide->GetCurrentDefines());
|
||||
}
|
||||
#endif
|
||||
if(popup.IsOpen()) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,13 @@ struct Navigator {
|
|||
bool operator<(const NavLine& b) const;
|
||||
};
|
||||
|
||||
struct NavItem {
|
||||
enum KindEnum { KIND_LINE = -4000, KIND_NEST, KIND_FILE, KIND_SRCFILE };
|
||||
|
||||
struct NavItem : AnnotationItem {
|
||||
// int priority = 0; // for sorting based on search accuracy
|
||||
/* int decl_line = 0;
|
||||
int decl_file = 0;
|
||||
|
||||
String nest;
|
||||
String qitem;
|
||||
String name;
|
||||
|
|
@ -30,13 +36,11 @@ struct Navigator {
|
|||
bool impl;
|
||||
bool decl;
|
||||
int8 pass;
|
||||
|
||||
Vector<NavLine> linefo;
|
||||
|
||||
void Set(const CppItem& m);
|
||||
*/
|
||||
};
|
||||
|
||||
enum KindEnum { KIND_LINE = 123, KIND_NEST, KIND_FILE, KIND_SRCFILE };
|
||||
|
||||
struct ScopeDisplay : Display {
|
||||
Navigator *navigator;
|
||||
|
||||
|
|
@ -52,23 +56,22 @@ struct Navigator {
|
|||
};
|
||||
|
||||
struct NavigatorDisplay : Display {
|
||||
const Vector<NavItem *>& item;
|
||||
const Vector<const NavItem *>& item;
|
||||
|
||||
int DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const;
|
||||
virtual void PaintBackground(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const;
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const;
|
||||
virtual Size GetStdSize(const Value& q) const;
|
||||
|
||||
NavigatorDisplay(const Vector<NavItem *>& item) : item(item) {}
|
||||
NavigatorDisplay(const Vector<const NavItem *>& item) : item(item) {}
|
||||
};
|
||||
|
||||
Ide *theide;
|
||||
|
||||
Array<NavItem> nitem;
|
||||
VectorMap<String, Vector<NavItem *> > gitem;
|
||||
Vector<NavItem *> litem;
|
||||
Array<NavItem> nest_item;
|
||||
VectorMap<int, SortedVectorMap<int, int> > linefo;
|
||||
Vector<const NavItem *> litem;
|
||||
Array<NavItem> nest_item; // list separators with nest (scope) or file
|
||||
VectorMap<int, SortedVectorMap<int, int> > linefo; // TODO remove?
|
||||
NavigatorDisplay navidisplay;
|
||||
bool navigating;
|
||||
TimeCallback search_trigger;
|
||||
|
|
@ -86,7 +89,6 @@ struct Navigator {
|
|||
ScopeDisplay scope_display;
|
||||
|
||||
void TriggerSearch();
|
||||
void NavGroup(bool local);
|
||||
void Search();
|
||||
void Scope();
|
||||
void ListLineEnabled(int i, bool& b);
|
||||
|
|
@ -103,9 +105,6 @@ struct Navigator {
|
|||
void GoToNavLine();
|
||||
void SyncCursor();
|
||||
|
||||
static bool SortByLines(const NavItem *a, const NavItem *b);
|
||||
static bool SortByNames(const NavItem *a, const NavItem *b);
|
||||
|
||||
typedef Navigator CLASSNAME;
|
||||
|
||||
Navigator();
|
||||
|
|
@ -152,6 +151,7 @@ struct AssistEditor : CodeEditor, Navigator {
|
|||
} assist_display;
|
||||
|
||||
RichTextCtrl annotation_popup;
|
||||
bool annotating = false;
|
||||
Vector<AnnotationItem> annotations;
|
||||
|
||||
int assist_cursor;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,38 @@ Image CxxIcon(int kind)
|
|||
return BrowserImg::unknown();
|
||||
}
|
||||
|
||||
int PaintCpp(Draw& w, const Rect& r, int kind, const String& name, const String& pretty, Color ink, bool focuscursor, bool retval_last)
|
||||
{
|
||||
int x = r.left;
|
||||
|
||||
Image img = CxxIcon(kind);
|
||||
Size isz = img.GetSize();
|
||||
w.DrawImage(x + (DPI(16) - isz.cx) / 2, r.top + (r.GetHeight() - isz.cy) / 2, img);
|
||||
|
||||
x += DPI(16);
|
||||
int y = r.top + (r.GetHeight() - Draw::GetStdFontCy()) / 2;
|
||||
|
||||
#ifdef _DEBUG
|
||||
String ks = " [" + AsString(kind) + "] ";
|
||||
w.DrawText(x, y, ks);
|
||||
x += GetTextSize(ks, StdFont()).cx;
|
||||
#endif
|
||||
|
||||
Vector<ItemTextPart> n = ParsePretty(name, pretty);
|
||||
int count = n.GetCount();
|
||||
if(retval_last)
|
||||
for(int i = 0; i < n.GetCount(); i++)
|
||||
if(n[i].type == ITEM_NAME) {
|
||||
PaintText(w, x, y, pretty, n, i, count - i, focuscursor, ink, false);
|
||||
w.DrawText(x, y, " → ", StdFont(), SGray());
|
||||
x += GetTextSize(" → ", StdFont()).cx;
|
||||
count = i;
|
||||
break;
|
||||
}
|
||||
PaintText(w, x, y, pretty, n, 0, count, focuscursor, ink, false);
|
||||
return x;
|
||||
}
|
||||
|
||||
void AssistEditor::AssistDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
int ii = q;
|
||||
|
|
@ -34,26 +66,7 @@ void AssistEditor::AssistDisplay::Paint(Draw& w, const Rect& r, const Value& q,
|
|||
AutoCompleteItem& m = editor->assist_item[editor->assist_item_ndx[ii]];
|
||||
|
||||
w.DrawRect(r, paper);
|
||||
bool focuscursor = (style & (FOCUS|CURSOR)) == (FOCUS|CURSOR) || (style & SELECT);
|
||||
|
||||
int x = r.left;
|
||||
int ry = r.top + r.GetHeight() / 2;
|
||||
|
||||
Image img = CxxIcon(m.kind);
|
||||
Size isz = img.GetSize();
|
||||
w.DrawImage(x + (DPI(16) - isz.cx) / 2, r.top + (r.GetHeight() - isz.cy) / 2, img);
|
||||
|
||||
x += DPI(16);
|
||||
int y = ry - Draw::GetStdFontCy() / 2;
|
||||
#ifdef _DEBUG
|
||||
String ks = " [" + AsString(m.kind) + "] ";
|
||||
w.DrawText(x, y, ks);
|
||||
x += GetTextSize(ks, StdFont()).cx;
|
||||
#endif
|
||||
int x0 = x;
|
||||
Vector<ItemTextPart> n = ParseSignature(m.name, m.signature);
|
||||
|
||||
int starti = 0;
|
||||
PaintText(w, x, y, m.signature, n, starti, n.GetCount(), focuscursor, ink, false);
|
||||
PaintCpp(w, r, m.kind, m.name, m.signature, ink, (style & (FOCUS|CURSOR)) == (FOCUS|CURSOR) || (style & SELECT));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Browser.h"
|
||||
#include <ide/ide.h>
|
||||
|
||||
#include <plugin/lz4/lz4.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Browser.h"
|
||||
#include <ide/ide.h>
|
||||
|
||||
bool MatchCib(const String& s, const String& match)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ void TopicEditor::InsertItem()
|
|||
String DecoratedItem(const String& name, const String& pretty)
|
||||
{
|
||||
String qtf = "[%00-00K ";
|
||||
Vector<ItemTextPart> n = ParseSignature(name, pretty);
|
||||
Vector<ItemTextPart> n = ParsePretty(name, pretty);
|
||||
/* TODO
|
||||
if(pari < 0) {
|
||||
if(m.virt)
|
||||
|
|
@ -435,7 +435,7 @@ String CreateQtf(const AnnotationItem& m, const String& lang, bool onlyhdr = fal
|
|||
qtf << "[s3%" << lang << " ";
|
||||
|
||||
if(!str) {
|
||||
Vector<ItemTextPart> n = ParseSignature(m.name, m.pretty);
|
||||
Vector<ItemTextPart> n = ParsePretty(m.name, m.pretty);
|
||||
if(!str) {
|
||||
bool was;
|
||||
for(const auto& h : n)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ void PaintText(Draw& w, int& x, int y, const char *text, const Vector<ItemTextPa
|
|||
int starti, int count, bool focuscursor, Color _ink, bool italic)
|
||||
{
|
||||
static int maxascent = MaxAscent(BrowserFont());
|
||||
for(int i = starti; i < count; i++) {
|
||||
const ItemTextPart& p = n[i];
|
||||
for(int i = 0; i < count; i++) {
|
||||
const ItemTextPart& p = n[starti + i];
|
||||
Font f = BrowserFont();
|
||||
Color ink = SColorText;
|
||||
switch(p.type) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Browser.h"
|
||||
#include <ide/ide.h>
|
||||
|
||||
struct MoveTopicDlg : public WithMoveTopicLayout<TopWindow> {
|
||||
typedef MoveTopicDlg CLASSNAME;
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ void SyncRefs()
|
|||
SyncRefsShowProgress = true;
|
||||
return;
|
||||
}
|
||||
TIMESTOP("SyncRefs");
|
||||
Progress pi;
|
||||
pi.AlignText(ALIGN_LEFT);
|
||||
Vector<String> upp = GetUppDirs();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Browser.h"
|
||||
#include <ide/ide.h>
|
||||
|
||||
bool IsTopicFile(const char *path)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class Hdepend {
|
|||
ArrayMap<String, Info> map;
|
||||
Vector<String> incdir; // include directories
|
||||
VectorMap<String, Index<String> > depends; // externally forced dependecies
|
||||
bool cache_time = false;
|
||||
bool console = true;
|
||||
|
||||
void Include(const char *trm, Info& info, const String& filedir, bool bydefine);
|
||||
void ScanFile(const String& path, int map_index);
|
||||
|
|
@ -69,8 +69,8 @@ class Hdepend {
|
|||
void GetMacroIndex(Index<String>& dest, int ix);
|
||||
|
||||
public:
|
||||
void SetDirs(Vector<String>&& id) { incdir = pick(id); map.Clear(); }
|
||||
void SetDirs(const String& includes) { incdir = pick(Split(includes, ';')); map.Clear(); }
|
||||
void SetDirs(Vector<String>&& id);
|
||||
void SetDirs(const String& includes);
|
||||
void TimeDirty();
|
||||
|
||||
void ClearDependencies() { depends.Clear(); }
|
||||
|
|
@ -85,7 +85,7 @@ public:
|
|||
const Vector<String>& GetDefines(const String& path);
|
||||
Vector<String> GetDependencies(const String& path, bool bydefine_too = true);
|
||||
const Vector<String>& GetAllFiles() { return map.GetKeys(); }
|
||||
void CacheTime() { cache_time = true; }
|
||||
void NoConsole() { console = false; }
|
||||
};
|
||||
|
||||
class IdeContext
|
||||
|
|
@ -153,8 +153,8 @@ public:
|
|||
virtual ~IdeContext() {}
|
||||
};
|
||||
|
||||
IdeContext *TheIde();
|
||||
void TheIde(IdeContext *context);
|
||||
Ide *TheIde();
|
||||
void TheIde(Ide *context);
|
||||
|
||||
bool IsVerbose();
|
||||
void PutConsole(const char *s);
|
||||
|
|
@ -391,7 +391,6 @@ public:
|
|||
|
||||
File() { Init(); }
|
||||
File(const String& s) : String(s) { Init(); }
|
||||
rval_default(File);
|
||||
};
|
||||
struct Config {
|
||||
String name;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void Hdepend::ScanFile(const String& path, int map_index)
|
|||
|
||||
auto Id = [&](const char *id) {
|
||||
int n = strlen(id);
|
||||
if(memcmp(term, id, n) == 0 && findarg(term[n], ' ', '\t')) {
|
||||
if(memcmp(term, id, n) == 0 && findarg(term[n], ' ', '\t') >= 0) {
|
||||
term += n + 1;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -160,6 +160,7 @@ void Hdepend::ScanFile(const String& path, int map_index)
|
|||
if(p.Char('#') && p.Id("define") && p.IsId() && id == p.ReadId())
|
||||
info.guarded = true;
|
||||
}
|
||||
term = p.GetPtr();
|
||||
}
|
||||
catch(CParser::Error) {}
|
||||
}
|
||||
|
|
@ -268,29 +269,19 @@ int Hdepend::File(const String& f)
|
|||
Info& info = map[ii];
|
||||
if(info.flag) return ii;
|
||||
info.flag = true;
|
||||
if(cache_time) {
|
||||
Time file_time = FileGetTime(path);
|
||||
if(IsNull(file_time) || file_time == info.time) {
|
||||
if(info.timedirty) {
|
||||
info.time = FileGetTime(path);
|
||||
for(int i = 0; i < info.depend.GetCount(); i++)
|
||||
File(map.GetKey(info.depend[i]));
|
||||
info.timedirty = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Time file_time = FileGetTime(path);
|
||||
if(IsNull(file_time) || file_time == info.time) {
|
||||
if(info.timedirty) {
|
||||
for(int i = 0; i < info.depend.GetCount(); i++)
|
||||
File(map.GetKey(info.depend[i]));
|
||||
info.timedirty = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
info.time = file_time;
|
||||
if(info.time > GetSysTime() + 10)
|
||||
PutConsole(String().Cat() << "WARNING: " << path << " has invalid (future) time " << info.time);
|
||||
ScanFile(path, ii);
|
||||
}
|
||||
info.time = file_time;
|
||||
if(console && info.time > GetSysTime() + 10)
|
||||
PutConsole(String().Cat() << "WARNING: " << path << " has invalid (future) time " << info.time);
|
||||
ScanFile(path, ii);
|
||||
}
|
||||
return ii;
|
||||
}
|
||||
|
|
@ -355,6 +346,19 @@ void Hdepend::ClearMacroFlag()
|
|||
map[i].macroflag = false;
|
||||
}
|
||||
|
||||
void Hdepend::SetDirs(Vector<String>&& id)
|
||||
{
|
||||
if(incdir != id) {
|
||||
incdir = pick(id);
|
||||
map.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Hdepend::SetDirs(const String& includes)
|
||||
{
|
||||
SetDirs(pick(Split(includes, ';')));
|
||||
}
|
||||
|
||||
void Hdepend::TimeDirty()
|
||||
{
|
||||
for(int i = 0; i < map.GetCount(); i++)
|
||||
|
|
@ -376,7 +380,7 @@ Time Hdepend::FileTime(const String& path)
|
|||
FindFile ff(dep[i]);
|
||||
if(ff) {
|
||||
Time tm = ff.GetLastWriteTime();
|
||||
if(tm > GetSysTime() + 10)
|
||||
if(console && tm > GetSysTime() + 10)
|
||||
PutConsole(String().Cat() << "WARNING: " << dep[i] << " has invalid (future) time " << tm);
|
||||
if(tm > h)
|
||||
h = tm;
|
||||
|
|
@ -398,8 +402,9 @@ bool Hdepend::BlitzApproved(const String& path)
|
|||
return true;
|
||||
for(int i = 0; i < info.depend.GetCount(); i++)
|
||||
if(!info.bydefine[i] && !map[info.depend[i]].CanBlitz()) {
|
||||
PutVerbose(String().Cat() << map.GetKey(info.depend[i])
|
||||
<< "(1) : blocks BLITZ of " << path);
|
||||
if(console)
|
||||
PutVerbose(String().Cat() << map.GetKey(info.depend[i])
|
||||
<< "(1) : blocks BLITZ of " << path);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#include "Core.h"
|
||||
#include <ide/ide.h>
|
||||
|
||||
static IdeContext *the_ide;
|
||||
static Ide *the_ide;
|
||||
|
||||
IdeContext *TheIde() { return the_ide; }
|
||||
void TheIde(IdeContext *context) { the_ide = context; }
|
||||
Ide *TheIde() { return the_ide; }
|
||||
void TheIde(Ide *context) { the_ide = context; }
|
||||
|
||||
bool IsVerbose() { return the_ide ? the_ide->IsVerbose() : false; }
|
||||
void PutConsole(const char *s) { if(the_ide) the_ide->PutConsole(s); }
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ bool IsCSourceFile(const char *path)
|
|||
bool IsCHeaderFile(const char *path)
|
||||
{
|
||||
String ext = ToLower(GetFileExt(path));
|
||||
return ext == ".h" || ext == ".hpp" || ext == ".hh" || ext == ".hxx";
|
||||
return ext == ".h" || ext == ".hpp" || ext == ".hh" || ext == ".hxx" || ext == ".i";
|
||||
}
|
||||
|
||||
bool IsFullDirectory(const String& d) {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@
|
|||
void AssistEditor::SyncHeaders()
|
||||
{
|
||||
// hdepend.CacheTime();
|
||||
TIMESTOP("SyncHeaders");
|
||||
hdepend.TimeDirty();
|
||||
hdepend.SetDirs(theide->GetCurrentIncludePath() + ";" + GetClangInternalIncludes());
|
||||
master_source.Clear();
|
||||
String editfile = NormalizePath(theide->editfile);
|
||||
if(editfile.GetCount() && !IsSourceFile(editfile)) {
|
||||
if(editfile.GetCount() && IsCHeaderFile(editfile)) {
|
||||
for(int pass = 0; pass < 2; pass++) { // all packages in second pass
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
for(int i = 0; i < wspc.GetCount(); i++) { // find package of included file
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
#if 0
|
||||
|
||||
// TODO: remove
|
||||
|
||||
#include "ide.h"
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
|
@ -750,3 +754,5 @@ void Navigator::NaviSort()
|
|||
sorting = !sorting;
|
||||
Search();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
596
uppsrc/ide/Navigator2.cpp
Normal file
596
uppsrc/ide/Navigator2.cpp
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
#include "ide.h"
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
String FormatNest(String nest)
|
||||
{
|
||||
int q = nest.Find("@");
|
||||
if(q >= 0) {
|
||||
nest.Trim(q);
|
||||
nest << "[anonymous]";
|
||||
}
|
||||
return nest;
|
||||
}
|
||||
|
||||
int CharFilterNavigator(int c)
|
||||
{
|
||||
return c == ':' ? '.' : IsAlNum(c) || c == '_' || c == '.' ? c : 0;
|
||||
}
|
||||
|
||||
void PaintTeXt(Draw& w, int& x, int y, const String& text, Font font, Color ink)
|
||||
{
|
||||
static int maxascent = MaxAscent(StdFont());
|
||||
Size sz = GetTextSize(text, font);
|
||||
w.DrawText(x, y + maxascent - font.GetAscent(), text, font, ink);
|
||||
x += sz.cx;
|
||||
}
|
||||
|
||||
int DrawFileName0(Draw& w, const Rect& r, const String& h, Color ink, int x)
|
||||
{
|
||||
if(h.GetCount() == 0)
|
||||
return 0;
|
||||
int q = h.Find("\xff");
|
||||
String ns;
|
||||
String fn = h;
|
||||
if(q >= 0) {
|
||||
ns = h.Mid(0, q) + ' ';
|
||||
fn = h.Mid(q + 1);
|
||||
}
|
||||
String s = GetFileName(GetFileFolder(h)) + "/";
|
||||
x += r.left;
|
||||
if(ns.GetCount()) {
|
||||
PaintTeXt(w, x, r.top, ns, StdFont().Bold(), ink);
|
||||
PaintTeXt(w, x, r.top, "(", StdFont(), ink);
|
||||
}
|
||||
PaintTeXt(w, x, r.top, s, StdFont(), ink);
|
||||
s = GetFileName(h);
|
||||
PaintTeXt(w, x, r.top, s, StdFont().Bold(), ink);
|
||||
if(ns.GetCount())
|
||||
PaintTeXt(w, x, r.top, ")", StdFont(), ink);
|
||||
return x - r.left;
|
||||
}
|
||||
|
||||
Size GetDrawFileNameSize(const String& h)
|
||||
{
|
||||
NilDraw w;
|
||||
return Size(DrawFileName0(w, Size(999999, 999999), h, Null, 0), StdFont().Bold().GetCy());
|
||||
}
|
||||
|
||||
void DrawFileName(Draw& w, const Rect& r, const String& h, Color ink)
|
||||
{
|
||||
DrawFileName0(w, r, h, ink, min(r.GetWidth() - GetDrawFileNameSize(h).cx, 0));
|
||||
}
|
||||
|
||||
int PaintFileName(Draw& w, const Rect& r, String h, Color ink)
|
||||
{
|
||||
if(*h == '\xff')
|
||||
h.Remove(0, 1);
|
||||
return DrawFileName0(w, r, h, ink, 0);
|
||||
}
|
||||
|
||||
Navigator::Navigator()
|
||||
: navidisplay(litem)
|
||||
{
|
||||
scope_display.navigator = this;
|
||||
scope.NoHeader();
|
||||
scope.AddColumn().SetDisplay(scope_display);
|
||||
scope.NoWantFocus();
|
||||
scope.WhenSel = THISBACK(Scope);
|
||||
scope.WhenLeftDouble = THISBACK(ScopeDblClk);
|
||||
|
||||
list.NoHeader();
|
||||
list.AddRowNumColumn().SetDisplay(navidisplay);
|
||||
list.SetLineCy(max(16, GetStdFontCy()));
|
||||
list.NoWantFocus();
|
||||
list.WhenLeftClick = THISBACK(NavigatorClick);
|
||||
list.WhenSel = THISBACK(SyncNavLines);
|
||||
list.WhenLineEnabled = THISBACK(ListLineEnabled);
|
||||
|
||||
navlines.NoHeader().NoWantFocus();
|
||||
navlines.WhenLeftClick = THISBACK(GoToNavLine);
|
||||
navlines.AddColumn().SetDisplay(Single<LineDisplay>());
|
||||
|
||||
search <<= THISBACK(TriggerSearch);
|
||||
search.SetFilter(CharFilterNavigator);
|
||||
search.WhenEnter = THISBACK(NavigatorEnter);
|
||||
|
||||
sortitems.Image(BrowserImg::Sort());
|
||||
sortitems <<= THISBACK(NaviSort);
|
||||
sorting = false;
|
||||
|
||||
dlgmode = false;
|
||||
}
|
||||
|
||||
void Navigator::SyncCursor()
|
||||
{
|
||||
String k = "(" + GetKeyDesc(IdeKeys::AK_GOTO().key[0]) + ") ";
|
||||
search.NullText("Symbol/lineno " + k);
|
||||
search.Tip(IsNull(search) ? String() : "Clear " + k);
|
||||
|
||||
if(!navigating && theide->editfile.GetCount()) {
|
||||
navlines.KillCursor();
|
||||
int q = linefo.Find(GetSourceFileIndex(theide->editfile));
|
||||
if(q < 0)
|
||||
return;
|
||||
navigating = true;
|
||||
SortedVectorMap<int, int>& m = linefo[q];
|
||||
q = m.FindUpperBound(GetCurrentLine() + 1) - 1;
|
||||
if(q >= 0 && q < m.GetCount())
|
||||
list.SetCursor(m[q]);
|
||||
navigating = false;
|
||||
}
|
||||
SyncLines();
|
||||
if(scope.IsCursor())
|
||||
scope.RefreshRow(scope.GetCursor());
|
||||
}
|
||||
|
||||
void Navigator::SyncLines()
|
||||
{
|
||||
if(IsNull(theide->editfile) || navigating)
|
||||
return;
|
||||
int ln = GetCurrentLine() + 1;
|
||||
int fi = GetSourceFileIndex(theide->editfile);
|
||||
int q = -1;
|
||||
for(int i = 0; i < navlines.GetCount(); i++) {
|
||||
const NavLine& l = navlines.Get(i, 0).To<NavLine>();
|
||||
if(l.file == fi && l.line <= ln && i < navlines.GetCount())
|
||||
q = i;
|
||||
}
|
||||
if(dlgmode)
|
||||
navlines.GoBegin();
|
||||
else
|
||||
if(q >= 0)
|
||||
navlines.SetCursor(q);
|
||||
}
|
||||
|
||||
void Navigator::SyncNavLines()
|
||||
{
|
||||
int sc = navlines.GetScroll();
|
||||
navlines.Clear();
|
||||
int ii = list.GetCursor();
|
||||
if(ii >= 0 && ii < litem.GetCount()) {
|
||||
Vector<NavLine> l = GetNavLines(*litem[ii]);
|
||||
for(int i = 0; i < l.GetCount(); i++) {
|
||||
String p = GetSourceFilePath(l[i].file);
|
||||
navlines.Add(RawToValue(l[i]));
|
||||
}
|
||||
navlines.ScrollTo(sc);
|
||||
SyncLines();
|
||||
}
|
||||
}
|
||||
|
||||
int Navigator::LineDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style, int x) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
const NavLine& l = q.To<NavLine>();
|
||||
x += r.left;
|
||||
String p = GetSourceFilePath(l.file);
|
||||
int y = r.top + (r.GetHeight() - StdFont().GetCy()) / 2;
|
||||
PaintTeXt(w, x, y, GetFileName(GetFileFolder(p)) + "/", StdFont(), ink);
|
||||
PaintTeXt(w, x, y, GetFileName(p), StdFont().Bold(), ink);
|
||||
PaintTeXt(w, x, y, " (", StdFont(), ink);
|
||||
PaintTeXt(w, x, y, AsString(l.line), StdFont().Bold(), ink);
|
||||
PaintTeXt(w, x, y, ")", StdFont(), ink);
|
||||
return x - r.left;
|
||||
}
|
||||
|
||||
void Navigator::LineDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
DoPaint(w, r, q, ink, paper, style, min(r.GetWidth() - GetStdSize(q).cx, 0));
|
||||
}
|
||||
|
||||
Size Navigator::LineDisplay::GetStdSize(const Value& q) const
|
||||
{
|
||||
NilDraw w;
|
||||
return Size(DoPaint(w, Size(999999, 999999), q, White(), White(), 0, 0), StdFont().Bold().GetCy());
|
||||
}
|
||||
|
||||
void Navigator::GoToNavLine()
|
||||
{
|
||||
if(dlgmode)
|
||||
return;
|
||||
int ii = navlines.GetClickPos().y;
|
||||
if(ii >= 0 && ii < navlines.GetCount() && theide) {
|
||||
const NavLine& l = navlines.Get(ii, 0).To<NavLine>();
|
||||
theide->GotoPos(GetSourceFilePath(l.file), l.line);
|
||||
}
|
||||
}
|
||||
|
||||
bool Navigator::NavLine::operator<(const NavLine& b) const
|
||||
{
|
||||
String p1 = GetSourceFilePath(file);
|
||||
String p2 = GetSourceFilePath(b.file);
|
||||
return CombineCompare/*(!impl, !b.impl)*/
|
||||
(GetFileExt(p2), GetFileExt(p1)) // .h > .c
|
||||
(GetFileName(p1), GetFileName(p2))
|
||||
(p1, p2)
|
||||
(line, b.line) < 0;
|
||||
}
|
||||
|
||||
Vector<Navigator::NavLine> Navigator::GetNavLines(const NavItem& m)
|
||||
{
|
||||
_DBG_
|
||||
Vector<NavLine> l;
|
||||
/*
|
||||
CodeBaseLock __;
|
||||
int q = CodeBase().Find(m.nest);
|
||||
if(q < 0 || IsNull(m.qitem))
|
||||
return l;
|
||||
const Array<CppItem>& a = CodeBase()[q];
|
||||
for(int i = 0; i < a.GetCount(); i++) {
|
||||
const CppItem& mm = a[i];
|
||||
if(mm.qitem == m.qitem) {
|
||||
NavLine& nl = l.Add();
|
||||
nl.impl = mm.impl;
|
||||
nl.file = mm.file;
|
||||
nl.line = mm.line;
|
||||
}
|
||||
}
|
||||
Sort(l);
|
||||
*/
|
||||
return l;
|
||||
}
|
||||
|
||||
void Navigator::Navigate()
|
||||
{
|
||||
if(navigating)
|
||||
return;
|
||||
navigating = true;
|
||||
int ii = list.GetCursor();
|
||||
if(theide && ii >= 0 && ii < litem.GetCount()) {
|
||||
int ln = GetCurrentLine() + 1;
|
||||
const NavItem& m = *litem[ii];
|
||||
if(m.kind == KIND_LINE || IsNull(search)) {
|
||||
theide->GotoPos(Null, m.line);
|
||||
if(m.kind == KIND_LINE) { // Go to line - restore file view
|
||||
search.Clear();
|
||||
Search();
|
||||
navigating = false;
|
||||
}
|
||||
SyncCursor();
|
||||
}
|
||||
else
|
||||
if(m.kind == KIND_SRCFILE) {
|
||||
theide->AddHistory();
|
||||
theide->EditFile(m.id);
|
||||
theide->AddHistory();
|
||||
}
|
||||
else {
|
||||
Vector<NavLine> l = GetNavLines(m);
|
||||
int q = l.GetCount() - 1;
|
||||
for(int i = 0; i < l.GetCount(); i++)
|
||||
if(GetSourceFilePath(l[i].file) == NormalizeSourcePath(theide->editfile) && l[i].line == ln) {
|
||||
q = (i + l.GetCount() + 1) % l.GetCount();
|
||||
break;
|
||||
}
|
||||
if(q >= 0 && q < l.GetCount()) {
|
||||
String path = GetSourceFilePath(l[q].file);
|
||||
// TODO:
|
||||
_DBG_
|
||||
// if(!theide->GotoDesignerFile(path, m.nest, m.name, l[q].line))
|
||||
// theide->GotoPos(path, l[q].line);
|
||||
}
|
||||
}
|
||||
}
|
||||
navigating = false;
|
||||
}
|
||||
|
||||
void Navigator::ScopeDblClk()
|
||||
{
|
||||
if(!scope.IsCursor())
|
||||
return;
|
||||
String h = scope.GetKey();
|
||||
if((byte)*h == 0xff)
|
||||
theide->GotoPos(h.Mid(1), 1);
|
||||
else {
|
||||
list.GoBegin();
|
||||
Navigate();
|
||||
}
|
||||
}
|
||||
|
||||
void Navigator::NavigatorClick()
|
||||
{
|
||||
if(dlgmode)
|
||||
return;
|
||||
int q = list.GetClickPos().y;
|
||||
if(q >= 0 && q < list.GetCount())
|
||||
Navigate();
|
||||
}
|
||||
|
||||
void Navigator::NavigatorEnter()
|
||||
{
|
||||
if(list.GetCount()) {
|
||||
list.GoBegin();
|
||||
Navigate();
|
||||
}
|
||||
}
|
||||
|
||||
void Ide::ToggleNavigator()
|
||||
{
|
||||
editor.Navigator(!editor.navigator);
|
||||
}
|
||||
|
||||
void Ide::SearchCode()
|
||||
{
|
||||
if(!editor.navigator)
|
||||
editor.Navigator(true);
|
||||
if(!IsNull(~editor.search)) {
|
||||
editor.search.Clear();
|
||||
editor.Search();
|
||||
editor.SetFocus();
|
||||
}
|
||||
else {
|
||||
String h = editor.GetWord();
|
||||
if(h.GetCount()) {
|
||||
editor.search <<= h;
|
||||
editor.search.SelectAll();
|
||||
editor.Search();
|
||||
}
|
||||
editor.search.SetFocus();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: What is this?
|
||||
void Ide::SwitchHeader() {
|
||||
int c = filelist.GetCursor();
|
||||
if(c < 0) return;
|
||||
String currfile = filelist[c];
|
||||
const char *ext = GetFileExtPos(currfile);
|
||||
if(!stricmp(ext, ".h") || !stricmp(ext, ".hpp")
|
||||
|| !stricmp(ext, ".lay") || !stricmp(ext, ".iml")) {
|
||||
int f = filelist.Find(ForceExt(currfile, ".cpp"));
|
||||
if(f < 0) f = filelist.Find(ForceExt(currfile, ".c"));
|
||||
if(f < 0) f = filelist.Find(ForceExt(currfile, ".cc"));
|
||||
if(f >= 0) filelist.SetCursor(f);
|
||||
}
|
||||
}
|
||||
|
||||
void Navigator::NavigatorDisplay::PaintBackground(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
int ii = q;
|
||||
if(ii < 0 || ii >= item.GetCount())
|
||||
return;
|
||||
const NavItem& m = *item[ii];
|
||||
bool focuscursor = (style & (FOCUS|CURSOR)) == (FOCUS|CURSOR) || (style & SELECT);
|
||||
if(findarg(m.kind, KIND_FILE, KIND_NEST) >= 0)
|
||||
w.DrawRect(r, focuscursor ? paper : m.kind == KIND_NEST ? Blend(SColorMark, SColorPaper, 220)
|
||||
: SColorFace);
|
||||
else
|
||||
w.DrawRect(r, paper);
|
||||
}
|
||||
|
||||
|
||||
int Navigator::NavigatorDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
int ii = q;
|
||||
if(ii < 0 || ii >= item.GetCount())
|
||||
return 0;
|
||||
const NavItem& m = *item[ii];
|
||||
bool focuscursor = (style & (FOCUS|CURSOR)) == (FOCUS|CURSOR) || (style & SELECT);
|
||||
|
||||
int x = r.left;
|
||||
int y = (r.GetHeight() - Draw::GetStdFontCy()) / 2;
|
||||
|
||||
if(findarg(m.kind, KIND_FILE, KIND_NEST) >= 0) {
|
||||
w.DrawRect(r, focuscursor ? paper : m.kind == KIND_NEST ? Blend(SColorMark, SColorPaper, 220)
|
||||
: SColorFace);
|
||||
if(findarg(m.kind, KIND_FILE) >= 0)
|
||||
return PaintFileName(w, r, m.pretty, ink);
|
||||
String h = FormatNest(m.pretty);
|
||||
w.DrawText(x, y, h, StdFont().Bold(), ink);
|
||||
return GetTextSize(h, StdFont().Bold()).cx;
|
||||
}
|
||||
|
||||
w.DrawRect(r, paper);
|
||||
|
||||
if(m.kind == KIND_SRCFILE)
|
||||
return PaintFileName(w, r, m.pretty, ink);
|
||||
|
||||
if(m.kind == KIND_LINE) {
|
||||
w.DrawText(x, y, m.pretty, StdFont().Bold(), ink);
|
||||
return GetTextSize(m.pretty, StdFont().Bold()).cx;
|
||||
}
|
||||
|
||||
return PaintCpp(w, r, m.kind, m.name, m.pretty, ink, focuscursor, true);
|
||||
}
|
||||
|
||||
void Navigator::NavigatorDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
DoPaint(w, r, q, ink, paper, style);
|
||||
}
|
||||
|
||||
Size Navigator::NavigatorDisplay::GetStdSize(const Value& q) const
|
||||
{
|
||||
NilDraw w;
|
||||
return Size(DoPaint(w, Size(999999, 999999), q, White(), White(), 0), Draw::GetStdFontCy());
|
||||
}
|
||||
|
||||
void Navigator::TriggerSearch()
|
||||
{
|
||||
search_trigger.KillSet(100, THISBACK(Search));
|
||||
}
|
||||
|
||||
void Navigator::Search()
|
||||
{
|
||||
sortitems.Check(sorting);
|
||||
int sc = scope.GetScroll();
|
||||
String key = scope.GetKey();
|
||||
String s = TrimBoth(~search);
|
||||
String search_name, search_nest;
|
||||
bool wholeclass = false;
|
||||
bool both = false;
|
||||
navigator_global = false;
|
||||
if(s.Find('.') >= 0) {
|
||||
Vector<String> h = Split((String)~search, '.');
|
||||
if(*s.Last() == '.')
|
||||
search_nest = Join(h, "::");
|
||||
else {
|
||||
search_name = h.Pop();
|
||||
if(h.GetCount())
|
||||
search_nest = Join(h, "::");
|
||||
}
|
||||
wholeclass = *s == '.' && search_nest.GetCount();
|
||||
}
|
||||
else {
|
||||
search_name = search_nest = ~search;
|
||||
both = true;
|
||||
}
|
||||
s = Join(Split(s, '.'), "::") + (s.EndsWith(".") ? "::" : "");
|
||||
int lineno = StrInt(s);
|
||||
nitem.Clear();
|
||||
Index<String> nests;
|
||||
if(IsNull(theide->editfile))
|
||||
return;
|
||||
int fileii = GetSourceFileIndex(theide->editfile);
|
||||
if(!IsNull(lineno)) {
|
||||
NavItem& m = nitem.Add();
|
||||
m.pretty = "Go to line " + AsString(lineno);
|
||||
m.kind = KIND_LINE;
|
||||
m.line = lineno;
|
||||
nests.Add(Null);
|
||||
}
|
||||
else
|
||||
if(IsNull(s) && !sorting) {
|
||||
bool sch = GetFileExt(theide->editfile) == ".sch";
|
||||
Ide *theide = TheIde();
|
||||
if(theide)
|
||||
for(const AnnotationItem& m : theide->editor.annotations) {
|
||||
NavItem& n = nitem.Add();
|
||||
(AnnotationItem&)n = m;
|
||||
nests.FindAdd(n.nest);
|
||||
}
|
||||
SortIndex(nests);
|
||||
}
|
||||
else { // TODO: Sort codeindex paths, add files in that order to make things stable
|
||||
navigator_global = true;
|
||||
String usearch_nest = ToUpper(search_nest);
|
||||
String usearch_name = ToUpper(search_name);
|
||||
Index<String> visited;
|
||||
for(int pass = 0; pass < 2; pass++)
|
||||
for(const auto& f : ~CodeIndex())
|
||||
for(const AnnotationItem& m : f.value.items) {
|
||||
int q = visited.Find(m.id);
|
||||
if(q >= 0) { // replace definition (.cpp) with declaration (.h)
|
||||
AnnotationItem& n = nitem[q];
|
||||
if(n.definition && !m.definition) { // file: make it stable
|
||||
(AnnotationItem&)n = m;
|
||||
}
|
||||
}
|
||||
else
|
||||
if((pass == 0 ? m.name.StartsWith(search_name) : m.uname.Find(usearch_name) >= 0) &&
|
||||
(pass == 0 ? m.nest.Find(search_nest) >= 0 : m.unest.Find(usearch_nest) >= 0)) {
|
||||
visited.Add(m.id);
|
||||
NavItem& n = nitem.Add();
|
||||
(AnnotationItem&)n = m;
|
||||
nests.FindAdd(n.nest);
|
||||
}
|
||||
}
|
||||
|
||||
SortIndex(nests);
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
String s = ToUpper(TrimBoth(~search));
|
||||
for(int i = 0; i < wspc.GetCount(); i++) {
|
||||
const Package& p = wspc.GetPackage(i);
|
||||
for(int j = 0; j < p.GetCount(); j++) {
|
||||
if(!p[j].separator && ToUpper(p[j]).Find(s) >= 0) {
|
||||
NavItem& m = nitem.Add();
|
||||
m.kind = KIND_SRCFILE;
|
||||
m.pretty = wspc[i] + "/" + p[j];
|
||||
m.id = SourcePath(wspc[i], p[j]);
|
||||
m.line = 0;
|
||||
nests.FindAdd("<files>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.Clear();
|
||||
scope.Add(Null);
|
||||
for(String n : nests)
|
||||
scope.Add(n);
|
||||
scope.ScrollTo(sc);
|
||||
if(!navigator_global || !scope.FindSetCursor(key))
|
||||
scope.GoBegin();
|
||||
}
|
||||
|
||||
int Navigator::ScopeDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
if(IsNull(q)) {
|
||||
const char *txt = "* ";
|
||||
int x = 0;
|
||||
w.DrawText(r.left, r.top, txt, StdFont().Bold().Italic(),
|
||||
style & CURSOR ? ink : HighlightSetup::GetHlStyle(HighlightSetup::INK_KEYWORD).color);
|
||||
x += GetTextSize(txt, StdFont().Bold().Italic()).cx;
|
||||
int ii = navigator->list.GetCursor();
|
||||
if(ii >= 0 && ii < navigator->litem.GetCount()) {
|
||||
const NavItem& m = *navigator->litem[ii];
|
||||
String txt = m.nest;
|
||||
if(IsCppCode(m.kind))
|
||||
txt << "::" << m.name;
|
||||
w.DrawText(r.left + x, r.top, txt, StdFont().Bold(), ink);
|
||||
x += GetTextSize(txt, StdFont().Bold()).cx;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
String h = q;
|
||||
if(*h == '\xff') // TODO
|
||||
return PaintFileName(w, r, h, ink);
|
||||
else
|
||||
h = FormatNest(h);
|
||||
w.DrawText(r.left, r.top, h, StdFont(), ink);
|
||||
return GetTextSize(h, StdFont()).cx;
|
||||
}
|
||||
|
||||
void Navigator::ScopeDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
DoPaint(w, r, q, ink, paper, style);
|
||||
}
|
||||
|
||||
Size Navigator::ScopeDisplay::GetStdSize(const Value& q) const
|
||||
{
|
||||
NilDraw w;
|
||||
return Size(DoPaint(w, Size(999999, 999999), q, White(), White(), 0), StdFont().Bold().GetCy());
|
||||
}
|
||||
|
||||
void Navigator::Scope()
|
||||
{
|
||||
LTIMING("FINALIZE");
|
||||
litem.Clear();
|
||||
nest_item.Clear();
|
||||
linefo.Clear();
|
||||
String sc = scope.GetKey();
|
||||
String nest;
|
||||
for(const NavItem& n : nitem) {
|
||||
if(IsNull(sc) || n.nest == sc) {
|
||||
if(!sorting && n.nest != nest) {
|
||||
NavItem& m = nest_item.Add();
|
||||
m.kind = KIND_NEST; // TODO: KIND_FILE
|
||||
nest = m.pretty = n.nest;
|
||||
litem.Add(&m);
|
||||
}
|
||||
litem.Add(&n);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO sorting
|
||||
|
||||
int lsc = list.GetScroll();
|
||||
list.Clear();
|
||||
list.SetVirtualCount(litem.GetCount());
|
||||
list.ScrollTo(lsc);
|
||||
}
|
||||
|
||||
void Navigator::ListLineEnabled(int i, bool& b)
|
||||
{
|
||||
if(i >= 0 && i < litem.GetCount()) {
|
||||
int kind = litem[i]->kind;
|
||||
if(findarg(kind, KIND_FILE, KIND_NEST) >= 0)
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Navigator::NaviSort()
|
||||
{
|
||||
sorting = !sorting;
|
||||
Search();
|
||||
}
|
||||
|
|
@ -62,7 +62,6 @@ void AutocompleteThread()
|
|||
f.includes != parsed_file.includes || f.defines != parsed_file.defines ||
|
||||
!clang.tu) {
|
||||
parsed_file = f;
|
||||
clang.Dispose();
|
||||
TIMESTOP("Autocomplete parse");
|
||||
autocomplete_parsing = true;
|
||||
clang.Parse(fn, f.content, f.includes, f.defines,
|
||||
|
|
@ -79,10 +78,10 @@ void AutocompleteThread()
|
|||
CXCodeCompleteResults *results;
|
||||
{
|
||||
TIMESTOP("clang_codeCompleteAt");
|
||||
autocomplete_parsing = false;
|
||||
autocomplete_parsing = true;
|
||||
results = clang_codeCompleteAt(clang.tu, fn, autocomplete_pos.y, autocomplete_pos.x, &ufile, 1,
|
||||
macros ? CXCodeComplete_IncludeMacros : 0);
|
||||
autocomplete_parsing = true;
|
||||
autocomplete_parsing = false;
|
||||
}
|
||||
DumpDiagnostics(clang.tu);
|
||||
if(results) {
|
||||
|
|
|
|||
|
|
@ -9,20 +9,6 @@ int64 current_file_serial;
|
|||
int64 current_file_done_serial;
|
||||
Event<const Vector<AnnotationItem>&> annotations_done;
|
||||
|
||||
struct CurrentFileVisitor : ClangVisitor {
|
||||
Vector<AnnotationItem> item;
|
||||
virtual void Item() {
|
||||
AnnotationItem& r = item.Add();
|
||||
r.kind = GetKind();
|
||||
r.name = GetName();
|
||||
r.line = GetLine();
|
||||
r.id = GetId();
|
||||
r.pretty = GetPretty();
|
||||
r.definition = IsDefinition();
|
||||
r.nspace = GetNamespace();
|
||||
}
|
||||
};
|
||||
|
||||
void CurrentFileThread()
|
||||
{
|
||||
MemoryIgnoreLeaksBlock __;
|
||||
|
|
@ -34,7 +20,7 @@ void CurrentFileThread()
|
|||
|
||||
auto DoAnnotations = [&] {
|
||||
if(!clang.tu || !annotations_done) return;
|
||||
CurrentFileVisitor v;
|
||||
ClangVisitor v;
|
||||
v.Do(clang.tu);
|
||||
// DumpDiagnostics(clang.tu);
|
||||
Ctrl::Call([&] {
|
||||
|
|
@ -42,7 +28,7 @@ void CurrentFileThread()
|
|||
parsed_file.real_filename == current_file.real_filename &&
|
||||
parsed_file.includes == current_file.includes &&
|
||||
serial == current_file_serial)
|
||||
annotations_done(v.item);
|
||||
annotations_done(v.item[0]);
|
||||
current_file_done_serial = serial;
|
||||
});
|
||||
};
|
||||
|
|
@ -64,7 +50,6 @@ void CurrentFileThread()
|
|||
f.includes != parsed_file.includes || f.defines != parsed_file.defines ||
|
||||
!clang.tu) { // TODO: same is in autocomplete
|
||||
parsed_file = f;
|
||||
clang.Dispose();
|
||||
{
|
||||
TIMESTOP("CurrentFile parse");
|
||||
current_file_parsing = true;
|
||||
|
|
|
|||
169
uppsrc/ide/clang/Indexer.cpp
Normal file
169
uppsrc/ide/clang/Indexer.cpp
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#include "clang.h"
|
||||
|
||||
#define LTIMING(x)
|
||||
#define LTIMESTOP(x)
|
||||
#define LLOG(x)
|
||||
|
||||
struct BlitzMaker {
|
||||
Time time;
|
||||
String blitz;
|
||||
Vector<String> individual;
|
||||
|
||||
void Do(const String& pk_name, const Vector<Tuple<String, bool>>& file, Hdepend& hdepend);
|
||||
};
|
||||
|
||||
void BlitzFile(String& blitz, const String& sourceFile, Hdepend& hdepend, int index)
|
||||
{
|
||||
blitz << "\r\n"
|
||||
<< "#define BLITZ_INDEX__ F" << index << "\r\n"
|
||||
<< "#include \"" << sourceFile << "\"\r\n";
|
||||
const Vector<String>& d = hdepend.GetDefines(sourceFile);
|
||||
for(int i = 0; i < d.GetCount(); i++)
|
||||
blitz << "#ifdef " << d[i] << "\r\n"
|
||||
<< "#undef " << d[i] << "\r\n"
|
||||
<< "#endif\r\n";
|
||||
blitz << "#undef BLITZ_INDEX__\r\n";
|
||||
}
|
||||
|
||||
void BlitzMaker::Do(const String& pk_name, const Vector<Tuple<String, bool>>& file, Hdepend& hdepend)
|
||||
{
|
||||
blitz.Clear();
|
||||
individual.Clear();
|
||||
time = Null;
|
||||
int index = 1;
|
||||
for(const auto& m : file) {
|
||||
if(IsCSourceFile(m.a)) {
|
||||
Time filetime = hdepend.FileTime(m.a);
|
||||
time = max(Nvl(time, filetime), filetime);
|
||||
if(hdepend.BlitzApproved(m.a) && !m.b)
|
||||
BlitzFile(blitz, m.a, hdepend, index++);
|
||||
else
|
||||
individual.Add(m.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayMap<String, FileAnnotation>& WriteCodeIndex()
|
||||
{
|
||||
DTIMING("WriteCodeIndex");
|
||||
static ArrayMap<String, FileAnnotation> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
const ArrayMap<String, FileAnnotation>& CodeIndex()
|
||||
{
|
||||
return WriteCodeIndex();
|
||||
}
|
||||
|
||||
static std::atomic<int> indexer_pkgi;
|
||||
static std::atomic<int> running_indexers;
|
||||
static Index<String> visited_files;
|
||||
static Mutex visited_files_mutex;
|
||||
|
||||
bool IsIndexing()
|
||||
{
|
||||
return running_indexers;
|
||||
}
|
||||
|
||||
void Indexer(const String& includes, const String& defines)
|
||||
{
|
||||
static Hdepend hdepend; // shared between threads
|
||||
static Mutex hdepend_mutex;
|
||||
ONCELOCK {
|
||||
hdepend.NoConsole();
|
||||
};
|
||||
Clang clang;
|
||||
int tm0 = msecs();
|
||||
running_indexers++;
|
||||
for(;;) {
|
||||
BlitzMaker m;
|
||||
String pk_name;
|
||||
Vector<Tuple<String, bool>> pk_files;
|
||||
Index<String> pk_files_index;
|
||||
{
|
||||
GuiLock __;
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
int pkgi = indexer_pkgi++;
|
||||
if(pkgi >= wspc.GetCount())
|
||||
break;
|
||||
LTIMING("Indexer Fetch");
|
||||
pk_name = wspc[pkgi];
|
||||
const Package& pk = wspc.GetPackage(pkgi);
|
||||
for(int i = 0; i < pk.GetCount(); i++) {
|
||||
String path = SourcePath(pk_name, pk[i]);
|
||||
pk_files.Add({ path, pk[i].noblitz });
|
||||
pk_files_index.Add(path);
|
||||
}
|
||||
}
|
||||
{
|
||||
Mutex::Lock __(hdepend_mutex);
|
||||
m.Do(pk_name, pk_files, hdepend);
|
||||
}
|
||||
// TODO: Check time
|
||||
|
||||
auto ProcessResults = [&] {
|
||||
ClangVisitor v;
|
||||
Index<String> doing_files;
|
||||
v.WhenFile = [&](const String& path) {
|
||||
return pk_files_index.Find(path) >= 0;
|
||||
};
|
||||
{
|
||||
DTIMING("Visitor");
|
||||
v.Do(clang.tu);
|
||||
}
|
||||
|
||||
{
|
||||
GuiLock __;
|
||||
DTIMING("Process files");
|
||||
for(int i = 0; i < v.item.GetCount(); i++) {
|
||||
DTIMING("Process file");
|
||||
FileAnnotation& f = WriteCodeIndex().GetAdd(v.item.GetKey(i));
|
||||
f.defines = defines;
|
||||
f.includes = includes;
|
||||
DTIMING("Process file pick");
|
||||
f.items = pick(v.item[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LTIMESTOP("======= Indexing " + pk_name);
|
||||
for(const String& fn : m.individual) {
|
||||
LTIMESTOP("Indexing " + fn);
|
||||
clang.Parse(fn, Null, includes, defines,
|
||||
CXTranslationUnit_DetailedPreprocessingRecord|
|
||||
CXTranslationUnit_KeepGoing|
|
||||
PARSE_FILE);
|
||||
if(clang.tu)
|
||||
ProcessResults();
|
||||
if(Thread::IsShutdownThreads())
|
||||
break;
|
||||
}
|
||||
if(Thread::IsShutdownThreads())
|
||||
break;
|
||||
LTIMESTOP("Indexing BLITZ " + pk_name);
|
||||
clang.Parse(ConfigFile(pk_name + "$$$blitz.cpp"), m.blitz, includes, defines,
|
||||
CXTranslationUnit_DetailedPreprocessingRecord|
|
||||
CXTranslationUnit_KeepGoing);
|
||||
if(clang.tu)
|
||||
ProcessResults();
|
||||
|
||||
if(Thread::IsShutdownThreads())
|
||||
break;
|
||||
}
|
||||
if(--running_indexers == 0)
|
||||
LLOG("Done everything " << (msecs() - tm0) / 1000.0 << " s");
|
||||
LLOG("Done");
|
||||
}
|
||||
|
||||
void StartIndexing(const String& includes, const String& defines)
|
||||
{
|
||||
{
|
||||
Mutex::Lock __(visited_files_mutex);
|
||||
visited_files.Clear();
|
||||
}
|
||||
indexer_pkgi = 0;
|
||||
if(!IsIndexing()) {
|
||||
for(int i = 0; i < CPU_Cores(); i++) // TODO: CPU_Cores?
|
||||
Thread::StartNice([=] { Indexer(includes, defines); });
|
||||
}
|
||||
}
|
||||
|
|
@ -177,7 +177,7 @@ String CleanupPretty(const String& signature)
|
|||
return r;
|
||||
}
|
||||
|
||||
Vector<ItemTextPart> ParseSignature(const String& name, const String& signature, int *fn_info)
|
||||
Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, int *fn_info)
|
||||
{
|
||||
Vector<ItemTextPart> part;
|
||||
int name_len = name.GetLength();
|
||||
|
|
@ -233,15 +233,13 @@ Vector<ItemTextPart> ParseSignature(const String& name, const String& signature,
|
|||
p.type = ITEM_CPP_TYPE;
|
||||
}
|
||||
else
|
||||
if(IsCppType(id)) {
|
||||
p.type = ITEM_CPP_TYPE;
|
||||
if(lastidi >= 0 && par == 0)
|
||||
was_type = true;
|
||||
if(IsCppKeyword(id)) {
|
||||
if(id == "virtual")
|
||||
part.Drop();
|
||||
else
|
||||
p.type = ITEM_CPP;
|
||||
}
|
||||
else
|
||||
if(IsCppKeyword(id))
|
||||
p.type = ITEM_CPP;
|
||||
else
|
||||
if(param) {
|
||||
if(lastidi >= 0 && par == 0)
|
||||
was_type = true;
|
||||
|
|
@ -301,10 +299,10 @@ Vector<ItemTextPart> ParseSignature(const String& name, const String& signature,
|
|||
|
||||
Image CxxIcon(int kind);
|
||||
|
||||
String SignatureQtf(const String& name, const String& signature, int pari)
|
||||
String SignatureQtf(const String& name, const String& pretty, int pari)
|
||||
{
|
||||
String qtf = "[%00-00K ";
|
||||
Vector<ItemTextPart> n = ParseSignature(name, signature);
|
||||
Vector<ItemTextPart> n = ParsePretty(name, pretty);
|
||||
for(int i = 0; i < n.GetCount(); i++) {
|
||||
ItemTextPart& p = n[i];
|
||||
qtf << "[";
|
||||
|
|
@ -331,7 +329,7 @@ String SignatureQtf(const String& name, const String& signature, int pari)
|
|||
break;
|
||||
}
|
||||
qtf << ' ';
|
||||
qtf << '\1' << signature.Mid(p.pos, p.len) << '\1';
|
||||
qtf << '\1' << pretty.Mid(p.pos, p.len) << '\1';
|
||||
qtf << ']';
|
||||
}
|
||||
return qtf + "]";
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
// #define DUMPTREE
|
||||
|
||||
bool ClangVisitor::ProcessNode(CXCursor c)
|
||||
bool ClangVisitor::ProcessNode(CXCursor cursor)
|
||||
{
|
||||
cursor = c;
|
||||
CXSourceLocation cxlocation = clang_getCursorLocation(cursor);
|
||||
|
||||
CXCursorKind cursorKind = clang_getCursorKind(cursor);
|
||||
|
|
@ -16,23 +15,40 @@ bool ClangVisitor::ProcessNode(CXCursor c)
|
|||
DDUMP(SourceLocation(cxlocation));
|
||||
#endif
|
||||
|
||||
if(!clang_Location_isFromMainFile(cxlocation))
|
||||
bool position_loaded = false;
|
||||
unsigned line;
|
||||
unsigned column;
|
||||
unsigned offset;
|
||||
String path;
|
||||
|
||||
auto LoadPosition = [&] {
|
||||
if(position_loaded) return;
|
||||
CXFile file;
|
||||
clang_getExpansionLocation(cxlocation, &file, &line, &column, &offset);
|
||||
path = FetchString(clang_getFileName(file));
|
||||
position_loaded = true;
|
||||
};
|
||||
|
||||
if(WhenFile)
|
||||
LoadPosition();
|
||||
if(!(WhenFile ? WhenFile(path) : clang_Location_isFromMainFile(cxlocation))) {
|
||||
return findarg(cursorKind, CXCursor_StructDecl, CXCursor_UnionDecl, CXCursor_ClassDecl,
|
||||
CXCursor_FunctionTemplate, CXCursor_FunctionDecl, CXCursor_Constructor,
|
||||
CXCursor_Destructor, CXCursor_CXXMethod, CXCursor_ClassTemplate,
|
||||
CXCursor_ClassTemplatePartialSpecialization, CXCursor_UnexposedDecl,
|
||||
CXCursor_UsingDeclaration, CXCursor_VarDecl, CXCursor_EnumConstantDecl,
|
||||
CXCursor_TypeAliasTemplateDecl, CXCursor_EnumDecl, CXCursor_ConversionFunction) < 0;
|
||||
}
|
||||
|
||||
String m;
|
||||
|
||||
CXCursor parent = clang_getCursorSemanticParent(cursor);
|
||||
CXCursorKind parentKind = clang_getCursorKind(parent);
|
||||
|
||||
name = GetCursorSpelling(cursor);
|
||||
type = GetTypeSpelling(cursor);
|
||||
String name = GetCursorSpelling(cursor);
|
||||
String type = GetTypeSpelling(cursor);
|
||||
String pid = FetchString(clang_getCursorPrettyPrinted(cursor, pp_id));
|
||||
|
||||
|
||||
#ifdef DUMPTREE
|
||||
_DBG_
|
||||
CXCursor ref = clang_getCursorReferenced(cursor);
|
||||
|
|
@ -49,16 +65,18 @@ bool ClangVisitor::ProcessNode(CXCursor c)
|
|||
#endif
|
||||
|
||||
CXCursor p = parent;
|
||||
scope.Clear();
|
||||
nspace.Clear();
|
||||
String scope;
|
||||
String nspace;
|
||||
for(;;) {
|
||||
CXCursorKind k = clang_getCursorKind(p);
|
||||
if(findarg(k, CXCursor_Namespace, CXCursor_ClassTemplate, CXCursor_StructDecl, CXCursor_UnionDecl, CXCursor_ClassDecl) < 0)
|
||||
break;
|
||||
String q = GetCursorSpelling(p);
|
||||
scope = scope.GetCount() ? q + "::" + scope : q;
|
||||
if(k == CXCursor_Namespace)
|
||||
nspace = nspace.GetCount() ? q + "::" + nspace : q;
|
||||
if(k != CXCursor_EnumDecl) {
|
||||
if(findarg(k, CXCursor_Namespace, CXCursor_ClassTemplate, CXCursor_StructDecl, CXCursor_UnionDecl, CXCursor_ClassDecl) < 0)
|
||||
break;
|
||||
String q = GetCursorSpelling(p);
|
||||
scope = scope.GetCount() ? q + "::" + scope : q;
|
||||
if(k == CXCursor_Namespace)
|
||||
nspace = nspace.GetCount() ? q + "::" + nspace : q;
|
||||
}
|
||||
p = clang_getCursorSemanticParent(p);
|
||||
}
|
||||
int q = scope.Find('('); // 'Struct::(unnamed enum at C:\u\upp.src\upptst\Annotations\main.cpp:47:2)'
|
||||
|
|
@ -67,7 +85,7 @@ bool ClangVisitor::ProcessNode(CXCursor c)
|
|||
if(scope.GetCount() && *scope.Last() != ':')
|
||||
scope << "::";
|
||||
|
||||
annotation = true;
|
||||
bool annotation = true;
|
||||
if(findarg(parentKind, CXCursor_FunctionTemplate, CXCursor_FunctionDecl, CXCursor_CXXMethod,
|
||||
CXCursor_Constructor, CXCursor_Destructor) >= 0)
|
||||
annotation = false; // local variable
|
||||
|
|
@ -76,6 +94,8 @@ bool ClangVisitor::ProcessNode(CXCursor c)
|
|||
case CXCursor_StructDecl:
|
||||
case CXCursor_UnionDecl:
|
||||
case CXCursor_ClassDecl:
|
||||
m = type;
|
||||
break;
|
||||
case CXCursor_FunctionTemplate:
|
||||
case CXCursor_FunctionDecl:
|
||||
case CXCursor_Constructor:
|
||||
|
|
@ -109,17 +129,22 @@ bool ClangVisitor::ProcessNode(CXCursor c)
|
|||
break;
|
||||
}
|
||||
if(annotation && m.GetCount()) {
|
||||
CXFile file;
|
||||
unsigned line_;
|
||||
unsigned column_;
|
||||
unsigned offset_;
|
||||
clang_getExpansionLocation(cxlocation, &file, &line_, &column_, &offset_);
|
||||
line = line_;
|
||||
column = column_;
|
||||
kind = cursorKind;
|
||||
pretty = CleanupPretty(FetchString(clang_getCursorPrettyPrinted(cursor, pp_pretty)));
|
||||
id = CleanupId(m);
|
||||
Item();
|
||||
LoadPosition();
|
||||
AnnotationItem& r = item.GetAdd(path).Add();
|
||||
r.kind = cursorKind;
|
||||
r.name = name;
|
||||
r.line = line;
|
||||
r.id = CleanupId(m);
|
||||
r.pretty = CleanupPretty(FetchString(clang_getCursorPrettyPrinted(cursor, pp_pretty)));
|
||||
r.definition = clang_isCursorDefinition(cursor);
|
||||
r.nspace = nspace;
|
||||
int q = FindId(r.id, r.name);
|
||||
if(q >= 0) {
|
||||
r.nest = r.id.Mid(0, q);
|
||||
r.nest.TrimEnd("::");
|
||||
}
|
||||
r.uname = ToUpper(name);
|
||||
r.unest = ToUpper(r.nest);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
1
uppsrc/ide/clang/blitz.cpp
Normal file
1
uppsrc/ide/clang/blitz.cpp
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include "clang.h"
|
||||
|
|
@ -77,6 +77,8 @@ void Clang::Dispose()
|
|||
bool Clang::Parse(const String& filename, const String& content, const String& includes_, const String& defines, dword options)
|
||||
{
|
||||
if(!index) return false;
|
||||
|
||||
Dispose();
|
||||
|
||||
String cmdline;
|
||||
|
||||
|
|
@ -99,10 +101,12 @@ bool Clang::Parse(const String& filename, const String& content, const String& i
|
|||
|
||||
for(const String& s : args)
|
||||
argv.Add(~s);
|
||||
|
||||
CXUnsavedFile ufile = { ~filename, ~content, (unsigned)content.GetCount() };
|
||||
|
||||
tu = clang_parseTranslationUnit(index, nullptr, argv, argv.GetCount(), &ufile, 1, options);
|
||||
CXUnsavedFile ufile = { ~filename, ~content, (unsigned)content.GetCount() };
|
||||
tu = clang_parseTranslationUnit(index, nullptr, argv, argv.GetCount(),
|
||||
options & PARSE_FILE ? nullptr : &ufile,
|
||||
options & PARSE_FILE ? 0 : 1,
|
||||
options);
|
||||
|
||||
// DumpDiagnostics(tu);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ enum AdditionalKinds {
|
|||
KIND_COMPLETE,
|
||||
};
|
||||
|
||||
Image CxxIcon(int kind); // TODO: Move here
|
||||
String SignatureQtf(const String& name, const String& signature, int pari);
|
||||
Image CxxIcon(int kind); // TODO: Move here
|
||||
int PaintCpp(Draw& w, const Rect& r, int kind, const String& name, const String& pretty, Color ink, bool focuscursor, bool retval_last = false);
|
||||
String SignatureQtf(const String& name, const String& pretty, int pari);
|
||||
|
||||
bool IsStruct(int kind);
|
||||
bool IsTemplate(int kind);
|
||||
|
|
@ -64,12 +65,12 @@ struct ItemTextPart : Moveable<ItemTextPart> {
|
|||
int pari;
|
||||
};
|
||||
|
||||
Vector<ItemTextPart> ParseSignature(const String& name, const String& signature, int *fn_info = NULL);
|
||||
Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, int *fn_info = NULL);
|
||||
|
||||
struct AutoCompleteItem : Moveable<AutoCompleteItem> {
|
||||
String parent;
|
||||
String name;
|
||||
String signature;
|
||||
String signature; // TODO: rename to pretty
|
||||
int kind;
|
||||
int priority;
|
||||
};
|
||||
|
|
@ -78,10 +79,15 @@ struct AnnotationItem : Moveable<AnnotationItem> {
|
|||
int kind;
|
||||
int line;
|
||||
bool definition;
|
||||
String name;
|
||||
String id;
|
||||
String pretty;
|
||||
String nspace;
|
||||
String name; // Method
|
||||
String id; // Upp::Class::Method(Upp::Point p)
|
||||
String pretty; // void Class::Method(Point p)
|
||||
String nspace; // Upp
|
||||
String uname; // METHOD
|
||||
String nest; // Upp::Class
|
||||
String unest; // UPP::CLASS
|
||||
|
||||
~AnnotationItem() { DHITCOUNT("AnnotationItem"); }
|
||||
};
|
||||
|
||||
struct CurrentFileContext {
|
||||
|
|
@ -92,6 +98,8 @@ struct CurrentFileContext {
|
|||
String content;
|
||||
};
|
||||
|
||||
enum { PARSE_FILE = 0x80000000 };
|
||||
|
||||
struct Clang {
|
||||
CXIndex index = nullptr;
|
||||
CXTranslationUnit tu = nullptr;
|
||||
|
|
@ -121,36 +129,14 @@ class ClangVisitor {
|
|||
bool initialized = false;
|
||||
CXPrintingPolicy pp_id, pp_pretty;
|
||||
|
||||
CXCursor cursor;
|
||||
int kind;
|
||||
String name;
|
||||
String id;
|
||||
String type;
|
||||
String scope;
|
||||
String nspace;
|
||||
String pretty;
|
||||
bool annotation;
|
||||
int line;
|
||||
int column;
|
||||
|
||||
bool ProcessNode(CXCursor c);
|
||||
|
||||
friend CXChildVisitResult clang_visitor(CXCursor cursor, CXCursor p, CXClientData clientData);
|
||||
|
||||
public:
|
||||
virtual void Item() = 0;
|
||||
|
||||
int GetKind() const { return kind; }
|
||||
String GetId() const { return id; }
|
||||
String GetName() const { return name; }
|
||||
String GetType() const { return type; }
|
||||
String GetScope() const { return scope; }
|
||||
String GetNamespace() const { return nspace; }
|
||||
String GetPretty() const { return pretty; }
|
||||
bool IsDefinition() const { return clang_isCursorDefinition(cursor); }
|
||||
bool IsAnnotation() const { return annotation; }
|
||||
int GetLine() const { return line; }
|
||||
int GetColumn() const { return column; }
|
||||
VectorMap<String, Vector<AnnotationItem>> item;
|
||||
|
||||
Gate<const String&> WhenFile;
|
||||
|
||||
void Do(CXTranslationUnit tu);
|
||||
~ClangVisitor();
|
||||
|
|
@ -167,4 +153,18 @@ void StartAutoComplete(const CurrentFileContext& ctx, int line, int column, bool
|
|||
Event<const Vector<AutoCompleteItem>&> done);
|
||||
void CancelAutoComplete();
|
||||
|
||||
|
||||
struct FileAnnotation {
|
||||
String defines;
|
||||
String includes;
|
||||
Time time;
|
||||
|
||||
Vector<AnnotationItem> items;
|
||||
};
|
||||
|
||||
bool IsIndexing();
|
||||
void StartIndexing(const String& includes, const String& defines);
|
||||
|
||||
const ArrayMap<String, FileAnnotation>& CodeIndex();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ file
|
|||
clang.h,
|
||||
todo.txt,
|
||||
help.txt,
|
||||
blitz.cpp,
|
||||
util.cpp,
|
||||
macros.cpp,
|
||||
CxxIcon.cpp,
|
||||
|
|
@ -19,5 +20,6 @@ file
|
|||
Codebase.cpp,
|
||||
Visitor.cpp,
|
||||
AutoComplete.cpp,
|
||||
CurrentFile.cpp;
|
||||
CurrentFile.cpp,
|
||||
Indexer.cpp;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,10 @@
|
|||
|
||||
- failed AC keeps running (sites[i]. instead of ->)
|
||||
|
||||
- writing to text is slow (IsSource detection?)
|
||||
|
||||
- background thread problem
|
||||
|
||||
- MSVC
|
||||
|
||||
- Enum annotations
|
||||
|
||||
- optimise loading
|
||||
|
||||
- TPP HELP WINDOW->EDITOR - go to active label
|
||||
|
|
@ -36,6 +32,61 @@
|
|||
|
||||
- this is just a test
|
||||
|
||||
- OpenWind.h autocomplete
|
||||
|
||||
- server_methods.i
|
||||
|
||||
- fixups?
|
||||
|
||||
- enum annotation popup (Ctrl::)
|
||||
|
||||
- .txt is pulsing all time
|
||||
|
||||
- Remove template < > in autocomplete
|
||||
|
||||
- newly created file looks like parsing until first function(?)
|
||||
|
||||
- current file indexing
|
||||
|
||||
- check editor mode
|
||||
|
||||
- navlines
|
||||
|
||||
- navigator - GotoDesignerFile
|
||||
|
||||
- i < items crash at start occassionally
|
||||
|
||||
- * nest in navigator local file
|
||||
|
||||
- remove $blitz items
|
||||
|
||||
- constructor/destructor name is not bold (check destructor in navigator display)
|
||||
|
||||
- PaintCpp ending spaces in navigator
|
||||
|
||||
- Error output: (): x += GetTextSize(" Ôćĺ ", StdFont());
|
||||
|
||||
- x += GetTextSize(" Ôćĺ ", StdFont()) - autocomplete fails on UTF8
|
||||
|
||||
LATER:
|
||||
|
||||
- slow .txt
|
||||
|
||||
- optimise hdepend (then maybe remove .h limitation for syncheaders)
|
||||
|
||||
|
||||
|
||||
|
||||
DONE:
|
||||
|
||||
- Upp:: missing from Vector
|
||||
|
||||
- class Ctrl
|
||||
|
||||
- class Logc
|
||||
|
||||
- writing to text is slow (IsSource detection?)
|
||||
|
||||
- .txt keeps syncing
|
||||
|
||||
- Enum annotations
|
||||
|
||||
|
|
|
|||
|
|
@ -361,7 +361,6 @@ void Ide::DeactivateBy(Ctrl *new_focus)
|
|||
DeactivationSave(true);
|
||||
SaveFile();
|
||||
DeactivationSave(false);
|
||||
editor.SyncHeaders();
|
||||
}
|
||||
TopWindow::DeactivateBy(new_focus);
|
||||
}
|
||||
|
|
@ -657,32 +656,19 @@ void Ide::SyncClang()
|
|||
auto Animate = [=](int& animator, int& dir, bool animate) -> Color {
|
||||
if(animator <= 0 && !animate) return Null;
|
||||
if(animate)
|
||||
dir = clamp(dir, -1, 1);
|
||||
animator = 20;
|
||||
else
|
||||
dir = -3;
|
||||
if(animator >= 15)
|
||||
dir = -1;
|
||||
if(animator <= 0)
|
||||
dir = 1;
|
||||
if(phase != animate_phase)
|
||||
animator = max(animator + dir, 0);
|
||||
Color bg;
|
||||
if(IsDarkTheme())
|
||||
bg = GrayColor(70 + animator);
|
||||
else {
|
||||
bg = SColorLtFace();
|
||||
auto C = [&](int c) { return clamp(c - animator, 0, 255); };
|
||||
bg = Color(C(bg.GetR()), C(bg.GetG()), C(bg.GetG()));
|
||||
}
|
||||
return bg;
|
||||
animator -= 3;
|
||||
return Blend(IsDarkTheme() ? GrayColor(70) : SColorLtFace(), Color(198, 170, 0), animator);
|
||||
};
|
||||
Color bg = Animate(animate_current_file, animate_current_file_dir, IsCurrentFileParsing());
|
||||
Color bg = Animate(animate_current_file, animate_current_file_dir, editor.annotating || IsCurrentFileParsing());
|
||||
if(!IsNull(bg)) {
|
||||
int cx = editor.GetBarSize().cx;
|
||||
for(int i = 0; i < cx; i++)
|
||||
a.Add(bg);
|
||||
a.Add(i > cx - DPI(6) ? bg : Null);
|
||||
}
|
||||
editor.AnimateBar(pick(a));
|
||||
editor.search.SetColor(Animate(animate_indexer, animate_indexer_dir, IsIndexing()));
|
||||
display.Animate(Animate(animate_autocomplete, animate_autocomplete_dir, IsAutocompleteParsing()));
|
||||
animate_phase = phase;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -724,6 +724,7 @@ public:
|
|||
|
||||
int animate_current_file = 0, animate_current_file_dir = 0;
|
||||
int animate_autocomplete = 0, animate_autocomplete_dir = 0;
|
||||
int animate_indexer = 0, animate_indexer_dir = 0;
|
||||
int animate_phase = 0;
|
||||
|
||||
// ------------------------------------
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ file
|
|||
GoToLine.cpp,
|
||||
Swaps.cpp,
|
||||
ParamInfo.cpp,
|
||||
Navigator2.cpp,
|
||||
Navigator.cpp,
|
||||
Annotations.cpp,
|
||||
Virtuals.cpp,
|
||||
|
|
|
|||
|
|
@ -303,7 +303,6 @@ void Ide::SaveFile(bool always)
|
|||
{
|
||||
issaving++;
|
||||
SaveFile0(always);
|
||||
editor.SyncHeaders();
|
||||
issaving--;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -333,8 +333,10 @@ void AppMain___()
|
|||
ide.SaveLastMain();
|
||||
ide.isscanning++;
|
||||
ide.MakeTitle();
|
||||
if(!ide.IsEditorMode())
|
||||
if(!ide.IsEditorMode()) {
|
||||
SyncRefs();
|
||||
StartIndexing(ide.GetCurrentIncludePath(), ide.GetCurrentDefines());
|
||||
}
|
||||
ide.FileSelected();
|
||||
ide.isscanning--;
|
||||
ide.MakeTitle();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue