Re: Class Variables - no attrAutoCompleteAfter patch
Andrew Lowe <[email protected]> Fri, 16 Feb 2007 17:23:50 +1100
| Newsgroups | gmane.comp.kde.devel.quanta |
|---|---|
| Message-ID | <[email protected]> |
Andras, I have cleaned up the code, and implemented your suggestions. Things should be pretty optimal, and I found some other ways to optimise... Comments below inline... Andras Mantia wrote: >On Thursday 15 February 2007, Andrew Lowe wrote: > > >>You may want to autocomplete function arguments as normal variables >>ie. when you type '$', but you do not want them as class arguments >>ie. after the '->' so I would think we just need to remove the >>className? >>That should already work. Actually that non-member autocompletion is >>done in a different place, in the "group" autocompletion. Normal >>variables are added to the "variable" group. The userTagsList is only >>used for members. It is kind'a hack, but that is... >> >> That makes more sense now.... removed class function arguments from the userTagsList completly. > > >>>In the completion code, I don't understand something. You set >>> >>>completion.type = type[tagNameList[i]]; >>> >>>But this will be wrong for XML, as in case of XML, type is >>>unitialized. Shouldn't this be moved inside the >>>+ if(completionDTD->family==Script) >>>? >>> >>> >>> >>> >>Yes, so it should - which incidently is what I moved from inside the >>if block, when I said I had found a mistake :-) >> >> > >I looked at your second patch and here there is: >- completions->append( completion ); >+ /* Author Andrew Lowe - [email protected] >+ * Here we actually append the completion type >+ */ >+ completion.type = type[tagNameList[i]]; >+ if(completionDTD->family==Script) > >So I don't understand why you think its a mistake to have that statement >inside the if block. > > I originally put the code their by mistake, however, as you have pointed out, it was correct to place it there... I wrote the code in the if statement (sorting code) after putting the variable type in. I thought it should be seperate because of this, however, as you point out, it should be there, because it makes no for XML families.. I have fixed this also Also in SAGroupParser::parseForScriptGroup where I am checking if the variable is a function argument, I check if the tagStr contains an open and closing paretheses '(' &')' because if they do not, there is no need to run the loops to trim tagStr down to just one line, and test the variable. I also included the diff against svn for the data/dtep/php/description.rc I forgot in earlier patches ( I was using my ~.kde/share/apps/quanta/dtep/php/ folder until just now) Thanks.. -- Andrew Lowe System Administrator & Programmer Information Technology Manildra Group Email: [email protected] Phone: 02 4423 8270 Mobile: 04 1323 8270 Fax: 02 4421 7760 _______________________________________________ quanta-devel mailing list [email protected] https://mail.kde.org/mailman/listinfo/quanta-devel
class-completions.patch
(text/plain, 7.2 KB)
Index: parsers/sagroupparser.cpp
===================================================================
--- parsers/sagroupparser.cpp (revision 633713)
+++ parsers/sagroupparser.cpp (working copy)
@@ -203,7 +203,9 @@
if (group.appendToTags)
{
QTag *qTag = new QTag();
- qTag->setName(s.left(s.find('(')));
+ // The location of the first open bracket '(', also the end of the tag name
+ int nameEnd = s.find('(');
+ qTag->setName(s.left(nameEnd));
qTag->className = "";
if (groupElement->parentNode)
{
@@ -216,7 +218,61 @@
}
}
}
- m_write->userTagList.insert(s.lower(), qTag);
+ // Test for variable or function Type by checking for an opening bracket "(" used by functions
+ // and store the type in the QTag type variable.
+ bool isArgument=false;
+ if (nameEnd == -1)
+ {
+ qTag->type="variable";
+ // If this tag is a class function argument, it should not belong to the class, so we need to remove it
+ if(qTag->className.length() != 0 && tagStr.contains('(') && tagStr.contains(')'))
+ {
+ // First we want to determine the whole line the tag is on
+ QString tagWholeLineStr = tagStr;
+ // Remove lines before target line
+ while(tagWholeLineStr.length() > 0) // this stops infinit looping in case something goes wrong!
+ {
+ int firstNewline = tagWholeLineStr.find('\n');
+ if(firstNewline == -1) //no new lines so we must be on the last
+ break;
+ QString checkLineStr = tagWholeLineStr.mid(firstNewline+1,tagWholeLineStr.length());
+ if(checkLineStr.contains(s))
+ tagWholeLineStr = checkLineStr;
+ else
+ break;
+ }
+ // Remove lines after target line - essentially same as above
+ while(tagWholeLineStr.length() > 0)
+ {
+ int lastNewLine = tagWholeLineStr.findRev('\n');
+ if(lastNewLine == -1)
+ break;
+ QString checkLineStr = tagWholeLineStr.mid(0,lastNewLine);
+ if(checkLineStr.contains(s))
+ tagWholeLineStr = checkLineStr;
+ else
+ break;
+ }
+ // Now we are left with the current line, lets check if the variable is inside parentheses
+ int lineOpenParenth=tagWholeLineStr.find('(');
+ if(lineOpenParenth != -1)
+ {
+ int lineCloseParenth=tagWholeLineStr.find(')');
+ if(lineCloseParenth != -1)
+ {
+ int lineNameLocation=tagWholeLineStr.find(s);
+ if(lineNameLocation > lineOpenParenth || lineNameLocation < lineCloseParenth) // Write the current tag to the list
+ isArgument=true;
+ }
+ }
+ }
+ }
+ else
+ {
+ qTag->type="function";
+ }
+ if(!isArgument)
+ m_write->userTagList.insert(s.lower(), qTag);
}
Index: src/document.cpp
===================================================================
--- src/document.cpp (revision 633713)
+++ src/document.cpp (working copy)
@@ -1285,6 +1285,8 @@
completion.userdata = word + "|";
QStringList tagNameList;
QMap<QString, QString> comments;
+ //A QMap to hold the completion type (function/string/class/etc)
+ QMap<QString, QString> type;
QString tagName;
QDictIterator<QTag> it(*(completionDTD->tagsList));
int i = 0;
@@ -1318,11 +1320,36 @@
tagName = tag->name() + QString("%1").arg(i, 10);
tagNameList += tagName;
comments.insert(tagName, tag->comment);
- i++;
+
+ // If the completion family is script, then we want to update the tag type
+ // it appears we use "script" for adding the completionDTD->attrAutoCompleteAfter when we run the slotFilterCompletion
+ // so we will continue to use that for functions (they need the attribute added), but variables get a new type - and we do not
+ // have to auto-complete them
+ if(completionDTD->family==Script)
+ {
+ if(tag->type=="variable")
+ type.insert(tagName, tag->type);
+ else if(tag->type=="function")
+ type.insert(tagName, "script");
+
+ // We add the type to the comment variable, so it displays on the screen, giving the user some feedback
+ if(comments[tagName].length())
+ comments[tagName] = tag->type + "\n" + comments[tagName];
+ else
+ comments[tagName] = tag->type + comments[tagName];
+ i++;
+ }
}
}
tagNameList.sort();
+ // tagNameList is sorted above to sort the completions by name alphabetically
+ // Now we want to sort the completions by their types.
+ // We only want to do this if we are completing Script DTDs
+ // We are going to use a couple of iterators to sort the list by Type
+ // Type Sorting is as follows: 0:Other, 1:Variables, 2: Functions (script)
+ QValueList<KTextEditor::CompletionEntry>::Iterator otherIt=completions->begin();
+ QValueList<KTextEditor::CompletionEntry>::Iterator variableIt=completions->begin();
for (uint i = 0; i < tagNameList.count(); i++)
{
if (completionDTD->family == Xml)
@@ -1331,10 +1358,42 @@
completion.text = tagNameList[i];
completion.text = completion.text.left(completion.text.length() - 10).stripWhiteSpace();
completion.comment = comments[tagNameList[i]];
- completions->append( completion );
+
+ if(completionDTD->family==Script)
+ {
+ // Here we actually append the completion type
+ completion.type = type[tagNameList[i]];
+ // And here is out sorting...
+ if(completion.type.contains("variable"))
+ {
+ // Insert after the last variable
+ variableIt++;
+ variableIt = completions->insert(variableIt, completion);
+ }
+ else
+ {
+ if(completion.type.contains("script"))
+ {
+ //Scripts can go at the end of the list
+ completions->append(completion);
+ }
+ else
+ {
+ // Other types go first, after the last other type
+ otherIt++;
+ otherIt = completions->insert(otherIt, completion);
+ // If we have no variables in the list, we need to point variableIt to otherIt, so they will go after the 'others'
+ if((*variableIt).text.length()==0)
+ variableIt=otherIt;
+ }
+ }
+ }
+ else
+ completions->append( completion );
}
// completionInProgress = true;
+
return completions;
}
Index: data/dtep/php/description.rc
===================================================================
--- data/dtep/php/description.rc (revision 633713)
+++ data/dtep/php/description.rc (working copy)
@@ -50,6 +50,8 @@
DefinitionRx = \$+([a-zA-Z0-9_\x7f-\xff]*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)
UsageRx = \$+([a-zA-Z0-9_\x7f-\xff]*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)
AutoCompleteAfter = \$+[a-zA-Z0-9_\x7f-\xff]*$
+AppendToTags = true
+ParentGroup = Classes
[StructGroup_3]
Name = Functions