work save

This commit is contained in:
royqh1979@gmail.com 2021-08-26 11:58:29 +08:00
parent f3cc986c4e
commit bf4d12b89f
4 changed files with 302 additions and 156 deletions

View File

@ -1381,11 +1381,57 @@ void Editor::showHeaderCompletion(bool autoComplete)
//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 result = "";
QString s;
if ((p.Line >= 1) && (p.Line <= lines()->count())) {
if ((p.Line<1) || (p.Line>lines()->count())) {
pWordBegin = p;
pWordEnd = p;
return "";
}
s = lines()->getString(p.Line - 1);
int len = s.length();
@ -1395,7 +1441,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
// Copy forward until end of word
if (purpose == WordPurpose::wpEvaluation
|| purpose == WordPurpose::wpInformation) {
while (wordEnd + 1 < len) do {
while (wordEnd + 1 < len) {
if ((purpose == WordPurpose::wpEvaluation)
&& (s[wordEnd + 1] == '[')) {
if (!findComplement(s, '[', ']', wordEnd, 1))
@ -1434,7 +1480,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
}
// Copy backward until begin of path
if (purpose == wpHeaderCompletion) {
if (purpose == WordPurpose::wpHeaderCompletion) {
while ((wordBegin >= 0) && (wordBegin < len)) {
if (isIdentChar(s[wordBegin]))
wordBegin--;
@ -1451,7 +1497,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
if (purpose == WordPurpose::wpHeaderCompletionStart) {
while ((wordBegin >= 0) && (wordBegin < len)) {
if (s[wordBegin] == '"'
|| s[wordBegin] == '<']) {
|| s[wordBegin] == '<') {
wordBegin--;
break;
} else if (s[wordBegin] == '/'
@ -1465,16 +1511,17 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
}
}
// && ( wordBegin < len)
// Copy backward until begin of word
if (purpose == WordPurpose::wpCompletion
|| purpose == WordPurpose::wpEvaluation
|| purpose == WordPurpose::wpInformation) {
while ((wordBegin >= 0) && (wordBegin<len)) {
if (s[wordBegin] == ']') then {
if (s[wordBegin] == ']') {
if (!findComplement(s, ']', '[', wordBegin, -1))
break
break;
else
wordBegin++; // step over [
wordBegin++; // step over mathing [
} else if (isIdentChar(s[wordBegin])) {
wordBegin--;
} else if (s[wordBegin] == '.'
@ -1484,8 +1531,8 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
} else if (
(s[wordBegin] == '>')
&& (wordBegin+2<len)
&& (s[WordBegin+1]==':')
&& (s[WordBegin+2]==':')
&& (s[wordBegin+1]==':')
&& (s[wordBegin+2]==':')
) { // allow template
if (!findComplement(s, '>', '<', wordBegin, -1))
break;
@ -1501,15 +1548,14 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
wordBegin-=2;
} else if ((wordBegin > 0)
&& (s[wordBegin] == ')')) {
if (!findComplement(s, ')', '(', WordBegin, -1))
if (!findComplement(s, ')', '(', wordBegin, -1))
break;
else
wordBegin--; // step over (
wordBegin--; // step over mathing (
} else
break;
}
}
}
// Get end result
result = s.mid(wordBegin + 1, wordEnd - wordBegin);
@ -1517,62 +1563,134 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin,
pWordBegin.Char = wordBegin+1;
pWordEnd.Line = p.Line;
pWordEnd.Char = wordEnd;
if (!result.isEmpty() && (
result[0] in ['.','-'])
and (Purpose in [wpCompletion, wpEvaluation, wpInformation]) then begin
i:=WordBegin;
line:=p.Line;
while line>=1 do begin
while i>=1 do begin
if S[i] in [' ',#9] then
dec(i)
// last line still have part of word
if (!result.isEmpty()
&& (
result[0] == '.'
|| result[0] == '-')
&& (purpose == WordPurpose::wpCompletion
|| purpose == WordPurpose::wpEvaluation
|| purpose == WordPurpose::wpInformation)) {
int i = wordBegin;
int line=p.Line;
while (line>=1) {
while (i>=0) {
if (s[i] == ' '
|| s[i] == '\t')
i--;
else
break;
end;
if i<1 then begin
dec(line);
if (line>=1) then begin
S:=editor.Lines[line-1];
i:=Length(s);
}
if (i<0) {
line--;
if (line>=1) {
s=lines()->getString(line-1);
i=s.length();
continue;
end else
} else
break;
end else begin
HighlightPos.Line := line;
HighlightPos.Char := i+1;
Result := GetWordAtPosition(editor,highlightPos,pWordBegin,pDummy,Purpose)+Result;
} else {
BufferCoord highlightPos;
BufferCoord pDummy;
highlightPos.Line = line;
highlightPos.Char = i+1;
result = getWordAtPosition(highlightPos,pWordBegin,pDummy,purpose)+result;
break;
end;
end;
end;
}
}
}
// Strip function parameters
while true do begin
ParamBegin := Pos('(', Result);
if ParamBegin > 0 then begin
ParamEnd := ParamBegin;
if (ParamBegin=1) and FindComplement(Result, '(', ')', ParamEnd, 1)
and (ParamEnd = Length(Result)) then begin
Delete(Result,ParamEnd,1);
Delete(Result,ParamBegin,1);
int paramBegin,paramEnd;
while (true) {
paramBegin = result.indexOf('(');
if (paramBegin > 0) {
paramEnd = paramBegin;
if ((paramBegin==0)
&& findComplement(result, '(', ')', paramEnd, 1)
&& (paramEnd = result.length()-1) ) {
//remove the enclosing parenthese pair
result = result.mid(1,result.length()-2);
continue;
end else begin
ParamEnd := ParamBegin;
if FindComplement(Result, '(', ')', ParamEnd, 1) then begin
Delete(Result, ParamBegin, ParamEnd - ParamBegin + 1);
end else
} else {
paramEnd = paramBegin;
if (findComplement(result, '(', ')', paramEnd, 1)) {
result.remove(paramBegin, paramEnd - paramBegin + 1);
} else
break;
end;
end else
}
} else
break;
end;
}
ParamBegin := 1;
while (ParamBegin <= Length(Result)) and (Result[ParamBegin] = '*') do begin
inc(ParamBegin);
end;
Delete(Result,1,ParamBegin-1);
paramBegin = 0;
while ((paramBegin < result.length()) && (result[paramBegin] == '*')) {
paramBegin++;
}
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

View File

@ -129,6 +129,7 @@ public:
BufferCoord& pWordBegin,
BufferCoord& pWordEnd,
WordPurpose purpose);
QString getPreviousWordAtPositionForSuggestion(const BufferCoord& p);
const PCppParser &parser() const;
@ -164,6 +165,8 @@ private:
void showCompletion(bool autoComplete);
void showHeaderCompletion(bool autoComplete);
bool testInFunc(int x,int y);
private:
static int newfileCount;
QByteArray mEncodingOption; // the encoding type set by the user

View File

@ -541,3 +541,22 @@ void resetCppParser(std::shared_ptr<CppParser> parser)
}
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;
}

View File

@ -105,6 +105,12 @@ int compareFileModifiedTime(const QString& filename1, const QString& filename2);
void changeTheme(const QString& themeName);
bool findComplement(const QString& s,
const QChar& fromToken,
const QChar& toToken,
int& curPos,
int increment);
class CppParser;
void resetCppParser(std::shared_ptr<CppParser> parser);