From f5efa06a416dfc3016aad4ded4ea4ba9aa7e39ca Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 25 Apr 2011 15:15:56 +0000 Subject: [PATCH] theide: Assist for #include git-svn-id: svn://ultimatepp.org/upp/trunk@3370 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Color.h | 5 +- uppsrc/Core/src.tpp/Color$en-us.tpp | 4 + uppsrc/ide/Assist.cpp | 258 ++++++++++++++++++++-------- uppsrc/ide/Browser/Browser.h | 7 + uppsrc/ide/Browser/ItemDisplay.cpp | 9 + uppsrc/ide/ide.h | 8 +- 6 files changed, 221 insertions(+), 70 deletions(-) diff --git a/uppsrc/Core/Color.h b/uppsrc/Core/Color.h index 7e6dddbbe..c9e10517f 100644 --- a/uppsrc/Core/Color.h +++ b/uppsrc/Core/Color.h @@ -38,6 +38,7 @@ public: int GetG() const { return GetGValue(Get()); } int GetB() const { return GetBValue(Get()); } + void SetNull() { color = 0xffffffff; } bool IsNullInstance() const { return color == 0xffffffff; } unsigned GetHashValue() const { return color; } bool operator==(Color c) const { return color == c.color; } @@ -45,11 +46,11 @@ public: void Serialize(Stream& s) { s % color; } - Color() { color = 0xffffffff; } + Color() { SetNull(); } Color(int r, int g, int b) { color = RGB(r, g, b); } Color(int n, int) { color = 0x80000000 | n; } - Color(const Nuller&) { color = 0xffffffff; } + Color(const Nuller&) { SetNull(); } operator Value() const { return RichValue(*this); } Color(const Value& q) { color = RichValue::Extract(q).color; } diff --git a/uppsrc/Core/src.tpp/Color$en-us.tpp b/uppsrc/Core/src.tpp/Color$en-us.tpp index a8623c8df..c6944f501 100644 --- a/uppsrc/Core/src.tpp/Color$en-us.tpp +++ b/uppsrc/Core/src.tpp/Color$en-us.tpp @@ -88,6 +88,10 @@ RGB code.&] [s7; [*/ Return value]-|The blue component.&] [s3; &] [s4;%- &] +[s5;:Color`:`:SetNull`(`):%- [@(0.0.255) void]_[* SetNull]()&] +[s2; Sets the Color to Null.&] +[s3;%- &] +[s4;%- &] [s5;:Color`:`:IsNullInstance`(`)const:%- [@(0.0.255) bool]_[* IsNullInstance]()_[@(0.0.255) c onst]&] [s7; [*/ Return value]-|True if Color is Null. Used to implement IsNull diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index 18d912a62..5f1746f0e 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -82,6 +82,8 @@ AssistEditor::AssistEditor() param_info.SetFrame(BlackFrame()); param_info.BackPaint(); param_info.NoSb(); + + include_assist = false; } int CppItemInfoOrder(const Value& va, const Value& vb) { @@ -100,12 +102,19 @@ void AssistEditor::CloseAssist() CloseTip(); } -String AssistEditor::ReadIdBack(int q) +bool isincludefnchar(int c) +{ + return c && c != '<' && c != '>' && c != '?' && + c != ' ' && c != '\"' && c != '/' && c != '\\' && c != '\n'; +} + +String AssistEditor::ReadIdBack(int q, bool include) { String id; - while(q > 0 && iscid(GetChar(q - 1))) + bool (*test)(int c) = include ? isincludefnchar : iscid; + while(q > 0 && (*test)(GetChar(q - 1))) q--; - while(q < GetLength() && iscid(GetChar(q))) + while(q < GetLength() && (*test)(GetChar(q))) id << (char)GetChar(q++); return id; } @@ -296,7 +305,7 @@ int memcmp_i(const char *s, const char *t, int n) void AssistEditor::SyncAssist() { String name; - name = ReadIdBack(GetCursor()); + name = ReadIdBack(GetCursor(), include_assist); assist.Clear(); int typei = type.GetCursor() - 1; for(int p = 0; p < 2; p++) { @@ -316,7 +325,84 @@ void AssistEditor::SyncAssist() } } } - assist.Sort(0, CppItemInfoOrder); + if(!include_assist) + assist.Sort(0, CppItemInfoOrder); +} + +bool AssistEditor::IncludeAssist() +{ + Vector include; + String ln = GetUtf8Line(GetCursorLine()); + CParser p(ln); + if(!p.Char('#') || !p.Id("include")) + return false; + if(p.Char('\"')) { + include.Add(GetFileFolder(theide->editfile)); + include_local = true; + } + else { + p.Char('<'); + theide->SetupDefaultMethod(); + VectorMap bm = GetMethodVars(theide->method); + include = SplitDirs(GetVar("UPP") + ';' + bm.Get("INCLUDE", "")); + include_local = false; + } + include_path.Clear(); + for(;;) { + String dir; + while(isincludefnchar(p.PeekChar())) + dir.Cat(p.GetChar()); + if(dir.GetCount() && (p.Char('/') || p.Char('\\'))) { + if(include_path.GetCount()) + include_path << '/'; + include_path << dir; + } + else + break; + } + Vector folder, upper_folder, file, upper_file; + for(int i = 0; i < include.GetCount(); i++) { + FindFile ff(AppendFileName(AppendFileName(include[i], include_path), "*.*")); + while(ff) { + String fn = ff.GetName(); + if(!ff.IsHidden()) + if(ff.IsFolder()) { + folder.Add(fn); + upper_folder.Add(ToUpper(fn)); + } + else { + static Index ext(Split(".h;.hpp;.hh;.hxx;.i;.lay;.iml;.t;.dli", ';')); + if(ext.Find(ToLower(GetFileExt(fn))) >= 0) { + file.Add(fn); + upper_file.Add(ToUpper(fn)); + } + } + ff.Next(); + } + } + IndexSort(upper_folder, folder); + for(int i = 0; i < folder.GetCount(); i++) { + String fn = folder[i]; + CppItemInfo& f = assist_item.GetAdd(fn); + f.name = f.natural = fn; + f.access = 0; + f.kind = KIND_INCLUDEFOLDER; + } + IndexSort(upper_file, file); + for(int i = 0; i < file.GetCount(); i++) { + String fn = file[i]; + CppItemInfo& f = assist_item.GetAdd(fn); + f.name = f.natural = fn; + f.access = 0; + static Index hdr(Split(".h;.hpp;.hh;.hxx", ';')); + f.kind = hdr.Find(ToLower(GetFileExt(fn))) >= 0 ? KIND_INCLUDEFILE + : KIND_INCLUDEFILE_ANY; + } + include_assist = true; + if(include_path.GetCount()) + include_path << "/"; + PopUpAssist(); + return true; } void AssistEditor::Assist() @@ -324,12 +410,15 @@ void AssistEditor::Assist() if(!assist_active) return; CloseAssist(); - Parser parser; - Context(parser, GetCursor()); int q = GetCursor(); assist_cursor = q; assist_type.Clear(); assist_item.Clear(); + include_assist = false; + if(IncludeAssist()) + return; + Parser parser; + Context(parser, GetCursor()); Index in_types; while(iscid(Ch(q - 1))) q--; @@ -385,15 +474,20 @@ void AssistEditor::PopUpAssist(bool auto_insert) int lcy = max(16, BrowserFont().Info().GetHeight()); type.Clear(); type.Add(AttrText("").Ink(SColorHighlight())); - for(int i = 0; i < assist_type.GetCount(); i++) { - String s = assist_type[i]; - if(s[0] == ':' && s[1] == ':') - s = s.Mid(2); - s = Nvl(s, ""); - if(s[0] == '<') - type.Add(AttrText(s).Ink(SColorMark())); - else - type.Add(Nvl(s, "")); + if(assist_type.GetCount() == 0) + popup.Zoom(1); + else { + for(int i = 0; i < assist_type.GetCount(); i++) { + String s = assist_type[i]; + if(s[0] == ':' && s[1] == ':') + s = s.Mid(2); + s = Nvl(s, ""); + if(s[0] == '<') + type.Add(AttrText(s).Ink(SColorMark())); + else + type.Add(Nvl(s, "")); + } + popup.NoZoom(); } type.SetCursor(0); if(!assist.GetCount()) @@ -491,52 +585,72 @@ void AssistEditor::AssistInsert() { if(assist.IsCursor()) { const CppItemInfo& f = ValueTo(assist.Get(0)); - String txt = f.name; - int l = txt.GetCount(); - int pl = txt.GetCount(); - if(!thisback && f.kind >= FUNCTION && f.kind <= INLINEFRIEND) - txt << "()"; - int cl = GetCursor(); - int ch = cl; - while(iscid(Ch(cl - 1))) - cl--; - while(iscid(Ch(ch))) - ch++; - Remove(cl, ch - cl); - SetCursor(cl); - if(thisback) - for(;;) { - int c = Ch(cl++); - if(!c || Ch(cl) == ',' || Ch(cl) == ')') - break; - if(c != ' ') { - if(thisbackn) - txt << ", "; - txt << ')'; - break; - } + if(include_assist) { + int ln = GetLine(GetCursor()); + int pos = GetPos(ln); + Remove(pos, GetLineLength(ln)); + SetCursor(pos); + Paste(ToUnicode(String().Cat() << "#include " + << (include_local ? "\"" : "<") + << include_path + << f.name + << (f.kind == KIND_INCLUDEFOLDER ? "/" : + include_local ? "\"" : ">") + , CHARSET_WIN1250)); + if(f.kind == KIND_INCLUDEFOLDER) { + Assist(); + IgnoreMouseUp(); + return; } - int n = Paste(ToUnicode(txt, CHARSET_WIN1250)); - if(!thisback && f.kind >= FUNCTION && f.kind <= INLINEFRIEND) { - SetCursor(GetCursor() - 1); - StartParamInfo(f, cl); - int x = f.natural.ReverseFind('('); - if(x >= 0 && f.natural[x + 1] == ')') - SetCursor(GetCursor() + 1); } - else - if(thisback) { - if(thisbackn) + else { + String txt = f.name; + int l = txt.GetCount(); + int pl = txt.GetCount(); + if(!thisback && f.kind >= FUNCTION && f.kind <= INLINEFRIEND) + txt << "()"; + int cl = GetCursor(); + int ch = cl; + while(iscid(Ch(cl - 1))) + cl--; + while(iscid(Ch(ch))) + ch++; + Remove(cl, ch - cl); + SetCursor(cl); + if(thisback) + for(;;) { + int c = Ch(cl++); + if(!c || Ch(cl) == ',' || Ch(cl) == ')') + break; + if(c != ' ') { + if(thisbackn) + txt << ", "; + txt << ')'; + break; + } + } + int n = Paste(ToUnicode(txt, CHARSET_WIN1250)); + if(!thisback && f.kind >= FUNCTION && f.kind <= INLINEFRIEND) { SetCursor(GetCursor() - 1); + StartParamInfo(f, cl); + int x = f.natural.ReverseFind('('); + if(x >= 0 && f.natural[x + 1] == ')') + SetCursor(GetCursor() + 1); + } + else + if(thisback) { + if(thisbackn) + SetCursor(GetCursor() - 1); + } + else + if(!inbody) + SetCursor(cl + n - thisbackn); + else + if(pl > l) + SetSelection(cl + l, cl + pl); + else + SetCursor(cl + l); } - else - if(!inbody) - SetCursor(cl + n - thisbackn); - else - if(pl > l) - SetSelection(cl + l, cl + pl); - else - SetCursor(cl + l); } CloseAssist(); IgnoreMouseUp(); @@ -615,16 +729,26 @@ bool AssistEditor::Key(dword key, int count) SyncAssist(); } else - if(auto_assist && InCode()) { - if(key == '.' || key == '>' && Ch(GetCursor() - 2) == '-' || - key == ':' && Ch(GetCursor() - 2) == ':') - Assist(); - else - if(key == '(') { - int q = GetCursor() - 1; - String id = IdBack(q); - if(id == "THISBACK" || id == "THISBACK1" || id == "THISBACK2" || id == "THISBACK3" || id == "THISBACK4") + if(auto_assist) { + if(InCode()) { + if(key == '.' || key == '>' && Ch(GetCursor() - 2) == '-' || + key == ':' && Ch(GetCursor() - 2) == ':') Assist(); + else + if(key == '(') { + int q = GetCursor() - 1; + String id = IdBack(q); + if(id == "THISBACK" || id == "THISBACK1" || id == "THISBACK2" || id == "THISBACK3" || id == "THISBACK4") + Assist(); + } + } + if(key == '\"' || key == '<') { + int q = GetCursor() - 2; + if(q > 0) { + String id = IdBack(q); + if(id == "include" && Ch(q - 1) == '#') + Assist(); + } } } return b; diff --git a/uppsrc/ide/Browser/Browser.h b/uppsrc/ide/Browser/Browser.h index 4492ebec8..df124db0c 100644 --- a/uppsrc/ide/Browser/Browser.h +++ b/uppsrc/ide/Browser/Browser.h @@ -71,6 +71,7 @@ enum { ITEM_SIGN, ITEM_UPP, ITEM_TYPE, + ITEM_PTYPE = ITEM_TYPE + 10000, }; @@ -98,6 +99,12 @@ ArrayMap& FileSet(); int GetItemHeight(const CppItem& m, int cx); +enum AdditionalKinds { + KIND_INCLUDEFILE = 100, + KIND_INCLUDEFILE_ANY, + KIND_INCLUDEFOLDER, +}; + struct CppItemInfoDisplay : public Display { bool namestart; diff --git a/uppsrc/ide/Browser/ItemDisplay.cpp b/uppsrc/ide/Browser/ItemDisplay.cpp index a06f1f627..8dcd18a99 100644 --- a/uppsrc/ide/Browser/ItemDisplay.cpp +++ b/uppsrc/ide/Browser/ItemDisplay.cpp @@ -111,6 +111,15 @@ int CppItemInfoDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, case FRIENDCLASS: img = BrowserImg::friend_class(); break; + case KIND_INCLUDEFILE: + img = IdeCommonImg::Header(); + break; + case KIND_INCLUDEFILE_ANY: + img = CtrlImg::File(); + break; + case KIND_INCLUDEFOLDER: + img = CtrlImg::Dir(); + break; } int by = ry - bk.GetSize().cy / 2; diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index 03c1738de..3c9bd054a 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -292,6 +292,8 @@ String Qualify(const String& scope, const String& type); int CharFilterMacro(int c); int CharFilterFileName(int c); +bool isincludefnchar(int c); + struct AssistEditor : CodeEditor { virtual bool Key(dword key, int count); virtual void LostFocus(); @@ -328,10 +330,13 @@ struct AssistEditor : CodeEditor { bool commentdp; bool inbody; bool thisback, thisbackn; + bool include_assist; Ide *theide; WString cachedline; int cachedpos; int cachedln; + bool include_local; + String include_path; RichTextCtrl param_info; String param_qtf; @@ -351,7 +356,8 @@ struct AssistEditor : CodeEditor { void PopUpAssist(bool auto_insert = false); void CloseAssist(); void Assist(); - String ReadIdBack(int q); + bool IncludeAssist(); + String ReadIdBack(int q, bool include = false); void SyncAssist(); void AssistInsert(); bool InCode();