- implement: user code snippet / template
- implement: auto generate javadoc-style docstring for functions - enhancement: use up/down key to navigate function parameter tooltip - enhancement: press esc to close function parameter tooltip
This commit is contained in:
parent
ae9c90236f
commit
237e86cea0
6
NEWS.md
6
NEWS.md
|
@ -1,4 +1,4 @@
|
||||||
Version 0.2.2
|
Version 0.3.0
|
||||||
- enhancement: support C++ using type alias;
|
- enhancement: support C++ using type alias;
|
||||||
- fix: when press shift, completion popu window will hide
|
- fix: when press shift, completion popu window will hide
|
||||||
- enhancement: options in debugger setting widget, to skip system/project/custom header&project files when step into
|
- enhancement: options in debugger setting widget, to skip system/project/custom header&project files when step into
|
||||||
|
@ -16,6 +16,10 @@ Version 0.2.2
|
||||||
- implement: search in project
|
- implement: search in project
|
||||||
- enhancement: view memory when debugging
|
- enhancement: view memory when debugging
|
||||||
- implement: symbol usage count
|
- implement: symbol usage count
|
||||||
|
- implement: user code snippet / template
|
||||||
|
- implement: auto generate javadoc-style docstring for functions
|
||||||
|
- enhancement: use up/down key to navigate function parameter tooltip
|
||||||
|
- enhancement: press esc to close function parameter tooltip
|
||||||
|
|
||||||
Version 0.2.1
|
Version 0.2.1
|
||||||
- fix: crash when load last opens
|
- fix: crash when load last opens
|
||||||
|
|
|
@ -510,52 +510,107 @@ void Editor::keyPressEvent(QKeyEvent *event)
|
||||||
setSelText("");
|
setSelText("");
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
QStringList params;
|
|
||||||
QStringList insertString;
|
QStringList insertString;
|
||||||
insertString.append("");
|
insertString.append("");
|
||||||
bool isVoid;
|
PStatement function = mParser->findFunctionAt(mFilename,caretY()+1);
|
||||||
QString funcName = mParser->FindFunctionDoc(mFilename,
|
if (function) {
|
||||||
caretY()+1,
|
QStringList params;
|
||||||
params,isVoid);
|
QString funcName = function->command;
|
||||||
if funcName <> '' then begin
|
bool isVoid = (function->type == "void");
|
||||||
insertString.Add(' * @brief '+USER_CODE_IN_INSERT_POS);
|
foreach (const PStatement& child, function->children) {
|
||||||
insertString.Add(' * ');
|
if (child->kind == StatementKind::skParameter)
|
||||||
for i:=0 to params.Count-1 do begin
|
params.append(child->command);
|
||||||
insertString.Add(' * @param '+params[i]+' '+USER_CODE_IN_INSERT_POS);
|
}
|
||||||
end;
|
insertString.append(QString(" * @brief ")+USER_CODE_IN_INSERT_POS);
|
||||||
if not isVoid then begin
|
insertString.append(" * ");
|
||||||
insertString.Add(' * ');
|
foreach (const QString& param, params) {
|
||||||
insertString.Add(' * @return '+USER_CODE_IN_INSERT_POS);
|
insertString.append(QString(" * @param %1 %2")
|
||||||
end;
|
.arg(param, USER_CODE_IN_INSERT_POS));
|
||||||
insertString.Add(' **/');
|
}
|
||||||
end else begin
|
if (!isVoid) {
|
||||||
insertString.Add(' * '+USER_CODE_IN_INSERT_POS);
|
insertString.append(" * ");
|
||||||
insertString.Add(' **/');
|
insertString.append(QString(" * @return ")+USER_CODE_IN_INSERT_POS);
|
||||||
end;
|
}
|
||||||
InsertUserCodeIn(insertString.Text);
|
insertString.append(" **/");
|
||||||
|
} else {
|
||||||
end else if fText.Highlighter.GetIsLastLineCommentNotFinish(fText.Lines.Ranges[fText.CaretY-2]) then
|
insertString.append(QString(" * ")+USER_CODE_IN_INSERT_POS);
|
||||||
s:=trimLeft(fText.LineText);
|
insertString.append(" **/");
|
||||||
if StartsStr('* ',s) then begin
|
}
|
||||||
Key:=0;
|
insertCodeSnippet(LinesToText(insertString));
|
||||||
s:=#13#10+'* ';
|
} else if (highlighter()
|
||||||
self.insertString(s,false);
|
&& caretY()>=2
|
||||||
p:=fText.CaretXY;
|
&& highlighter()->isLastLineCommentNotFinished(
|
||||||
inc(p.Line);
|
lines()->ranges(caretY()-2).state)) {
|
||||||
p.Char := length(fText.Lines[p.Line-1])+1;
|
s=TrimLeft(lineText());
|
||||||
fText.CaretXY := p;
|
if (s.startsWith("* ")) {
|
||||||
end;
|
handled = true;
|
||||||
end;
|
s+=lineBreak()+"* ";
|
||||||
end;
|
insertString(s,false);
|
||||||
|
BufferCoord p = caretXY();
|
||||||
|
p.Line++;
|
||||||
|
p.Char = lines()->getString(p.Line-1).length()+1;
|
||||||
|
setCaretXY(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case Qt::Key_Escape: // Update function tip
|
||||||
|
mLastIdCharPressed = 0;
|
||||||
|
if (mTabStopBegin>=0) {
|
||||||
|
mTabStopBegin = -1;
|
||||||
|
invalidateLine(caretY());
|
||||||
|
clearUserCodeInTabStops();
|
||||||
|
}
|
||||||
|
pMainWindow->functionTip()->hide();
|
||||||
|
return;
|
||||||
|
case Qt::Key_Tab:
|
||||||
|
if (mUserCodeInTabStops.count()>0) {
|
||||||
|
handled = true;
|
||||||
|
int oldLine = caretY();
|
||||||
|
popUserCodeInTabStops();
|
||||||
|
if (oldLine!=caretY()) {
|
||||||
|
invalidateLine(oldLine);
|
||||||
|
}
|
||||||
|
invalidateLine(caretY());
|
||||||
|
} else {
|
||||||
|
if (mTabStopBegin >= 0) {
|
||||||
|
handled = true;
|
||||||
|
mTabStopBegin = -1;
|
||||||
|
invalidateLine(caretY());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case Qt::Key_Up:
|
||||||
|
if (pMainWindow->functionTip()->isVisible()) {
|
||||||
|
handled = true;
|
||||||
|
pMainWindow->functionTip()->previousTip();
|
||||||
|
} else {
|
||||||
|
mLastIdCharPressed = 0;
|
||||||
|
clearUserCodeInTabStops();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case Qt::Key_Down:
|
||||||
|
if (pMainWindow->functionTip()->isVisible()) {
|
||||||
|
handled = true;
|
||||||
|
pMainWindow->functionTip()->nextTip();
|
||||||
|
} else {
|
||||||
|
mLastIdCharPressed = 0;
|
||||||
|
clearUserCodeInTabStops();
|
||||||
|
}
|
||||||
|
return;
|
||||||
case Qt::Key_Delete:
|
case Qt::Key_Delete:
|
||||||
// remove completed character
|
// remove completed character
|
||||||
mLastIdCharPressed = 0;
|
mLastIdCharPressed = 0;
|
||||||
undoSymbolCompletion(caretX());
|
if (!selAvail()) {
|
||||||
|
undoSymbolCompletion(caretX());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case Qt::Key_Backspace:
|
case Qt::Key_Backspace:
|
||||||
// remove completed character
|
// remove completed character
|
||||||
mLastIdCharPressed = 0;
|
mLastIdCharPressed = 0;
|
||||||
undoSymbolCompletion(caretX()-1);
|
if (!selAvail()) {
|
||||||
|
undoSymbolCompletion(caretX()-1);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,19 +1225,31 @@ void Editor::onStatusChanged(SynStatusChanges changes)
|
||||||
|
|
||||||
if (changes.testFlag(SynStatusChange::scCaretX)
|
if (changes.testFlag(SynStatusChange::scCaretX)
|
||||||
|| changes.testFlag(SynStatusChange::scCaretY)) {
|
|| changes.testFlag(SynStatusChange::scCaretY)) {
|
||||||
if (mTabStopBegin >=0 && mTabStopY==caretY()) {
|
if (mTabStopBegin >=0) {
|
||||||
if (lineText().startsWith(mLineBeforeTabStop)
|
if (mTabStopY==caretY()) {
|
||||||
&& lineText().endsWith(mLineAfterTabStop))
|
if (mLineAfterTabStop.isEmpty()) {
|
||||||
mTabStopBegin = mLineBeforeTabStop.length();
|
if (lineText().startsWith(mLineBeforeTabStop))
|
||||||
if (mLineAfterTabStop.isEmpty())
|
mTabStopBegin = mLineBeforeTabStop.length()+1;
|
||||||
mTabStopEnd = lineText().length()+1;
|
mTabStopEnd = lineText().length()+1;
|
||||||
else
|
} else {
|
||||||
mTabStopEnd = lineText().length()
|
if (lineText().startsWith(mLineBeforeTabStop)
|
||||||
- mLineAfterTabStop.length();
|
&& lineText().endsWith(mLineAfterTabStop))
|
||||||
mXOffsetSince = mTabStopEnd - caretX();
|
mTabStopBegin = mLineBeforeTabStop.length();
|
||||||
if (caretX() < mTabStopBegin ||
|
mTabStopEnd = lineText().length()
|
||||||
caretX() > (mTabStopEnd+1))
|
- mLineAfterTabStop.length();
|
||||||
mTabStopBegin = -1;
|
}
|
||||||
|
mXOffsetSince = mTabStopEnd - caretX();
|
||||||
|
if (caretX() < mTabStopBegin ||
|
||||||
|
caretX() > (mTabStopEnd+1)) {
|
||||||
|
mTabStopBegin = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mTabStopBegin>=0) {
|
||||||
|
invalidateLine(mTabStopY);
|
||||||
|
mTabStopBegin = -1;
|
||||||
|
clearUserCodeInTabStops();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1804,10 +1871,10 @@ void Editor::insertCodeSnippet(const QString &code)
|
||||||
leftSpaces(lineText()),true).length();
|
leftSpaces(lineText()),true).length();
|
||||||
QStringList newSl;
|
QStringList newSl;
|
||||||
for (int i=0;i<sl.count();i++) {
|
for (int i=0;i<sl.count();i++) {
|
||||||
int lastPos = 0;
|
int lastPos = -1;
|
||||||
QString s = sl[i];
|
QString s = sl[i];
|
||||||
if (i>0)
|
if (i>0)
|
||||||
lastPos = -spaceCount;
|
lastPos = -spaceCount-1;
|
||||||
while (true) {
|
while (true) {
|
||||||
int insertPos = s.indexOf(USER_CODE_IN_INSERT_POS);
|
int insertPos = s.indexOf(USER_CODE_IN_INSERT_POS);
|
||||||
if (insertPos < 0) // no %INSERT% macro in this line now
|
if (insertPos < 0) // no %INSERT% macro in this line now
|
||||||
|
@ -1822,7 +1889,9 @@ void Editor::insertCodeSnippet(const QString &code)
|
||||||
lastI = i;
|
lastI = i;
|
||||||
mUserCodeInTabStops.append(p);
|
mUserCodeInTabStops.append(p);
|
||||||
}
|
}
|
||||||
lastPos = 0;
|
lastPos = -1;
|
||||||
|
if (i>0)
|
||||||
|
lastPos = -spaceCount-1;
|
||||||
while (true) {
|
while (true) {
|
||||||
int insertPos = s.indexOf(USER_CODE_IN_REPL_POS_BEGIN);
|
int insertPos = s.indexOf(USER_CODE_IN_REPL_POS_BEGIN);
|
||||||
if (insertPos < 0) // no %INSERT% macro in this line now
|
if (insertPos < 0) // no %INSERT% macro in this line now
|
||||||
|
@ -1832,7 +1901,6 @@ void Editor::insertCodeSnippet(const QString &code)
|
||||||
insertPos--;
|
insertPos--;
|
||||||
p->x = insertPos - lastPos;
|
p->x = insertPos - lastPos;
|
||||||
|
|
||||||
|
|
||||||
int insertEndPos = insertPos +
|
int insertEndPos = insertPos +
|
||||||
s.mid(insertPos).indexOf(USER_CODE_IN_REPL_POS_END);
|
s.mid(insertPos).indexOf(USER_CODE_IN_REPL_POS_END);
|
||||||
if (insertEndPos < insertPos) {
|
if (insertEndPos < insertPos) {
|
||||||
|
@ -2067,8 +2135,8 @@ void Editor::completionInsert(bool appendFunc)
|
||||||
|
|
||||||
// delete the part of the word that's already been typed ...
|
// delete the part of the word that's already been typed ...
|
||||||
BufferCoord p = wordEnd();
|
BufferCoord p = wordEnd();
|
||||||
setBlockBegin(wordStart());
|
BufferCoord pStart = wordStart();
|
||||||
setBlockEnd(p);
|
setCaretAndSelection(pStart,pStart,p);
|
||||||
|
|
||||||
// if we are inserting a function,
|
// if we are inserting a function,
|
||||||
if (appendFunc) {
|
if (appendFunc) {
|
||||||
|
@ -2086,6 +2154,7 @@ void Editor::completionInsert(bool appendFunc)
|
||||||
// ... by replacing the selection
|
// ... by replacing the selection
|
||||||
if (statement->kind == StatementKind::skUserCodeSnippet) { // it's a user code template
|
if (statement->kind == StatementKind::skUserCodeSnippet) { // it's a user code template
|
||||||
// insertUserCodeIn(Statement->value);
|
// insertUserCodeIn(Statement->value);
|
||||||
|
//first move caret to the begin of the word to be replaced
|
||||||
insertCodeSnippet(statement->value);
|
insertCodeSnippet(statement->value);
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
|
@ -2620,20 +2689,21 @@ void Editor::popUserCodeInTabStops()
|
||||||
newCursorPos.Char = mTabStopEnd + p->x;
|
newCursorPos.Char = mTabStopEnd + p->x;
|
||||||
tabStopEnd = mTabStopEnd + p->endX;
|
tabStopEnd = mTabStopEnd + p->endX;
|
||||||
} else {
|
} else {
|
||||||
newCursorPos.Char = p->x;
|
newCursorPos.Char = p->x+1;
|
||||||
tabStopEnd = p->endX;
|
tabStopEnd = p->endX+1;
|
||||||
}
|
}
|
||||||
newCursorPos.Line = caretY() + p->y;
|
mTabStopY = caretY() + p->y;
|
||||||
|
newCursorPos.Line = mTabStopY;
|
||||||
|
|
||||||
setCaretXY(newCursorPos);
|
setCaretXY(newCursorPos);
|
||||||
|
|
||||||
mTabStopY = caretY();
|
|
||||||
setBlockBegin(newCursorPos);
|
setBlockBegin(newCursorPos);
|
||||||
newCursorPos.Char = tabStopEnd;
|
newCursorPos.Char = tabStopEnd;
|
||||||
setBlockEnd(newCursorPos);
|
setBlockEnd(newCursorPos);
|
||||||
mTabStopBegin= caretX();
|
mTabStopBegin= caretX();
|
||||||
mTabStopEnd = tabStopEnd;
|
mTabStopEnd = tabStopEnd;
|
||||||
mLineBeforeTabStop = lineText().mid(0, mTabStopBegin) ;
|
mLineBeforeTabStop = lineText().mid(0, mTabStopBegin) ;
|
||||||
mLineAfterTabStop = lineText().mid(mTabStopEnd+1) ;
|
mLineAfterTabStop = lineText().mid(mTabStopEnd) ;
|
||||||
mXOffsetSince=0;
|
mXOffsetSince=0;
|
||||||
mUserCodeInTabStops.pop_front();
|
mUserCodeInTabStops.pop_front();
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,6 @@ private:
|
||||||
void clearUserCodeInTabStops();
|
void clearUserCodeInTabStops();
|
||||||
void popUserCodeInTabStops();
|
void popUserCodeInTabStops();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray mEncodingOption; // the encoding type set by the user
|
QByteArray mEncodingOption; // the encoding type set by the user
|
||||||
QByteArray mFileEncoding; // the real encoding of the file (auto detected)
|
QByteArray mFileEncoding; // the real encoding of the file (auto detected)
|
||||||
|
|
|
@ -83,8 +83,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
ui->tblStackTrace->setModel(mDebugger->backtraceModel());
|
ui->tblStackTrace->setModel(mDebugger->backtraceModel());
|
||||||
ui->watchView->setModel(mDebugger->watchModel());
|
ui->watchView->setModel(mDebugger->watchModel());
|
||||||
|
|
||||||
ui->actionIndent->setShortcut(Qt::Key_Tab);
|
// ui->actionIndent->setShortcut(Qt::Key_Tab);
|
||||||
ui->actionUnIndent->setShortcut(Qt::Key_Tab | Qt::ShiftModifier);
|
// ui->actionUnIndent->setShortcut(Qt::Key_Tab | Qt::ShiftModifier);
|
||||||
|
|
||||||
ui->tableIssues->setErrorColor(QColor("Red"));
|
ui->tableIssues->setErrorColor(QColor("Red"));
|
||||||
ui->tableIssues->setWarningColor(QColor("Orange"));
|
ui->tableIssues->setWarningColor(QColor("Orange"));
|
||||||
|
|
|
@ -5395,6 +5395,16 @@ void SynEdit::timerEvent(QTimerEvent *event)
|
||||||
bool SynEdit::event(QEvent *event)
|
bool SynEdit::event(QEvent *event)
|
||||||
{
|
{
|
||||||
switch(event->type()) {
|
switch(event->type()) {
|
||||||
|
case QEvent::KeyPress:{
|
||||||
|
QKeyEvent* keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
|
if(keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab)
|
||||||
|
{
|
||||||
|
// process tab key presse event
|
||||||
|
keyPressEvent(keyEvent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case QEvent::FontChange:
|
case QEvent::FontChange:
|
||||||
synFontChanged();
|
synFontChanged();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -807,4 +807,5 @@ QString parseMacros(const QString &s)
|
||||||
result.replace("<SOURCEPATH>", "");
|
result.replace("<SOURCEPATH>", "");
|
||||||
result.replace("<WORDXY>", "");
|
result.replace("<WORDXY>", "");
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,6 +474,7 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin
|
||||||
foreach (const PCodeSnippet& codeIn,mCodeSnippets) {
|
foreach (const PCodeSnippet& codeIn,mCodeSnippets) {
|
||||||
PStatement statement = std::make_shared<Statement>();
|
PStatement statement = std::make_shared<Statement>();
|
||||||
statement->command = codeIn->prefix;
|
statement->command = codeIn->prefix;
|
||||||
|
statement->value = codeIn->code;
|
||||||
statement->kind = StatementKind::skUserCodeSnippet;
|
statement->kind = StatementKind::skUserCodeSnippet;
|
||||||
statement->fullName = codeIn->prefix;
|
statement->fullName = codeIn->prefix;
|
||||||
statement->usageCount = 0;
|
statement->usageCount = 0;
|
||||||
|
|
Loading…
Reference in New Issue