work save

This commit is contained in:
royqh1979@gmail.com 2021-09-24 11:41:14 +08:00
parent bfa5835cfa
commit 428b293196
6 changed files with 307 additions and 33 deletions

View File

@ -1151,7 +1151,10 @@ void Editor::onStatusChanged(SynStatusChanges changes)
}
pMainWindow->updateStatusbarForLineCol();
// // Update the function tip
// Update the function tip
if (pSettings->editor().showFunctionTips()) {
updateFunctionTip();
}
// fFunctionTip.ForceHide := false;
// if Assigned(fFunctionTipTimer) then begin
// if fFunctionTip.Activated and FunctionTipAllowed then begin
@ -1164,32 +1167,7 @@ void Editor::onStatusChanged(SynStatusChanges changes)
// end;
}
// // Remove error line colors
// if not fIgnoreCaretChange then begin
// if (fErrorLine <> -1) and not fText.SelAvail then begin
// fText.InvalidateLine(fErrorLine);
// fText.InvalidateGutterLine(fErrorLine);
// fErrorLine := -1;
// end;
// end else
// fIgnoreCaretChange := false;
// if fText.SelAvail then begin
// if fText.GetWordAtRowCol(fText.CaretXY) = fText.SelText then begin
// fSelChanged:=True;
// BeginUpdate;
// EndUpdate;
// end else if fSelChanged then begin
// fSelChanged:=False; //invalidate to unhighlight others
// BeginUpdate;
// EndUpdate;
// end;
// end else if fSelChanged then begin
// fSelChanged:=False; //invalidate to unhighlight others
// BeginUpdate;
// EndUpdate;
// end;
// end;
if (changes.testFlag(scInsertMode) | changes.testFlag(scReadOnly))
pMainWindow->updateForStatusbarModeInfo();
@ -2266,6 +2244,201 @@ QString Editor::getHintForFunction(const PStatement &statement, const PStatement
return result;
}
void Editor::updateFunctionTip()
{
BufferCoord caretPos = caretXY();
NormalizedBufferCoord curPos = normalizeBufferPos(caretPos);
NormalizedBufferCoord nextPos;
int nBraces = 0;
int nCommas = 0;
int FMaxScanLength = 500;
// Find out where the function ends...
for (int i=0;i<FMaxScanLength;i++) {
nextPos = moveBufferPos(curPos,1);
// Stopping characters...
QChar ch = charAtNormalizedBufferPos(curPos);
QChar nextCh = charAtNormalizedBufferPos(nextPos);
if (ch == '\0' || ch == ';') {
return;
// Opening brace, increase count
} else if (ch == '(') {
nBraces++;
// Ending brace, decrease count or success (found ending)!
} else if (ch == ')') {
nBraces--;
if (nBraces == -1)
break;
// Single line comments
} else if ((ch == '/') && (nextCh == '/')) {
// Walk up to an enter sequence
while (ch!='\0' && ch!='\n') {
curPos = nextPos;
nextPos = moveBufferPos(curPos,1);
ch = charAtNormalizedBufferPos(curPos);
nextCh = charAtNormalizedBufferPos(nextPos);
}
// Skip linebreak;
if (ch == '\n') {
curPos = nextPos;
nextPos = moveBufferPos(curPos,1);
}
} else if ((ch == '/') && (nextCh == '*')) {
// Walk up to "*/"
while (ch!='\0' && !(ch=='*' && nextCh=='/')) {
curPos = nextPos;
nextPos = moveBufferPos(curPos,1);
ch = charAtNormalizedBufferPos(curPos);
nextCh = charAtNormalizedBufferPos(nextPos);
}
// Step over
if (ch!='\0') {
curPos = nextPos;
nextPos = moveBufferPos(curPos,1);
}
} else
curPos = nextPos;
}
// If we couldn't find the closing brace or reached the FMaxScanLength...
if (nBraces!=-1) {
return;
}
NormalizedBufferCoord FFunctionEnd = curPos;
NormalizedBufferCoord prevPos;
// We've stopped at the ending ), start walking backwards )*here* with nBraces = -1
for (int i=0;i<FMaxScanLength;i++) {
prevPos = moveBufferPos(curPos,-1);
QChar ch = charAtNormalizedBufferPos(curPos);
QChar prevCh = charAtNormalizedBufferPos(prevPos);
if (prevCh == '*' && ch == '/' ) {
while (true) {
curPos = prevPos;
prevPos = moveBufferPos(curPos,-1);
ch = charAtNormalizedBufferPos(curPos);
prevCh = charAtNormalizedBufferPos(prevPos);
if (prevCh == '\0')
return;
if (prevCh == '/' && ch == '*' ) {
curPos = prevPos;
prevPos = moveBufferPos(curPos,-1);
break;;
}
}
} else if (ch == ')') {
nBraces++ ;
} else if (ch == '(') {
nBraces--;
if (nBraces == -1) // found it!
break;;
} else if (ch == ',') {
if (nBraces == 0)
nCommas++;
}
curPos = prevPos;
if (curPos.Line<1)
break;
}
// If we couldn't find the closing brace or reached the FMaxScanLength...
if (nBraces!=-1) {
return;
}
NormalizedBufferCoord FFunctionStart = curPos;
// Skip blanks
while (curPos.Line>=1) {
prevPos = moveBufferPos(curPos,-1);
QChar prevCh = charAtNormalizedBufferPos(prevPos);
if (prevCh == '\t' || prevCh == ' '
|| prevCh == '\n') {
curPos = prevPos;
} else {
break;
}
}
prevPos = moveBufferPos(curPos,-1);
if (prevPos.Line<1)
return;
// Get the name of the function we're about to show
BufferCoord FuncStartXY;
FuncStartXY.Line = prevPos.Line;
FuncStartXY.Char = prevPos.Char;
QString token;
PSynHighlighterAttribute HLAttr;
if (!getHighlighterAttriAtRowCol(FuncStartXY,token,HLAttr)) {
return;
}
if (HLAttr->name()!=SYNS_AttrIdentifier)
return;
BufferCoord pWordBegin, pWordEnd;
QString s = getWordAtPosition(this, FuncStartXY, pWordBegin,pWordEnd, WordPurpose::wpInformation);
// Don't bother scanning the database when there's no identifier to scan for
// Only do the cumbersome list filling when showing a new tooltip...
if (s != pMainWindow->functionTip()->functionFullName()
&& !mParser->parsing()) {
pMainWindow->functionTip()->clearTips();
mParser->fillListOfFunctions()
}
FSelIndex := 0;
FCustomSelIndex := False;
// Fill a cache of known functions...
FToolTips.BeginUpdate;
FToolTips.Clear;
FParser.FillListOfFunctions(fFileName,S,FuncStartXY.Line, FToolTips);
FToolTips.EndUpdate;
end;
// If we can't find it in our database, hide
if FToolTips.Count = 0 then begin
ReleaseHandle;
Exit;
end;
FOldFunction := S;
// get the current token position in the text
// this is where the prototype name usually starts
FTokenPos := CurPos - Length(S);
// Search for the best possible overload match according to comma count
if (shoFindBestMatchingToolTip in FOptions) then
// Only do so when the user didn't select his own
if not FCustomSelIndex then
S := FindClosestToolTip(S, nCommas);
// Select the current one
if (FSelIndex < FToolTips.Count) then
S := FToolTips.Strings[FSelIndex];
// set the hint caption
Caption := Trim(S);
// we use the LookupEditor to get the highlighter-attributes
// from. check the DrawAdvanced method!
FLookupEditor.Text := Caption;
FLookupEditor.Highlighter := FEditor.Highlighter;
// get the index of the current argument (where the cursor is)
FCurParamIndex := GetCommaIndex(P, FFunctionStart + 1, CaretPos - 1);
RethinkCoordAndActivate;
}
void Editor::setInProject(bool newInProject)
{
if (mInProject == newInProject)

View File

@ -197,6 +197,8 @@ private:
QString getHintForFunction(const PStatement& statement, const PStatement& scope,
const QString& filename, int line);
void updateFunctionTip();
private:
QByteArray mEncodingOption; // the encoding type set by the user

View File

@ -149,6 +149,7 @@ MainWindow::MainWindow(QWidget *parent)
mCompletionPopup = std::make_shared<CodeCompletionPopup>();
mHeaderCompletionPopup = std::make_shared<HeaderCompletionPopup>();
mFunctionTip = std::make_shared<FunctionTooltipWidget>();
updateAppTitle();
@ -1967,6 +1968,11 @@ const std::shared_ptr<HeaderCompletionPopup> &MainWindow::headerCompletionPopup(
return mHeaderCompletionPopup;
}
const std::shared_ptr<FunctionTooltipWidget> &MainWindow::functionTip() const
{
return mFunctionTip;
}
const std::shared_ptr<CodeCompletionPopup> &MainWindow::completionPopup() const
{
return mCompletionPopup;

View File

@ -9,6 +9,7 @@
#include "widgets/classbrowser.h"
#include "widgets/codecompletionpopup.h"
#include "widgets/headercompletionpopup.h"
#include "widgets/functiontooltipwidget.h"
#include "caretlist.h"
QT_BEGIN_NAMESPACE
@ -102,6 +103,9 @@ public:
const std::shared_ptr<CodeCompletionPopup> &completionPopup() const;
const std::shared_ptr<HeaderCompletionPopup> &headerCompletionPopup() const;
const std::shared_ptr<FunctionTooltipWidget> &functionTip() const;
CaretList &caretList();
void updateCaretActions();
@ -358,6 +362,7 @@ private:
std::shared_ptr<CodeCompletionPopup> mCompletionPopup;
std::shared_ptr<HeaderCompletionPopup> mHeaderCompletionPopup;
std::shared_ptr<FunctionTooltipWidget> mFunctionTip;
SearchResultModel mSearchResultModel;
PSearchResultListModel mSearchResultListModel;

View File

@ -38,6 +38,7 @@ void FunctionTooltipWidget::addTip(const QString &name, const QString& fullname,
info->returnType = returnType;
info->params = splitArgs(args);
info->nonameParams = splitArgs(noNameArgs);
mInfos.append(info);
}
void FunctionTooltipWidget::clearTips()
@ -56,14 +57,47 @@ void FunctionTooltipWidget::setParamPos(int newParamPos)
mParamPos = newParamPos;
}
int FunctionTooltipWidget::index() const
void FunctionTooltipWidget::nextTip()
{
return mIndex;
if (mInfos.length()>0)
mInfoIndex = std::min(mInfoIndex+1,mInfos.length()-1);
updateTip();
}
void FunctionTooltipWidget::setIndex(int newIndex)
void FunctionTooltipWidget::previousTip()
{
mIndex = newIndex;
if (mInfos.length()>0)
mInfoIndex = std::max(mInfoIndex-1,0);
updateTip();
}
void FunctionTooltipWidget::updateTip()
{
mTotalLabel->setVisible(mInfos.length()>1);
mUpButton->setVisible(mInfos.length()>1);
mDownButton->setVisible(mInfos.length()>1);
mUpButton->setEnabled(mInfoIndex!=0);
mDownButton->setEnabled(mInfoIndex!=mInfos.length()-1);
if (mInfos.length()<=0)
return;
PFunctionInfo info = mInfos[mInfoIndex];
QString text = info->returnType+ " " + info->name;
if (info->params.length()==0) {
text += "()";
} else {
QStringList displayList;
for (int i=0;i<info->params.length();i++){
const QString& param = info->params[i];
if (mParamIndex == i) {
displayList.append(QString("<b>%1</b>").arg(param));
} else {
displayList.append(param);
}
}
text += "( "+displayList.join(", ") + ") ";
}
mInfoLabel->setText(text);
}
QStringList FunctionTooltipWidget::splitArgs(QString argStr)
@ -94,3 +128,41 @@ QStringList FunctionTooltipWidget::splitArgs(QString argStr)
}
return result;
}
const QString &FunctionTooltipWidget::functionFullName() const
{
return mFunctioFullName;
}
void FunctionTooltipWidget::setFunctioFullName(const QString &newFunctioFullName)
{
mFunctioFullName = newFunctioFullName;
}
int FunctionTooltipWidget::paramIndex() const
{
return mParamIndex;
}
void FunctionTooltipWidget::setParamIndex(int newParamIndex)
{
mParamIndex = newParamIndex;
}
void FunctionTooltipWidget::closeEvent(QCloseEvent *)
{
}
void FunctionTooltipWidget::showEvent(QShowEvent *)
{
if (mInfos.length()>0) {
mInfoIndex = 0;
}
updateTip();
}
void FunctionTooltipWidget::hideEvent(QHideEvent *event)
{
mInfos.clear();
}

View File

@ -25,9 +25,16 @@ public:
void clearTips();
int paramPos() const;
void setParamPos(int newParamPos);
void nextTip();
void previousTip();
void updateTip();
int paramIndex() const;
void setParamIndex(int newParamIndex);
const QString &functionFullName() const;
void setFunctioFullName(const QString &newFunctioFullName);
int index() const;
void setIndex(int newIndex);
signals:
private:
QStringList splitArgs(QString args);
@ -37,8 +44,17 @@ private:
QToolButton* mUpButton;
QToolButton* mDownButton;
int mParamPos;
int mIndex;
int mInfoIndex;
int mParamIndex;
QString mFunctioFullName;
QList<PFunctionInfo> mInfos;
// QWidget interface
protected:
void closeEvent(QCloseEvent *event) override;
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
};
#endif // FUNCTIONTOOLTIPWIDGET_H