* work save for symbol completion
This commit is contained in:
parent
ac0250c4fe
commit
0f59b1c665
|
@ -434,10 +434,20 @@ void Editor::onStatusChanged(SynStatusChanges changes)
|
||||||
// mainForm.CaretList.AddCaret(self,fText.CaretY,fText.CaretX);
|
// mainForm.CaretList.AddCaret(self,fText.CaretY,fText.CaretX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QChar Editor::getCurrentChar()
|
||||||
|
{
|
||||||
|
if (lineText().length()<caretX())
|
||||||
|
return QChar();
|
||||||
|
else
|
||||||
|
return lineText()[caretX()-1];
|
||||||
|
}
|
||||||
|
|
||||||
bool Editor::handleSymbolCompletion(QChar key)
|
bool Editor::handleSymbolCompletion(QChar key)
|
||||||
{
|
{
|
||||||
if (!pSettings->editor().completeSymbols() || selAvail())
|
if (!pSettings->editor().completeSymbols() || selAvail())
|
||||||
return false;
|
return false;
|
||||||
|
if (!insertMode())
|
||||||
|
return false;
|
||||||
|
|
||||||
//todo: better methods to detect current caret type
|
//todo: better methods to detect current caret type
|
||||||
if (caretX() <= 1) {
|
if (caretX() <= 1) {
|
||||||
|
@ -477,83 +487,265 @@ bool Editor::handleSymbolCompletion(QChar key)
|
||||||
switch(key.unicode()) {
|
switch(key.unicode()) {
|
||||||
case '(':
|
case '(':
|
||||||
if (pSettings->editor().completeParenthese()) {
|
if (pSettings->editor().completeParenthese()) {
|
||||||
handleParentheseCompletion();
|
return handleParentheseCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case ')':
|
case ')':
|
||||||
if (pSettings->editor().completeParenthese() && pSettings->editor().overwriteSymbols()) {
|
if (pSettings->editor().completeParenthese() && pSettings->editor().overwriteSymbols()) {
|
||||||
handleParentheseSkip();
|
return handleParentheseSkip();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '[':
|
case '[':
|
||||||
if (pSettings->editor().completeBracket()) {
|
if (pSettings->editor().completeBracket()) {
|
||||||
handleBracketCompletion();
|
return handleBracketCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case ']':
|
case ']':
|
||||||
if (pSettings->editor().completeBracket() && pSettings->editor().overwriteSymbols()) {
|
if (pSettings->editor().completeBracket() && pSettings->editor().overwriteSymbols()) {
|
||||||
HandleBracketSkip();
|
return handleBracketSkip();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '*':
|
case '*':
|
||||||
status = getQuoteState();
|
status = getQuoteStatus();
|
||||||
if (pSettings->editor().completeComment() && (status == QuoteStatus::NotQuote)) {
|
if (pSettings->editor().completeComment() && (status == QuoteStatus::NotQuote)) {
|
||||||
handleMultilineCommentCompletion();
|
return handleMultilineCommentCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '{':
|
case '{':
|
||||||
if (pSettings->editor().completeBrace()) {
|
if (pSettings->editor().completeBrace()) {
|
||||||
handleBraceCompletion();
|
return handleBraceCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '}':
|
case '}':
|
||||||
if (pSettings->editor().completeBrace() && pSettings->editor().overwriteSymbols()) {
|
if (pSettings->editor().completeBrace() && pSettings->editor().overwriteSymbols()) {
|
||||||
handleBraceSkip();
|
return handleBraceSkip();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '\'':
|
case '\'':
|
||||||
if (pSettings->editor().completeSingleQuote()) {
|
if (pSettings->editor().completeSingleQuote()) {
|
||||||
handleSingleQuoteCompletion();
|
return handleSingleQuoteCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '\"':
|
case '\"':
|
||||||
if (pSettings->editor().completeDoubleQuote()) {
|
if (pSettings->editor().completeDoubleQuote()) {
|
||||||
handleDoubleQuoteCompletion();
|
return handleDoubleQuoteCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '<':
|
case '<':
|
||||||
if (pSettings->editor().completeGlobalInclude()) { // #include <>
|
if (pSettings->editor().completeGlobalInclude()) { // #include <>
|
||||||
handleGlobalIncludeCompletion();
|
return handleGlobalIncludeCompletion();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case '>':
|
case '>':
|
||||||
if (pSettings->editor().completeGlobalInclude() && pSettings->editor().overwriteSymbols()) { // #include <>
|
if (pSettings->editor().completeGlobalInclude() && pSettings->editor().overwriteSymbols()) { // #include <>
|
||||||
handleGlobalIncludeSkip();
|
return handleGlobalIncludeSkip();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::handleParentheseCompletion()
|
bool Editor::handleParentheseCompletion()
|
||||||
{
|
{
|
||||||
status := GetQuoteState;
|
QuoteStatus status = getQuoteStatus();
|
||||||
if (status in [RawString,NotQuote]) then begin
|
if (status == QuoteStatus::RawString || status == QuoteStatus::NotQuote) {
|
||||||
InsertString(')', false);
|
beginUpdate();
|
||||||
end;
|
CommandProcessor(SynEditorCommand::ecChar,'(');
|
||||||
if (status=NotQuote) and FunctionTipAllowed then
|
BufferCoord oldCaret = caretXY();
|
||||||
fFunctionTip.Activated := true;
|
CommandProcessor(SynEditorCommand::ecChar,')');
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// if (status == QuoteStatus::NotQuote) && FunctionTipAllowed then
|
||||||
|
// fFunctionTip.Activated := true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleParentheseSkip()
|
||||||
|
{
|
||||||
|
if (getCurrentChar() != ')')
|
||||||
|
return false;
|
||||||
|
QuoteStatus status = getQuoteStatus();
|
||||||
|
if (status == QuoteStatus::RawStringNoEscape) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (status != QuoteStatus::NotQuote)
|
||||||
|
return false;
|
||||||
|
BufferCoord pos = getMatchingBracket();
|
||||||
|
if (pos.Line != 0) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// if FunctionTipAllowed then
|
||||||
|
// fFunctionTip.Activated := false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleBracketCompletion()
|
||||||
|
{
|
||||||
|
// QuoteStatus status = getQuoteStatus();
|
||||||
|
// if (status == QuoteStatus::RawString || status == QuoteStatus::NotQuote) {
|
||||||
|
beginUpdate();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'[');
|
||||||
|
BufferCoord oldCaret = caretXY();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,']');
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleBracketSkip()
|
||||||
|
{
|
||||||
|
if (getCurrentChar() != ']')
|
||||||
|
return false;
|
||||||
|
BufferCoord pos = getMatchingBracket();
|
||||||
|
if (pos.Line != 0) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleMultilineCommentCompletion()
|
||||||
|
{
|
||||||
|
if (((caretX() > 1) && (caretX()-1 < lineText().length())) && (lineText()[caretX() - 1] == '/')) {
|
||||||
|
beginUpdate();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'*');
|
||||||
|
BufferCoord oldCaret = caretXY();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'*');
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'/');
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleBraceCompletion()
|
||||||
|
{
|
||||||
|
QString s = lineText().trimmed();
|
||||||
|
int i= caretY()-2;
|
||||||
|
while ((s.isEmpty()) && (i>=0)) {
|
||||||
|
s=lines()->getString(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
beginUpdate();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'{');
|
||||||
|
BufferCoord oldCaret = caretXY();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'}');
|
||||||
|
if (
|
||||||
|
( (s.startsWith("struct")
|
||||||
|
|| s.startsWith("class")
|
||||||
|
|| s.startsWith("union")
|
||||||
|
|| s.startsWith("typedef")
|
||||||
|
|| s.startsWith("public")
|
||||||
|
|| s.startsWith("private")
|
||||||
|
|| s.startsWith("enum") )
|
||||||
|
&& !s.contains(';')
|
||||||
|
) || s.endsWith('=')) {
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,';');
|
||||||
|
}
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleBraceSkip()
|
||||||
|
{
|
||||||
|
if (getCurrentChar() != '}')
|
||||||
|
return false;
|
||||||
|
BufferCoord pos = getMatchingBracket();
|
||||||
|
if (pos.Line != 0) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleSingleQuoteCompletion()
|
||||||
|
{
|
||||||
|
QuoteStatus status = getQuoteStatus();
|
||||||
|
QChar ch = getCurrentChar();
|
||||||
|
if (ch == '\'') {
|
||||||
|
if (status == QuoteStatus::SingleQuote) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (status == QuoteStatus::NotQuote) {
|
||||||
|
if (highlighter()->isWordBreakChar(ch) || highlighter()->isSpaceChar(ch)) {
|
||||||
|
// insert ''
|
||||||
|
beginUpdate();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'\'');
|
||||||
|
BufferCoord oldCaret = caretXY();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'\'');
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleDoubleQuoteCompletion()
|
||||||
|
{
|
||||||
|
QuoteStatus status = getQuoteStatus();
|
||||||
|
QChar ch = getCurrentChar();
|
||||||
|
if (ch == '"') {
|
||||||
|
if (status == QuoteStatus::DoubleQuote && status == QuoteStatus::RawString) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (status == QuoteStatus::NotQuote) {
|
||||||
|
if (highlighter()->isWordBreakChar(ch) || highlighter()->isSpaceChar(ch)) {
|
||||||
|
// insert ""
|
||||||
|
beginUpdate();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'"');
|
||||||
|
BufferCoord oldCaret = caretXY();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'"');
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleGlobalIncludeCompletion()
|
||||||
|
{
|
||||||
|
if (!lineText().startsWith('#'))
|
||||||
|
return false;
|
||||||
|
QString s= lineText().mid(1).trimmed();
|
||||||
|
if (!s.startsWith("include")) //it's not #include
|
||||||
|
return false;
|
||||||
|
beginUpdate();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'<');
|
||||||
|
BufferCoord oldCaret = caretXY();
|
||||||
|
CommandProcessor(SynEditorCommand::ecChar,'>');
|
||||||
|
setCaretXY(oldCaret);
|
||||||
|
endUpdate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::handleGlobalIncludeSkip()
|
||||||
|
{
|
||||||
|
if (getCurrentChar()!='>')
|
||||||
|
return false;
|
||||||
|
QString s= lineText().mid(1).trimmed();
|
||||||
|
if (!s.startsWith("include")) //it's not #include
|
||||||
|
return false;
|
||||||
|
BufferCoord pos = getMatchingBracket();
|
||||||
|
if (pos.Line != 0) {
|
||||||
|
setCaretXY( BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Editor::QuoteStatus Editor::getQuoteStatus()
|
Editor::QuoteStatus Editor::getQuoteStatus()
|
||||||
|
@ -563,62 +755,105 @@ Editor::QuoteStatus Editor::getQuoteStatus()
|
||||||
Result = QuoteStatus::DoubleQuote;
|
Result = QuoteStatus::DoubleQuote;
|
||||||
|
|
||||||
QString Line = lines()->getString(caretY()-1);
|
QString Line = lines()->getString(caretY()-1);
|
||||||
int posX =fText.CaretX-1;
|
int posX = caretX()-1;
|
||||||
if posX > Length(Line) then begin
|
if (posX >= Line.length()) {
|
||||||
posX := Length(Line);
|
posX = Line.length()-1;
|
||||||
end;
|
}
|
||||||
i:=1;
|
for (int i=0; i<=posX;i++) {
|
||||||
while (i<=posX) do begin
|
if (i+1<Line.length() && (Line[i] == 'R') && (Line[i+1] == '"') && (Result == QuoteStatus::NotQuote)) {
|
||||||
if (Line[i] = 'R') and (Line[i+1] = '"') and (Result = NotQuote) then begin
|
Result = QuoteStatus::RawString;
|
||||||
Result := RawString;
|
i++; // skip R
|
||||||
inc(i); // skip R
|
} else if (Line[i] == '(') {
|
||||||
end else if Line[i] = '(' then begin
|
switch(Result) {
|
||||||
Case Result of
|
case QuoteStatus::RawString:
|
||||||
RawString: Result:=RawStringNoEscape;
|
Result=QuoteStatus::RawStringNoEscape;
|
||||||
//RawStringNoEscape: do nothing
|
break;
|
||||||
end
|
//case RawStringNoEscape: do nothing
|
||||||
end else if Line[i] = ')' then begin
|
}
|
||||||
Case Result of
|
} else if (Line[i] == ')') {
|
||||||
RawStringNoEscape: Result:=RawString;
|
switch(Result) {
|
||||||
end
|
case QuoteStatus::RawStringNoEscape:
|
||||||
end else if Line[i] = '"' then begin
|
Result=QuoteStatus::RawString;
|
||||||
Case Result of
|
break;
|
||||||
NotQuote: Result := DoubleQuote;
|
}
|
||||||
SingleQuote: Result := SingleQuote;
|
} else if (Line[i] == '"') {
|
||||||
SingleQuoteEscape: Result := SingleQuote;
|
switch(Result) {
|
||||||
DoubleQuote: Result := NotQuote;
|
case QuoteStatus::NotQuote:
|
||||||
DoubleQuoteEscape: Result := DoubleQuote;
|
Result = QuoteStatus::DoubleQuote;
|
||||||
RawString: Result:=NotQuote;
|
break;
|
||||||
//RawStringNoEscape: do nothing
|
case QuoteStatus::SingleQuote:
|
||||||
end
|
Result = QuoteStatus::SingleQuote;
|
||||||
end else if Line[i] = '''' then
|
break;
|
||||||
Case Result of
|
case QuoteStatus::SingleQuoteEscape:
|
||||||
NotQuote: Result := SingleQuote;
|
Result = QuoteStatus::SingleQuote;
|
||||||
SingleQuote: Result := NotQuote;
|
break;
|
||||||
SingleQuoteEscape: Result := SingleQuote;
|
case QuoteStatus::DoubleQuote:
|
||||||
DoubleQuote: Result := DoubleQuote;
|
Result = QuoteStatus::NotQuote;
|
||||||
DoubleQuoteEscape: Result := DoubleQuote;
|
break;
|
||||||
end
|
case QuoteStatus::DoubleQuoteEscape:
|
||||||
else if Line[i] = '\' then
|
Result = QuoteStatus::DoubleQuote;
|
||||||
Case Result of
|
break;
|
||||||
NotQuote: Result := NotQuote;
|
case QuoteStatus::RawString:
|
||||||
SingleQuote: Result := SingleQuoteEscape;
|
Result=QuoteStatus::NotQuote;
|
||||||
SingleQuoteEscape: Result := SingleQuote;
|
break;
|
||||||
DoubleQuote: Result := DoubleQuoteEscape;
|
//RawStringNoEscape: do nothing
|
||||||
DoubleQuoteEscape: Result := DoubleQuote;
|
}
|
||||||
end
|
} else if (Line[i] == '\'') {
|
||||||
else begin
|
switch(Result) {
|
||||||
Case Result of
|
case QuoteStatus::NotQuote:
|
||||||
NotQuote: Result := NotQuote;
|
Result = QuoteStatus::SingleQuote;
|
||||||
SingleQuote: Result := SingleQuote;
|
break;
|
||||||
SingleQuoteEscape: Result := SingleQuote;
|
case QuoteStatus::SingleQuote:
|
||||||
DoubleQuote: Result := DoubleQuote;
|
Result = QuoteStatus::NotQuote;
|
||||||
DoubleQuoteEscape: Result := DoubleQuote;
|
break;
|
||||||
end;
|
case QuoteStatus::SingleQuoteEscape:
|
||||||
end;
|
Result = QuoteStatus::SingleQuote;
|
||||||
inc(i);
|
break;
|
||||||
end;
|
case QuoteStatus::DoubleQuote:
|
||||||
end;
|
Result = QuoteStatus::DoubleQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::DoubleQuoteEscape:
|
||||||
|
Result = QuoteStatus::DoubleQuote;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (Line[i] == '\\') {
|
||||||
|
switch(Result) {
|
||||||
|
case QuoteStatus::NotQuote:
|
||||||
|
Result = QuoteStatus::NotQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::SingleQuote:
|
||||||
|
Result = QuoteStatus::SingleQuoteEscape;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::SingleQuoteEscape:
|
||||||
|
Result = QuoteStatus::SingleQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::DoubleQuote:
|
||||||
|
Result = QuoteStatus::DoubleQuoteEscape;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::DoubleQuoteEscape:
|
||||||
|
Result = QuoteStatus::DoubleQuote;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(Result) {
|
||||||
|
case QuoteStatus::NotQuote:
|
||||||
|
Result = QuoteStatus::NotQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::SingleQuote:
|
||||||
|
Result = QuoteStatus::SingleQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::SingleQuoteEscape:
|
||||||
|
Result = QuoteStatus::SingleQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::DoubleQuote:
|
||||||
|
Result = QuoteStatus::DoubleQuote;
|
||||||
|
break;
|
||||||
|
case QuoteStatus::DoubleQuoteEscape:
|
||||||
|
Result = QuoteStatus::DoubleQuote;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,8 +90,19 @@ protected slots:
|
||||||
void onStatusChanged(SynStatusChanges changes);
|
void onStatusChanged(SynStatusChanges changes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QChar getCurrentChar();
|
||||||
bool handleSymbolCompletion(QChar key);
|
bool handleSymbolCompletion(QChar key);
|
||||||
void handleParentheseCompletion();
|
bool handleParentheseCompletion();
|
||||||
|
bool handleParentheseSkip();
|
||||||
|
bool handleBracketCompletion();
|
||||||
|
bool handleBracketSkip();
|
||||||
|
bool handleMultilineCommentCompletion();
|
||||||
|
bool handleBraceCompletion();
|
||||||
|
bool handleBraceSkip();
|
||||||
|
bool handleSingleQuoteCompletion();
|
||||||
|
bool handleDoubleQuoteCompletion();
|
||||||
|
bool handleGlobalIncludeCompletion();
|
||||||
|
bool handleGlobalIncludeSkip();
|
||||||
QuoteStatus getQuoteStatus();
|
QuoteStatus getQuoteStatus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -273,7 +273,6 @@ void SynEdit::setCaretXYCentered(bool ForceToMiddle, const BufferCoord &value)
|
||||||
mBlockEnd = mBlockBegin;
|
mBlockEnd = mBlockBegin;
|
||||||
if (ForceToMiddle)
|
if (ForceToMiddle)
|
||||||
ensureCursorPosVisibleEx(true); // but here after block has been set
|
ensureCursorPosVisibleEx(true); // but here after block has been set
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynEdit::setInsertMode(bool value)
|
void SynEdit::setInsertMode(bool value)
|
||||||
|
@ -395,6 +394,130 @@ bool SynEdit::GetHighlighterAttriAtRowColEx(const BufferCoord &XY, QString &Toke
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SynEdit::beginUpdate()
|
||||||
|
{
|
||||||
|
incPaintLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SynEdit::endUpdate()
|
||||||
|
{
|
||||||
|
decPaintLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferCoord SynEdit::getMatchingBracket()
|
||||||
|
{
|
||||||
|
return getMatchingBracketEx(caretXY());
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferCoord SynEdit::getMatchingBracketEx(BufferCoord APoint)
|
||||||
|
{
|
||||||
|
QChar Brackets[] = {'(', ')', '[', ']', '{', '}', '<', '>'};
|
||||||
|
QString Line;
|
||||||
|
int i, PosX, PosY, Len;
|
||||||
|
QChar Test, BracketInc, BracketDec;
|
||||||
|
int NumBrackets;
|
||||||
|
QString vDummy;
|
||||||
|
PSynHighlighterAttribute attr;
|
||||||
|
BufferCoord p;
|
||||||
|
bool isCommentOrStringOrChar;
|
||||||
|
int nBrackets = sizeof(Brackets) / sizeof(QChar);
|
||||||
|
|
||||||
|
if (mLines->count()<1)
|
||||||
|
return BufferCoord{0,0};
|
||||||
|
if (!mHighlighter)
|
||||||
|
return BufferCoord{0,0};
|
||||||
|
// get char at caret
|
||||||
|
PosX = std::max(APoint.Char,1);
|
||||||
|
PosY = std::max(APoint.Line,1);
|
||||||
|
Line = mLines->getString(APoint.Line - 1);
|
||||||
|
if (Line.length() >= PosX ) {
|
||||||
|
Test = Line[PosX-1];
|
||||||
|
// is it one of the recognized brackets?
|
||||||
|
for (i = 0; i<nBrackets; i++) {
|
||||||
|
if (Test == Brackets[i]) {
|
||||||
|
// this is the bracket, get the matching one and the direction
|
||||||
|
BracketInc = Brackets[i];
|
||||||
|
BracketDec = Brackets[i xor 1]; // 0 -> 1, 1 -> 0, ...
|
||||||
|
// search for the matching bracket (that is until NumBrackets = 0)
|
||||||
|
NumBrackets = 1;
|
||||||
|
if (i%2==1) {
|
||||||
|
do {
|
||||||
|
// search until start of line
|
||||||
|
while (PosX > 1) {
|
||||||
|
PosX--;
|
||||||
|
Test = Line[PosX-1];
|
||||||
|
p.Char = PosX;
|
||||||
|
p.Line = PosY;
|
||||||
|
if ((Test == BracketInc) || (Test == BracketDec)) {
|
||||||
|
if (GetHighlighterAttriAtRowCol(p, vDummy, attr))
|
||||||
|
isCommentOrStringOrChar =
|
||||||
|
(attr == mHighlighter->stringAttribute()) ||
|
||||||
|
(attr == mHighlighter->commentAttribute()) ||
|
||||||
|
(attr->name() == SYNS_AttrCharacter);
|
||||||
|
else
|
||||||
|
isCommentOrStringOrChar = false;
|
||||||
|
if ((Test == BracketInc) && (!isCommentOrStringOrChar))
|
||||||
|
NumBrackets++;
|
||||||
|
else if ((Test == BracketDec) && (!isCommentOrStringOrChar)) {
|
||||||
|
NumBrackets--;
|
||||||
|
if (NumBrackets == 0) {
|
||||||
|
// matching bracket found, set caret and bail out
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get previous line if possible
|
||||||
|
if (PosY == 1)
|
||||||
|
break;
|
||||||
|
PosY--;
|
||||||
|
Line = mLines->getString(PosY - 1);
|
||||||
|
PosX = Line.length() + 1;
|
||||||
|
} while (true);
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
// search until end of line
|
||||||
|
Len = Line.length();
|
||||||
|
while (PosX < Len) {
|
||||||
|
PosX++;
|
||||||
|
Test = Line[PosX-1];
|
||||||
|
p.Char = PosX;
|
||||||
|
p.Line = PosY;
|
||||||
|
if ((Test == BracketInc) || (Test == BracketDec)) {
|
||||||
|
if (GetHighlighterAttriAtRowCol(p, vDummy, attr))
|
||||||
|
isCommentOrStringOrChar =
|
||||||
|
(attr == mHighlighter->stringAttribute()) ||
|
||||||
|
(attr == mHighlighter->commentAttribute()) ||
|
||||||
|
(attr->name() == SYNS_AttrCharacter);
|
||||||
|
else
|
||||||
|
isCommentOrStringOrChar = false;
|
||||||
|
if ((Test == BracketInc) && (!isCommentOrStringOrChar))
|
||||||
|
NumBrackets++;
|
||||||
|
else if ((Test == BracketDec) && (!isCommentOrStringOrChar)) {
|
||||||
|
NumBrackets--;
|
||||||
|
if (NumBrackets == 0) {
|
||||||
|
// matching bracket found, set caret and bail out
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get next line if possible
|
||||||
|
if (PosY == mLines->count())
|
||||||
|
break;
|
||||||
|
PosY++;
|
||||||
|
Line = mLines->getString(PosY - 1);
|
||||||
|
PosX = 0;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
// don't test the other brackets, we're done
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BufferCoord{0,0};
|
||||||
|
}
|
||||||
|
|
||||||
void SynEdit::invalidateGutter()
|
void SynEdit::invalidateGutter()
|
||||||
{
|
{
|
||||||
invalidateGutterLines(-1, -1);
|
invalidateGutterLines(-1, -1);
|
||||||
|
|
|
@ -234,6 +234,11 @@ public:
|
||||||
virtual void untab() { CommandProcessor(SynEditorCommand::ecShiftTab);}
|
virtual void untab() { CommandProcessor(SynEditorCommand::ecShiftTab);}
|
||||||
virtual void toggleComment() { CommandProcessor(SynEditorCommand::ecToggleComment);}
|
virtual void toggleComment() { CommandProcessor(SynEditorCommand::ecToggleComment);}
|
||||||
|
|
||||||
|
virtual void beginUpdate();
|
||||||
|
virtual void endUpdate();
|
||||||
|
virtual BufferCoord getMatchingBracket();
|
||||||
|
virtual BufferCoord getMatchingBracketEx(BufferCoord APoint);
|
||||||
|
|
||||||
|
|
||||||
// setter && getters
|
// setter && getters
|
||||||
int topLine() const;
|
int topLine() const;
|
||||||
|
|
|
@ -84,6 +84,40 @@ bool SynHighlighter::isSpaceChar(const QChar &ch)
|
||||||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
|
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SynHighlighter::isWordBreakChar(const QChar &ch)
|
||||||
|
{
|
||||||
|
switch (ch.unicode()) {
|
||||||
|
case '.':
|
||||||
|
case ',':
|
||||||
|
case ';':
|
||||||
|
case ':':
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
case '!':
|
||||||
|
case '?':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '^':
|
||||||
|
case '|':
|
||||||
|
case '&':
|
||||||
|
case '-':
|
||||||
|
case '=':
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
case '/':
|
||||||
|
case '\\':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SynHighlighter::isIdentChar(const QChar &ch) const
|
bool SynHighlighter::isIdentChar(const QChar &ch) const
|
||||||
{
|
{
|
||||||
if (ch == '_') {
|
if (ch == '_') {
|
||||||
|
|
|
@ -108,7 +108,8 @@ public:
|
||||||
virtual QString languageName() = 0;
|
virtual QString languageName() = 0;
|
||||||
virtual SynHighlighterLanguage language() = 0;
|
virtual SynHighlighterLanguage language() = 0;
|
||||||
|
|
||||||
static bool isSpaceChar(const QChar& ch);
|
virtual bool isSpaceChar(const QChar& ch);
|
||||||
|
virtual bool isWordBreakChar(const QChar& ch);
|
||||||
bool enabled() const;
|
bool enabled() const;
|
||||||
void setEnabled(bool value);
|
void setEnabled(bool value);
|
||||||
|
|
||||||
|
|
|
@ -1271,6 +1271,7 @@ void Settings::CompilerSet::setProperties(const QString &binDir)
|
||||||
addExistingDirectory(mCppIncludeDirs, includeTrailingPathDelimiter(folder) + "include");
|
addExistingDirectory(mCppIncludeDirs, includeTrailingPathDelimiter(folder) + "include");
|
||||||
|
|
||||||
// Find default directories
|
// Find default directories
|
||||||
|
// C include dirs
|
||||||
arguments.clear();
|
arguments.clear();
|
||||||
arguments.append("-xc");
|
arguments.append("-xc");
|
||||||
arguments.append("-v");
|
arguments.append("-v");
|
||||||
|
@ -1278,7 +1279,7 @@ void Settings::CompilerSet::setProperties(const QString &binDir)
|
||||||
arguments.append(NULL_FILE);
|
arguments.append(NULL_FILE);
|
||||||
output = getCompilerOutput(binDir,GCC_PROGRAM,arguments);
|
output = getCompilerOutput(binDir,GCC_PROGRAM,arguments);
|
||||||
|
|
||||||
// C include dirs
|
|
||||||
delimPos1 = output.indexOf("#include <...> search starts here:");
|
delimPos1 = output.indexOf("#include <...> search starts here:");
|
||||||
delimPos2 = output.indexOf("End of search list.");
|
delimPos2 = output.indexOf("End of search list.");
|
||||||
if (delimPos1 >0 && delimPos2>0 ) {
|
if (delimPos1 >0 && delimPos2>0 ) {
|
||||||
|
@ -1291,35 +1292,9 @@ void Settings::CompilerSet::setProperties(const QString &binDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// bin dirs
|
|
||||||
targetStr = QByteArray("COMPILER_PATH=");
|
|
||||||
delimPos1 = output.indexOf(targetStr);
|
|
||||||
if (delimPos1>=0) {
|
|
||||||
delimPos1+=targetStr.length();
|
|
||||||
delimPos2 = delimPos1;
|
|
||||||
while (delimPos2 < output.length() && output[delimPos2]!='\n')
|
|
||||||
delimPos2+=1;
|
|
||||||
QList<QByteArray> lines = output.mid(delimPos1,delimPos2-delimPos1).split(';');
|
|
||||||
for (QByteArray& line:lines) {
|
|
||||||
QByteArray trimmedLine = line.trimmed();
|
|
||||||
addExistingDirectory(mBinDirs,trimmedLine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// lib dirs
|
|
||||||
targetStr = QByteArray("LIBRARY_PATH=");
|
|
||||||
delimPos1 = output.indexOf(targetStr);
|
|
||||||
if (delimPos1>=0) {
|
|
||||||
delimPos1+=targetStr.length();
|
|
||||||
delimPos2 = delimPos1;
|
|
||||||
while (delimPos2 < output.length() && output[delimPos2]!='\n')
|
|
||||||
delimPos2+=1;
|
|
||||||
QList<QByteArray> lines = output.mid(delimPos1,delimPos2-delimPos1).split(';');
|
|
||||||
for (QByteArray& line:lines) {
|
|
||||||
QByteArray trimmedLine = line.trimmed();
|
|
||||||
addExistingDirectory(mLibDirs,trimmedLine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Find default directories
|
||||||
|
// C++ include dirs
|
||||||
arguments.clear();
|
arguments.clear();
|
||||||
arguments.append("-xc++");
|
arguments.append("-xc++");
|
||||||
arguments.append("-E");
|
arguments.append("-E");
|
||||||
|
@ -1328,7 +1303,6 @@ void Settings::CompilerSet::setProperties(const QString &binDir)
|
||||||
output = getCompilerOutput(binDir,GCC_PROGRAM,arguments);
|
output = getCompilerOutput(binDir,GCC_PROGRAM,arguments);
|
||||||
//gcc -xc++ -E -v NUL
|
//gcc -xc++ -E -v NUL
|
||||||
|
|
||||||
// C include dirs
|
|
||||||
delimPos1 = output.indexOf("#include <...> search starts here:");
|
delimPos1 = output.indexOf("#include <...> search starts here:");
|
||||||
delimPos2 = output.indexOf("End of search list.");
|
delimPos2 = output.indexOf("End of search list.");
|
||||||
if (delimPos1 >0 && delimPos2>0 ) {
|
if (delimPos1 >0 && delimPos2>0 ) {
|
||||||
|
@ -1342,6 +1316,41 @@ void Settings::CompilerSet::setProperties(const QString &binDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find default directories
|
||||||
|
arguments.clear();
|
||||||
|
arguments.append("-print-search-dirs");
|
||||||
|
arguments.append(NULL_FILE);
|
||||||
|
output = getCompilerOutput(binDir,GCC_PROGRAM,arguments);
|
||||||
|
// bin dirs
|
||||||
|
targetStr = QByteArray("programs: =");
|
||||||
|
delimPos1 = output.indexOf(targetStr);
|
||||||
|
if (delimPos1>=0) {
|
||||||
|
delimPos1+=targetStr.length();
|
||||||
|
delimPos2 = delimPos1;
|
||||||
|
while (delimPos2 < output.length() && output[delimPos2]!='\n')
|
||||||
|
delimPos2+=1;
|
||||||
|
QList<QByteArray> lines = output.mid(delimPos1,delimPos2-delimPos1).split(';');
|
||||||
|
for (QByteArray& line:lines) {
|
||||||
|
QByteArray trimmedLine = line.trimmed();
|
||||||
|
if (!trimmedLine.isEmpty())
|
||||||
|
addExistingDirectory(mBinDirs,trimmedLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// lib dirs
|
||||||
|
targetStr = QByteArray("libraries: =");
|
||||||
|
delimPos1 = output.indexOf(targetStr);
|
||||||
|
if (delimPos1>=0) {
|
||||||
|
delimPos1+=targetStr.length();
|
||||||
|
delimPos2 = delimPos1;
|
||||||
|
while (delimPos2 < output.length() && output[delimPos2]!='\n')
|
||||||
|
delimPos2+=1;
|
||||||
|
QList<QByteArray> lines = output.mid(delimPos1,delimPos2-delimPos1).split(';');
|
||||||
|
for (QByteArray& line:lines) {
|
||||||
|
QByteArray trimmedLine = line.trimmed();
|
||||||
|
if (!trimmedLine.isEmpty())
|
||||||
|
addExistingDirectory(mLibDirs,trimmedLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::CompilerSet::setDefines() {
|
void Settings::CompilerSet::setDefines() {
|
||||||
|
|
Loading…
Reference in New Issue