work save
This commit is contained in:
parent
f3cc986c4e
commit
bf4d12b89f
|
@ -1381,133 +1381,179 @@ void Editor::showHeaderCompletion(bool autoComplete)
|
||||||
//todo:
|
//todo:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Editor::testInFunc(int x, int y)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
QString s = lines()->getString(y);
|
||||||
|
int posY = y;
|
||||||
|
int posX = std::min(x,s.length()-1); // x is started from 1
|
||||||
|
int bracketLevel=0;
|
||||||
|
while (true) {
|
||||||
|
while (posX < 0) {
|
||||||
|
posY--;
|
||||||
|
if (posY < 0)
|
||||||
|
return false;
|
||||||
|
s = lines()->getString(posY);
|
||||||
|
posX = s.length()-1;
|
||||||
|
}
|
||||||
|
if (s[posX] == '>'
|
||||||
|
|| s[posX] == ']') {
|
||||||
|
bracketLevel++;
|
||||||
|
} else if (s[posX] == '<'
|
||||||
|
|| s[posX] == '[') {
|
||||||
|
bracketLevel--;
|
||||||
|
} else if (bracketLevel==0) {
|
||||||
|
switch (s[posX].unicode()) {
|
||||||
|
case '(':
|
||||||
|
return true;
|
||||||
|
case ';':
|
||||||
|
case '{':
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(isIdentChar(s[posX])
|
||||||
|
|| s[posX] == ' '
|
||||||
|
|| s[posX] == '\t'
|
||||||
|
|| s[posX] == '*'
|
||||||
|
|| s[posX] == '&'))
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
posX--;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord &pWordEnd, WordPurpose purpose)
|
QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord &pWordEnd, WordPurpose purpose)
|
||||||
{
|
{
|
||||||
QString result = "";
|
QString result = "";
|
||||||
QString s;
|
QString s;
|
||||||
if ((p.Line >= 1) && (p.Line <= lines()->count())) {
|
if ((p.Line<1) || (p.Line>lines()->count())) {
|
||||||
s = lines()->getString(p.Line - 1);
|
pWordBegin = p;
|
||||||
int len = s.length();
|
pWordEnd = p;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
int wordBegin = p.Char - 1 - 1; //BufferCoord::Char starts with 1
|
s = lines()->getString(p.Line - 1);
|
||||||
int wordEnd = p.Char - 1 - 1;
|
int len = s.length();
|
||||||
|
|
||||||
// Copy forward until end of word
|
int wordBegin = p.Char - 1 - 1; //BufferCoord::Char starts with 1
|
||||||
if (purpose == WordPurpose::wpEvaluation
|
int wordEnd = p.Char - 1 - 1;
|
||||||
|| purpose == WordPurpose::wpInformation) {
|
|
||||||
while (wordEnd + 1 < len) do {
|
// Copy forward until end of word
|
||||||
if ((purpose == WordPurpose::wpEvaluation)
|
if (purpose == WordPurpose::wpEvaluation
|
||||||
&& (s[wordEnd + 1] == '[')) {
|
|| purpose == WordPurpose::wpInformation) {
|
||||||
if (!findComplement(s, '[', ']', wordEnd, 1))
|
while (wordEnd + 1 < len) {
|
||||||
break;
|
if ((purpose == WordPurpose::wpEvaluation)
|
||||||
} else if (isIdentChar(s[wordEnd + 1])) {
|
&& (s[wordEnd + 1] == '[')) {
|
||||||
wordEnd++;
|
if (!findComplement(s, '[', ']', wordEnd, 1))
|
||||||
} else
|
|
||||||
break;
|
break;
|
||||||
}
|
} else if (isIdentChar(s[wordEnd + 1])) {
|
||||||
|
wordEnd++;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy backward until #
|
// Copy backward until #
|
||||||
if (purpose == WordPurpose::wpDirective) {
|
if (purpose == WordPurpose::wpDirective) {
|
||||||
while ((wordBegin >= 0) && (wordBegin < len)) {
|
while ((wordBegin >= 0) && (wordBegin < len)) {
|
||||||
if (isIdentChar(s[wordBegin]))
|
if (isIdentChar(s[wordBegin]))
|
||||||
wordBegin--;
|
wordBegin--;
|
||||||
else if (s[wordBegin] == '#') {
|
else if (s[wordBegin] == '#') {
|
||||||
wordBegin--;
|
wordBegin--;
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy backward until @
|
// Copy backward until @
|
||||||
if (purpose == WordPurpose::wpJavadoc) {
|
if (purpose == WordPurpose::wpJavadoc) {
|
||||||
while ((wordBegin >= 0) && (wordBegin < len)) {
|
while ((wordBegin >= 0) && (wordBegin < len)) {
|
||||||
if (isIdentChar(s[wordBegin]))
|
if (isIdentChar(s[wordBegin]))
|
||||||
wordBegin--;
|
wordBegin--;
|
||||||
else if (s[wordBegin] == '@') {
|
else if (s[wordBegin] == '@') {
|
||||||
wordBegin--;
|
wordBegin--;
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy backward until begin of path
|
// Copy backward until begin of path
|
||||||
if (purpose == wpHeaderCompletion) {
|
if (purpose == WordPurpose::wpHeaderCompletion) {
|
||||||
while ((wordBegin >= 0) && (wordBegin < len)) {
|
while ((wordBegin >= 0) && (wordBegin < len)) {
|
||||||
if (isIdentChar(s[wordBegin]))
|
if (isIdentChar(s[wordBegin]))
|
||||||
wordBegin--;
|
wordBegin--;
|
||||||
else if (s[wordBegin] == '/'
|
else if (s[wordBegin] == '/'
|
||||||
|
|| s[wordBegin] == '\\'
|
||||||
|
|| s[wordBegin] == '.') {
|
||||||
|
wordBegin--;
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (purpose == WordPurpose::wpHeaderCompletionStart) {
|
||||||
|
while ((wordBegin >= 0) && (wordBegin < len)) {
|
||||||
|
if (s[wordBegin] == '"'
|
||||||
|
|| s[wordBegin] == '<') {
|
||||||
|
wordBegin--;
|
||||||
|
break;
|
||||||
|
} else if (s[wordBegin] == '/'
|
||||||
|| s[wordBegin] == '\\'
|
|| s[wordBegin] == '\\'
|
||||||
|| s[wordBegin] == '.') {
|
|| s[wordBegin] == '.') {
|
||||||
wordBegin--;
|
wordBegin--;
|
||||||
break;
|
} else if (isIdentChar(s[wordBegin]))
|
||||||
} else
|
wordBegin--;
|
||||||
break;
|
else
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (purpose == WordPurpose::wpHeaderCompletionStart) {
|
// && ( wordBegin < len)
|
||||||
while ((wordBegin >= 0) && (wordBegin < len)) {
|
// Copy backward until begin of word
|
||||||
if (s[wordBegin] == '"'
|
if (purpose == WordPurpose::wpCompletion
|
||||||
|| s[wordBegin] == '<']) {
|
|| purpose == WordPurpose::wpEvaluation
|
||||||
wordBegin--;
|
|| purpose == WordPurpose::wpInformation) {
|
||||||
|
while ((wordBegin >= 0) && (wordBegin<len)) {
|
||||||
|
if (s[wordBegin] == ']') {
|
||||||
|
if (!findComplement(s, ']', '[', wordBegin, -1))
|
||||||
break;
|
break;
|
||||||
} else if (s[wordBegin] == '/'
|
|
||||||
|| s[wordBegin] == '\\'
|
|
||||||
|| s[wordBegin] == '.') {
|
|
||||||
wordBegin--;
|
|
||||||
} else if (isIdentChar(s[wordBegin]))
|
|
||||||
wordBegin--;
|
|
||||||
else
|
else
|
||||||
|
wordBegin++; // step over mathing [
|
||||||
|
} else if (isIdentChar(s[wordBegin])) {
|
||||||
|
wordBegin--;
|
||||||
|
} else if (s[wordBegin] == '.'
|
||||||
|
|| s[wordBegin] == ':'
|
||||||
|
|| s[wordBegin] == '~') { // allow destructor signs
|
||||||
|
wordBegin--;
|
||||||
|
} else if (
|
||||||
|
(s[wordBegin] == '>')
|
||||||
|
&& (wordBegin+2<len)
|
||||||
|
&& (s[wordBegin+1]==':')
|
||||||
|
&& (s[wordBegin+2]==':')
|
||||||
|
) { // allow template
|
||||||
|
if (!findComplement(s, '>', '<', wordBegin, -1))
|
||||||
break;
|
break;
|
||||||
}
|
else
|
||||||
}
|
wordBegin--; // step over >
|
||||||
|
} else if ((wordBegin-1 >= 0)
|
||||||
// Copy backward until begin of word
|
&& (s[wordBegin - 1] == '-')
|
||||||
if (purpose == WordPurpose::wpCompletion
|
&& (s[wordBegin] == '>')) {
|
||||||
|| purpose == WordPurpose::wpEvaluation
|
wordBegin-=2;
|
||||||
|| purpose == WordPurpose::wpInformation) {
|
} else if ((wordBegin-1 >= 0)
|
||||||
while ((wordBegin >= 0) && (wordBegin < len)) {
|
&& (s[wordBegin - 1] == ':')
|
||||||
if (s[wordBegin] == ']') then {
|
&& (s[wordBegin] == ':')) {
|
||||||
if (!findComplement(s, ']', '[', wordBegin, -1))
|
wordBegin-=2;
|
||||||
break
|
} else if ((wordBegin > 0)
|
||||||
else
|
&& (s[wordBegin] == ')')) {
|
||||||
wordBegin++; // step over [
|
if (!findComplement(s, ')', '(', wordBegin, -1))
|
||||||
} else if (isIdentChar(s[wordBegin])) {
|
|
||||||
wordBegin--;
|
|
||||||
} else if (s[wordBegin] == '.'
|
|
||||||
|| s[wordBegin] == ':'
|
|
||||||
|| s[wordBegin] == '~') { // allow destructor signs
|
|
||||||
wordBegin--;
|
|
||||||
} else if (
|
|
||||||
(s[wordBegin] == '>')
|
|
||||||
&& (wordBegin+2<len)
|
|
||||||
&& (s[WordBegin+1]==':')
|
|
||||||
&& (s[WordBegin+2]==':')
|
|
||||||
) { // allow template
|
|
||||||
if (!findComplement(s, '>', '<', wordBegin, -1))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
wordBegin--; // step over >
|
|
||||||
} else if ((wordBegin-1 >= 0)
|
|
||||||
&& (s[wordBegin - 1] == '-')
|
|
||||||
&& (s[wordBegin] == '>')) {
|
|
||||||
wordBegin-=2;
|
|
||||||
} else if ((wordBegin-1 >= 0)
|
|
||||||
&& (s[wordBegin - 1] == ':')
|
|
||||||
&& (s[wordBegin] == ':')) {
|
|
||||||
wordBegin-=2;
|
|
||||||
} else if ((wordBegin > 0)
|
|
||||||
&& (s[wordBegin] == ')')) {
|
|
||||||
if (!findComplement(s, ')', '(', WordBegin, -1))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
wordBegin--; // step over (
|
|
||||||
} else
|
|
||||||
break;
|
break;
|
||||||
}
|
else
|
||||||
|
wordBegin--; // step over mathing (
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1517,62 +1563,134 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
|
||||||
pWordBegin.Char = wordBegin+1;
|
pWordBegin.Char = wordBegin+1;
|
||||||
pWordEnd.Line = p.Line;
|
pWordEnd.Line = p.Line;
|
||||||
pWordEnd.Char = wordEnd;
|
pWordEnd.Char = wordEnd;
|
||||||
if (!result.isEmpty() && (
|
|
||||||
result[0] in ['.','-'])
|
// last line still have part of word
|
||||||
and (Purpose in [wpCompletion, wpEvaluation, wpInformation]) then begin
|
if (!result.isEmpty()
|
||||||
i:=WordBegin;
|
&& (
|
||||||
line:=p.Line;
|
result[0] == '.'
|
||||||
while line>=1 do begin
|
|| result[0] == '-')
|
||||||
while i>=1 do begin
|
&& (purpose == WordPurpose::wpCompletion
|
||||||
if S[i] in [' ',#9] then
|
|| purpose == WordPurpose::wpEvaluation
|
||||||
dec(i)
|
|| purpose == WordPurpose::wpInformation)) {
|
||||||
else
|
int i = wordBegin;
|
||||||
break;
|
int line=p.Line;
|
||||||
end;
|
while (line>=1) {
|
||||||
if i<1 then begin
|
while (i>=0) {
|
||||||
dec(line);
|
if (s[i] == ' '
|
||||||
if (line>=1) then begin
|
|| s[i] == '\t')
|
||||||
S:=editor.Lines[line-1];
|
i--;
|
||||||
i:=Length(s);
|
else
|
||||||
continue;
|
break;
|
||||||
end else
|
}
|
||||||
break;
|
if (i<0) {
|
||||||
end else begin
|
line--;
|
||||||
HighlightPos.Line := line;
|
if (line>=1) {
|
||||||
HighlightPos.Char := i+1;
|
s=lines()->getString(line-1);
|
||||||
Result := GetWordAtPosition(editor,highlightPos,pWordBegin,pDummy,Purpose)+Result;
|
i=s.length();
|
||||||
break;
|
continue;
|
||||||
end;
|
} else
|
||||||
end;
|
break;
|
||||||
end;
|
} else {
|
||||||
|
BufferCoord highlightPos;
|
||||||
|
BufferCoord pDummy;
|
||||||
|
highlightPos.Line = line;
|
||||||
|
highlightPos.Char = i+1;
|
||||||
|
result = getWordAtPosition(highlightPos,pWordBegin,pDummy,purpose)+result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Strip function parameters
|
// Strip function parameters
|
||||||
while true do begin
|
int paramBegin,paramEnd;
|
||||||
ParamBegin := Pos('(', Result);
|
while (true) {
|
||||||
if ParamBegin > 0 then begin
|
paramBegin = result.indexOf('(');
|
||||||
ParamEnd := ParamBegin;
|
if (paramBegin > 0) {
|
||||||
if (ParamBegin=1) and FindComplement(Result, '(', ')', ParamEnd, 1)
|
paramEnd = paramBegin;
|
||||||
and (ParamEnd = Length(Result)) then begin
|
if ((paramBegin==0)
|
||||||
Delete(Result,ParamEnd,1);
|
&& findComplement(result, '(', ')', paramEnd, 1)
|
||||||
Delete(Result,ParamBegin,1);
|
&& (paramEnd = result.length()-1) ) {
|
||||||
continue;
|
//remove the enclosing parenthese pair
|
||||||
end else begin
|
result = result.mid(1,result.length()-2);
|
||||||
ParamEnd := ParamBegin;
|
continue;
|
||||||
if FindComplement(Result, '(', ')', ParamEnd, 1) then begin
|
} else {
|
||||||
Delete(Result, ParamBegin, ParamEnd - ParamBegin + 1);
|
paramEnd = paramBegin;
|
||||||
end else
|
if (findComplement(result, '(', ')', paramEnd, 1)) {
|
||||||
|
result.remove(paramBegin, paramEnd - paramBegin + 1);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
break;
|
break;
|
||||||
end;
|
}
|
||||||
end else
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
|
|
||||||
ParamBegin := 1;
|
paramBegin = 0;
|
||||||
while (ParamBegin <= Length(Result)) and (Result[ParamBegin] = '*') do begin
|
while ((paramBegin < result.length()) && (result[paramBegin] == '*')) {
|
||||||
inc(ParamBegin);
|
paramBegin++;
|
||||||
end;
|
}
|
||||||
Delete(Result,1,ParamBegin-1);
|
result.remove(0,paramBegin);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Editor::getPreviousWordAtPositionForSuggestion(const BufferCoord &p)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
if ((p.Line<1) || (p.Line>lines()->count())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
bool inFunc = testInFunc(p.Char-1,p.Line-1);
|
||||||
|
|
||||||
|
QString s = lines()->getString(p.Line - 1);
|
||||||
|
int wordBegin;
|
||||||
|
int wordEnd = p.Char-1;
|
||||||
|
if (wordEnd >= s.length())
|
||||||
|
wordEnd = s.length()-1;
|
||||||
|
while (true) {
|
||||||
|
int bracketLevel=0;
|
||||||
|
bool skipNextWord=false;
|
||||||
|
while (wordEnd > 0) {
|
||||||
|
if (s[wordEnd] == '>'
|
||||||
|
|| s[wordEnd] == ']') {
|
||||||
|
bracketLevel++;
|
||||||
|
} else if (s[wordEnd] == '<'
|
||||||
|
|| s[wordEnd] == '[') {
|
||||||
|
bracketLevel--;
|
||||||
|
} else if (bracketLevel==0) {
|
||||||
|
//we can't differentiate multiple definition and function parameter define here , so we don't handle ','
|
||||||
|
if (s[wordEnd] == ',') {
|
||||||
|
if (inFunc) // in func, dont skip ','
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
skipNextWord=true;
|
||||||
|
} else if (s[wordEnd] != ' '
|
||||||
|
&& s[wordEnd] != '\t') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wordEnd--;
|
||||||
|
}
|
||||||
|
if (wordEnd<0)
|
||||||
|
return "";
|
||||||
|
if (bracketLevel > 0)
|
||||||
|
return "";
|
||||||
|
if (!isIdentChar(s[wordEnd]))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
wordBegin = wordEnd;
|
||||||
|
while ((wordBegin >= 0) && isIdentChar(s[wordBegin])) {
|
||||||
|
wordBegin--;
|
||||||
|
}
|
||||||
|
wordBegin++;
|
||||||
|
|
||||||
|
if (s[wordBegin]>='0' && s[wordBegin]<='9') // not valid word
|
||||||
|
return "";
|
||||||
|
|
||||||
|
result = s.mid(wordBegin, wordEnd - wordBegin+1);
|
||||||
|
if ((result != "const") && !skipNextWord)
|
||||||
|
break;
|
||||||
|
wordEnd = wordBegin-1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PCppParser &Editor::parser() const
|
const PCppParser &Editor::parser() const
|
||||||
|
|
|
@ -129,6 +129,7 @@ public:
|
||||||
BufferCoord& pWordBegin,
|
BufferCoord& pWordBegin,
|
||||||
BufferCoord& pWordEnd,
|
BufferCoord& pWordEnd,
|
||||||
WordPurpose purpose);
|
WordPurpose purpose);
|
||||||
|
QString getPreviousWordAtPositionForSuggestion(const BufferCoord& p);
|
||||||
|
|
||||||
const PCppParser &parser() const;
|
const PCppParser &parser() const;
|
||||||
|
|
||||||
|
@ -164,6 +165,8 @@ private:
|
||||||
void showCompletion(bool autoComplete);
|
void showCompletion(bool autoComplete);
|
||||||
void showHeaderCompletion(bool autoComplete);
|
void showHeaderCompletion(bool autoComplete);
|
||||||
|
|
||||||
|
bool testInFunc(int x,int y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int newfileCount;
|
static int newfileCount;
|
||||||
QByteArray mEncodingOption; // the encoding type set by the user
|
QByteArray mEncodingOption; // the encoding type set by the user
|
||||||
|
|
|
@ -541,3 +541,22 @@ void resetCppParser(std::shared_ptr<CppParser> parser)
|
||||||
}
|
}
|
||||||
parser->parseHardDefines();
|
parser->parseHardDefines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool findComplement(const QString &s, const QChar &fromToken, const QChar &toToken, int &curPos, int increment)
|
||||||
|
{
|
||||||
|
int curPosBackup = curPos;
|
||||||
|
int level = 0;
|
||||||
|
//todo: skip comment, char and strings
|
||||||
|
while ((curPos < s.length()) && (curPos >= 0)) {
|
||||||
|
if (s[curPos] == fromToken) {
|
||||||
|
level++;
|
||||||
|
} else if (s[curPos] == toToken) {
|
||||||
|
level--;
|
||||||
|
if (level == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
curPos += increment;
|
||||||
|
}
|
||||||
|
curPos = curPosBackup;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,12 @@ int compareFileModifiedTime(const QString& filename1, const QString& filename2);
|
||||||
|
|
||||||
void changeTheme(const QString& themeName);
|
void changeTheme(const QString& themeName);
|
||||||
|
|
||||||
|
bool findComplement(const QString& s,
|
||||||
|
const QChar& fromToken,
|
||||||
|
const QChar& toToken,
|
||||||
|
int& curPos,
|
||||||
|
int increment);
|
||||||
|
|
||||||
class CppParser;
|
class CppParser;
|
||||||
void resetCppParser(std::shared_ptr<CppParser> parser);
|
void resetCppParser(std::shared_ptr<CppParser> parser);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue