Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CodeCompletion::OnKeyDown));
Key events are not generated inside a plugin, so it is necessary to Connect() to the editor with something like:
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
if (ed)
ed->GetControl()->Connect(wxEVT_KEY_DOWN, (wxObjectEventFunction)&CodeCompletion::OnKeyDown, NULL, this);
...
void CodeCompletion::OnKeyDown(wxKeyEvent& event)
{
}
Also, take a look at:
void CodeCompletion::EditorEventHook(cbEditor* editor, wxScintillaEvent& event)
1. create new event type i.e wxEVT_SCI_AUTOCOMP_MOVED in wxscintilla.cpp, there are already few events between C::B begin and C::B end
I see in sdk\wxscintilla\src\wxscintilla.cpp
BEGIN_EVENT_TABLE(wxScintilla, wxControl)
EVT_PAINT (wxScintilla::OnPaint)
EVT_SCROLLWIN (wxScintilla::OnScrollWin)
EVT_SCROLL (wxScintilla::OnScroll)
EVT_SIZE (wxScintilla::OnSize)
EVT_LEFT_DOWN (wxScintilla::OnMouseLeftDown)
// Let Scintilla see the double click as a second click
EVT_LEFT_DCLICK (wxScintilla::OnMouseLeftDown)
EVT_MOTION (wxScintilla::OnMouseMove)
EVT_LEFT_UP (wxScintilla::OnMouseLeftUp)
#if defined(__WXGTK__) || defined(__WXMAC__)
EVT_RIGHT_UP (wxScintilla::OnMouseRightUp)
#else
EVT_CONTEXT_MENU (wxScintilla::OnContextMenu)
#endif
EVT_MOUSEWHEEL (wxScintilla::OnMouseWheel)
EVT_MIDDLE_UP (wxScintilla::OnMouseMiddleUp)
EVT_CHAR (wxScintilla::OnChar)
EVT_KEY_DOWN (wxScintilla::OnKeyDown)
EVT_KILL_FOCUS (wxScintilla::OnLoseFocus)
EVT_SET_FOCUS (wxScintilla::OnGainFocus)
EVT_SYS_COLOUR_CHANGED (wxScintilla::OnSysColourChanged)
EVT_ERASE_BACKGROUND (wxScintilla::OnEraseBackground)
EVT_MENU_RANGE (10, 16, wxScintilla::OnMenu)
EVT_LISTBOX_DCLICK (wxID_ANY, wxScintilla::OnListBox)
END_EVENT_TABLE()
So, it looks like you can add one for EVT_LISTBOX, see http://docs.wxwidgets.org/trunk/classwx_list_box.html
EVT_LISTBOX(id, func):
Process a wxEVT_COMMAND_LISTBOX_SELECTED event, when an item on the list is selected or the selection changes.
EVT_LISTBOX_DCLICK(id, func):
Process a wxEVT_COMMAND_LISTBOX_DOUBLECLICKED event, when the listbox is double-clicked.
wxScintilla::OnListBox basically just enter the selected text in autocompletion:
void wxScintilla::OnListBox(wxCommandEvent& WXUNUSED(evt))
{
m_swx->DoOnListBox();
}
void ScintillaWX::DoOnListBox() {
AutoCompleteCompleted();
}
So, double click on the list box will finally call AutoCompleteCompleted(), which just enter a selected item's text.
Ollydbg, thanks a lot for advice :) Inspired by your post I tried to handle EVT_LISTBOX event:
cbStyledTextCtrl* control = editor->GetControl();
control->Connect(wxID_ANY, EVT_LISTBOX,
(wxObjectEventFunction)&CodeCompletion::OnAutocompleteListbox,
NULL, this );
but event has never occurred. So I set breakpoint on wxScintilla::OnListBox, and find out that this method is never called! So I had to go deeper and I find that wxxcintilla doesn't use wxListBox but wxListView (http://docs.wxwidgets.org/trunk/classwx_list_view.html), so I have to handle wxEVT_COMMAND_LIST_ITEM_SELECTED.
Now, all I need is documentation, but CC parser doesn't recognize them. Maybe parser should read xml generated by doxygen?
parsing comments in CC:
pros:
- builtin
- realtime parsing
cons:
- not implemented
reading from xml:
pros:
- xml is easy to read
- can read external documentation( user will only specify patches to it)
cons:
- user must have already generated docs
What you think, what will be better?
What does this do to performance? (Memory/CPU)
Plain documentation is stored in additional map, so memory isn't wasted when token haven't got documentation.
Html is generated on the fly from tokens generated (and cached) in CodeCompletion::CodeComplete, there aren't additional searches in token tree. Most of the times token index is passed in link's href, so it can be obtained from tree without search.
I second that.
And me too :) But first I have to find out how create patch that adds files to repo.
Can you make the comment panel's background color different from the code editor's background?
currently, they are both white.
I forgot that default background color is white :) I already added border. I think that colors of background, text and links should be customizable.
EDIT: it seems that click on the HTML link(in the comment panel) does not work.
Which exactly doesn't work? Can you try this code:
struct ThisLinkWorks{};
//! A test class.
/*!
A more elaborate class description.
*/
class Test
{
public:
//! An enum.
/*! More detailed enum description. */
enum TEnum {
TVal1 = 2, /*!< Enum value TVal1. */
TVal2, /*!< Enum value TVal2. */
TVal3 /*!< Enum value TVal3. */
}
//! Enum pointer.
/*! Details. */
*enumPtr,
//! Enum variable.
/*! Details. */
enumVar;
//! A constructor.
//! Constructing constructor of constructive Test class.
/*!
A more elaborate description of the constructor.
*/
Test();
//! A destructor.
/*!
A more elaborate description of the destructor.
*/
~Test();
//! A normal member taking two arguments and returning an <font color=red>integer</font> value.
/*!
\param a an integer argument.
\param s a constant character pointer.
\return The test results
\sa Test, ~Test, Test() testMeToo publicVar
*/
int testMe(int a, const char* s);
//! A pure virtual member.
/*!
\sa testMe()
\param c1 the first argument.
\param c2 the second argument.
*/
virtual void testMeToo(char c1, char c2) = 0;
//! A public variable.
/*!
Details.
*/
int publicVar;
//! A function variable.
/*!
Details.
*/
int (*handler)(int a, int b);
ThisLinkWorks function4(ThisLinkDoesntWork tldw);
};
PS. Can also try to implement methods using codecompletion?
Please stick to lower case file names.
Ok.
Well in fact, on Windows none of the blue links works for me:
I just tested it on windows, and it works very bad, much worse than on linux. Fortunately I know how to fix it.
I don't understand this sentence.
Sorry, if it wasn't clear. I mean when you have function/method declaration:void function(int arg0, float arg1);
you can use autocomplete to write implementation easily:void fun| // <- use autocomplete here
and you will get void function(int arg0, float arg1)
The only requirement is that implementation must be outside block.
Next update, now all newly added functionalities are disabled by default. To enable them you have modify your config file manually.
<USE_DOCUMENTATION_HELPER bool="1" />
<DOCUMENTATION_HELPER_BACKGROUND_COLOR>
<colour r="255" g="255" b="255" />
</DOCUMENTATION_HELPER_BACKGROUND_COLOR>
<DOCUMENTATION_HELPER_TEXT_COLOR>
<colour r="0" g="0" b="0" />
</DOCUMENTATION_HELPER_TEXT_COLOR>
<DOCUMENTATION_HELPER_LINK_COLOR>
<colour r="0" g="0" b="255" />
</DOCUMENTATION_HELPER_LINK_COLOR>
These lines enables documentation helper, and sets colours used in generated html document.
<DETECT_IMPLEMENTATION bool="1" />
This one enables functionality described in my previous post - if you use autocomplete in global scope or inside class declaration then arguments' types and names will be added.
<SORT_CRITERION1 int="2" />
<SORT_CRITERION2 int="1" />
<SORT_CRITERION3 int="6" />
<SORT_CRITERION4 int="5" />
<SORT_CRITERION5 int="7" />
<SORT_CRITERION6 int="8" />
<SORT_CRITERION7 int="4" />
<SORT_CRITERION8 int="0" />
By the way I also added possibility to sort autocomplete list. You can use up to 8 sort criteria. Lower criterion number means higher priority (SORT_CRITERION1 has highest priority). Argument's specify how auto complete list will be sorted. Possible values and its meanings:
enum Criterium
{
NO_CRITERION = 0,
CMP_SCOPE = 1, // compare by token's scope
IS_LOCAL = 2, // compare by Token::m_IsTemp: checks if token is local variable
CMP_NAME = 3, //compare by token's name
CMP_KIND = 4, //compare by token's kind with order defined by Token::m_TokenKind value; don't use this comparator with lower priority than IS_FN, IS_VAR, IS_CLASS, IS_NS
IS_FN = 5, // compare by token's kind: checks if token is function
IS_VAR = 6, //compare by token's kind: checks if token is variable
IS_CLASS = 7, // ... is it class
IS_NS = 8, // ... is it namespace
};
And if you set criterion to "0" (NO_CRITERION) all criteria with lower priority will be disabled, so to sort only by token's name simply set SORT_CRITERION1 to "0".
edit: those tags should be sub-nodes of <code_completion> node.
edit2: Changes in project files are not included in patch, so remember to add doxygen_parser.* files to project.
Oh, sorry. I cut out too much when I was removing unnecessary chunks from patch.
You can use revised patch (in attachment) or apply this:
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (wersja 8771)
+++ src/plugins/codecompletion/parser/parserthread.cpp (kopia robocza)
@@ -197,7 +197,8 @@
m_IsBuffer(parserThreadOptions.useBuffer),
m_Buffer(bufferOrFilename)
{
- m_Tokenizer.SetTokenizerOption(parserThreadOptions.wantPreprocessor);
+ bool storeDocumentation = true;
+ m_Tokenizer.SetTokenizerOption(parserThreadOptions.wantPreprocessor, storeDocumentation);
if (!m_TokenTree)
cbThrow(_T("m_TokenTree is a nullptr?!"));
}
I have a wired build issue:
[ 58.3%] g++.exe -Wall -g -pipe -mthreads -fmessage-length=0 -fexceptions -Winvalid-pch -DHAVE_W32API_H -D__WXMSW__ -DWXUSINGDLL -DcbDEBUG -DCB_PRECOMP -DWX_PRECOMP -DwxUSE_UNICODE -DBUILDING_PLUGIN -iquote.objs\include -I.objs\include -I. -IE:\code\cb\wx\wxWidgets-2.8.12\include -IE:\code\cb\wx\wxWidgets-2.8.12\contrib\include -IE:\code\cb\wx\wxWidgets-2.8.12\lib\gcc_dll\mswu -Isdk\wxscintilla\include -Isdk\wxpropgrid\include -Iinclude\tinyxml -Iinclude -Iinclude\mozilla_chardet -Iinclude\mozilla_chardet\mfbt -Iinclude\mozilla_chardet\nsprpub\pr\include -Iinclude\mozilla_chardet\xpcom -Iinclude\mozilla_chardet\xpcom\base -Iinclude\mozilla_chardet\xpcom\glue -c plugins\codecompletion\codecompletion.cpp -o .objs\plugins\codecompletion\codecompletion.o
In file included from plugins\codecompletion\codecompletion.h:17:0,
from plugins\codecompletion\codecompletion.cpp:53:
plugins\codecompletion\doxygen_parser.h:181:9: error: expected identifier before numeric constant
plugins\codecompletion\doxygen_parser.h:181:9: error: expected '}' before numeric constant
plugins\codecompletion\doxygen_parser.h:181:9: error: expected unqualified-id before numeric constant
plugins\codecompletion\doxygen_parser.h:197:37: error: 'Command' was not declared in this scope
plugins\codecompletion\doxygen_parser.h:197:50: error: expected primary-expression before 'const'
plugins\codecompletion\doxygen_parser.h:197:72: error: expected primary-expression before 'const'
plugins\codecompletion\doxygen_parser.h:199:40: error: 'Command' was not declared in this scope
plugins\codecompletion\doxygen_parser.h:199:53: error: expected primary-expression before 'const'
plugins\codecompletion\doxygen_parser.h:199:75: error: expected primary-expression before 'int'
plugins\codecompletion\doxygen_parser.h:201:12: error: 'Command' does not name a type
plugins\codecompletion\doxygen_parser.h:207:27: error: uninitialized const 'separatorTag' [-fpermissive]
plugins\codecompletion\doxygen_parser.h:211:39: error: expected ')' before '*' token
plugins\codecompletion\doxygen_parser.h:213:27: error: expected constructor, destructor, or type conversion before ';' token
plugins\codecompletion\doxygen_parser.h:229:23: error: non-member function 'bool IsAttached()' cannot have cv-qualifier
plugins\codecompletion\doxygen_parser.h:235:1: error: expected unqualified-id before 'protected'
plugins\codecompletion\doxygen_parser.h:251:1: error: expected unqualified-id before 'public'
plugins\codecompletion\doxygen_parser.h:259:1: error: expected unqualified-id before 'protected'
plugins\codecompletion\doxygen_parser.h:284:5: error: expected unqualified-id before 'private'
plugins\codecompletion\doxygen_parser.h:284:5: error: expected unqualified-id before 'protected'
plugins\codecompletion\doxygen_parser.h:284:5: error: 'virtual' outside class declaration
plugins\codecompletion\doxygen_parser.h:284:5: error: non-member function 'const wxEventTable* GetEventTable()' cannot have cv-qualifier
plugins\codecompletion\doxygen_parser.h:284:5: error: no matching function for call to 'wxEventHashTable::wxEventHashTable()'
plugins\codecompletion\doxygen_parser.h:284:5: note: candidates are:
E:\code\cb\wx\wxWidgets-2.8.12\include/wx/event.h:2380:5: note: wxEventHashTable::wxEventHashTable(const wxEventHashTable&)
E:\code\cb\wx\wxWidgets-2.8.12\include/wx/event.h:2380:5: note: candidate expects 1 argument, 0 provided
E:\code\cb\wx\wxWidgets-2.8.12\include/wx/event.h:2342:5: note: wxEventHashTable::wxEventHashTable(const wxEventTable&)
E:\code\cb\wx\wxWidgets-2.8.12\include/wx/event.h:2342:5: note: candidate expects 1 argument, 0 provided
plugins\codecompletion\doxygen_parser.h:284:5: error: 'virtual' outside class declaration
plugins\codecompletion\doxygen_parser.h:284:5: error: non-member function 'wxEventHashTable& GetEventHashTable()' cannot have cv-qualifier
plugins\codecompletion\doxygen_parser.h:285:1: error: expected declaration before '}' token
The first error happens here:
class DocumentationHelper : public /*wxHtmlWindow*/ wxEvtHandler
{
//typedef wxHtmlWindow BaseClass;
typedef wxEvtHandler BaseClass;
public:
enum Command
{
NO_COMMAND,
DISPLAY_TOKEN, //args: token index
SEARCH, //args: token name
SEARCH_ALL, //args: token name **************Here
OPEN_DECL, //args: token index
OPEN_IMPL, //args: token index
CLOSE, //args: -----
};
I just run the preprocessor:
@echo Add MinGW path
@set PATH=E:\code\gcc\PCXMinGW463\bin;%PATH%
g++.exe -Wall -g -pipe -mthreads -fmessage-length=0 -fexceptions -Winvalid-pch -DHAVE_W32API_H -D__WXMSW__ -DWXUSINGDLL -DcbDEBUG -DCB_PRECOMP -DWX_PRECOMP -DwxUSE_UNICODE -DBUILDING_PLUGIN -iquote.objs\include -I.objs\include -I. -IE:\code\cb\wx\wxWidgets-2.8.12\include -IE:\code\cb\wx\wxWidgets-2.8.12\contrib\include -IE:\code\cb\wx\wxWidgets-2.8.12\lib\gcc_dll\mswu -Isdk\wxscintilla\include -Isdk\wxpropgrid\include -Iinclude\tinyxml -Iinclude -Iinclude\mozilla_chardet -Iinclude\mozilla_chardet\mfbt -Iinclude\mozilla_chardet\nsprpub\pr\include -Iinclude\mozilla_chardet\xpcom -Iinclude\mozilla_chardet\xpcom\base -Iinclude\mozilla_chardet\xpcom\glue -E plugins\codecompletion\codecompletion.cpp >> a.txt
The wired thing is, when I look at the a.txt(the preprocessed output), I see such code:
class DocumentationHelper : public wxEvtHandler
{
typedef wxEvtHandler BaseClass;
public:
enum Command
{
NO_COMMAND,
DISPLAY_TOKEN,
SEARCH,
0x0,
OPEN_DECL,
OPEN_IMPL,
CLOSE,
};
I don't know where the "0x0" comes???? I just searched the whole file, and I see no macro definition of "SEARCH_ALL". I have no idea what happens.....
EDIT:
It looks like I can add such code to avoid the issue.
#ifdef SEARCH_ALL
#undef SEARCH_ALL
#endif
But I still have no idea where does the previous "SEARCH_ALL" defined.
Ok, by putting the text:
<USE_DOCUMENTATION_HELPER bool="1" />
<DOCUMENTATION_HELPER_BACKGROUND_COLOR>
<colour r="255" g="255" b="255" />
</DOCUMENTATION_HELPER_BACKGROUND_COLOR>
<DOCUMENTATION_HELPER_TEXT_COLOR>
<colour r="0" g="0" b="0" />
</DOCUMENTATION_HELPER_TEXT_COLOR>
<DOCUMENTATION_HELPER_LINK_COLOR>
<colour r="0" g="0" b="255" />
</DOCUMENTATION_HELPER_LINK_COLOR>
in the configure file, section:
<code_completion>
....
</code_completion>
I'm happy testing this new feature, really good job, p2rkw!!!
If you don't know where macro is defined, then it's defined in windows.h :) Thanks for information, I will change this name.
Nope, this time its well hidden in "ntddchgr.h" of the DDK ([MinGW]\include\ddk\) of MinGW.
This shows very nice, how badly macros can suck.
Oh, and BTW: In my personal projects I always declare enums as following:
enum ECommand
{
eNO_COMMAND,
eDISPLAY_TOKEN, //args: token index
eSEARCH, //args: token name
eSEARCH_ALL, //args: token name
eOPEN_DECL, //args: token index
eOPEN_IMPL, //args: token index
eCLOSE, //args: -----
};
Notice the prefixes... this usually never conflicts with #defines, as they are 99% of the cases declared upper-case only.
Gui added, last bugs fixed... It seems to be finished now :) http://developer.berlios.de/patch/?func=detailpatch&patch_id=3381&group_id=5358
(Ability to define custom sort order had been removed from this patch, so remember to clean your configuration file.)
Thanks! the patch is big, so I just apply the patch, and build it. I see two build warnings:
1,
plugins\codecompletion\codecompletion.cpp|1658|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]|
The code is:
ccSearchData searchData { control, editor->GetFilename() };
So, it would better:
ccSearchData searchData= { control, editor->GetFilename() };
2,
plugins\codecompletion\doxygen_parser.cpp|559|warning: comparison between signed and unsigned integer expressions [-Wsign-compare]|
Here
for(int i = 0; i < (size_t)(sizeof(arguments)/sizeof(arguments[0])); ++i )
i should be unsigned int.
:)
@p2rkw: How difficult would it be to extend the parser to accept comments on more complicated declarations, ex. the following from stl:
/**
* @brief This does what you think it does.
* @ingroup sorting_algorithms
* @param a A thing of arbitrary type.
* @param b Another thing of arbitrary type.
* @return The lesser of the parameters.
*
* This is the simple classic generic implementation. It will work on
* temporary expressions, since they are only evaluated once, unlike a
* preprocessor macro.
*/
template<typename _Tp>
inline const _Tp&
min(const _Tp& __a, const _Tp& __b)
{
// concept requirements
__glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
//return __b < __a ? __b : __a;
if (__b < __a)
return __b;
return __a;
}
Do these functions have a purpose?
F:\cb\src\plugins\codecompletion\doxygen_parser.cpp:26:12: warning: 'int GetAverangeCharWidth(cbStyledTextCtrl*, int)' defined but not used [-Wunused-function]
F:\cb\src\plugins\codecompletion\parser\tokentree.cpp:96:17: warning: 'bool TokenTreeHelper::CompareBaseArguments(const wxString&, const wxString&)' defined but not used [-Wunused-function]
This patch works.
Never mind.
When I do not enable new features of the C++ language, the parser correctly skips items such as cbegin(), however, the doxygen parser does not skip them. All of the following documentation is appended to size().
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* Returns a read-only (constant) iterator that points to the
* first element in the %vector. Iteration is done in ordinary
* element order.
*/
const_iterator
cbegin() const
{ return const_iterator(this->_M_impl._M_start); }
/**
* Returns a read-only (constant) iterator that points one past
* the last element in the %vector. Iteration is done in
* ordinary element order.
*/
const_iterator
cend() const
{ return const_iterator(this->_M_impl._M_finish); }
/**
* Returns a read-only (constant) reverse iterator that points
* to the last element in the %vector. Iteration is done in
* reverse element order.
*/
const_reverse_iterator
crbegin() const
{ return const_reverse_iterator(end()); }
/**
* Returns a read-only (constant) reverse iterator that points
* to one before the first element in the %vector. Iteration
* is done in reverse element order.
*/
const_reverse_iterator
crend() const
{ return const_reverse_iterator(begin()); }
#endif
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const
{ return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
New problem code identified:
enum TokenizerState
{
tsSkipEqual = 0x0001, /// Skip the assignment statement
tsSkipQuestion = 0x0002, /// Skip the conditional evaluation statement
tsSkipSubScrip = 0x0004, /// Skip the array-subscript notation statement
tsSingleAngleBrace = 0x0008, /// Reserve angle braces
tsReadRawExpression = 0x0010, /// Reserve every chars
tsSkipNone = 0x1000, /// Skip None
// convenient masks
tsSkipUnWanted = tsSkipEqual | tsSkipQuestion | tsSkipSubScrip,
tsTemplateArgument = tsSkipUnWanted | tsSingleAngleBrace
};
All of the line comments are attached to the token after them. So, for example, tsSkipUnWanted says "Skip None" (I am not sure if this issue existed previously though).